From 5ae8e1330c58ef27f842c0f9000d06bfd9274140 Mon Sep 17 00:00:00 2001 From: michi Date: Thu, 19 Jul 2007 13:51:21 +0000 Subject: [PATCH] * src/vm/jit/powerpc/emit.c (emit_patcher_traps): Formerly known as emit_patcher_stubs, now emits traps instead of stubs. * src/vm/jit/powerpc/codegen.c (codegen_emit, codegen_emit_stub_native): Call the new patcher functions and adapted to above change. * src/vm/jit/powerpc/patcher.c: Adapted patchers to new signature for traps. (patcher_wrapper): Removed, this is obsolete. * src/vm/jit/powerpc/asmpart.S (asm_patcher_wrapper): Removed, this is obsolete. * src/vm/jit/powerpc/linux/md-os.c (md_signal_handler_sigsegv): Only calls the exception handling if exception object present. * src/vm/jit/powerpc/darwin/md-os.c (md_signal_handler_sigsegv): Likewise. * src/vm/jit/patcher-common.h [__POWERPC__]: Enabled new patcher stuff. * src/vm/jit/patcher.h [__POWERPC__]: Defined away old patcher stuff. --- src/vm/jit/patcher-common.h | 4 +- src/vm/jit/patcher.h | 4 +- src/vm/jit/powerpc/asmpart.S | 170 +--------------- src/vm/jit/powerpc/codegen.c | 54 +++--- src/vm/jit/powerpc/darwin/md-os.c | 12 +- src/vm/jit/powerpc/emit.c | 96 ++------- src/vm/jit/powerpc/linux/md-os.c | 12 +- src/vm/jit/powerpc/patcher.c | 310 +++++++++++------------------- 8 files changed, 169 insertions(+), 493 deletions(-) diff --git a/src/vm/jit/patcher-common.h b/src/vm/jit/patcher-common.h index f53c90b1f..203e03241 100644 --- a/src/vm/jit/patcher-common.h +++ b/src/vm/jit/patcher-common.h @@ -77,7 +77,7 @@ java_objectheader *patcher_handler(u1 *pc); /* patcher prototypes and macros **********************************************/ -#if defined(__ALPHA__) || defined(__ARM__) +#if defined(__ALPHA__) || defined(__ARM__) || defined(__POWERPC__) /* new patcher functions */ @@ -140,7 +140,7 @@ bool patcher_invokevirtual(patchref_t *pr); bool patcher_invokeinterface(patchref_t *pr); #define PATCHER_invokeinterface (functionptr) patcher_invokeinterface -#if defined(__ALPHA__) +#if defined(__ALPHA__) || defined(__POWERPC__) bool patcher_checkcast_interface(patchref_t *pr); #define PATCHER_checkcast_interface (functionptr) patcher_checkcast_interface diff --git a/src/vm/jit/patcher.h b/src/vm/jit/patcher.h index 2b15fb8bd..b95db2f56 100644 --- a/src/vm/jit/patcher.h +++ b/src/vm/jit/patcher.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: patcher.h 8186 2007-07-05 23:48:16Z michi $ + $Id: patcher.h 8216 2007-07-19 13:51:21Z michi $ */ @@ -41,7 +41,7 @@ #include "vm/global.h" -#if defined(__ALPHA__) || defined(__ARM__) +#if defined(__ALPHA__) || defined(__ARM__) || defined(__POWERPC__) # error "you should no longer include this file" #else diff --git a/src/vm/jit/powerpc/asmpart.S b/src/vm/jit/powerpc/asmpart.S index ab55c89e2..2f2cdf49f 100644 --- a/src/vm/jit/powerpc/asmpart.S +++ b/src/vm/jit/powerpc/asmpart.S @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: asmpart.S 7989 2007-05-30 21:04:42Z twisti $ + $Id: asmpart.S 8216 2007-07-19 13:51:21Z michi $ */ @@ -60,8 +60,6 @@ .globl asm_abstractmethoderror - .globl asm_patcher_wrapper - #if defined(ENABLE_REPLACEMENT) .globl asm_replacement_out .globl asm_replacement_in @@ -978,152 +976,6 @@ asm_abstractmethoderror: b L_asm_handle_nat_exception -/* asm_patcher_wrapper ********************************************************* - - XXX - - Stack layout: - 20 return address into JIT code (patch position) - 16 pointer to virtual java_objectheader - 12 machine code (which is patched back later) - 8 unresolved class/method/field reference - 4 data segment displacement from load instructions - 0 patcher function pointer to call (pv is saved here afterwards) - -*******************************************************************************/ - -asm_patcher_wrapper: - mflr r0 /* get Java return address (leaf) */ - stw r0,6*4(sp) /* store it in the stub stackframe */ - /* keep stack 16-bytes aligned: 6+1+37 = 44 */ - stwu sp,-(LA_SIZE+(5+58)*4)(sp) - -#if defined(__DARWIN__) - stw a0,LA_SIZE+(5+0)*4(sp) /* save argument registers */ - stw a1,LA_SIZE+(5+1)*4(sp) /* preserve linkage area (24 bytes) */ - stw a2,LA_SIZE+(5+2)*4(sp) /* and 4 bytes for 4 argument */ - stw a3,LA_SIZE+(5+3)*4(sp) - stw a4,LA_SIZE+(5+4)*4(sp) - stw a5,LA_SIZE+(5+5)*4(sp) - stw a6,LA_SIZE+(5+6)*4(sp) - stw a7,LA_SIZE+(5+7)*4(sp) - - stfd fa0,LA_SIZE+(5+8)*4(sp) - stfd fa1,LA_SIZE+(5+10)*4(sp) - stfd fa2,LA_SIZE+(5+12)*4(sp) - stfd fa3,LA_SIZE+(5+14)*4(sp) - stfd fa4,LA_SIZE+(5+16)*4(sp) - stfd fa5,LA_SIZE+(5+18)*4(sp) - stfd fa6,LA_SIZE+(5+20)*4(sp) - stfd fa7,LA_SIZE+(5+22)*4(sp) - stfd fa8,LA_SIZE+(5+24)*4(sp) - stfd fa9,LA_SIZE+(5+26)*4(sp) - stfd fa10,LA_SIZE+(5+28)*4(sp) - stfd fa11,LA_SIZE+(5+30)*4(sp) - stfd fa12,LA_SIZE+(5+32)*4(sp) - - stw t0,LA_SIZE+(5+33)*4(sp) - stw t1,LA_SIZE+(5+34)*4(sp) - stw t2,LA_SIZE+(5+35)*4(sp) - stw t3,LA_SIZE+(5+36)*4(sp) - stw t4,LA_SIZE+(5+37)*4(sp) - stw t5,LA_SIZE+(5+38)*4(sp) - stw t6,LA_SIZE+(5+39)*4(sp) - stw t7,LA_SIZE+(5+40)*4(sp) - - stfd ft0,LA_SIZE+(5+42)*4(sp) - stfd ft1,LA_SIZE+(5+44)*4(sp) - stfd ft2,LA_SIZE+(5+46)*4(sp) - stfd ft3,LA_SIZE+(5+48)*4(sp) - stfd ft4,LA_SIZE+(5+50)*4(sp) - stfd ft5,LA_SIZE+(5+52)*4(sp) -#else - /* save 8 int/8 float arguments */ - SAVE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+1) - SAVE_TEMPORARY_REGISTERS(LA_SIZE_IN_POINTERS+1+24) -#endif - - stw itmp1,LA_SIZE+(5+54)*4(sp) - stw itmp2,LA_SIZE+(5+55)*4(sp) - stw pv,LA_SIZE+(5+56)*4(sp) - - addi a0,sp,LA_SIZE+(5+58)*4 /* pass SP of patcher stub */ - mr a1,pv /* pass PV */ - mr a2,r0 /* pass RA (correct for leafs) */ - bl patcher_wrapper - stw v0,LA_SIZE+(5+57)*4(sp) /* save return value */ - -#if defined(__DARWIN__) - lwz a0,LA_SIZE+(5+0)*4(sp) - lwz a1,LA_SIZE+(5+1)*4(sp) - lwz a2,LA_SIZE+(5+2)*4(sp) - lwz a3,LA_SIZE+(5+3)*4(sp) - lwz a4,LA_SIZE+(5+4)*4(sp) - lwz a5,LA_SIZE+(5+5)*4(sp) - lwz a6,LA_SIZE+(5+6)*4(sp) - lwz a7,LA_SIZE+(5+7)*4(sp) - - lfd fa0,LA_SIZE+(5+8)*4(sp) - lfd fa1,LA_SIZE+(5+10)*4(sp) - lfd fa2,LA_SIZE+(5+12)*4(sp) - lfd fa3,LA_SIZE+(5+14)*4(sp) - lfd fa4,LA_SIZE+(5+16)*4(sp) - lfd fa5,LA_SIZE+(5+18)*4(sp) - lfd fa6,LA_SIZE+(5+20)*4(sp) - lfd fa7,LA_SIZE+(5+22)*4(sp) - lfd fa8,LA_SIZE+(5+24)*4(sp) - lfd fa9,LA_SIZE+(5+26)*4(sp) - lfd fa10,LA_SIZE+(5+28)*4(sp) - lfd fa11,LA_SIZE+(5+30)*4(sp) - lfd fa12,LA_SIZE+(5+32)*4(sp) - - lwz t0,LA_SIZE+(5+33)*4(sp) - lwz t1,LA_SIZE+(5+34)*4(sp) - lwz t2,LA_SIZE+(5+35)*4(sp) - lwz t3,LA_SIZE+(5+36)*4(sp) - lwz t4,LA_SIZE+(5+37)*4(sp) - lwz t5,LA_SIZE+(5+38)*4(sp) - lwz t6,LA_SIZE+(5+39)*4(sp) - lwz t7,LA_SIZE+(5+40)*4(sp) - - lfd ft0,LA_SIZE+(5+42)*4(sp) - lfd ft1,LA_SIZE+(5+44)*4(sp) - lfd ft2,LA_SIZE+(5+46)*4(sp) - lfd ft3,LA_SIZE+(5+48)*4(sp) - lfd ft4,LA_SIZE+(5+50)*4(sp) - lfd ft5,LA_SIZE+(5+52)*4(sp) -#else - /* restore 8 int/8 float arguments */ - RESTORE_ARGUMENT_REGISTERS(LA_SIZE_IN_POINTERS+1) - RESTORE_TEMPORARY_REGISTERS(LA_SIZE_IN_POINTERS+1+24) -#endif - - lwz itmp1,LA_SIZE+(5+54)*4(sp) - lwz itmp2,LA_SIZE+(5+55)*4(sp) - lwz pv,LA_SIZE+(5+56)*4(sp) - lwz itmp3,LA_SIZE+(5+57)*4(sp) /* restore return value into temp reg.*/ - - lwz r0,6*4+LA_SIZE+(5+58)*4(sp) /* restore RA */ - mtlr r0 - - mr. itmp3,itmp3 /* check for an exception */ - bne L_asm_patcher_wrapper_exception - - /* get return address (into JIT code) */ - lwz itmp3,5*4+LA_SIZE+(5+58)*4(sp) - - /* remove stack frame + patcher stub stack */ - addi sp,sp,8*4+LA_SIZE+(5+58)*4 - - mtctr itmp3 - bctr /* jump to new patched code */ - -L_asm_patcher_wrapper_exception: - mr xptr,itmp3 /* get exception */ - lwz xpc,5*4+LA_SIZE+(5+58)*4(sp) - addi sp,sp,8*4+LA_SIZE+(5+58)*4 - b L_asm_handle_exception - #if defined(ENABLE_REPLACEMENT) /* asm_replacement_out ********************************************************* @@ -1613,26 +1465,6 @@ L_exceptions_asm_new_abstractmethoderror$lazy_ptr: .long dyld_stub_binding_helper -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align 2 -L_patcher_wrapper$stub: - .indirect_symbol _patcher_wrapper - mflr r0 - bcl 20,31,L00$_patcher_wrapper -L00$_patcher_wrapper: - mflr r11 - addis r11,r11,ha16(L_patcher_wrapper$lazy_ptr - L00$_patcher_wrapper) - mtlr r0 - lwzu r12,lo16(L_patcher_wrapper$lazy_ptr - L00$_patcher_wrapper)(r11) - mtctr r12 - bctr -.data -.lazy_symbol_pointer -L_patcher_wrapper$lazy_ptr: - .indirect_symbol _patcher_wrapper - .long dyld_stub_binding_helper - - # if defined(ENABLE_REPLACEMENT) .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 diff --git a/src/vm/jit/powerpc/codegen.c b/src/vm/jit/powerpc/codegen.c index 7a4aeec78..cec29e578 100644 --- a/src/vm/jit/powerpc/codegen.c +++ b/src/vm/jit/powerpc/codegen.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: codegen.c 8211 2007-07-18 19:52:23Z michi $ + $Id: codegen.c 8216 2007-07-19 13:51:21Z michi $ */ @@ -62,7 +62,7 @@ #include "vm/jit/md.h" #include "vm/jit/methodheader.h" #include "vm/jit/parse.h" -#include "vm/jit/patcher.h" +#include "vm/jit/patcher-common.h" #include "vm/jit/reg.h" #include "vm/jit/replace.h" #include "vm/jit/stacktrace.h" @@ -544,7 +544,7 @@ bool codegen_emit(jitdata *jd) disp = dseg_add_unique_address(cd, cr); - codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, disp); } else @@ -1639,7 +1639,7 @@ bool codegen_emit(jitdata *jd) fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, uf); - codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp); + patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); } else { fi = iptr->sx.s23.s3.fmiref->p.field; @@ -1647,7 +1647,7 @@ bool codegen_emit(jitdata *jd) disp = dseg_add_address(cd, &(fi->value)); if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) - codegen_addpatchref(cd, PATCHER_initialize_class, + patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, disp); } @@ -1685,7 +1685,7 @@ bool codegen_emit(jitdata *jd) fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, uf); - codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp); + patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); } else { fi = iptr->sx.s23.s3.fmiref->p.field; @@ -1693,7 +1693,7 @@ bool codegen_emit(jitdata *jd) disp = dseg_add_address(cd, &(fi->value)); if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) - codegen_addpatchref(cd, PATCHER_initialize_class, + patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, disp); } @@ -1732,7 +1732,7 @@ bool codegen_emit(jitdata *jd) fieldtype = uf->fieldref->parseddesc.fd->type; disp = 0; - codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); + patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0); } else { fi = iptr->sx.s23.s3.fmiref->p.field; @@ -1798,7 +1798,7 @@ bool codegen_emit(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_FTMP2); if (INSTRUCTION_IS_UNRESOLVED(iptr)) - codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); + patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0); /* implicit null-pointer check */ switch (fieldtype) { @@ -1833,7 +1833,7 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { unresolved_class *uc = iptr->sx.s23.s2.uc; - codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0); } #endif /* ENABLE_VERIFIER */ @@ -2169,7 +2169,7 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { unresolved_class *uc = iptr->sx.s23.s2.uc; - codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0); } #endif /* ENABLE_VERIFIER */ goto nowperformreturn; @@ -2462,7 +2462,7 @@ gen_method: if (lm == NULL) { disp = dseg_add_unique_address(cd, um); - codegen_addpatchref(cd, PATCHER_invokestatic_special, + patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, disp); } else @@ -2482,7 +2482,7 @@ gen_method: case ICMD_INVOKEVIRTUAL: if (lm == NULL) { - codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0); + patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0); s1 = 0; } @@ -2507,7 +2507,7 @@ gen_method: case ICMD_INVOKEINTERFACE: if (lm == NULL) { - codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0); + patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0); s1 = 0; s2 = 0; @@ -2589,7 +2589,7 @@ gen_method: disp = dseg_add_unique_s4(cd, 0); /* super->flags */ - codegen_addpatchref(cd, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, disp); @@ -2603,7 +2603,7 @@ gen_method: if ((super == NULL) || (super->flags & ACC_INTERFACE)) { if (super == NULL) { - codegen_addpatchref(cd, + patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0); @@ -2638,7 +2638,7 @@ gen_method: disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, disp); } @@ -2694,7 +2694,7 @@ gen_method: if (INSTRUCTION_IS_UNRESOLVED(iptr)) { disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, disp); } @@ -2752,7 +2752,7 @@ gen_method: disp = dseg_add_unique_s4(cd, 0); /* super->flags */ - codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, disp); M_ILD(REG_ITMP3, REG_PV, disp); @@ -2764,7 +2764,7 @@ gen_method: if ((super == NULL) || (super->flags & ACC_INTERFACE)) { if (super == NULL) { - codegen_addpatchref(cd, + patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0); } @@ -2798,7 +2798,7 @@ gen_method: disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, disp); } @@ -2870,7 +2870,7 @@ gen_method: if (INSTRUCTION_IS_UNRESOLVED(iptr)) { disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, disp); } else @@ -2915,9 +2915,9 @@ gen_method: dseg_createlinenumbertable(cd); - /* generate stubs */ + /* generate traps */ - emit_patcher_stubs(jd); + emit_patcher_traps(jd); /* everything's ok */ @@ -3015,7 +3015,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) #if !defined(WITH_STATIC_CLASSPATH) if (f == NULL) - codegen_addpatchref(cd, PATCHER_resolve_native_function, m, funcdisp); + patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp); #endif /* emit trace code */ @@ -3224,9 +3224,9 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) M_MTCTR(REG_ITMP3); M_RTS; - /* generate patcher stubs */ + /* generate patcher traps */ - emit_patcher_stubs(jd); + emit_patcher_traps(jd); } diff --git a/src/vm/jit/powerpc/darwin/md-os.c b/src/vm/jit/powerpc/darwin/md-os.c index d7749c4b9..edc58f963 100644 --- a/src/vm/jit/powerpc/darwin/md-os.c +++ b/src/vm/jit/powerpc/darwin/md-os.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: md-os.c 8178 2007-07-05 11:13:20Z michi $ + $Id: md-os.c 8216 2007-07-19 13:51:21Z michi $ */ @@ -125,11 +125,13 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) o = exceptions_new_hardware_exception(pv, sp, ra, xpc, type, val, &sfi); - /* set registers */ + /* set registers (only if exception object ready) */ - _ss->r11 = (ptrint) o; - _ss->r12 = (ptrint) xpc; - _ss->srr0 = (ptrint) asm_handle_exception; + if (o != NULL) { + _ss->r11 = (ptrint) o; + _ss->r12 = (ptrint) xpc; + _ss->srr0 = (ptrint) asm_handle_exception; + } } diff --git a/src/vm/jit/powerpc/emit.c b/src/vm/jit/powerpc/emit.c index 040609771..5a86e5cec 100644 --- a/src/vm/jit/powerpc/emit.c +++ b/src/vm/jit/powerpc/emit.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: emit.c 8211 2007-07-18 19:52:23Z michi $ + $Id: emit.c 8216 2007-07-19 13:51:21Z michi $ */ @@ -51,6 +51,7 @@ #include "vm/jit/dseg.h" #include "vm/jit/emit-common.h" #include "vm/jit/jit.h" +#include "vm/jit/patcher-common.h" #include "vm/jit/replace.h" #include "vmcore/options.h" @@ -506,114 +507,45 @@ void emit_exception_check(codegendata *cd, instruction *iptr) } -/* emit_patcher_stubs ********************************************************** +/* emit_patcher_traps ********************************************************** Generates the code for the patcher stubs. *******************************************************************************/ -void emit_patcher_stubs(jitdata *jd) +void emit_patcher_traps(jitdata *jd) { codegendata *cd; - patchref *pref; - u4 mcode; + codeinfo *code; + patchref_t *pr; u1 *savedmcodeptr; u1 *tmpmcodeptr; - s4 targetdisp; - s4 disp; /* get required compiler data */ - cd = jd->cd; + cd = jd->cd; + code = jd->code; /* generate code patching stub call code */ - targetdisp = 0; - - for (pref = cd->patchrefs; pref != NULL; pref = pref->next) { - /* check code segment size */ - - MCODECHECK(100); + for (pr = list_first_unsynced(code->patchers); pr != NULL; pr = list_next_unsynced(code->patchers, pr)) { /* Get machine code which is patched back in later. The - call is 1 instruction word long. */ + trap is 1 instruction word long. */ - tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos); + tmpmcodeptr = (u1 *) (cd->mcodebase + pr->mpc); - mcode = *((u4 *) tmpmcodeptr); + pr->mcode = *((u4 *) tmpmcodeptr); - /* Patch in the call to call the following code (done at + /* Patch in the trap to call the signal handler (done at compile time). */ savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */ cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */ - disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1); - M_BR(disp); + M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_PATCHER); cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */ - - /* create stack frame - keep stack 16-byte aligned */ - - M_AADD_IMM(REG_SP, -8 * 4, REG_SP); - - /* calculate return address and move it onto the stack */ - - M_LDA(REG_ITMP3, REG_PV, pref->branchpos); - M_AST_INTERN(REG_ITMP3, REG_SP, 5 * 4); - - /* move pointer to java_objectheader onto stack */ - -#if defined(ENABLE_THREADS) - /* order reversed because of data segment layout */ - - (void) dseg_add_unique_address(cd, NULL); /* flcword */ - (void) dseg_add_unique_address(cd, lock_get_initial_lock_word()); - disp = dseg_add_unique_address(cd, NULL); /* vftbl */ - - M_LDA(REG_ITMP3, REG_PV, disp); - M_AST_INTERN(REG_ITMP3, REG_SP, 4 * 4); -#else - /* do nothing */ -#endif - - /* move machine code onto stack */ - - disp = dseg_add_s4(cd, mcode); - M_ILD(REG_ITMP3, REG_PV, disp); - M_IST_INTERN(REG_ITMP3, REG_SP, 3 * 4); - - /* move class/method/field reference onto stack */ - - disp = dseg_add_address(cd, pref->ref); - M_ALD(REG_ITMP3, REG_PV, disp); - M_AST_INTERN(REG_ITMP3, REG_SP, 2 * 4); - - /* move data segment displacement onto stack */ - - disp = dseg_add_s4(cd, pref->disp); - M_ILD(REG_ITMP3, REG_PV, disp); - M_IST_INTERN(REG_ITMP3, REG_SP, 1 * 4); - - /* move patcher function pointer onto stack */ - - disp = dseg_add_functionptr(cd, pref->patcher); - M_ALD(REG_ITMP3, REG_PV, disp); - M_AST_INTERN(REG_ITMP3, REG_SP, 0 * 4); - - if (targetdisp == 0) { - targetdisp = ((u4 *) cd->mcodeptr) - ((u4 *) cd->mcodebase); - - disp = dseg_add_functionptr(cd, asm_patcher_wrapper); - M_ALD(REG_ITMP3, REG_PV, disp); - M_MTCTR(REG_ITMP3); - M_RTS; - } - else { - disp = (((u4 *) cd->mcodebase) + targetdisp) - - (((u4 *) cd->mcodeptr) + 1); - M_BR(disp); - } } } diff --git a/src/vm/jit/powerpc/linux/md-os.c b/src/vm/jit/powerpc/linux/md-os.c index d5e90ef2f..1f8b1664c 100644 --- a/src/vm/jit/powerpc/linux/md-os.c +++ b/src/vm/jit/powerpc/linux/md-os.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: md-os.c 8178 2007-07-05 11:13:20Z michi $ + $Id: md-os.c 8216 2007-07-19 13:51:21Z michi $ */ @@ -125,11 +125,13 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) o = exceptions_new_hardware_exception(pv, sp, ra, xpc, type, val, &sfi); - /* set registers */ + /* set registers (only if exception object ready) */ - _gregs[REG_ITMP1_XPTR] = (ptrint) o; - _gregs[REG_ITMP2_XPC] = (ptrint) xpc; - _gregs[PT_NIP] = (ptrint) asm_handle_exception; + if (o != NULL) { + _gregs[REG_ITMP1_XPTR] = (ptrint) o; + _gregs[REG_ITMP2_XPC] = (ptrint) xpc; + _gregs[PT_NIP] = (ptrint) asm_handle_exception; + } } diff --git a/src/vm/jit/powerpc/patcher.c b/src/vm/jit/powerpc/patcher.c index 275acb322..105f7a583 100644 --- a/src/vm/jit/powerpc/patcher.c +++ b/src/vm/jit/powerpc/patcher.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: patcher.c 7596 2007-03-28 21:05:53Z twisti $ + $Id: patcher.c 8216 2007-07-19 13:51:21Z michi $ */ @@ -41,9 +41,9 @@ #include "vm/initialize.h" #include "vm/jit/asmpart.h" -#include "vm/jit/patcher.h" #include "vm/jit/md.h" #include "vm/jit/methodheader.h" +#include "vm/jit/patcher-common.h" #include "vm/jit/stacktrace.h" #include "vmcore/class.h" @@ -53,90 +53,9 @@ #include "vmcore/references.h" -/* patcher_wrapper ************************************************************* - - Wrapper for all patchers. It also creates the stackframe info - structure. - - If the return value of the patcher function is false, it gets the - exception object, clears the exception pointer and returns the - exception. - -*******************************************************************************/ - -java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) -{ - stackframeinfo sfi; - u1 *xpc; - java_objectheader *o; - u4 mcode; - functionptr f; - bool result; - java_objectheader *e; - - /* define the patcher function */ - - bool (*patcher_function)(u1 *); - - assert(pv != NULL); - - /* get stuff from the stack */ - - xpc = (u1 *) *((ptrint *) (sp + 5 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 4)); - f = (functionptr) *((ptrint *) (sp + 0 * 4)); - - /* Correct RA is calculated in codegen.c and stored in the patcher - stub stack. There's no need to adjust xpc. */ - - /* store PV into the patcher function position */ - - *((ptrint *) (sp + 0 * 4)) = (ptrint) pv; - - /* cast the passed function to a patcher function */ - - patcher_function = (bool (*)(u1 *)) (ptrint) f; - - /* enter a monitor on the patching position */ - - PATCHER_MONITORENTER; - - /* create the stackframeinfo */ - - stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 8 * 4, ra, xpc); - - /* call the proper patcher function */ - - result = (patcher_function)(sp); - - /* remove the stackframeinfo */ - - stacktrace_remove_stackframeinfo(&sfi); - - /* check for return value and exit accordingly */ - - if (result == false) { - e = exceptions_get_and_clear_exception(); - - PATCHER_MONITOREXIT; - - return e; - } - - /* patch back original code */ - - mcode = *((u4 *) (sp + 3 * 4)); - - *((u4 *) xpc) = mcode; - - /* synchronize instruction cache */ - - md_icacheflush(xpc, 4); - - PATCHER_MARK_PATCHED_MONITOREXIT; - - return NULL; -} +#define PATCH_BACK_ORIGINAL_MCODE \ + *((u4 *) pr->mpc) = (u4) pr->mcode; \ + md_icacheflush((u1 *) pr->mpc, 4); /* patcher_initialize_class **************************************************** @@ -146,13 +65,13 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) *******************************************************************************/ -bool patcher_initialize_class(u1 *sp) +bool patcher_initialize_class(patchref_t *pr) { classinfo *c; /* get stuff from the stack */ - c = (classinfo *) *((ptrint *) (sp + 2 * 4)); + c = (classinfo *) pr->ref; /* check if the class is initialized */ @@ -160,6 +79,8 @@ bool patcher_initialize_class(u1 *sp) if (!initialize_class(c)) return false; + PATCH_BACK_ORIGINAL_MCODE; + return true; } @@ -172,19 +93,21 @@ bool patcher_initialize_class(u1 *sp) *******************************************************************************/ #ifdef ENABLE_VERIFIER -bool patcher_resolve_class(u1 *sp) +bool patcher_resolve_class(patchref_t *pr) { unresolved_class *uc; /* get stuff from the stack */ - uc = (unresolved_class *) *((ptrint *) (sp + 2 * 4)); + uc = (unresolved_class *) pr->ref; /* resolve the class and check subtype constraints */ if (!resolve_class_eager_no_access_check(uc)) return false; + PATCH_BACK_ORIGINAL_MCODE; + return true; } #endif /* ENABLE_VERIFIER */ @@ -221,31 +144,31 @@ bool patcher_resolve_class(u1 *sp) *******************************************************************************/ -bool patcher_resolve_classref_to_classinfo(u1 *sp) +bool patcher_resolve_classref_to_classinfo(patchref_t *pr) { constant_classref *cr; - s4 disp; - u1 *pv; + u1 *datap; classinfo *c; /* get stuff from the stack */ - cr = (constant_classref *) *((ptrint *) (sp + 2 * 4)); - disp = *((s4 *) (sp + 1 * 4)); - pv = (u1 *) *((ptrint *) (sp + 0 * 4)); + cr = (constant_classref *) pr->ref; + datap = (u1 *) pr->datap; /* get the classinfo */ if (!(c = resolve_classref_eager(cr))) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* patch the classinfo pointer */ - *((ptrint *) (pv + disp)) = (ptrint) c; + *((ptrint *) datap) = (ptrint) c; /* synchronize data cache */ - md_dcacheflush(pv + disp, SIZEOF_VOID_P); + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } @@ -269,31 +192,31 @@ bool patcher_resolve_classref_to_classinfo(u1 *sp) *******************************************************************************/ -bool patcher_resolve_classref_to_vftbl(u1 *sp) +bool patcher_resolve_classref_to_vftbl(patchref_t *pr) { constant_classref *cr; - s4 disp; - u1 *pv; + u1 *datap; classinfo *c; /* get stuff from the stack */ - cr = (constant_classref *) *((ptrint *) (sp + 2 * 4)); - disp = *((s4 *) (sp + 1 * 4)); - pv = (u1 *) *((ptrint *) (sp + 0 * 4)); + cr = (constant_classref *) pr->ref; + datap = (u1 *) pr->datap; /* get the fieldinfo */ if (!(c = resolve_classref_eager(cr))) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* patch super class' vftbl */ - *((ptrint *) (pv + disp)) = (ptrint) c->vftbl; + *((ptrint *) datap) = (ptrint) c->vftbl; /* synchronize data cache */ - md_dcacheflush(pv + disp, SIZEOF_VOID_P); + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } @@ -308,31 +231,31 @@ bool patcher_resolve_classref_to_vftbl(u1 *sp) *******************************************************************************/ -bool patcher_resolve_classref_to_flags(u1 *sp) +bool patcher_resolve_classref_to_flags(patchref_t *pr) { constant_classref *cr; - s4 disp; - u1 *pv; + u1 *datap; classinfo *c; /* get stuff from the stack */ - cr = (constant_classref *) *((ptrint *) (sp + 2 * 4)); - disp = *((s4 *) (sp + 1 * 4)); - pv = (u1 *) *((ptrint *) (sp + 0 * 4)); + cr = (constant_classref *) pr->ref; + datap = (u1 *) pr->datap; /* get the fieldinfo */ if (!(c = resolve_classref_eager(cr))) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* patch class flags */ - *((s4 *) (pv + disp)) = (s4) c->flags; + *((s4 *) datap) = (s4) c->flags; /* synchronize data cache */ - md_dcacheflush(pv + disp, SIZEOF_VOID_P); + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } @@ -345,31 +268,31 @@ bool patcher_resolve_classref_to_flags(u1 *sp) *******************************************************************************/ #if !defined(WITH_STATIC_CLASSPATH) -bool patcher_resolve_native_function(u1 *sp) +bool patcher_resolve_native_function(patchref_t *pr) { methodinfo *m; - s4 disp; - u1 *pv; + u1 *datap; functionptr f; /* get stuff from the stack */ - m = (methodinfo *) *((ptrint *) (sp + 2 * 4)); - disp = *((s4 *) (sp + 1 * 4)); - pv = (u1 *) *((ptrint *) (sp + 0 * 4)); + m = (methodinfo *) pr->ref; + datap = (u1 *) pr->datap; /* resolve native function */ if (!(f = native_resolve_function(m))) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* patch native function pointer */ - *((ptrint *) (pv + disp)) = (ptrint) f; + *((ptrint *) datap) = (ptrint) f; /* synchronize data cache */ - md_dcacheflush(pv + disp, SIZEOF_VOID_P); + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } @@ -386,22 +309,18 @@ bool patcher_resolve_native_function(u1 *sp) *******************************************************************************/ -bool patcher_get_putstatic(u1 *sp) +bool patcher_get_putstatic(patchref_t *pr) { u1 *ra; - u4 mcode; unresolved_field *uf; - s4 disp; - u1 *pv; + u1 *datap; fieldinfo *fi; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - mcode = *((u4 *) (sp + 3 * 4)); - uf = (unresolved_field *) *((ptrint *) (sp + 2 * 4)); - disp = *((s4 *) (sp + 1 * 4)); - pv = (u1 *) *((ptrint *) (sp + 0 * 4)); + ra = (u1 *) pr->mpc; + uf = (unresolved_field *) pr->ref; + datap = (u1 *) pr->datap; /* get the fieldinfo */ @@ -414,13 +333,15 @@ bool patcher_get_putstatic(u1 *sp) if (!initialize_class(fi->class)) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* patch the field value's address */ - *((ptrint *) (pv + disp)) = (ptrint) &(fi->value); + *((ptrint *) datap) = (ptrint) &(fi->value); /* synchronize data cache */ - md_dcacheflush(pv + disp, SIZEOF_VOID_P); + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } @@ -435,74 +356,53 @@ bool patcher_get_putstatic(u1 *sp) *******************************************************************************/ -bool patcher_get_putfield(u1 *sp) +bool patcher_get_putfield(patchref_t *pr) { u1 *ra; unresolved_field *uf; - u1 *pv; fieldinfo *fi; s2 disp; - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - uf = (unresolved_field *) *((ptrint *) (sp + 2 * 4)); - pv = (u1 *) *((ptrint *) (sp + 1 * 4)); + ra = (u1 *) pr->mpc; + uf = (unresolved_field *) pr->ref; /* get the fieldinfo */ if (!(fi = resolve_field_eager(uf))) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* if we show NOPs, we have to skip them */ - if (opt_shownops) { - /* patch the field's offset */ - - if (IS_LNG_TYPE(fi->type)) { - /* If the field has type long, we have to patch two - instructions. But we have to check which instruction - is first. We do that with the offset of the first - instruction. */ - - disp = *((u4 *) (ra + 1 * 4)); - - if (disp == 4) { - *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); - *((u4 *) (ra + 2 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); - } - else { - *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); - *((u4 *) (ra + 2 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); - } + if (opt_shownops) + ra = ra + 1 * 4; + + /* patch the field's offset */ + + if (IS_LNG_TYPE(fi->type)) { + /* If the field has type long, we have to patch two + instructions. But we have to check which instruction + is first. We do that with the offset of the first + instruction. */ + + disp = *((u4 *) (ra + 0 * 4)); + + if (disp == 4) { + *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); + *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); } - else - *((u4 *) (ra + 1 * 4)) |= (s2) (fi->offset & 0x0000ffff); - } - else { - if (IS_LNG_TYPE(fi->type)) { - - disp = *((u4 *) (sp + 3 * 4)); - - /* We patch the first instruction in the patcher stub - stack and the second in the code. The first - instruction is patched back later in - patcher_wrapper. */ - - if (disp == 4) { - *((u4 *) (sp + 3 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); - *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); - } - else { - *((u4 *) (sp + 3 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); - *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); - } + else { + *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); + *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); } - else - *((u4 *) (sp + 3 * 4)) |= (s2) (fi->offset & 0x0000ffff); } + else + *((u4 *) (ra + 0 * 4)) |= (s2) (fi->offset & 0x0000ffff); /* synchronize instruction cache */ - md_icacheflush(ra + 1 * 4, 2 * 4); + md_icacheflush(ra + 0 * 4, 2 * 4); return true; } @@ -519,31 +419,31 @@ bool patcher_get_putfield(u1 *sp) ******************************************************************************/ -bool patcher_invokestatic_special(u1 *sp) +bool patcher_invokestatic_special(patchref_t *pr) { unresolved_method *um; - s4 disp; - u1 *pv; + u1 *datap; methodinfo *m; /* get stuff from the stack */ - um = (unresolved_method *) *((ptrint *) (sp + 2 * 4)); - disp = *((s4 *) (sp + 1 * 4)); - pv = (u1 *) *((ptrint *) (sp + 0 * 4)); + um = (unresolved_method *) pr->ref; + datap = (u1 *) pr->datap; /* get the fieldinfo */ if (!(m = resolve_method_eager(um))) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* patch stubroutine */ - *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine; + *((ptrint *) datap) = (ptrint) m->stubroutine; /* synchronize data cache */ - md_dcacheflush(pv + disp, SIZEOF_VOID_P); + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } @@ -561,7 +461,7 @@ bool patcher_invokestatic_special(u1 *sp) *******************************************************************************/ -bool patcher_invokevirtual(u1 *sp) +bool patcher_invokevirtual(patchref_t *pr) { u1 *ra; unresolved_method *um; @@ -570,14 +470,16 @@ bool patcher_invokevirtual(u1 *sp) /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - um = (unresolved_method *) *((ptrint *) (sp + 2 * 4)); + ra = (u1 *) pr->mpc; + um = (unresolved_method *) pr->ref; /* get the fieldinfo */ if (!(m = resolve_method_eager(um))) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* if we show NOPs, we have to skip them */ if (opt_shownops) @@ -610,7 +512,7 @@ bool patcher_invokevirtual(u1 *sp) *******************************************************************************/ -bool patcher_invokeinterface(u1 *sp) +bool patcher_invokeinterface(patchref_t *pr) { u1 *ra; unresolved_method *um; @@ -619,14 +521,16 @@ bool patcher_invokeinterface(u1 *sp) /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - um = (unresolved_method *) *((ptrint *) (sp + 2 * 4)); + ra = (u1 *) pr->mpc; + um = (unresolved_method *) pr->ref; /* get the fieldinfo */ if (!(m = resolve_method_eager(um))) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* if we show NOPs, we have to skip them */ if (opt_shownops) @@ -671,7 +575,7 @@ bool patcher_invokeinterface(u1 *sp) *******************************************************************************/ -bool patcher_checkcast_interface(u1 *sp) +bool patcher_checkcast_interface(patchref_t *pr) { u1 *ra; constant_classref *cr; @@ -680,14 +584,16 @@ bool patcher_checkcast_interface(u1 *sp) /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 2 * 4)); + ra = (u1 *) pr->mpc; + cr = (constant_classref *) pr->ref; /* get the fieldinfo */ if (!(c = resolve_classref_eager(cr))) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* if we show NOPs, we have to skip them */ if (opt_shownops) @@ -725,7 +631,7 @@ bool patcher_checkcast_interface(u1 *sp) *******************************************************************************/ -bool patcher_instanceof_interface(u1 *sp) +bool patcher_instanceof_interface(patchref_t *pr) { u1 *ra; constant_classref *cr; @@ -734,14 +640,16 @@ bool patcher_instanceof_interface(u1 *sp) /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 2 * 4)); + ra = (u1 *) pr->mpc; + cr = (constant_classref *) pr->ref; /* get the fieldinfo */ if (!(c = resolve_classref_eager(cr))) return false; + PATCH_BACK_ORIGINAL_MCODE; + /* if we show NOPs, we have to skip them */ if (opt_shownops) -- 2.25.1