X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fx86_64%2Fcodegen.c;h=623978d42c2ebedc8a8e21b0c05e630bc9fea2db;hb=ac822cd13dc1a39b128ec99771972139fabbb3a1;hp=75de5aa030187d57b10cd15e8a71ead6b2a3989b;hpb=6ae727f265cc1ca9cc46c97df802a1940355e3ed;p=cacao.git diff --git a/src/vm/jit/x86_64/codegen.c b/src/vm/jit/x86_64/codegen.c index 75de5aa03..623978d42 100644 --- a/src/vm/jit/x86_64/codegen.c +++ b/src/vm/jit/x86_64/codegen.c @@ -1,9 +1,7 @@ /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64 - 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. @@ -29,6 +27,7 @@ #include #include +#include #include "vm/types.h" @@ -40,39 +39,41 @@ #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/exceptions.hpp" #include "vm/global.h" -#include "vm/stringlocal.h" -#include "vm/vm.h" +#include "vm/loader.h" +#include "vm/options.h" +#include "vm/primitive.hpp" +#include "vm/statistics.h" +#include "vm/string.hpp" +#include "vm/vm.hpp" #include "vm/jit/abi.h" #include "vm/jit/asmpart.h" +#include "vm/jit/code.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" #include "vm/jit/emit-common.h" -#include "vm/jit/jit.h" +#include "vm/jit/jit.hpp" +#include "vm/jit/linenumbertable.h" #include "vm/jit/methodheader.h" #include "vm/jit/parse.h" #include "vm/jit/patcher-common.h" #include "vm/jit/reg.h" #include "vm/jit/replace.h" -#include "vm/jit/stacktrace.h" +#include "vm/jit/stacktrace.hpp" +#include "vm/jit/trap.h" #if defined(ENABLE_LSRA) # include "vm/jit/allocator/lsra.h" #endif -#include "vmcore/loader.h" -#include "vmcore/options.h" -#include "vmcore/statistics.h" - /* codegen_emit **************************************************************** @@ -92,7 +93,6 @@ bool codegen_emit(jitdata *jd) varinfo *var, *dst; basicblock *bptr; instruction *iptr; - exception_entry *ex; constant_classref *cr; unresolved_class *uc; methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */ @@ -134,7 +134,7 @@ bool codegen_emit(jitdata *jd) #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) + if (checksync && code_is_synchronized(code)) cd->stackframesize++; #endif @@ -142,7 +142,7 @@ bool codegen_emit(jitdata *jd) native code e.g. libc or jni (alignment problems with movaps). */ - if (!jd->isleafmethod || opt_verbosecall) + if (!code_is_leafmethod(code) || opt_verbosecall) cd->stackframesize |= 0x1; /* create method header */ @@ -150,36 +150,16 @@ 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 */ + code->synchronizedoffset = rd->memuse * 8; + + if (code_is_leafmethod(code)) + (void) dseg_add_unique_s4(cd, 1); /* IsLeaf */ 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, 0); /* 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 */ - (void) dseg_addlinenumbertablesize(cd); - - (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */ - - /* 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); - } - #if defined(ENABLE_PROFILING) /* generate method profiling code */ @@ -262,7 +242,7 @@ bool codegen_emit(jitdata *jd) /* save monitorenter argument */ #if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { /* stack offset for monitor argument */ s1 = rd->memuse; @@ -282,12 +262,12 @@ bool codegen_emit(jitdata *jd) /* decide which monitor enter function to call */ if (m->flags & ACC_STATIC) { - M_MOV_IMM(&m->class->object.header, REG_A0); + M_MOV_IMM(&m->clazz->object.header, REG_A0); } else { M_TEST(REG_A0); M_BNE(8); - M_ALD_MEM(REG_A0, EXCEPTION_HARDWARE_NULLPOINTER); + M_ALD_MEM(REG_A0, TRAP_NullPointerException); } M_AST(REG_A0, REG_SP, s1 * 8); @@ -401,7 +381,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; } @@ -421,14 +401,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 */ @@ -1768,11 +1748,11 @@ bool codegen_emit(jitdata *jd) fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) { + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) { PROFILE_CYCLE_STOP; patcher_add_patch_ref(jd, PATCHER_initialize_class, - fi->class, 0); + fi->clazz, 0); PROFILE_CYCLE_START; } @@ -1823,11 +1803,11 @@ bool codegen_emit(jitdata *jd) fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) { + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) { PROFILE_CYCLE_STOP; patcher_add_patch_ref(jd, PATCHER_initialize_class, - fi->class, 0); + fi->clazz, 0); PROFILE_CYCLE_START; } @@ -1879,11 +1859,11 @@ bool codegen_emit(jitdata *jd) fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) { + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) { PROFILE_CYCLE_STOP; patcher_add_patch_ref(jd, PATCHER_initialize_class, - fi->class, 0); + fi->clazz, 0); PROFILE_CYCLE_START; } @@ -1905,8 +1885,8 @@ bool codegen_emit(jitdata *jd) if (IS_IMM32(iptr->sx.s23.s2.constval)) M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0); else { - M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0); - M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4); + M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2); + M_LST(REG_ITMP2, REG_ITMP1, 0); } break; } @@ -2028,9 +2008,12 @@ bool codegen_emit(jitdata *jd) case TYPE_LNG: case TYPE_ADR: case TYPE_DBL: - /* XXX why no check for IS_IMM32? */ - M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp); - M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4); + /* XXX why no check for IS_IMM32? -- probably because of the patcher */ + M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2); + if (disp) /* resolved, disp can never be 0 */ + M_LST(REG_ITMP2, s1, disp); + else /* unresolved */ + M_LST32(REG_ITMP2, s1, disp); break; } break; @@ -2196,7 +2179,7 @@ nowperformreturn: #endif /* !defined(NDEBUG) */ #if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* we need to save the proper return value */ @@ -2450,9 +2433,9 @@ gen_method: } 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 */ @@ -2512,9 +2495,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 */ @@ -2587,8 +2567,6 @@ gen_method: M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl)); M_ALD(REG_ITMP3, RIP, disp); - CODEGEN_CRITICAL_SECTION_START; - M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval)); /* if (s1 != REG_ITMP1) { */ @@ -2611,8 +2589,6 @@ gen_method: M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); /* } */ - CODEGEN_CRITICAL_SECTION_END; - M_ICMP(REG_ITMP3, REG_ITMP2); emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); @@ -2676,9 +2652,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); @@ -2760,14 +2733,10 @@ gen_method: M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl)); M_ALD(REG_ITMP2, RIP, disp); - CODEGEN_CRITICAL_SECTION_START; - M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval)); M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval)); - CODEGEN_CRITICAL_SECTION_END; - M_ISUB(REG_ITMP2, REG_ITMP1); M_CLR(d); /* may be REG_ITMP2 */ M_ICMP(REG_ITMP3, REG_ITMP1); @@ -2865,8 +2834,6 @@ gen_method: } /* if (bptr -> flags >= BBREACHED) */ } /* for basic block */ - dseg_createlinenumbertable(cd); - /* Generate patcher traps. */ emit_patcher_traps(jd); @@ -2910,7 +2877,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s /* calculate stack frame size */ cd->stackframesize = - sizeof(stackframeinfo) / SIZEOF_VOID_P + + sizeof(stackframeinfo_t) / SIZEOF_VOID_P + sizeof(localref_table) / SIZEOF_VOID_P + md->paramcount + (md->returntype.type == TYPE_VOID ? 0 : 1) + @@ -2922,12 +2889,9 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s (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 */ #if defined(ENABLE_PROFILING) /* generate native method profiling code */ @@ -2948,8 +2912,8 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s /* Save callee saved integer registers in stackframeinfo (GC may need to recover them during a collection). */ - disp = cd->stackframesize * 8 - sizeof(stackframeinfo) + - OFFSET(stackframeinfo, intregs); + disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) + + OFFSET(stackframeinfo_t, intregs); for (i = 0; i < INT_SAV_CNT; i++) M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8); @@ -3061,7 +3025,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s /* put env into first argument register */ - M_MOV_IMM(_Jv_env, REG_A0); + M_MOV_IMM(VM_get_jnienv(), REG_A0); } /* Call the native function. */ @@ -3076,6 +3040,20 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s case TYPE_INT: case TYPE_LNG: case TYPE_ADR: + switch (md->returntype.primitivetype) { + case PRIMITIVETYPE_BOOLEAN: + M_BZEXT(REG_RESULT, REG_RESULT); + break; + case PRIMITIVETYPE_BYTE: + M_BSEXT(REG_RESULT, REG_RESULT); + break; + case PRIMITIVETYPE_CHAR: + M_CZEXT(REG_RESULT, REG_RESULT); + break; + case PRIMITIVETYPE_SHORT: + M_SSEXT(REG_RESULT, REG_RESULT); + break; + } M_LST(REG_RESULT, REG_SP, 0 * 8); break; case TYPE_FLT: @@ -3114,8 +3092,8 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s /* Restore callee saved integer registers from stackframeinfo (GC might have modified them during a collection). */ - disp = cd->stackframesize * 8 - sizeof(stackframeinfo) + - OFFSET(stackframeinfo, intregs); + disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) + + OFFSET(stackframeinfo_t, intregs); for (i = 0; i < INT_SAV_CNT; i++) M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);