X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fsparc64%2Fpatcher.c;h=8276672543ad85ba27aff78042821c566f78d0a6;hb=9f859ad50d3d5d98c185d40b86b2179bc4dc9aeb;hp=0939fd2c61a3f45b5af02503d4708174304def41;hpb=18557c7e9d7ece9b3173ff7bce74d999b45b557d;p=cacao.git diff --git a/src/vm/jit/sparc64/patcher.c b/src/vm/jit/sparc64/patcher.c index 0939fd2c6..827667254 100644 --- a/src/vm/jit/sparc64/patcher.c +++ b/src/vm/jit/sparc64/patcher.c @@ -1,4 +1,4 @@ -/* src/vm/jit/mips/patcher.c - MIPS code patching functions +/* src/vm/jit/mips/patcher.c - SPARC code patching functions Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, @@ -22,40 +22,39 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Contact: cacao@cacaojvm.org - - Authors: Christian Thalinger - - Changes: - - $Id: patcher.c 5164 2006-07-19 15:54:01Z twisti $ - */ #include "config.h" #include +#include #include "vm/types.h" +#include "mm/memory.h" + +#include "vm/jit/sparc64/md-abi.h" #include "vm/jit/sparc64/codegen.h" -#include "mm/memory.h" #include "native/native.h" #include "vm/builtin.h" -#include "vm/class.h" #include "vm/exceptions.h" -#include "vm/field.h" #include "vm/initialize.h" -#include "vm/options.h" -#include "vm/resolve.h" -#include "vm/references.h" + #include "vm/jit/asmpart.h" #include "vm/jit/patcher.h" +#include "vm/jit/md.h" +#include "vm/jit/methodheader.h" +#include "vm/jit/stacktrace.h" + +#include "vmcore/class.h" +#include "vmcore/field.h" +#include "vmcore/options.h" +#include "vmcore/references.h" +#include "vm/resolve.h" -#include "vm/jit/sparc64/md-abi.h" - +#include "vm/jit/sparc64/solaris/macro_rename.h" /* patcher_wrapper ************************************************************* @@ -68,12 +67,12 @@ *******************************************************************************/ -java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) +java_object_t *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) { stackframeinfo sfi; u1 *xpc; u1 *javasp; - java_objectheader *o; + java_object_t *o; #if SIZEOF_VOID_P == 8 u8 mcode; #else @@ -81,9 +80,8 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) #endif functionptr f; bool result; - java_objectheader *e; + java_handle_t *e; - /* define the patcher function */ bool (*patcher_function)(u1 *); @@ -93,7 +91,7 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) /* get stuff from the stack */ xpc = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); + o = (java_object_t *) *((ptrint *) (sp + 4 * 8)); f = (functionptr) *((ptrint *) (sp + 0 * 8)); /* store PV into the patcher function position */ @@ -108,9 +106,10 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) PATCHER_MONITORENTER; - /* calculate sp of the current java function considering the WINSAVE regs */ + /* the (data) sp points directly to the patcher fields */ + /* calculate the real sp of the current java function considering the WINSAVE regs */ - javasp = sp - 16 * 8 - BIAS; + javasp = sp - JITSTACK_CNT * 8 - BIAS; /* create the stackframeinfo */ @@ -134,13 +133,13 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) return e; } - /* patch back original code */ + /* patch back original (potentially patched) code */ #if SIZEOF_VOID_P == 8 mcode = *((u8 *) (sp + 3 * 8)); - *((u4 *) (xpc + 0 * 4)) = mcode; - *((u4 *) (xpc + 1 * 4)) = mcode >> 32; + *((u4 *) (xpc + 0 * 4)) = mcode >> 32; + *((u4 *) (xpc + 1 * 4)) = mcode; #else mcode[0] = *((u4 *) (sp + 3 * 8)); mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); @@ -179,7 +178,6 @@ bool patcher_get_putstatic(u1 *sp) /* get stuff from the stack */ - uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8)); disp = *((s4 *) (sp + 1 * 8)); pv = (u1 *) *((ptrint *) (sp + 0 * 8)); @@ -197,7 +195,7 @@ bool patcher_get_putstatic(u1 *sp) /* patch the field value's address */ - *((ptrint *) (pv + disp)) = (ptrint) &(fi->value); + *((intptr_t *) (pv + disp)) = (intptr_t) fi->value; /* synchronize data cache */ @@ -219,23 +217,11 @@ bool patcher_get_putstatic(u1 *sp) bool patcher_get_putfield(u1 *sp) { u1 *ra; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif unresolved_field *uf; fieldinfo *fi; - assert(0); ra = (u1 *) *((ptrint *) (sp + 5 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8)); /* get the fieldinfo */ @@ -243,50 +229,22 @@ bool patcher_get_putfield(u1 *sp) if (!(fi = resolve_field_eager(uf))) return false; - /* patch back original code */ - -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif - /* if we show disassembly, we have to skip the nop's */ if (opt_shownops) { - ra = ra + PATCHER_CALL_SIZE; + /* patch the field's offset into the instruction */ -#if SIZEOF_VOID_P == 4 - if (fi->type == TYPE_LNG) { -# if WORDS_BIGENDIAN == 1 - /* ATTENTION: order of these instructions depend on M_LLD_INTERN */ - *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); - *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); -# else - /* ATTENTION: order of these instructions depend on M_LLD_INTERN */ - *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); - *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); -# endif - } else -#endif - *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff); + *((u4 *) (ra + 2 * 4)) |= (s2) (fi->offset & 0x00001fff); - /* synchronize instruction cache */ + /* synchronize instruction cache */ - if (opt_showdisassemble) { -#if SIZEOF_VOID_P == 4 - if (fi->type == TYPE_LNG) - md_icacheflush(ra - 2 * 4, 4 * 4); - else -#endif - md_icacheflush(ra - 2 * 4, 3 * 4); + md_icacheflush(ra + 2 * 4, 1 * 4); } else { - md_icacheflush(ra, 2 * 4); + /* otherwise store the patched instruction on the stack */ + + *((u4 *) (sp + 3 * 8)) |= (s2) (fi->offset & 0x00001fff); } -} return true; } @@ -462,10 +420,10 @@ bool patcher_invokestatic_special(u1 *sp) Machine code: - xxx ldx t9,0(a0) - xxx ldx s8,64(t9) - xxx jmpl s8 - 00000000 nop + xxx ldx g2,0(o0) + xxx ldx o5,64(g2) + xxx jmpl o5 + xxx nop *******************************************************************************/ @@ -475,8 +433,6 @@ bool patcher_invokevirtual(u1 *sp) unresolved_method *um; methodinfo *m; - assert(0); - /* get stuff from the stack */ ra = (u1 *) *((ptrint *) (sp + 5 * 8)); @@ -492,13 +448,13 @@ bool patcher_invokevirtual(u1 *sp) if (opt_shownops) { ra = ra + PATCHER_CALL_SIZE; - /* patch vftbl index */ + /* patch vftbl index */ *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex) & 0x00001fff); - /* synchronize instruction cache */ + /* synchronize instruction cache */ md_icacheflush(ra + 1 * 4, 1 * 4); } @@ -530,25 +486,12 @@ bool patcher_invokevirtual(u1 *sp) bool patcher_invokeinterface(u1 *sp) { u1 *ra; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif unresolved_method *um; methodinfo *m; - assert(0); - /* get stuff from the stack */ ra = (u1 *) *((ptrint *) (sp + 5 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif um = (unresolved_method *) *((ptrint *) (sp + 2 * 8)); /* get the fieldinfo */ @@ -556,37 +499,42 @@ bool patcher_invokeinterface(u1 *sp) if (!(m = resolve_method_eager(um))) return false; - /* patch back original code */ + /* if we show disassembly, we have to skip the nop's */ -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif + if (opt_shownops) { + ra = ra + PATCHER_CALL_SIZE; - /* if we show disassembly, we have to skip the nop's */ + /* patch interfacetable index */ - if (opt_showdisassemble) - ra = ra + 2 * 4; + *((s4 *) (ra + 1 * 4)) |= + (s4) ((OFFSET(vftbl_t, interfacetable[0]) - + sizeof(methodptr*) * m->class->index) & 0x00001fff); - /* patch interfacetable index */ + /* patch method offset */ - *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - - sizeof(methodptr*) * m->class->index) & 0x0000ffff); + *((s4 *) (ra + 2 * 4)) |= + (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x00001fff); - /* patch method offset */ + /* synchronize instruction cache */ - *((s4 *) (ra + 2 * 4)) |= - (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff); + md_icacheflush(ra + 1 * 4, 2 * 4); + } +else { + /* patch interfacetable index */ - /* synchronize instruction cache */ + *((s4 *) (sp + 3 * 8 + 4)) |= + (s4) ((OFFSET(vftbl_t, interfacetable[0]) - + sizeof(methodptr*) * m->class->index) & 0x00001fff); - if (opt_showdisassemble) - md_icacheflush(ra - 2 * 4, 5 * 4); - else - md_icacheflush(ra, 3 * 4); + /* patch method offset */ + + *((s4 *) (ra + 2 * 4)) |= + (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x00001fff); + + /* synchronize instruction cache */ + + md_icacheflush(ra + 2 * 4, 1 * 4); + } return true; } @@ -634,7 +582,7 @@ bool patcher_checkcast_instanceof_flags(u1 *sp) } -/* patcher_checkcast_instanceof_interface ************************************** +/* patcher_checkcast_interface ************************************** Machine code: @@ -648,28 +596,15 @@ bool patcher_checkcast_instanceof_flags(u1 *sp) *******************************************************************************/ -bool patcher_checkcast_instanceof_interface(u1 *sp) +bool patcher_checkcast_interface(u1 *sp) { u1 *ra; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif constant_classref *cr; classinfo *c; - assert(0); - /* get stuff from the stack */ ra = (u1 *) *((ptrint *) (sp + 5 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); /* get the fieldinfo */ @@ -677,32 +612,75 @@ bool patcher_checkcast_instanceof_interface(u1 *sp) if (!(c = resolve_classref_eager(cr))) return false; - /* patch back original code */ + /* if we show disassembly, we have to skip the nop's */ -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif + if (opt_shownops) + ra = ra + PATCHER_CALL_SIZE; + + /* patch super class index */ + + *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x00001fff); + + *((s4 *) (ra + (3 + EXCEPTION_CHECK_INSTRUCTIONS) * 4)) |= + (s4) ((OFFSET(vftbl_t, interfacetable[0]) + - c->index * sizeof(methodptr*)) & 0x00001fff); + + /* synchronize instruction cache */ + + if (opt_shownops) + md_icacheflush(ra - 2 * 4, (6 + EXCEPTION_CHECK_INSTRUCTIONS) * 4); + else + md_icacheflush(ra, (4 + EXCEPTION_CHECK_INSTRUCTIONS) * 4); + + return true; +} + +/* patcher_instanceof_interface ************************************************ + + Machine code: + + + dd030000 ld v1,0(a4) + 8c79001c lw t9,28(v1) + 27390000 addiu t9,t9,0 + 1b200082 blez t9,zero,0x000000001051843c + 00000000 nop + dc790000 ld t9,0(v1) + +*******************************************************************************/ + +bool patcher_instanceof_interface(u1 *sp) +{ + u1 *ra; + constant_classref *cr; + classinfo *c; + + /* get stuff from the stack */ + + ra = (u1 *) *((ptrint *) (sp + 5 * 8)); + cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); + + /* get the fieldinfo */ + + if (!(c = resolve_classref_eager(cr))) + return false; /* if we show disassembly, we have to skip the nop's */ - if (opt_showdisassemble) - ra = ra + 2 * 4; + if (opt_shownops) + ra = ra + PATCHER_CALL_SIZE; /* patch super class index */ - *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff); - - *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - - c->index * sizeof(methodptr*)) & 0x0000ffff); + *((s4 *) (ra + 2 * 4)) |= (s4) ((c->index) & 0x00001fff); + *((s4 *) (ra + 5 * 4)) |= + (s4) ((OFFSET(vftbl_t, interfacetable[0]) - + c->index * sizeof(methodptr*)) & 0x00001fff); /* synchronize instruction cache */ - if (opt_showdisassemble) - md_icacheflush(ra - 2 * 4, 8 * 4); + if (opt_shownops) + md_icacheflush(ra - PATCHER_CALL_SIZE * 4, 8 * 4); else md_icacheflush(ra, 6 * 4); @@ -786,15 +764,14 @@ bool patcher_clinit(u1 *sp) bool patcher_athrow_areturn(u1 *sp) { unresolved_class *uc; - classinfo *c; /* get stuff from the stack */ uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8)); - /* resolve the class */ + /* resolve the class and check subtype constraints */ - if (!resolve_class(uc, resolveEager, false, &c)) + if (!resolve_class_eager_no_access_check(uc)) return false; return true;