X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Falpha%2Fpatcher.c;h=253465b71d9e6d22f99f17f97de0b75cde0d2e80;hb=323ce1100da6d6e62cf9bc74a1efa5da401e03ed;hp=84e08cf7ab3457ad6e499072352bd52be8e7a074;hpb=0cb9e5b1b15311480fb95d9df053644a3e025e80;p=cacao.git diff --git a/src/vm/jit/alpha/patcher.c b/src/vm/jit/alpha/patcher.c index 84e08cf7a..253465b71 100644 --- a/src/vm/jit/alpha/patcher.c +++ b/src/vm/jit/alpha/patcher.c @@ -22,8 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: patcher.c 7251 2007-01-29 20:24:53Z twisti $ - */ @@ -33,6 +31,8 @@ #include "vm/types.h" +#include "vm/jit/alpha/md.h" + #include "mm/memory.h" #include "native/native.h" @@ -42,8 +42,7 @@ #include "vm/initialize.h" #include "vm/jit/asmpart.h" -#include "vm/jit/patcher.h" -#include "vm/jit/md.h" +#include "vm/jit/patcher-common.h" #include "vm/jit/methodheader.h" #include "vm/jit/stacktrace.h" @@ -51,146 +50,24 @@ #include "vmcore/field.h" #include "vmcore/options.h" #include "vmcore/references.h" -#include "vmcore/resolve.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 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); - f = (functionptr) *((ptrint *) (sp + 0 * 8)); - - /* calculate and set the new return address */ - - xpc = xpc - 1 * 4; - - *((ptrint *) (sp + 5 * 8)) = (ptrint) xpc; - - /* store PV into the patcher function position */ - - *((ptrint *) (sp + 0 * 8)) = (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 + 6 * 8, ra, xpc); - - /* call the proper patcher function */ - - result = (patcher_function)(sp); - - /* remove the stackframeinfo */ - - stacktrace_remove_stackframeinfo(&sfi); - - /* check for an error, get the exception and return it */ - - if (result == false) { - e = exceptions_get_and_clear_exception(); - - PATCHER_MONITOREXIT; - - return e; - } - - /* patch back original code */ +#include "vm/resolve.h" - mcode = *((u4 *) (sp + 3 * 8)); - *((u4 *) xpc) = mcode; +#define PATCH_BACK_ORIGINAL_MCODE \ + *((u4 *) pr->mpc) = (u4) pr->mcode; \ + md_icacheflush(NULL, 0); - /* synchronize instruction cache */ - md_icacheflush(NULL, 0); - - PATCHER_MARK_PATCHED_MONITOREXIT; - - return NULL; -} - -/* patcher_initialize_class **************************************************** - - Initalizes a given classinfo pointer. This function does not patch - any data. - -*******************************************************************************/ - -bool patcher_initialize_class(u1 *sp) -{ - classinfo *c; - - /* get stuff from the stack */ - - c = (classinfo *) *((ptrint *) (sp + 2 * 8)); - - /* check if the class is initialized */ - - if (!(c->state & CLASS_INITIALIZED)) - if (!initialize_class(c)) - return false; - - return true; -} - -/* patcher_resolve_class ***************************************************** +/* patcher_patch_code ********************************************************** - Initalizes a given classinfo pointer. This function does not patch - any data. + Just patches back the original machine code. *******************************************************************************/ -#ifdef ENABLE_VERIFIER -bool patcher_resolve_class(u1 *sp) +void patcher_patch_code(patchref_t *pr) { - unresolved_class *uc; - classinfo *c; - - /* get stuff from the stack */ - - uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8)); - - /* resolve the class */ - - if (!resolve_class(uc, resolveEager, false, &c)) - return false; - - return true; + PATCH_BACK_ORIGINAL_MCODE; } -#endif /* ENABLE_VERIFIER */ /* patcher_resolve_classref_to_classinfo *************************************** @@ -217,27 +94,27 @@ 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 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); + 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; return true; } @@ -254,27 +131,27 @@ 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 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); + 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; return true; } @@ -288,64 +165,30 @@ 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 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); + cr = (constant_classref *) pr->ref; + datap = (u1 *) pr->datap; /* get the fieldinfo */ if (!(c = resolve_classref_eager(cr))) return false; - /* patch class flags */ - - *((s4 *) (pv + disp)) = (s4) c->flags; - - return true; -} - + PATCH_BACK_ORIGINAL_MCODE; -/* patcher_resolve_native_function ********************************************* - - XXX - -*******************************************************************************/ - -#if !defined(WITH_STATIC_CLASSPATH) -bool patcher_resolve_native_function(u1 *sp) -{ - methodinfo *m; - s4 disp; - u1 *pv; - functionptr f; - - /* get stuff from the stack */ - - m = (methodinfo *) *((ptrint *) (sp + 2 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); - - /* resolve native function */ - - if (!(f = native_resolve_function(m))) - return false; - - /* patch native function pointer */ + /* patch class flags */ - *((ptrint *) (pv + disp)) = (ptrint) f; + *((s4 *) datap) = (s4) c->flags; return true; } -#endif /* !defined(WITH_STATIC_CLASSPATH) */ /* patcher_get_putstatic ******************************************************* @@ -358,18 +201,16 @@ bool patcher_resolve_native_function(u1 *sp) *******************************************************************************/ -bool patcher_get_putstatic(u1 *sp) +bool patcher_get_putstatic(patchref_t *pr) { unresolved_field *uf; - s4 disp; - u1 *pv; + u1 *datap; fieldinfo *fi; /* get stuff from the stack */ - uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); + uf = (unresolved_field *) pr->ref; + datap = (u1 *) pr->datap; /* get the fieldinfo */ @@ -382,9 +223,11 @@ 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); + *((intptr_t *) datap) = (intptr_t) fi->value; return true; } @@ -399,32 +242,32 @@ bool patcher_get_putstatic(u1 *sp) *******************************************************************************/ -bool patcher_get_putfield(u1 *sp) +bool patcher_get_putfield(patchref_t *pr) { u1 *ra; unresolved_field *uf; fieldinfo *fi; - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8)); + 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 disassembly, we have to skip the nop */ - if (opt_shownops) { - /* patch the field's offset into the instruction */ + if (opt_shownops) + ra = ra + 4; + + /* patch the field's offset into the instruction */ - *((u4 *) (ra + 4)) |= (s2) (fi->offset & 0x0000ffff); - } - else { - /* otherwise store the patched instruction on the stack */ + *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff); - *((u4 *) (sp + 3 * 8)) |= (s2) (fi->offset & 0x0000ffff); - } + md_icacheflush(NULL, 0); return true; } @@ -440,27 +283,27 @@ 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 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); + 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; return true; } @@ -477,7 +320,7 @@ bool patcher_invokestatic_special(u1 *sp) *******************************************************************************/ -bool patcher_invokevirtual(u1 *sp) +bool patcher_invokevirtual(patchref_t *pr) { u1 *ra; unresolved_method *um; @@ -485,14 +328,16 @@ bool patcher_invokevirtual(u1 *sp) /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - um = (unresolved_method *) *((ptrint *) (sp + 2 * 8)); + 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 disassembly, we have to skip the nop */ if (opt_shownops) @@ -503,6 +348,8 @@ bool patcher_invokevirtual(u1 *sp) *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex) & 0x0000ffff); + md_icacheflush(NULL, 0); + return true; } @@ -519,7 +366,7 @@ bool patcher_invokevirtual(u1 *sp) *******************************************************************************/ -bool patcher_invokeinterface(u1 *sp) +bool patcher_invokeinterface(patchref_t *pr) { u1 *ra; unresolved_method *um; @@ -527,14 +374,16 @@ bool patcher_invokeinterface(u1 *sp) /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - um = (unresolved_method *) *((ptrint *) (sp + 2 * 8)); + 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 disassembly, we have to skip the nop */ if (opt_shownops) @@ -550,11 +399,62 @@ bool patcher_invokeinterface(u1 *sp) *((s4 *) (ra + 4 + 4)) |= (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff); + md_icacheflush(NULL, 0); + + return true; +} + + +/* patcher_checkcast_interface ************************************************* + + Machine code: + + + a78e0000 ldq at,0(s5) + a3bc001c ldl gp,28(at) + 23bdfffd lda gp,-3(gp) + efa0002e ble gp,0x00000200002bf6b0 + a7bcffe8 ldq gp,-24(at) + +*******************************************************************************/ + +bool patcher_checkcast_interface(patchref_t *pr) +{ + u1 *ra; + constant_classref *cr; + classinfo *c; + + /* get stuff from the stack */ + + 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 disassembly, we have to skip the nop */ + + if (opt_shownops) + ra = ra + 4; + + /* 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); + + md_icacheflush(NULL, 0); + return true; } -/* patcher_checkcast_instanceof_interface ************************************** +/* patcher_instanceof_interface ************************************************ Machine code: @@ -567,7 +467,7 @@ bool patcher_invokeinterface(u1 *sp) *******************************************************************************/ -bool patcher_checkcast_instanceof_interface(u1 *sp) +bool patcher_instanceof_interface(patchref_t *pr) { u1 *ra; constant_classref *cr; @@ -575,14 +475,16 @@ bool patcher_checkcast_instanceof_interface(u1 *sp) /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); + 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 disassembly, we have to skip the nop */ if (opt_shownops) @@ -595,6 +497,8 @@ bool patcher_checkcast_instanceof_interface(u1 *sp) *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*)) & 0x0000ffff); + md_icacheflush(NULL, 0); + return true; }