X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fs390%2Fpatcher.c;h=7148e7804c661c58d45e2aa4ca2457389dd592b6;hb=b8fd3429ec5849325ebd364e5f120084d442e922;hp=7bde50881ff8da92dc423570d7d1be06f1b484f3;hpb=3bd3f058b1c7cab92cb2e2876b3dd77ca9f9af40;p=cacao.git diff --git a/src/vm/jit/s390/patcher.c b/src/vm/jit/s390/patcher.c index 7bde50881..7148e7804 100644 --- a/src/vm/jit/s390/patcher.c +++ b/src/vm/jit/s390/patcher.c @@ -26,110 +26,47 @@ Authors: Christian Thalinger - Changes: - - $Id: patcher.c 7312 2007-02-10 00:49:37Z pm $ + Changes: Peter Molnar */ #include "config.h" -#include "vm/types.h" -#include "vm/jit/s390/codegen.h" +#include +#include #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/references.h" +#include "vm/jit/patcher-common.h" +#include "vm/jit/s390/codegen.h" +#include "vm/jit/s390/md-abi.h" +#include "vm/jit/stacktrace.h" #include "vm/resolve.h" -#include "vm/jit/patcher.h" +#include "vm/types.h" +#include "vmcore/class.h" +#include "vmcore/field.h" +#include "vmcore/options.h" +#include "vmcore/references.h" -#include -#define OOPS() assert(0); -#define __PORTED__ +#define PATCH_BACK_ORIGINAL_MCODE \ + *((u2 *) pr->mpc) = (u2) pr->mcode; + +#define PATCHER_TRACE -/* patcher_wrapper ************************************************************* - Wrapper for all patchers. It also creates the stackframe info - structure. +/* patcher_patch_code ********************************************************** - If the return value of the patcher function is false, it gets the - exception object, clears the exception pointer and returns the - exception. + Just patches back the original machine code. *******************************************************************************/ -java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) +void patcher_patch_code(patchref_t *pr) { - stackframeinfo sfi; - u1 *xpc; - java_objectheader *o; - functionptr f; - bool result; - java_objectheader *e; - - /* define the patcher function */ - - bool (*patcher_function)(u1 *); - - /* get stuff from the stack */ - - xpc = (u1 *) *((ptrint *) (sp + 5 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 4)); - f = (functionptr) *((ptrint *) (sp + 0 * 4)); - - /* TODO here was PATCHER_CALL_SIZE previously ! */ - xpc = xpc - 4; /* the patch position is 4 bytes before the RA */ - - *((ptrint *) (sp + 5 * 4)) = (ptrint) 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 */ - - /* RA is passed as NULL, but the XPC is correct and can be used in - stacktrace_create_extern_stackframeinfo for - md_codegen_get_pv_from_pc. */ - - stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 6 * 4, xpc, 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; - } - - PATCHER_MARK_PATCHED_MONITOREXIT; - - return NULL; + PATCH_BACK_ORIGINAL_MCODE; } @@ -139,22 +76,18 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) *******************************************************************************/ -bool patcher_get_putstatic(u1 *sp) +bool patcher_get_putstatic(patchref_t *pr) { - u1 *ra; - u4 mcode; unresolved_field *uf; - s4 disp; + u1 *datap; fieldinfo *fi; - u1 *pv; + + PATCHER_TRACE; /* 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)); + uf = (unresolved_field *) pr->ref; + datap = (u1 *) pr->datap; /* get the fieldinfo */ @@ -167,11 +100,11 @@ bool patcher_get_putstatic(u1 *sp) if (!initialize_class(fi->class)) return false; - *((ptrint *) (pv + disp)) = (ptrint) &(fi->value); + PATCH_BACK_ORIGINAL_MCODE; - /* patch back original code */ + /* patch the field value's address */ - *((u4 *) ra) = mcode; + *((intptr_t *) datap) = (intptr_t) fi->value; return true; } @@ -181,338 +114,108 @@ bool patcher_get_putstatic(u1 *sp) Machine code: - - 45 8b 8f 00 00 00 00 mov 0x0(%r15),%r9d - *******************************************************************************/ -bool patcher_get_putfield(u1 *sp) +bool patcher_get_putfield(patchref_t *pr) { - OOPS(); u1 *ra; - u8 mcode; unresolved_field *uf; fieldinfo *fi; - u1 byte; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8)); - - /* get the fieldinfo */ - - if (!(fi = resolve_field_eager(uf))) - return false; - - /* patch back original code (instruction code is smaller than 8 bytes) */ - - *((u4 *) (ra + 0)) = (u4) mcode; - *((u1 *) (ra + 4)) = (u1) (mcode >> 32); - - /* if we show disassembly, we have to skip the nop's */ - - if (opt_shownops) - ra = ra + 5; - - /* patch the field's offset: we check for the field type, because the */ - /* instructions have different lengths */ - - if (IS_INT_LNG_TYPE(fi->type)) { - /* check for special case: %rsp or %r12 as base register */ - - byte = *(ra + 3); - - if (byte == 0x24) - *((u4 *) (ra + 4)) = (u4) (fi->offset); - else - *((u4 *) (ra + 3)) = (u4) (fi->offset); - } - else { - /* check for special case: %rsp or %r12 as base register */ - - byte = *(ra + 5); - - if (byte == 0x24) - *((u4 *) (ra + 6)) = (u4) (fi->offset); - else - *((u4 *) (ra + 5)) = (u4) (fi->offset); - } - - return true; -} - - -/* patcher_putfieldconst ******************************************************* - - Machine code: - - - 41 c7 85 00 00 00 00 7b 00 00 00 movl $0x7b,0x0(%r13) + s4 disp; -*******************************************************************************/ - -bool patcher_putfieldconst(u1 *sp) -{ - OOPS(); - u1 *ra; - u8 mcode; - unresolved_field *uf; - fieldinfo *fi; + PATCHER_TRACE; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8)); + ra = (u1 *) pr->mpc; + uf = (unresolved_field *) pr->ref; + disp = pr->disp; /* get the fieldinfo */ if (!(fi = resolve_field_eager(uf))) return false; - /* patch back original code */ - - *((u8 *) ra) = mcode; + PATCH_BACK_ORIGINAL_MCODE; - /* if we show disassembly, we have to skip the nop's */ + /* If NOPs are generated, skip them */ if (opt_shownops) - ra = ra + 5; + ra += PATCHER_NOPS_SKIP; - /* patch the field's offset */ + /* If there is an operand load before, skip the load size passed in disp (see ICMD_PUTFIELD) */ - if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) { - /* handle special case when the base register is %r12 */ + ra += disp; - if (*(ra + 2) == 0x84) { - *((u4 *) (ra + 4)) = (u4) (fi->offset); - *((u4 *) (ra + 12 + 4)) = (u4) (fi->offset + 4); - } - else { - *((u4 *) (ra + 3)) = (u4) (fi->offset); - *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4); - } - } - else { - /* handle special case when the base register is %r12 */ + /* patch correct offset */ - if (*(ra + 2) == 0x84) - *((u4 *) (ra + 4)) = (u4) (fi->offset); - else - *((u4 *) (ra + 3)) = (u4) (fi->offset); + if (fi->type == TYPE_LNG) { + ASSERT_VALID_DISP(fi->offset + 4); + /* 2 RX operations, for 2 words; each already contains a 0 or 4 offset. */ + N_RX_SET_DISP(ra, fi->offset + N_RX_GET_DISP(ra)); + ra += SZ_RX; + N_RX_SET_DISP(ra, fi->offset + N_RX_GET_DISP(ra)); + } else { + ASSERT_VALID_DISP(fi->offset); + /* 1 RX operation */ + N_RX_SET_DISP(ra, fi->offset); } return true; } - -/* patcher_aconst ************************************************************** - - Machine code: - - - 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi - -*******************************************************************************/ - -bool patcher_aconst(u1 *sp) -{ - OOPS(); - u1 *ra; - u8 mcode; - constant_classref *cr; - classinfo *c; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - - /* get the classinfo */ - - if (!(c = resolve_classref_eager(cr))) - return false; - - /* patch back original code */ - - *((u8 *) ra) = mcode; - - /* if we show disassembly, we have to skip the nop's */ - - if (opt_shownops) - ra = ra + 5; - - /* patch the classinfo pointer */ - - *((ptrint *) (ra + 2)) = (ptrint) c; - - return true; -} - - -/* patcher_builtin_multianewarray ********************************************** - - Machine code: - - - 48 bf 02 00 00 00 00 00 00 00 mov $0x2,%rdi - 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi - 48 89 e2 mov %rsp,%rdx - 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax - 48 ff d0 callq *%rax - -*******************************************************************************/ - -bool patcher_builtin_multianewarray(u1 *sp) -{ - OOPS(); - u1 *ra; - u8 mcode; - constant_classref *cr; - classinfo *c; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - - /* get the classinfo */ - - if (!(c = resolve_classref_eager(cr))) - return false; - - /* patch back original code */ - - *((u8 *) ra) = mcode; - - /* if we show disassembly, we have to skip the nop's */ - - if (opt_shownops) - ra = ra + 5; - - /* patch the classinfo pointer */ - - *((ptrint *) (ra + 10 + 2)) = (ptrint) c; - - return true; -} - - -/* patcher_builtin_arraycheckcast ********************************************** - - Machine code: - - - 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi - 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax - 48 ff d0 callq *%rax - -*******************************************************************************/ - -bool patcher_builtin_arraycheckcast(u1 *sp) -{ - OOPS(); - u1 *ra; - u8 mcode; - constant_classref *cr; - classinfo *c; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - - /* get the classinfo */ - - if (!(c = resolve_classref_eager(cr))) - return false; - - /* patch back original code */ - - *((u8 *) ra) = mcode; - - /* if we show disassembly, we have to skip the nop's */ - - if (opt_shownops) - ra = ra + 5; - - /* patch the classinfo pointer */ - - *((ptrint *) (ra + 2)) = (ptrint) c; - - return true; -} - - /* patcher_invokestatic_special ************************************************ Machine code: *******************************************************************************/ -__PORTED__ bool patcher_invokestatic_special(u1 *sp) +bool patcher_invokestatic_special(patchref_t *pr) { - u1 *ra; - u4 mcode; unresolved_method *um; - s4 disp; - u1 *pv; + u1 *datap; methodinfo *m; + PATCHER_TRACE; + /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - mcode = *((u4 *) (sp + 3 * 4)); - 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; - *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine; - - /* patch back original code */ - - *((u4 *) ra) = mcode; + PATCH_BACK_ORIGINAL_MCODE; /* patch stubroutine */ + *((ptrint *) datap) = (ptrint) m->stubroutine; + return true; } - /* patcher_invokevirtual ******************************************************* Machine code: - - 4c 8b 17 mov (%rdi),%r10 - 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax - 48 ff d0 callq *%rax - *******************************************************************************/ -bool patcher_invokevirtual(u1 *sp) +bool patcher_invokevirtual(patchref_t *pr) { - OOPS(); u1 *ra; - u8 mcode; unresolved_method *um; methodinfo *m; + s4 off; + + PATCHER_TRACE; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - um = (unresolved_method *) *((ptrint *) (sp + 2 * 8)); + ra = (u1 *) pr->mpc; + um = (unresolved_method *) pr->ref; /* get the fieldinfo */ @@ -521,18 +224,23 @@ bool patcher_invokevirtual(u1 *sp) /* patch back original code */ - *((u8 *) ra) = mcode; + PATCH_BACK_ORIGINAL_MCODE; - /* if we show disassembly, we have to skip the nop's */ + /* If NOPs are generated, skip them */ if (opt_shownops) - ra = ra + 5; + ra += PATCHER_NOPS_SKIP; /* patch vftbl index */ - *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) + + + off = (s4) (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex); + ASSERT_VALID_DISP(off); + + N_RX_SET_DISP(ra + SZ_RX, off); + return true; } @@ -541,27 +249,21 @@ bool patcher_invokevirtual(u1 *sp) Machine code: - - 4c 8b 17 mov (%rdi),%r10 - 4d 8b 92 00 00 00 00 mov 0x0(%r10),%r10 - 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax - 48 ff d0 callq *%rax - *******************************************************************************/ -bool patcher_invokeinterface(u1 *sp) +bool patcher_invokeinterface(patchref_t *pr) { - OOPS(); u1 *ra; - u8 mcode; unresolved_method *um; methodinfo *m; + s4 idx, off; + + PATCHER_TRACE; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - um = (unresolved_method *) *((ptrint *) (sp + 2 * 8)); + ra = (u1 *) pr->mpc; + um = (unresolved_method *) pr->ref; /* get the fieldinfo */ @@ -570,23 +272,32 @@ bool patcher_invokeinterface(u1 *sp) /* patch back original code */ - *((u8 *) ra) = mcode; + PATCH_BACK_ORIGINAL_MCODE; - /* if we show disassembly, we have to skip the nop's */ + /* If NOPs are generated, skip them */ if (opt_shownops) - ra = ra + 5; + ra += PATCHER_NOPS_SKIP; + + /* get interfacetable index */ - /* patch interfacetable index */ + idx = (s4) (OFFSET(vftbl_t, interfacetable[0]) - + sizeof(methodptr) * m->class->index); - *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) - - sizeof(methodptr) * m->class->index); + ASSERT_VALID_IMM(idx); - /* patch method offset */ + /* get method offset */ - *((s4 *) (ra + 3 + 7 + 3)) = + off = (s4) (sizeof(methodptr) * (m - m->class->methods)); + ASSERT_VALID_DISP(off); + + /* patch them */ + + N_RI_SET_IMM(ra + SZ_L, idx); + N_RX_SET_DISP(ra + SZ_L + SZ_LHI + SZ_L, off); + return true; } @@ -599,35 +310,29 @@ bool patcher_invokeinterface(u1 *sp) *******************************************************************************/ -__PORTED__ 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; - u4 mcode; - u1 *ra; + + PATCHER_TRACE; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - mcode = *((u4 *) (sp + 3 * 4)); - 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 class flags */ + PATCH_BACK_ORIGINAL_MCODE; - *((s4 *) (pv + disp)) = (s4) c->flags; - - /* patch back original code */ + /* patch class flags */ - *((u4 *) ra) = mcode; + *((s4 *) datap) = (s4) c->flags; return true; } @@ -640,35 +345,29 @@ __PORTED__ bool patcher_resolve_classref_to_flags(u1 *sp) *******************************************************************************/ -__PORTED__ 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; - u4 mcode; - u1 *ra; + + PATCHER_TRACE; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - mcode = *((u4 *) (sp + 3 * 4)); - 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 the classinfo pointer */ + PATCH_BACK_ORIGINAL_MCODE; - *((ptrint *) (pv + disp)) = (ptrint) c; - - /* patch back original code */ + /* patch the classinfo pointer */ - *((u4 *) ra) = mcode; + *((ptrint *) datap) = (ptrint) c; return true; } @@ -680,35 +379,29 @@ __PORTED__ 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; - u4 mcode; - u1 *ra; + + PATCHER_TRACE; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - mcode = *((u4 *) (sp + 3 * 4)); - 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 super class' vftbl */ - - *((ptrint *) (pv + disp)) = (ptrint) c->vftbl; + PATCH_BACK_ORIGINAL_MCODE; - /* patch back original code */ + /* patch super class' vftbl */ - *((u4 *) ra) = mcode; + *((ptrint *) datap) = (ptrint) c->vftbl; return true; } @@ -717,127 +410,21 @@ bool patcher_resolve_classref_to_vftbl(u1 *sp) Machine code: - - 45 8b 9a 1c 00 00 00 mov 0x1c(%r10),%r11d - 49 81 eb 00 00 00 00 sub $0x0,%r11 - 4d 85 db test %r11,%r11 - 0f 8e 94 04 00 00 jle 0x00002aaaaab018f8 - 4d 8b 9a 00 00 00 00 mov 0x0(%r10),%r11 - *******************************************************************************/ -bool patcher_checkcast_instanceof_interface(u1 *sp) +bool patcher_checkcast_instanceof_interface(patchref_t *pr) { - OOPS(); - u1 *ra; - u8 mcode; - constant_classref *cr; - classinfo *c; - - /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - - /* get the fieldinfo */ - - if (!(c = resolve_classref_eager(cr))) - return false; - - /* patch back original code */ - - *((u8 *) ra) = mcode; - - /* if we show disassembly, we have to skip the nop's */ - - if (opt_shownops) - ra = ra + 5; - - /* patch super class index */ - - *((s4 *) (ra + 7 + 3)) = (s4) c->index; - - *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) = - (s4) (OFFSET(vftbl_t, interfacetable[0]) - - c->index * sizeof(methodptr*)); - - return true; -} - - -/* patcher_checkcast_class ***************************************************** - - Machine code: - - - 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11 - 45 8b 92 20 00 00 00 mov 0x20(%r10),%r10d - 45 8b 9b 20 00 00 00 mov 0x20(%r11),%r11d - 4d 29 da sub %r11,%r10 - 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11 - -*******************************************************************************/ - -bool patcher_checkcast_class(u1 *sp) -{ - OOPS(); u1 *ra; - u8 mcode; constant_classref *cr; classinfo *c; - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - - /* get the fieldinfo */ - - if (!(c = resolve_classref_eager(cr))) - return false; - - /* patch back original code */ - - *((u8 *) ra) = mcode; - - /* if we show disassembly, we have to skip the nop's */ - - if (opt_shownops) - ra = ra + 5; - - /* patch super class' vftbl */ - - *((ptrint *) (ra + 2)) = (ptrint) c->vftbl; - *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl; - - return true; -} - - -/* patcher_instanceof_class **************************************************** - - Machine code: - - - 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10 - -*******************************************************************************/ - -bool patcher_instanceof_class(u1 *sp) -{ - OOPS(); - u1 *ra; - u8 mcode; - constant_classref *cr; - classinfo *c; + PATCHER_TRACE; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); + ra = (u1 *) pr->mpc; + cr = (constant_classref *) pr->ref; /* get the fieldinfo */ @@ -846,137 +433,47 @@ bool patcher_instanceof_class(u1 *sp) /* patch back original code */ - *((u8 *) ra) = mcode; + PATCH_BACK_ORIGINAL_MCODE; - /* if we show disassembly, we have to skip the nop's */ + /* If NOPs are generated, skip them */ if (opt_shownops) - ra = ra + 5; - - /* patch super class' vftbl */ - - *((ptrint *) (ra + 2)) = (ptrint) c->vftbl; - - return true; -} - - -/* patcher_clinit ************************************************************** + ra += PATCHER_NOPS_SKIP; - May be used for GET/PUTSTATIC and in native stub. - - Machine code: - -*******************************************************************************/ - -__PORTED__ bool patcher_clinit(u1 *sp) -{ - u1 *ra; - u4 mcode; - classinfo *c; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - mcode = *((u4 *) (sp + 3 * 4)); - c = (classinfo *) *((ptrint *) (sp + 2 * 4)); - - /* check if the class is initialized */ - - if (!(c->state & CLASS_INITIALIZED)) - if (!initialize_class(c)) - return false; - - /* patch back original code */ - - *((u4 *) ra) = mcode; - - return true; -} - - -/* patcher_athrow_areturn ****************************************************** - - Machine code: - - - -*******************************************************************************/ - -#ifdef ENABLE_VERIFIER -__PORTED__ bool patcher_athrow_areturn(u1 *sp) -{ - u1 *ra; - u4 mcode; - unresolved_class *uc; - classinfo *c; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 4)); - mcode = *((u4 *) (sp + 3 * 4)); - uc = (unresolved_class *) *((ptrint *) (sp + 2 * 4)); - - /* resolve the class */ - - if (!resolve_class(uc, resolveEager, false, &c)) - return false; - - /* patch back original code */ - - *((u4 *) ra) = mcode; - - return true; -} -#endif /* ENABLE_VERIFIER */ - - -/* patcher_resolve_native ****************************************************** - - Machine code: - - - 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax - 48 ff d0 callq *%rax - -*******************************************************************************/ - -#if !defined(WITH_STATIC_CLASSPATH) -bool patcher_resolve_native(u1 *sp) -{ - OOPS(); - u1 *ra; - u8 mcode; - methodinfo *m; - functionptr f; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - mcode = *((u8 *) (sp + 3 * 8)); - m = (methodinfo *) *((ptrint *) (sp + 2 * 8)); - - /* resolve native function */ - - if (!(f = native_resolve_function(m))) - return false; - - /* patch back original code */ - - *((u8 *) ra) = mcode; - - /* if we show disassembly, we have to skip the nop's */ - - if (opt_shownops) - ra = ra + 5; - - /* patch native function pointer */ + /* patch super class index */ - *((ptrint *) (ra + 2)) = (ptrint) f; + /* From here, split your editor and open codegen.c */ + + switch (N_RX_GET_REG(ra)) { + case REG_ITMP1: + /* First M_ALD is into ITMP1 */ + /* INSTANCEOF code */ + + N_RI_SET_IMM(ra + SZ_L + SZ_L, - c->index); + N_RI_SET_IMM( + ra + SZ_L + SZ_L + SZ_AHI + SZ_BRC, + (int16_t)(OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*)) + ); + break; + + case REG_ITMP2: + /* First M_ALD is into ITMP2 */ + /* CHECKCAST code */ + + N_RI_SET_IMM(ra + SZ_L + SZ_L, - c->index); + N_RI_SET_IMM( + ra + SZ_L + SZ_L + SZ_AHI + SZ_BRC + SZ_ILL, + (int16_t)(OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*)) + ); + break; + + default: + assert(0); + break; + } return true; } -#endif /* !defined(WITH_STATIC_CLASSPATH) */ /*