Re: [PATCH] x86: add OP_AND(reg, reg)

2009-06-24 Thread Pekka Enberg
On Thu, 2009-06-25 at 01:02 +0200, Arthur HUILLET wrote:
> It is necessary for System.out.println
> 
> Signed-off-by: Arthur HUILLET 

Seems reasonable although I usually don't like merging something that
has no users. Anyway, applied!


--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


Re: [PATCH] regression: ObjectStackTest now enabled

2009-06-24 Thread Pekka Enberg
On Wed, 2009-06-24 at 22:25 +0200, Arthur HUILLET wrote:
> Signed-off-by: Arthur HUILLET 
> ---
>  regression/jvm/ObjectStackTest.java |3 +--
>  1 files changed, 1 insertions(+), 2 deletions(-)

Nice work! Applied.


--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


Re: [PATCH 3/3] bc2ir: mimic stack spilling/reloading

2009-06-24 Thread Pekka Enberg
On Wed, 2009-06-24 at 22:21 +0200, Arthur HUILLET wrote:
> @@ -276,6 +277,121 @@ out:
>   return err;
>  }
>  
> +static void assign_temporary(struct basic_block *bb, int entry, int slotnb,
> + struct var_info *tmp_high, struct var_info *tmp_low)
> +{

Indentation gone crazy in this function.

> + unsigned int i;
> + struct expression *expr;
> +
> + for (i = 0; i < bb->nr_mimic_stack_expr; i++) {
> + expr = bb->mimic_stack_expr[i];
> +
> + if (expr_type(expr) != EXPR_MIMIC_STACK_SLOT)
> + continue;
> +
> + if (expr->entry != entry ||
> + expr->slotnb != slotnb)
> + continue;
> +
> + expr_set_type(expr, EXPR_TEMPORARY);
> + expr->tmp_high = tmp_high;
> + expr->tmp_low = tmp_low;
> + }
> +}

> +static int __do_resolve_mimic_stack_slots(int nr_neighbors, struct 
> basic_block **neighbors,
> + int entry)
> +{

The "__do" prefix makes no sense. The "__" is inherited from the kernel
and strictly speaking, we should not be using it in userspace. The "do"
prefix is what most people seem to do in userspace. But the combination
of the two is just... strange.

Anyway, I fixed it (and other goofs) up and applied the patch. Thanks!



--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


Re: [PATCH 1/3] jit: add EXPR_MIMIC_STACK_SLOT and expr_set_type

2009-06-24 Thread Pekka Enberg
On Wed, 2009-06-24 at 22:21 +0200, Arthur HUILLET wrote:
> This will be necessary for bc2ir to work.
> 
> Signed-off-by: Arthur HUILLET 

> @@ -235,6 +236,13 @@ struct expression {
>  
>   /* EXPR_ARRAY_SIZE_CHECK and EXPR_MULTIARRAY_SIZE_CHECK */
>   struct tree_node *size_expr;
> +
> + /* EXPR_MIMIC_STACK_SLOT */
> + struct {
> + char entry;
> + int slotnb;

I did s/slotnb/slot_ndx/ for the whole patch.

Patch applied.


--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


Re: [PATCH 1/2] jit: add predecessors to basic block structure

2009-06-24 Thread Pekka Enberg
On Wed, 2009-06-24 at 18:13 +0200, Arthur HUILLET wrote:
> diff --git a/test/jit/basic-block-assert.h
> b/test/jit/basic-block-assert.h
> index 8f00672..abec84c 100644
> --- a/test/jit/basic-block-assert.h
> +++ b/test/jit/basic-block-assert.h
> @@ -12,16 +12,28 @@ static void inline assert_basic_block(struct 
> compilation_unit *parent,
>   assert_int_equals(end, bb->end);
>  }
>  
> +static void inline __assert_bb_neighbors(struct basic_block **neigh, int 
> nneigh, struct basic_block **array, unsigned long sz)

The more common way to write the above is

  static inline void

Anyway, I went ahead and cleaned up the whole header file which had
turned into a big mess.

Patch applied.

Pekka


--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


Re: Monoburg arithmetic operations

2009-06-24 Thread Pekka Enberg
On Thu, 2009-06-25 at 00:53 +0200, Arthur Huillet wrote:
> I wasted several hours until I noticed that OP_AND was only implemented with
> (reg, EXPR_LOCAL).
> 
> The (reg, reg) variant is missing for several binops, and it's very difficult
> with monoburg to notice it.

Yup, I think it's worth some of our time to spend on either (a)
improving monoburg error reporting, (b) switching to some other tool, or
(c) writing our own replacement. That said, I think Mono no longer has a
"instruction selection" phase as we know it but rather directly
generates LIR at the bytecode (or whatever it's called in .NET) parsing
phase.

Pekka


--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


[PATCH] x86: add OP_AND(reg, reg)

2009-06-24 Thread Arthur HUILLET
It is necessary for System.out.println

Signed-off-by: Arthur HUILLET 
---
 arch/x86/emit-code.c|7 +++
 arch/x86/include/arch/instruction.h |1 +
 arch/x86/insn-selector_32.brg   |   15 +++
 arch/x86/lir-printer.c  |7 +++
 arch/x86/use-def.c  |1 +
 5 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c
index d66d9f0..3033adb 100644
--- a/arch/x86/emit-code.c
+++ b/arch/x86/emit-code.c
@@ -759,6 +759,12 @@ static void emit_add_membase_reg(struct buffer *buf,
emit_membase_reg(buf, 0x03, src, dest);
 }
 
+static void emit_and_reg_reg(struct buffer *buf,
+struct operand *src, struct operand *dest)
+{
+   emit_reg_reg(buf, 0x23, dest, src);
+}
+
 static void emit_and_membase_reg(struct buffer *buf,
 struct operand *src, struct operand *dest)
 {
@@ -1003,6 +1009,7 @@ struct emitter emitters[] = {
DECL_EMITTER(INSN_ADD_MEMBASE_REG, emit_add_membase_reg, TWO_OPERANDS),
DECL_EMITTER(INSN_ADD_REG_REG, emit_add_reg_reg, TWO_OPERANDS),
DECL_EMITTER(INSN_AND_MEMBASE_REG, emit_and_membase_reg, TWO_OPERANDS),
+   DECL_EMITTER(INSN_AND_REG_REG, emit_and_reg_reg, TWO_OPERANDS),
DECL_EMITTER(INSN_CALL_REG, emit_indirect_call, SINGLE_OPERAND),
DECL_EMITTER(INSN_CLTD_REG_REG, emit_cltd_reg_reg, TWO_OPERANDS),
DECL_EMITTER(INSN_CMP_IMM_REG, emit_cmp_imm_reg, TWO_OPERANDS),
diff --git a/arch/x86/include/arch/instruction.h 
b/arch/x86/include/arch/instruction.h
index 5e38144..8355a63 100644
--- a/arch/x86/include/arch/instruction.h
+++ b/arch/x86/include/arch/instruction.h
@@ -61,6 +61,7 @@ enum insn_type {
INSN_ADD_MEMBASE_REG,
INSN_ADD_REG_REG,
INSN_AND_MEMBASE_REG,
+   INSN_AND_REG_REG,
INSN_CALL_REG,
INSN_CALL_REL,
INSN_CLTD_REG_REG,  /* CDQ in Intel manuals*/
diff --git a/arch/x86/insn-selector_32.brg b/arch/x86/insn-selector_32.brg
index fce1f50..bbe0f9e 100644
--- a/arch/x86/insn-selector_32.brg
+++ b/arch/x86/insn-selector_32.brg
@@ -432,6 +432,21 @@ reg:   OP_AND(reg, EXPR_LOCAL) 1
}
 }
 
+reg:   OP_AND(reg, reg) 1
+{
+   struct expression *expr;
+
+   expr = to_expr(tree);
+
+   state->reg1 = state->left->reg1;
+   binop_reg_reg_low(state, s, tree, INSN_AND_REG_REG);
+
+   if (expr->vm_type == J_LONG) {
+   state->reg2 = state->left->reg2;
+   binop_reg_reg_high(state, s, tree, INSN_AND_REG_REG);
+   }
+}
+
 reg:   OP_XOR(reg, EXPR_LOCAL) 1
 {
struct expression *expr;
diff --git a/arch/x86/lir-printer.c b/arch/x86/lir-printer.c
index 195f80e..31c89f6 100644
--- a/arch/x86/lir-printer.c
+++ b/arch/x86/lir-printer.c
@@ -196,6 +196,12 @@ static int print_and_membase_reg(struct string *str, 
struct insn *insn)
return print_membase_reg(str, insn);
 }
 
+static int print_and_reg_reg(struct string *str, struct insn *insn)
+{
+   print_func_name(str);
+   return print_reg_reg(str, insn);
+}
+
 static int print_call_reg(struct string *str, struct insn *insn)
 {
print_func_name(str);
@@ -501,6 +507,7 @@ static print_insn_fn insn_printers[] = {
[INSN_ADD_MEMBASE_REG] = print_add_membase_reg,
[INSN_ADD_REG_REG] = print_add_reg_reg,
[INSN_AND_MEMBASE_REG] = print_and_membase_reg,
+   [INSN_AND_REG_REG] = print_and_reg_reg,
[INSN_CALL_REG] = print_call_reg,
[INSN_CALL_REL] = print_call_rel,
[INSN_CLTD_REG_REG] = print_cltd_reg_reg,   /* CDQ in Intel 
manuals*/
diff --git a/arch/x86/use-def.c b/arch/x86/use-def.c
index 95342ad..38a4ef4 100644
--- a/arch/x86/use-def.c
+++ b/arch/x86/use-def.c
@@ -37,6 +37,7 @@ static struct insn_info insn_infos[] = {
DECLARE_INFO(INSN_ADD_MEMBASE_REG, USE_SRC | DEF_DST),
DECLARE_INFO(INSN_ADD_REG_REG, USE_SRC | DEF_DST),
DECLARE_INFO(INSN_AND_MEMBASE_REG, USE_SRC | DEF_DST),
+   DECLARE_INFO(INSN_AND_REG_REG, USE_SRC | DEF_DST),
DECLARE_INFO(INSN_CALL_REG, USE_SRC | DEF_EAX | DEF_ECX | DEF_EDX),
DECLARE_INFO(INSN_CALL_REL, USE_NONE | DEF_EAX | DEF_ECX | DEF_EDX),
DECLARE_INFO(INSN_CLTD_REG_REG, USE_SRC | DEF_SRC | DEF_DST),
-- 
1.6.2.2



--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


Monoburg arithmetic operations

2009-06-24 Thread Arthur Huillet
Hi, 

I wasted several hours until I noticed that OP_AND was only implemented with
(reg, EXPR_LOCAL).

The (reg, reg) variant is missing for several binops, and it's very difficult
with monoburg to notice it.

Implementing the (reg, reg) variants for operations will be my work of tomorrow
as it is necessary for System.out.println, as exposed by my tests.

This explains the upcoming patches.

By the way, System.out.println:

jato: arch/x86/insn-selector_32.c:1762: mono_burg_emit: Assertion `!"conversion
not implemented"' failed.


So that's on my list too :)

-- 
Greetings, 
A.H.


--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


[PATCH] regression: ObjectStackTest now enabled

2009-06-24 Thread Arthur HUILLET
Signed-off-by: Arthur HUILLET 
---
 regression/jvm/ObjectStackTest.java |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/regression/jvm/ObjectStackTest.java 
b/regression/jvm/ObjectStackTest.java
index d49cc62..04efeca 100644
--- a/regression/jvm/ObjectStackTest.java
+++ b/regression/jvm/ObjectStackTest.java
@@ -49,8 +49,7 @@ public class ObjectStackTest extends TestCase {
 
 public static void testObjectStackWhenBranching() {
 assertIsGreaterThanOne(2);
-// TODO
-// assertIsNotGreaterThanOne(1);
+assertIsNotGreaterThanOne(1);
 }
 
 public static void main(String[] args) {
-- 
1.6.2.2



--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


[PATCH 3/3] bc2ir: mimic stack spilling/reloading

2009-06-24 Thread Arthur HUILLET
Mimic stack is now correctly spilled and reloaded at basic block
boundaries.

Signed-off-by: Arthur HUILLET 
---
 jit/bytecode-to-ir.c |  155 +-
 1 files changed, 141 insertions(+), 14 deletions(-)

diff --git a/jit/bytecode-to-ir.c b/jit/bytecode-to-ir.c
index 862a335..52d872f 100644
--- a/jit/bytecode-to-ir.c
+++ b/jit/bytecode-to-ir.c
@@ -102,28 +102,24 @@ void convert_statement(struct parse_context *ctx, struct 
statement *stmt)
 
 static int spill_expression(struct basic_block *bb,
struct stack *reload_stack,
-   struct expression *expr)
+   struct expression *expr, int slotnb)
 {
-   struct compilation_unit *cu = bb->b_parent;
-   struct var_info *tmp_low, *tmp_high;
struct statement *store, *branch;
-   struct expression *tmp;
+   struct expression *exit_tmp, *entry_tmp;
 
-   tmp_low = get_var(cu);
-   if (expr->vm_type == J_LONG)
-   tmp_high = get_var(cu);
-   else
-   tmp_high = NULL;
+   exit_tmp = mimic_stack_expr(expr->vm_type, 0, slotnb);
+   entry_tmp = mimic_stack_expr(expr->vm_type, 1, slotnb);
 
-   tmp = temporary_expr(expr->vm_type, tmp_high, tmp_low);
-   if (!tmp)
+   if (!exit_tmp || !entry_tmp)
return -ENOMEM;
 
+   bb_add_mimic_stack_expr(bb, exit_tmp);
+
store = alloc_statement(STMT_STORE);
if (!store)
return -ENOMEM;
 
-   store->store_dest = &tmp->node;
+   store->store_dest = &exit_tmp->node;
store->store_src = &expr->node;
 
if (bb->has_branch)
@@ -143,7 +139,7 @@ static int spill_expression(struct basic_block *bb,
 * And add a reload expression that is put on the mimic stack of
 * successor basic blocks.
 */
-   stack_push(reload_stack, expr_get(tmp));
+   stack_push(reload_stack, expr_get(entry_tmp));
 
return 0;
 }
@@ -160,15 +156,18 @@ static struct stack *spill_mimic_stack(struct basic_block 
*bb)
 * The reload stack contains elements in reverse order of the mimic
 * stack.
 */
+   int spillcount = 0;
while (!stack_is_empty(bb->mimic_stack)) {
struct expression *expr;
int err;
 
expr = stack_pop(bb->mimic_stack);
 
-   err = spill_expression(bb, reload_stack, expr);
+   err = spill_expression(bb, reload_stack, expr, spillcount);
if (err)
goto error_oom;
+
+   spillcount++;
}
return reload_stack;
 error_oom:
@@ -259,6 +258,8 @@ static int convert_bb_to_ir(struct basic_block *bb)
 
expr_get(expr);
 
+   bb_add_mimic_stack_expr(s, expr);
+
stack_push(s->mimic_stack, expr);
}
expr_put(expr);
@@ -276,6 +277,121 @@ out:
return err;
 }
 
+static void assign_temporary(struct basic_block *bb, int entry, int slotnb,
+   struct var_info *tmp_high, struct var_info *tmp_low)
+{
+   unsigned int i;
+   struct expression *expr;
+
+   for (i = 0; i < bb->nr_mimic_stack_expr; i++) {
+   expr = bb->mimic_stack_expr[i];
+
+   if (expr_type(expr) != EXPR_MIMIC_STACK_SLOT)
+   continue;
+
+   if (expr->entry != entry ||
+   expr->slotnb != slotnb)
+   continue;
+
+   expr_set_type(expr, EXPR_TEMPORARY);
+   expr->tmp_high = tmp_high;
+   expr->tmp_low = tmp_low;
+   }
+}
+
+static void pick_and_propagate_temporaries(struct basic_block *bb, int entry)
+{
+   struct expression *expr;
+   struct var_info *tmp_high, *tmp_low;
+   struct basic_block **neighbors;
+   int neighbors_nr;
+   unsigned int i;
+   int slotnb;
+
+   if (entry) {
+   neighbors = bb->predecessors;
+   neighbors_nr = bb->nr_predecessors;
+   } else {
+   neighbors = bb->successors;
+   neighbors_nr = bb->nr_successors;
+   }
+
+   for (i = 0; i < bb->nr_mimic_stack_expr; i++) {
+   expr = bb->mimic_stack_expr[i];
+
+   /* Skip expressions that already been transformed */
+   if (expr_type(expr) != EXPR_MIMIC_STACK_SLOT)
+   continue;
+
+   /* Skip slots related to the exit when treating entrance
+* and vice versa */
+   if (expr->entry != entry)
+   continue;
+
+   tmp_low = get_var(bb->b_parent);
+   if (expr->vm_type == J_LONG)
+   tmp_high = get_var(bb->b_parent);
+   else tmp_high = NULL;
+
+  

[PATCH 2/3] jit: add list of mimic stack exprs to struct basic_block

2009-06-24 Thread Arthur HUILLET
BC2IR needs it to properly replace them by temporaries.

Signed-off-by: Arthur HUILLET 
---
 include/jit/basic-block.h |3 +++
 jit/basic-block.c |   26 --
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/include/jit/basic-block.h b/include/jit/basic-block.h
index 4919c95..c953ebe 100644
--- a/include/jit/basic-block.h
+++ b/include/jit/basic-block.h
@@ -26,6 +26,8 @@ struct basic_block {
struct basic_block **successors;
unsigned long nr_predecessors;
struct basic_block **predecessors;
+   unsigned long nr_mimic_stack_expr;
+   struct expression **mimic_stack_expr;
unsigned long mach_offset;
 
/* The mimic stack is used to simulate JVM operand stack at
@@ -69,6 +71,7 @@ struct basic_block *bb_split(struct basic_block *, unsigned 
long);
 void bb_add_stmt(struct basic_block *, struct statement *);
 void bb_add_insn(struct basic_block *, struct insn *);
 int bb_add_successor(struct basic_block *, struct basic_block *);
+int bb_add_mimic_stack_expr(struct basic_block *, struct expression *);
 struct statement *bb_remove_last_stmt(struct basic_block *bb);
 unsigned char *bb_native_ptr(struct basic_block *bb);
 
diff --git a/jit/basic-block.c b/jit/basic-block.c
index 5a4fa53..23709a0 100644
--- a/jit/basic-block.c
+++ b/jit/basic-block.c
@@ -77,6 +77,7 @@ void free_basic_block(struct basic_block *bb)
free_insn_list(&bb->insn_list);
free(bb->successors);
free(bb->predecessors);
+   free(bb->mimic_stack_expr);
free(bb->use_set);
free(bb->def_set);
free(bb->live_in_set);
@@ -146,20 +147,20 @@ void bb_add_insn(struct basic_block *bb, struct insn 
*insn)
list_add_tail(&insn->insn_list_node, &bb->insn_list);
 }
 
-int __bb_add_neighbor(struct basic_block *new, struct basic_block ***array, 
unsigned long *nb)
+int __bb_add_neighbor(void *new, void **array, unsigned long *nb)
 {
unsigned long new_size;
-   struct basic_block **new_neighbors;
+   void *new_array;
 
-   new_size = sizeof(struct basic_block *) * (*nb + 1);
+   new_size = sizeof(void *) * (*nb + 1);
 
-   new_neighbors = realloc(*array, new_size);
-   if (new_neighbors == NULL)
+   new_array = realloc(*array, new_size);
+   if (new_array == NULL)
return -ENOMEM;
 
-   *array = new_neighbors;
+   *array = new_array;
 
-   (*array)[*nb] = new;
+   ((void **)(*array))[*nb] = new;
(*nb)++;
 
return 0;
@@ -167,13 +168,18 @@ int __bb_add_neighbor(struct basic_block *new, struct 
basic_block ***array, unsi
 
 int bb_add_successor(struct basic_block *bb, struct basic_block *successor)
 {
-   __bb_add_neighbor(bb, &successor->predecessors, 
&successor->nr_predecessors);
-   return __bb_add_neighbor(successor, &bb->successors, 
&bb->nr_successors);
+   __bb_add_neighbor(bb, (void **)&successor->predecessors, 
&successor->nr_predecessors);
+   return __bb_add_neighbor(successor, (void **)&bb->successors, 
&bb->nr_successors);
 }
 
 int bb_add_predecessor(struct basic_block *bb, struct basic_block *predecessor)
 {
-   return __bb_add_neighbor(predecessor, &bb->predecessors, 
&bb->nr_predecessors);
+   return __bb_add_neighbor(predecessor, (void **)&bb->predecessors, 
&bb->nr_predecessors);
+}
+
+int bb_add_mimic_stack_expr(struct basic_block *bb, struct expression *expr)
+{
+   return __bb_add_neighbor(expr, (void **)&bb->mimic_stack_expr, 
&bb->nr_mimic_stack_expr);
 }
 
 unsigned char *bb_native_ptr(struct basic_block *bb)
-- 
1.6.2.2



--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


[PATCH 1/3] jit: add EXPR_MIMIC_STACK_SLOT and expr_set_type

2009-06-24 Thread Arthur HUILLET
This will be necessary for bc2ir to work.

Signed-off-by: Arthur HUILLET 
---
 include/jit/expression.h |   16 
 jit/expression.c |   12 
 jit/tree-printer.c   |   11 +--
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/include/jit/expression.h b/include/jit/expression.h
index 43b41c0..d771778 100644
--- a/include/jit/expression.h
+++ b/include/jit/expression.h
@@ -35,6 +35,7 @@ enum expression_type {
EXPR_NULL_CHECK,
EXPR_ARRAY_SIZE_CHECK,
EXPR_MULTIARRAY_SIZE_CHECK,
+   EXPR_MIMIC_STACK_SLOT,
EXPR_LAST,  /* Not a real type. Keep this last. */
 };
 
@@ -235,6 +236,13 @@ struct expression {
 
/* EXPR_ARRAY_SIZE_CHECK and EXPR_MULTIARRAY_SIZE_CHECK */
struct tree_node *size_expr;
+
+   /* EXPR_MIMIC_STACK_SLOT */
+   struct {
+   char entry;
+   int slotnb;
+   };
+
};
 };
 
@@ -248,6 +256,13 @@ static inline enum expression_type expr_type(struct 
expression *expr)
return (expr->node.op & EXPR_TYPE_MASK) >> EXPR_TYPE_SHIFT;
 }
 
+static inline void expr_set_type(struct expression *expr, int type)
+{
+   unsigned long op = expr->node.op & ~EXPR_TYPE_MASK;
+   type <<= EXPR_TYPE_SHIFT;
+   expr->node.op = op | type;
+}
+
 static inline enum binary_operator expr_bin_op(struct expression *expr)
 {
return (expr->node.op & OP_MASK) >> OP_SHIFT;
@@ -268,6 +283,7 @@ struct expression *value_expr(enum vm_type, unsigned long 
long);
 struct expression *fvalue_expr(enum vm_type, double);
 struct expression *local_expr(enum vm_type, unsigned long);
 struct expression *temporary_expr(enum vm_type, struct var_info *, struct 
var_info *);
+struct expression *mimic_stack_expr(enum vm_type, int, int);
 struct expression *array_deref_expr(enum vm_type, struct expression *, struct 
expression *);
 struct expression *binop_expr(enum vm_type, enum binary_operator, struct 
expression *, struct expression *);
 struct expression *unary_op_expr(enum vm_type, enum unary_operator, struct 
expression *);
diff --git a/jit/expression.c b/jit/expression.c
index 8e4d736..a73217c 100644
--- a/jit/expression.c
+++ b/jit/expression.c
@@ -44,6 +44,7 @@ int expr_nr_kids(struct expression *expr)
case EXPR_NO_ARGS:
case EXPR_NEW:
case EXPR_EXCEPTION_REF:
+   case EXPR_MIMIC_STACK_SLOT:
return 0;
default:
assert(!"Invalid expression type");
@@ -134,6 +135,17 @@ struct expression *temporary_expr(enum vm_type vm_type, 
struct var_info *tmp_hig
return expr;
 }
 
+struct expression *mimic_stack_expr(enum vm_type vm_type, int entry, int 
slotnb)
+{
+   struct expression *expr = alloc_expression(EXPR_MIMIC_STACK_SLOT, 
vm_type);
+   if (expr) {
+   expr->entry = entry;
+   expr->slotnb = slotnb;
+   }
+
+   return expr;
+}
+
 struct expression *array_deref_expr(enum vm_type vm_type,
struct expression *arrayref,
struct expression *array_index)
diff --git a/jit/tree-printer.c b/jit/tree-printer.c
index c96c87b..7a8c32a 100644
--- a/jit/tree-printer.c
+++ b/jit/tree-printer.c
@@ -84,7 +84,7 @@ static int simple_expr(struct expression *expr)
 
return type == EXPR_VALUE || type == EXPR_FVALUE || type == EXPR_LOCAL
|| type == EXPR_TEMPORARY || type == EXPR_CLASS_FIELD
-   || type == EXPR_NO_ARGS || type == EXPR_EXCEPTION_REF;
+   || type == EXPR_NO_ARGS || type == EXPR_EXCEPTION_REF || type == 
EXPR_MIMIC_STACK_SLOT;
 }
 
 static int __tree_print(int, struct tree_node *, struct string *);
@@ -355,6 +355,12 @@ static int print_temporary_expr(int lvl, struct string 
*str,
  expr->tmp_high, expr->tmp_low);
 }
 
+static int print_mimic_stack_slot_expr(int lvl, struct string *str,
+   struct expression *expr)
+{
+   return str_append(str, "[mimic stack slot %d at %s]", expr->slotnb, 
expr->entry ? "entry" : "exit");
+}
+
 static int print_array_deref_expr(int lvl, struct string *str,
  struct expression *expr)
 {
@@ -807,7 +813,8 @@ static print_expr_fn expr_printers[] = {
[EXPR_EXCEPTION_REF] = print_exception_ref_expr,
[EXPR_NULL_CHECK] = print_null_check_expr,
[EXPR_ARRAY_SIZE_CHECK] = print_array_size_check_expr,
-   [EXPR_MULTIARRAY_SIZE_CHECK] = print_multiarray_size_check_expr
+   [EXPR_MULTIARRAY_SIZE_CHECK] = print_multiarray_size_check_expr,
+   [EXPR_MIMIC_STACK_SLOT] = print_mimic_stack_slot_expr,
 
 };
 
-- 
1.6.2.2



--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm

[PATCH 2/2] jit: set up bb predecessors in bb_add_successor

2009-06-24 Thread Arthur HUILLET
Signed-off-by: Arthur HUILLET 
---
 jit/basic-block.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/jit/basic-block.c b/jit/basic-block.c
index df984eb..5a4fa53 100644
--- a/jit/basic-block.c
+++ b/jit/basic-block.c
@@ -167,6 +167,7 @@ int __bb_add_neighbor(struct basic_block *new, struct 
basic_block ***array, unsi
 
 int bb_add_successor(struct basic_block *bb, struct basic_block *successor)
 {
+   __bb_add_neighbor(bb, &successor->predecessors, 
&successor->nr_predecessors);
return __bb_add_neighbor(successor, &bb->successors, 
&bb->nr_successors);
 }
 
-- 
1.6.2.2



--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


[PATCH 1/2] jit: add predecessors to basic block structure

2009-06-24 Thread Arthur HUILLET
The list of predecessors is not set yet, this is just the
infrastructure.

Signed-off-by: Arthur HUILLET 
---
 include/jit/basic-block.h |2 ++
 jit/basic-block.c |   32 +++-
 jit/trace-jit.c   |   23 +++
 test/jit/basic-block-assert.h |   22 +-
 4 files changed, 61 insertions(+), 18 deletions(-)

diff --git a/include/jit/basic-block.h b/include/jit/basic-block.h
index b555d9e..4919c95 100644
--- a/include/jit/basic-block.h
+++ b/include/jit/basic-block.h
@@ -24,6 +24,8 @@ struct basic_block {
unsigned long br_target_off;/* Branch target offset in bytecode 
insns. */
unsigned long nr_successors;
struct basic_block **successors;
+   unsigned long nr_predecessors;
+   struct basic_block **predecessors;
unsigned long mach_offset;
 
/* The mimic stack is used to simulate JVM operand stack at
diff --git a/jit/basic-block.c b/jit/basic-block.c
index 22b102a..df984eb 100644
--- a/jit/basic-block.c
+++ b/jit/basic-block.c
@@ -76,6 +76,7 @@ void free_basic_block(struct basic_block *bb)
free_stmt_list(&bb->stmt_list);
free_insn_list(&bb->insn_list);
free(bb->successors);
+   free(bb->predecessors);
free(bb->use_set);
free(bb->def_set);
free(bb->live_in_set);
@@ -112,6 +113,9 @@ struct basic_block *bb_split(struct basic_block *orig_bb, 
unsigned long offset)
new_bb->nr_successors = orig_bb->nr_successors;
orig_bb->nr_successors = 0;
 
+   new_bb->predecessors = NULL;
+   new_bb->nr_predecessors = 0;
+
if (orig_bb->has_branch) {
orig_bb->has_branch = false;
new_bb->has_branch = true;
@@ -142,25 +146,35 @@ void bb_add_insn(struct basic_block *bb, struct insn 
*insn)
list_add_tail(&insn->insn_list_node, &bb->insn_list);
 }
 
-int bb_add_successor(struct basic_block *bb, struct basic_block *successor)
+int __bb_add_neighbor(struct basic_block *new, struct basic_block ***array, 
unsigned long *nb)
 {
-   int new_size;
-   struct basic_block **new_successors;
+   unsigned long new_size;
+   struct basic_block **new_neighbors;
 
-   new_size = sizeof(struct basic_block *) * (bb->nr_successors + 1);
+   new_size = sizeof(struct basic_block *) * (*nb + 1);
 
-   new_successors = realloc(bb->successors, new_size);
-   if (new_successors == NULL)
+   new_neighbors = realloc(*array, new_size);
+   if (new_neighbors == NULL)
return -ENOMEM;
 
-   bb->successors = new_successors;
+   *array = new_neighbors;
 
-   bb->successors[bb->nr_successors] = successor;
-   bb->nr_successors++;
+   (*array)[*nb] = new;
+   (*nb)++;
 
return 0;
 }
 
+int bb_add_successor(struct basic_block *bb, struct basic_block *successor)
+{
+   return __bb_add_neighbor(successor, &bb->successors, 
&bb->nr_successors);
+}
+
+int bb_add_predecessor(struct basic_block *bb, struct basic_block *predecessor)
+{
+   return __bb_add_neighbor(predecessor, &bb->predecessors, 
&bb->nr_predecessors);
+}
+
 unsigned char *bb_native_ptr(struct basic_block *bb)
 {
return buffer_ptr(bb->b_parent->objcode) + bb->mach_offset;
diff --git a/jit/trace-jit.c b/jit/trace-jit.c
index c11a896..feb23d8 100644
--- a/jit/trace-jit.c
+++ b/jit/trace-jit.c
@@ -54,7 +54,7 @@ void trace_cfg(struct compilation_unit *cu)
struct basic_block *bb;
 
printf("Control Flow Graph:\n\n");
-   printf("  #:\t\tRange\t\tSuccessors\n");
+   printf("  #:\t\tRange\t\tSuccessors\t\tPredecessors\n");
 
for_each_basic_block(bb, &cu->bb_list) {
unsigned long i;
@@ -63,15 +63,30 @@ void trace_cfg(struct compilation_unit *cu)
if (bb->is_eh)
printf(" (eh)");
 
+   printf("\t");
+
for (i = 0; i < bb->nr_successors; i++) {
-   if (i == 0)
-   printf("\t");
-   else
+   if (i != 0)
printf(", ");
 
printf("%p", bb->successors[i]);
}
 
+   if (i == 0)
+   printf("none");
+
+   printf("\t");
+
+   for (i = 0; i < bb->nr_predecessors; i++) {
+   if (i != 0)
+   printf(", ");
+
+   printf("%p", bb->predecessors[i]);
+   }
+
+   if (i == 0)
+   printf("none");
+
printf("\n");
}
 
diff --git a/test/jit/basic-block-assert.h b/test/jit/basic-block-assert.h
index 8f00672..abec84c 100644
--- a/test/jit/basic-block-assert.h
+++ b/test/jit/basic-block-assert.h
@@ -12,16 +12,28 @@ static void inline assert_basic_block(struct 
compilation_unit *parent,
assert_int_equals(end, bb->e

[PATCH] bc2ir: fix refcount bug in spill_expression

2009-06-24 Thread Arthur HUILLET
Signed-off-by: Arthur HUILLET 
---
 jit/bytecode-to-ir.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/jit/bytecode-to-ir.c b/jit/bytecode-to-ir.c
index 76fd5a4..862a335 100644
--- a/jit/bytecode-to-ir.c
+++ b/jit/bytecode-to-ir.c
@@ -143,7 +143,7 @@ static int spill_expression(struct basic_block *bb,
 * And add a reload expression that is put on the mimic stack of
 * successor basic blocks.
 */
-   stack_push(reload_stack, tmp);
+   stack_push(reload_stack, expr_get(tmp));
 
return 0;
 }
-- 
1.6.2.2



--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


[PATCH 2/7] vm: replace signal_from_jit_method() with signal_from_native()

2009-06-24 Thread Tomek Grabiec
The rationale for this is the same as for
commit 3d406995e21bf1695f6abc743fb37d16cc387f9e
("jit: remove is_jit_method() and introduce is_native()")

Signed-off-by: Tomek Grabiec 
---
 arch/x86/include/arch/signal.h |2 +-
 arch/x86/signal.c  |9 ++---
 vm/signal.c|8 ++--
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/arch/signal.h b/arch/x86/include/arch/signal.h
index 1940a34..69406cd 100644
--- a/arch/x86/include/arch/signal.h
+++ b/arch/x86/include/arch/signal.h
@@ -19,7 +19,7 @@
 
 struct compilation_unit;
 
-bool signal_from_jit_method(void *ctx);
+bool signal_from_native(void *ctx);
 struct compilation_unit *get_signal_source_cu(void *ctx);
 
 #endif
diff --git a/arch/x86/signal.c b/arch/x86/signal.c
index 61d7eba..f36464c 100644
--- a/arch/x86/signal.c
+++ b/arch/x86/signal.c
@@ -32,18 +32,13 @@
 
 #include 
 
-bool signal_from_jit_method(void *ctx)
+bool signal_from_native(void *ctx)
 {
ucontext_t *uc;
-   unsigned long ip;
 
uc = ctx;
-   ip = uc->uc_mcontext.gregs[REG_IP];
 
-   if (is_native(ip))
-   return false;
-
-   return true;
+   return is_native(uc->uc_mcontext.gregs[REG_IP]);
 }
 
 struct compilation_unit *get_signal_source_cu(void *ctx)
diff --git a/vm/signal.c b/vm/signal.c
index d52ea50..2453549 100644
--- a/vm/signal.c
+++ b/vm/signal.c
@@ -51,19 +51,23 @@ static void throw_null_pointer_exception(void)
 
 static void sigfpe_handler(int sig, siginfo_t *si, void *ctx)
 {
-   if (signal_from_jit_method(ctx) && si->si_code == FPE_INTDIV) {
+   if (signal_from_native(ctx))
+   goto exit;
+
+   if (si->si_code == FPE_INTDIV) {
if (install_signal_bh(ctx, throw_arithmetic_exception) == 0)
return;
 
fprintf(stderr, "%s: install_signal_bh() failed.\n", __func__);
}
 
+ exit:
print_backtrace_and_die(sig, si, ctx);
 }
 
 static void sigsegv_handler(int sig, siginfo_t *si, void *ctx)
 {
-   if (!signal_from_jit_method(ctx))
+   if (signal_from_native(ctx))
goto exit;
 
/* Assume that zero-page access is caused by dereferencing a
-- 
1.6.0.6


--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


[PATCH 5/7] vm: the foundation for java stack trace collecting

2009-06-24 Thread Tomek Grabiec
A number of utility functions are introduced for backtrace traversal
to assist java stack trace collecting. Only JIT methods and VM natives
should appear in stack trace so all native functions and trampolines
must be filtered out.

A new per-thread variable bottom_stack_frame is introduced to detect
when to stop tracig back. It is set to a native frame pointer of the
function that calls the main() method.

Signed-off-by: Tomek Grabiec 
---
 Makefile|3 +-
 arch/x86/include/arch/stack-frame.h |   18 +++--
 arch/x86/stack-frame.c  |   17 
 include/vm/stack-trace.h|   39 +
 test/arch-x86/stack-frame-test_32.c |6 ++
 vm/jato.c   |4 +
 vm/stack-trace.c|  160 +++
 7 files changed, 240 insertions(+), 7 deletions(-)
 create mode 100644 include/vm/stack-trace.h
 create mode 100644 vm/stack-trace.c

diff --git a/Makefile b/Makefile
index 76fc6b9..1d39741 100644
--- a/Makefile
+++ b/Makefile
@@ -104,7 +104,8 @@ VM_OBJS = \
vm/class.o  \
vm/list.o   \
vm/radix-tree.o \
-   vm/guard-page.o
+   vm/guard-page.o \
+   vm/stack-trace.o
 
 JAMVM_OBJS = \
vm/jato.o   \
diff --git a/arch/x86/include/arch/stack-frame.h 
b/arch/x86/include/arch/stack-frame.h
index 3813668..e9b2ad9 100644
--- a/arch/x86/include/arch/stack-frame.h
+++ b/arch/x86/include/arch/stack-frame.h
@@ -8,13 +8,19 @@ struct methodblock;
 struct expression;
 struct compilation_unit;
 
+struct native_stack_frame {
+   void *prev; /* previous stack frame link */
+   unsigned long return_address;
+   unsigned long args[0];
+} __attribute__((packed));
+
 struct jit_stack_frame {
-   struct jit_stack_frame *prev;
-   unsigned long old_ebx;
-   unsigned long old_esi;
-   unsigned long old_edi;
-   unsigned long return_address;
-   unsigned long args[0];
+   void *prev; /* previous stack frame link */
+   unsigned long old_ebx;
+   unsigned long old_esi;
+   unsigned long old_edi;
+   unsigned long return_address;
+   unsigned long args[0];
 } __attribute__((packed));
 
 unsigned long frame_local_offset(struct methodblock *, struct expression *);
diff --git a/arch/x86/stack-frame.c b/arch/x86/stack-frame.c
index 1754592..dc8ff82 100644
--- a/arch/x86/stack-frame.c
+++ b/arch/x86/stack-frame.c
@@ -26,6 +26,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -100,3 +101,19 @@ unsigned long cu_frame_locals_offset(struct 
compilation_unit *cu)
unsigned long frame_size = frame_locals_size(cu->stack_frame);
return frame_size * sizeof(unsigned long);
 }
+
+/*
+ * Checks whether given native function was called from jit trampoline
+ * code. It checks whether return address points after a relative call
+ * to jit_magic_trampoline, which is typical for trampolines.
+ */
+bool called_from_jit_trampoline(struct native_stack_frame *frame)
+{
+   void **call_rel_target_p;
+   void *call_target;
+
+   call_rel_target_p = (void **)(frame->return_address - sizeof(void*));
+   call_target = *call_rel_target_p + frame->return_address;
+
+   return call_target == &jit_magic_trampoline;
+}
diff --git a/include/vm/stack-trace.h b/include/vm/stack-trace.h
new file mode 100644
index 000..5064ecf
--- /dev/null
+++ b/include/vm/stack-trace.h
@@ -0,0 +1,39 @@
+#ifndef JATO_VM_STACK_TRACE_H
+#define JATO_VM_STACK_TRACE_H
+
+#include 
+#include 
+
+#include 
+
+/*
+ * Points to a native stack frame that is considered as bottom-most
+ * for given thread.
+ */
+extern __thread struct native_stack_frame *bottom_stack_frame;
+
+struct stack_trace_elem {
+   /* Holds instruction address of this stack trace element. */
+   unsigned long addr;
+
+   /*
+* If true then @frame has format of struct native_stack_frame
+* and struct jit_stack_frame otherwise.
+*/
+   bool is_native;
+
+   /* If true then frame belongs to a trampoline */
+   bool is_trampoline;
+
+   /* Points to a stack frame of this stack trace element. */
+   void *frame;
+};
+
+int init_stack_trace_elem(struct stack_trace_elem *elem);
+int get_prev_stack_trace_elem(struct stack_trace_elem *elem);
+int skip_frames_from_class(struct stack_trace_elem *elem, struct object 
*class);
+int get_stack_trace_depth(struct stack_trace_elem *elem);
+
+bool called_from_jit_trampoline(struct native_stack_frame *frame);
+
+#endif /* JATO_VM_STACK_TRACE_H */
diff --git a/test/arch-x86/stack-frame-test_32.c 
b/test/arch-x86/stack-frame-test_32.c
index db53f06..1fd5b6a 100644
--- a/test/arch-x86/stack-frame-test_32.c
+++ b/test/arch-x86/stack-frame-test_32.c
@@ -8,6 +8,12 @@
 #include 
 #include 
 
+/* Stub required by called_from_jit_trampoline() in arch/x86/stack-frame.c */
+void *jit_magic_trampoline(struct compilation_unit *cu)
+{

[PATCH 4/7] vm: put all functions implementing virtual machine native methods in a separate section

2009-06-24 Thread Tomek Grabiec
All VM natives should be placed in a .vm_native section to allow
stack traversal functions to distinguish between regular native functions
and native functions which implement native java methods. The former
ones do not appear in stack trace but the latter do.

Signed-off-by: Tomek Grabiec 
---
 Makefile |3 +-
 arch/x86/jato_32.ld  |  199 ++
 include/vm/natives.h |   17 
 vm/jato.c|4 +-
 4 files changed, 220 insertions(+), 3 deletions(-)
 create mode 100644 arch/x86/jato_32.ld

diff --git a/Makefile b/Makefile
index 1161405..76fc6b9 100644
--- a/Makefile
+++ b/Makefile
@@ -39,6 +39,7 @@ endif
 export ARCH_CFLAGS
 
 ARCH_CONFIG=arch/$(ARCH)/include/arch/config$(ARCH_POSTFIX).h
+LINKER_SCRIPT=arch/$(ARCH)/jato$(ARCH_POSTFIX).ld
 
 # Make the build silent by default
 V =
@@ -193,7 +194,7 @@ arch/$(ARCH)/insn-selector$(ARCH_POSTFIX).c: FORCE
 
 $(PROGRAM): lib monoburg $(JAMVM_ARCH_H) compile
$(E) "  CC  " $@
-   $(Q) $(CC) $(DEFAULT_CFLAGS) $(CFLAGS) $(OBJS) -o $(PROGRAM) $(LIBS) 
$(DEFAULT_LIBS)
+   $(Q) $(CC) -T $(LINKER_SCRIPT) $(DEFAULT_CFLAGS) $(CFLAGS) $(OBJS) -o 
$(PROGRAM) $(LIBS) $(DEFAULT_LIBS)
 
 compile: $(OBJS)
 
diff --git a/arch/x86/jato_32.ld b/arch/x86/jato_32.ld
new file mode 100644
index 000..083ea62
--- /dev/null
+++ b/arch/x86/jato_32.ld
@@ -0,0 +1,199 @@
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = 0x08048000); . = 0x08048000 + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  .hash   : { *(.hash) }
+  .gnu.hash   : { *(.gnu.hash) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .gnu.version: { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rel.dyn:
+{
+  *(.rel.init)
+  *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+  *(.rel.fini)
+  *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+  *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+  *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+  *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+  *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+  *(.rel.ctors)
+  *(.rel.dtors)
+  *(.rel.got)
+  *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+}
+  .rela.dyn   :
+{
+  *(.rela.init)
+  *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+  *(.rela.fini)
+  *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+  *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+  *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+  *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+  *(.rela.ctors)
+  *(.rela.dtors)
+  *(.rela.got)
+  *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+}
+  .rel.plt: { *(.rel.plt) }
+  .rela.plt   : { *(.rela.plt) }
+  .init   :
+  {
+KEEP (*(.init))
+  } =0x90909090
+  .plt: { *(.plt) }
+  .text   :
+  {
+*(.text .stub .text.* .gnu.linkonce.t.*)
+KEEP (*(.text.*personality*))
+/* .gnu.warning sections are handled specially by elf32.em.  */
+*(.gnu.warning)
+  } =0x90909090
+  .fini   :
+  {
+KEEP (*(.fini))
+  } =0x90909090
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1: { *(.rodata1) }
+  .eh_frame_hdr : { *(.eh_frame_hdr) }
+  .eh_frame   : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+ the same address within the page on the next page up.  */
+  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & 
(CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), 
CONSTANT (COMMONPAGESIZE));
+  /* Exception handling  */
+  .eh_frame   : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  /* Thread Local Storage sections  */
+  .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  .preinit_array :
+  {
+PROVIDE_HIDDEN (__preinit_array_start = .);
+KEEP (*(.preinit_array))
+PROVIDE_HIDDEN (__preinit_array_end = .);
+  }
+  .init_array :
+  {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+  }
+  .fini_array :
+  {
+PROVIDE_HIDDEN (__fini_array_start = .);
+KEEP (*(.fini_array))
+KEEP (*(SORT(.fini_array.*)))
+PROVIDE_HIDDEN (__fini_array_end = .);
+  }
+  .ctors  :
+  {
+/* gcc uses crtbegin.o to find the start of
+   

[PATCH 6/7] vm: support for stack trace printing

2009-06-24 Thread Tomek Grabiec
The natives VMThrowable.fillInStackTrace and VMThrowable.getStackTrace
are implemented. The stack trace can not be printed yet by invoking
printStackTrace() on java.lang.Throwable instance because jato cannot
execute PrintStream.print() yet. The stack trace can be however
printed when printStackTrace() is executed by JamVM which happens when
exception is thrown out of main() method.

Signed-off-by: Tomek Grabiec 
---
 include/jit/bc-offset-mapping.h |1 +
 include/vm/stack-trace.h|   11 ++
 jit/bc-offset-mapping.c |   14 +++
 vm/jato.c   |   17 +--
 vm/stack-trace.c|  238 +++
 5 files changed, 270 insertions(+), 11 deletions(-)

diff --git a/include/jit/bc-offset-mapping.h b/include/jit/bc-offset-mapping.h
index c47ea51..b6d76a6 100644
--- a/include/jit/bc-offset-mapping.h
+++ b/include/jit/bc-offset-mapping.h
@@ -13,5 +13,6 @@ unsigned long native_ptr_to_bytecode_offset(struct 
compilation_unit *cu,
 void print_bytecode_offset(unsigned long bc_offset, struct string *str);
 void tree_patch_bc_offset(struct tree_node *node, unsigned long bc_offset);
 bool all_insn_have_bytecode_offset(struct compilation_unit *cu);
+int bytecode_offset_to_line_no(struct methodblock *mb, unsigned long 
bc_offset);
 
 #endif
diff --git a/include/vm/stack-trace.h b/include/vm/stack-trace.h
index 5064ecf..72d192a 100644
--- a/include/vm/stack-trace.h
+++ b/include/vm/stack-trace.h
@@ -2,6 +2,9 @@
 #define JATO_VM_STACK_TRACE_H
 
 #include 
+
+#include 
+#include 
 #include 
 
 #include 
@@ -29,10 +32,18 @@ struct stack_trace_elem {
void *frame;
 };
 
+void init_stack_trace_printing(void);
 int init_stack_trace_elem(struct stack_trace_elem *elem);
 int get_prev_stack_trace_elem(struct stack_trace_elem *elem);
 int skip_frames_from_class(struct stack_trace_elem *elem, struct object 
*class);
 int get_stack_trace_depth(struct stack_trace_elem *elem);
+struct object *get_stack_trace(struct stack_trace_elem *);
+struct object *get_stack_trace_from_ctx(void *ctx);
+struct object *convert_stack_trace(struct object *vmthrowable);
+struct object *new_stack_trace_element(struct methodblock *, unsigned long);
+struct object * __vm_native vm_throwable_fill_in_stack_trace(struct object *);
+struct object * __vm_native vm_throwable_get_stack_trace(struct object *, 
struct object *);
+void set_throwable_vmstate(struct object *throwable, struct object *vmstate);
 
 bool called_from_jit_trampoline(struct native_stack_frame *frame);
 
diff --git a/jit/bc-offset-mapping.c b/jit/bc-offset-mapping.c
index be3756d..f7b097e 100644
--- a/jit/bc-offset-mapping.c
+++ b/jit/bc-offset-mapping.c
@@ -116,3 +116,17 @@ bool all_insn_have_bytecode_offset(struct compilation_unit 
*cu)
 
return true;
 }
+
+int bytecode_offset_to_line_no(struct methodblock *mb, unsigned long bc_offset)
+{
+   int i;
+
+   if(mb->line_no_table_size == 0 || bc_offset == BC_OFFSET_UNKNOWN)
+   return -1;
+
+   i = mb->line_no_table_size - 1;
+   while (i && bc_offset < mb->line_no_table[i].start_pc)
+   i--;
+
+   return mb->line_no_table[i].line_no;
+}
diff --git a/vm/jato.c b/vm/jato.c
index 10e3353..00e71c1 100644
--- a/vm/jato.c
+++ b/vm/jato.c
@@ -274,21 +274,14 @@ static void __vm_native vm_runtime_exit(int status)
exitVM(status);
 }
 
-/*
- * This stub is needed by java.lang.VMThrowable constructor to work. It should
- * return java.lang.VMState instance, or null in which case no stack trace will
- * be printed by printStackTrace() method.
- */
-static struct object * __vm_native vm_fill_in_stack_trace(struct object 
*object)
-{
-   return NULL;
-}
-
 static void jit_init_natives(void)
 {
vm_register_native("java/lang/VMRuntime", "exit", vm_runtime_exit);
vm_register_native("jato/internal/VM", "exit", vm_runtime_exit);
-   vm_register_native("java/lang/VMThrowable", "fillInStackTrace", 
vm_fill_in_stack_trace);
+   vm_register_native("java/lang/VMThrowable", "fillInStackTrace",
+   vm_throwable_fill_in_stack_trace);
+   vm_register_native("java/lang/VMThrowable", "getStackTrace",
+   vm_throwable_get_stack_trace);
 }
 
 int main(int argc, char *argv[]) {
@@ -321,6 +314,8 @@ int main(int argc, char *argv[]) {
 exitVM(1);
 }
 
+init_stack_trace_printing();
+
 mainThreadSetContextClassLoader(system_loader);
 
 for(cpntr = argv[class_arg]; *cpntr; cpntr++)
diff --git a/vm/stack-trace.c b/vm/stack-trace.c
index 773b501..a92e8f4 100644
--- a/vm/stack-trace.c
+++ b/vm/stack-trace.c
@@ -25,12 +25,66 @@
  */
 #include 
 #include 
+#include 
 
+#include 
 #include 
+#include 
 #include 
 
+#include 
+
 __thread struct native_stack_frame *bottom_stack_frame;
 
+static struct object *vmthrowable_class;
+static struct object *throwable_class;
+static struct object *ste_class;
+static struct object *ste_array_class;
+static int backtrace_offset;
+static in

[PATCH 7/7] jit: fix condition on which fixup_direct_calls() is called from jit_magic_trampoline()

2009-06-24 Thread Tomek Grabiec
fixup_direct_calls() should be called whenever return address (ret) is
not NULL, it should not depend on whether compilation unit is marked
as compiled. That's because native methods are never marked as
compiled and yet we can fixup the calls.

Signed-off-by: Tomek Grabiec 
---
 jit/trampoline.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/jit/trampoline.c b/jit/trampoline.c
index 1fe6503..833a7d5 100644
--- a/jit/trampoline.c
+++ b/jit/trampoline.c
@@ -112,7 +112,7 @@ void *jit_magic_trampoline(struct compilation_unit *cu)
 * Therefore, do fixup for direct call sites unconditionally and fixup
 * vtables if method can be invoked via invokevirtual.
 */
-   if (cu->is_compiled)
+   if (ret)
fixup_direct_calls(method->trampoline, (unsigned long) ret);
 
pthread_mutex_unlock(&cu->mutex);
-- 
1.6.0.6


--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel


[PATCH 1/7] vm: move code creating exceptions out of signal handlers

2009-06-24 Thread Tomek Grabiec
It is not safe to execute jit code in signal handler context. One of
the reasons is that throwing-by-signal mechanisms don't work in code
executed from signal handler. That's becasue kernel will not execute
user defined signal handler for SIGSEGV when second signal occures
while executing the handler.

This issue is addressed by introducing "bottom halfs". These are
functions which are executed in normal context immediately after
signal handler returns. They are installed by manipulating ucontext_t
structure associated with signal handler.

Signed-off-by: Tomek Grabiec 
---
 arch/x86/signal.c   |   28 
 include/vm/signal.h |3 +++
 vm/signal.c |   45 +
 3 files changed, 52 insertions(+), 24 deletions(-)

diff --git a/arch/x86/signal.c b/arch/x86/signal.c
index 6b59881..61d7eba 100644
--- a/arch/x86/signal.c
+++ b/arch/x86/signal.c
@@ -30,6 +30,8 @@
 #include 
 #include 
 
+#include 
+
 bool signal_from_jit_method(void *ctx)
 {
ucontext_t *uc;
@@ -51,3 +53,29 @@ struct compilation_unit *get_signal_source_cu(void *ctx)
uc = ctx;
return get_cu_from_native_addr(uc->uc_mcontext.gregs[REG_IP]);
 }
+
+/**
+ * install_signal_bh - installs signal's bottom half function by
+ * modifying user context so that control will be returned to @bh
+ * when signal handler returns. When @bh function returns, the
+ * control should be returned to the source of the signal.
+ *
+ * @ctx: pointer to struct ucontext_t
+ * @bh: bottom half function to install
+ */
+int install_signal_bh(void *ctx, signal_bh_fn bh)
+{
+   unsigned long *stack;
+   ucontext_t *uc;
+
+   uc = ctx;
+
+   /* push return address on stack */
+   stack = (unsigned long*)uc->uc_mcontext.gregs[REG_SP] - 1;
+   *stack = uc->uc_mcontext.gregs[REG_IP];
+   uc->uc_mcontext.gregs[REG_SP] -= sizeof(unsigned long);
+
+   uc->uc_mcontext.gregs[REG_IP] = (unsigned long)bh;
+
+   return 0;
+}
diff --git a/include/vm/signal.h b/include/vm/signal.h
index 8aee067..dad9381 100644
--- a/include/vm/signal.h
+++ b/include/vm/signal.h
@@ -1,6 +1,9 @@
 #ifndef VM_SIGNAL_H
 #define VM_SIGNAL_H
 
+typedef void (*signal_bh_fn)(void);
+
 void setup_signal_handlers(void);
+int install_signal_bh(void *ctx, signal_bh_fn bh);
 
 #endif /* VM_SIGNAL_H */
diff --git a/vm/signal.c b/vm/signal.c
index 747276a..d52ea50 100644
--- a/vm/signal.c
+++ b/vm/signal.c
@@ -27,6 +27,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include 
@@ -35,25 +36,28 @@
 #include 
 #include 
 
+static void throw_arithmetic_exception(void)
+{
+   signal_new_exception("java/lang/ArithmeticException",
+"division by zero");
+   throw_from_native(0);
+}
+
+static void throw_null_pointer_exception(void)
+{
+   signal_new_exception("java/lang/NullPointerException", NULL);
+   throw_from_native(0);
+}
+
 static void sigfpe_handler(int sig, siginfo_t *si, void *ctx)
 {
if (signal_from_jit_method(ctx) && si->si_code == FPE_INTDIV) {
-   struct object *exception;
-
-   /* TODO: exception's stack trace should be filled using ctx */
-   exception = new_exception(
-   "java/lang/ArithmeticException", "division by zero");
-   if (exception == NULL) {
-   /* TODO: throw OutOfMemoryError */
-   fprintf(stderr, "%s: Out of memory\n", __func__);
-   goto exit;
-   }
+   if (install_signal_bh(ctx, throw_arithmetic_exception) == 0)
+   return;
 
-   throw_exception_from_signal(ctx, exception);
-   return;
+   fprintf(stderr, "%s: install_signal_bh() failed.\n", __func__);
}
 
- exit:
print_backtrace_and_die(sig, si, ctx);
 }
 
@@ -65,23 +69,16 @@ static void sigsegv_handler(int sig, siginfo_t *si, void 
*ctx)
/* Assume that zero-page access is caused by dereferencing a
   null pointer */
if ((unsigned long)si->si_addr < (unsigned long)getpagesize()) {
-   struct object *exception;
-
/* We must be extra caucious here because IP might be
   invalid */
if (get_signal_source_cu(ctx) == NULL)
goto exit;
 
-   /* TODO: exception's stack trace should be filled using ctx */
-   exception = new_exception("java/lang/NullPointerException", 
NULL);
-   if (exception == NULL) {
-   /* TODO: throw OutOfMemoryError */
-   fprintf(stderr, "%s: Out of memory\n", __func__);
-   goto exit;
-   }
+   if (install_signal_bh(ctx, throw_null_pointer_exception) == 0)
+   return;
 
-   throw_exception_from_signal(ctx, exception);
-   return;
+   fpr

[PATCH 3/7] vm: skip __cleanup_args if args_size is 0.

2009-06-24 Thread Tomek Grabiec

Signed-off-by: Tomek Grabiec 
---
 arch/x86/include/arch/stack-frame.h |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/arch/stack-frame.h 
b/arch/x86/include/arch/stack-frame.h
index 3f27fae..3813668 100644
--- a/arch/x86/include/arch/stack-frame.h
+++ b/arch/x86/include/arch/stack-frame.h
@@ -52,7 +52,7 @@ unsigned long cu_frame_locals_offset(struct compilation_unit 
*cu);
  */
 #ifdef CONFIG_X86_32
 #define __cleanup_args(args_size)  \
-   ({  \
+   if (args_size) {\
__asm__ volatile (  \
 "movl %%ebp, %%esi \n" \
 "addl %1, %%esi \n"\
@@ -78,10 +78,10 @@ unsigned long cu_frame_locals_offset(struct 
compilation_unit *cu);
 : "b" (args_size), "n"(2*sizeof(unsigned long))\
 : "%eax", "%edi", "%esi", "%ecx", "cc", "memory"   \
); \
-   })
+   }
 #else
 #define __cleanup_args(args_size)  \
-   ({  \
+   if (args_size) {\
__asm__ volatile (  \
 "movq %%rbp, %%rsi \n" \
 "addq %1, %%rsi \n"\
@@ -107,7 +107,7 @@ unsigned long cu_frame_locals_offset(struct 
compilation_unit *cu);
 : "b" (args_size), "n"(2*sizeof(unsigned long))\
 : "%rax", "%rdi", "%rsi", "%rcx", "cc", "memory"   \
); \
-   })
+   }
 #endif
 
 #endif
-- 
1.6.0.6


--
___
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel