diff options
Diffstat (limited to 'vm/mterp/out')
-rw-r--r-- | vm/mterp/out/InterpAsm-armv4t.S | 434 | ||||
-rw-r--r-- | vm/mterp/out/InterpAsm-armv5te-vfp.S | 434 | ||||
-rw-r--r-- | vm/mterp/out/InterpAsm-armv5te.S | 434 | ||||
-rw-r--r-- | vm/mterp/out/InterpC-allstubs.c | 28 | ||||
-rw-r--r-- | vm/mterp/out/InterpC-armv4t.c | 24 | ||||
-rw-r--r-- | vm/mterp/out/InterpC-armv5te-vfp.c | 24 | ||||
-rw-r--r-- | vm/mterp/out/InterpC-armv5te.c | 24 | ||||
-rw-r--r-- | vm/mterp/out/InterpC-portdbg.c | 58 | ||||
-rw-r--r-- | vm/mterp/out/InterpC-portstd.c | 52 | ||||
-rw-r--r-- | vm/mterp/out/InterpC-x86.c | 28 |
10 files changed, 1382 insertions, 158 deletions
diff --git a/vm/mterp/out/InterpAsm-armv4t.S b/vm/mterp/out/InterpAsm-armv4t.S index a348e31e4..61fc16bfc 100644 --- a/vm/mterp/out/InterpAsm-armv4t.S +++ b/vm/mterp/out/InterpAsm-armv4t.S @@ -175,6 +175,8 @@ unspecified registers or condition codes. * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork. */ #define GOTO_OPCODE(_reg) add pc, rIBASE, _reg, lsl #6 +#define GOTO_OPCODE_IFEQ(_reg) addeq pc, rIBASE, _reg, lsl #6 +#define GOTO_OPCODE_IFNE(_reg) addne pc, rIBASE, _reg, lsl #6 /* * Get/set the 32-bit value from a Dalvik register. @@ -182,6 +184,14 @@ unspecified registers or condition codes. #define GET_VREG(_reg, _vreg) ldr _reg, [rFP, _vreg, lsl #2] #define SET_VREG(_reg, _vreg) str _reg, [rFP, _vreg, lsl #2] +#if defined(WITH_JIT) +/* + * Null definition for overhead measuring purposes + */ +#define GET_JIT_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitTable] +#define GET_JIT_PROF_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitProfTable] +#endif + /* * Convert a virtual register index into an address. */ @@ -302,10 +312,21 @@ dvmMterpStdRun: cmp r1, #kInterpEntryInstr @ usual case? bne .Lnot_instr @ no, handle it +#if defined(WITH_JIT) +.Lno_singleStep: + /* Entry is always a possible trace start */ + GET_JIT_PROF_TABLE(r0) + FETCH_INST() + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) +#else /* start executing the instruction at rPC */ FETCH_INST() @ load rINST from rPC GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif .Lnot_instr: cmp r1, #kInterpEntryReturn @ were we returning from a method? @@ -315,6 +336,22 @@ dvmMterpStdRun: cmp r1, #kInterpEntryThrow @ were we throwing an exception? beq common_exceptionThrown +#if defined(WITH_JIT) +.Lnot_throw: + ldr r0,[rGLUE, #offGlue_jitResume] + ldr r2,[rGLUE, #offGlue_jitResumePC] + cmp r1, #kInterpEntryResume @ resuming after Jit single-step? + bne .Lbad_arg + cmp rPC,r2 + bne .Lno_singleStep @ must have branched, don't resume + mov r1, #kInterpEntryInstr + strb r1, [rGLUE, #offGlue_entryPoint] + ldr rINST, .LdvmCompilerTemplate + bx r0 @ re-enter the translation +.LdvmCompilerTemplate: + .word dvmCompilerTemplateStart +#endif + .Lbad_arg: ldr r0, strBadEntryPoint @ r1 holds value of entryPoint @@ -1111,10 +1148,18 @@ dalvik_inst: movs r9, r0, asr #24 @ r9<- ssssssAA (sign-extended) mov r9, r9, lsl #1 @ r9<- byte offset bmi common_backwardBranch @ backward branch, do periodic checks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction - +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ .balign 64 @@ -1130,9 +1175,18 @@ dalvik_inst: FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) movs r9, r0, asl #1 @ r9<- byte offset, check sign bmi common_backwardBranch @ backward branch, do periodic checks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ @@ -1157,10 +1211,18 @@ dalvik_inst: orrs r0, r0, r1, lsl #16 @ r0<- AAAAaaaa, check sign mov r9, r0, asl #1 @ r9<- byte offset ble common_backwardBranch @ backward branch, do periodic checks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction - +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ .balign 64 @@ -1186,9 +1248,18 @@ dalvik_inst: movs r9, r0, asl #1 @ r9<- branch byte offset, check sign bmi common_backwardBranch @ backward branch, do periodic checks beq common_backwardBranch @ (want to use BLE but V is unknown) +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ @@ -1216,9 +1287,18 @@ dalvik_inst: movs r9, r0, asl #1 @ r9<- branch byte offset, check sign bmi common_backwardBranch @ backward branch, do periodic checks beq common_backwardBranch @ (want to use BLE but V is unknown) +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1465,9 +1545,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1495,9 +1582,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1525,9 +1619,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1555,9 +1656,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1585,9 +1693,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1615,9 +1730,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1642,9 +1764,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1669,9 +1801,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1696,9 +1838,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1723,9 +1875,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1750,9 +1912,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1777,9 +1949,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -9298,15 +9480,192 @@ d2l_doconv: dvmAsmSisterEnd: /* File: armv5te/footer.S */ + /* * =========================================================================== * Common subroutines and data * =========================================================================== */ + + .text .align 2 +#if defined(WITH_JIT) +/* + * Return from the translation cache to the interpreter when the compiler is + * having issues translating/executing a Dalvik instruction. We have to skip + * the code cache lookup otherwise it is possible to indefinitely bouce + * between the interpreter and the code cache if the instruction that fails + * to be compiled happens to be at a trace start. + */ + .global dvmJitToInterpPunt +dvmJitToInterpPunt: + mov rPC, r0 +#ifdef EXIT_STATS + mov r0,lr + bl dvmBumpPunt; +#endif + EXPORT_PC() + adrl rIBASE, dvmAsmInstructionStart + FETCH_INST() + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) + +/* + * Return to the interpreter to handle a single instruction. + * On entry: + * r0 <= PC + * r1 <= PC of resume instruction + * lr <= resume point in translation + */ + .global dvmJitToInterpSingleStep +dvmJitToInterpSingleStep: + str lr,[rGLUE,#offGlue_jitResume] + str r1,[rGLUE,#offGlue_jitResumePC] + mov r1,#kInterpEntryInstr + @ enum is 4 byte in aapcs-EABI + str r1, [rGLUE, #offGlue_entryPoint] + mov rPC,r0 + EXPORT_PC() + adrl rIBASE, dvmAsmInstructionStart + mov r2,#kJitSingleStep @ Ask for single step and then revert + str r2,[rGLUE,#offGlue_jitState] + mov r1,#1 @ set changeInterp to bail to debug interp + b common_gotoBail + + +/* + * Return from the translation cache and immediately request + * a translation for the exit target. Commonly used following + * invokes. + */ + .global dvmJitToTraceSelect +dvmJitToTraceSelect: + ldr rPC,[r14, #-1] @ get our target PC + add rINST,r14,#-5 @ save start of chain branch + mov r0,rPC + bl dvmJitGetCodeAddr @ Is there a translation? + cmp r0,#0 + beq 2f + mov r1,rINST + bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) + ldr rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + bx r0 @ continue native execution + +/* No translation, so request one if profiling isn't disabled*/ +2: + GET_JIT_PROF_TABLE(r0) + FETCH_INST() + cmp r0, #0 + bne common_selectTrace + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) + +/* + * Return from the translation cache to the interpreter. + * The return was done with a BLX from thumb mode, and + * the following 32-bit word contains the target rPC value. + * Note that lr (r14) will have its low-order bit set to denote + * its thumb-mode origin. + * + * We'll need to stash our lr origin away, recover the new + * target and then check to see if there is a translation available + * for our new target. If so, we do a translation chain and + * go back to native execution. Otherwise, it's back to the + * interpreter (after treating this entry as a potential + * trace start). + */ + .global dvmJitToInterpNormal +dvmJitToInterpNormal: + ldr rPC,[r14, #-1] @ get our target PC + add rINST,r14,#-5 @ save start of chain branch +#ifdef EXIT_STATS + bl dvmBumpNormal +#endif + mov r0,rPC + bl dvmJitGetCodeAddr @ Is there a translation? + cmp r0,#0 + beq 1f @ go if not, otherwise do chain + mov r1,rINST + bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) + ldr rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + bx r0 @ continue native execution + +/* + * Return from the translation cache to the interpreter to do method invocation. + * Check if translation exists for the callee, but don't chain to it. + */ + .global dvmJitToInterpNoChain +dvmJitToInterpNoChain: +#ifdef EXIT_STATS + bl dvmBumpNoChain +#endif + mov r0,rPC + bl dvmJitGetCodeAddr @ Is there a translation? + cmp r0,#0 + bxne r0 @ continue native execution if so + +/* + * No translation, restore interpreter regs and start interpreting. + * rGLUE & rFP were preserved in the translated code, and rPC has + * already been restored by the time we get here. We'll need to set + * up rIBASE & rINST, and load the address of the JitTable into r0. + */ +1: + EXPORT_PC() + adrl rIBASE, dvmAsmInstructionStart + FETCH_INST() + GET_JIT_PROF_TABLE(r0) + @ NOTE: intended fallthrough +/* + * Common code to update potential trace start counter, and initiate + * a trace-build if appropriate. On entry, rPC should point to the + * next instruction to execute, and rINST should be already loaded with + * the next opcode word, and r0 holds a pointer to the jit profile + * table (pJitProfTable). + */ +common_testUpdateProfile: + cmp r0,#0 + GET_INST_OPCODE(ip) + GOTO_OPCODE_IFEQ(ip) @ if not profiling, fallthrough otherwise */ + +common_updateProfile: + eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function + lsl r3,r3,#23 @ shift out excess 511 + ldrb r1,[r0,r3,lsr #23] @ get counter + GET_INST_OPCODE(ip) + subs r1,r1,#1 @ decrement counter + strb r1,[r0,r3,lsr #23] @ and store it + GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ + +/* + * Here, we switch to the debug interpreter to request + * trace selection. First, though, check to see if there + * is already a native translation in place (and, if so, + * jump to it now). + */ + mov r1,#255 + strb r1,[r0,r3,lsr #23] @ reset counter + EXPORT_PC() + mov r0,rPC + bl dvmJitGetCodeAddr @ r0<- dvmJitGetCodeAddr(rPC) + cmp r0,#0 + ldrne rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + beq common_selectTrace + bxne r0 @ jump to the translation +common_selectTrace: + mov r2,#kJitTSelectRequest @ ask for trace selection + str r2,[rGLUE,#offGlue_jitState] + mov r1,#1 @ set changeInterp + b common_gotoBail + +.LdvmCompilerTemplateStart: + .word dvmCompilerTemplateStart + +#endif + /* * Common code when a backward branch is taken. * @@ -9316,9 +9675,18 @@ dvmAsmSisterEnd: common_backwardBranch: mov r0, #kInterpEntryInstr bl common_periodicChecks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) +#else FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif /* @@ -9492,6 +9860,10 @@ common_invokeMethodNoRange: #endif str rFP, [r10, #offStackSaveArea_prevFrame] str rPC, [r10, #offStackSaveArea_savedPc] +#if defined(WITH_JIT) + mov r9, #0 + str r9, [r10, #offStackSaveArea_returnAddr] +#endif str r0, [r10, #offStackSaveArea_method] tst r3, #ACC_NATIVE bne .LinvokeNative @@ -9520,11 +9892,22 @@ common_invokeMethodNoRange: @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ... +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) mov rFP, r1 @ fp = newFp GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 mov rINST, r9 @ publish new rINST str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp + cmp r0,#0 + bne common_updateProfile GOTO_OPCODE(ip) @ jump to next instruction +#else + mov rFP, r1 @ fp = newFp + GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 + mov rINST, r9 @ publish new rINST + str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp + GOTO_OPCODE(ip) @ jump to next instruction +#endif .LinvokeNative: @ Prep for the native call @@ -9630,10 +10013,26 @@ common_returnFromMethod: str r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex str rFP, [r3, #offThread_curFrame] @ self->curFrame = fp +#if defined(WITH_JIT) + ldr r3, [r0, #offStackSaveArea_returnAddr] @ r3 = saveArea->returnAddr + GET_JIT_PROF_TABLE(r0) + mov rPC, r9 @ publish new rPC + str r1, [rGLUE, #offGlue_methodClassDex] + cmp r3, #0 @ caller is compiled code + bne 1f + GET_INST_OPCODE(ip) @ extract opcode from rINST + cmp r0,#0 + bne common_updateProfile + GOTO_OPCODE(ip) @ jump to next instruction +1: + ldr rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + blx r3 +#else GET_INST_OPCODE(ip) @ extract opcode from rINST mov rPC, r9 @ publish new rPC str r1, [rGLUE, #offGlue_methodClassDex] GOTO_OPCODE(ip) @ jump to next instruction +#endif /* * Return handling, calls through "glue code". @@ -9656,12 +10055,19 @@ common_returnFromMethod: * * This does not return. */ + .global dvmMterpCommonExceptionThrown +dvmMterpCommonExceptionThrown: common_exceptionThrown: .LexceptionNew: mov r0, #kInterpEntryThrow mov r9, #0 bl common_periodicChecks +#if defined(WITH_JIT) + mov r2,#kJitTSelectAbort @ abandon trace selection in progress + str r2,[rGLUE,#offGlue_jitState] +#endif + ldr r10, [rGLUE, #offGlue_self] @ r10<- glue->self ldr r9, [r10, #offThread_exception] @ r9<- self->exception mov r1, r10 @ r1<- self diff --git a/vm/mterp/out/InterpAsm-armv5te-vfp.S b/vm/mterp/out/InterpAsm-armv5te-vfp.S index 77f621326..3e557003e 100644 --- a/vm/mterp/out/InterpAsm-armv5te-vfp.S +++ b/vm/mterp/out/InterpAsm-armv5te-vfp.S @@ -175,6 +175,8 @@ unspecified registers or condition codes. * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork. */ #define GOTO_OPCODE(_reg) add pc, rIBASE, _reg, lsl #6 +#define GOTO_OPCODE_IFEQ(_reg) addeq pc, rIBASE, _reg, lsl #6 +#define GOTO_OPCODE_IFNE(_reg) addne pc, rIBASE, _reg, lsl #6 /* * Get/set the 32-bit value from a Dalvik register. @@ -182,6 +184,14 @@ unspecified registers or condition codes. #define GET_VREG(_reg, _vreg) ldr _reg, [rFP, _vreg, lsl #2] #define SET_VREG(_reg, _vreg) str _reg, [rFP, _vreg, lsl #2] +#if defined(WITH_JIT) +/* + * Null definition for overhead measuring purposes + */ +#define GET_JIT_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitTable] +#define GET_JIT_PROF_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitProfTable] +#endif + /* * Convert a virtual register index into an address. */ @@ -302,10 +312,21 @@ dvmMterpStdRun: cmp r1, #kInterpEntryInstr @ usual case? bne .Lnot_instr @ no, handle it +#if defined(WITH_JIT) +.Lno_singleStep: + /* Entry is always a possible trace start */ + GET_JIT_PROF_TABLE(r0) + FETCH_INST() + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) +#else /* start executing the instruction at rPC */ FETCH_INST() @ load rINST from rPC GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif .Lnot_instr: cmp r1, #kInterpEntryReturn @ were we returning from a method? @@ -315,6 +336,22 @@ dvmMterpStdRun: cmp r1, #kInterpEntryThrow @ were we throwing an exception? beq common_exceptionThrown +#if defined(WITH_JIT) +.Lnot_throw: + ldr r0,[rGLUE, #offGlue_jitResume] + ldr r2,[rGLUE, #offGlue_jitResumePC] + cmp r1, #kInterpEntryResume @ resuming after Jit single-step? + bne .Lbad_arg + cmp rPC,r2 + bne .Lno_singleStep @ must have branched, don't resume + mov r1, #kInterpEntryInstr + strb r1, [rGLUE, #offGlue_entryPoint] + ldr rINST, .LdvmCompilerTemplate + bx r0 @ re-enter the translation +.LdvmCompilerTemplate: + .word dvmCompilerTemplateStart +#endif + .Lbad_arg: ldr r0, strBadEntryPoint @ r1 holds value of entryPoint @@ -1111,10 +1148,18 @@ dalvik_inst: movs r9, r0, asr #24 @ r9<- ssssssAA (sign-extended) mov r9, r9, lsl #1 @ r9<- byte offset bmi common_backwardBranch @ backward branch, do periodic checks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction - +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ .balign 64 @@ -1130,9 +1175,18 @@ dalvik_inst: FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) movs r9, r0, asl #1 @ r9<- byte offset, check sign bmi common_backwardBranch @ backward branch, do periodic checks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ @@ -1157,10 +1211,18 @@ dalvik_inst: orrs r0, r0, r1, lsl #16 @ r0<- AAAAaaaa, check sign mov r9, r0, asl #1 @ r9<- byte offset ble common_backwardBranch @ backward branch, do periodic checks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction - +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ .balign 64 @@ -1186,9 +1248,18 @@ dalvik_inst: movs r9, r0, asl #1 @ r9<- branch byte offset, check sign bmi common_backwardBranch @ backward branch, do periodic checks beq common_backwardBranch @ (want to use BLE but V is unknown) +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ @@ -1216,9 +1287,18 @@ dalvik_inst: movs r9, r0, asl #1 @ r9<- branch byte offset, check sign bmi common_backwardBranch @ backward branch, do periodic checks beq common_backwardBranch @ (want to use BLE but V is unknown) +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1443,9 +1523,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1473,9 +1560,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1503,9 +1597,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1533,9 +1634,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1563,9 +1671,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1593,9 +1708,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1620,9 +1742,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1647,9 +1779,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1674,9 +1816,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1701,9 +1853,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1728,9 +1890,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1755,9 +1927,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -8812,15 +8994,192 @@ d2l_doconv: dvmAsmSisterEnd: /* File: armv5te/footer.S */ + /* * =========================================================================== * Common subroutines and data * =========================================================================== */ + + .text .align 2 +#if defined(WITH_JIT) +/* + * Return from the translation cache to the interpreter when the compiler is + * having issues translating/executing a Dalvik instruction. We have to skip + * the code cache lookup otherwise it is possible to indefinitely bouce + * between the interpreter and the code cache if the instruction that fails + * to be compiled happens to be at a trace start. + */ + .global dvmJitToInterpPunt +dvmJitToInterpPunt: + mov rPC, r0 +#ifdef EXIT_STATS + mov r0,lr + bl dvmBumpPunt; +#endif + EXPORT_PC() + adrl rIBASE, dvmAsmInstructionStart + FETCH_INST() + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) + +/* + * Return to the interpreter to handle a single instruction. + * On entry: + * r0 <= PC + * r1 <= PC of resume instruction + * lr <= resume point in translation + */ + .global dvmJitToInterpSingleStep +dvmJitToInterpSingleStep: + str lr,[rGLUE,#offGlue_jitResume] + str r1,[rGLUE,#offGlue_jitResumePC] + mov r1,#kInterpEntryInstr + @ enum is 4 byte in aapcs-EABI + str r1, [rGLUE, #offGlue_entryPoint] + mov rPC,r0 + EXPORT_PC() + adrl rIBASE, dvmAsmInstructionStart + mov r2,#kJitSingleStep @ Ask for single step and then revert + str r2,[rGLUE,#offGlue_jitState] + mov r1,#1 @ set changeInterp to bail to debug interp + b common_gotoBail + + +/* + * Return from the translation cache and immediately request + * a translation for the exit target. Commonly used following + * invokes. + */ + .global dvmJitToTraceSelect +dvmJitToTraceSelect: + ldr rPC,[r14, #-1] @ get our target PC + add rINST,r14,#-5 @ save start of chain branch + mov r0,rPC + bl dvmJitGetCodeAddr @ Is there a translation? + cmp r0,#0 + beq 2f + mov r1,rINST + bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) + ldr rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + bx r0 @ continue native execution + +/* No translation, so request one if profiling isn't disabled*/ +2: + GET_JIT_PROF_TABLE(r0) + FETCH_INST() + cmp r0, #0 + bne common_selectTrace + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) + +/* + * Return from the translation cache to the interpreter. + * The return was done with a BLX from thumb mode, and + * the following 32-bit word contains the target rPC value. + * Note that lr (r14) will have its low-order bit set to denote + * its thumb-mode origin. + * + * We'll need to stash our lr origin away, recover the new + * target and then check to see if there is a translation available + * for our new target. If so, we do a translation chain and + * go back to native execution. Otherwise, it's back to the + * interpreter (after treating this entry as a potential + * trace start). + */ + .global dvmJitToInterpNormal +dvmJitToInterpNormal: + ldr rPC,[r14, #-1] @ get our target PC + add rINST,r14,#-5 @ save start of chain branch +#ifdef EXIT_STATS + bl dvmBumpNormal +#endif + mov r0,rPC + bl dvmJitGetCodeAddr @ Is there a translation? + cmp r0,#0 + beq 1f @ go if not, otherwise do chain + mov r1,rINST + bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) + ldr rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + bx r0 @ continue native execution + +/* + * Return from the translation cache to the interpreter to do method invocation. + * Check if translation exists for the callee, but don't chain to it. + */ + .global dvmJitToInterpNoChain +dvmJitToInterpNoChain: +#ifdef EXIT_STATS + bl dvmBumpNoChain +#endif + mov r0,rPC + bl dvmJitGetCodeAddr @ Is there a translation? + cmp r0,#0 + bxne r0 @ continue native execution if so + +/* + * No translation, restore interpreter regs and start interpreting. + * rGLUE & rFP were preserved in the translated code, and rPC has + * already been restored by the time we get here. We'll need to set + * up rIBASE & rINST, and load the address of the JitTable into r0. + */ +1: + EXPORT_PC() + adrl rIBASE, dvmAsmInstructionStart + FETCH_INST() + GET_JIT_PROF_TABLE(r0) + @ NOTE: intended fallthrough +/* + * Common code to update potential trace start counter, and initiate + * a trace-build if appropriate. On entry, rPC should point to the + * next instruction to execute, and rINST should be already loaded with + * the next opcode word, and r0 holds a pointer to the jit profile + * table (pJitProfTable). + */ +common_testUpdateProfile: + cmp r0,#0 + GET_INST_OPCODE(ip) + GOTO_OPCODE_IFEQ(ip) @ if not profiling, fallthrough otherwise */ + +common_updateProfile: + eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function + lsl r3,r3,#23 @ shift out excess 511 + ldrb r1,[r0,r3,lsr #23] @ get counter + GET_INST_OPCODE(ip) + subs r1,r1,#1 @ decrement counter + strb r1,[r0,r3,lsr #23] @ and store it + GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ + +/* + * Here, we switch to the debug interpreter to request + * trace selection. First, though, check to see if there + * is already a native translation in place (and, if so, + * jump to it now). + */ + mov r1,#255 + strb r1,[r0,r3,lsr #23] @ reset counter + EXPORT_PC() + mov r0,rPC + bl dvmJitGetCodeAddr @ r0<- dvmJitGetCodeAddr(rPC) + cmp r0,#0 + ldrne rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + beq common_selectTrace + bxne r0 @ jump to the translation +common_selectTrace: + mov r2,#kJitTSelectRequest @ ask for trace selection + str r2,[rGLUE,#offGlue_jitState] + mov r1,#1 @ set changeInterp + b common_gotoBail + +.LdvmCompilerTemplateStart: + .word dvmCompilerTemplateStart + +#endif + /* * Common code when a backward branch is taken. * @@ -8830,9 +9189,18 @@ dvmAsmSisterEnd: common_backwardBranch: mov r0, #kInterpEntryInstr bl common_periodicChecks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) +#else FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif /* @@ -9006,6 +9374,10 @@ common_invokeMethodNoRange: #endif str rFP, [r10, #offStackSaveArea_prevFrame] str rPC, [r10, #offStackSaveArea_savedPc] +#if defined(WITH_JIT) + mov r9, #0 + str r9, [r10, #offStackSaveArea_returnAddr] +#endif str r0, [r10, #offStackSaveArea_method] tst r3, #ACC_NATIVE bne .LinvokeNative @@ -9034,11 +9406,22 @@ common_invokeMethodNoRange: @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ... +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) mov rFP, r1 @ fp = newFp GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 mov rINST, r9 @ publish new rINST str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp + cmp r0,#0 + bne common_updateProfile GOTO_OPCODE(ip) @ jump to next instruction +#else + mov rFP, r1 @ fp = newFp + GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 + mov rINST, r9 @ publish new rINST + str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp + GOTO_OPCODE(ip) @ jump to next instruction +#endif .LinvokeNative: @ Prep for the native call @@ -9144,10 +9527,26 @@ common_returnFromMethod: str r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex str rFP, [r3, #offThread_curFrame] @ self->curFrame = fp +#if defined(WITH_JIT) + ldr r3, [r0, #offStackSaveArea_returnAddr] @ r3 = saveArea->returnAddr + GET_JIT_PROF_TABLE(r0) + mov rPC, r9 @ publish new rPC + str r1, [rGLUE, #offGlue_methodClassDex] + cmp r3, #0 @ caller is compiled code + bne 1f + GET_INST_OPCODE(ip) @ extract opcode from rINST + cmp r0,#0 + bne common_updateProfile + GOTO_OPCODE(ip) @ jump to next instruction +1: + ldr rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + blx r3 +#else GET_INST_OPCODE(ip) @ extract opcode from rINST mov rPC, r9 @ publish new rPC str r1, [rGLUE, #offGlue_methodClassDex] GOTO_OPCODE(ip) @ jump to next instruction +#endif /* * Return handling, calls through "glue code". @@ -9170,12 +9569,19 @@ common_returnFromMethod: * * This does not return. */ + .global dvmMterpCommonExceptionThrown +dvmMterpCommonExceptionThrown: common_exceptionThrown: .LexceptionNew: mov r0, #kInterpEntryThrow mov r9, #0 bl common_periodicChecks +#if defined(WITH_JIT) + mov r2,#kJitTSelectAbort @ abandon trace selection in progress + str r2,[rGLUE,#offGlue_jitState] +#endif + ldr r10, [rGLUE, #offGlue_self] @ r10<- glue->self ldr r9, [r10, #offThread_exception] @ r9<- self->exception mov r1, r10 @ r1<- self diff --git a/vm/mterp/out/InterpAsm-armv5te.S b/vm/mterp/out/InterpAsm-armv5te.S index 8deb4aa70..9c380eaaf 100644 --- a/vm/mterp/out/InterpAsm-armv5te.S +++ b/vm/mterp/out/InterpAsm-armv5te.S @@ -175,6 +175,8 @@ unspecified registers or condition codes. * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork. */ #define GOTO_OPCODE(_reg) add pc, rIBASE, _reg, lsl #6 +#define GOTO_OPCODE_IFEQ(_reg) addeq pc, rIBASE, _reg, lsl #6 +#define GOTO_OPCODE_IFNE(_reg) addne pc, rIBASE, _reg, lsl #6 /* * Get/set the 32-bit value from a Dalvik register. @@ -182,6 +184,14 @@ unspecified registers or condition codes. #define GET_VREG(_reg, _vreg) ldr _reg, [rFP, _vreg, lsl #2] #define SET_VREG(_reg, _vreg) str _reg, [rFP, _vreg, lsl #2] +#if defined(WITH_JIT) +/* + * Null definition for overhead measuring purposes + */ +#define GET_JIT_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitTable] +#define GET_JIT_PROF_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitProfTable] +#endif + /* * Convert a virtual register index into an address. */ @@ -302,10 +312,21 @@ dvmMterpStdRun: cmp r1, #kInterpEntryInstr @ usual case? bne .Lnot_instr @ no, handle it +#if defined(WITH_JIT) +.Lno_singleStep: + /* Entry is always a possible trace start */ + GET_JIT_PROF_TABLE(r0) + FETCH_INST() + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) +#else /* start executing the instruction at rPC */ FETCH_INST() @ load rINST from rPC GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif .Lnot_instr: cmp r1, #kInterpEntryReturn @ were we returning from a method? @@ -315,6 +336,22 @@ dvmMterpStdRun: cmp r1, #kInterpEntryThrow @ were we throwing an exception? beq common_exceptionThrown +#if defined(WITH_JIT) +.Lnot_throw: + ldr r0,[rGLUE, #offGlue_jitResume] + ldr r2,[rGLUE, #offGlue_jitResumePC] + cmp r1, #kInterpEntryResume @ resuming after Jit single-step? + bne .Lbad_arg + cmp rPC,r2 + bne .Lno_singleStep @ must have branched, don't resume + mov r1, #kInterpEntryInstr + strb r1, [rGLUE, #offGlue_entryPoint] + ldr rINST, .LdvmCompilerTemplate + bx r0 @ re-enter the translation +.LdvmCompilerTemplate: + .word dvmCompilerTemplateStart +#endif + .Lbad_arg: ldr r0, strBadEntryPoint @ r1 holds value of entryPoint @@ -1111,10 +1148,18 @@ dalvik_inst: movs r9, r0, asr #24 @ r9<- ssssssAA (sign-extended) mov r9, r9, lsl #1 @ r9<- byte offset bmi common_backwardBranch @ backward branch, do periodic checks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction - +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ .balign 64 @@ -1130,9 +1175,18 @@ dalvik_inst: FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) movs r9, r0, asl #1 @ r9<- byte offset, check sign bmi common_backwardBranch @ backward branch, do periodic checks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ @@ -1157,10 +1211,18 @@ dalvik_inst: orrs r0, r0, r1, lsl #16 @ r0<- AAAAaaaa, check sign mov r9, r0, asl #1 @ r9<- byte offset ble common_backwardBranch @ backward branch, do periodic checks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction - +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ .balign 64 @@ -1186,9 +1248,18 @@ dalvik_inst: movs r9, r0, asl #1 @ r9<- branch byte offset, check sign bmi common_backwardBranch @ backward branch, do periodic checks beq common_backwardBranch @ (want to use BLE but V is unknown) +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif /* ------------------------------ */ @@ -1216,9 +1287,18 @@ dalvik_inst: movs r9, r0, asl #1 @ r9<- branch byte offset, check sign bmi common_backwardBranch @ backward branch, do periodic checks beq common_backwardBranch @ (want to use BLE but V is unknown) +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1465,9 +1545,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1495,9 +1582,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1525,9 +1619,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1555,9 +1656,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1585,9 +1693,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1615,9 +1730,16 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ yes, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + b common_testUpdateProfile +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1642,9 +1764,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1669,9 +1801,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1696,9 +1838,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1723,9 +1875,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1750,9 +1912,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -1777,9 +1949,19 @@ dalvik_inst: FETCH_S(r9, 1) @ r9<- branch offset, in code units movs r9, r9, asl #1 @ convert to bytes, check sign bmi common_backwardBranch @ backward branch, do periodic checks -1: FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST +1: +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#else + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + GET_INST_OPCODE(ip) @ extract opcode from rINST + GOTO_OPCODE(ip) @ jump to next instruction +#endif @@ -9292,15 +9474,192 @@ d2l_doconv: dvmAsmSisterEnd: /* File: armv5te/footer.S */ + /* * =========================================================================== * Common subroutines and data * =========================================================================== */ + + .text .align 2 +#if defined(WITH_JIT) +/* + * Return from the translation cache to the interpreter when the compiler is + * having issues translating/executing a Dalvik instruction. We have to skip + * the code cache lookup otherwise it is possible to indefinitely bouce + * between the interpreter and the code cache if the instruction that fails + * to be compiled happens to be at a trace start. + */ + .global dvmJitToInterpPunt +dvmJitToInterpPunt: + mov rPC, r0 +#ifdef EXIT_STATS + mov r0,lr + bl dvmBumpPunt; +#endif + EXPORT_PC() + adrl rIBASE, dvmAsmInstructionStart + FETCH_INST() + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) + +/* + * Return to the interpreter to handle a single instruction. + * On entry: + * r0 <= PC + * r1 <= PC of resume instruction + * lr <= resume point in translation + */ + .global dvmJitToInterpSingleStep +dvmJitToInterpSingleStep: + str lr,[rGLUE,#offGlue_jitResume] + str r1,[rGLUE,#offGlue_jitResumePC] + mov r1,#kInterpEntryInstr + @ enum is 4 byte in aapcs-EABI + str r1, [rGLUE, #offGlue_entryPoint] + mov rPC,r0 + EXPORT_PC() + adrl rIBASE, dvmAsmInstructionStart + mov r2,#kJitSingleStep @ Ask for single step and then revert + str r2,[rGLUE,#offGlue_jitState] + mov r1,#1 @ set changeInterp to bail to debug interp + b common_gotoBail + + +/* + * Return from the translation cache and immediately request + * a translation for the exit target. Commonly used following + * invokes. + */ + .global dvmJitToTraceSelect +dvmJitToTraceSelect: + ldr rPC,[r14, #-1] @ get our target PC + add rINST,r14,#-5 @ save start of chain branch + mov r0,rPC + bl dvmJitGetCodeAddr @ Is there a translation? + cmp r0,#0 + beq 2f + mov r1,rINST + bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) + ldr rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + bx r0 @ continue native execution + +/* No translation, so request one if profiling isn't disabled*/ +2: + GET_JIT_PROF_TABLE(r0) + FETCH_INST() + cmp r0, #0 + bne common_selectTrace + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) + +/* + * Return from the translation cache to the interpreter. + * The return was done with a BLX from thumb mode, and + * the following 32-bit word contains the target rPC value. + * Note that lr (r14) will have its low-order bit set to denote + * its thumb-mode origin. + * + * We'll need to stash our lr origin away, recover the new + * target and then check to see if there is a translation available + * for our new target. If so, we do a translation chain and + * go back to native execution. Otherwise, it's back to the + * interpreter (after treating this entry as a potential + * trace start). + */ + .global dvmJitToInterpNormal +dvmJitToInterpNormal: + ldr rPC,[r14, #-1] @ get our target PC + add rINST,r14,#-5 @ save start of chain branch +#ifdef EXIT_STATS + bl dvmBumpNormal +#endif + mov r0,rPC + bl dvmJitGetCodeAddr @ Is there a translation? + cmp r0,#0 + beq 1f @ go if not, otherwise do chain + mov r1,rINST + bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) + ldr rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + bx r0 @ continue native execution + +/* + * Return from the translation cache to the interpreter to do method invocation. + * Check if translation exists for the callee, but don't chain to it. + */ + .global dvmJitToInterpNoChain +dvmJitToInterpNoChain: +#ifdef EXIT_STATS + bl dvmBumpNoChain +#endif + mov r0,rPC + bl dvmJitGetCodeAddr @ Is there a translation? + cmp r0,#0 + bxne r0 @ continue native execution if so + +/* + * No translation, restore interpreter regs and start interpreting. + * rGLUE & rFP were preserved in the translated code, and rPC has + * already been restored by the time we get here. We'll need to set + * up rIBASE & rINST, and load the address of the JitTable into r0. + */ +1: + EXPORT_PC() + adrl rIBASE, dvmAsmInstructionStart + FETCH_INST() + GET_JIT_PROF_TABLE(r0) + @ NOTE: intended fallthrough +/* + * Common code to update potential trace start counter, and initiate + * a trace-build if appropriate. On entry, rPC should point to the + * next instruction to execute, and rINST should be already loaded with + * the next opcode word, and r0 holds a pointer to the jit profile + * table (pJitProfTable). + */ +common_testUpdateProfile: + cmp r0,#0 + GET_INST_OPCODE(ip) + GOTO_OPCODE_IFEQ(ip) @ if not profiling, fallthrough otherwise */ + +common_updateProfile: + eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function + lsl r3,r3,#23 @ shift out excess 511 + ldrb r1,[r0,r3,lsr #23] @ get counter + GET_INST_OPCODE(ip) + subs r1,r1,#1 @ decrement counter + strb r1,[r0,r3,lsr #23] @ and store it + GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ + +/* + * Here, we switch to the debug interpreter to request + * trace selection. First, though, check to see if there + * is already a native translation in place (and, if so, + * jump to it now). + */ + mov r1,#255 + strb r1,[r0,r3,lsr #23] @ reset counter + EXPORT_PC() + mov r0,rPC + bl dvmJitGetCodeAddr @ r0<- dvmJitGetCodeAddr(rPC) + cmp r0,#0 + ldrne rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + beq common_selectTrace + bxne r0 @ jump to the translation +common_selectTrace: + mov r2,#kJitTSelectRequest @ ask for trace selection + str r2,[rGLUE,#offGlue_jitState] + mov r1,#1 @ set changeInterp + b common_gotoBail + +.LdvmCompilerTemplateStart: + .word dvmCompilerTemplateStart + +#endif + /* * Common code when a backward branch is taken. * @@ -9310,9 +9669,18 @@ dvmAsmSisterEnd: common_backwardBranch: mov r0, #kInterpEntryInstr bl common_periodicChecks +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) + FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST + cmp r0,#0 + bne common_updateProfile + GET_INST_OPCODE(ip) + GOTO_OPCODE(ip) +#else FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction +#endif /* @@ -9486,6 +9854,10 @@ common_invokeMethodNoRange: #endif str rFP, [r10, #offStackSaveArea_prevFrame] str rPC, [r10, #offStackSaveArea_savedPc] +#if defined(WITH_JIT) + mov r9, #0 + str r9, [r10, #offStackSaveArea_returnAddr] +#endif str r0, [r10, #offStackSaveArea_method] tst r3, #ACC_NATIVE bne .LinvokeNative @@ -9514,11 +9886,22 @@ common_invokeMethodNoRange: @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ... +#if defined(WITH_JIT) + GET_JIT_PROF_TABLE(r0) mov rFP, r1 @ fp = newFp GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 mov rINST, r9 @ publish new rINST str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp + cmp r0,#0 + bne common_updateProfile GOTO_OPCODE(ip) @ jump to next instruction +#else + mov rFP, r1 @ fp = newFp + GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 + mov rINST, r9 @ publish new rINST + str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp + GOTO_OPCODE(ip) @ jump to next instruction +#endif .LinvokeNative: @ Prep for the native call @@ -9624,10 +10007,26 @@ common_returnFromMethod: str r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex str rFP, [r3, #offThread_curFrame] @ self->curFrame = fp +#if defined(WITH_JIT) + ldr r3, [r0, #offStackSaveArea_returnAddr] @ r3 = saveArea->returnAddr + GET_JIT_PROF_TABLE(r0) + mov rPC, r9 @ publish new rPC + str r1, [rGLUE, #offGlue_methodClassDex] + cmp r3, #0 @ caller is compiled code + bne 1f + GET_INST_OPCODE(ip) @ extract opcode from rINST + cmp r0,#0 + bne common_updateProfile + GOTO_OPCODE(ip) @ jump to next instruction +1: + ldr rINST, .LdvmCompilerTemplateStart @ rINST is rCBASE in compiled code + blx r3 +#else GET_INST_OPCODE(ip) @ extract opcode from rINST mov rPC, r9 @ publish new rPC str r1, [rGLUE, #offGlue_methodClassDex] GOTO_OPCODE(ip) @ jump to next instruction +#endif /* * Return handling, calls through "glue code". @@ -9650,12 +10049,19 @@ common_returnFromMethod: * * This does not return. */ + .global dvmMterpCommonExceptionThrown +dvmMterpCommonExceptionThrown: common_exceptionThrown: .LexceptionNew: mov r0, #kInterpEntryThrow mov r9, #0 bl common_periodicChecks +#if defined(WITH_JIT) + mov r2,#kJitTSelectAbort @ abandon trace selection in progress + str r2,[rGLUE,#offGlue_jitState] +#endif + ldr r10, [rGLUE, #offGlue_self] @ r10<- glue->self ldr r9, [r10, #offThread_exception] @ r9<- self->exception mov r1, r10 @ r1<- self diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c index 420873e1c..0b70c9ef6 100644 --- a/vm/mterp/out/InterpC-allstubs.c +++ b/vm/mterp/out/InterpC-allstubs.c @@ -26,6 +26,7 @@ #include "interp/InterpDefs.h" #include "mterp/Mterp.h" #include <math.h> // needed for fmod, fmodf +#include "mterp/common/FindInterface.h" /* * Configuration defines. These affect the C implementations, i.e. the @@ -334,29 +335,21 @@ static inline void putDoubleToArray(u4* ptr, int idx, double dval) * If we're building without debug and profiling support, we never switch. */ #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER) +#if defined(WITH_JIT) +# define NEED_INTERP_SWITCH(_current) ( \ + (_current == INTERP_STD) ? \ + dvmJitDebuggerOrProfilerActive(interpState->jitState) : \ + !dvmJitDebuggerOrProfilerActive(interpState->jitState) ) +#else # define NEED_INTERP_SWITCH(_current) ( \ (_current == INTERP_STD) ? \ dvmDebuggerOrProfilerActive() : !dvmDebuggerOrProfilerActive() ) +#endif #else # define NEED_INTERP_SWITCH(_current) (false) #endif /* - * Look up an interface on a class using the cache. - */ -INLINE Method* dvmFindInterfaceMethodInCache(ClassObject* thisClass, - u4 methodIdx, const Method* method, DvmDex* methodClassDex) -{ -#define ATOMIC_CACHE_CALC \ - dvmInterpFindInterfaceMethod(thisClass, methodIdx, method, methodClassDex) - - return (Method*) ATOMIC_CACHE_LOOKUP(methodClassDex->pInterfaceCache, - DEX_INTERFACE_CACHE_SIZE, thisClass, methodIdx); - -#undef ATOMIC_CACHE_CALC -} - -/* * Check to see if "obj" is NULL. If so, throw an exception. Assumes the * pc has already been exported to the stack. * @@ -420,7 +413,6 @@ static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) return true; } - /* File: cstubs/stubdefs.c */ /* this is a standard (no debug support) interpreter */ #define INTERP_TYPE INTERP_STD @@ -3877,6 +3869,9 @@ GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, #endif newSaveArea->prevFrame = fp; newSaveArea->savedPc = pc; +#if defined(WITH_JIT) + newSaveArea->returnAddr = 0; +#endif newSaveArea->method = methodToCall; if (!dvmIsNativeMethod(methodToCall)) { @@ -3971,7 +3966,6 @@ GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, assert(false); // should not get here GOTO_TARGET_END - /* File: cstubs/enddefs.c */ /* undefine "magic" name remapping */ diff --git a/vm/mterp/out/InterpC-armv4t.c b/vm/mterp/out/InterpC-armv4t.c index 2f4b2e80a..80e87cf53 100644 --- a/vm/mterp/out/InterpC-armv4t.c +++ b/vm/mterp/out/InterpC-armv4t.c @@ -26,6 +26,7 @@ #include "interp/InterpDefs.h" #include "mterp/Mterp.h" #include <math.h> // needed for fmod, fmodf +#include "mterp/common/FindInterface.h" /* * Configuration defines. These affect the C implementations, i.e. the @@ -334,29 +335,21 @@ static inline void putDoubleToArray(u4* ptr, int idx, double dval) * If we're building without debug and profiling support, we never switch. */ #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER) +#if defined(WITH_JIT) +# define NEED_INTERP_SWITCH(_current) ( \ + (_current == INTERP_STD) ? \ + dvmJitDebuggerOrProfilerActive(interpState->jitState) : \ + !dvmJitDebuggerOrProfilerActive(interpState->jitState) ) +#else # define NEED_INTERP_SWITCH(_current) ( \ (_current == INTERP_STD) ? \ dvmDebuggerOrProfilerActive() : !dvmDebuggerOrProfilerActive() ) +#endif #else # define NEED_INTERP_SWITCH(_current) (false) #endif /* - * Look up an interface on a class using the cache. - */ -INLINE Method* dvmFindInterfaceMethodInCache(ClassObject* thisClass, - u4 methodIdx, const Method* method, DvmDex* methodClassDex) -{ -#define ATOMIC_CACHE_CALC \ - dvmInterpFindInterfaceMethod(thisClass, methodIdx, method, methodClassDex) - - return (Method*) ATOMIC_CACHE_LOOKUP(methodClassDex->pInterfaceCache, - DEX_INTERFACE_CACHE_SIZE, thisClass, methodIdx); - -#undef ATOMIC_CACHE_CALC -} - -/* * Check to see if "obj" is NULL. If so, throw an exception. Assumes the * pc has already been exported to the stack. * @@ -420,7 +413,6 @@ static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) return true; } - /* File: cstubs/stubdefs.c */ /* this is a standard (no debug support) interpreter */ #define INTERP_TYPE INTERP_STD diff --git a/vm/mterp/out/InterpC-armv5te-vfp.c b/vm/mterp/out/InterpC-armv5te-vfp.c index 92c29fb80..326ba3db9 100644 --- a/vm/mterp/out/InterpC-armv5te-vfp.c +++ b/vm/mterp/out/InterpC-armv5te-vfp.c @@ -26,6 +26,7 @@ #include "interp/InterpDefs.h" #include "mterp/Mterp.h" #include <math.h> // needed for fmod, fmodf +#include "mterp/common/FindInterface.h" /* * Configuration defines. These affect the C implementations, i.e. the @@ -334,29 +335,21 @@ static inline void putDoubleToArray(u4* ptr, int idx, double dval) * If we're building without debug and profiling support, we never switch. */ #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER) +#if defined(WITH_JIT) +# define NEED_INTERP_SWITCH(_current) ( \ + (_current == INTERP_STD) ? \ + dvmJitDebuggerOrProfilerActive(interpState->jitState) : \ + !dvmJitDebuggerOrProfilerActive(interpState->jitState) ) +#else # define NEED_INTERP_SWITCH(_current) ( \ (_current == INTERP_STD) ? \ dvmDebuggerOrProfilerActive() : !dvmDebuggerOrProfilerActive() ) +#endif #else # define NEED_INTERP_SWITCH(_current) (false) #endif /* - * Look up an interface on a class using the cache. - */ -INLINE Method* dvmFindInterfaceMethodInCache(ClassObject* thisClass, - u4 methodIdx, const Method* method, DvmDex* methodClassDex) -{ -#define ATOMIC_CACHE_CALC \ - dvmInterpFindInterfaceMethod(thisClass, methodIdx, method, methodClassDex) - - return (Method*) ATOMIC_CACHE_LOOKUP(methodClassDex->pInterfaceCache, - DEX_INTERFACE_CACHE_SIZE, thisClass, methodIdx); - -#undef ATOMIC_CACHE_CALC -} - -/* * Check to see if "obj" is NULL. If so, throw an exception. Assumes the * pc has already been exported to the stack. * @@ -420,7 +413,6 @@ static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) return true; } - /* File: cstubs/stubdefs.c */ /* this is a standard (no debug support) interpreter */ #define INTERP_TYPE INTERP_STD diff --git a/vm/mterp/out/InterpC-armv5te.c b/vm/mterp/out/InterpC-armv5te.c index 70794cc12..9cf78811d 100644 --- a/vm/mterp/out/InterpC-armv5te.c +++ b/vm/mterp/out/InterpC-armv5te.c @@ -26,6 +26,7 @@ #include "interp/InterpDefs.h" #include "mterp/Mterp.h" #include <math.h> // needed for fmod, fmodf +#include "mterp/common/FindInterface.h" /* * Configuration defines. These affect the C implementations, i.e. the @@ -334,29 +335,21 @@ static inline void putDoubleToArray(u4* ptr, int idx, double dval) * If we're building without debug and profiling support, we never switch. */ #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER) +#if defined(WITH_JIT) +# define NEED_INTERP_SWITCH(_current) ( \ + (_current == INTERP_STD) ? \ + dvmJitDebuggerOrProfilerActive(interpState->jitState) : \ + !dvmJitDebuggerOrProfilerActive(interpState->jitState) ) +#else # define NEED_INTERP_SWITCH(_current) ( \ (_current == INTERP_STD) ? \ dvmDebuggerOrProfilerActive() : !dvmDebuggerOrProfilerActive() ) +#endif #else # define NEED_INTERP_SWITCH(_current) (false) #endif /* - * Look up an interface on a class using the cache. - */ -INLINE Method* dvmFindInterfaceMethodInCache(ClassObject* thisClass, - u4 methodIdx, const Method* method, DvmDex* methodClassDex) -{ -#define ATOMIC_CACHE_CALC \ - dvmInterpFindInterfaceMethod(thisClass, methodIdx, method, methodClassDex) - - return (Method*) ATOMIC_CACHE_LOOKUP(methodClassDex->pInterfaceCache, - DEX_INTERFACE_CACHE_SIZE, thisClass, methodIdx); - -#undef ATOMIC_CACHE_CALC -} - -/* * Check to see if "obj" is NULL. If so, throw an exception. Assumes the * pc has already been exported to the stack. * @@ -420,7 +413,6 @@ static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) return true; } - /* File: cstubs/stubdefs.c */ /* this is a standard (no debug support) interpreter */ #define INTERP_TYPE INTERP_STD diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c index 188639c16..c8f428c45 100644 --- a/vm/mterp/out/InterpC-portdbg.c +++ b/vm/mterp/out/InterpC-portdbg.c @@ -26,6 +26,7 @@ #include "interp/InterpDefs.h" #include "mterp/Mterp.h" #include <math.h> // needed for fmod, fmodf +#include "mterp/common/FindInterface.h" /* * Configuration defines. These affect the C implementations, i.e. the @@ -334,29 +335,21 @@ static inline void putDoubleToArray(u4* ptr, int idx, double dval) * If we're building without debug and profiling support, we never switch. */ #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER) +#if defined(WITH_JIT) +# define NEED_INTERP_SWITCH(_current) ( \ + (_current == INTERP_STD) ? \ + dvmJitDebuggerOrProfilerActive(interpState->jitState) : \ + !dvmJitDebuggerOrProfilerActive(interpState->jitState) ) +#else # define NEED_INTERP_SWITCH(_current) ( \ (_current == INTERP_STD) ? \ dvmDebuggerOrProfilerActive() : !dvmDebuggerOrProfilerActive() ) +#endif #else # define NEED_INTERP_SWITCH(_current) (false) #endif /* - * Look up an interface on a class using the cache. - */ -INLINE Method* dvmFindInterfaceMethodInCache(ClassObject* thisClass, - u4 methodIdx, const Method* method, DvmDex* methodClassDex) -{ -#define ATOMIC_CACHE_CALC \ - dvmInterpFindInterfaceMethod(thisClass, methodIdx, method, methodClassDex) - - return (Method*) ATOMIC_CACHE_LOOKUP(methodClassDex->pInterfaceCache, - DEX_INTERFACE_CACHE_SIZE, thisClass, methodIdx); - -#undef ATOMIC_CACHE_CALC -} - -/* * Check to see if "obj" is NULL. If so, throw an exception. Assumes the * pc has already been exported to the stack. * @@ -420,7 +413,6 @@ static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) return true; } - /* File: portable/portdbg.c */ #define INTERP_FUNC_NAME dvmInterpretDbg #define INTERP_TYPE INTERP_DBG @@ -428,6 +420,14 @@ static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) #define CHECK_DEBUG_AND_PROF() \ checkDebugAndProf(pc, fp, self, curMethod, &debugIsMethodEntry) +#if defined(WITH_JIT) +#define CHECK_JIT() \ + if (dvmCheckJit(pc, self, interpState)) GOTO_bail_switch() +#else +#define CHECK_JIT() \ + ((void)0) +#endif + /* File: portable/stubdefs.c */ /* * In the C mterp stubs, "goto" is a function call followed immediately @@ -459,6 +459,7 @@ static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) inst = FETCH(0); \ CHECK_DEBUG_AND_PROF(); \ CHECK_TRACKED_REFS(); \ + CHECK_JIT(); \ goto *handlerTable[INST_INST(inst)]; \ } #else @@ -1479,11 +1480,32 @@ bool INTERP_FUNC_NAME(Thread* self, InterpState* interpState) const Method* methodToCall; bool methodCallRange; + #if defined(THREADED_INTERP) /* static computed goto table */ DEFINE_GOTO_TABLE(handlerTable); #endif +#if defined(WITH_JIT) +#if 0 + LOGD("*DebugInterp - entrypoint is %d, tgt is 0x%x, %s\n", + interpState->entryPoint, + interpState->pc, + interpState->method->name); +#endif + +#if INTERP_TYPE == INTERP_DBG + /* Check to see if we've got a trace selection request. If we do, + * but something is amiss, revert to the fast interpreter. + */ + if (dvmJitCheckTraceRequest(self,interpState)) { + interpState->nextMode = INTERP_STD; + //LOGD("** something wrong, exiting\n"); + return true; + } +#endif +#endif + /* copy state in */ curMethod = interpState->method; pc = interpState->pc; @@ -4138,6 +4160,9 @@ GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, #endif newSaveArea->prevFrame = fp; newSaveArea->savedPc = pc; +#if defined(WITH_JIT) + newSaveArea->returnAddr = 0; +#endif newSaveArea->method = methodToCall; if (!dvmIsNativeMethod(methodToCall)) { @@ -4232,7 +4257,6 @@ GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, assert(false); // should not get here GOTO_TARGET_END - /* File: portable/enddefs.c */ /*--- end of opcodes ---*/ diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c index 90d4ab41c..baf7a86f3 100644 --- a/vm/mterp/out/InterpC-portstd.c +++ b/vm/mterp/out/InterpC-portstd.c @@ -26,6 +26,7 @@ #include "interp/InterpDefs.h" #include "mterp/Mterp.h" #include <math.h> // needed for fmod, fmodf +#include "mterp/common/FindInterface.h" /* * Configuration defines. These affect the C implementations, i.e. the @@ -334,29 +335,21 @@ static inline void putDoubleToArray(u4* ptr, int idx, double dval) * If we're building without debug and profiling support, we never switch. */ #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER) +#if defined(WITH_JIT) +# define NEED_INTERP_SWITCH(_current) ( \ + (_current == INTERP_STD) ? \ + dvmJitDebuggerOrProfilerActive(interpState->jitState) : \ + !dvmJitDebuggerOrProfilerActive(interpState->jitState) ) +#else # define NEED_INTERP_SWITCH(_current) ( \ (_current == INTERP_STD) ? \ dvmDebuggerOrProfilerActive() : !dvmDebuggerOrProfilerActive() ) +#endif #else # define NEED_INTERP_SWITCH(_current) (false) #endif /* - * Look up an interface on a class using the cache. - */ -INLINE Method* dvmFindInterfaceMethodInCache(ClassObject* thisClass, - u4 methodIdx, const Method* method, DvmDex* methodClassDex) -{ -#define ATOMIC_CACHE_CALC \ - dvmInterpFindInterfaceMethod(thisClass, methodIdx, method, methodClassDex) - - return (Method*) ATOMIC_CACHE_LOOKUP(methodClassDex->pInterfaceCache, - DEX_INTERFACE_CACHE_SIZE, thisClass, methodIdx); - -#undef ATOMIC_CACHE_CALC -} - -/* * Check to see if "obj" is NULL. If so, throw an exception. Assumes the * pc has already been exported to the stack. * @@ -420,13 +413,14 @@ static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) return true; } - /* File: portable/portstd.c */ #define INTERP_FUNC_NAME dvmInterpretStd #define INTERP_TYPE INTERP_STD #define CHECK_DEBUG_AND_PROF() ((void)0) +#define CHECK_JIT() ((void)0) + /* File: portable/stubdefs.c */ /* * In the C mterp stubs, "goto" is a function call followed immediately @@ -458,6 +452,7 @@ static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) inst = FETCH(0); \ CHECK_DEBUG_AND_PROF(); \ CHECK_TRACKED_REFS(); \ + CHECK_JIT(); \ goto *handlerTable[INST_INST(inst)]; \ } #else @@ -1199,11 +1194,32 @@ bool INTERP_FUNC_NAME(Thread* self, InterpState* interpState) const Method* methodToCall; bool methodCallRange; + #if defined(THREADED_INTERP) /* static computed goto table */ DEFINE_GOTO_TABLE(handlerTable); #endif +#if defined(WITH_JIT) +#if 0 + LOGD("*DebugInterp - entrypoint is %d, tgt is 0x%x, %s\n", + interpState->entryPoint, + interpState->pc, + interpState->method->name); +#endif + +#if INTERP_TYPE == INTERP_DBG + /* Check to see if we've got a trace selection request. If we do, + * but something is amiss, revert to the fast interpreter. + */ + if (dvmJitCheckTraceRequest(self,interpState)) { + interpState->nextMode = INTERP_STD; + //LOGD("** something wrong, exiting\n"); + return true; + } +#endif +#endif + /* copy state in */ curMethod = interpState->method; pc = interpState->pc; @@ -3858,6 +3874,9 @@ GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, #endif newSaveArea->prevFrame = fp; newSaveArea->savedPc = pc; +#if defined(WITH_JIT) + newSaveArea->returnAddr = 0; +#endif newSaveArea->method = methodToCall; if (!dvmIsNativeMethod(methodToCall)) { @@ -3952,7 +3971,6 @@ GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, assert(false); // should not get here GOTO_TARGET_END - /* File: portable/enddefs.c */ /*--- end of opcodes ---*/ diff --git a/vm/mterp/out/InterpC-x86.c b/vm/mterp/out/InterpC-x86.c index 469b69075..b17e53021 100644 --- a/vm/mterp/out/InterpC-x86.c +++ b/vm/mterp/out/InterpC-x86.c @@ -26,6 +26,7 @@ #include "interp/InterpDefs.h" #include "mterp/Mterp.h" #include <math.h> // needed for fmod, fmodf +#include "mterp/common/FindInterface.h" /* * Configuration defines. These affect the C implementations, i.e. the @@ -334,29 +335,21 @@ static inline void putDoubleToArray(u4* ptr, int idx, double dval) * If we're building without debug and profiling support, we never switch. */ #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER) +#if defined(WITH_JIT) +# define NEED_INTERP_SWITCH(_current) ( \ + (_current == INTERP_STD) ? \ + dvmJitDebuggerOrProfilerActive(interpState->jitState) : \ + !dvmJitDebuggerOrProfilerActive(interpState->jitState) ) +#else # define NEED_INTERP_SWITCH(_current) ( \ (_current == INTERP_STD) ? \ dvmDebuggerOrProfilerActive() : !dvmDebuggerOrProfilerActive() ) +#endif #else # define NEED_INTERP_SWITCH(_current) (false) #endif /* - * Look up an interface on a class using the cache. - */ -INLINE Method* dvmFindInterfaceMethodInCache(ClassObject* thisClass, - u4 methodIdx, const Method* method, DvmDex* methodClassDex) -{ -#define ATOMIC_CACHE_CALC \ - dvmInterpFindInterfaceMethod(thisClass, methodIdx, method, methodClassDex) - - return (Method*) ATOMIC_CACHE_LOOKUP(methodClassDex->pInterfaceCache, - DEX_INTERFACE_CACHE_SIZE, thisClass, methodIdx); - -#undef ATOMIC_CACHE_CALC -} - -/* * Check to see if "obj" is NULL. If so, throw an exception. Assumes the * pc has already been exported to the stack. * @@ -420,7 +413,6 @@ static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) return true; } - /* File: cstubs/stubdefs.c */ /* this is a standard (no debug support) interpreter */ #define INTERP_TYPE INTERP_STD @@ -2041,6 +2033,9 @@ GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, #endif newSaveArea->prevFrame = fp; newSaveArea->savedPc = pc; +#if defined(WITH_JIT) + newSaveArea->returnAddr = 0; +#endif newSaveArea->method = methodToCall; if (!dvmIsNativeMethod(methodToCall)) { @@ -2135,7 +2130,6 @@ GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, assert(false); // should not get here GOTO_TARGET_END - /* File: cstubs/enddefs.c */ /* undefine "magic" name remapping */ |