Motivation: Exception manager will need to translate native
instruction pointers to bytecode offsets to select appropriate
exception handler from exception_table.

This solution uses a per-thread variable to store the current bytecode
offset, which is set before converting a bytecode and before selecting
instructions for a tree node. HIR (struct expression, struct statement)
and LIR (struct insn) entities upon allocation assign that variable's
value to 'bytecode_offset' field.

Signed-off-by: Tomek Grabiec <[email protected]>
---
 Makefile                            |    3 +-
 arch/x86/include/arch/instruction.h |    3 +
 arch/x86/insn-selector_32.brg       |    3 +
 arch/x86/instruction.c              |    2 +
 include/jit/bc-offset-mapping.h     |   19 ++++++
 include/jit/expression.h            |    5 ++
 include/jit/statement.h             |    4 +
 jit/bc-offset-mapping.c             |  114 +++++++++++++++++++++++++++++++++++
 jit/bytecode-to-ir.c                |    6 ++
 jit/expression.c                    |    2 +
 jit/spill-reload.c                  |    4 +
 jit/statement.c                     |    2 +
 test/arch-x86/Makefile              |    1 +
 test/include/arch/instruction.h     |    5 ++
 test/jit/Makefile                   |    1 +
 vm/jato.c                           |    2 +
 16 files changed, 175 insertions(+), 1 deletions(-)
 create mode 100644 include/jit/bc-offset-mapping.h
 create mode 100644 jit/bc-offset-mapping.c

diff --git a/Makefile b/Makefile
index 9dd15c9..ee2587f 100644
--- a/Makefile
+++ b/Makefile
@@ -79,7 +79,8 @@ JIT_OBJS = \
        jit/typeconv-bc.o       \
        jit/vtable.o            \
        jit/fixup-site.o        \
-       jit/exception.o
+       jit/exception.o         \
+       jit/bc-offset-mapping.o
 
 VM_OBJS = \
        vm/bitset.o             \
diff --git a/arch/x86/include/arch/instruction.h 
b/arch/x86/include/arch/instruction.h
index ec5f4cb..a27b24b 100644
--- a/arch/x86/include/arch/instruction.h
+++ b/arch/x86/include/arch/instruction.h
@@ -120,6 +120,9 @@ struct insn {
        /* Position of this instruction in LIR.  */
        unsigned long lir_pos;
        bool escaped;
+
+       /* Offset of bytecode instruction from which this one comes from */
+       unsigned long bytecode_offset;
 };
 
 static inline unsigned long lir_position(struct use_position *reg)
diff --git a/arch/x86/insn-selector_32.brg b/arch/x86/insn-selector_32.brg
index 9dcc26c..46fe6a0 100644
--- a/arch/x86/insn-selector_32.brg
+++ b/arch/x86/insn-selector_32.brg
@@ -13,6 +13,7 @@
 #include <jit/emulate.h>
 #include <jit/expression.h>
 #include <jit/statement.h>
+#include <jit/bc-offset-mapping.h>
 
 #include <arch/instruction.h>
 #include <arch/stack-frame.h>
@@ -1313,7 +1314,9 @@ static void emit_code(struct basic_block *bb, MBState 
*state, int goal)
        for (i = 0; nts[i]; i++)
                emit_code(bb, kids[i], nts[i]);
 
+       set_current_bytecode_offset(tree_bytecode_offset(state->tree));
        mono_burg_emit(ern, state, state->tree, bb);
+       set_current_bytecode_offset(BC_OFFSET_UNKNOWN);
 }
 
 static void free_state(MBState *state)
diff --git a/arch/x86/instruction.c b/arch/x86/instruction.c
index 624651a..4d9418f 100644
--- a/arch/x86/instruction.c
+++ b/arch/x86/instruction.c
@@ -25,6 +25,7 @@
  */
 
 #include <arch/instruction.h>
+#include <jit/bc-offset-mapping.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -37,6 +38,7 @@ struct insn *alloc_insn(enum insn_type type)
                INIT_LIST_HEAD(&insn->insn_list_node);
                INIT_LIST_HEAD(&insn->branch_list_node);
                insn->type = type;
+               insn->bytecode_offset = get_current_bytecode_offset();
        }
        return insn;
 }
diff --git a/include/jit/bc-offset-mapping.h b/include/jit/bc-offset-mapping.h
new file mode 100644
index 0000000..2485a39
--- /dev/null
+++ b/include/jit/bc-offset-mapping.h
@@ -0,0 +1,19 @@
+#ifndef _BC_OFFSET_MAPPING_
+#define _BC_OFFSET_MAPPING_
+
+#include <jit/compilation-unit.h>
+#include <jit/tree-node.h>
+#include <vm/string.h>
+#include <limits.h>
+
+#define BC_OFFSET_UNKNOWN ULONG_MAX
+
+void init_bytecode_offset_mapping(void);
+unsigned long get_current_bytecode_offset(void);
+void set_current_bytecode_offset(unsigned long bc_offset);
+unsigned long native_ptr_to_bytecode_offset(struct compilation_unit *cu,
+                                           unsigned char *native_ptr);
+void print_bytecode_offset(unsigned long bc_offset, struct string *str);
+unsigned long tree_bytecode_offset(struct tree_node *node);
+
+#endif
diff --git a/include/jit/expression.h b/include/jit/expression.h
index cba8209..81e8989 100644
--- a/include/jit/expression.h
+++ b/include/jit/expression.h
@@ -76,6 +76,11 @@ enum unary_operator {
 struct expression {
        unsigned long refcount;
        enum vm_type vm_type;
+
+       /* Offset of bytecode instruction from which this expression
+          comes from */
+       unsigned long bytecode_offset;
+
        union {
                struct tree_node node;
 
diff --git a/include/jit/statement.h b/include/jit/statement.h
index f87abc0..cdbc2f6 100644
--- a/include/jit/statement.h
+++ b/include/jit/statement.h
@@ -23,6 +23,10 @@ enum statement_type {
 };
 
 struct statement {
+       /* Offset of bytecode instruction from which this statement
+          comes from */
+       unsigned long bytecode_offset;
+
        union {
                struct tree_node node;
 
diff --git a/jit/bc-offset-mapping.c b/jit/bc-offset-mapping.c
new file mode 100644
index 0000000..e6a9906
--- /dev/null
+++ b/jit/bc-offset-mapping.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2009 Tomasz Grabiec
+ *
+ * This file is released under the GPL version 2 with the following
+ * clarification and special exception:
+ *
+ *     Linking this library statically or dynamically with other modules is
+ *     making a combined work based on this library. Thus, the terms and
+ *     conditions of the GNU General Public License cover the whole
+ *     combination.
+ *
+ *     As a special exception, the copyright holders of this library give you
+ *     permission to link this library with independent modules to produce an
+ *     executable, regardless of the license terms of these independent
+ *     modules, and to copy and distribute the resulting executable under terms
+ *     of your choice, provided that you also meet, for each linked independent
+ *     module, the terms and conditions of the license of that module. An
+ *     independent module is a module which is not derived from or based on
+ *     this library. If you modify this library, you may extend this exception
+ *     to your version of the library, but you are not obligated to do so. If
+ *     you do not wish to do so, delete this exception statement from your
+ *     version.
+ *
+ * Please refer to the file LICENSE for details.
+ */
+
+#include <jit/bc-offset-mapping.h>
+#include <jit/statement.h>
+#include <jit/expression.h>
+
+#include <vm/string.h>
+#include <vm/buffer.h>
+
+#include <arch/instruction.h>
+
+#include <pthread.h>
+#include <malloc.h>
+
+static pthread_key_t bytecode_offset_key;
+
+static void key_descructor(void *value)
+{
+       free(value);
+       pthread_setspecific(bytecode_offset_key, NULL);
+}
+
+void init_bytecode_offset_mapping(void)
+{
+       pthread_key_create(&bytecode_offset_key, key_descructor);
+}
+
+static unsigned long *get_current(void)
+{
+       unsigned long *current;
+
+       current = pthread_getspecific(bytecode_offset_key);
+       if (current == NULL) {
+               current = malloc(sizeof(unsigned long));
+               pthread_setspecific(bytecode_offset_key, current);
+
+               *current = BC_OFFSET_UNKNOWN;
+       }
+
+       return current;
+}
+
+unsigned long get_current_bytecode_offset(void)
+{
+       unsigned long *current = get_current();
+
+       return *current;
+}
+
+void set_current_bytecode_offset(unsigned long bytecode_offset)
+{
+       unsigned long *current = get_current();
+
+       *current = bytecode_offset;
+}
+
+unsigned long native_ptr_to_bytecode_offset(struct compilation_unit *cu,
+                                           unsigned char *native_ptr)
+{
+       unsigned char *method_ptr = buffer_ptr(cu->objcode);
+       struct basic_block *bb;
+       struct insn *insn;
+
+       for_each_basic_block(bb, &cu->bb_list) {
+               for_each_insn(insn, &bb->insn_list) {
+                       if (method_ptr + insn->mach_offset == native_ptr)
+                               return insn->bytecode_offset;
+               }
+       }
+
+       return BC_OFFSET_UNKNOWN;
+}
+
+void print_bytecode_offset(unsigned long bytecode_offset, struct string *str)
+{
+       if (bytecode_offset == BC_OFFSET_UNKNOWN)
+               str_append(str, "?");
+       else {
+               static char buf[32];
+               sprintf(buf, "%ld", bytecode_offset);
+               str_append(str, buf);
+       }
+}
+
+unsigned long tree_bytecode_offset(struct tree_node *node)
+{
+       if (node_is_stmt(node))
+               return to_stmt(node)->bytecode_offset;
+
+       return to_expr(node)->bytecode_offset;
+}
diff --git a/jit/bytecode-to-ir.c b/jit/bytecode-to-ir.c
index 8680efa..854d28b 100644
--- a/jit/bytecode-to-ir.c
+++ b/jit/bytecode-to-ir.c
@@ -11,6 +11,7 @@
 #include <jit/compiler.h>
 #include <jit/statement.h>
 #include <jit/expression.h>
+#include <jit/bc-offset-mapping.h>
 
 #include <vm/bytecode.h>
 #include <vm/bytecodes.h>
@@ -297,9 +298,14 @@ int convert_to_ir(struct compilation_unit *cu)
        int err = 0;
 
        while (ctx.offset < ctx.code_size) {
+               set_current_bytecode_offset(ctx.offset);
+
                err = parse_bytecode_insn(&ctx);
                if (err)
                        break;
        }
+
+       set_current_bytecode_offset(BC_OFFSET_UNKNOWN);
+
        return err;
 }
diff --git a/jit/expression.c b/jit/expression.c
index 8a37502..42dce3f 100644
--- a/jit/expression.c
+++ b/jit/expression.c
@@ -6,6 +6,7 @@
  */
 
 #include <jit/expression.h>
+#include <jit/bc-offset-mapping.h>
 #include <vm/vm.h>
 #include <vm/method.h>
 #include <stdlib.h>
@@ -21,6 +22,7 @@ struct expression *alloc_expression(enum expression_type type,
                expr->node.op = type << EXPR_TYPE_SHIFT;
                expr->vm_type = vm_type;
                expr->refcount = 1;
+               expr->bytecode_offset = get_current_bytecode_offset();
        }
        return expr;
 }
diff --git a/jit/spill-reload.c b/jit/spill-reload.c
index 14e1758..f8d3230 100644
--- a/jit/spill-reload.c
+++ b/jit/spill-reload.c
@@ -63,6 +63,8 @@ static int insert_spill_insn(struct live_interval *interval, 
struct compilation_
 
        interval->spill_slot = slot;
 
+       spill->bytecode_offset = last->bytecode_offset;
+
        list_add(&spill->insn_list_node, &last->insn_list_node);
 
        return 0;
@@ -89,6 +91,8 @@ static int insert_reload_insn(struct live_interval *interval, 
struct compilation
        if (!reload)
                return -ENOMEM;
 
+       reload->bytecode_offset = first->bytecode_offset;
+
        list_add_tail(&reload->insn_list_node, &first->insn_list_node);
 
        return 0;
diff --git a/jit/statement.c b/jit/statement.c
index 0c8ecf4..1e590d2 100644
--- a/jit/statement.c
+++ b/jit/statement.c
@@ -9,6 +9,7 @@
 #include <assert.h>
 #include <jit/expression.h>
 #include <jit/statement.h>
+#include <jit/bc-offset-mapping.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -19,6 +20,7 @@ struct statement *alloc_statement(enum statement_type type)
                memset(stmt, 0, sizeof *stmt);
                INIT_LIST_HEAD(&stmt->stmt_list_node);
                stmt->node.op = type << STMT_TYPE_SHIFT;
+               stmt->bytecode_offset = get_current_bytecode_offset();
        }
 
        return stmt;
diff --git a/test/arch-x86/Makefile b/test/arch-x86/Makefile
index 5014de5..8ab76d4 100644
--- a/test/arch-x86/Makefile
+++ b/test/arch-x86/Makefile
@@ -43,6 +43,7 @@ OBJS = \
        ../../jit/statement.o \
        ../../jit/tree-printer.o \
        ../../jit/fixup-site.o \
+       ../../jit/bc-offset-mapping.o \
        ../../arch/x86/emit-code$(ARCH_POSTFIX).o \
        ../../arch/x86/instruction.o \
        ../../arch/x86/insn-selector$(ARCH_POSTFIX).o \
diff --git a/test/include/arch/instruction.h b/test/include/arch/instruction.h
index d9776ca..bf61c74 100644
--- a/test/include/arch/instruction.h
+++ b/test/include/arch/instruction.h
@@ -52,8 +52,13 @@ struct insn {
                 struct operand operand;
         };
         struct list_head insn_list_node;
+       /* Offset in machine code.  */
+       unsigned long mach_offset;
        /* Position of this instruction in LIR.  */
        unsigned long           lir_pos;
+
+       /* Offset of bytecode instruction from which this one comes from */
+       unsigned long bytecode_offset;
 };
 
 static inline unsigned long lir_position(struct use_position *reg)
diff --git a/test/jit/Makefile b/test/jit/Makefile
index 1fb21d9..89d1489 100644
--- a/test/jit/Makefile
+++ b/test/jit/Makefile
@@ -34,6 +34,7 @@ OBJS = \
        ../../jit/tree-printer.o \
        ../../jit/args.o \
        ../../jit/exception.o \
+       ../../jit/bc-offset-mapping.o \
        ../libharness/libharness.o \
        ../jamvm/alloc-stub.o \
        ../jamvm/resolve-stub.o \
diff --git a/vm/jato.c b/vm/jato.c
index 8598648..f52bb40 100644
--- a/vm/jato.c
+++ b/vm/jato.c
@@ -29,6 +29,7 @@
 #include <vm/signal.h>
 #include <vm/vm.h>
 #include <jit/compiler.h>
+#include <jit/bc-offset-mapping.h>
 
 #ifdef USE_ZIP
 #define BCP_MESSAGE "<jar/zip files and directories separated by :>"
@@ -293,6 +294,7 @@ int main(int argc, char *argv[]) {
     exe_name = argv[0];
 
     setup_signal_handlers();
+    init_bytecode_offset_mapping();
 
     setDefaultInitArgs(&args);
     int class_arg = parseCommandLine(argc, argv, &args);
-- 
1.6.0.6


------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations 
Conference from O'Reilly Media. Velocity features a full day of 
expert-led, hands-on workshops and two days of sessions from industry 
leaders in dedicated Performance & Operations tracks. Use code vel09scf 
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
_______________________________________________
Jatovm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to