From f9f33287693f9f9aa44318036b8aab627bd21a32 Mon Sep 17 00:00:00 2001 From: Bill Buzbee Date: Sun, 22 Nov 2009 12:45:30 -0800 Subject: [PATCH] Jit: Misc fixes, move_exception, blocking mode, self-cosim OP_MOVE_EXCEPTION handler was neglecting to reset. Blocking mode was failing to signal empty queue in some cases Self-cosim was including operations in traces that can't be done twice Added OP_MOVE_EXCEPTION to self cosim's no-replay ops (it has side effects) Restored threshold of 1 to self-cosim (now able to boot device with self-cosim) When threshold < 6, disable 2nd-level translation filter --- vm/compiler/Compiler.c | 3 +++ vm/compiler/codegen/arm/CodegenDriver.c | 15 +++---------- vm/interp/Jit.c | 38 +++++++++++++++++++++++++++------ 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/vm/compiler/Compiler.c b/vm/compiler/Compiler.c index b53ebf8df..5787378d2 100644 --- a/vm/compiler/Compiler.c +++ b/vm/compiler/Compiler.c @@ -38,6 +38,9 @@ static CompilerWorkOrder workDequeue(void) gDvmJit.compilerWorkDequeueIndex = 0; } gDvmJit.compilerQueueLength--; + if (gDvmJit.compilerQueueLength == 0) { + int cc = pthread_cond_signal(&gDvmJit.compilerQueueEmpty); + } /* Remember the high water mark of the queue length */ if (gDvmJit.compilerQueueLength > gDvmJit.compilerMaxQueued) diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c index 857536f48..35460ed01 100644 --- a/vm/compiler/codegen/arm/CodegenDriver.c +++ b/vm/compiler/codegen/arm/CodegenDriver.c @@ -208,13 +208,6 @@ static bool genConversionPortable(CompilationUnit *cUnit, MIR *mir) } #if defined(WITH_SELF_VERIFICATION) -/* Prevent certain opcodes from being jitted */ -static inline bool selfVerificationPuntOps(OpCode op) -{ - return (op == OP_MONITOR_ENTER || op == OP_MONITOR_EXIT || - op == OP_NEW_INSTANCE || op == OP_NEW_ARRAY); -} - /* * The following are used to keep compiled loads and stores from modifying * memory during self verification mode. @@ -2048,10 +2041,13 @@ static bool handleFmt11x(CompilationUnit *cUnit, MIR *mir) int offset = offsetof(InterpState, self); int exOffset = offsetof(Thread, exception); int selfReg = allocTemp(cUnit); + int resetReg = allocTemp(cUnit); RegLocation rlDest = getDestLoc(cUnit, mir, 0); rlResult = evalLoc(cUnit, rlDest, kCoreReg, true); loadWordDisp(cUnit, rGLUE, offset, selfReg); + loadConstant(cUnit, resetReg, 0); loadWordDisp(cUnit, selfReg, exOffset, rlResult.lowReg); + storeWordDisp(cUnit, selfReg, exOffset, resetReg); storeValue(cUnit, rlDest, rlResult); break; } @@ -3882,11 +3878,6 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit) ((gDvmJit.opList[dalvikOpCode >> 3] & (1 << (dalvikOpCode & 0x7))) != 0); -#if defined(WITH_SELF_VERIFICATION) - /* Punt on opcodes we can't replay */ - if (selfVerificationPuntOps(dalvikOpCode)) - singleStepMe = true; -#endif if (singleStepMe || cUnit->allSingleStep) { notHandled = false; genInterpSingleStep(cUnit, mir); diff --git a/vm/interp/Jit.c b/vm/interp/Jit.c index 018a77f87..69cfdf2f3 100644 --- a/vm/interp/Jit.c +++ b/vm/interp/Jit.c @@ -350,11 +350,7 @@ int dvmJitStartup(void) #if defined(WITH_SELF_VERIFICATION) // Force JIT into blocking, translate everything mode - /* - * FIXME - * Cannot boot to home with threshold 1 - * gDvmJit.threshold = 1; - */ + gDvmJit.threshold = 1; gDvmJit.blockingMode = true; #endif @@ -550,6 +546,18 @@ void dvmJitAbortTraceSelect(InterpState* interpState) interpState->jitState = kJitTSelectAbort; } +#if defined(WITH_SELF_VERIFICATION) +static bool selfVerificationPuntOps(DecodedInstruction *decInsn) +{ + OpCode op = decInsn->opCode; + int flags = dexGetInstrFlags(gDvm.instrFlags, op); + return (op == OP_MONITOR_ENTER || op == OP_MONITOR_EXIT || + op == OP_NEW_INSTANCE || op == OP_NEW_ARRAY || + op == OP_CHECK_CAST || op == OP_MOVE_EXCEPTION || + (flags & kInstrInvoke)); +} +#endif + /* * Adds to the current trace request one instruction at a time, just * before that instruction is interpreted. This is the primary trace @@ -580,6 +588,21 @@ int dvmCheckJit(const u2* pc, Thread* self, InterpState* interpState) const u2 *lastPC = interpState->lastPC; interpState->lastPC = pc; +#if defined(WITH_SELF_VERIFICATION) + /* + * We can't allow some instructions to be executed twice, and so they + * must not appear in any translations. End the trace before they + * are inlcluded. + */ + if (lastPC && interpState->jitState == kJitTSelect) { + DecodedInstruction decInsn; + dexDecodeInstruction(gDvm.instrFormat, lastPC, &decInsn); + if (selfVerificationPuntOps(&decInsn)) { + interpState->jitState = kJitTSelectEnd; + } + } +#endif + switch (interpState->jitState) { char* nopStr; int target; @@ -603,6 +626,7 @@ int dvmCheckJit(const u2* pc, Thread* self, InterpState* interpState) break; } + #if defined(SHOW_TRACE) LOGD("TraceGen: adding %s",getOpcodeName(decInsn.opCode)); #endif @@ -931,8 +955,8 @@ bool dvmJitCheckTraceRequest(Thread* self, InterpState* interpState) res = true; } - /* If stress mode (threshold==1), always translate */ - res &= (gDvmJit.threshold != 1); + /* If stress mode (threshold <= 6), always translate */ + res &= (gDvmJit.threshold > 6); /* * If the compiler is backlogged, or if a debugger or profiler is -- 2.11.0