This is necessary for basic block freeing after compilation to be possible.
Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- arch/x86/emit-code.c | 30 ++++++++++++++++++++---------- arch/x86/insn-selector.brg | 2 ++ include/jit/compilation-unit.h | 6 ++++++ include/jit/compiler.h | 14 ++++++++++---- include/vm/static.h | 7 ++++++- jit/compilation-unit.c | 1 + jit/emit.c | 24 ++++++++++++++++++++++++ jit/fixup-site.c | 8 +++----- 8 files changed, 72 insertions(+), 20 deletions(-) diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c index 2ef7d3e..0cb7ba0 100644 --- a/arch/x86/emit-code.c +++ b/arch/x86/emit-code.c @@ -426,7 +426,7 @@ void fixup_direct_calls(struct jit_trampoline *t, unsigned long target) if (!is_compiled) continue; - site_addr = fixup_site_addr(this); + site_addr = this->insn_ptr; new_target = target - ((unsigned long) site_addr + CALL_INSN_SIZE); cpu_write_u32(site_addr+1, new_target); @@ -446,12 +446,25 @@ void fixup_static(struct vm_class *vmc) list_for_each_entry_safe(this, next, &vmc->static_fixup_site_list, vmc_node) { - struct vm_field *vmf = this->vmf; - void *site_addr = buffer_ptr(this->cu->objcode) - + this->insn->mach_offset; - void *new_target = vmc->static_values + vmf->offset; + struct vm_field *vmf; + void *new_target; + bool is_compiled; + + /* + * We should not fixup sites from methods which are + * not yet compiled. + */ + pthread_mutex_lock(&this->cu->mutex); + is_compiled = this->cu->is_compiled; + pthread_mutex_unlock(&this->cu->mutex); + + if (!is_compiled) + continue; + + vmf = this->vmf; + new_target = vmc->static_values + vmf->offset; - cpu_write_u32(site_addr + 2, (unsigned long) new_target); + cpu_write_u32(this->insn_ptr + 2, (unsigned long) new_target); list_del(&this->vmc_node); @@ -477,10 +490,7 @@ int fixup_static_at(unsigned long addr) list_for_each_entry_safe(this, t, &cu->static_fixup_site_list, cu_node) { - void *site_addr = buffer_ptr(cu->objcode) - + this->insn->mach_offset; - - if ((unsigned long) site_addr == addr) { + if ((unsigned long) this->insn_ptr == addr) { struct vm_class *vmc = this->vmf->class; pthread_mutex_unlock(&cu->mutex); diff --git a/arch/x86/insn-selector.brg b/arch/x86/insn-selector.brg index 65bc5d1..778786d 100644 --- a/arch/x86/insn-selector.brg +++ b/arch/x86/insn-selector.brg @@ -3013,6 +3013,8 @@ static void invoke(struct basic_block *s, struct tree_node *tree, struct compila fixup->relcall_insn = call_insn; trampoline_add_fixup_site(method->trampoline, fixup); + list_add(&fixup->fixup_site_backpatch_list_node, + &fixup->cu->fixup_site_backpatch_list); } nr_stack_args = get_stack_args_count(method); diff --git a/include/jit/compilation-unit.h b/include/jit/compilation-unit.h index d3366f7..4e56868 100644 --- a/include/jit/compilation-unit.h +++ b/include/jit/compilation-unit.h @@ -91,6 +91,12 @@ struct compilation_unit { struct radix_tree *safepoint_map; /* + * Contains list of fixup_sites inside this compilation unit's + * code which needs to patched after code emission. + */ + struct list_head fixup_site_backpatch_list; + + /* * Contains native pointers of exception handlers. Indices to * this table are the same as for exception table in code * attribute. diff --git a/include/jit/compiler.h b/include/jit/compiler.h index b523ba5..1eeee0a 100644 --- a/include/jit/compiler.h +++ b/include/jit/compiler.h @@ -19,10 +19,17 @@ struct buffer; struct fixup_site { /* Compilation unit to which relcall_insn belongs */ struct compilation_unit *cu; - /* We need this, because we don't have native pointer at - instruction selection */ - struct insn *relcall_insn; + + union { + /* This is set during instruction selection */ + struct insn *relcall_insn; + + /* This will be set after code emission */ + void *insn_ptr; + }; + struct list_head fixup_list_node; + struct list_head fixup_site_backpatch_list_node; }; struct jit_trampoline { @@ -66,7 +73,6 @@ void free_jit_trampoline(struct jit_trampoline *); struct fixup_site *alloc_fixup_site(void); void free_fixup_site(struct fixup_site *); void trampoline_add_fixup_site(struct jit_trampoline *, struct fixup_site *); -unsigned char *fixup_site_addr(struct fixup_site *); const char *method_symbol(struct vm_method *method, char *symbol, size_t len); diff --git a/include/vm/static.h b/include/vm/static.h index 6e434e0..0382134 100644 --- a/include/vm/static.h +++ b/include/vm/static.h @@ -18,7 +18,12 @@ struct static_fixup_site { struct list_head cu_node; enum static_fixup_type type; - struct insn *insn; + + union { + struct insn *insn; + void *insn_ptr; + }; + struct vm_field *vmf; struct compilation_unit *cu; }; diff --git a/jit/compilation-unit.c b/jit/compilation-unit.c index 9093d82..5dce9f3 100644 --- a/jit/compilation-unit.c +++ b/jit/compilation-unit.c @@ -97,6 +97,7 @@ struct compilation_unit *compilation_unit_alloc(struct vm_method *method) INIT_LIST_HEAD(&cu->static_fixup_site_list); INIT_LIST_HEAD(&cu->tableswitch_list); INIT_LIST_HEAD(&cu->lookupswitch_list); + INIT_LIST_HEAD(&cu->fixup_site_backpatch_list); for (unsigned int i = 0; i < NR_FIXED_REGISTERS; ++i) { struct var_info *ret; diff --git a/jit/emit.c b/jit/emit.c index a65f35f..fb049e2 100644 --- a/jit/emit.c +++ b/jit/emit.c @@ -112,6 +112,28 @@ static void backpatch_lookupswitch_targets(struct compilation_unit *cu) } } +static void backpatch_fixup_sites(struct compilation_unit *cu) +{ + struct fixup_site *this; + + list_for_each_entry(this, &cu->fixup_site_backpatch_list, + fixup_site_backpatch_list_node) + { + this->insn_ptr = buffer_ptr(cu->objcode) + + this->relcall_insn->mach_offset; + } +} + +static void backpatch_static_fixup_sites(struct compilation_unit *cu) +{ + struct static_fixup_site *this; + + list_for_each_entry(this, &cu->static_fixup_site_list, cu_node) { + this->insn_ptr = buffer_ptr(cu->objcode) + + this->insn->mach_offset; + } +} + void emit_body(struct basic_block *bb, struct buffer *buf) { struct insn *insn; @@ -199,6 +221,8 @@ int emit_machine_code(struct compilation_unit *cu) backpatch_tableswitch_targets(cu); backpatch_lookupswitch_targets(cu); + backpatch_fixup_sites(cu); + backpatch_static_fixup_sites(cu); build_exception_handlers_table(cu); cu->exit_bb_ptr = bb_native_ptr(cu->exit_bb); diff --git a/jit/fixup-site.c b/jit/fixup-site.c index 0d38d8a..681e223 100644 --- a/jit/fixup-site.c +++ b/jit/fixup-site.c @@ -39,6 +39,9 @@ struct fixup_site *alloc_fixup_site(void) memset(site, 0, sizeof(*site)); + INIT_LIST_HEAD(&site->fixup_list_node); + INIT_LIST_HEAD(&site->fixup_site_backpatch_list_node); + return site; } @@ -54,8 +57,3 @@ void trampoline_add_fixup_site(struct jit_trampoline *trampoline, list_add_tail(&site->fixup_list_node, &trampoline->fixup_site_list); pthread_mutex_unlock(&trampoline->mutex); } - -unsigned char *fixup_site_addr(struct fixup_site *site) -{ - return buffer_ptr(site->cu->objcode) + site->relcall_insn->mach_offset; -} -- 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