as emit_patcher_stubs, now emits traps instead of stubs.
* src/vm/jit/arm/codegen.c (codegen_emit, codegen_emit_stub_native): Call the
new patcher functions and adapted to above change.
* src/vm/jit/arm/patcher.c: Adapted patchers to new signature for traps.
(patcher_get_putfield): Fixed severe bug for long values.
(patcher_wrapper): Removed, this is obsolete.
* src/vm/jit/arm/codegen.h (M_TRAP): Added.
* src/vm/jit/arm/asmpart.S (asm_patcher_wrapper): Removed, this is obsolete.
* src/vm/jit/arm/linux/md-os.c (md_signal_handler_sigill): Only calls the
exception handling if exception object present.
* src/vm/jit/patcher-common.c: Fixed includes.
* src/vm/jit/patcher-common.h [__ARM__]: Added prototypes for patcher functions.
(patchref_t): Added datap.
* src/vm/jit/patcher.h [__ARM__]: Defined away old patcher stuff.
* src/vm/jit/codegen-common.c (codegen_finish): Resolves pr->datap as well.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: asmpart.S 8127 2007-06-21 11:55:56Z michi $
+ $Id: asmpart.S 8160 2007-06-28 01:52:19Z michi $
*/
.globl asm_abstractmethoderror
- .globl asm_patcher_wrapper
-
.globl asm_cacheflush
.globl asm_getclassvalues_atomic
b asm_handle_exception_loop
-/* asm_patcher_wrapper *********************************************************
-* *
-* TODO: document me *
-* *
-* Stack layout when calling patcher function: *
-* 28 empty because stack needs to be aligned *
-* 24 saved REG_ITMP3, should be restored ( -8) *
-* 20 data segment displacement from load instructions (-12) *
-* 16 return address into JIT code (patch position) (-16) *
-* 12 pointer to virtual java_objectheader *
-* 8 machine code (which is patched back later) *
-* [ 8 result of patcher function (indicates exception) ] *
-* 4 unresolved class/method/field reference *
-* [ 0 patcher function pointer to call ] *
-* 0 saved IP of caller (caller needs it!) *
-* *
-*******************************************************************************/
-
-#define PATCHSTACKSIZE 8*4
-
-asm_patcher_wrapper:
- mov itmp3, sp /* preserve original SP in ITMP3 */
-
- SAVE_ARGUMENT_REGISTERS_IP /* save our argument registers & LR */
- SAVE_FLOAT_REGISTERS /* save our float registers here */
-
- mov a0, itmp3 /* pass SP of patcher stub */
- mov a1, ip /* pass PV */
- mov a2, lr /* pass RA (correct for leafs) */
- bl patcher_wrapper
- mov itmp3, res1 /* save return value */
-
- RESTORE_FLOAT_REGISTERS /* restore our float registers here */
- RESTORE_ARGUMENT_REGISTERS_IP /* load our argument registers & LR */
-
- add sp, sp, #PATCHSTACKSIZE /* remove patcher stack frame */
-
- tst itmp3, itmp3 /* check for an exception */
- bne L_asm_patcher_wrapper_exception
-
- ldr itmp3, [sp, #-8] /* restore ITMP3 for calling method */
- ldr pc, [sp, #-16] /* jump to new patched code */
-
-L_asm_patcher_wrapper_exception:
- mov xptr, itmp3 /* get exception */
- ldr xpc, [sp, #-16] /* RA is xpc */
-
- /* Note: A normal branch instruction could modify the PV here, */
- /* so we use this construct instead. */
- ldr pc, [pc, #-4]
- .word asm_handle_exception
-
-
/* asm_abstractmethoderror *****************************************************
Creates and throws an AbstractMethodError.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: codegen.c 8127 2007-06-21 11:55:56Z michi $
+ $Id: codegen.c 8160 2007-06-28 01:52:19Z michi $
*/
#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"
#if defined(ENABLE_LSRA)
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_aconst,
- iptr->sx.val.c.ref,
- disp);
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
+ iptr->sx.val.c.ref, disp);
if (opt_showdisassemble)
M_NOP;
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
+ patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
if (opt_showdisassemble)
M_NOP;
fieldtype = fi->type;
if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
- codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
+ patcher_add_patch_ref(jd, PATCHER_initialize_class,
+ fi->class, 0);
if (opt_showdisassemble)
M_NOP;
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
+ patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
if (opt_showdisassemble)
M_NOP;
fieldtype = fi->type;
if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
- codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
+ patcher_add_patch_ref(jd, PATCHER_initialize_class,
+ fi->class, 0);
if (opt_showdisassemble)
M_NOP;
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
unresolved_field *uf = iptr->sx.s23.s3.uf;
- codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+ patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
if (opt_showdisassemble)
M_NOP;
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
unresolved_field *uf = iptr->sx.s23.s3.uf;
- codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+ patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
if (opt_showdisassemble)
M_NOP;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_INTMOVE(s1, REG_ITMP1_XPTR);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- codegen_addpatchref(cd, PATCHER_athrow_areturn,
+ patcher_add_patch_ref(jd, PATCHER_resolve_class,
iptr->sx.s23.s2.uc, 0);
if (opt_showdisassemble)
s1 = emit_load_s1(jd, iptr, REG_RESULT);
M_INTMOVE(s1, REG_RESULT);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- codegen_addpatchref(cd, PATCHER_athrow_areturn,
+ patcher_add_patch_ref(jd, PATCHER_resolve_class,
iptr->sx.s23.s2.uc, 0);
if (opt_showdisassemble)
if (lm == NULL) {
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_invokestatic_special,
+ patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
um, disp);
if (opt_showdisassemble)
case ICMD_INVOKEVIRTUAL:
if (lm == NULL) {
- codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
+ patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
if (opt_showdisassemble)
M_NOP;
case ICMD_INVOKEINTERFACE:
if (lm == NULL) {
- codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
+ patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
if (opt_showdisassemble)
M_NOP;
emit_label_beq(cd, BRANCH_LABEL_1);
disp = dseg_add_unique_s4(cd, 0); /* super->flags */
- codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
iptr->sx.s23.s3.c.ref, disp);
if (opt_showdisassemble)
disp = dseg_add_unique_s4(cd, superindex);
}
if (super == NULL) {
- codegen_addpatchref(cd,
- PATCHER_checkcast_instanceof_interface,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_index,
iptr->sx.s23.s3.c.ref, disp);
if (opt_showdisassemble)
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
iptr->sx.s23.s3.c.ref,
disp);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
iptr->sx.s23.s3.c.ref,
disp);
emit_label_beq(cd, BRANCH_LABEL_1);
disp = dseg_add_unique_s4(cd, 0); /* super->flags */
- codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
iptr->sx.s23.s3.c.ref, disp);
if (opt_showdisassemble)
if (d == REG_ITMP2)
M_EOR(d, d, d);
- codegen_addpatchref(cd,
- PATCHER_checkcast_instanceof_interface,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_index,
iptr->sx.s23.s3.c.ref, disp);
if (opt_showdisassemble)
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
- iptr->sx.s23.s3.c.ref,
- disp);
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
+ iptr->sx.s23.s3.c.ref, disp);
if (opt_showdisassemble)
M_NOP;
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
disp = dseg_add_unique_address(cd, NULL);
- codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
iptr->sx.s23.s3.c.ref, disp);
if (opt_showdisassemble)
/* generate stubs */
- emit_patcher_stubs(jd);
+ emit_patcher_traps(jd);
/* everything's ok */
#if !defined(WITH_STATIC_CLASSPATH)
if (f == NULL) {
- codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
+ patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
if (opt_showdisassemble)
M_NOP;
/* generate patcher stubs */
- emit_patcher_stubs(jd);
+ emit_patcher_traps(jd);
}
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: codegen.h 7929 2007-05-21 11:45:31Z michi $
+ $Id: codegen.h 8160 2007-06-28 01:52:19Z michi $
*/
#define M_DMOV(a,b) M_MVFD(b,a)
+#define M_TRAP(a,i) M_UNDEFINED(UNCOND,i,a);
#define M_TRAPEQ(a,i) M_UNDEFINED(COND_EQ,i,a);
#define M_TRAPLE(a,i) M_UNDEFINED(COND_LE,i,a);
#define M_TRAPHI(a,i) M_UNDEFINED(COND_HI,i,a);
#include "vm/jit/asmpart.h"
#include "vm/jit/emit-common.h"
#include "vm/jit/jit.h"
+#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#include "toolbox/logging.h" /* XXX for debugging only */
}
-/* emit_patcher_stubs **********************************************************
+/* emit_patcher_traps **********************************************************
- Generates the code for the patcher stubs.
+ Generates the code for the patcher traps.
*******************************************************************************/
-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;
-
- /* generate patcher stub call code */
-
- targetdisp = 0;
+ cd = jd->cd;
+ code = jd->code;
- for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
- /* check code segment size */
+ /* generate patcher traps code */
- 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) + 2);
- M_B(disp);
+ M_TRAP(0, EXCEPTION_HARDWARE_PATCHER);
cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
-
- /* create stack frame (align stack to 8-byte) */
-
- M_SUB_IMM(REG_SP, REG_SP, 8 * 4);
-
- /* save itmp3 onto stack */
-
- M_STR_INTERN(REG_ITMP3, REG_SP, 6 * 4);
-
- /* calculate return address and move it onto stack */
- /* ATTENTION: we can not use BL to branch to patcher stub, */
- /* ATTENTION: because we need to preserve LR for leaf methods */
-
- disp = (s4) (((u4 *) cd->mcodeptr) - (((u4 *) tmpmcodeptr) + 1) + 2);
-
- M_SUB_IMM_EXT_MUL4(REG_ITMP3, REG_PC, disp);
- M_STR_INTERN(REG_ITMP3, REG_SP, 4 * 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_SUB_IMM_EXT_MUL4(REG_ITMP3, REG_PV, -disp / 4);
- M_STR_INTERN(REG_ITMP3, REG_SP, 3 * 4);
-#else
- M_EOR(REG_ITMP3, REG_ITMP3, REG_ITMP3);
- M_STR_INTERN(REG_ITMP3, REG_SP, 3 * 4);
-#endif
-
- /* move machine code onto stack */
-
- disp = dseg_add_unique_s4(cd, mcode);
- M_DSEG_LOAD(REG_ITMP3, disp);
- M_STR_INTERN(REG_ITMP3, REG_SP, 2 * 4);
-
- /* move class/method/field reference onto stack */
-
- disp = dseg_add_unique_address(cd, pref->ref);
- M_DSEG_LOAD(REG_ITMP3, disp);
- M_STR_INTERN(REG_ITMP3, REG_SP, 1 * 4);
-
- /* move data segment displacement onto stack */
-
- disp = dseg_add_unique_s4(cd, pref->disp);
- M_DSEG_LOAD(REG_ITMP3, disp);
- M_STR_INTERN(REG_ITMP3, REG_SP, 5 * 4);
-
- /* move patcher function pointer onto stack */
-
- disp = dseg_add_functionptr(cd, pref->patcher);
- M_DSEG_LOAD(REG_ITMP3, disp);
- M_STR_INTERN(REG_ITMP3, REG_SP, 0 * 4);
-
- /* finally call the patcher via asm_patcher_wrapper */
- /* ATTENTION: don't use REG_PV here, because some patchers need it */
-
- if (targetdisp == 0) {
- targetdisp = ((u4 *) cd->mcodeptr) - ((u4 *) cd->mcodebase);
-
- disp = dseg_add_functionptr(cd, asm_patcher_wrapper);
- /*M_DSEG_BRANCH_NOLINK(REG_PC, REG_PV, a);*/
- /* TODO: this is only a hack */
- M_DSEG_LOAD(REG_ITMP3, disp);
- M_MOV(REG_PC, REG_ITMP3);
- }
- else {
- disp = (((u4 *) cd->mcodebase) + targetdisp) -
- (((u4 *) cd->mcodeptr) + 2);
-
- M_B(disp);
- }
}
}
o = exceptions_new_hardware_exception(pv, sp, ra, xpc, type, val);
- /* set registers */
-
- _sc->arm_r10 = (ptrint) o;
- _sc->arm_fp = (ptrint) xpc;
- _sc->arm_pc = (ptrint) asm_handle_exception;
+ /* set registers if we have an exception, return continue execution
+ otherwise (this is needed for patchers to work) */
+
+ if (o != NULL) {
+ _sc->arm_r10 = (ptrint) o;
+ _sc->arm_fp = (ptrint) xpc;
+ _sc->arm_pc = (ptrint) asm_handle_exception;
+ }
}
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: patcher.c 7929 2007-05-21 11:45:31Z michi $
+ $Id: patcher.c 8160 2007-06-28 01:52:19Z michi $
*/
#include "vm/jit/asmpart.h"
#include "vm/jit/md.h"
-#include "vm/jit/patcher.h"
+#include "vm/jit/patcher-common.h"
#include "vmcore/field.h"
#include "vmcore/options.h"
#include "vm/resolve.h"
+#define PATCH_BACK_ORIGINAL_MCODE \
+ *((u4 *) pr->mpc) = (u4) pr->mcode; \
+ md_icacheflush((u1 *) pr->mpc, 1 * 4);
+
#define gen_resolveload(inst,offset) \
assert((offset) >= -0x0fff && (offset) <= 0x0fff); \
assert(!((inst) & 0x0fff)); \
}
-/* 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 + 4 * 4));
- o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
- f = (functionptr) *((ptrint *) (sp + 0 * 4));
-
- /* calculate and set the new return address */
-
- xpc = xpc - 1 * 4;
-
- *((ptrint *) (sp + 4 * 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 */
-
- 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 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 */
-
- mcode = *((u4 *) (sp + 2 * 4));
-
- *((u4 *) xpc) = mcode;
-
- /* synchronize instruction cache */
-
- md_icacheflush(xpc, 1 * 4);
-
- PATCHER_MARK_PATCHED_MONITOREXIT;
-
- return NULL;
-}
-
-
/* patcher_get_putstatic *******************************************************
Machine code:
*******************************************************************************/
-bool patcher_get_putstatic(u1 *sp)
+bool patcher_get_putstatic(patchref_t *pr)
{
- s4 disp;
unresolved_field *uf;
- u1 *pv;
+ u1 *datap;
fieldinfo *fi;
/* get stuff from the stack */
- disp = *((s4 *) (sp + 5 * 4));
- uf = (unresolved_field *) *((ptrint *) (sp + 1 * 4));
- pv = (u1 *) *((ptrint *) (sp + 0 * 4));
+ uf = (unresolved_field *) pr->ref;
+ datap = (u1 *) pr->datap;
/* get the fieldinfo */
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);
return true;
}
*******************************************************************************/
-bool patcher_get_putfield(u1 *sp)
+bool patcher_get_putfield(patchref_t *pr)
{
u1 *ra;
u4 mcode;
unresolved_field *uf;
- u1 *pv;
fieldinfo *fi;
/* get stuff from the stack */
- ra = (u1*) *((ptrint *) (sp + 4 * 4));
- mcode = *((u4 *) (sp + 2 * 4));
- uf = (unresolved_field*) *((ptrint *) (sp + 1 * 4));
- pv = (u1*) *((ptrint *) (sp + 0 * 4));
+ ra = (u1*) pr->mpc;
+ mcode = pr->mcode;
+ 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_showdisassemble) {
+ if (opt_showdisassemble)
ra = ra + 1 * 4;
- /* patch the field's offset into the instruction */
-
- switch(fi->type) {
- case TYPE_ADR:
- case TYPE_INT:
-#if defined(ENABLE_SOFTFLOAT)
- case TYPE_FLT:
-#endif
- assert(fi->offset <= 0x0fff);
- *((u4 *) (ra + 0 * 4)) |= (fi->offset & 0x0fff);
- break;
-
- case TYPE_LNG:
-#if defined(ENABLE_SOFTFLOAT)
- case TYPE_DBL:
-#endif
- assert((fi->offset + 4) <= 0x0fff);
- *((u4 *) (ra + 0 * 4)) |= ((fi->offset + 0) & 0x0fff);
- *((u4 *) (ra + 1 * 4)) |= ((fi->offset + 4) & 0x0fff);
- break;
-
-#if !defined(ENABLE_SOFTFLOAT)
- case TYPE_FLT:
- case TYPE_DBL:
- assert(fi->offset <= 0x03ff);
- *((u4 *) (ra + 0 * 4)) |= ((fi->offset >> 2) & 0x00ff);
- break;
-#endif
- }
- }
- else {
- /* patch the field's offset into the instruction stored on the
- stack and the next instruction in the code */
+ /* patch the field's offset into the instruction */
- switch(fi->type) {
- case TYPE_ADR:
- case TYPE_INT:
+ switch(fi->type) {
+ case TYPE_ADR:
+ case TYPE_INT:
#if defined(ENABLE_SOFTFLOAT)
- case TYPE_FLT:
+ case TYPE_FLT:
#endif
- assert(fi->offset <= 0x0fff);
- *((u4 *) (sp + 2 * 4)) |= (fi->offset & 0x0fff);
- break;
+ assert(fi->offset <= 0x0fff);
+ *((u4 *) (ra + 0 * 4)) |= (fi->offset & 0x0fff);
+ break;
- case TYPE_LNG:
+ case TYPE_LNG:
#if defined(ENABLE_SOFTFLOAT)
- case TYPE_DBL:
+ case TYPE_DBL:
#endif
- assert((fi->offset + 4) <= 0x0fff);
- *((u4 *) (sp + 2 * 4)) |= ((fi->offset + 0) & 0x0fff);
- *((u4 *) (ra + 1 * 4)) |= ((fi->offset + 4) & 0x0fff);
- break;
+ assert((fi->offset + 4) <= 0x0fff);
+ *((u4 *) (ra + 0 * 4)) |= ((fi->offset + 0) & 0x0fff);
+ *((u4 *) (ra + 1 * 4)) &= 0xfffff000;
+ *((u4 *) (ra + 1 * 4)) |= ((fi->offset + 4) & 0x0fff);
+ break;
#if !defined(ENABLE_SOFTFLOAT)
- case TYPE_FLT:
- case TYPE_DBL:
- assert(fi->offset <= 0x03ff);
- *((u4 *) (sp + 2 * 4)) |= ((fi->offset >> 2) & 0x00ff);
- break;
+ case TYPE_FLT:
+ case TYPE_DBL:
+ assert(fi->offset <= 0x03ff);
+ *((u4 *) (ra + 0 * 4)) |= ((fi->offset >> 2) & 0x00ff);
+ break;
#endif
- }
}
/* synchronize instruction cache */
}
-/* patcher_aconst **************************************************************
+/* patcher_resolve_classref_to_classinfo ***************************************
- Machine code:
+ ACONST - Machine code:
<patched call postition>
e51cc030 ldr r0, [ip, #-48]
-*******************************************************************************/
-
-bool patcher_aconst(u1 *sp)
-{
- s4 disp;
- constant_classref *cr;
- u1 *pv;
- classinfo *c;
-
- /* get stuff from the stack */
-
- disp = *((s4 *) (sp + 5 * 4));
- cr = (constant_classref *) *((ptrint *) (sp + 1 * 4));
- pv = (u1 *) *((ptrint *) (sp + 0 * 4));
-
- /* get the classinfo */
-
- if (!(c = resolve_classref_eager(cr)))
- return false;
-
- /* patch the classinfo pointer */
-
- *((ptrint *) (pv + disp)) = (ptrint) c;
-
- return true;
-}
-
-
-/* patcher_builtin_multianewarray **********************************************
-
- Machine code:
-
+ MULTIANEWARRAY - Machine code:
+
<patched call position>
e3a00002 mov r0, #2 ; 0x2
e51c1064 ldr r1, [ip, #-100]
e1a0e00f mov lr, pc
e51cf068 ldr pc, [ip, #-104]
-*******************************************************************************/
-
-bool patcher_builtin_multianewarray(u1 *sp)
-{
- s4 disp;
- constant_classref *cr;
- u1 *pv;
- classinfo *c;
-
- /* get stuff from the stack */
-
- disp = *((s4 *) (sp + 5 * 4));
- cr = (constant_classref *) *((ptrint *) (sp + 1 * 4));
- pv = (u1 *) *((ptrint *) (sp + 0 * 4));
-
- /* get the classinfo */
-
- if (!(c = resolve_classref_eager(cr)))
- return false;
-
- /* patch the classinfo pointer */
-
- *((ptrint *) (pv + disp)) = (ptrint) c;
-
- return true;
-}
-
-
-/* patcher_builtin_arraycheckcast **********************************************
-
- Machine code:
+ ARRAYCHECKCAST - Machine code:
<patched call position>
e51c1120 ldr r1, [ip, #-288]
*******************************************************************************/
-bool patcher_builtin_arraycheckcast(u1 *sp)
+bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
{
- s4 disp;
constant_classref *cr;
- u1 *pv;
+ u1 *datap;
classinfo *c;
/* get stuff from the stack */
- disp = *((s4 *) (sp + 5 * 4));
- cr = (constant_classref *) *((ptrint *) (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;
return true;
}
******************************************************************************/
-bool patcher_invokestatic_special(u1 *sp)
+bool patcher_invokestatic_special(patchref_t *pr)
{
- s4 disp;
unresolved_method *um;
- u1 *pv;
+ u1 *datap;
methodinfo *m;
/* get stuff from the stack */
- disp = *((s4 *) (sp + 5 * 4));
- um = (unresolved_method*) *((ptrint *) (sp + 1 * 4));
- pv = (u1*) *((ptrint *) (sp + 0 * 4));
+ um = (unresolved_method*) pr->ref;
+ datap = (u1 *) pr->datap;
/* get the methodinfo */
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;
}
*******************************************************************************/
-bool patcher_invokevirtual(u1 *sp)
+bool patcher_invokevirtual(patchref_t *pr)
{
u1 *ra;
unresolved_method *um;
/* get stuff from the stack */
- ra = (u1 *) *((ptrint *) (sp + 4 * 4));
- um = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
+ ra = (u1 *) pr->mpc;
+ um = (unresolved_method *) pr->ref;
/* get the methodinfo */
if (!(m = resolve_method_eager(um)))
return false;
+ PATCH_BACK_ORIGINAL_MCODE;
+
/* if we show disassembly, we have to skip the nop */
if (opt_showdisassemble)
*******************************************************************************/
-bool patcher_invokeinterface(u1 *sp)
+bool patcher_invokeinterface(patchref_t *pr)
{
u1 *ra;
unresolved_method *um;
/* get stuff from the stack */
- ra = (u1 *) *((ptrint *) (sp + 4 * 4));
- um = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
+ ra = (u1 *) pr->mpc;
+ um = (unresolved_method *) pr->ref;
/* get the methodinfo */
if (!(m = resolve_method_eager(um)))
return false;
+ PATCH_BACK_ORIGINAL_MCODE;
+
/* if we show disassembly, we have to skip the nop */
if (opt_showdisassemble)
*******************************************************************************/
-bool patcher_checkcast_instanceof_flags(u1 *sp)
+bool patcher_resolve_classref_to_flags(patchref_t *pr)
{
- s4 disp;
constant_classref *cr;
- u1 *pv;
+ u1 *datap;
classinfo *c;
/* get stuff from the stack */
- disp = *((s4 *) (sp + 5 * 4));
- cr = (constant_classref *) *((ptrint *) (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 class flags */
- *((s4 *) (pv + disp)) = (s4) c->flags;
+ *((s4 *) datap) = (s4) c->flags;
return true;
}
-/* patcher_checkcast_instanceof_interface **************************************
+/* patcher_resolve_classref_to_index *******************************************
Machine code:
*******************************************************************************/
-bool patcher_checkcast_instanceof_interface(u1 *sp)
+bool patcher_resolve_classref_to_index(patchref_t *pr)
{
- s4 disp;
constant_classref *cr;
- u1 *pv;
+ u1 *datap;
classinfo *c;
/* get stuff from the stack */
- disp = *((s4 *) (sp + 5 * 4));
- cr = (constant_classref *) *((ptrint *) (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 super class index */
- *((s4 *) (pv + disp)) = (s4) c->index;
+ *((s4 *) datap) = (s4) c->index;
return true;
}
-/* patcher_checkcast_instanceof_class ******************************************
+/* patcher_resolve_classref_to_vftbl *******************************************
Machine code:
*******************************************************************************/
-bool patcher_checkcast_instanceof_class(u1 *sp)
+bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
{
- s4 disp;
constant_classref *cr;
- u1 *pv;
+ u1 *datap;
classinfo *c;
/* get stuff from the stack */
- disp = *((s4 *) (sp + 5 * 4));
- cr = (constant_classref *) *((ptrint *) (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 super class' vftbl */
- *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
+ *((ptrint *) datap) = (ptrint) c->vftbl;
return true;
}
-/* patcher_clinit **************************************************************
+/* patcher_initialize_class ****************************************************
XXX
*******************************************************************************/
-bool patcher_clinit(u1 *sp)
+bool patcher_initialize_class(patchref_t *pr)
{
classinfo *c;
/* get stuff from the stack */
- c = (classinfo *) *((ptrint *) (sp + 1 * 4));
+ c = (classinfo *) pr->ref;
/* check if the class is initialized */
if (!initialize_class(c))
return false;
+ PATCH_BACK_ORIGINAL_MCODE;
+
return true;
}
-/* patcher_athrow_areturn ******************************************************
+/* patcher_resolve_class *******************************************************
Machine code:
*******************************************************************************/
#ifdef ENABLE_VERIFIER
-bool patcher_athrow_areturn(u1 *sp)
+bool patcher_resolve_class(patchref_t *pr)
{
unresolved_class *uc;
/* get stuff from the stack */
- uc = (unresolved_class *) *((ptrint *) (sp + 1 * 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 */
-/* patcher_resolve_native ******************************************************
+/* patcher_resolve_native_function *********************************************
XXX
*******************************************************************************/
#if !defined(WITH_STATIC_CLASSPATH)
-bool patcher_resolve_native(u1 *sp)
+bool patcher_resolve_native_function(patchref_t *pr)
{
- s4 disp;
methodinfo *m;
- u1 *pv;
+ u1 *datap;
functionptr f;
/* get stuff from the stack */
- disp = *((s4 *) (sp + 5 * 4));
- m = (methodinfo *) *((ptrint *) (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;
return true;
}
memory. All functions writing values into the data area return the offset
relative the begin of the code area (start of procedure).
- $Id: codegen-common.c 8145 2007-06-27 08:54:10Z michi $
+ $Id: codegen-common.c 8160 2007-06-28 01:52:19Z michi $
*/
pr = list_first_unsynced(code->patchers);
while (pr) {
pr->mpc += (ptrint) epoint;
+ pr->datap = (ptrint) (pr->disp + epoint);
pr = list_next_unsynced(code->patchers, pr);
}
#include "mm/memory.h"
+#include "threads/lock-common.h"
+
#include "toolbox/list.h"
#include "toolbox/logging.h" /* XXX remove me! */
#include "vm/jit/code.h"
#include "vm/jit/jit.h"
-#include "vm/jit/patcher.h"
#include "vm/jit/patcher-common.h"
#include "vmcore/options.h"
*******************************************************************************/
typedef struct patchref_t {
- ptrint mpc; /* position in code segment */
+ ptrint mpc; /* absolute position in code segment */
+ ptrint datap; /* absolute position in data segment */
s4 disp; /* displacement of ref in the data segment */
functionptr patcher; /* patcher function to call */
voidptr ref; /* reference passed */
java_objectheader *patcher_handler(u1 *pc);
+/* patcher prototypes and macros **********************************************/
+
+#if defined(__ARM__)
+
+/* new patcher functions */
+
+bool patcher_resolve_class(patchref_t *pr);
+#define PATCHER_resolve_class (functionptr) patcher_resolve_class
+
+bool patcher_initialize_class(patchref_t *pr);
+#define PATCHER_initialize_class (functionptr) patcher_initialize_class
+
+bool patcher_resolve_classref_to_classinfo(patchref_t *pr);
+#define PATCHER_resolve_classref_to_classinfo (functionptr) patcher_resolve_classref_to_classinfo
+
+bool patcher_resolve_classref_to_vftbl(patchref_t *pr);
+#define PATCHER_resolve_classref_to_vftbl (functionptr) patcher_resolve_classref_to_vftbl
+
+bool patcher_resolve_classref_to_index(patchref_t *pr);
+#define PATCHER_resolve_classref_to_index (functionptr) patcher_resolve_classref_to_index
+
+bool patcher_resolve_classref_to_flags(patchref_t *pr);
+#define PATCHER_resolve_classref_to_flags (functionptr) patcher_resolve_classref_to_flags
+
+#if !defined(WITH_STATIC_CLASSPATH)
+bool patcher_resolve_native_function(patchref_t *pr);
+#define PATCHER_resolve_native_function (functionptr) patcher_resolve_native_function
+#endif
+
+/* old patcher functions */
+
+bool patcher_get_putstatic(patchref_t *pr);
+#define PATCHER_get_putstatic (functionptr) patcher_get_putstatic
+
+#if defined(__I386__)
+
+bool patcher_getfield(patchref_t *pr);
+#define PATCHER_getfield (functionptr) patcher_getfield
+
+bool patcher_putfield(patchref_t *pr);
+#define PATCHER_putfield (functionptr) patcher_putfield
+
+#else
+
+bool patcher_get_putfield(patchref_t *pr);
+#define PATCHER_get_putfield (functionptr) patcher_get_putfield
+
+#endif /* defined(__I386__) */
+
+#if defined(__I386__) || defined(__X86_64__)
+
+bool patcher_putfieldconst(patchref_t *pr);
+#define PATCHER_putfieldconst (functionptr) patcher_putfieldconst
+
+#endif /* defined(__I386__) || defined(__X86_64__) */
+
+bool patcher_invokestatic_special(patchref_t *pr);
+#define PATCHER_invokestatic_special (functionptr) patcher_invokestatic_special
+
+bool patcher_invokevirtual(patchref_t *pr);
+#define PATCHER_invokevirtual (functionptr) patcher_invokevirtual
+
+bool patcher_invokeinterface(patchref_t *pr);
+#define PATCHER_invokeinterface (functionptr) patcher_invokeinterface
+
+#endif /* architecture list */
+
+
#endif /* _PATCHER_COMMON_H */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: patcher.h 7813 2007-04-25 19:20:13Z twisti $
+ $Id: patcher.h 8160 2007-06-28 01:52:19Z michi $
*/
#include "vm/global.h"
+#if defined(__ARM__)
+# error "you should no longer include this file"
+#else
+
+
/* patcher macros *************************************************************/
#define PATCHER_FLAG_PATCHED (vftbl_t *) 0xdeadbeef
bool intrp_patcher_resolve_native(u1 *sp);
#endif /* defined(ENABLE_INTRP) */
+#endif /* architecture list */
+
#endif /* _PATCHER_H */