diff options
author | Bill Buzbee <buzbee@google.com> | 2010-02-03 16:02:36 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-02-03 16:02:36 -0800 |
commit | e7ce72b4e44c2ee29c790d0fb4eb8ef8633c891d (patch) | |
tree | 3c0f4376e194916b92fec6d1e235058d51f4d347 /vm/compiler | |
parent | e664cc031abea29d3817834ce9746edbe191bcf5 (diff) | |
parent | f5ceaebfe5633a16b11a7073d2bf36b5bb0c9945 (diff) | |
download | android_dalvik-e7ce72b4e44c2ee29c790d0fb4eb8ef8633c891d.tar.gz android_dalvik-e7ce72b4e44c2ee29c790d0fb4eb8ef8633c891d.tar.bz2 android_dalvik-e7ce72b4e44c2ee29c790d0fb4eb8ef8633c891d.zip |
Merge "Jit: Rework monitor enter/exit to simplify thread suspension" into dalvik-dev
Diffstat (limited to 'vm/compiler')
-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 |
14 files changed, 339 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: |