diff options
-rw-r--r-- | vm/compiler/codegen/arm/CodegenDriver.c | 53 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/Thumb2/Gen.c | 32 | ||||
-rw-r--r-- | vm/compiler/template/armv5te-vfp/TemplateOpList.h | 2 | ||||
-rw-r--r-- | vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER.S | 23 | ||||
-rw-r--r-- | vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S | 29 | ||||
-rw-r--r-- | vm/compiler/template/armv5te/TemplateOpList.h | 2 | ||||
-rw-r--r-- | vm/compiler/template/armv5te/footer.S | 2 | ||||
-rw-r--r-- | vm/compiler/template/armv7-a/TEMPLATE_MONITOR_ENTER.S | 29 | ||||
-rw-r--r-- | vm/compiler/template/armv7-a/TemplateOpList.h | 2 | ||||
-rw-r--r-- | vm/compiler/template/config-armv5te-vfp | 2 | ||||
-rw-r--r-- | vm/compiler/template/config-armv7-a | 3 | ||||
-rw-r--r-- | vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S | 66 | ||||
-rw-r--r-- | vm/compiler/template/out/CompilerTemplateAsm-armv5te.S | 66 | ||||
-rw-r--r-- | vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S | 72 | ||||
-rw-r--r-- | vm/mterp/common/asm-constants.h | 5 |
15 files changed, 344 insertions, 44 deletions
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c index 648d8f4d6..5be07aa3d 100644 --- a/vm/compiler/codegen/arm/CodegenDriver.c +++ b/vm/compiler/codegen/arm/CodegenDriver.c @@ -1693,46 +1693,41 @@ static void genInterpSingleStep(CompilationUnit *cUnit, MIR *mir) opReg(cUnit, kOpBlx, r2); } +/* + * To prevent a thread in a monitor wait from blocking the Jit from + * resetting the code cache, heavyweight monitor lock will not + * be allowed to return to an existing translation. Instead, we will + * handle them by branching to a handler, which will in turn call the + * runtime lock routine and then branch directly back to the + * interpreter main loop. Given the high cost of the heavyweight + * lock operation, this additional cost should be slight (especially when + * considering that we expect the vast majority of lock operations to + * use the fast-path thin lock bypass). + */ static void genMonitorPortable(CompilationUnit *cUnit, MIR *mir) { bool isEnter = (mir->dalvikInsn.opCode == OP_MONITOR_ENTER); - flushAllRegs(cUnit); /* Send everything to home location */ genExportPC(cUnit, mir); + flushAllRegs(cUnit); /* Send everything to home location */ RegLocation rlSrc = getSrcLoc(cUnit, mir, 0); loadValueDirectFixed(cUnit, rlSrc, r1); loadWordDisp(cUnit, rGLUE, offsetof(InterpState, self), r0); + genNullCheck(cUnit, rlSrc.sRegLow, r1, mir->offset, NULL); if (isEnter) { - loadConstant(cUnit, r2, (int)dvmLockObject); + /* Get dPC of next insn */ + loadConstant(cUnit, r4PC, (int)(cUnit->method->insns + mir->offset + + dexGetInstrWidthAbs(gDvm.instrWidth, OP_MONITOR_ENTER))); +#if defined(WITH_DEADLOCK_PREDICTION) + genDispatchToHandler(cUnit, TEMPLATE_MONITOR_ENTER_DEBUG); +#else + genDispatchToHandler(cUnit, TEMPLATE_MONITOR_ENTER); +#endif } else { loadConstant(cUnit, r2, (int)dvmUnlockObject); + /* Do the call */ + opReg(cUnit, kOpBlx, r2); + clobberCallRegs(cUnit); } - genNullCheck(cUnit, rlSrc.sRegLow, r1, mir->offset, NULL); - /* Do the call */ - opReg(cUnit, kOpBlx, r2); - /* - * Refresh Jit's on/off status, which may have changed if we were - * sent to VM_MONITOR state above. - * TUNING: pointer chase, but must reload following call - */ - loadWordDisp(cUnit, rGLUE, offsetof(InterpState, ppJitProfTable), r0); - loadWordDisp(cUnit, r0, 0, r0); - storeWordDisp(cUnit, rGLUE, offsetof(InterpState, pJitProfTable), r0); -#if defined(WITH_DEADLOCK_PREDICTION) - if (isEnter) { - loadWordDisp(cUnit, rGLUE, offsetof(InterpState, self), r0); - loadWordDisp(cUnit, r0, offsetof(Thread, exception), r1); - opRegImm(cUnit, kOpCmp, r1, 0); - ArmLIR *branchOver = opCondBranch(cUnit, kArmCondEq); - loadConstant(cUnit, r0, - (int) (cUnit->method->insns + mir->offset)); - genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON); - /* noreturn */ - ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel); - target->defMask = ENCODE_ALL; - branchOver->generic.target = (LIR *) target; - } -#endif - clobberCallRegs(cUnit); } /* diff --git a/vm/compiler/codegen/arm/Thumb2/Gen.c b/vm/compiler/codegen/arm/Thumb2/Gen.c index 5f2a6a259..1f947c2ad 100644 --- a/vm/compiler/codegen/arm/Thumb2/Gen.c +++ b/vm/compiler/codegen/arm/Thumb2/Gen.c @@ -231,26 +231,30 @@ static void genMonitor(CompilationUnit *cUnit, MIR *mir) offsetof(Object, lock) >> 2); } // Note: end of IT block - branch = newLIR2(cUnit, kThumb2Cbz, r2, 0); + // Export PC (part 1) + loadConstant(cUnit, r3, (int) (cUnit->method->insns + mir->offset)); + if (enter) { - loadConstant(cUnit, r7, (int)dvmLockObject); + /* Get dPC of next insn */ + loadConstant(cUnit, r4PC, (int)(cUnit->method->insns + mir->offset + + dexGetInstrWidthAbs(gDvm.instrWidth, OP_MONITOR_ENTER))); + // Export PC (part 2) + newLIR3(cUnit, kThumb2StrRRI8Predec, r3, rFP, + sizeof(StackSaveArea) - + offsetof(StackSaveArea, xtra.currentPc)); + /* Call template, and don't return */ + genDispatchToHandler(cUnit, TEMPLATE_MONITOR_ENTER); } else { loadConstant(cUnit, r7, (int)dvmUnlockObject); + // Export PC (part 2) + newLIR3(cUnit, kThumb2StrRRI8Predec, r3, rFP, + sizeof(StackSaveArea) - + offsetof(StackSaveArea, xtra.currentPc)); + opReg(cUnit, kOpBlx, r7); + clobberCallRegs(cUnit); } - genExportPC(cUnit, mir); - opReg(cUnit, kOpBlx, r7); - /* - * Refresh Jit's on/off status, which may have changed if we were - * sent to VM_MONITOR state above. - * TUNING: pointer chase, but must refresh following return from call - */ - loadWordDisp(cUnit, rGLUE, offsetof(InterpState, ppJitProfTable), r0); - loadWordDisp(cUnit, r0, 0, r0); - storeWordDisp(cUnit, rGLUE, offsetof(InterpState, pJitProfTable), r0); - - clobberCallRegs(cUnit); // Resume here target = newLIR0(cUnit, kArmPseudoTargetLabel); diff --git a/vm/compiler/template/armv5te-vfp/TemplateOpList.h b/vm/compiler/template/armv5te-vfp/TemplateOpList.h index d414e1be4..8855d46ee 100644 --- a/vm/compiler/template/armv5te-vfp/TemplateOpList.h +++ b/vm/compiler/template/armv5te-vfp/TemplateOpList.h @@ -56,3 +56,5 @@ JIT_TEMPLATE(RESTORE_STATE) JIT_TEMPLATE(STRING_COMPARETO) JIT_TEMPLATE(STRING_INDEXOF) JIT_TEMPLATE(INTERPRET) +JIT_TEMPLATE(MONITOR_ENTER) +JIT_TEMPLATE(MONITOR_ENTER_DEBUG) diff --git a/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER.S b/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER.S new file mode 100644 index 000000000..fa931bbeb --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER.S @@ -0,0 +1,23 @@ + /* + * Call out to the runtime to lock an object. Because this thread + * may have been suspended in THREAD_MONITOR state and the Jit's + * translation cache subsequently cleared, we cannot return directly. + * Instead, unconditionally transition to the interpreter to resume. + * + * On entry: + * r0 - self pointer + * r1 - the object (which has already been null-checked by the caller + * r4 - the Dalvik PC of the following instruction. + * + ldr r2, .LdvmLockObject + mov r3, #0 @ Record that we're not returning + str r3, [r0, #offThread_inJitCodeCache] + blx r2 @ dvmLockObject(self, obj) + @ refresh Jit's on/off status + ldr r0, [rGLUE, #offGlue_ppJitProfTable] + ldr r0, [r0] + ldr r2, .LdvmJitToInterpNoChain + str r0, [rGLUE, #offGlue_pJitProfTable] + @ Bail to interpreter - no chain [note - r4 still contains rPC] + bx r2 + diff --git a/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S b/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S new file mode 100644 index 000000000..c030cec64 --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S @@ -0,0 +1,29 @@ + /* + * To support deadlock prediction, this version of MONITOR_ENTER + * will always call the heavyweight dvmLockObject, check for an + * exception and then bail out to the interpreter. + * + * On entry: + * r0 - self pointer + * r1 - the object (which has already been null-checked by the caller + * r4 - the Dalvik PC of the following instruction. + * + */ + ldr r2, .LdvmLockObject + mov r3, #0 @ Record that we're not returning + str r3, [r0, #offThread_inJitCodeCache] + blx r2 @ dvmLockObject(self, obj) + @ refresh Jit's on/off status & test for exception + ldr r0, [rGLUE, #offGlue_ppJitProfTable] + ldr r1, [rGLUE, #offGlue_self] + ldr r0, [r0] + ldr r1, [r1, #offThread_exception] + str r0, [rGLUE, #offGlue_pJitProfTable] + cmp r1, #0 + beq 1f + ldr r2, .LhandleException + sub r0, r4, #2 @ roll dPC back to this monitor instruction + bx r2 +1: + @ Bail to interpreter - no chain [note - r4 still contains rPC] + ldr pc, .LdvmJitToInterpNoChain diff --git a/vm/compiler/template/armv5te/TemplateOpList.h b/vm/compiler/template/armv5te/TemplateOpList.h index 1b5e6ea99..c7ae80a28 100644 --- a/vm/compiler/template/armv5te/TemplateOpList.h +++ b/vm/compiler/template/armv5te/TemplateOpList.h @@ -41,3 +41,5 @@ JIT_TEMPLATE(RESTORE_STATE) JIT_TEMPLATE(STRING_COMPARETO) JIT_TEMPLATE(STRING_INDEXOF) JIT_TEMPLATE(INTERPRET) +JIT_TEMPLATE(MONITOR_ENTER) +JIT_TEMPLATE(MONITOR_ENTER_DEBUG) diff --git a/vm/compiler/template/armv5te/footer.S b/vm/compiler/template/armv5te/footer.S index 5d76f4869..0e817a638 100644 --- a/vm/compiler/template/armv5te/footer.S +++ b/vm/compiler/template/armv5te/footer.S @@ -77,6 +77,8 @@ .word dvmMterpStdBail .LdvmMterpCommonExceptionThrown: .word dvmMterpCommonExceptionThrown +.LdvmLockObject: + .word dvmLockObject .L__aeabi_cdcmple: .word __aeabi_cdcmple .L__aeabi_cfcmple: diff --git a/vm/compiler/template/armv7-a/TEMPLATE_MONITOR_ENTER.S b/vm/compiler/template/armv7-a/TEMPLATE_MONITOR_ENTER.S new file mode 100644 index 000000000..a26e52816 --- /dev/null +++ b/vm/compiler/template/armv7-a/TEMPLATE_MONITOR_ENTER.S @@ -0,0 +1,29 @@ + /* + * thumb2 specific. + * + * In this variant of the MONITOR_ENTER handler, we assume that + * the test for the simple thin lock case has already been done. + * So, we'll just call dvmLockObject(), refresh the + * jit's on/off switch on return and then bail out to the interpreter. + * We have to bail to the interpreter because the translation cache + * may have been cleared while we were blocked on a monitor in + * dvmLockObject. + * + * On entry: + * r0 - self pointer + * r1 - the object (which has already been null-checked by the caller + * r4 - the Dalvik PC of the following instruction. + * + */ + ldr r2, .LdvmLockObject + mov r3, #0 @ Record that we're not returning + str r3, [r0, #offThread_inJitCodeCache] + blx r2 @ dvmLockObject(self, obj) + @ refresh Jit's on/off status + ldr r0, [rGLUE, #offGlue_ppJitProfTable] + ldr r0, [r0] + ldr r2, .LdvmJitToInterpNoChain + str r0, [rGLUE, #offGlue_pJitProfTable] + @ Bail to interpreter - no chain [note - r4 still contains rPC] + bx r2 + diff --git a/vm/compiler/template/armv7-a/TemplateOpList.h b/vm/compiler/template/armv7-a/TemplateOpList.h index d414e1be4..8855d46ee 100644 --- a/vm/compiler/template/armv7-a/TemplateOpList.h +++ b/vm/compiler/template/armv7-a/TemplateOpList.h @@ -56,3 +56,5 @@ JIT_TEMPLATE(RESTORE_STATE) JIT_TEMPLATE(STRING_COMPARETO) JIT_TEMPLATE(STRING_INDEXOF) JIT_TEMPLATE(INTERPRET) +JIT_TEMPLATE(MONITOR_ENTER) +JIT_TEMPLATE(MONITOR_ENTER_DEBUG) diff --git a/vm/compiler/template/config-armv5te-vfp b/vm/compiler/template/config-armv5te-vfp index 0a1c7c7de..1b02261eb 100644 --- a/vm/compiler/template/config-armv5te-vfp +++ b/vm/compiler/template/config-armv5te-vfp @@ -46,6 +46,8 @@ op-start armv5te-vfp op TEMPLATE_STRING_COMPARETO armv5te op TEMPLATE_STRING_INDEXOF armv5te op TEMPLATE_INTERPRET armv5te + op TEMPLATE_MONITOR_ENTER armv5te + op TEMPLATE_MONITOR_ENTER_DEBUG armv5te op-end diff --git a/vm/compiler/template/config-armv7-a b/vm/compiler/template/config-armv7-a index 89fbb2315..29d90197f 100644 --- a/vm/compiler/template/config-armv7-a +++ b/vm/compiler/template/config-armv7-a @@ -46,7 +46,8 @@ op-start armv5te-vfp op TEMPLATE_STRING_COMPARETO armv5te op TEMPLATE_STRING_INDEXOF armv5te op TEMPLATE_INTERPRET armv5te - + op TEMPLATE_MONITOR_ENTER armv7-a + op TEMPLATE_MONITOR_ENTER_DEBUG armv5te op-end # "helper" code for C; include if you use any of the C stubs (this generates diff --git a/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S b/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S index afd69f353..3090a1776 100644 --- a/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S +++ b/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S @@ -1388,6 +1388,70 @@ dvmCompiler_TEMPLATE_INTERPRET: .LinterpPunt: .word dvmJitToInterpPunt +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_MONITOR_ENTER +dvmCompiler_TEMPLATE_MONITOR_ENTER: +/* File: armv5te/TEMPLATE_MONITOR_ENTER.S */ + /* + * Call out to the runtime to lock an object. Because this thread + * may have been suspended in THREAD_MONITOR state and the Jit's + * translation cache subsequently cleared, we cannot return directly. + * Instead, unconditionally transition to the interpreter to resume. + * + * On entry: + * r0 - self pointer + * r1 - the object (which has already been null-checked by the caller + * r4 - the Dalvik PC of the following instruction. + * + ldr r2, .LdvmLockObject + mov r3, #0 @ Record that we're not returning + str r3, [r0, #offThread_inJitCodeCache] + blx r2 @ dvmLockObject(self, obj) + @ refresh Jit's on/off status + ldr r0, [rGLUE, #offGlue_ppJitProfTable] + ldr r0, [r0] + ldr r2, .LdvmJitToInterpNoChain + str r0, [rGLUE, #offGlue_pJitProfTable] + @ Bail to interpreter - no chain [note - r4 still contains rPC] + bx r2 + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_MONITOR_ENTER_DEBUG +dvmCompiler_TEMPLATE_MONITOR_ENTER_DEBUG: +/* File: armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S */ + /* + * To support deadlock prediction, this version of MONITOR_ENTER + * will always call the heavyweight dvmLockObject, check for an + * exception and then bail out to the interpreter. + * + * On entry: + * r0 - self pointer + * r1 - the object (which has already been null-checked by the caller + * r4 - the Dalvik PC of the following instruction. + * + */ + ldr r2, .LdvmLockObject + mov r3, #0 @ Record that we're not returning + str r3, [r0, #offThread_inJitCodeCache] + blx r2 @ dvmLockObject(self, obj) + @ refresh Jit's on/off status & test for exception + ldr r0, [rGLUE, #offGlue_ppJitProfTable] + ldr r1, [rGLUE, #offGlue_self] + ldr r0, [r0] + ldr r1, [r1, #offThread_exception] + str r0, [rGLUE, #offGlue_pJitProfTable] + cmp r1, #0 + beq 1f + ldr r2, .LhandleException + sub r0, r4, #2 @ roll dPC back to this monitor instruction + bx r2 +1: + @ Bail to interpreter - no chain [note - r4 still contains rPC] + ldr pc, .LdvmJitToInterpNoChain + .size dvmCompilerTemplateStart, .-dvmCompilerTemplateStart /* File: armv5te/footer.S */ /* @@ -1469,6 +1533,8 @@ dvmCompiler_TEMPLATE_INTERPRET: .word dvmMterpStdBail .LdvmMterpCommonExceptionThrown: .word dvmMterpCommonExceptionThrown +.LdvmLockObject: + .word dvmLockObject .L__aeabi_cdcmple: .word __aeabi_cdcmple .L__aeabi_cfcmple: diff --git a/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S b/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S index d73e0101c..ffb978634 100644 --- a/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S +++ b/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S @@ -1113,6 +1113,70 @@ dvmCompiler_TEMPLATE_INTERPRET: .LinterpPunt: .word dvmJitToInterpPunt +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_MONITOR_ENTER +dvmCompiler_TEMPLATE_MONITOR_ENTER: +/* File: armv5te/TEMPLATE_MONITOR_ENTER.S */ + /* + * Call out to the runtime to lock an object. Because this thread + * may have been suspended in THREAD_MONITOR state and the Jit's + * translation cache subsequently cleared, we cannot return directly. + * Instead, unconditionally transition to the interpreter to resume. + * + * On entry: + * r0 - self pointer + * r1 - the object (which has already been null-checked by the caller + * r4 - the Dalvik PC of the following instruction. + * + ldr r2, .LdvmLockObject + mov r3, #0 @ Record that we're not returning + str r3, [r0, #offThread_inJitCodeCache] + blx r2 @ dvmLockObject(self, obj) + @ refresh Jit's on/off status + ldr r0, [rGLUE, #offGlue_ppJitProfTable] + ldr r0, [r0] + ldr r2, .LdvmJitToInterpNoChain + str r0, [rGLUE, #offGlue_pJitProfTable] + @ Bail to interpreter - no chain [note - r4 still contains rPC] + bx r2 + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_MONITOR_ENTER_DEBUG +dvmCompiler_TEMPLATE_MONITOR_ENTER_DEBUG: +/* File: armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S */ + /* + * To support deadlock prediction, this version of MONITOR_ENTER + * will always call the heavyweight dvmLockObject, check for an + * exception and then bail out to the interpreter. + * + * On entry: + * r0 - self pointer + * r1 - the object (which has already been null-checked by the caller + * r4 - the Dalvik PC of the following instruction. + * + */ + ldr r2, .LdvmLockObject + mov r3, #0 @ Record that we're not returning + str r3, [r0, #offThread_inJitCodeCache] + blx r2 @ dvmLockObject(self, obj) + @ refresh Jit's on/off status & test for exception + ldr r0, [rGLUE, #offGlue_ppJitProfTable] + ldr r1, [rGLUE, #offGlue_self] + ldr r0, [r0] + ldr r1, [r1, #offThread_exception] + str r0, [rGLUE, #offGlue_pJitProfTable] + cmp r1, #0 + beq 1f + ldr r2, .LhandleException + sub r0, r4, #2 @ roll dPC back to this monitor instruction + bx r2 +1: + @ Bail to interpreter - no chain [note - r4 still contains rPC] + ldr pc, .LdvmJitToInterpNoChain + .size dvmCompilerTemplateStart, .-dvmCompilerTemplateStart /* File: armv5te/footer.S */ /* @@ -1194,6 +1258,8 @@ dvmCompiler_TEMPLATE_INTERPRET: .word dvmMterpStdBail .LdvmMterpCommonExceptionThrown: .word dvmMterpCommonExceptionThrown +.LdvmLockObject: + .word dvmLockObject .L__aeabi_cdcmple: .word __aeabi_cdcmple .L__aeabi_cfcmple: diff --git a/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S b/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S index 12af0d27c..b157ff3f0 100644 --- a/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S +++ b/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S @@ -1388,6 +1388,76 @@ dvmCompiler_TEMPLATE_INTERPRET: .LinterpPunt: .word dvmJitToInterpPunt +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_MONITOR_ENTER +dvmCompiler_TEMPLATE_MONITOR_ENTER: +/* File: armv7-a/TEMPLATE_MONITOR_ENTER.S */ + /* + * thumb2 specific. + * + * In this variant of the MONITOR_ENTER handler, we assume that + * the test for the simple thin lock case has already been done. + * So, we'll just call dvmLockObject(), refresh the + * jit's on/off switch on return and then bail out to the interpreter. + * We have to bail to the interpreter because the translation cache + * may have been cleared while we were blocked on a monitor in + * dvmLockObject. + * + * On entry: + * r0 - self pointer + * r1 - the object (which has already been null-checked by the caller + * r4 - the Dalvik PC of the following instruction. + * + */ + ldr r2, .LdvmLockObject + mov r3, #0 @ Record that we're not returning + str r3, [r0, #offThread_inJitCodeCache] + blx r2 @ dvmLockObject(self, obj) + @ refresh Jit's on/off status + ldr r0, [rGLUE, #offGlue_ppJitProfTable] + ldr r0, [r0] + ldr r2, .LdvmJitToInterpNoChain + str r0, [rGLUE, #offGlue_pJitProfTable] + @ Bail to interpreter - no chain [note - r4 still contains rPC] + bx r2 + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_MONITOR_ENTER_DEBUG +dvmCompiler_TEMPLATE_MONITOR_ENTER_DEBUG: +/* File: armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S */ + /* + * To support deadlock prediction, this version of MONITOR_ENTER + * will always call the heavyweight dvmLockObject, check for an + * exception and then bail out to the interpreter. + * + * On entry: + * r0 - self pointer + * r1 - the object (which has already been null-checked by the caller + * r4 - the Dalvik PC of the following instruction. + * + */ + ldr r2, .LdvmLockObject + mov r3, #0 @ Record that we're not returning + str r3, [r0, #offThread_inJitCodeCache] + blx r2 @ dvmLockObject(self, obj) + @ refresh Jit's on/off status & test for exception + ldr r0, [rGLUE, #offGlue_ppJitProfTable] + ldr r1, [rGLUE, #offGlue_self] + ldr r0, [r0] + ldr r1, [r1, #offThread_exception] + str r0, [rGLUE, #offGlue_pJitProfTable] + cmp r1, #0 + beq 1f + ldr r2, .LhandleException + sub r0, r4, #2 @ roll dPC back to this monitor instruction + bx r2 +1: + @ Bail to interpreter - no chain [note - r4 still contains rPC] + ldr pc, .LdvmJitToInterpNoChain + .size dvmCompilerTemplateStart, .-dvmCompilerTemplateStart /* File: armv5te/footer.S */ /* @@ -1469,6 +1539,8 @@ dvmCompiler_TEMPLATE_INTERPRET: .word dvmMterpStdBail .LdvmMterpCommonExceptionThrown: .word dvmMterpCommonExceptionThrown +.LdvmLockObject: + .word dvmLockObject .L__aeabi_cdcmple: .word __aeabi_cdcmple .L__aeabi_cfcmple: diff --git a/vm/mterp/common/asm-constants.h b/vm/mterp/common/asm-constants.h index a3c8cecc7..ab2479997 100644 --- a/vm/mterp/common/asm-constants.h +++ b/vm/mterp/common/asm-constants.h @@ -240,6 +240,11 @@ MTERP_OFFSET(offThread_jniLocal_topCookie, \ /* Object fields */ MTERP_OFFSET(offObject_clazz, Object, clazz, 0) +MTERP_OFFSET(offObject_lock, Object, lock, 4) + +/* Lock shape */ +MTERP_CONSTANT(LW_LOCK_OWNER_SHIFT, 3) +MTERP_CONSTANT(LW_HASH_STATE_SHIFT, 1) /* ArrayObject fields */ MTERP_OFFSET(offArrayObject_length, ArrayObject, length, 8) |