Browsing the insn list is ineffective way of bytecode offset lookup.
Those structures might also be freed after compilation in the future.

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/x86/disassemble.c          |    2 +-
 include/jit/bc-offset-mapping.h |    5 +-
 include/jit/compilation-unit.h  |    6 +++
 jit/bc-offset-mapping.c         |   80 +++++++++++++++++++++++++++-----------
 jit/compilation-unit.c          |    7 +++
 jit/compiler.c                  |    4 ++
 jit/exception.c                 |    2 +-
 jit/trace-jit.c                 |    2 +-
 vm/stack-trace.c                |    6 +-
 9 files changed, 83 insertions(+), 31 deletions(-)

diff --git a/arch/x86/disassemble.c b/arch/x86/disassemble.c
index 095ebac..bdd068c 100644
--- a/arch/x86/disassemble.c
+++ b/arch/x86/disassemble.c
@@ -84,7 +84,7 @@ unsigned char *disassinstr(struct compilation_unit *cu, 
unsigned char *code)
                struct string *str = alloc_str();
                unsigned long bc_offset;
 
-               bc_offset = native_ptr_to_bytecode_offset(cu, code);
+               bc_offset = jit_lookup_bc_offset(cu, code);
                print_bytecode_offset(bc_offset, str);
                trace_printf("[ %5s ]", str->value);
                free_str(str);
diff --git a/include/jit/bc-offset-mapping.h b/include/jit/bc-offset-mapping.h
index 2b9086f..24ae41f 100644
--- a/include/jit/bc-offset-mapping.h
+++ b/include/jit/bc-offset-mapping.h
@@ -9,11 +9,12 @@
 
 #define BC_OFFSET_UNKNOWN ULONG_MAX
 
-unsigned long native_ptr_to_bytecode_offset(struct compilation_unit *cu,
-                                           unsigned char *native_ptr);
+unsigned long jit_lookup_bc_offset(struct compilation_unit *cu,
+                                  unsigned char *native_ptr);
 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 vm_method *mb, unsigned long bc_offset);
+int build_bc_offset_map(struct compilation_unit *cu);
 
 #endif
diff --git a/include/jit/compilation-unit.h b/include/jit/compilation-unit.h
index d3fff81..6f1ec12 100644
--- a/include/jit/compilation-unit.h
+++ b/include/jit/compilation-unit.h
@@ -63,6 +63,12 @@ struct compilation_unit {
         * code (not trampoline).
         */
        void *native_ptr;
+
+       /*
+        * This maps bytecode offset to every native address
+        * inside JIT code.
+        */
+       unsigned long *bc_offset_map;
 };
 
 struct compilation_unit *compilation_unit_alloc(struct vm_method *);
diff --git a/jit/bc-offset-mapping.c b/jit/bc-offset-mapping.c
index 00f3de9..ac92221 100644
--- a/jit/bc-offset-mapping.c
+++ b/jit/bc-offset-mapping.c
@@ -24,6 +24,8 @@
  * Please refer to the file LICENSE for details.
  */
 
+#include <errno.h>
+#include <malloc.h>
 #include <stdio.h>
 
 #include "jit/bc-offset-mapping.h"
@@ -54,43 +56,75 @@ void tree_patch_bc_offset(struct tree_node *node, unsigned 
long bc_offset)
 }
 
 /**
- * native_ptr_to_bytecode_offset - translates native instruction pointer
- *                                 to bytecode offset from which given
- *                                 instruction originates.
- * @cu: compilation unit of method containing @native_ptr.
- * @native_ptr: native instruction pointer to be translated.
+ * Constructs native to bytecode offset translation table.
+ * Must be called after compiltion is finished.
  */
-unsigned long native_ptr_to_bytecode_offset(struct compilation_unit *cu,
-                                           unsigned char *native_ptr)
+int build_bc_offset_map(struct compilation_unit *cu)
 {
-       unsigned long method_addr = (unsigned long)buffer_ptr(cu->objcode);
-       unsigned long offset;
+       unsigned long code_size;
        struct basic_block *bb;
        struct insn *insn;
-       struct insn *prev_insn = NULL;
+       struct insn *prev_insn;
 
-       if ((unsigned long)native_ptr < method_addr)
-               return BC_OFFSET_UNKNOWN;
+       code_size = buffer_offset(cu->objcode);
+       cu->bc_offset_map = malloc(sizeof(unsigned long) * code_size);
+       if (!cu->bc_offset_map)
+               return -ENOMEM;
 
-       offset = (unsigned long)native_ptr - method_addr;
+       /* Set all fields to unknown (ULONG_MAX) by default. */
+       memset(cu->bc_offset_map, 0xff, sizeof(unsigned long) * code_size);
+
+       prev_insn = NULL;
 
        for_each_basic_block(bb, &cu->bb_list) {
                for_each_insn(insn, &bb->insn_list) {
-                       if (insn->mach_offset == offset)
-                               return insn->bytecode_offset;
-
-                       if (insn->mach_offset > offset) {
-                               if (prev_insn &&
-                                   prev_insn->mach_offset <= offset)
-                                       return prev_insn->bytecode_offset;
-                               break;
-                       }
+                       /* We put bc-offset mapping not only for the
+                        * insn offset but also for the offset of last
+                        * insn byte. That's because for call site
+                        * bc-offset we pall for return address - 1.
+                        */
+                       if (prev_insn)
+                               cu->bc_offset_map[insn->mach_offset - 1] =
+                                       prev_insn->bytecode_offset;
+
+                       cu->bc_offset_map[insn->mach_offset] =
+                               insn->bytecode_offset;
 
                        prev_insn = insn;
                }
        }
 
-       return BC_OFFSET_UNKNOWN;
+       return 0;
+}
+
+/**
+ * native_ptr_to_bytecode_offset - translates native instruction pointer
+ *                                 to bytecode offset from which given
+ *                                 instruction originates.
+ * @cu: compilation unit of method containing @native_ptr.
+ * @native_ptr: native instruction pointer to be translated.
+ */
+unsigned long
+jit_lookup_bc_offset(struct compilation_unit *cu, unsigned char *native_ptr)
+{
+       unsigned long native_addr;
+       unsigned long method_addr;
+       unsigned long offset;
+
+       if (!cu->bc_offset_map)
+               return BC_OFFSET_UNKNOWN;
+
+       native_addr = (unsigned long) native_ptr;
+       method_addr = (unsigned long) buffer_ptr(cu->objcode);
+
+       if (native_addr < method_addr)
+               return BC_OFFSET_UNKNOWN;
+
+       offset = native_addr - method_addr;
+       if (offset >= buffer_offset(cu->objcode))
+               return BC_OFFSET_UNKNOWN;
+
+       return cu->bc_offset_map[offset];
 }
 
 void print_bytecode_offset(unsigned long bytecode_offset, struct string *str)
diff --git a/jit/compilation-unit.c b/jit/compilation-unit.c
index d67e216..3beb43a 100644
--- a/jit/compilation-unit.c
+++ b/jit/compilation-unit.c
@@ -95,6 +95,12 @@ static void free_var_infos(struct var_info *var_infos)
        }
 }
 
+static void free_bc_offset_map(unsigned long *map)
+{
+       if (map)
+               free(map);
+}
+
 void free_compilation_unit(struct compilation_unit *cu)
 {
        struct basic_block *bb, *tmp_bb;
@@ -108,6 +114,7 @@ void free_compilation_unit(struct compilation_unit *cu)
        free_buffer(cu->objcode);
        free_var_infos(cu->var_infos);
        free_stack_frame(cu->stack_frame);
+       free_bc_offset_map(cu->bc_offset_map);
        free(cu);
 }
 
diff --git a/jit/compiler.c b/jit/compiler.c
index e88dd55..8be6044 100644
--- a/jit/compiler.c
+++ b/jit/compiler.c
@@ -113,6 +113,10 @@ int compile(struct compilation_unit *cu)
        if (err)
                goto out;
 
+       err = build_bc_offset_map(cu);
+       if (err)
+               goto out;
+
        if (opt_trace_machine_code)
                trace_machine_code(cu);
 
diff --git a/jit/exception.c b/jit/exception.c
index e6115e0..f99291d 100644
--- a/jit/exception.c
+++ b/jit/exception.c
@@ -274,7 +274,7 @@ throw_from_jit(struct compilation_unit *cu, struct 
jit_stack_frame *frame,
 
        clear_exception();
 
-       bc_offset = native_ptr_to_bytecode_offset(cu, native_ptr);
+       bc_offset = jit_lookup_bc_offset(cu, native_ptr);
        if (bc_offset != BC_OFFSET_UNKNOWN) {
                eh_ptr = find_handler(cu, exception->class, bc_offset);
                if (eh_ptr != NULL) {
diff --git a/jit/trace-jit.c b/jit/trace-jit.c
index 90e91c4..d1f3e4f 100644
--- a/jit/trace-jit.c
+++ b/jit/trace-jit.c
@@ -463,7 +463,7 @@ static void print_source_and_line(struct compilation_unit 
*cu,
        else
                trace_printf("UNKNOWN");
 
-       pc = native_ptr_to_bytecode_offset(cu, ptr);
+       pc = jit_lookup_bc_offset(cu, ptr);
        if (pc == BC_OFFSET_UNKNOWN)
                return;
 
diff --git a/vm/stack-trace.c b/vm/stack-trace.c
index 31cf218..df870bb 100644
--- a/vm/stack-trace.c
+++ b/vm/stack-trace.c
@@ -414,7 +414,7 @@ static struct vm_object *get_intermediate_stack_trace(void)
                if (vm_method_is_native(cu->method))
                        bc_offset = BC_OFFSET_UNKNOWN;
                else
-                       bc_offset = native_ptr_to_bytecode_offset(cu,
+                       bc_offset = jit_lookup_bc_offset(cu,
                                                (unsigned char*)st_elem.addr);
 
                array_set_field_ptr(array, i++, cu->method);
@@ -449,8 +449,8 @@ void print_java_stack_trace_elem(struct stack_trace_elem 
*elem)
        if (elem->type == STACK_TRACE_ELEM_TYPE_TRAMPOLINE)
                bc_offset = 0;
        else {
-               bc_offset = native_ptr_to_bytecode_offset(cu,
-                                               (unsigned char*)elem->addr);
+               bc_offset = jit_lookup_bc_offset(cu,
+                                               (unsigned char *) elem->addr);
                if (bc_offset == BC_OFFSET_UNKNOWN)
                        goto out;
        }
-- 
1.6.0.6


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to