X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fmips%2Fcodegen.c;h=5260e939d6b802dbd998156d9f8504b621fe319f;hb=3cf9c83d2043bb7eaa5ec20d8b87220f58afc12b;hp=9514a03ca91f00962a549b5b3320737b594db834;hpb=4d752760c14baff33c0ae90bcd71c9975a03692d;p=cacao.git diff --git a/src/vm/jit/mips/codegen.c b/src/vm/jit/mips/codegen.c index 9514a03ca..5260e939d 100644 --- a/src/vm/jit/mips/codegen.c +++ b/src/vm/jit/mips/codegen.c @@ -1,9 +1,7 @@ /* src/vm/jit/mips/codegen.c - machine code generator for MIPS - 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,33 +37,33 @@ #include "mm/memory.h" -#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/vm.h" +#include "vm/jit/builtin.hpp" +#include "vm/class.h" +#include "vm/exceptions.hpp" +#include "vm/options.h" +#include "vm/vm.hpp" #include "vm/jit/abi.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/md.h" -#include "vm/jit/patcher-common.h" +#include "vm/jit/emit-common.hpp" +#include "vm/jit/jit.hpp" +#include "vm/jit/linenumbertable.hpp" +#include "vm/jit/patcher-common.hpp" #include "vm/jit/reg.h" -#include "vm/jit/replace.h" +#include "vm/jit/replace.hpp" +#include "vm/jit/trap.h" #if defined(ENABLE_LSRA) # include "vm/jit/allocator/lsra.h" #endif -#include "vmcore/class.h" -#include "vmcore/options.h" - /* codegen_emit **************************************************************** @@ -83,7 +81,6 @@ bool codegen_emit(jitdata *jd) varinfo *var; basicblock *bptr; instruction *iptr; - exception_entry *ex; u2 currentline; constant_classref *cr; unresolved_class *uc; @@ -118,7 +115,7 @@ bool codegen_emit(jitdata *jd) s4 i, p, t, l; s4 savedregs_num; - savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */ + savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */ /* space to save used callee saved registers */ @@ -130,7 +127,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)) { # if SIZEOF_VOID_P == 8 cd->stackframesize++; # else @@ -150,34 +147,18 @@ 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; + + /* REMOVEME: We still need it for exception handling in assembler. */ + + if (code_is_leafmethod(code)) + (void) dseg_add_unique_s4(cd, 1); 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); + (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */ (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ - 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); - } - /* create stack frame (if necessary) */ if (cd->stackframesize) @@ -186,7 +167,7 @@ bool codegen_emit(jitdata *jd) /* save return address and used callee saved registers */ p = cd->stackframesize; - if (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { p--; M_AST(REG_RA, REG_SP, p * 8); } for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) { @@ -283,7 +264,7 @@ bool codegen_emit(jitdata *jd) /* call monitorenter function */ #if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { /* stack offset for monitor argument */ s1 = rd->memuse; @@ -305,7 +286,7 @@ bool codegen_emit(jitdata *jd) /* get correct lock object */ if (m->flags & ACC_STATIC) { - disp = dseg_add_address(cd, &m->class->object.header); + disp = dseg_add_address(cd, &m->clazz->object.header); M_ALD(REG_A0, REG_PV, disp); disp = dseg_add_functionptr(cd, LOCK_monitor_enter); M_ALD(REG_ITMP3, REG_PV, disp); @@ -315,7 +296,7 @@ bool codegen_emit(jitdata *jd) M_BNEZ(REG_A0, 2); disp = dseg_add_functionptr(cd, LOCK_monitor_enter); M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */ - M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER); + M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException); } M_JSR(REG_RA, REG_ITMP3); @@ -408,7 +389,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; } @@ -429,14 +410,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 */ @@ -1994,9 +1975,9 @@ 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)) patcher_add_patch_ref(jd, PATCHER_initialize_class, - fi->class, disp); + fi->clazz, disp); } M_ALD(REG_ITMP1, REG_PV, disp); @@ -2044,9 +2025,9 @@ 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)) patcher_add_patch_ref(jd, PATCHER_initialize_class, - fi->class, disp); + fi->clazz, disp); } M_ALD(REG_ITMP1, REG_PV, disp); @@ -2093,9 +2074,9 @@ 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)) patcher_add_patch_ref(jd, PATCHER_initialize_class, - fi->class, disp); + fi->clazz, disp); } M_ALD(REG_ITMP1, REG_PV, disp); @@ -2832,7 +2813,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); @@ -2893,7 +2874,7 @@ nowperformreturn: /* restore return address */ - if (!jd->isleafmethod) { + if (!code_is_leafmethod(code)) { p--; M_ALD(REG_RA, REG_SP, p * 8); } @@ -3099,22 +3080,31 @@ gen_method: switch (iptr->opc) { case ICMD_BUILTIN: - disp = dseg_add_functionptr(cd, bte->fp); + if (bte->stub == NULL) { + disp = dseg_add_functionptr(cd, bte->fp); + M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */ - M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */ + /* generate the actual call */ - /* generate the actual call */ + /* TWISTI: i actually don't know the reason for using + REG_ITMP3 here instead of REG_PV. */ - /* TWISTI: i actually don't know the reason for using - REG_ITMP3 here instead of REG_PV. */ + M_JSR(REG_RA, REG_ITMP3); + M_NOP; + } + else { + disp = dseg_add_functionptr(cd, bte->stub); + M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */ + + /* generate the actual call */ + + M_JSR(REG_RA, REG_PV); + M_NOP; + } - M_JSR(REG_RA, REG_ITMP3); - M_NOP; REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); disp = (s4) (cd->mcodeptr - cd->mcodebase); M_LDA(REG_PV, REG_RA, -disp); - - emit_exception_check(cd, iptr); break; case ICMD_INVOKESPECIAL: @@ -3178,9 +3168,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 */ @@ -3245,9 +3235,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 */ @@ -3318,8 +3305,6 @@ gen_method: M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl)); M_ALD(REG_ITMP3, REG_PV, disp); - CODEGEN_CRITICAL_SECTION_START; - M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval)); /* if (s1 != REG_ITMP1) { */ /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */ @@ -3334,8 +3319,6 @@ gen_method: M_ALD(REG_ITMP3, REG_PV, disp); M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); - CODEGEN_CRITICAL_SECTION_END; - /* } */ M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3); emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1); @@ -3400,9 +3383,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); @@ -3480,14 +3460,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_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); M_CMPULT(REG_ITMP2, REG_ITMP1, d); M_XOR_IMM(d, 1, d); @@ -3593,8 +3569,6 @@ gen_method: } /* if (bptr -> flags >= BBREACHED) */ } /* for basic block */ - dseg_createlinenumbertable(cd); - /* generate traps */ emit_patcher_traps(jd); @@ -3605,48 +3579,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); /* codeinfo pointer */ - M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */ - M_JMP(REG_PV); - M_NOP; -} - - /* 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; /* displacement of the function */ + int s1, s2; + int disp; /* get required compiler data */ @@ -3657,13 +3605,12 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* initialize variables */ md = m->parseddesc; - nativeparams = (m->flags & ACC_STATIC) ? 2 : 1; /* calculate stack frame size */ cd->stackframesize = 1 + /* return address */ - sizeof(stackframeinfo) / SIZEOF_VOID_P + + sizeof(stackframeinfo_t) / SIZEOF_VOID_P + sizeof(localref_table) / SIZEOF_VOID_P + md->paramcount + /* for saving arguments over calls */ #if SIZEOF_VOID_P == 4 @@ -3681,12 +3628,9 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) (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 */ /* generate stub code */ @@ -3698,15 +3642,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) 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) - patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp); -#endif - /* save integer and float argument registers */ #if SIZEOF_VOID_P == 8 @@ -3749,15 +3684,18 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* prepare data structures for native function call */ - M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0); + M_MOV(REG_SP, REG_A0); M_MOV(REG_PV, REG_A1); - M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2); - M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8); disp = dseg_add_functionptr(cd, codegen_start_native_call); M_ALD(REG_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); M_NOP; /* XXX fill me! */ + /* remember class argument */ + + if (m->flags & ACC_STATIC) + M_MOV(REG_RESULT, REG_ITMP3); + /* restore integer and float argument registers */ #if SIZEOF_VOID_P == 8 @@ -3800,7 +3738,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* 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->params[i].type; if (IS_INT_LNG_TYPE(t)) { @@ -3922,21 +3860,24 @@ 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) { - disp = dseg_add_address(cd, m->class); - M_ALD(REG_A1, REG_PV, disp); - } + if (m->flags & ACC_NATIVE) { + /* put class into second argument register */ - /* put env into first argument register */ + if (m->flags & ACC_STATIC) + M_MOV(REG_ITMP3, REG_A1); - disp = dseg_add_address(cd, _Jv_env); - M_ALD(REG_A0, REG_PV, disp); + /* put env into first argument register */ - /* do the native function call */ + disp = dseg_add_address(cd, VM_get_jnienv()); + M_ALD(REG_A0, REG_PV, disp); + } + + /* Call the native function. */ - M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */ + disp = dseg_add_functionptr(cd, f); + M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */ M_JSR(REG_RA, REG_ITMP3); /* call native method */ M_NOP; /* delay slot */ @@ -3956,14 +3897,14 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) #else case TYPE_INT: case TYPE_ADR: - M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8); + M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8); break; case TYPE_LNG: - M_LST(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8); + M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8); break; case TYPE_FLT: case TYPE_DBL: - M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8); + M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8); break; #endif case TYPE_VOID: @@ -3977,7 +3918,8 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) /* remove native stackframe info */ - M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 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_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); @@ -4000,14 +3942,14 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) #else case TYPE_INT: case TYPE_ADR: - M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8); + M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8); break; case TYPE_LNG: - M_LLD(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8); + M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8); break; case TYPE_FLT: case TYPE_DBL: - M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8); + M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8); break; #endif case TYPE_VOID: