X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fpowerpc64%2Fcodegen.c;h=7c609638f81d49574abc9c015c5ecee2967a24bf;hb=8c6bb03b79a31fcdb02e2331a91a928d558c2845;hp=b292ccc170cfa6fb0b82aba2e5dea92172332e95;hpb=93d91b37f73057094a15b9d9ba14e1bd06e13f99;p=cacao.git diff --git a/src/vm/jit/powerpc64/codegen.c b/src/vm/jit/powerpc64/codegen.c index b292ccc17..7c609638f 100644 --- a/src/vm/jit/powerpc64/codegen.c +++ b/src/vm/jit/powerpc64/codegen.c @@ -1,9 +1,7 @@ /* src/vm/jit/powerpc64/codegen.c - machine code generator for 64-bit PowerPC - 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. @@ -39,35 +37,34 @@ #include "vm/jit/powerpc64/arch.h" #include "vm/jit/powerpc64/codegen.h" -#include "mm/memory.h" +#include "mm/memory.hpp" -#include "native/localref.h" -#include "native/native.h" +#include "native/localref.hpp" +#include "native/native.hpp" -#include "threads/lock-common.h" +#include "threads/lock.hpp" -#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/vm.hpp" #include "vm/jit/abi.h" #include "vm/jit/abi-asm.h" -#include "vm/jit/md.h" #include "vm/jit/asmpart.h" -#include "vm/jit/codegen-common.h" +#include "vm/jit/codegen-common.hpp" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" -#include "vm/jit/jit.h" -#include "vm/jit/parse.h" -#include "vm/jit/patcher.h" +#include "vm/jit/emit-common.hpp" +#include "vm/jit/jit.hpp" +#include "vm/jit/linenumbertable.hpp" +#include "vm/jit/parse.hpp" +#include "vm/jit/patcher-common.hpp" #include "vm/jit/reg.h" -#include "vm/jit/replace.h" -#include "vm/jit/stacktrace.h" - -#include "vmcore/loader.h" -#include "vmcore/options.h" +#include "vm/jit/replace.hpp" +#include "vm/jit/stacktrace.hpp" +#include "vm/jit/trap.h" #if defined(ENABLE_LSRA) # include "vm/jit/allocator/lsra.h" @@ -91,7 +88,6 @@ bool codegen_emit(jitdata *jd) varinfo *var; basicblock *bptr; instruction *iptr; - exception_entry *ex; u2 currentline; methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */ unresolved_method *um; @@ -135,7 +131,7 @@ bool codegen_emit(jitdata *jd) /* monitor_exit. The stack position for the argument can not be shared */ /* with place to save the return register on PPC64, since both values */ /* reside in R3 */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { /* reserve 2 slots for long/double return values for monitorexit */ cd->stackframesize += 2; } @@ -156,39 +152,21 @@ bool codegen_emit(jitdata *jd) (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */ -#if defined(ENABLE_THREADS) - /* IsSync contains the offset relative to the stack pointer for the - argument of monitor_exit used in the exception handler. Since the - offset could be zero and give a wrong meaning of the flag it is - offset by one. - */ - - if (checksync && (m->flags & ACC_SYNCHRONIZED)) - (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* 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, 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 */ + (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */ + (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ - 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); - } - /* create stack frame (if necessary) */ - if (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { M_MFLR(REG_ZERO); M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET); } @@ -260,7 +238,7 @@ bool codegen_emit(jitdata *jd) #if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { /* stackoffset for argument used for LOCK_monitor_exit */ s1 = rd->memuse; @@ -288,13 +266,13 @@ bool codegen_emit(jitdata *jd) /* get or test the lock object */ if (m->flags & ACC_STATIC) { - p = dseg_add_address(cd, &m->class->object.header); + p = dseg_add_address(cd, &m->clazz->object.header); M_ALD(REG_A0, REG_PV, p); } else { M_TST(REG_A0); M_BNE(1); - M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER); + M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException); } M_AST(REG_A0, REG_SP, s1 * 8); /* rd->memuse * 8 */ @@ -388,7 +366,7 @@ bool codegen_emit(jitdata *jd) 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; } @@ -408,14 +386,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_inline_start(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_end(cd, iptr); + linenumbertable_list_entry_add(cd, iptr->line); break; case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */ @@ -464,7 +442,7 @@ bool codegen_emit(jitdata *jd) if (INSTRUCTION_IS_UNRESOLVED(iptr)) { disp = dseg_add_unique_address(cd, iptr->sx.val.c.ref); - codegen_addpatchref(cd, PATCHER_aconst, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.val.c.ref, disp); } else { @@ -1202,7 +1180,6 @@ bool codegen_emit(jitdata *jd) case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */ case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */ - s1 = emit_load_s1(jd, iptr, REG_FTMP1); s2 = emit_load_s2(jd, iptr, REG_FTMP2); d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); @@ -1231,109 +1208,8 @@ bool codegen_emit(jitdata *jd) M_IADD_IMM(REG_ZERO, -1, d); emit_store_dst(jd, iptr, d); break; - - case ICMD_IF_FCMPEQ: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPEQ: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - M_BNAN(1); - emit_beq(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPNE: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPNE: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - emit_bnan(cd, iptr->dst.block); - emit_bne(cd, iptr->dst.block); - break; - - - case ICMD_IF_FCMPL_LT: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPL_LT: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - emit_bnan(cd, iptr->dst.block); - emit_blt(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPL_GT: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPL_GT: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - M_BNAN(1); - emit_bgt(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPL_LE: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPL_LE: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - emit_bnan(cd, iptr->dst.block); - emit_ble(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPL_GE: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPL_GE: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - M_BNAN(1); - emit_bge(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPG_LT: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPG_LT: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - M_BNAN(1); - emit_blt(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPG_GT: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPG_GT: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - emit_bnan(cd, iptr->dst.block); - emit_bgt(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPG_LE: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPG_LE: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - M_BNAN(1); - emit_ble(cd, iptr->dst.block); - break; - - case ICMD_IF_FCMPG_GE: /* ..., value, value ==> ... */ - case ICMD_IF_DCMPG_GE: - - s1 = emit_load_s1(jd, iptr, REG_FTMP1); - s2 = emit_load_s2(jd, iptr, REG_FTMP2); - M_FCMPU(s1, s2); - emit_bnan(cd, iptr->dst.block); - emit_bge(cd, iptr->dst.block); - break; - + /* memory operations **************************************************/ case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */ @@ -1567,7 +1443,7 @@ bool codegen_emit(jitdata *jd) fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_get_putstatic, + patcher_add_patch_ref(jd, PATCHER_get_putstatic, iptr->sx.s23.s3.uf, disp); } @@ -1576,8 +1452,8 @@ bool codegen_emit(jitdata *jd) fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) { - codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp); + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) { + patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, disp); } } @@ -1615,7 +1491,7 @@ bool codegen_emit(jitdata *jd) fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_get_putstatic, + patcher_add_patch_ref(jd, PATCHER_get_putstatic, iptr->sx.s23.s3.uf, disp); } else { @@ -1623,8 +1499,8 @@ bool codegen_emit(jitdata *jd) fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) { - codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp); + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) { + patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, disp); } } @@ -1663,7 +1539,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; @@ -1719,7 +1595,7 @@ bool codegen_emit(jitdata *jd) s2 = emit_load_s2(jd, iptr, REG_FTMP2); if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0); + patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0); } @@ -1753,7 +1629,7 @@ bool codegen_emit(jitdata *jd) #ifdef ENABLE_VERIFIER 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); } #endif /* ENABLE_VERIFIER */ @@ -1762,12 +1638,16 @@ bool codegen_emit(jitdata *jd) M_ALD(REG_ITMP2, REG_PV, disp); M_MTCTR(REG_ITMP2); - if (jd->isleafmethod) M_MFLR(REG_ITMP3); /* save LR */ + if (code_is_leafmethod(code)) + M_MFLR(REG_ITMP3); /* save LR */ + M_BL(0); /* get current PC */ M_MFLR(REG_ITMP2_XPC); - if (jd->isleafmethod) M_MTLR(REG_ITMP3); /* restore LR */ - M_RTS; /* jump to CTR */ + if (code_is_leafmethod(code)) + M_MTLR(REG_ITMP3); /* restore LR */ + + M_RTS; /* jump to CTR */ ALIGNCODENOP; break; @@ -1926,7 +1806,7 @@ bool codegen_emit(jitdata *jd) #ifdef ENABLE_VERIFIER 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); } #endif /* ENABLE_VERIFIER */ @@ -1959,7 +1839,7 @@ nowperformreturn: #endif #if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { disp = dseg_add_functionptr(cd, LOCK_monitor_exit); M_ALD(REG_ITMP3, REG_PV, disp); M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */ @@ -2006,7 +1886,7 @@ nowperformreturn: /* restore return address */ - if (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD may have a displacement overflow. */ @@ -2177,23 +2057,25 @@ gen_method: switch (iptr->opc) { case ICMD_BUILTIN: - disp = dseg_add_functionptr(cd, bte->fp); - M_ALD(REG_PV, REG_PV, disp); - M_ALD(REG_PV, REG_PV, 0); /* TOC */ + if (bte->stub == NULL) { + disp = dseg_add_functionptr(cd, bte->fp); + M_ALD(REG_PV, REG_PV, disp); + M_ALD(REG_PV, REG_PV, 0); /* TOC */ + } + else { + disp = dseg_add_functionptr(cd, bte->stub); + M_ALD(REG_PV, REG_PV, disp); + } /* generate the actual call */ - REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); M_MTCTR(REG_PV); M_JSR; REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); disp = (s4) (cd->mcodeptr - cd->mcodebase); M_MFLR(REG_ITMP1); M_LDA(REG_PV, REG_ITMP1, -disp); - - emit_exception_check(cd, iptr); break; - case ICMD_INVOKESPECIAL: emit_nullpointer_check(cd, iptr, REG_A0); /* fall through */ @@ -2202,7 +2084,7 @@ gen_method: if (lm == NULL) { disp = dseg_add_unique_address(cd, um); - codegen_addpatchref(cd, PATCHER_invokestatic_special, + patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, disp); } else { disp = dseg_add_address(cd, lm->stubroutine); @@ -2217,11 +2099,11 @@ gen_method: disp = (s4) (cd->mcodeptr - cd->mcodebase); M_MFLR(REG_ITMP1); M_LDA(REG_PV, REG_ITMP1, -disp); - break; + 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]) + @@ -2244,16 +2126,16 @@ gen_method: 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; + sizeof(methodptr*) * lm->clazz->index; - s2 = sizeof(methodptr) * (lm - lm->class->methods); + s2 = sizeof(methodptr) * (lm - lm->clazz->methods); } /* implicit null-pointer check */ @@ -2320,10 +2202,6 @@ gen_method: superindex = super->index; } - if ((super == NULL) || !(super->flags & ACC_INTERFACE)) { - CODEGEN_CRITICAL_SECTION_NEW; - } - s1 = emit_load_s1(jd, iptr, REG_ITMP1); /* if class is not resolved, check which code to call */ @@ -2333,8 +2211,8 @@ gen_method: 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); @@ -2348,7 +2226,7 @@ gen_method: if ((super == NULL) || (super->flags & ACC_INTERFACE)) { if (super == NULL) { - codegen_addpatchref(cd, + patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0); @@ -2381,7 +2259,7 @@ gen_method: emit_label(cd, BRANCH_LABEL_2); disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_checkcast_class, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, disp); } else { @@ -2392,16 +2270,12 @@ gen_method: M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl)); - CODEGEN_CRITICAL_SECTION_START; - M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_ALD(REG_ITMP2, REG_PV, disp); if (s1 != REG_ITMP1) { M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval)); - CODEGEN_CRITICAL_SECTION_END; - M_SUB(REG_ITMP3, REG_ITMP1, REG_ITMP3); M_EXTSW(REG_ITMP3, REG_ITMP3); } else { @@ -2410,9 +2284,6 @@ gen_method: M_EXTSW(REG_ITMP3, REG_ITMP3); M_ALD(REG_ITMP2, REG_PV, disp); M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval)); - - CODEGEN_CRITICAL_SECTION_END; - } M_CMPU(REG_ITMP3, REG_ITMP2); emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1); @@ -2436,7 +2307,7 @@ gen_method: 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); } else { @@ -2489,10 +2360,6 @@ gen_method: superindex = super->index; } - if ((super == NULL) || !(super->flags & ACC_INTERFACE)) { - CODEGEN_CRITICAL_SECTION_NEW; - } - s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); if (s1 == d) { @@ -2509,7 +2376,7 @@ gen_method: 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); M_ILD(REG_ITMP3, REG_PV, disp); @@ -2521,7 +2388,7 @@ gen_method: if ((super == NULL) || (super->flags & ACC_INTERFACE)) { if (super == NULL) { - codegen_addpatchref(cd, + patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0); @@ -2556,7 +2423,7 @@ gen_method: emit_label(cd, BRANCH_LABEL_2); disp = dseg_add_unique_address(cd, NULL); - codegen_addpatchref(cd, PATCHER_instanceof_class, + patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, disp); @@ -2569,14 +2436,10 @@ gen_method: M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl)); M_ALD(REG_ITMP2, REG_PV, disp); - CODEGEN_CRITICAL_SECTION_START; - M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval)); - CODEGEN_CRITICAL_SECTION_END; - M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); M_EXTSW(REG_ITMP1, REG_ITMP1); M_CMPU(REG_ITMP1, REG_ITMP2); @@ -2628,7 +2491,7 @@ gen_method: 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); } else { disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls); @@ -2671,11 +2534,9 @@ gen_method: } /* if (bptr -> flags >= BBREACHED) */ } /* for basic block */ - dseg_createlinenumbertable(cd); - - /* generate stubs */ + /* generate traps */ - emit_patcher_stubs(jd); + emit_patcher_traps(jd); /* everything's ok */ @@ -2683,48 +2544,22 @@ gen_method: } -/* codegen_emit_stub_compiler ************************************************** - - Emits a stub routine which calls the compiler. - -*******************************************************************************/ - -void codegen_emit_stub_compiler(jitdata *jd) -{ - methodinfo *m; - codegendata *cd; - - /* get required compiler data */ - - m = jd->m; - cd = jd->cd; - - /* code for the stub */ - - M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); - M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); - M_MTCTR(REG_PV); - M_RTS; -} - - /* 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; methoddesc *md; - s4 nativeparams; s4 i, j; s4 t; - s4 s1, s2, disp; - s4 funcdisp; + int s1, s2; + int disp; /* get required compiler data */ @@ -2732,15 +2567,18 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) code = jd->code; cd = jd->cd; + /* Sanity check. */ + + assert(!code_is_leafmethod(code)); + /* set some variables */ md = m->parseddesc; - nativeparams = (m->flags & ACC_STATIC) ? 2 : 1; /* calculate stackframe size */ cd->stackframesize = - sizeof(stackframeinfo) / SIZEOF_VOID_P + + sizeof(stackframeinfo_t) / SIZEOF_VOID_P + sizeof(localref_table) / SIZEOF_VOID_P + 4 + /* 4 stackframeinfo arguments (darwin)*/ nmd->paramcount + @@ -2750,14 +2588,11 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* create method header */ - (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ - (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */ - (void) dseg_add_unique_s4(cd, 0); /* IsSync */ - (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 */ + (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ + (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 */ /* generate code */ @@ -2765,43 +2600,22 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET); M_STDU(REG_SP, REG_SP, -(cd->stackframesize * 8)); -#if !defined(NDEBUG) - if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) - emit_verbosecall_enter(jd); -#endif - - /* get function address (this must happen before the stackframeinfo) */ - - funcdisp = dseg_add_functionptr(cd, f); - -#if !defined(WITH_STATIC_CLASSPATH) - if (f == NULL) { - codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp); - } -#endif - /* save integer and float argument registers */ - j = 0; - for (i = 0; i < md->paramcount; i++) { - t = md->paramtypes[i].type; - - if (IS_INT_LNG_TYPE(t)) { - if (!md->params[i].inmemory) { - s1 = md->params[i].regoff; - M_LST(s1, REG_SP, LA_SIZE + PA_SIZE + 4*8 + j * 8); - j++; - } - } - } + if (!md->params[i].inmemory) { + s1 = md->params[i].regoff; - for (i = 0; i < md->paramcount; i++) { - if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) { - if (!md->params[i].inmemory) { - s1 = md->params[i].regoff; - M_DST(s1, REG_SP, LA_SIZE + PA_SIZE + 4*8 + j * 8); - j++; + switch (md->paramtypes[i].type) { + case TYPE_INT: + case TYPE_LNG: + case TYPE_ADR: + M_LST(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DST(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8); + break; } } } @@ -2811,7 +2625,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) M_MOV(REG_SP, REG_A0); M_MOV(REG_PV, REG_A1); disp = dseg_add_functionptr(cd, codegen_start_native_call); - M_ALD(REG_ITMP1, REG_PV, disp); M_ALD(REG_ITMP1, REG_ITMP1, 0); /* TOC */ M_MTCTR(REG_ITMP1); @@ -2824,33 +2637,27 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* restore integer and float argument registers */ - j = 0; - for (i = 0; i < md->paramcount; i++) { - t = md->paramtypes[i].type; - - if (IS_INT_LNG_TYPE(t)) { - if (!md->params[i].inmemory) { - s1 = md->params[i].regoff; - M_LLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8); - j++; - } - } - } + if (!md->params[i].inmemory) { + s1 = md->params[i].regoff; - for (i = 0; i < md->paramcount; i++) { - if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) { - if (!md->params[i].inmemory) { - s1 = md->params[i].regoff; - M_DLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8); - j++; + switch (md->paramtypes[i].type) { + case TYPE_INT: + case TYPE_LNG: + case TYPE_ADR: + M_LLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DLD(s1, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + i * 8); + break; } } } /* copy or spill arguments to new locations */ - 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; if (IS_INT_LNG_TYPE(t)) { @@ -2889,21 +2696,26 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) } } - /* put class into second argument register */ + /* Handle native Java methods. */ - if (m->flags & ACC_STATIC) - M_MOV(REG_ITMP3, REG_A1); + if (m->flags & ACC_NATIVE) { + /* put class into second argument register */ + + if (m->flags & ACC_STATIC) + M_MOV(REG_ITMP3, REG_A1); - /* put env into first argument register */ + /* put env into first argument register */ - disp = dseg_add_unique_address(cd, _Jv_env); - M_ALD(REG_A0, REG_PV, disp); + disp = dseg_add_unique_address(cd, VM_get_jnienv()); + M_ALD(REG_A0, REG_PV, disp); + } - /* generate the actual native call */ + /* Call the native function. */ /* native functions have a different TOC for sure */ M_AST(REG_TOC, REG_SP, 40); /* save old TOC */ - M_ALD(REG_ITMP3, REG_PV, funcdisp); + disp = dseg_add_functionptr(cd, f); + M_ALD(REG_ITMP3, REG_PV, disp); M_ALD(REG_TOC, REG_ITMP3, 8); /* load TOC from func. descriptor */ M_ALD(REG_ITMP3, REG_ITMP3, 0); M_MTCTR(REG_ITMP3); @@ -2914,24 +2726,17 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) if (md->returntype.type != TYPE_VOID) { if (IS_INT_LNG_TYPE(md->returntype.type)) { - M_LST(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); + M_LST(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8); } else { - M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); + M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8); } } -#if !defined(NDEBUG) - /* print call trace */ - - if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) { - emit_verbosecall_exit(jd); - } -#endif - /* remove native stackframe info */ - M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A0); + M_MOV(REG_SP, REG_A0); + M_MOV(REG_PV, REG_A1); disp = dseg_add_functionptr(cd, codegen_finish_native_call); M_ALD(REG_ITMP1, REG_PV, disp); M_ALD(REG_ITMP1, REG_ITMP1, 0); /* XXX what about TOC? */ @@ -2943,14 +2748,10 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) if (md->returntype.type != TYPE_VOID) { if (IS_INT_LNG_TYPE(md->returntype.type)) { - M_LLD(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); + M_LLD(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8); } else { -/* if (IS_2_WORD_TYPE(md->returntype.type)) */ - M_DLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); -/* else - M_FLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); F XXX - */ + M_DLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 2 * 8); } } @@ -2973,15 +2774,9 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) M_ALD(REG_ITMP3, REG_PV, disp); M_MTCTR(REG_ITMP3); M_RTS; - - /* generate patcher stub call code */ - - emit_patcher_stubs(jd); } - - /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where