Merge change Id726991b
* changes:
Jit stress mode: translate everything we can and self verify.
diff --git a/vm/Init.c b/vm/Init.c
index 7f83bc5..f77dba6 100644
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -114,8 +114,8 @@
dvmFprintf(stderr, " -Xjitop:hexopvalue[-endvalue]"
"[,hexopvalue[-endvalue]]*\n");
dvmFprintf(stderr, " -Xincludeselectedmethod\n");
- dvmFprintf(stderr, " -Xthreshold:decimalvalue\n");
- dvmFprintf(stderr, " -Xblocking\n");
+ dvmFprintf(stderr, " -Xjitthreshold:decimalvalue\n");
+ dvmFprintf(stderr, " -Xjitblocking\n");
dvmFprintf(stderr, " -Xjitmethod:signture[,signature]* "
"(eg Ljava/lang/String\\;replace)\n");
dvmFprintf(stderr, " -Xjitverbose\n");
@@ -899,10 +899,10 @@
processXjitop(argv[i]);
} else if (strncmp(argv[i], "-Xjitmethod", 11) == 0) {
processXjitmethod(argv[i]);
- } else if (strncmp(argv[i], "-Xblocking", 10) == 0) {
+ } else if (strncmp(argv[i], "-Xjitblocking", 13) == 0) {
gDvmJit.blockingMode = true;
- } else if (strncmp(argv[i], "-Xthreshold:", 12) == 0) {
- gDvmJit.threshold = atoi(argv[i] + 12);
+ } else if (strncmp(argv[i], "-Xjitthreshold:", 15) == 0) {
+ gDvmJit.threshold = atoi(argv[i] + 15);
} else if (strncmp(argv[i], "-Xincludeselectedop", 19) == 0) {
gDvmJit.includeSelectedOp = true;
} else if (strncmp(argv[i], "-Xincludeselectedmethod", 23) == 0) {
diff --git a/vm/compiler/Compiler.c b/vm/compiler/Compiler.c
index a44e1c3..b53ebf8 100644
--- a/vm/compiler/Compiler.c
+++ b/vm/compiler/Compiler.c
@@ -96,11 +96,13 @@
/* Block until queue length is 0 */
void dvmCompilerDrainQueue(void)
{
+ int oldStatus = dvmChangeStatus(NULL, THREAD_VMWAIT);
dvmLockMutex(&gDvmJit.compilerLock);
while (workQueueLength() != 0 && !gDvmJit.haltCompilerThread) {
pthread_cond_wait(&gDvmJit.compilerQueueEmpty, &gDvmJit.compilerLock);
}
dvmUnlockMutex(&gDvmJit.compilerLock);
+ dvmChangeStatus(NULL, oldStatus);
}
static void *compilerThreadStart(void *arg)
@@ -135,11 +137,12 @@
if (gDvmJit.haltCompilerThread) {
LOGD("Compiler shutdown in progress - discarding request");
} else {
- /* Compilation is successful */
- if (dvmCompilerDoWork(&work)) {
- dvmJitSetCodeAddr(work.pc, work.result.codeAddress,
- work.result.instructionSet);
+ /* If compilation failed, use interpret-template */
+ if (!dvmCompilerDoWork(&work)) {
+ work.result.codeAddress = gDvmJit.interpretTemplate;
}
+ dvmJitSetCodeAddr(work.pc, work.result.codeAddress,
+ work.result.instructionSet);
}
free(work.info);
dvmLockMutex(&gDvmJit.compilerLock);
diff --git a/vm/compiler/codegen/arm/armv7-a/ArchVariant.c b/vm/compiler/codegen/arm/armv7-a/ArchVariant.c
index 02b9b79..a2e4175 100644
--- a/vm/compiler/codegen/arm/armv7-a/ArchVariant.c
+++ b/vm/compiler/codegen/arm/armv7-a/ArchVariant.c
@@ -323,6 +323,7 @@
if (isDouble) {
rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg);
rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
+ clobberSReg(cUnit, rlDest.sRegLow);
rlResult = evalLoc(cUnit, rlDest, kCoreReg, true);
loadConstant(cUnit, rlResult.lowReg, defaultResult);
newLIR2(cUnit, kThumb2Vcmpd, S2D(rlSrc1.lowReg, r1Src2.highReg),
@@ -330,6 +331,7 @@
} else {
rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg);
rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg);
+ clobberSReg(cUnit, rlDest.sRegLow);
rlResult = evalLoc(cUnit, rlDest, kCoreReg, true);
loadConstant(cUnit, rlResult.lowReg, defaultResult);
newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg);
diff --git a/vm/interp/InterpDefs.h b/vm/interp/InterpDefs.h
index 41a2bb8..744033e 100644
--- a/vm/interp/InterpDefs.h
+++ b/vm/interp/InterpDefs.h
@@ -150,7 +150,7 @@
JitState jitState;
void* jitResume;
u2* jitResumePC;
- const u2* jitTraceInProgress;
+ int jitThreshold;
#endif
#if defined(WITH_PROFILER) || defined(WITH_DEBUGGER)
diff --git a/vm/interp/Jit.c b/vm/interp/Jit.c
index d9b9caa..4c09979 100644
--- a/vm/interp/Jit.c
+++ b/vm/interp/Jit.c
@@ -348,6 +348,12 @@
unsigned int i;
bool res = true; /* Assume success */
+#if defined(WITH_SELF_VERIFICATION)
+ // Force JIT into blocking, translate everything mode
+ gDvmJit.threshold = 1;
+ gDvmJit.blockingMode = true;
+#endif
+
// Create the compiler thread and setup miscellaneous chores */
res &= dvmCompilerStartup();
@@ -380,7 +386,7 @@
res = false;
goto done;
}
- memset(pJitProfTable,0,JIT_PROF_SIZE);
+ memset(pJitProfTable,gDvmJit.threshold,JIT_PROF_SIZE);
for (i=0; i < gDvmJit.jitTableSize; i++) {
pJitTable[i].u.info.chain = gDvmJit.jitTableSize;
}
@@ -514,6 +520,32 @@
}
}
+void setTraceConstruction(JitEntry *slot, bool value)
+{
+
+ JitEntryInfoUnion oldValue;
+ JitEntryInfoUnion newValue;
+ do {
+ oldValue = slot->u;
+ newValue = oldValue;
+ newValue.info.traceConstruction = value;
+ } while (!ATOMIC_CMP_SWAP( &slot->u.infoWord,
+ oldValue.infoWord, newValue.infoWord));
+}
+
+void resetTracehead(InterpState* interpState, JitEntry *slot)
+{
+ slot->codeAddress = gDvmJit.interpretTemplate;
+ setTraceConstruction(slot, false);
+}
+
+/* Clean up any pending trace builds */
+void dvmJitAbortTraceSelect(InterpState* interpState)
+{
+ if (interpState->jitState == kJitTSelect)
+ interpState->jitState = kJitTSelectAbort;
+}
+
/*
* Adds to the current trace request one instruction at a time, just
* before that instruction is interpreted. This is the primary trace
@@ -539,6 +571,7 @@
|| gDvm.activeProfilers
#endif
);
+
/* Prepare to handle last PC and stage the current PC */
const u2 *lastPC = interpState->lastPC;
interpState->lastPC = pc;
@@ -625,6 +658,8 @@
case kJitTSelectEnd:
{
if (interpState->totalTraceLen == 0) {
+ /* Bad trace - mark as untranslatable */
+ dvmJitAbortTraceSelect(interpState);
switchInterp = !debugOrProfile;
break;
}
@@ -635,6 +670,7 @@
LOGE("Out of memory in trace selection");
dvmJitStopTranslationRequests();
interpState->jitState = kJitTSelectAbort;
+ dvmJitAbortTraceSelect(interpState);
switchInterp = !debugOrProfile;
break;
}
@@ -650,7 +686,8 @@
#endif
dvmCompilerWorkEnqueue(
interpState->currTraceHead,kWorkOrderTrace,desc);
- interpState->jitTraceInProgress = NULL;
+ setTraceConstruction(
+ dvmJitLookupAndAdd(interpState->currTraceHead), false);
if (gDvmJit.blockingMode) {
dvmCompilerDrainQueue();
}
@@ -668,6 +705,7 @@
#if defined(SHOW_TRACE)
LOGD("TraceGen: trace abort");
#endif
+ dvmJitAbortTraceSelect(interpState);
interpState->jitState = kJitNormal;
switchInterp = !debugOrProfile;
break;
@@ -864,7 +902,6 @@
* otherwise. NOTE: may be called even when trace selection is not being
* requested
*/
-
bool dvmJitCheckTraceRequest(Thread* self, InterpState* interpState)
{
bool res = false; /* Assume success */
@@ -873,11 +910,6 @@
* If previous trace-building attempt failed, force it's head to be
* interpret-only.
*/
- if (interpState->jitTraceInProgress) {
- JitEntry *slot = dvmJitLookupAndAdd(interpState->jitTraceInProgress);
- slot->codeAddress = gDvmJit.interpretTemplate;
- interpState->jitTraceInProgress = NULL;
- }
if (gDvmJit.pJitEntryTable != NULL) {
/* Two-level filtering scheme */
for (i=0; i< JIT_TRACE_THRESH_FILTER_SIZE; i++) {
@@ -894,6 +926,10 @@
interpState->threshFilter[i] = interpState->pc;
res = true;
}
+
+ /* If stress mode (threshold==1), always translate */
+ res &= (gDvmJit.threshold != 1);
+
/*
* If the compiler is backlogged, or if a debugger or profiler is
* active, cancel any JIT actions
@@ -919,26 +955,38 @@
interpState->jitState = kJitTSelectAbort;
LOGD("JIT: JitTable full, disabling profiling");
dvmJitStopTranslationRequests();
- } else if (slot->u.info.traceRequested) {
- /* Trace already requested - revert to interpreter */
+ } else if (slot->u.info.traceConstruction) {
+ /*
+ * Trace already request in progress, but most likely it
+ * aborted without cleaning up. Assume the worst and
+ * mark trace head as untranslatable. If we're wrong,
+ * the compiler thread will correct the entry when the
+ * translation is completed. The downside here is that
+ * some existing translation may chain to the interpret-only
+ * template instead of the real translation during this
+ * window. Performance, but not correctness, issue.
+ */
+ interpState->jitState = kJitTSelectAbort;
+ resetTracehead(interpState, slot);
+ } else if (slot->codeAddress) {
+ /* Nothing to do here - just return */
interpState->jitState = kJitTSelectAbort;
} else {
- /* Mark request */
- JitEntryInfoUnion oldValue;
- JitEntryInfoUnion newValue;
- do {
- oldValue = slot->u;
- newValue = oldValue;
- newValue.info.traceRequested = true;
- } while (!ATOMIC_CMP_SWAP( &slot->u.infoWord,
- oldValue.infoWord, newValue.infoWord));
+ /*
+ * Mark request. Note, we are not guaranteed exclusivity
+ * here. A window exists for another thread to be
+ * attempting to build this same trace. Rather than
+ * bear the cost of locking, we'll just allow that to
+ * happen. The compiler thread, if it chooses, can
+ * discard redundant requests.
+ */
+ setTraceConstruction(slot, true);
}
}
switch (interpState->jitState) {
case kJitTSelectRequest:
interpState->jitState = kJitTSelect;
interpState->currTraceHead = interpState->pc;
- interpState->jitTraceInProgress = interpState->pc;
interpState->currTraceRun = 0;
interpState->totalTraceLen = 0;
interpState->currRunHead = interpState->pc;
diff --git a/vm/interp/Jit.h b/vm/interp/Jit.h
index a69a1f0..b093164 100644
--- a/vm/interp/Jit.h
+++ b/vm/interp/Jit.h
@@ -89,13 +89,13 @@
*/
typedef struct JitEntryInfo {
- unsigned int traceRequested:1; /* already requested a translation */
+ unsigned int traceConstruction:1; /* build underway? */
unsigned int isMethodEntry:1;
unsigned int inlineCandidate:1;
unsigned int profileEnabled:1;
JitInstructionSetType instructionSet:4;
unsigned int unused:8;
- u2 chain; /* Index of next in chain */
+ u2 chain; /* Index of next in chain */
} JitEntryInfo;
typedef union JitEntryInfoUnion {
@@ -122,6 +122,8 @@
s8 dvmJitd2l(double d);
s8 dvmJitf2l(float f);
void dvmJitSetCodeAddr(const u2* dPC, void *nPC, JitInstructionSetType set);
+void dvmJitAbortTraceSelect(InterpState* interpState);
+JitEntry *dvmJitLookupAndAdd(const u2* dPC);
#endif /*_DALVIK_INTERP_JIT*/
diff --git a/vm/mterp/Mterp.c b/vm/mterp/Mterp.c
index 053f544..dbae516 100644
--- a/vm/mterp/Mterp.c
+++ b/vm/mterp/Mterp.c
@@ -83,6 +83,7 @@
glue->pSelfSuspendCount = &self->suspendCount;
#if defined(WITH_JIT)
glue->pJitProfTable = gDvmJit.pProfTable;
+ glue->jitThreshold = gDvmJit.threshold;
#endif
#if defined(WITH_DEBUGGER)
glue->pDebuggerActive = &gDvm.debuggerActive;
diff --git a/vm/mterp/armv5te/footer.S b/vm/mterp/armv5te/footer.S
index e6c6cfc..317f151 100644
--- a/vm/mterp/armv5te/footer.S
+++ b/vm/mterp/armv5te/footer.S
@@ -209,7 +209,7 @@
* is already a native translation in place (and, if so,
* jump to it now).
*/
- mov r1,#255
+ GET_JIT_THRESHOLD(r1)
strb r1,[r0,r3,lsr #23] @ reset counter
EXPORT_PC()
mov r0,rPC
diff --git a/vm/mterp/armv5te/header.S b/vm/mterp/armv5te/header.S
index e129b15..78b2282 100644
--- a/vm/mterp/armv5te/header.S
+++ b/vm/mterp/armv5te/header.S
@@ -180,6 +180,7 @@
#if defined(WITH_JIT)
#define GET_JIT_ENABLED(_reg) ldr _reg,[rGLUE,#offGlue_jitEnabled]
#define GET_JIT_PROF_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitProfTable]
+#define GET_JIT_THRESHOLD(_reg) ldr _reg,[rGLUE,#offGlue_jitThreshold]
#endif
/*
diff --git a/vm/mterp/c/gotoTargets.c b/vm/mterp/c/gotoTargets.c
index 67b3299..1bf188f 100644
--- a/vm/mterp/c/gotoTargets.c
+++ b/vm/mterp/c/gotoTargets.c
@@ -532,6 +532,10 @@
if (dvmIsBreakFrame(fp)) {
/* bail without popping the method frame from stack */
LOGVV("+++ returned into break frame\n");
+#if defined(WITH_JIT)
+ /* Let the Jit know the return is terminating normally */
+ CHECK_JIT();
+#endif
GOTO_bail();
}
@@ -578,9 +582,7 @@
#if defined(WITH_JIT)
// Something threw during trace selection - abort the current trace
- if (interpState->jitState == kJitTSelect) {
- interpState->jitState = kJitTSelectEnd;
- }
+ dvmJitAbortTraceSelect(interpState);
#endif
/*
* We save off the exception and clear the exception status. While
@@ -892,6 +894,11 @@
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
+#if defined(WITH_JIT)
+ /* Allow the Jit to end any pending trace building */
+ CHECK_JIT();
+#endif
+
/*
* Jump through native call bridge. Because we leave no
* space for locals on native calls, "newFp" points directly
diff --git a/vm/mterp/common/asm-constants.h b/vm/mterp/common/asm-constants.h
index baf6af7..f982793 100644
--- a/vm/mterp/common/asm-constants.h
+++ b/vm/mterp/common/asm-constants.h
@@ -106,6 +106,7 @@
MTERP_OFFSET(offGlue_jitState, MterpGlue, jitState, 60)
MTERP_OFFSET(offGlue_jitResume, MterpGlue, jitResume, 64)
MTERP_OFFSET(offGlue_jitResumePC, MterpGlue, jitResumePC, 68)
+MTERP_OFFSET(offGlue_jitThreshold, MterpGlue, jitThreshold, 72)
#endif
#elif defined(WITH_DEBUGGER)
MTERP_OFFSET(offGlue_pDebuggerActive, MterpGlue, pDebuggerActive, 40)
@@ -115,6 +116,7 @@
MTERP_OFFSET(offGlue_jitState, MterpGlue, jitState, 56)
MTERP_OFFSET(offGlue_jitResume, MterpGlue, jitResume, 60)
MTERP_OFFSET(offGlue_jitResumePC, MterpGlue, jitResumePC, 64)
+MTERP_OFFSET(offGlue_jitThreshold, MterpGlue, jitThreshold, 68)
#endif
#elif defined(WITH_PROFILER)
MTERP_OFFSET(offGlue_pActiveProfilers, MterpGlue, pActiveProfilers, 40)
@@ -124,6 +126,7 @@
MTERP_OFFSET(offGlue_jitState, MterpGlue, jitState, 56)
MTERP_OFFSET(offGlue_jitResume, MterpGlue, jitResume, 60)
MTERP_OFFSET(offGlue_jitResumePC, MterpGlue, jitResumePC, 64)
+MTERP_OFFSET(offGlue_jitThreshold, MterpGlue, jitThreshold, 68)
#endif
#else
MTERP_OFFSET(offGlue_entryPoint, MterpGlue, entryPoint, 40)
@@ -132,6 +135,7 @@
MTERP_OFFSET(offGlue_jitState, MterpGlue, jitState, 52)
MTERP_OFFSET(offGlue_jitResume, MterpGlue, jitResume, 56)
MTERP_OFFSET(offGlue_jitResumePC, MterpGlue, jitResumePC, 60)
+MTERP_OFFSET(offGlue_jitThreshold, MterpGlue, jitThreshold, 64)
#endif
#endif
/* make sure all JValue union members are stored at the same offset */
diff --git a/vm/mterp/out/InterpAsm-armv4t.S b/vm/mterp/out/InterpAsm-armv4t.S
index f1729eb..56d0a26 100644
--- a/vm/mterp/out/InterpAsm-armv4t.S
+++ b/vm/mterp/out/InterpAsm-armv4t.S
@@ -187,6 +187,7 @@
#if defined(WITH_JIT)
#define GET_JIT_ENABLED(_reg) ldr _reg,[rGLUE,#offGlue_jitEnabled]
#define GET_JIT_PROF_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitProfTable]
+#define GET_JIT_THRESHOLD(_reg) ldr _reg,[rGLUE,#offGlue_jitThreshold]
#endif
/*
@@ -9681,7 +9682,7 @@
* is already a native translation in place (and, if so,
* jump to it now).
*/
- mov r1,#255
+ GET_JIT_THRESHOLD(r1)
strb r1,[r0,r3,lsr #23] @ reset counter
EXPORT_PC()
mov r0,rPC
diff --git a/vm/mterp/out/InterpAsm-armv5te-vfp.S b/vm/mterp/out/InterpAsm-armv5te-vfp.S
index 5cf8cca..c7926f6 100644
--- a/vm/mterp/out/InterpAsm-armv5te-vfp.S
+++ b/vm/mterp/out/InterpAsm-armv5te-vfp.S
@@ -187,6 +187,7 @@
#if defined(WITH_JIT)
#define GET_JIT_ENABLED(_reg) ldr _reg,[rGLUE,#offGlue_jitEnabled]
#define GET_JIT_PROF_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitProfTable]
+#define GET_JIT_THRESHOLD(_reg) ldr _reg,[rGLUE,#offGlue_jitThreshold]
#endif
/*
@@ -9199,7 +9200,7 @@
* is already a native translation in place (and, if so,
* jump to it now).
*/
- mov r1,#255
+ GET_JIT_THRESHOLD(r1)
strb r1,[r0,r3,lsr #23] @ reset counter
EXPORT_PC()
mov r0,rPC
diff --git a/vm/mterp/out/InterpAsm-armv5te.S b/vm/mterp/out/InterpAsm-armv5te.S
index 5e1ed1c..3c5c496 100644
--- a/vm/mterp/out/InterpAsm-armv5te.S
+++ b/vm/mterp/out/InterpAsm-armv5te.S
@@ -187,6 +187,7 @@
#if defined(WITH_JIT)
#define GET_JIT_ENABLED(_reg) ldr _reg,[rGLUE,#offGlue_jitEnabled]
#define GET_JIT_PROF_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitProfTable]
+#define GET_JIT_THRESHOLD(_reg) ldr _reg,[rGLUE,#offGlue_jitThreshold]
#endif
/*
@@ -9675,7 +9676,7 @@
* is already a native translation in place (and, if so,
* jump to it now).
*/
- mov r1,#255
+ GET_JIT_THRESHOLD(r1)
strb r1,[r0,r3,lsr #23] @ reset counter
EXPORT_PC()
mov r0,rPC
diff --git a/vm/mterp/out/InterpAsm-armv7-a.S b/vm/mterp/out/InterpAsm-armv7-a.S
index 7af0a79..aaf85d9 100644
--- a/vm/mterp/out/InterpAsm-armv7-a.S
+++ b/vm/mterp/out/InterpAsm-armv7-a.S
@@ -187,6 +187,7 @@
#if defined(WITH_JIT)
#define GET_JIT_ENABLED(_reg) ldr _reg,[rGLUE,#offGlue_jitEnabled]
#define GET_JIT_PROF_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitProfTable]
+#define GET_JIT_THRESHOLD(_reg) ldr _reg,[rGLUE,#offGlue_jitThreshold]
#endif
/*
@@ -9135,7 +9136,7 @@
* is already a native translation in place (and, if so,
* jump to it now).
*/
- mov r1,#255
+ GET_JIT_THRESHOLD(r1)
strb r1,[r0,r3,lsr #23] @ reset counter
EXPORT_PC()
mov r0,rPC
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index 1d31227..04d7c32 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -3565,6 +3565,10 @@
if (dvmIsBreakFrame(fp)) {
/* bail without popping the method frame from stack */
LOGVV("+++ returned into break frame\n");
+#if defined(WITH_JIT)
+ /* Let the Jit know the return is terminating normally */
+ CHECK_JIT();
+#endif
GOTO_bail();
}
@@ -3611,9 +3615,7 @@
#if defined(WITH_JIT)
// Something threw during trace selection - abort the current trace
- if (interpState->jitState == kJitTSelect) {
- interpState->jitState = kJitTSelectEnd;
- }
+ dvmJitAbortTraceSelect(interpState);
#endif
/*
* We save off the exception and clear the exception status. While
@@ -3925,6 +3927,11 @@
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
+#if defined(WITH_JIT)
+ /* Allow the Jit to end any pending trace building */
+ CHECK_JIT();
+#endif
+
/*
* Jump through native call bridge. Because we leave no
* space for locals on native calls, "newFp" points directly
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index 03fe00e..4d15b45 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -3863,6 +3863,10 @@
if (dvmIsBreakFrame(fp)) {
/* bail without popping the method frame from stack */
LOGVV("+++ returned into break frame\n");
+#if defined(WITH_JIT)
+ /* Let the Jit know the return is terminating normally */
+ CHECK_JIT();
+#endif
GOTO_bail();
}
@@ -3909,9 +3913,7 @@
#if defined(WITH_JIT)
// Something threw during trace selection - abort the current trace
- if (interpState->jitState == kJitTSelect) {
- interpState->jitState = kJitTSelectEnd;
- }
+ dvmJitAbortTraceSelect(interpState);
#endif
/*
* We save off the exception and clear the exception status. While
@@ -4223,6 +4225,11 @@
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
+#if defined(WITH_JIT)
+ /* Allow the Jit to end any pending trace building */
+ CHECK_JIT();
+#endif
+
/*
* Jump through native call bridge. Because we leave no
* space for locals on native calls, "newFp" points directly
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index a092da0..6ea6a56 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -3579,6 +3579,10 @@
if (dvmIsBreakFrame(fp)) {
/* bail without popping the method frame from stack */
LOGVV("+++ returned into break frame\n");
+#if defined(WITH_JIT)
+ /* Let the Jit know the return is terminating normally */
+ CHECK_JIT();
+#endif
GOTO_bail();
}
@@ -3625,9 +3629,7 @@
#if defined(WITH_JIT)
// Something threw during trace selection - abort the current trace
- if (interpState->jitState == kJitTSelect) {
- interpState->jitState = kJitTSelectEnd;
- }
+ dvmJitAbortTraceSelect(interpState);
#endif
/*
* We save off the exception and clear the exception status. While
@@ -3939,6 +3941,11 @@
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
+#if defined(WITH_JIT)
+ /* Allow the Jit to end any pending trace building */
+ CHECK_JIT();
+#endif
+
/*
* Jump through native call bridge. Because we leave no
* space for locals on native calls, "newFp" points directly
diff --git a/vm/mterp/out/InterpC-x86.c b/vm/mterp/out/InterpC-x86.c
index fa2dfa8..ed42355 100644
--- a/vm/mterp/out/InterpC-x86.c
+++ b/vm/mterp/out/InterpC-x86.c
@@ -1720,6 +1720,10 @@
if (dvmIsBreakFrame(fp)) {
/* bail without popping the method frame from stack */
LOGVV("+++ returned into break frame\n");
+#if defined(WITH_JIT)
+ /* Let the Jit know the return is terminating normally */
+ CHECK_JIT();
+#endif
GOTO_bail();
}
@@ -1766,9 +1770,7 @@
#if defined(WITH_JIT)
// Something threw during trace selection - abort the current trace
- if (interpState->jitState == kJitTSelect) {
- interpState->jitState = kJitTSelectEnd;
- }
+ dvmJitAbortTraceSelect(interpState);
#endif
/*
* We save off the exception and clear the exception status. While
@@ -2080,6 +2082,11 @@
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
methodToCall->name, methodToCall->shorty);
+#if defined(WITH_JIT)
+ /* Allow the Jit to end any pending trace building */
+ CHECK_JIT();
+#endif
+
/*
* Jump through native call bridge. Because we leave no
* space for locals on native calls, "newFp" points directly