From e3b6afd111193cfd9ccec43d5f759088a79e5bbb Mon Sep 17 00:00:00 2001 From: twisti Date: Tue, 12 Jul 2005 23:49:49 +0000 Subject: [PATCH] * Implemented stacktraces --- src/vm/jit/mips/asmoffsets.h | 12 +- src/vm/jit/mips/asmpart.S | 64 ++++-- src/vm/jit/mips/codegen.c | 367 +++++++++++++++++++++++------------ src/vm/jit/mips/md.c | 34 +++- 4 files changed, 332 insertions(+), 145 deletions(-) diff --git a/src/vm/jit/mips/asmoffsets.h b/src/vm/jit/mips/asmoffsets.h index 3c2f3ee0b..dac04a679 100644 --- a/src/vm/jit/mips/asmoffsets.h +++ b/src/vm/jit/mips/asmoffsets.h @@ -28,7 +28,7 @@ Changes: - $Id: asmoffsets.h 1735 2004-12-07 14:33:27Z twisti $ + $Id: asmoffsets.h 3023 2005-07-12 23:49:49Z twisti $ */ @@ -44,10 +44,12 @@ #define IsLeaf -20 #define IntSave -24 #define FltSave -28 -#define LineNumberTableSize 0 /* XXX dummy entries */ -#define LineNumberTableStart 0 /* XXX dummy entries */ -#define ExTableSize -32 -#define ExTableStart -32 +/* 4-byte alignment padding */ +#define LineNumberTableSize -40 +#define LineNumberTableStart -48 +/* 4-byte alignment padding */ +#define ExTableSize -56 +#define ExTableStart -56 #define ExEntrySize -32 #define ExStartPC -8 diff --git a/src/vm/jit/mips/asmpart.S b/src/vm/jit/mips/asmpart.S index 238878081..c764e5f88 100644 --- a/src/vm/jit/mips/asmpart.S +++ b/src/vm/jit/mips/asmpart.S @@ -28,7 +28,7 @@ Changes: Christian Thalinger - $Id: asmpart.S 3002 2005-07-12 16:02:45Z twisti $ + $Id: asmpart.S 3023 2005-07-12 23:49:49Z twisti $ */ @@ -98,6 +98,10 @@ .dword calljava_xhandler /* end pc */ .dword asm_calljavafunction /* start pc */ .word 1 /* extable size */ + .word 0 /* ALIGNMENT PADDING */ + .dword 0 /* line number table start */ + .dword 0 /* line number table size */ + .word 0 /* ALIGNMENT PADDING */ .word 0 /* fltsave */ .word 0 /* intsave */ .word 0 /* isleaf */ @@ -178,6 +182,10 @@ calljava_xhandler: .dword calljava_xhandler2 /* end pc */ .dword asm_calljavafunction2 /* start pc */ .word 1 /* extable size */ + .word 0 /* ALIGNMENT PADDING */ + .dword 0 /* line number table start */ + .dword 0 /* line number table size */ + .word 0 /* ALIGNMENT PADDING */ .word 0 /* fltsave */ .word 1 /* intsave */ .word 0 /* isleaf */ @@ -381,6 +389,7 @@ noregchange: /* directly to the caller (ra). */ L_asm_call_jit_compiler_exception: +#if 0 #if defined(USE_THREADS) && defined(NATIVE_THREADS) aaddiu sp,sp,-2*8 ast ra,0*8(sp) @@ -392,6 +401,20 @@ L_asm_call_jit_compiler_exception: #endif ald xptr,0(v0) /* get the exception pointer */ ast zero,0(v0) /* clear the exception pointer */ +#endif + + aaddiu sp,sp,-2*8 + ast ra,0*8(sp) + + move a0,zero /* fill in the correct stacktrace */ + aaddiu a1,sp,2*8 /* pass sp of parent Java function */ + move a2,ra /* pass ra to parent Java function */ + move a3,a2 /* xpc is the same as ra */ + jal stacktrace_extern_fillInStackTrace + move xptr,v0 + + ald ra,0*8(sp) + aaddiu sp,sp,2*8 aaddiu xpc,ra,-4 /* faulting address is return adress - 4 */ b asm_handle_nat_exception @@ -668,32 +691,49 @@ ex_flt2: .ent asm_wrapper_patcher asm_wrapper_patcher: - aaddiu sp,sp,-(16+21+4+1)*8 /* create stack frame */ + aaddiu sp,sp,-((16+21+4)*8+sizestackframeinfo) /* create stack frame */ SAVE_ARGUMENT_REGISTERS(0) /* save 8 int/8 float argument registers */ SAVE_TEMPORARY_REGISTERS(16) /* save 5 int/16 float temporary registers */ ast itmp1,(16+21+0)*8(sp) /* save itmp1 */ ast itmp2,(16+21+1)*8(sp) /* save itmp2 */ - ast ra,(16+21+2+1)*8(sp) /* save method return address (for leafs) */ - ast pv,(16+21+3+1)*8(sp) /* save pv of calling java function */ + ast ra,(16+21+2)*8(sp) /* save method return address (for leafs) */ + ast pv,(16+21+3)*8(sp) /* save pv of calling java function */ + +#if 1 + aaddiu a0,sp,(16+21+4)*8 /* create stackframe info */ + move a1,pv /* pass java pv */ + aaddiu a2,sp,((5+16+21+4)*8+sizestackframeinfo) /* pass java sp */ + move a3,ra /* this is correct for leafs */ + ald a4,((4+16+21+4)*8+sizestackframeinfo)(sp) /* pass xpc */ + jal stacktrace_create_extern_stackframeinfo +#endif - aaddiu a0,sp,(0+16+21+4+1)*8 /* pass sp */ - ald itmp3,(0+16+21+4+1)*8(sp) /* get function pointer */ - ald itmp1,(16+21+3+1)*8(sp) /* save pv to the position of fp */ - ast itmp1,(0+16+21+4+1)*8(sp) + aaddiu a0,sp,((0+16+21+4)*8+sizestackframeinfo) /* pass sp */ + ald itmp3,((0+16+21+4)*8+sizestackframeinfo)(sp) /* get function pointer */ + ald itmp1,(16+21+3)*8(sp) /* save pv to the position of fp */ + ast itmp1,((0+16+21+4)*8+sizestackframeinfo)(sp) jalr itmp3 + ast v0,((0+16+21+4)*8+sizestackframeinfo)(sp) /* save return value */ + +#if 1 + aaddiu a0,sp,(16+21+4)*8 /* remove stackframe info */ + jal stacktrace_remove_stackframeinfo +#endif RESTORE_ARGUMENT_REGISTERS(0) /* restore 8 int/8 float argument registers */ RESTORE_TEMPORARY_REGISTERS(16) /* restore 5 int/16 float temporary reg. */ ald itmp1,(16+21+0)*8(sp) /* restore itmp1 */ ald itmp2,(16+21+1)*8(sp) /* restore itmp2 */ - ald ra,(16+21+2+1)*8(sp) /* restore method return address (for leafs)*/ - ald pv,(16+21+3+1)*8(sp) /* restore pv of calling java function */ + ald ra,(16+21+2)*8(sp) /* restore method return address (for leafs)*/ + ald pv,(16+21+3)*8(sp) /* restore pv of calling java function */ + + ald v0,((0+16+21+4)*8+sizestackframeinfo)(sp) /* restore return value */ - ald itmp3,(4+16+21+4+1)*8(sp) /* get return address (into JIT code) */ - aaddiu sp,sp,(5+16+21+4+1)*8 /* remove stack frame */ + ald itmp3,((4+16+21+4)*8+sizestackframeinfo)(sp) /* get ra to jit code*/ + aaddiu sp,sp,((5+16+21+4)*8+sizestackframeinfo) /* remove stack frame */ beqz v0,L_asm_wrapper_patcher_exception diff --git a/src/vm/jit/mips/codegen.c b/src/vm/jit/mips/codegen.c index 0e6ce8b0d..16d50a5f7 100644 --- a/src/vm/jit/mips/codegen.c +++ b/src/vm/jit/mips/codegen.c @@ -34,7 +34,7 @@ This module generates MIPS machine code for a sequence of intermediate code commands (ICMDs). - $Id: codegen.c 3002 2005-07-12 16:02:45Z twisti $ + $Id: codegen.c 3023 2005-07-12 23:49:49Z twisti $ */ @@ -87,6 +87,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd) basicblock *bptr; instruction *iptr; exceptiontable *ex; + u2 currentline; methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */ builtintable_entry *bte; methoddesc *md; @@ -105,10 +106,8 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd) parentargs_base = rd->memuse + savedregs_num; #if defined(USE_THREADS) /* space to save argument of monitor_enter */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) parentargs_base++; - #endif /* adjust frame size for 16 byte alignment */ @@ -125,7 +124,6 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd) (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */ #if defined(USE_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 @@ -133,16 +131,17 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd) */ if (checksync && (m->flags & ACC_SYNCHRONIZED)) - (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */ + (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */ else - #endif - (void) dseg_adds4(cd, 0); /* IsSync */ (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */ - (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);/* IntSave */ - (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);/* FltSave */ + (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */ + (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ + + dseg_addlinenumbertablesize(cd); + (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */ /* create exception table */ @@ -459,6 +458,10 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd) len = bptr->icount; for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) { + if (iptr->line != currentline) { + dseg_addlinenumber(cd, iptr->line, (u1 *) mcodeptr); + currentline = iptr->line; + } MCODECHECK(64); /* an instruction usually needs < 64 words */ @@ -3569,6 +3572,8 @@ afteractualcall: } /* if (bptr -> flags >= BBREACHED) */ } /* for basic block */ + codegen_createlinenumbertable(cd); + { s4 *xcodeptr; branchref *bref; @@ -3589,7 +3594,7 @@ afteractualcall: bref->branchpos, (u1 *) mcodeptr - cd->mcodebase); - MCODECHECK(12); + MCODECHECK(16); M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC); @@ -3600,17 +3605,34 @@ afteractualcall: } else { xcodeptr = mcodeptr; - M_ASUB_IMM(REG_SP, 1 * 8, REG_SP); + M_MOV(REG_PV, rd->argintregs[0]); + M_MOV(REG_SP, rd->argintregs[1]); + + if (m->isleafmethod) + M_MOV(REG_RA, rd->argintregs[2]); + else + M_ALD(rd->argintregs[2], + REG_SP, parentargs_base * 8 - SIZEOF_VOID_P); + + M_MOV(REG_ITMP2_XPC, rd->argintregs[3]); + + M_ASUB_IMM(REG_SP, 2 * 8, REG_SP); M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8); - a = dseg_addaddress(cd, new_arithmeticexception); + if (m->isleafmethod) + M_AST(REG_RA, REG_SP, 1 * 8); + + a = dseg_addaddress(cd, stacktrace_inline_arithmeticexception); M_ALD(REG_ITMP3, REG_PV, a); M_JSR(REG_RA, REG_ITMP3); M_NOP; M_MOV(REG_RESULT, REG_ITMP1_XPTR); + if (m->isleafmethod) + M_ALD(REG_RA, REG_SP, 1 * 8); + M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); - M_AADD_IMM(REG_SP, 1 * 8, REG_SP); + M_AADD_IMM(REG_SP, 2 * 8, REG_SP); a = dseg_addaddress(cd, asm_handle_exception); M_ALD(REG_ITMP3, REG_PV, a); @@ -3619,7 +3641,7 @@ afteractualcall: } } - /* generate bound check stubs */ + /* generate ArrayIndexOutOfBoundsException stubs */ xcodeptr = NULL; @@ -3628,7 +3650,9 @@ afteractualcall: bref->branchpos, (u1 *) mcodeptr - cd->mcodebase); - MCODECHECK(14); + MCODECHECK(20); + + /* move index register into REG_ITMP1 */ M_MOV(bref->reg, REG_ITMP1); M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC); @@ -3640,18 +3664,35 @@ afteractualcall: } else { xcodeptr = mcodeptr; - M_ASUB_IMM(REG_SP, 1 * 8, REG_SP); + M_MOV(REG_PV, rd->argintregs[0]); + M_MOV(REG_SP, rd->argintregs[1]); + + if (m->isleafmethod) + M_MOV(REG_RA, rd->argintregs[2]); + else + M_ALD(rd->argintregs[2], + REG_SP, parentargs_base * 8 - SIZEOF_VOID_P); + + M_MOV(REG_ITMP2_XPC, rd->argintregs[3]); + M_MOV(REG_ITMP1, rd->argintregs[4]); + + M_ASUB_IMM(REG_SP, 2 * 8, REG_SP); M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8); - M_MOV(REG_ITMP1, rd->argintregs[0]); - a = dseg_addaddress(cd, new_arrayindexoutofboundsexception); + if (m->isleafmethod) + M_AST(REG_RA, REG_SP, 1 * 8); + + a = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception); M_ALD(REG_ITMP3, REG_PV, a); M_JSR(REG_RA, REG_ITMP3); M_NOP; M_MOV(REG_RESULT, REG_ITMP1_XPTR); + if (m->isleafmethod) + M_ALD(REG_RA, REG_SP, 1 * 8); + M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); - M_AADD_IMM(REG_SP, 1 * 8, REG_SP); + M_AADD_IMM(REG_SP, 2 * 8, REG_SP); a = dseg_addaddress(cd, asm_handle_exception); M_ALD(REG_ITMP3, REG_PV, a); @@ -3660,7 +3701,7 @@ afteractualcall: } } - /* generate ArithmeticException stubs */ + /* generate ArrayStoreException stubs */ xcodeptr = NULL; @@ -3676,7 +3717,7 @@ afteractualcall: bref->branchpos, (u1 *) mcodeptr - cd->mcodebase); - MCODECHECK(12); + MCODECHECK(16); M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC); @@ -3687,10 +3728,16 @@ afteractualcall: } else { xcodeptr = mcodeptr; + M_MOV(REG_PV, rd->argintregs[0]); + M_MOV(REG_SP, rd->argintregs[1]); + M_ALD(rd->argintregs[2], + REG_SP, parentargs_base * 8 - SIZEOF_VOID_P); + M_MOV(REG_ITMP2_XPC, rd->argintregs[3]); + M_ASUB_IMM(REG_SP, 1 * 8, REG_SP); M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8); - a = dseg_addaddress(cd, new_arraystoreexception); + a = dseg_addaddress(cd, stacktrace_inline_arraystoreexception); M_ALD(REG_ITMP3, REG_PV, a); M_JSR(REG_RA, REG_ITMP3); M_NOP; @@ -3706,11 +3753,11 @@ afteractualcall: } } - /* generate negative array size check stubs */ + /* generate ClassCastException stubs */ xcodeptr = NULL; - for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) { + for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) { if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) { gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, bref->branchpos, @@ -3722,7 +3769,7 @@ afteractualcall: bref->branchpos, (u1 *) mcodeptr - cd->mcodebase); - MCODECHECK(12); + MCODECHECK(16); M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC); @@ -3733,17 +3780,34 @@ afteractualcall: } else { xcodeptr = mcodeptr; - M_ASUB_IMM(REG_SP, 1 * 8, REG_SP); + M_MOV(REG_PV, rd->argintregs[0]); + M_MOV(REG_SP, rd->argintregs[1]); + + if (m->isleafmethod) + M_MOV(REG_RA, rd->argintregs[2]); + else + M_ALD(rd->argintregs[2], + REG_SP, parentargs_base * 8 - SIZEOF_VOID_P); + + M_MOV(REG_ITMP2_XPC, rd->argintregs[3]); + + M_ASUB_IMM(REG_SP, 2 * 8, REG_SP); M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8); - a = dseg_addaddress(cd, new_negativearraysizeexception); + if (m->isleafmethod) + M_AST(REG_RA, REG_SP, 1 * 8); + + a = dseg_addaddress(cd, stacktrace_inline_classcastexception); M_ALD(REG_ITMP3, REG_PV, a); M_JSR(REG_RA, REG_ITMP3); M_NOP; M_MOV(REG_RESULT, REG_ITMP1_XPTR); + if (m->isleafmethod) + M_ALD(REG_RA, REG_SP, 1 * 8); + M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); - M_AADD_IMM(REG_SP, 1 * 8, REG_SP); + M_AADD_IMM(REG_SP, 2 * 8, REG_SP); a = dseg_addaddress(cd, asm_handle_exception); M_ALD(REG_ITMP3, REG_PV, a); @@ -3752,11 +3816,11 @@ afteractualcall: } } - /* generate cast check stubs */ + /* generate NegativeArraySizeException stubs */ xcodeptr = NULL; - for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) { + for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) { if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) { gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, bref->branchpos, @@ -3768,7 +3832,7 @@ afteractualcall: bref->branchpos, (u1 *) mcodeptr - cd->mcodebase); - MCODECHECK(12); + MCODECHECK(16); M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC); @@ -3779,10 +3843,16 @@ afteractualcall: } else { xcodeptr = mcodeptr; + M_MOV(REG_PV, rd->argintregs[0]); + M_MOV(REG_SP, rd->argintregs[1]); + M_ALD(rd->argintregs[2], + REG_SP, parentargs_base * 8 - SIZEOF_VOID_P); + M_MOV(REG_ITMP2_XPC, rd->argintregs[3]); + M_ASUB_IMM(REG_SP, 1 * 8, REG_SP); M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8); - a = dseg_addaddress(cd, new_classcastexception); + a = dseg_addaddress(cd, stacktrace_inline_negativearraysizeexception); M_ALD(REG_ITMP3, REG_PV, a); M_JSR(REG_RA, REG_ITMP3); M_NOP; @@ -3798,11 +3868,11 @@ afteractualcall: } } - /* generate exception check stubs */ + /* generate NullPointerException stubs */ xcodeptr = NULL; - for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) { + for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) { if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) { gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, bref->branchpos, @@ -3814,7 +3884,7 @@ afteractualcall: bref->branchpos, (u1 *) mcodeptr - cd->mcodebase); - MCODECHECK(13); + MCODECHECK(16); M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC); @@ -3825,27 +3895,34 @@ afteractualcall: } else { xcodeptr = mcodeptr; -#if defined(USE_THREADS) && defined(NATIVE_THREADS) - M_ASUB_IMM(REG_SP, 1 * 8, REG_SP); + M_MOV(REG_PV, rd->argintregs[0]); + M_MOV(REG_SP, rd->argintregs[1]); + + if (m->isleafmethod) + M_MOV(REG_RA, rd->argintregs[2]); + else + M_ALD(rd->argintregs[2], + REG_SP, parentargs_base * 8 - SIZEOF_VOID_P); + + M_MOV(REG_ITMP2_XPC, rd->argintregs[3]); + + M_ASUB_IMM(REG_SP, 2 * 8, REG_SP); M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8); - a = dseg_addaddress(cd, builtin_get_exceptionptrptr); + if (m->isleafmethod) + M_AST(REG_RA, REG_SP, 1 * 8); + + a = dseg_addaddress(cd, stacktrace_inline_nullpointerexception); M_ALD(REG_ITMP3, REG_PV, a); M_JSR(REG_RA, REG_ITMP3); M_NOP; + M_MOV(REG_RESULT, REG_ITMP1_XPTR); - /* get the exceptionptr from the ptrprt and clear it */ - M_ALD(REG_ITMP1_XPTR, REG_RESULT, 0); - M_AST(REG_ZERO, REG_RESULT, 0); + if (m->isleafmethod) + M_ALD(REG_RA, REG_SP, 1 * 8); M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); - M_AADD_IMM(REG_SP, 1 * 8, REG_SP); -#else - a = dseg_addaddress(cd, &_exceptionptr); - M_ALD(REG_ITMP3, REG_PV, a); - M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0); - M_AST(REG_ZERO, REG_ITMP3, 0); -#endif + M_AADD_IMM(REG_SP, 2 * 8, REG_SP); a = dseg_addaddress(cd, asm_handle_exception); M_ALD(REG_ITMP3, REG_PV, a); @@ -3854,11 +3931,11 @@ afteractualcall: } } - /* generate null pointer check stubs */ + /* generate ICMD_CHECKEXCEPTION stubs */ xcodeptr = NULL; - for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) { + for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) { if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) { gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, bref->branchpos, @@ -3870,7 +3947,7 @@ afteractualcall: bref->branchpos, (u1 *) mcodeptr - cd->mcodebase); - MCODECHECK(12); + MCODECHECK(16); M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC); @@ -3881,10 +3958,16 @@ afteractualcall: } else { xcodeptr = mcodeptr; + M_MOV(REG_PV, rd->argintregs[0]); + M_MOV(REG_SP, rd->argintregs[1]); + M_ALD(rd->argintregs[2], + REG_SP, parentargs_base * 8 - SIZEOF_VOID_P); + M_MOV(REG_ITMP2_XPC, rd->argintregs[3]); + M_ASUB_IMM(REG_SP, 1 * 8, REG_SP); M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8); - a = dseg_addaddress(cd, new_nullpointerexception); + a = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace); M_ALD(REG_ITMP3, REG_PV, a); M_JSR(REG_RA, REG_ITMP3); M_NOP; @@ -3900,8 +3983,7 @@ afteractualcall: } } - - /* generate put/getstatic stub call code */ + /* generate patcher stub call code */ { patchref *pref; @@ -4065,24 +4147,16 @@ functionptr createcompilerstub(methodinfo *m) *******************************************************************************/ -#if defined(USE_THREADS) && defined(NATIVE_THREADS) -#define NATIVESTUB_STACK 2 -#else -#define NATIVESTUB_STACK 1 -#endif - - functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, registerdata *rd, methoddesc *nmd) { - s4 *mcodeptr; /* code generation pointer */ - s4 stackframesize; /* size of stackframe if needed */ - s4 disp; - methoddesc *md; - s4 nativeparams; - s4 i, j; /* count variables */ - s4 t; - s4 s1, s2, off; + s4 *mcodeptr; /* code generation pointer */ + s4 stackframesize; /* size of stackframe if needed */ + methoddesc *md; + s4 nativeparams; + s4 i, j; /* count variables */ + s4 t; + s4 s1, s2, disp; /* initialize variables */ @@ -4090,10 +4164,14 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, nativeparams = (m->flags & ACC_STATIC) ? 2 : 1; - /* calculate stack frame size */ - stackframesize = nmd->memuse + NATIVESTUB_STACK; + stackframesize = + 1 + /* return address */ + sizeof(stackframeinfo) / SIZEOF_VOID_P + + md->paramcount + /* for saving arguments over calls */ + 1 + /* for saving return address */ + nmd->memuse; /* create method header */ @@ -4120,7 +4198,7 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, /* generate stub code */ M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe */ - M_AST(REG_RA, REG_SP, 0); /* store return address */ + M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* store ra */ /* if function is static, check for initialized */ @@ -4159,15 +4237,13 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, } } - off = dseg_addaddress(cd, m); - M_ALD(REG_ITMP1, REG_PV, off); + disp = dseg_addaddress(cd, m); + M_ALD(REG_ITMP1, REG_PV, disp); M_AST(REG_ITMP1, REG_SP, 0 * 8); - off = dseg_addaddress(cd, builtin_trace_args); - M_ALD(REG_ITMP3, REG_PV, off); + disp = dseg_addaddress(cd, builtin_trace_args); + M_ALD(REG_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); M_NOP; - disp = (s4) ((u1 *) mcodeptr - cd->mcodebase); - M_LDA(REG_PV, REG_RA, -disp); for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++) if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) @@ -4189,6 +4265,42 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, } +#if 1 + /* save integer and float argument registers */ + + for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) + if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) + M_LST(rd->argintregs[i], REG_SP, j++ * 8); + + for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) + if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) + M_DST(rd->argfltregs[i], REG_SP, j++ * 8); + + /* create native stackframe info */ + + M_AADD_IMM(REG_SP, + stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo), + rd->argintregs[0]); + M_MOV(REG_PV, rd->argintregs[1]); + M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]); + M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P); + disp = dseg_addaddress(cd, stacktrace_create_native_stackframeinfo); + M_ALD(REG_ITMP3, REG_PV, disp); + M_JSR(REG_RA, REG_ITMP3); + M_NOP; /* XXX fill me! */ + + /* restore integer and float argument registers */ + + for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) + if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) + M_LLD(rd->argintregs[i], REG_SP, j++ * 8); + + for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) + if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) + M_DLD(rd->argfltregs[i], REG_SP, j++ * 8); +#endif + + /* copy or spill arguments to new locations */ for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) { @@ -4243,14 +4355,14 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, /* put class into second argument register */ if (m->flags & ACC_STATIC) { - off = dseg_addaddress(cd, m->class); - M_ALD(rd->argintregs[1], REG_PV, off); + disp = dseg_addaddress(cd, m->class); + M_ALD(rd->argintregs[1], REG_PV, disp); } /* put env into first argument register */ - off = dseg_addaddress(cd, &env); - M_ALD(rd->argintregs[0], REG_PV, off); + disp = dseg_addaddress(cd, &env); + M_ALD(rd->argintregs[0], REG_PV, disp); /* do the native function call */ @@ -4264,12 +4376,33 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, } #endif - off = dseg_addaddress(cd, f); - M_ALD(REG_ITMP3, REG_PV, off); /* load adress of native method */ + disp = dseg_addaddress(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 */ - disp = (s4) ((u1 *) mcodeptr - cd->mcodebase); - M_LDA(REG_PV, REG_RA, -disp); + + +#if 1 + /* remove native stackframe info */ + + if (IS_INT_LNG_TYPE(md->returntype.type)) + M_LST(REG_RESULT, REG_SP, 0 * 8); + else + M_DST(REG_FRESULT, REG_SP, 0 * 8); + + M_AADD_IMM(REG_SP, + stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo), + rd->argintregs[0]); + disp = dseg_addaddress(cd, stacktrace_remove_stackframeinfo); + M_ALD(REG_ITMP3, REG_PV, disp); + M_JSR(REG_RA, REG_ITMP3); + M_NOP; /* XXX fill me! */ + + if (IS_INT_LNG_TYPE(md->returntype.type)) + M_LLD(REG_RESULT, REG_SP, 0 * 8); + else + M_DLD(REG_FRESULT, REG_SP, 0 * 8); +#endif /* call finished trace function */ @@ -4280,20 +4413,18 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, M_AST(REG_RESULT, REG_SP, 0 * 8); M_DST(REG_FRESULT, REG_SP, 1 * 8); - off = dseg_addaddress(cd, m); - M_ALD(rd->argintregs[0], REG_PV, off); + disp = dseg_addaddress(cd, m); + M_ALD(rd->argintregs[0], REG_PV, disp); M_MOV(REG_RESULT, rd->argintregs[1]); M_DMFC1(REG_ITMP1, REG_FRESULT); M_DMTC1(REG_ITMP1, rd->argfltregs[2]); M_DMTC1(REG_ITMP1, rd->argfltregs[3]); - off = dseg_addaddress(cd, builtin_displaymethodstop); - M_ALD(REG_ITMP3, REG_PV, off); + disp = dseg_addaddress(cd, builtin_displaymethodstop); + M_ALD(REG_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); M_NOP; - disp = (s4) ((u1 *) mcodeptr - cd->mcodebase); - M_LDA(REG_PV, REG_RA, -disp); M_ALD(REG_RESULT, REG_SP, 0 * 8); M_DLD(REG_FRESULT, REG_SP, 1 * 8); @@ -4304,30 +4435,28 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, /* check for exception */ #if defined(USE_THREADS) && defined(NATIVE_THREADS) - off = dseg_addaddress(cd, builtin_get_exceptionptrptr); - M_ALD(REG_ITMP3, REG_PV, off); + disp = dseg_addaddress(cd, builtin_get_exceptionptrptr); + M_ALD(REG_ITMP3, REG_PV, disp); M_JSR(REG_RA, REG_ITMP3); /* delay slot */ - if (IS_FLT_DBL_TYPE(md->returntype.type)) { - M_DST(REG_FRESULT, REG_SP, 1 * 8); - } else { - M_AST(REG_RESULT, REG_SP, 1 * 8); - } + if (IS_INT_LNG_TYPE(md->returntype.type)) + M_AST(REG_RESULT, REG_SP, 0 * 8); + else + M_DST(REG_FRESULT, REG_SP, 0 * 8); M_MOV(REG_RESULT, REG_ITMP3); - if (IS_FLT_DBL_TYPE(md->returntype.type)) { - M_DLD(REG_FRESULT, REG_SP, 1 * 8); - } else { - M_ALD(REG_RESULT, REG_SP, 1 * 8); - } + if (IS_INT_LNG_TYPE(md->returntype.type)) + M_ALD(REG_RESULT, REG_SP, 0 * 8); + else + M_DLD(REG_FRESULT, REG_SP, 0 * 8); #else - off = dseg_addaddress(cd, &_exceptionptr); - M_ALD(REG_ITMP3, REG_PV, off); /* get address of exceptionptr */ + disp = dseg_addaddress(cd, &_exceptionptr); + M_ALD(REG_ITMP3, REG_PV, disp); /* get address of exceptionptr */ #endif - M_LLD(REG_RA, REG_SP, 0); /* load return address */ + M_ALD(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* load ra */ M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */ M_BNEZ(REG_ITMP1, 2); /* if no exception then return */ @@ -4340,8 +4469,8 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */ - off = dseg_addaddress(cd, asm_handle_nat_exception); - M_ALD(REG_ITMP3, REG_PV, off); /* load asm exception handler address */ + disp = dseg_addaddress(cd, asm_handle_nat_exception); + M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */ M_JMP(REG_ITMP3); /* jump to asm exception handler */ M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */ /* delay slot */ @@ -4390,9 +4519,9 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, /* order reversed because of data segment layout */ (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */ - off = dseg_addaddress(cd, NULL); /* vftbl */ + disp = dseg_addaddress(cd, NULL); /* vftbl */ - M_LDA(REG_ITMP3, REG_PV, off); + M_LDA(REG_ITMP3, REG_PV, disp); M_AST(REG_ITMP3, REG_SP, 3 * 8); #else M_AST(REG_ZERO, REG_SP, 3 * 8); @@ -4400,24 +4529,24 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd, /* move machine code onto stack */ - off = dseg_adds8(cd, mcode); - M_LLD(REG_ITMP3, REG_PV, off); + disp = dseg_adds8(cd, mcode); + M_LLD(REG_ITMP3, REG_PV, disp); M_LST(REG_ITMP3, REG_SP, 2 * 8); /* move class/method/field reference onto stack */ - off = dseg_addaddress(cd, pref->ref); - M_ALD(REG_ITMP3, REG_PV, off); + disp = dseg_addaddress(cd, pref->ref); + M_ALD(REG_ITMP3, REG_PV, disp); M_AST(REG_ITMP3, REG_SP, 1 * 8); /* move patcher function pointer onto stack */ - off = dseg_addaddress(cd, pref->patcher); - M_ALD(REG_ITMP3, REG_PV, off); + disp = dseg_addaddress(cd, pref->patcher); + M_ALD(REG_ITMP3, REG_PV, disp); M_AST(REG_ITMP3, REG_SP, 0 * 8); - off = dseg_addaddress(cd, asm_wrapper_patcher); - M_ALD(REG_ITMP3, REG_PV, off); + disp = dseg_addaddress(cd, asm_wrapper_patcher); + M_ALD(REG_ITMP3, REG_PV, disp); M_JMP(REG_ITMP3); M_NOP; } diff --git a/src/vm/jit/mips/md.c b/src/vm/jit/mips/md.c index 5f97e2433..4193d5617 100644 --- a/src/vm/jit/mips/md.c +++ b/src/vm/jit/mips/md.c @@ -29,7 +29,7 @@ Changes: Christian Thalinger - $Id: md.c 3002 2005-07-12 16:02:45Z twisti $ + $Id: md.c 3023 2005-07-12 23:49:49Z twisti $ */ @@ -48,6 +48,7 @@ #include "vm/exceptions.h" #include "vm/stringlocal.h" #include "vm/jit/asmpart.h" +#include "vm/jit/stacktrace.h" /* md_init ********************************************************************* @@ -83,10 +84,14 @@ void md_init(void) void signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) { - ucontext_t *_uc; - mcontext_t *_mc; - u4 instr; - ptrint addr; + ucontext_t *_uc; + mcontext_t *_mc; + u4 instr; + ptrint addr; + u1 *pv; + u1 *sp; + functionptr ra; + functionptr xpc; _uc = (struct ucontext *) _p; _mc = &_uc->uc_mcontext; @@ -95,8 +100,15 @@ void signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) addr = _mc->gregs[(instr >> 21) & 0x1f]; if (addr == 0) { - _mc->gregs[REG_ITMP1_XPTR] = (ptrint) new_nullpointerexception(); - _mc->gregs[REG_ITMP2_XPC] = _mc->gregs[CTX_EPC]; + pv = (u1 *) _mc->gregs[REG_PV]; + sp = (u1 *) _mc->gregs[REG_SP]; + ra = (functionptr) _mc->gregs[REG_RA]; /* this is correct for leafs*/ + xpc = (functionptr) _mc->gregs[CTX_EPC]; + + _mc->gregs[REG_ITMP1_XPTR] = + (ptrint) stacktrace_hardware_nullpointerexception(pv, sp, ra, xpc); + + _mc->gregs[REG_ITMP2_XPC] = (ptrint) xpc; _mc->gregs[CTX_EPC] = (ptrint) asm_handle_exception; } else { @@ -175,14 +187,17 @@ functionptr codegen_findmethod(functionptr pc) mcode = *((u4 *) ra); - if ((mcode >> 16) != 0x237a) { - log_text("No `lda pv,x(ra)' instruction found on return address!"); + if ((mcode >> 16) != 0x67fe) { + log_text("No `daddiu s8,ra,x' instruction found on return address!"); assert(0); } offset = (s2) (mcode & 0x0000ffff); pv += offset; +#if 0 + /* XXX TWISTI: implement this! */ + /* check for second instruction (ldah) */ mcode = *((u4 *) (ra + 1 * 4)); @@ -191,6 +206,7 @@ functionptr codegen_findmethod(functionptr pc) offset = (s2) (mcode << 16); pv += offset; } +#endif return (functionptr) pv; } -- 2.25.1