summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen/arm/Thumb2
diff options
context:
space:
mode:
authorBill Buzbee <buzbee@google.com>2010-02-02 11:04:33 -0800
committerBill Buzbee <buzbee@google.com>2010-02-03 14:47:49 -0800
commitf5ceaebfe5633a16b11a7073d2bf36b5bb0c9945 (patch)
tree5502cdcbf8742846adeb33c060e57e9baa12ec44 /vm/compiler/codegen/arm/Thumb2
parent5043da6f678448f6111d1a0dcc584f5adf01b526 (diff)
downloadandroid_dalvik-f5ceaebfe5633a16b11a7073d2bf36b5bb0c9945.tar.gz
android_dalvik-f5ceaebfe5633a16b11a7073d2bf36b5bb0c9945.tar.bz2
android_dalvik-f5ceaebfe5633a16b11a7073d2bf36b5bb0c9945.zip
Jit: Rework monitor enter/exit to simplify thread suspension
The Jit must stop all threads in order to flush the translation cache (and other tables). Threads which are blocked in a monitor wait cause some headache here because they effectively hold a references to the translation cache (though the return address on the native stack). The new model introduced in this CL is that for the fast path of monitor enter, control is allowed to resume in the translation cache. However, if we need to do a heavyweight lock (which may cause us to block) control does not return to the translation cache but instead bails out to the interpreter. This allows us to safely clear the code cache even if some threads are in THREAD_MONITOR state.
Diffstat (limited to 'vm/compiler/codegen/arm/Thumb2')
-rw-r--r--vm/compiler/codegen/arm/Thumb2/Gen.c32
1 files changed, 18 insertions, 14 deletions
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);