On Mon, 2009-07-06 at 01:16 +0200, Tomek Grabiec wrote: > We cannot overwrite a register which is not saved (ESI) because this > will lead to a corruption in JIT code. The proper solution is > to copy the call arguments. > > Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
I'm confused. What exactly is the problem here and why do we need to copy arguments? > --- > arch/x86/emit-code.c | 37 +++++++++++++++++++++++++++++++------ > include/jit/compiler.h | 3 ++- > include/jit/emit-code.h | 3 ++- > jit/trampoline.c | 7 ++++--- > 4 files changed, 39 insertions(+), 11 deletions(-) > > diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c > index 236ba0e..c4ba179 100644 > --- a/arch/x86/emit-code.c > +++ b/arch/x86/emit-code.c > @@ -1389,21 +1389,46 @@ void emit_trampoline(struct compilation_unit *cu, > } > > void emit_jni_trampoline(struct buffer *buf, struct vm_jni_env *jni_env, > - void *target) > + void *target, struct vm_method *method) > { > + unsigned long args_size; > + > jit_text_lock(); > > buf->buf = jit_text_ptr(); > > - /* save return address into caller-saved register */ > - __emit_pop_reg(buf, REG_ESI); > + __emit_push_reg(buf, REG_ESI); > + __emit_push_reg(buf, REG_EDI); > + __emit_push_reg(buf, REG_ECX); > + > + /* > + * Make a copy of call arguments > + */ > + __emit_mov_reg_reg(buf, REG_ESP, REG_ESI); > + __emit_add_imm_reg(buf, (3 + 1) * sizeof(unsigned long), REG_ESI); > + > + args_size = sizeof(unsigned long) + (method->args_count + 1); > + > + __emit_add_imm_reg(buf, -args_size, REG_ESP); > + __emit_mov_reg_reg(buf, REG_ESP, REG_EDI); > + > + __emit_mov_imm_reg(buf, method->args_count + 1, REG_ECX); > + > + /* CLD */ > + emit(buf, 0xfc); > + > + /* REP MOVSD */ > + emit(buf, 0xf3); > + emit(buf, 0xa5); > > __emit_push_imm(buf, (unsigned long) jni_env); > __emit_call(buf, target); > - __emit_add_imm_reg(buf, 4, REG_ESP); > + __emit_add_imm_reg(buf, args_size + sizeof(unsigned long), REG_ESP); > + > + __emit_pop_reg(buf, REG_ECX); > + __emit_pop_reg(buf, REG_EDI); > + __emit_pop_reg(buf, REG_ESI); > > - /* return to caller*/ > - __emit_push_reg(buf, REG_ESI); > emit_ret(buf); > > jit_text_reserve(buffer_offset(buf)); > diff --git a/include/jit/compiler.h b/include/jit/compiler.h > index 8584954..e2609ef 100644 > --- a/include/jit/compiler.h > +++ b/include/jit/compiler.h > @@ -14,6 +14,7 @@ struct compilation_unit; > struct expression; > struct statement; > struct buffer; > +struct vm_method; > > struct fixup_site { > /* Compilation unit to which relcall_insn belongs */ > @@ -62,7 +63,7 @@ void *jit_magic_trampoline(struct compilation_unit *); > struct jit_trampoline *alloc_jit_trampoline(void); > struct jni_trampoline *alloc_jni_trampoline(void); > struct jit_trampoline *build_jit_trampoline(struct compilation_unit *); > -struct jni_trampoline *build_jni_trampoline(void *); > +struct jni_trampoline *build_jni_trampoline(struct vm_method *, void *); > void free_jit_trampoline(struct jit_trampoline *); > void free_jni_trampoline(struct jni_trampoline *); > > diff --git a/include/jit/emit-code.h b/include/jit/emit-code.h > index 07c41bf..291955f 100644 > --- a/include/jit/emit-code.h > +++ b/include/jit/emit-code.h > @@ -8,6 +8,7 @@ struct buffer; > struct insn; > struct vm_object; > struct vm_jni_env; > +struct vm_method; > > enum emitter_type { > NO_OPERANDS = 1, > @@ -39,6 +40,6 @@ extern void emit_body(struct basic_block *, struct buffer > *); > extern void backpatch_branch_target(struct buffer *buf, struct insn *insn, > unsigned long target_offset); > extern void emit_jni_trampoline(struct buffer *buf, struct vm_jni_env > *jni_env, > - void *target); > + void *target, struct vm_method *method); > > #endif /* JATO_EMIT_CODE_H */ > diff --git a/jit/trampoline.c b/jit/trampoline.c > index 0de2db5..42f3afa 100644 > --- a/jit/trampoline.c > +++ b/jit/trampoline.c > @@ -65,7 +65,8 @@ static void *jit_native_trampoline(struct compilation_unit > *cu) > add_cu_mapping((unsigned long)ret, cu); > > if (!method->jni_trampoline) > - method->jni_trampoline = build_jni_trampoline(ret); > + method->jni_trampoline = > + build_jni_trampoline(method, ret); > > return buffer_ptr(method->jni_trampoline->objcode); > } > @@ -151,13 +152,13 @@ struct jit_trampoline *build_jit_trampoline(struct > compilation_unit *cu) > return trampoline; > } > > -struct jni_trampoline *build_jni_trampoline(void *target) > +struct jni_trampoline *build_jni_trampoline(struct vm_method *vmm, void > *target) > { > struct jni_trampoline *trampoline; > > trampoline = alloc_jni_trampoline(); > if (trampoline) > emit_jni_trampoline(trampoline->objcode, vm_jni_get_jni_env(), > - target); > + target, vmm); > return trampoline; > } ------------------------------------------------------------------------------ _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel