aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Enberg <penberg@kernel.org>2012-02-16 19:38:44 +0200
committerPekka Enberg <penberg@kernel.org>2012-02-16 19:38:44 +0200
commit5d7ed9dc79184989a1c298a01e4e560ebb2ba162 (patch)
tree1d88e29d3c5a58383a6894bdcca9c6a3c6d0a495
parentbf76cc8dad96eb8c9c9b38994d1e1cbb712bc805 (diff)
downloadjato-5d7ed9dc79184989a1c298a01e4e560ebb2ba162.tar.gz
x86: Use varargs for vm_object_alloc_multi_array()
In preparation for fixing multianewarray support on x86-64, convert vm_object_alloc_multi_array() to use varargs instead of passing a pointer to stack. Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r--arch/x86/insn-selector_32.brg6
-rw-r--r--arch/x86/insn-selector_64.brg10
-rw-r--r--include/vm/object.h3
-rw-r--r--vm/object.c34
4 files changed, 32 insertions, 21 deletions
diff --git a/arch/x86/insn-selector_32.brg b/arch/x86/insn-selector_32.brg
index c3ab9004..eb4b2abc 100644
--- a/arch/x86/insn-selector_32.brg
+++ b/arch/x86/insn-selector_32.brg
@@ -1130,7 +1130,6 @@ arg: EXPR_MULTIARRAY_SIZE_CHECK(arg)
reg: EXPR_MULTIANEWARRAY(arg)
{
struct var_info *xax;
- struct var_info *stack_ptr;
unsigned int dimension;
struct expression *expr;
struct expression *size_check;
@@ -1140,18 +1139,15 @@ reg: EXPR_MULTIANEWARRAY(arg)
xax = get_fixed_var(s->b_parent, MACH_REG_xAX);
state->reg1 = get_var(s->b_parent, J_REFERENCE);
- stack_ptr = get_fixed_var(s->b_parent, MACH_REG_xSP);
-
size_check = to_expr(expr->multianewarray_dimensions);
dimension = nr_args(to_expr(size_check->size_expr));
- select_insn(s, tree, reg_insn(INSN_PUSH_REG, stack_ptr));
select_insn(s, tree, imm_insn(INSN_PUSH_IMM, dimension));
select_insn(s, tree, imm_insn(INSN_PUSH_IMM, (unsigned long) expr->multianewarray_ref_type));
select_safepoint_insn(s, tree, rel_insn(INSN_CALL_REL, (unsigned long) vm_object_alloc_multi_array));
select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, xax, state->reg1));
- method_args_cleanup(s, tree, dimension + 3);
+ method_args_cleanup(s, tree, dimension + 2);
select_exception_test(s, tree);
}
diff --git a/arch/x86/insn-selector_64.brg b/arch/x86/insn-selector_64.brg
index 81f18e33..eb41ea6f 100644
--- a/arch/x86/insn-selector_64.brg
+++ b/arch/x86/insn-selector_64.brg
@@ -981,9 +981,8 @@ arg: EXPR_MULTIARRAY_SIZE_CHECK(arg)
reg: EXPR_MULTIANEWARRAY(arg)
{
- struct var_info *rsi, *rdi, *rdx;
+ struct var_info *rsi, *rdi;
struct var_info *xax;
- struct var_info *stack_ptr;
unsigned int dimension;
struct expression *expr;
struct expression *size_check;
@@ -993,14 +992,9 @@ reg: EXPR_MULTIANEWARRAY(arg)
xax = get_fixed_var(s->b_parent, MACH_REG_xAX);
state->reg1 = get_var(s->b_parent, J_REFERENCE);
- stack_ptr = get_fixed_var(s->b_parent, MACH_REG_xSP);
-
size_check = to_expr(expr->multianewarray_dimensions);
dimension = nr_args(to_expr(size_check->size_expr));
- rdx = get_fixed_var(s->b_parent, MACH_REG_RDX);
- select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, stack_ptr, rdx));
-
rsi = get_fixed_var(s->b_parent, MACH_REG_RSI);
select_insn(s, tree, imm_reg_insn(INSN_MOV_IMM_REG, dimension, rsi));
@@ -1010,7 +1004,7 @@ reg: EXPR_MULTIANEWARRAY(arg)
select_safepoint_insn(s, tree, rel_insn(INSN_CALL_REL, (unsigned long) vm_object_alloc_multi_array));
select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, xax, state->reg1));
- method_args_cleanup(s, tree, dimension + 3);
+ method_args_cleanup(s, tree, dimension + 2);
select_exception_test(s, tree);
}
diff --git a/include/vm/object.h b/include/vm/object.h
index 93e515b3..f399ed1d 100644
--- a/include/vm/object.h
+++ b/include/vm/object.h
@@ -65,8 +65,7 @@ int init_vm_objects(void);
struct vm_object *vm_object_alloc(struct vm_class *class);
struct vm_object *vm_object_alloc_array_raw(struct vm_class *class, size_t elem_size, int count);
struct vm_object *vm_object_alloc_primitive_array(int type, int count);
-struct vm_object *vm_object_alloc_multi_array(struct vm_class *class,
- int nr_dimensions, int *count);
+struct vm_object *vm_object_alloc_multi_array(struct vm_class *class, int nr_dimensions, ...);
struct vm_object *vm_object_alloc_array(struct vm_class *class, int count);
struct vm_object *vm_object_alloc_array_of(struct vm_class *elem_class, int count);
diff --git a/vm/object.c b/vm/object.c
index 4679d25e..e2cea1b8 100644
--- a/vm/object.c
+++ b/vm/object.c
@@ -145,12 +145,13 @@ struct vm_object *vm_object_alloc_primitive_array(int type, int count)
return &res->object;
}
-struct vm_object *
-vm_object_alloc_multi_array(struct vm_class *class, int nr_dimensions, int *counts)
+static struct vm_object *
+do_vm_object_alloc_multi_array(struct vm_class *class, int nr_dimensions, va_list ap)
{
struct vm_class *elem_class;
struct vm_array *res;
int elem_size;
+ int len;
assert(nr_dimensions > 0);
@@ -160,25 +161,46 @@ vm_object_alloc_multi_array(struct vm_class *class, int nr_dimensions, int *coun
elem_class = vm_class_get_array_element_class(class);
elem_size = vmtype_get_size(vm_class_get_storage_vmtype(elem_class));
- res = gc_alloc(sizeof(*res) + elem_size * counts[0]);
+ len = va_arg(ap, int);
+
+ res = gc_alloc(sizeof(*res) + elem_size * len);
if (!res)
return throw_oom_error();
vm_object_init_common(&res->object);
- res->array_length = counts[0];
+ res->array_length = len;
res->object.class = class;
if (nr_dimensions == 1)
return &res->object;
struct vm_object **elems = vm_array_elems(&res->object);
- for (int i = 0; i < counts[0]; ++i)
- elems[i] = vm_object_alloc_multi_array(elem_class, nr_dimensions - 1, counts + 1);
+ for (int i = 0; i < res->array_length; ++i) {
+ va_list dup_ap;
+
+ va_copy(dup_ap, ap);
+
+ elems[i] = do_vm_object_alloc_multi_array(elem_class, nr_dimensions - 1, dup_ap);
+ }
return &res->object;
}
+struct vm_object *
+vm_object_alloc_multi_array(struct vm_class *class, int nr_dimensions, ...)
+{
+ va_list ap, dup_ap;
+
+ va_start(ap, nr_dimensions);
+
+ va_copy(dup_ap, ap);
+
+ va_end(ap);
+
+ return do_vm_object_alloc_multi_array(class, nr_dimensions, ap);
+}
+
struct vm_object *vm_object_alloc_array(struct vm_class *class, int count)
{
struct vm_array *res;