X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fm68k%2Fcodegen.c;h=e020a3b4e09c5662aac7db4152a346b61a7b5574;hb=5d22373538ae0e6903b8d3c3be1c1643135d856f;hp=36d01bb245f118cf8d0c7d3bc46f1dabf0fa1cc9;hpb=4b29f4acd7a81f9d8969ccbe8e6a10322a553480;p=cacao.git diff --git a/src/vm/jit/m68k/codegen.c b/src/vm/jit/m68k/codegen.c index 36d01bb24..e020a3b4e 100644 --- a/src/vm/jit/m68k/codegen.c +++ b/src/vm/jit/m68k/codegen.c @@ -1,9 +1,7 @@ /* src/vm/jit/m68k/codegen.c - Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel, - C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, - E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, - J. Wenninger, Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -22,49 +20,48 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: codegen.c 7564 2007-03-23 23:36:17Z twisti $ - */ #include "config.h" #include +#include #include "md-abi.h" -#include "md-os.h" #include "vm/types.h" #include "vm/jit/m68k/codegen.h" #include "vm/jit/m68k/emit.h" #include "mm/memory.h" -#include "native/jni.h" + +#include "native/localref.h" #include "native/native.h" #include "threads/lock-common.h" -#include "vm/builtin.h" -#include "vm/exceptions.h" +#include "vm/jit/builtin.hpp" +#include "vm/exceptions.hpp" #include "vm/global.h" -#include "vm/stringlocal.h" -#include "vm/vm.h" +#include "vm/loader.hpp" +#include "vm/options.h" +#include "vm/utf8.h" +#include "vm/vm.hpp" #include "vm/jit/asmpart.h" -#include "vm/jit/codegen-common.h" +#include "vm/jit/codegen-common.hpp" +#include "vm/jit/patcher-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" -#include "vm/jit/jit.h" +#include "vm/jit/linenumbertable.h" +#include "vm/jit/emit-common.hpp" +#include "vm/jit/jit.hpp" +#include "vm/jit/abi.h" #include "vm/jit/parse.h" -#include "vm/jit/patcher.h" #include "vm/jit/reg.h" -#include "vm/jit/replace.h" -#include "vm/jit/stacktrace.h" -#include "vm/jit/md.h" - -#include "vmcore/loader.h" -#include "vmcore/options.h" -#include "vmcore/utf8.h" +#include "vm/jit/replace.hpp" +#include "vm/jit/stacktrace.hpp" +#include "vm/jit/trap.h" bool codegen_emit(jitdata *jd) @@ -74,11 +71,9 @@ bool codegen_emit(jitdata *jd) codegendata *cd; registerdata *rd; s4 len, s1, s2, s3, d, disp; - ptrint a; varinfo *var; basicblock *bptr; instruction *iptr; - exception_entry *ex; u2 currentline; methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */ unresolved_method *um; @@ -109,55 +104,49 @@ bool codegen_emit(jitdata *jd) savedregs_num += (INT_SAV_CNT - rd->savintreguse); savedregs_num += (ADR_SAV_CNT - rd->savadrreguse); - savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2; + savedregs_num += (FLT_SAV_CNT - rd->savfltreguse); cd->stackframesize = rd->memuse + savedregs_num; + + /* we always add 2 stack slots. + * 1 word the lock word, which may be unused and resides @ rd->memuse * 8 + * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8 + * on the other hand we could use 2 words when a builtin returns a doulbe which are + * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd + * so we always _need_ at least 2 slots, and this keeps the code simple */ + cd->stackframesize += 2; - /* FIXME: we could need 2 words to move a double result, which gets - * passed in %d0, %d1 into a floating point register, this is of - * course onyl true when not using ENABLE_SOFTFLOAT, so this could be - * optimized away, for now always use 2 more words. When optimizing watch - * the threading code, which stores the lock word, the offset would change */ - cd->stackframesize += 2; + cd->stackframesize *= 8; /* we use 8 byte stack slots */ +#if 0 #if defined(ENABLE_THREADS) /* we need additional space to save argument of monitor_enter */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) { cd->stackframesize += 2; } else { - cd->stackframesize ++; + cd->stackframesize += 1; } } #endif - +#endif /* create method header */ (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ - (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */ -#if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) - (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync */ - else -#endif - (void) dseg_add_unique_s4(cd, 0); /* IsSync */ - (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */ + (void) dseg_add_unique_s4(cd, cd->stackframesize); /* FrameSize */ - /* XXX we use the IntSAce a split field for the adr now */ - (void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */ - (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ + code->synchronizedoffset = rd->memuse * 8; - dseg_addlinenumbertablesize(cd); + /* REMOVEME: We still need it for exception handling in assembler. */ - (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */ + if (code_is_leafmethod(code)) + (void) dseg_add_unique_s4(cd, 1); + else + (void) dseg_add_unique_s4(cd, 0); - /* create exception table */ - for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) { - dseg_add_target(cd, ex->start); - dseg_add_target(cd, ex->end); - dseg_add_target(cd, ex->handler); - (void) dseg_add_unique_address(cd, ex->catchtype.any); - } + /* XXX we use the IntSave a split field for the adr now */ + (void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */ + (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ #if defined(ENABLE_PROFILING) assert(0); @@ -167,19 +156,19 @@ bool codegen_emit(jitdata *jd) emit_verbosecall_enter(jd); #endif /* create stack frame */ - M_AADD_IMM(-(cd->stackframesize*4), REG_SP); + M_AADD_IMM(-(cd->stackframesize), REG_SP); /* save used callee saved registers */ p = cd->stackframesize; for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) { - p--; M_IST(rd->savintregs[i], REG_SP, p*4); + p-=8; M_IST(rd->savintregs[i], REG_SP, p); } for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) { - p--; M_AST(rd->savadrregs[i], REG_SP, p*4); + p-=8; M_AST(rd->savadrregs[i], REG_SP, p); } #if !defined(ENABLE_SOFTFLOAT) for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) { - p-=2; M_DST(rd->savfltregs[i], REG_SP, p*4); + p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p); } #else assert(FLT_SAV_CNT == 0); @@ -212,22 +201,17 @@ bool codegen_emit(jitdata *jd) case TYPE_INT: if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */ if (IS_2_WORD_TYPE(t)) { - M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4); + M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4); } else { - M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4); + M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4); } } else { /* stack arg -> spilled */ -#if 1 - M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4); - M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4); + M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4); + M_IST(REG_ITMP1, REG_SP, var->vv.regoff); if (IS_2_WORD_TYPE(t)) { - M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4 + 4); - M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4); + M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4); + M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4); } -#else - /* Reuse Memory Position on Caller Stack */ - var->vv.regoff = cd->stackframesize + s1; -#endif } break; #if !defined(ENABLE_SOFTFLOAT) @@ -235,37 +219,27 @@ bool codegen_emit(jitdata *jd) case TYPE_DBL: if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */ if (IS_2_WORD_TYPE(t)) { - M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4); + M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4); } else { - M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4); + M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4); } } else { /* stack-arg -> spilled */ -#if 1 if (IS_2_WORD_TYPE(t)) { - M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4); - M_DST(REG_FTMP1, REG_SP, var->vv.regoff * 4); + M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4); + M_DST(REG_FTMP1, REG_SP, var->vv.regoff); } else { - M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4); - M_FST(REG_FTMP1, REG_SP, var->vv.regoff * 4); + M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4); + M_FST(REG_FTMP1, REG_SP, var->vv.regoff); } -#else - /* Reuse Memory Position on Caller Stack */ - var->vv.regoff = cd->stackframesize + s1; -#endif } break; #endif /* SOFTFLOAT */ case TYPE_ADR: if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */ - M_ALD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4); + M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4); } else { /* stack-arg -> spilled */ -#if 1 - M_ALD(REG_ATMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4); - M_AST(REG_ATMP1, REG_SP, var->vv.regoff * 4); -#else - /* Reuse Memory Position on Caller Stack */ - var->vv.regoff = cd->stackframesize + s1; -#endif + M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4); + M_AST(REG_ATMP1, REG_SP, var->vv.regoff); } break; default: assert(0); @@ -273,19 +247,19 @@ bool codegen_emit(jitdata *jd) } /* end for argument out of stack*/ #if defined(ENABLE_THREADS) - /* call monitor_enter function */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + /* call lock_monitor_enter function */ + if (checksync && code_is_synchronized(code)) { if (m->flags & ACC_STATIC) { - M_AMOV_IMM((&m->class->object.header), REG_ATMP1); + M_AMOV_IMM((&m->clazz->object.header), REG_ATMP1); } else { /* for non-static case the first arg is the object */ - M_ALD(REG_ATMP1, REG_SP, cd->stackframesize*4 + 4); + M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4); M_ATST(REG_ATMP1); M_BNE(2); - M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER); + M_TRAP(TRAP_NullPointerException); } - M_AST(REG_ATMP1, REG_SP, rd->memuse * 4 + 2*4); + M_AST(REG_ATMP1, REG_SP, rd->memuse * 8); M_AST(REG_ATMP1, REG_SP, 0 * 4); M_JSR_IMM(LOCK_monitor_enter); } @@ -306,15 +280,42 @@ bool codegen_emit(jitdata *jd) /* branch resolving */ codegen_resolve_branchrefs(cd, bptr); + /* handle replacement points */ + REPLACEMENT_POINT_BLOCK_START(cd, bptr); + +#if defined(ENABLE_PROFILING) + assert(0); +#endif /* FIXME there are still some constrcuts to copy in here */ +#if defined(ENABLE_LSRA) + assert(0); +#endif + + /* copy interface registers to their destination */ + len = bptr->indepth; + MCODECHECK(64+len); + + while (len > 0) { + len--; + var = VAR(bptr->invars[len]); + if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) { + d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR); + M_ADRMOVE(REG_ATMP1_XPTR, d); + emit_store(jd, NULL, var, d); + } + else { + assert((var->flags & INOUT)); + } + } + /* walk through all instructions */ len = bptr->icount; currentline = 0; for (iptr = bptr->iinstr; len > 0; len--, iptr++) { if (iptr->line != currentline) { - dseg_addlinenumber(cd, iptr->line); + linenumbertable_list_entry_add(cd, iptr->line); currentline = iptr->line; } @@ -334,14 +335,14 @@ bool codegen_emit(jitdata *jd) case ICMD_INLINE_BODY: REPLACEMENT_POINT_INLINE_BODY(cd, iptr); - dseg_addlinenumber_inline_start(cd, iptr); - dseg_addlinenumber(cd, iptr->line); + linenumbertable_list_entry_add_intern(cd, iptr); + linenumbertable_list_entry_add(cd, iptr->line); break; case ICMD_INLINE_END: - dseg_addlinenumber_inline_end(cd, iptr); - dseg_addlinenumber(cd, iptr->line); + linenumbertable_list_entry_add_inline(cd, iptr); + linenumbertable_list_entry_add(cd, iptr->line); break; case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */ @@ -396,6 +397,76 @@ bool codegen_emit(jitdata *jd) break; + /* some long operations *********************************************/ + case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */ + s1 = emit_load_s1_low(jd, iptr, REG_ITMP3); + s2 = emit_load_s2_low(jd, iptr, REG_ITMP1); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED); + M_INTMOVE(s2, REG_ITMP1); + M_IADD(s1, REG_ITMP1); /* low word */ + s1 = emit_load_s1_high(jd, iptr, REG_ITMP3); + s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); + M_INTMOVE(s2, REG_ITMP2); + M_IADDX(s1, REG_ITMP2); /* high word */ + emit_store_dst(jd, iptr, d); + break; + + case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */ + /* sx.val.l = constant */ + s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); + s2 = emit_load_s1_high(jd, iptr, REG_ITMP2); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED); + + M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3); + + s3 = iptr->sx.val.l & 0xffffffff; + M_INTMOVE(s1, REG_ITMP1); + M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */ + + M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */ + M_LNGMOVE(REG_ITMP12_PACKED, d); + emit_store_dst(jd, iptr, d); + break; + + case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */ + s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); + s2 = emit_load_s2_low(jd, iptr, REG_ITMP3); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED); + M_INTMOVE(s1, REG_ITMP1); + M_ISUB(s2, REG_ITMP1); /* low word */ + s1 = emit_load_s1_high(jd, iptr, REG_ITMP2); + s2 = emit_load_s2_high(jd, iptr, REG_ITMP3); + M_INTMOVE(s1, REG_ITMP2); + M_ISUBX(s2, REG_ITMP2); /* high word */ + emit_store_dst(jd, iptr, d); + break; + + case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */ + /* sx.val.l = constant */ + s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); + s2 = emit_load_s1_high(jd, iptr, REG_ITMP2); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED); + + M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3); + + s3 = (-iptr->sx.val.l) & 0xffffffff; + M_INTMOVE(s1, REG_ITMP1); + M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */ + + M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */ + M_LNGMOVE(REG_ITMP12_PACKED, d); + emit_store_dst(jd, iptr, d); + break; + + case ICMD_LNEG: /* ..., value ==> ..., - value */ + s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED); + d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED); + M_LNGMOVE(s1, REG_ITMP12_PACKED); + M_INEG(GET_LOW_REG(REG_ITMP12_PACKED)); + M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED)); + M_LNGMOVE(REG_ITMP12_PACKED, d); + emit_store_dst(jd, iptr, d); + break; /* integer operations ************************************************/ case ICMD_INEG: /* ..., value ==> ..., - value */ @@ -408,16 +479,6 @@ bool codegen_emit(jitdata *jd) emit_store_dst(jd, iptr, d); break; -#if 0 - case ICMD_LNEG: /* ..., value ==> ..., - value */ - - s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED); - d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED); - M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d)); - M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d)); - emit_store_dst(jd, iptr, d); - break; -#endif case ICMD_I2L: /* ..., value ==> ..., value */ s1 = emit_load_s1(jd, iptr, REG_ITMP3); @@ -897,6 +958,7 @@ bool codegen_emit(jitdata *jd) M_F2D(s1, d); emit_store_dst(jd, iptr, d); break; + case ICMD_D2F: /* ..., value ==> ..., (float) value */ s1 = emit_load_s1(jd, iptr, REG_FTMP1); d = codegen_reg_of_dst(jd, iptr, REG_FTMP2); @@ -904,7 +966,19 @@ bool codegen_emit(jitdata *jd) emit_store_dst(jd, iptr, d); break; + case ICMD_FNEG: /* ..., value ==> ..., - value */ + s1 = emit_load_s1(jd, iptr, REG_FTMP1); + d = codegen_reg_of_dst(jd, iptr, REG_FTMP2); + M_FNEG(s1, d); + emit_store_dst(jd, iptr, d); + break; + case ICMD_DNEG: /* ..., value ==> ..., - value */ + s1 = emit_load_s1(jd, iptr, REG_FTMP1); + d = codegen_reg_of_dst(jd, iptr, REG_FTMP2); + M_DNEG(s1, d); + emit_store_dst(jd, iptr, d); + break; #endif @@ -937,7 +1011,7 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { constant_classref *cr = iptr->sx.val.c.ref;; - codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, cr, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, 0); M_AMOV_IMM(0, d); } else { M_AMOV_IMM(iptr->sx.val.anyptr, d); @@ -955,7 +1029,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 */ M_JSR_PCREL(2); /* get current PC */ @@ -1026,21 +1100,27 @@ bool codegen_emit(jitdata *jd) /* MEMORY *************************************************************/ - case ICMD_GETSTATIC: - if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + + case ICMD_GETSTATIC: /* ... ==> ..., value */ + + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; - codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0); - } else { - fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field; + disp = 0; + patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0); + } + else { + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) { - codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0); - } + disp = (intptr_t) fi->value; - disp = (ptrint) &(fi->value); + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) { + patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, + 0); + } } + M_AMOV_IMM(disp, REG_ATMP1); switch (fieldtype) { #if defined(ENABLE_SOFTFLOAT) @@ -1080,15 +1160,18 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; + disp = 0; - codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0); - } else { + patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0); + } + else { fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; - disp = &(fi->value); + disp = (intptr_t) fi->value; - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) - codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0); + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) + patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, + 0); } M_AMOV_IMM(disp, REG_ATMP1); @@ -1134,7 +1217,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; @@ -1202,7 +1285,7 @@ bool codegen_emit(jitdata *jd) } 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) { @@ -1238,7 +1321,7 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_ATMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); /* implicit null-pointer check */ - M_ILD(d, s1, OFFSET(java_arrayheader, size)); + M_ILD(d, s1, OFFSET(java_array_t, size)); emit_store_dst(jd, iptr, d); break; @@ -1249,7 +1332,7 @@ bool codegen_emit(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1266,7 +1349,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(1, REG_ITMP2); - M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1283,7 +1366,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(1, REG_ITMP2); - M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); @@ -1301,7 +1384,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1317,7 +1400,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP1); M_ISSL_IMM(3, REG_ITMP1); - M_IADD_IMM(OFFSET(java_longarray, data[0]), REG_ITMP1); + M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP1, REG_ATMP1); /* implicit null-pointer check */ @@ -1331,7 +1414,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_floatarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1351,7 +1434,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(3, REG_ITMP2); - M_IADD_IMM(OFFSET(java_doublearray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1372,7 +1455,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); @@ -1388,7 +1471,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_INTMOVE(s2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1402,7 +1485,7 @@ bool codegen_emit(jitdata *jd) s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(1, REG_ITMP2); - M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1416,7 +1499,7 @@ bool codegen_emit(jitdata *jd) s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(1, REG_ITMP2); - M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1430,7 +1513,7 @@ bool codegen_emit(jitdata *jd) s3 = emit_load_s3(jd, iptr, REG_ITMP3); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1444,7 +1527,7 @@ bool codegen_emit(jitdata *jd) M_INTMOVE(s2, REG_ITMP1); M_ISSL_IMM(3, REG_ITMP1); - M_IADD_IMM(OFFSET(java_longarray, data[0]), REG_ITMP1); + M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP1, REG_ATMP1); /* implicit null-pointer check */ @@ -1458,7 +1541,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(2, REG_ITMP2); - M_IADD_IMM(OFFSET(java_floatarray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1477,7 +1560,7 @@ bool codegen_emit(jitdata *jd) emit_arrayindexoutofbounds_check(cd, iptr, s1, s2); M_INTMOVE(s2, REG_ITMP2); M_ISSL_IMM(3, REG_ITMP2); - M_IADD_IMM(OFFSET(java_doublearray, data[0]), REG_ITMP2); + M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP2, REG_ATMP1); /* implicit null-pointer check */ @@ -1499,19 +1582,19 @@ bool codegen_emit(jitdata *jd) s3 = emit_load_s3(jd, iptr, REG_ATMP2); /* XXX what if array is NULL */ - disp = dseg_add_functionptr(cd, BUILTIN_canstore); + disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore); M_AST(s1, REG_SP, 0*4); M_AST(s3, REG_SP, 1*4); - M_JSR_IMM(BUILTIN_canstore); - emit_exception_check(cd, iptr); + M_JSR_IMM(BUILTIN_FAST_canstore); + emit_arraystore_check(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_ATMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP1); s3 = emit_load_s3(jd, iptr, REG_ATMP2); M_INTMOVE(s2, REG_ITMP1); M_ISSL_IMM(2, REG_ITMP1); - M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP1); + M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1); M_ADRMOVE(s1, REG_ATMP1); M_AADDINT(REG_ITMP1, REG_ATMP1); /* implicit null-pointer check */ @@ -1522,6 +1605,8 @@ bool codegen_emit(jitdata *jd) /* METHOD INVOCATION *********************************************************/ case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */ + REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr); + bte = iptr->sx.s23.s3.bte; md = bte->md; goto gen_method; @@ -1561,27 +1646,27 @@ bool codegen_emit(jitdata *jd) #endif case TYPE_LNG: d = emit_load(jd, iptr, var, REG_ITMP12_PACKED); - M_LST(d, REG_SP, md->params[s3].regoff*4); + M_LST(d, REG_SP, md->params[s3].regoff); break; #if defined(ENABLE_SOFTFLOAT) case TYPE_FLT: #endif case TYPE_INT: d = emit_load(jd, iptr, var, REG_ITMP1); - M_IST(d, REG_SP, md->params[s3].regoff*4); + M_IST(d, REG_SP, md->params[s3].regoff); break; case TYPE_ADR: d = emit_load(jd, iptr, var, REG_ATMP1); - M_AST(d, REG_SP, md->params[s3].regoff*4); + M_AST(d, REG_SP, md->params[s3].regoff); break; #if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: d = emit_load(jd, iptr, var, REG_FTMP1); - M_FST(d, REG_SP, md->params[s3].regoff*4); + M_FST(d, REG_SP, md->params[s3].regoff); break; case TYPE_DBL: d = emit_load(jd, iptr, var, REG_FTMP1); - M_DST(d, REG_SP, md->params[s3].regoff*4); + M_DST(d, REG_SP, md->params[s3].regoff); break; #endif default: @@ -1591,13 +1676,15 @@ bool codegen_emit(jitdata *jd) /* arguments in place now */ switch(iptr->opc) { - case ICMD_BUILTIN: - disp = (ptrint) bte->fp; + case ICMD_BUILTIN: + if (bte->stub == NULL) + disp = (ptrint) bte->fp; + else + disp = (ptrint) bte->stub; d = md->returntype.type; M_JSR_IMM(disp); REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); - emit_exception_check(cd, iptr); break; case ICMD_INVOKESPECIAL: @@ -1607,7 +1694,7 @@ bool codegen_emit(jitdata *jd) /* fall through */ case ICMD_INVOKESTATIC: if (lm == NULL) { - codegen_addpatchref(cd, PATCHER_invokestatic_special, um, 0); + patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, 0); disp = 0; M_AMOV_IMM(disp, REG_ATMP1); } else { @@ -1623,7 +1710,7 @@ bool codegen_emit(jitdata *jd) case ICMD_INVOKEVIRTUAL: if (lm == NULL) { - codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0); + patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0); s1 = 0; } else { s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex; @@ -1631,26 +1718,26 @@ bool codegen_emit(jitdata *jd) /* load object pointer (==argument 0) */ M_ALD(REG_ATMP1, REG_SP, 0); /* implicit null-pointer check */ - M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl)); M_ALD(REG_ATMP3, REG_METHODPTR, s1); /* generate the actual call */ M_JSR(REG_ATMP3); break; 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; } else { - s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index; - s2 = sizeof(methodptr) * (lm - lm->class->methods); + s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->clazz->index; + s2 = sizeof(methodptr) * (lm - lm->clazz->methods); } /* load object pointer (==argument 0) */ M_ALD(REG_ATMP1, REG_SP, 0); /* implicit null-pointer check */ - M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl)); M_ALD(REG_METHODPTR, REG_METHODPTR, s1); M_ALD(REG_ATMP3, REG_METHODPTR, s2); @@ -1663,6 +1750,7 @@ bool codegen_emit(jitdata *jd) } /* switch (iptr->opc) */ REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); + REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr); /* store return value */ d = md->returntype.type; @@ -1704,8 +1792,8 @@ bool codegen_emit(jitdata *jd) case TYPE_DBL: s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1); if (iptr->opc == ICMD_BUILTIN) { - M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4); - M_DLD(s1, REG_SP, rd->memuse * 4); + M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4); + M_DLD(s1, REG_SP, rd->memuse * 4 + 4); } else { M_DBLMOVE(REG_FRESULT, s1); } @@ -1738,7 +1826,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; @@ -1784,8 +1872,8 @@ nowperformreturn: #if defined(ENABLE_THREADS) /* call lock_monitor_exit */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { - M_ILD(REG_ITMP3, REG_SP, rd->memuse * 4 + 2*4); + if (checksync && code_is_synchronized(code)) { + M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8); /* we need to save the proper return value */ /* we do not care for the long -> doubel convert space here */ @@ -1794,21 +1882,21 @@ nowperformreturn: case ICMD_DRETURN: #endif case ICMD_LRETURN: - M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4); + M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8); break; #if defined(ENABLE_SOFTFLOAT) case ICMD_FRETURN: #endif case ICMD_IRETURN: case ICMD_ARETURN: - M_IST(REG_RESULT , REG_SP, rd->memuse * 4); + M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8); break; #if !defined(ENABLE_SOFTFLOAT) case ICMD_FRETURN: - M_FST(REG_FRESULT, REG_SP, rd->memuse * 4); + M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8); break; case ICMD_DRETURN: - M_DST(REG_FRESULT, REG_SP, rd->memuse * 4); + M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8); break; #endif } @@ -1823,21 +1911,21 @@ nowperformreturn: case ICMD_DRETURN: #endif case ICMD_LRETURN: - M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4); + M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8); break; #if defined(ENABLE_SOFTFLOAT) case ICMD_FRETURN: #endif case ICMD_IRETURN: case ICMD_ARETURN: - M_ILD(REG_RESULT , REG_SP, rd->memuse * 4); + M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8); break; #if !defined(ENABLE_SOFTFLOAT) case ICMD_FRETURN: - M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4); + M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8); break; case ICMD_DRETURN: - M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4); + M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8); break; #endif } @@ -1847,7 +1935,7 @@ nowperformreturn: /* restore return address */ #if 0 - if (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD may have a displacement overflow. */ @@ -1858,18 +1946,18 @@ nowperformreturn: /* restore saved registers */ for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) { - p--; M_ILD(rd->savintregs[i], REG_SP, p * 4); + p-=8; M_ILD(rd->savintregs[i], REG_SP, p); } for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) { - p--; M_ALD(rd->savadrregs[i], REG_SP, p*4); + p-=8; M_ALD(rd->savadrregs[i], REG_SP, p); } #if !defined(ENABLE_SOFTFLOAT) for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) { - p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4); + p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p); } #endif /* deallocate stack */ - M_AADD_IMM(cd->stackframesize*4, REG_SP); + M_AADD_IMM(cd->stackframesize, REG_SP); M_RET; } break; @@ -1904,9 +1992,6 @@ nowperformreturn: superindex = super->index; } - if ((super == NULL) || !(super->flags & ACC_INTERFACE)) - CODEGEN_CRITICAL_SECTION_NEW; - s1 = emit_load_s1(jd, iptr, REG_ATMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); @@ -1921,7 +2006,7 @@ nowperformreturn: M_ATST(s1); emit_label_beq(cd, BRANCH_LABEL_1); - codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0); M_IMOV_IMM32(0, REG_ITMP3); M_IAND_IMM(ACC_INTERFACE, REG_ITMP3); @@ -1932,13 +2017,13 @@ nowperformreturn: if ((super == NULL) || (super->flags & ACC_INTERFACE)) { if (super == NULL) { - codegen_addpatchref(cd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0); + patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0); } else { M_ATST(s1); emit_label_beq(cd, BRANCH_LABEL_3); } - M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl)); M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength)); M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */ M_ITST(REG_ITMP3); @@ -1960,7 +2045,7 @@ nowperformreturn: if (super == NULL) { emit_label(cd, BRANCH_LABEL_2); - codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0); M_AMOV_IMM(0, REG_ATMP2); } else { M_AMOV_IMM(super->vftbl, REG_ATMP2); @@ -1968,16 +2053,12 @@ nowperformreturn: emit_label_beq(cd, BRANCH_LABEL_5); } - M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl)); - - CODEGEN_CRITICAL_SECTION_START; + M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl)); M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval)); - CODEGEN_CRITICAL_SECTION_END; - M_ISUB(REG_ITMP3, REG_ITMP1); M_ICMP(REG_ITMP2, REG_ITMP1); M_BHI(4); @@ -2029,9 +2110,6 @@ nowperformreturn: superindex = super->index; } - if ((super == NULL) || !(super->flags & ACC_INTERFACE)) - CODEGEN_CRITICAL_SECTION_NEW; - s1 = emit_load_s1(jd, iptr, REG_ATMP1); assert(VAROP(iptr->s1)->type == TYPE_ADR); @@ -2041,7 +2119,7 @@ nowperformreturn: M_ATST(s1); emit_label_beq(cd, BRANCH_LABEL_1); - codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0); M_IMOV_IMM32(0, REG_ITMP2); M_IAND_IMM(ACC_INTERFACE, REG_ITMP2); @@ -2052,13 +2130,13 @@ nowperformreturn: if ((super == NULL) || (super->flags & ACC_INTERFACE)) { if (super == NULL) { - codegen_addpatchref(cd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0); + patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0); } else { M_ATST(s1); emit_label_beq(cd, BRANCH_LABEL_3); } - M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl)); + M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl)); M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength)); M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */ @@ -2081,7 +2159,7 @@ nowperformreturn: if (super == NULL) { emit_label(cd, BRANCH_LABEL_2); - codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0); M_AMOV_IMM(0, REG_ATMP3); } else { M_AMOV_IMM(super->vftbl, REG_ATMP3); @@ -2089,16 +2167,12 @@ nowperformreturn: emit_label_beq(cd, BRANCH_LABEL_5); } - M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl)); - - CODEGEN_CRITICAL_SECTION_START; + M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl)); M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); /* REG_ITMP3 == sub->vftbl->baseval */ M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval)); - CODEGEN_CRITICAL_SECTION_END; - M_ISUB(REG_ITMP1, REG_ITMP3); M_ICMP(REG_ITMP2, REG_ITMP3); /* XXX was CMPU */ @@ -2120,7 +2194,7 @@ nowperformreturn: s1 = emit_load_s1(jd, iptr, REG_ATMP2); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0); M_AMOV_IMM(0, REG_ATMP1); } else { M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1); @@ -2227,7 +2301,7 @@ nowperformreturn: /* a1 = arraydescriptor */ if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0); + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0); M_AMOV_IMM(0, REG_ATMP1); } else { M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1); @@ -2257,59 +2331,44 @@ nowperformreturn: exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc); return false; } /* switch */ - M_TPF; + /* M_TPF; */ /* nop after each ICMD */ } /* for each instruction */ - } /* if (btpre->flags >= BBREACHED) */ - } /* for each basic block */ - - dseg_createlinenumbertable(cd); - /* generate stubs */ - emit_patcher_stubs(jd); - REPLACEMENT_EMIT_STUBS(jd); + /* At the end of a basic block we may have to append some nops, + because the patcher stub calling code might be longer than the + actual instruction. So codepatching does not change the + following block unintentionally. */ - return true; -} - - -/* codegen_emit_stub_compiler ************************************************** - - Emits a stub routine which calls the compiler. - -*******************************************************************************/ - -void codegen_emit_stub_compiler(jitdata *jd) -{ - methodinfo *m; - codegendata *cd; + if (cd->mcodeptr < cd->lastmcodeptr) { + while (cd->mcodeptr < cd->lastmcodeptr) { + M_NOP; + } + } - /* get required compiler data */ - m = jd->m; - cd = jd->cd; + } /* if (btpre->flags >= BBREACHED) */ + } /* for each basic block */ - /* code for the stub */ + /* generate stubs */ + emit_patcher_traps(jd); - M_AMOV_IMM(m, REG_ATMP1); - M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3); - M_JMP(REG_ATMP3); + return true; } - /* codegen_emit_stub_native **************************************************** Emits a stub routine which calls a native method. *******************************************************************************/ -void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) +void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams) { methodinfo *m; codeinfo *code; codegendata *cd; registerdata *rd; methoddesc *md; - s4 nativeparams, i, j, t, s1, s2; + s4 i, j, t, s1, s2; /* get required compiler data */ @@ -2319,58 +2378,30 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) rd = jd->rd; md = m->parseddesc; - nativeparams = (m->flags & ACC_STATIC) ? 2 : 1; /* calc stackframe size */ - cd->stackframesize = sizeof(stackframeinfo) / SIZEOF_VOID_P + - sizeof(localref_table) / SIZEOF_VOID_P + - nmd->memuse + - 1 + /* functionptr */ - 4; /* args for codegen_start_native_call */ + cd->stackframesize = + sizeof(stackframeinfo_t) / SIZEOF_VOID_P + + sizeof(localref_table) / SIZEOF_VOID_P + + nmd->memuse + + 1 + /* functionptr */ + 4; /* args for codegen_start_native_call */ /* create method header */ (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ - (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */ - (void) dseg_add_unique_s4(cd, 0); /* IsSync */ + (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */ (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */ (void) dseg_add_unique_s4(cd, 0); /* IntSave */ (void) dseg_add_unique_s4(cd, 0); /* FltSave */ - (void) dseg_addlinenumbertablesize(cd); - (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */ - - /* print call trace */ -#if !defined(NDEBUG) - if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) { - emit_verbosecall_enter(jd); - } -#endif /* generate code */ - M_AADD_IMM(-(cd->stackframesize*4), REG_SP); - - /* get function address (this must happen before the stackframeinfo) */ -#if !defined(WITH_STATIC_CLASSPATH) - if (f == NULL) { - codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0); - } -#endif - M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */ - - M_AST(REG_ATMP2, REG_SP, 4 * 4); + M_AADD_IMM(-(cd->stackframesize*8), REG_SP); /* put arguments for codegen_start_native_call onto stack */ /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */ M_AMOV(REG_SP, REG_ATMP1); - M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1); - - M_ALD(REG_ATMP3, REG_ATMP1, 0 * 4); - M_AST(REG_ATMP3, REG_SP, 3 * 4); /* ra */ - - M_AST(REG_ATMP1, REG_SP, 0 * 4); /* datasp */ - - M_AADD_IMM(1 * 4 , REG_ATMP1); - M_AST(REG_ATMP1, REG_SP, 2 * 4); /* sp */ + M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */ M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */ dseg_adddata(cd); /* this patches it */ @@ -2379,17 +2410,18 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) M_JSR_IMM(codegen_start_native_call); - /* load function pointer */ - M_ALD(REG_ATMP2, REG_SP, 4 * 4); + /* remember class argument */ + if (m->flags & ACC_STATIC) + M_INT2ADRMOVE(REG_RESULT, REG_ATMP3); /* copy arguments into stackframe */ - for (i = md->paramcount -1, j = i + nativeparams; i >= 0; --i, --j) { + for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j) { t = md->paramtypes[i].type; /* all arguments via stack */ assert(md->params[i].inmemory); - s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4; - s2 = nmd->params[j].regoff * 4; + s1 = md->params[i].regoff + cd->stackframesize * 8 + 4; + s2 = nmd->params[j].regoff; /* simply copy argument stack */ M_ILD(REG_ITMP1, REG_SP, s1); @@ -2400,66 +2432,51 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) } } - /* for static function class as second arg */ - if (m->flags & ACC_STATIC) { - M_AMOV_IMM(m->class, REG_ATMP1); - M_AST(REG_ATMP1, REG_SP, 1 * 4); + /* builtins are not invoked like natives, environemtn and clazz are only needed for natives */ + if (m->flags & ACC_NATIVE) { + /* for static function class as second arg */ + if (m->flags & ACC_STATIC) + M_AST(REG_ATMP3, REG_SP, 1 * 4); + + /* env ist first argument */ + M_AMOV_IMM(VM_get_jnienv(), REG_ATMP1); + M_AST(REG_ATMP1, REG_SP, 0 * 4); } - /* env ist first argument */ - M_AMOV_IMM(_Jv_env, REG_ATMP1); - M_AST(REG_ATMP1, REG_SP, 0 * 4); /* call the native function */ + M_AMOV_IMM(f, REG_ATMP2); M_JSR(REG_ATMP2); /* save return value */ switch (md->returntype.type) { case TYPE_VOID: break; -#if defined(ENABLE_SOFTFLOAT) + /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */ case TYPE_DBL: -#endif case TYPE_LNG: - M_IST(REG_D1, REG_SP, 2 * 4); + M_IST(REG_D1, REG_SP, 2 * 8); /* fall through */ -#if defined(ENABLE_SOFTFLOAT) case TYPE_FLT: -#endif case TYPE_INT: case TYPE_ADR: - M_IST(REG_D0, REG_SP, 1 * 4); + M_IST(REG_D0, REG_SP, 2 * 8); /* XXX can this be correct ? */ break; -#if !defined(ENABLE_SOFTFLOAT) - /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */ - case TYPE_FLT: - M_INT2FLTMOVE(REG_D0, REG_D0); - M_FST(REG_D0, REG_SP, 1 * 4); - break; - case TYPE_DBL: - /* to convert %d0, %d1 to dbl we need 2 memory slots - * it is safe reuse argument stack slots here */ - M_IST(REG_D0, REG_SP, 1 * 4); - M_IST(REG_D1, REG_SP, 2 * 4); - /*M_DST(REG_D0, REG_SP, 1 * 4);*/ - break; -#endif default: assert(0); } - - /* print call trace */ -#if ! defined(NDEBUG) - if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) { - emit_verbosecall_exit(jd); - } -#endif + /* remove native stackframe info */ /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */ - M_AMOV(REG_SP, REG_ATMP3); - M_AADD_IMM(cd->stackframesize * 4, REG_ATMP3); - M_AST(REG_ATMP3, REG_SP, 0 * 4); /* datasp */ + M_AMOV(REG_SP, REG_ATMP1); + M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */ + + M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */ + dseg_adddata(cd); /* this patches it */ + + M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */ + M_JSR_IMM(codegen_finish_native_call); M_INT2ADRMOVE(REG_RESULT, REG_ATMP1); @@ -2467,33 +2484,32 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) switch (md->returntype.type) { case TYPE_VOID: break; -#if defined(ENABLE_SOFTFLOAT) case TYPE_DBL: -#endif - case TYPE_LNG: - M_ILD(REG_D1, REG_SP, 2 * 4); + case TYPE_LNG: M_ILD(REG_D1, REG_SP, 2 * 8); /* fall through */ -#if defined(ENABLE_SOFTFLOAT) case TYPE_FLT: -#endif case TYPE_INT: case TYPE_ADR: - M_ILD(REG_D0, REG_SP, 1 * 4); + M_ILD(REG_D0, REG_SP, 2 * 8); /* XXX */ break; + default: assert(0); + } #if !defined(ENABLE_SOFTFLOAT) + /* additionally load values into floating points registers + * as cacao jit code expects them there */ + switch (md->returntype.type) { case TYPE_FLT: - M_FLD(REG_D0, REG_SP, 1 * 4); + M_FLD(REG_D0, REG_SP, 2 * 8); break; case TYPE_DBL: - M_DLD(REG_D0, REG_SP, 1 * 4); + M_DLD(REG_D0, REG_SP, 2 * 8); /* XXX */ break; -#endif - default: assert(0); } +#endif /* restore saved registers */ - M_AADD_IMM(cd->stackframesize*4, REG_SP); + M_AADD_IMM(cd->stackframesize*8, REG_SP); /* check for exception */ M_ATST(REG_ATMP1); M_BNE(2); @@ -2507,9 +2523,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* should never be reached from within jit code*/ M_JSR_IMM(0); - - /* generate patcher stub call code */ - emit_patcher_stubs(jd); }