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