kJitOff = 0,
kJitNormal = 1, // Profiling in mterp or running native
kJitTSelectRequest = 2, // Transition state - start trace selection
- kJitTSelect = 3, // Actively selecting trace in dbg interp
- kJitTSelectAbort = 4, // Something threw during selection - abort
- kJitTSelectEnd = 5, // Done with the trace - wrap it up
- kJitSingleStep = 6, // Single step interpretation
- kJitSingleStepEnd = 7, // Done with single step, return to mterp
- kJitSelfVerification = 8, // Self Verification Mode
+ kJitTSelectRequestHot = 3, // Transition state - start hot trace selection
+ kJitTSelect = 4, // Actively selecting trace in dbg interp
+ kJitTSelectAbort = 5, // Something threw during selection - abort
+ kJitTSelectEnd = 6, // Done with the trace - wrap it up
+ kJitSingleStep = 7, // Single step interpretation
+ kJitSingleStepEnd = 8, // Done with single step, return to mterp
+ kJitSelfVerification = 9, // Self Verification Mode
} JitState;
#if defined(WITH_SELF_VERIFICATION)
kSVSStart = 1, // Shadow space set up, running compiled code
kSVSPunt = 2, // Exiting compiled code by punting
kSVSSingleStep = 3, // Exiting compiled code by single stepping
- kSVSTraceSelect = 4, // Exiting compiled code by trace select
- kSVSNormal = 5, // Exiting compiled code normally
- kSVSNoChain = 6, // Exiting compiled code by no chain
- kSVSBackwardBranch = 7, // Exiting compiled code with backward branch trace
- kSVSDebugInterp = 8, // Normal state restored, running debug interpreter
+ kSVSTraceSelectNoChain = 4,// Exiting compiled code by trace select no chain
+ kSVSTraceSelect = 5, // Exiting compiled code by trace select
+ kSVSNormal = 6, // Exiting compiled code normally
+ kSVSNoChain = 7, // Exiting compiled code by no chain
+ kSVSBackwardBranch = 8, // Exiting compiled code with backward branch trace
+ kSVSDebugInterp = 9, // Normal state restored, running debug interpreter
} SelfVerificationState;
#endif
case kChainingCellHot:
case kChainingCellInvokeSingleton:
targetOffset = offsetof(InterpState,
- jitToInterpEntries.dvmJitToTraceSelect);
+ jitToInterpEntries.dvmJitToInterpTraceSelect);
break;
case kChainingCellInvokePredicted:
targetOffset = 0;
#if defined(WITH_SELF_VERIFICATION)
case kChainingCellBackwardBranch:
targetOffset = offsetof(InterpState,
- jitToInterpEntries.dvmJitToBackwardBranch);
+ jitToInterpEntries.dvmJitToInterpBackwardBranch);
break;
#elif defined(WITH_JIT_TUNING)
case kChainingCellBackwardBranch:
unsigned int offset)
{
loadWordDisp(cUnit, rGLUE, offsetof(InterpState,
- jitToInterpEntries.dvmJitToTraceSelect), r0);
+ jitToInterpEntries.dvmJitToInterpTraceSelect), r0);
opReg(cUnit, kOpBlx, r0);
addWordData(cUnit, (int) (cUnit->method->insns + offset), true);
}
{
#if defined(WITH_SELF_VERIFICATION)
newLIR3(cUnit, kThumbLdrRRI5, r0, rGLUE,
- offsetof(InterpState, jitToInterpEntries.dvmJitToBackwardBranch) >> 2);
+ offsetof(InterpState,
+ jitToInterpEntries.dvmJitToInterpBackwardBranch) >> 2);
#else
newLIR3(cUnit, kThumbLdrRRI5, r0, rGLUE,
offsetof(InterpState, jitToInterpEntries.dvmJitToInterpNormal) >> 2);
const Method *callee)
{
loadWordDisp(cUnit, rGLUE, offsetof(InterpState,
- jitToInterpEntries.dvmJitToTraceSelect), r0);
+ jitToInterpEntries.dvmJitToInterpTraceSelect), r0);
opReg(cUnit, kOpBlx, r0);
addWordData(cUnit, (int) (callee->insns), true);
}
bxne r2 @ yes - go ahead
@ continue executing the next instruction through the interpreter
- ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
+ ldr r1, .LdvmJitToInterpTraceSelectNoChain @ defined in footer.S
add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes)
#if defined(EXIT_STATS)
mov r0, #kCallsiteInterpreted
bxne lr @ bail to the interpreter
#endif
- ldr r10, .LdvmJitToInterpNoChain
+ ldr r10, .LdvmJitToInterpTraceSelectNoChain
ldr r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self
#if defined(EXIT_STATS)
mov r0, #kInlineCacheMiss
#endif
- mov pc, r10 @ dvmJitToInterpNoChain
+ mov pc, r10 @ dvmJitToInterpTraceSelectNoChain
bxne r2 @ yes - go ahead
@ continue executing the next instruction through the interpreter
- ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
+ ldr r1, .LdvmJitToInterpTraceSelectNoChain @ defined in footer.S
add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes)
#if defined(EXIT_STATS)
mov r0, #kCallsiteInterpreted
.align 2
.LdvmAsmInstructionStart:
.word dvmAsmInstructionStart
+.LdvmJitToInterpTraceSelectNoChain:
+ .word dvmJitToInterpTraceSelectNoChain
.LdvmJitToInterpNoChain:
.word dvmJitToInterpNoChain
.LdvmMterpStdBail:
bxne lr @ bail to the interpreter
#endif
- ldr r10, .LdvmJitToInterpNoChain
+ ldr r10, .LdvmJitToInterpTraceSelectNoChain
ldr r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self
#if defined(EXIT_STATS)
mov r0, #kInlineCacheMiss
#endif
- mov pc, r10 @ dvmJitToInterpNoChain
+ mov pc, r10 @ dvmJitToInterpTraceSelectNoChain
/* ------------------------------ */
.balign 4
bxne r2 @ yes - go ahead
@ continue executing the next instruction through the interpreter
- ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
+ ldr r1, .LdvmJitToInterpTraceSelectNoChain @ defined in footer.S
add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes)
#if defined(EXIT_STATS)
mov r0, #kCallsiteInterpreted
bxne r2 @ yes - go ahead
@ continue executing the next instruction through the interpreter
- ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
+ ldr r1, .LdvmJitToInterpTraceSelectNoChain @ defined in footer.S
add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes)
#if defined(EXIT_STATS)
mov r0, #kCallsiteInterpreted
.align 2
.LdvmAsmInstructionStart:
.word dvmAsmInstructionStart
+.LdvmJitToInterpTraceSelectNoChain:
+ .word dvmJitToInterpTraceSelectNoChain
.LdvmJitToInterpNoChain:
.word dvmJitToInterpNoChain
.LdvmMterpStdBail:
bxne lr @ bail to the interpreter
#endif
- ldr r10, .LdvmJitToInterpNoChain
+ ldr r10, .LdvmJitToInterpTraceSelectNoChain
ldr r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self
#if defined(EXIT_STATS)
mov r0, #kInlineCacheMiss
#endif
- mov pc, r10 @ dvmJitToInterpNoChain
+ mov pc, r10 @ dvmJitToInterpTraceSelectNoChain
/* ------------------------------ */
.balign 4
bxne r2 @ yes - go ahead
@ continue executing the next instruction through the interpreter
- ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
+ ldr r1, .LdvmJitToInterpTraceSelectNoChain @ defined in footer.S
add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes)
#if defined(EXIT_STATS)
mov r0, #kCallsiteInterpreted
bxne r2 @ yes - go ahead
@ continue executing the next instruction through the interpreter
- ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
+ ldr r1, .LdvmJitToInterpTraceSelectNoChain @ defined in footer.S
add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes)
#if defined(EXIT_STATS)
mov r0, #kCallsiteInterpreted
.align 2
.LdvmAsmInstructionStart:
.word dvmAsmInstructionStart
+.LdvmJitToInterpTraceSelectNoChain:
+ .word dvmJitToInterpTraceSelectNoChain
.LdvmJitToInterpNoChain:
.word dvmJitToInterpNoChain
.LdvmMterpStdBail:
bxne lr @ bail to the interpreter
#endif
- ldr r10, .LdvmJitToInterpNoChain
+ ldr r10, .LdvmJitToInterpTraceSelectNoChain
ldr r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self
#if defined(EXIT_STATS)
mov r0, #kInlineCacheMiss
#endif
- mov pc, r10 @ dvmJitToInterpNoChain
+ mov pc, r10 @ dvmJitToInterpTraceSelectNoChain
/* ------------------------------ */
.balign 4
bxne r2 @ yes - go ahead
@ continue executing the next instruction through the interpreter
- ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
+ ldr r1, .LdvmJitToInterpTraceSelectNoChain @ defined in footer.S
add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes)
#if defined(EXIT_STATS)
mov r0, #kCallsiteInterpreted
bxne r2 @ yes - go ahead
@ continue executing the next instruction through the interpreter
- ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
+ ldr r1, .LdvmJitToInterpTraceSelectNoChain @ defined in footer.S
add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes)
#if defined(EXIT_STATS)
mov r0, #kCallsiteInterpreted
.align 2
.LdvmAsmInstructionStart:
.word dvmAsmInstructionStart
+.LdvmJitToInterpTraceSelectNoChain:
+ .word dvmJitToInterpTraceSelectNoChain
.LdvmJitToInterpNoChain:
.word dvmJitToInterpNoChain
.LdvmMterpStdBail:
extern void dvmJitToInterpNoChain();
extern void dvmJitToInterpPunt();
extern void dvmJitToInterpSingleStep();
- extern void dvmJitToTraceSelect();
+ extern void dvmJitToInterpTraceSelectNoChain();
+ extern void dvmJitToInterpTraceSelect();
extern void dvmJitToPatchPredictedChain();
#if defined(WITH_SELF_VERIFICATION)
- extern void dvmJitToBackwardBranch();
+ extern void dvmJitToInterpBackwardBranch();
#endif
/*
dvmJitToInterpNoChain,
dvmJitToInterpPunt,
dvmJitToInterpSingleStep,
- dvmJitToTraceSelect,
+ dvmJitToInterpTraceSelectNoChain,
+ dvmJitToInterpTraceSelect,
dvmJitToPatchPredictedChain,
#if defined(WITH_SELF_VERIFICATION)
- dvmJitToBackwardBranch,
+ dvmJitToInterpBackwardBranch,
#endif
};
void *dvmJitToInterpNoChain;
void *dvmJitToInterpPunt;
void *dvmJitToInterpSingleStep;
- void *dvmJitToTraceSelect;
+ void *dvmJitToInterpTraceSelectNoChain;
+ void *dvmJitToInterpTraceSelect;
void *dvmJitToPatchPredictedChain;
#if defined(WITH_SELF_VERIFICATION)
- void *dvmJitToBackwardBranch;
+ void *dvmJitToInterpBackwardBranch;
#endif
};
*/
#define JIT_CALLEE_SAVE_DOUBLE_COUNT 8
-#define JIT_TRACE_THRESH_FILTER_SIZE 16
+/* Number of entries in the 2nd level JIT profiler filter cache */
+#define JIT_TRACE_THRESH_FILTER_SIZE 32
+/* Granularity of coverage (power of 2) by each cached entry */
+#define JIT_TRACE_THRESH_FILTER_GRAN_LOG2 6
#endif
/*
int currRunLen; // Length of run in 16-bit words
int lastThreshFilter;
const u2* lastPC; // Stage the PC first for the threaded interpreter
- const u2* threshFilter[JIT_TRACE_THRESH_FILTER_SIZE];
+ intptr_t threshFilter[JIT_TRACE_THRESH_FILTER_SIZE];
JitTraceRun trace[MAX_JIT_RUN_LEN];
double calleeSave[JIT_CALLEE_SAVE_DOUBLE_COUNT];
#endif
switchInterp = !debugOrProfile;
break;
case kJitTSelectRequest:
+ case kJitTSelectRequestHot:
case kJitTSelectAbort:
#if defined(SHOW_TRACE)
LOGD("TraceGen: trace abort");
{
bool res = false; /* Assume success */
int i;
+ intptr_t filterKey = ((intptr_t) interpState->pc) >>
+ JIT_TRACE_THRESH_FILTER_GRAN_LOG2;
+
/*
* If previous trace-building attempt failed, force it's head to be
* interpret-only.
*/
if (gDvmJit.pJitEntryTable != NULL) {
- /* Two-level filtering scheme */
- for (i=0; i< JIT_TRACE_THRESH_FILTER_SIZE; i++) {
- if (interpState->pc == interpState->threshFilter[i]) {
- break;
+ /* Bypass the filter for hot trace requests */
+ if (interpState->jitState != kJitTSelectRequestHot) {
+ /* Two-level filtering scheme */
+ for (i=0; i< JIT_TRACE_THRESH_FILTER_SIZE; i++) {
+ if (filterKey == interpState->threshFilter[i]) {
+ break;
+ }
+ }
+ if (i == JIT_TRACE_THRESH_FILTER_SIZE) {
+ /*
+ * Use random replacement policy - otherwise we could miss a
+ * large loop that contains more traces than the size of our
+ * filter array.
+ */
+ i = rand() % JIT_TRACE_THRESH_FILTER_SIZE;
+ interpState->threshFilter[i] = filterKey;
+ res = true;
}
- }
- if (i == JIT_TRACE_THRESH_FILTER_SIZE) {
- /*
- * Use random replacement policy - otherwise we could miss a large
- * loop that contains more traces than the size of our filter array.
- */
- i = rand() % JIT_TRACE_THRESH_FILTER_SIZE;
- interpState->threshFilter[i] = interpState->pc;
- res = true;
- }
- /* If stress mode (threshold <= 6), always translate */
- res &= (gDvmJit.threshold > 6);
+ /* If stress mode (threshold <= 6), always translate */
+ res &= (gDvmJit.threshold > 6);
+ }
/*
* If the compiler is backlogged, or if a debugger or profiler is
if (interpState->jitState != kJitOff) {
interpState->jitState = kJitNormal;
}
- } else if (interpState->jitState == kJitTSelectRequest) {
+ } else if (interpState->jitState == kJitTSelectRequest ||
+ interpState->jitState == kJitTSelectRequestHot) {
JitEntry *slot = lookupAndAdd(interpState->pc, false);
if (slot == NULL) {
/*
}
switch (interpState->jitState) {
case kJitTSelectRequest:
+ case kJitTSelectRequestHot:
interpState->jitState = kJitTSelect;
interpState->currTraceHead = interpState->pc;
interpState->currTraceRun = 0;
mov r2,#kSVSSingleStep @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
- .global dvmJitToTraceSelect
-dvmJitToTraceSelect:
+ .global dvmJitToInterpTraceSelectNoChain
+dvmJitToInterpTraceSelectNoChain:
+ mov r0,rPC @ pass our target PC
+ mov r2,#kSVSTraceSelectNoChain @ r2<- interpreter entry point
+ b dvmJitSelfVerificationEnd @ doesn't return
+
+ .global dvmJitToInterpTraceSelect
+dvmJitToInterpTraceSelect:
ldr r0,[lr, #-1] @ pass our target PC
mov r2,#kSVSTraceSelect @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
- .global dvmJitToBackwardBranch
-dvmJitToBackwardBranch:
+ .global dvmJitToInterpBackwardBranch
+dvmJitToInterpBackwardBranch:
ldr r0,[lr, #-1] @ pass our target PC
mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
mov r1,#1 @ set changeInterp to bail to debug interp
b common_gotoBail
+/*
+ * Return from the translation cache and immediately request
+ * a translation for the exit target. Commonly used for callees.
+ */
+ .global dvmJitToInterpTraceSelectNoChain
+dvmJitToInterpTraceSelectNoChain:
+#ifdef EXIT_STATS
+ bl dvmBumpNoChain
+#endif
+ ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
+ mov r0,rPC
+ bl dvmJitGetCodeAddr @ Is there a translation?
+ str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
+ mov r1, rPC @ arg1 of translation may need this
+ mov lr, #0 @ in case target is HANDLER_INTERPRET
+ cmp r0,#0
+ bxne r0 @ continue native execution if so
+ b 2f
/*
* Return from the translation cache and immediately request
* a translation for the exit target. Commonly used following
* invokes.
*/
- .global dvmJitToTraceSelect
-dvmJitToTraceSelect:
+ .global dvmJitToInterpTraceSelect
+dvmJitToInterpTraceSelect:
ldr rPC,[lr, #-1] @ get our target PC
ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
add rINST,lr,#-5 @ save start of chain branch
GET_JIT_PROF_TABLE(r0)
FETCH_INST()
cmp r0, #0
+ movne r2,#kJitTSelectRequestHot @ ask for trace selection
bne common_selectTrace
GET_INST_OPCODE(ip)
GOTO_OPCODE(ip)
cmp r0,#0
#if !defined(WITH_SELF_VERIFICATION)
bxne r0 @ jump to the translation
+ mov r2,#kJitTSelectRequest @ ask for trace selection
+ @ fall-through to common_selectTrace
#else
+ moveq r2,#kJitTSelectRequest @ ask for trace selection
beq common_selectTrace
/*
* At this point, we have a target translation. However, if
/* no return */
#endif
+/*
+ * On entry:
+ * r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
+ */
common_selectTrace:
- mov r2,#kJitTSelectRequest @ ask for trace selection
str r2,[rGLUE,#offGlue_jitState]
mov r2,#kInterpEntryInstr @ normal entry reason
str r2,[rGLUE,#offGlue_entryPoint]
#endif
#if defined(WITH_JIT)
-MTERP_CONSTANT(kJitOff, 0)
-MTERP_CONSTANT(kJitNormal, 1)
-MTERP_CONSTANT(kJitTSelectRequest, 2)
-MTERP_CONSTANT(kJitTSelect, 3)
-MTERP_CONSTANT(kJitTSelectAbort, 4)
-MTERP_CONSTANT(kJitTSelectEnd, 5)
-MTERP_CONSTANT(kJitSingleStep, 6)
-MTERP_CONSTANT(kJitSingleStepEnd, 7)
-MTERP_CONSTANT(kJitSelfVerification, 8)
+MTERP_CONSTANT(kJitOff, 0)
+MTERP_CONSTANT(kJitNormal, 1)
+MTERP_CONSTANT(kJitTSelectRequest, 2)
+MTERP_CONSTANT(kJitTSelectRequestHot, 3)
+MTERP_CONSTANT(kJitTSelect, 4)
+MTERP_CONSTANT(kJitTSelectAbort, 5)
+MTERP_CONSTANT(kJitTSelectEnd, 6)
+MTERP_CONSTANT(kJitSingleStep, 7)
+MTERP_CONSTANT(kJitSingleStepEnd, 8)
+MTERP_CONSTANT(kJitSelfVerification, 9)
#if defined(WITH_SELF_VERIFICATION)
MTERP_CONSTANT(kSVSIdle, 0)
MTERP_CONSTANT(kSVSStart, 1)
MTERP_CONSTANT(kSVSPunt, 2)
MTERP_CONSTANT(kSVSSingleStep, 3)
-MTERP_CONSTANT(kSVSTraceSelect, 4)
-MTERP_CONSTANT(kSVSNormal, 5)
-MTERP_CONSTANT(kSVSNoChain, 6)
-MTERP_CONSTANT(kSVSBackwardBranch, 7)
-MTERP_CONSTANT(kSVSDebugInterp, 8)
+MTERP_CONSTANT(kSVSTraceSelectNoChain, 4)
+MTERP_CONSTANT(kSVSTraceSelect, 5)
+MTERP_CONSTANT(kSVSNormal, 6)
+MTERP_CONSTANT(kSVSNoChain, 7)
+MTERP_CONSTANT(kSVSBackwardBranch, 8)
+MTERP_CONSTANT(kSVSDebugInterp, 9)
#endif
#endif
mov r2,#kSVSSingleStep @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
- .global dvmJitToTraceSelect
-dvmJitToTraceSelect:
+ .global dvmJitToInterpTraceSelectNoChain
+dvmJitToInterpTraceSelectNoChain:
+ mov r0,rPC @ pass our target PC
+ mov r2,#kSVSTraceSelectNoChain @ r2<- interpreter entry point
+ b dvmJitSelfVerificationEnd @ doesn't return
+
+ .global dvmJitToInterpTraceSelect
+dvmJitToInterpTraceSelect:
ldr r0,[lr, #-1] @ pass our target PC
mov r2,#kSVSTraceSelect @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
- .global dvmJitToBackwardBranch
-dvmJitToBackwardBranch:
+ .global dvmJitToInterpBackwardBranch
+dvmJitToInterpBackwardBranch:
ldr r0,[lr, #-1] @ pass our target PC
mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
mov r1,#1 @ set changeInterp to bail to debug interp
b common_gotoBail
+/*
+ * Return from the translation cache and immediately request
+ * a translation for the exit target. Commonly used for callees.
+ */
+ .global dvmJitToInterpTraceSelectNoChain
+dvmJitToInterpTraceSelectNoChain:
+#ifdef EXIT_STATS
+ bl dvmBumpNoChain
+#endif
+ ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
+ mov r0,rPC
+ bl dvmJitGetCodeAddr @ Is there a translation?
+ str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
+ mov r1, rPC @ arg1 of translation may need this
+ mov lr, #0 @ in case target is HANDLER_INTERPRET
+ cmp r0,#0
+ bxne r0 @ continue native execution if so
+ b 2f
/*
* Return from the translation cache and immediately request
* a translation for the exit target. Commonly used following
* invokes.
*/
- .global dvmJitToTraceSelect
-dvmJitToTraceSelect:
+ .global dvmJitToInterpTraceSelect
+dvmJitToInterpTraceSelect:
ldr rPC,[lr, #-1] @ get our target PC
ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
add rINST,lr,#-5 @ save start of chain branch
GET_JIT_PROF_TABLE(r0)
FETCH_INST()
cmp r0, #0
+ movne r2,#kJitTSelectRequestHot @ ask for trace selection
bne common_selectTrace
GET_INST_OPCODE(ip)
GOTO_OPCODE(ip)
cmp r0,#0
#if !defined(WITH_SELF_VERIFICATION)
bxne r0 @ jump to the translation
+ mov r2,#kJitTSelectRequest @ ask for trace selection
+ @ fall-through to common_selectTrace
#else
+ moveq r2,#kJitTSelectRequest @ ask for trace selection
beq common_selectTrace
/*
* At this point, we have a target translation. However, if
/* no return */
#endif
+/*
+ * On entry:
+ * r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
+ */
common_selectTrace:
- mov r2,#kJitTSelectRequest @ ask for trace selection
str r2,[rGLUE,#offGlue_jitState]
mov r2,#kInterpEntryInstr @ normal entry reason
str r2,[rGLUE,#offGlue_entryPoint]
mov r2,#kSVSSingleStep @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
- .global dvmJitToTraceSelect
-dvmJitToTraceSelect:
+ .global dvmJitToInterpTraceSelectNoChain
+dvmJitToInterpTraceSelectNoChain:
+ mov r0,rPC @ pass our target PC
+ mov r2,#kSVSTraceSelectNoChain @ r2<- interpreter entry point
+ b dvmJitSelfVerificationEnd @ doesn't return
+
+ .global dvmJitToInterpTraceSelect
+dvmJitToInterpTraceSelect:
ldr r0,[lr, #-1] @ pass our target PC
mov r2,#kSVSTraceSelect @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
- .global dvmJitToBackwardBranch
-dvmJitToBackwardBranch:
+ .global dvmJitToInterpBackwardBranch
+dvmJitToInterpBackwardBranch:
ldr r0,[lr, #-1] @ pass our target PC
mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
mov r1,#1 @ set changeInterp to bail to debug interp
b common_gotoBail
+/*
+ * Return from the translation cache and immediately request
+ * a translation for the exit target. Commonly used for callees.
+ */
+ .global dvmJitToInterpTraceSelectNoChain
+dvmJitToInterpTraceSelectNoChain:
+#ifdef EXIT_STATS
+ bl dvmBumpNoChain
+#endif
+ ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
+ mov r0,rPC
+ bl dvmJitGetCodeAddr @ Is there a translation?
+ str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
+ mov r1, rPC @ arg1 of translation may need this
+ mov lr, #0 @ in case target is HANDLER_INTERPRET
+ cmp r0,#0
+ bxne r0 @ continue native execution if so
+ b 2f
/*
* Return from the translation cache and immediately request
* a translation for the exit target. Commonly used following
* invokes.
*/
- .global dvmJitToTraceSelect
-dvmJitToTraceSelect:
+ .global dvmJitToInterpTraceSelect
+dvmJitToInterpTraceSelect:
ldr rPC,[lr, #-1] @ get our target PC
ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
add rINST,lr,#-5 @ save start of chain branch
GET_JIT_PROF_TABLE(r0)
FETCH_INST()
cmp r0, #0
+ movne r2,#kJitTSelectRequestHot @ ask for trace selection
bne common_selectTrace
GET_INST_OPCODE(ip)
GOTO_OPCODE(ip)
cmp r0,#0
#if !defined(WITH_SELF_VERIFICATION)
bxne r0 @ jump to the translation
+ mov r2,#kJitTSelectRequest @ ask for trace selection
+ @ fall-through to common_selectTrace
#else
+ moveq r2,#kJitTSelectRequest @ ask for trace selection
beq common_selectTrace
/*
* At this point, we have a target translation. However, if
/* no return */
#endif
+/*
+ * On entry:
+ * r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
+ */
common_selectTrace:
- mov r2,#kJitTSelectRequest @ ask for trace selection
str r2,[rGLUE,#offGlue_jitState]
mov r2,#kInterpEntryInstr @ normal entry reason
str r2,[rGLUE,#offGlue_entryPoint]
mov r2,#kSVSSingleStep @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
- .global dvmJitToTraceSelect
-dvmJitToTraceSelect:
+ .global dvmJitToInterpTraceSelectNoChain
+dvmJitToInterpTraceSelectNoChain:
+ mov r0,rPC @ pass our target PC
+ mov r2,#kSVSTraceSelectNoChain @ r2<- interpreter entry point
+ b dvmJitSelfVerificationEnd @ doesn't return
+
+ .global dvmJitToInterpTraceSelect
+dvmJitToInterpTraceSelect:
ldr r0,[lr, #-1] @ pass our target PC
mov r2,#kSVSTraceSelect @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
- .global dvmJitToBackwardBranch
-dvmJitToBackwardBranch:
+ .global dvmJitToInterpBackwardBranch
+dvmJitToInterpBackwardBranch:
ldr r0,[lr, #-1] @ pass our target PC
mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
mov r1,#1 @ set changeInterp to bail to debug interp
b common_gotoBail
+/*
+ * Return from the translation cache and immediately request
+ * a translation for the exit target. Commonly used for callees.
+ */
+ .global dvmJitToInterpTraceSelectNoChain
+dvmJitToInterpTraceSelectNoChain:
+#ifdef EXIT_STATS
+ bl dvmBumpNoChain
+#endif
+ ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
+ mov r0,rPC
+ bl dvmJitGetCodeAddr @ Is there a translation?
+ str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
+ mov r1, rPC @ arg1 of translation may need this
+ mov lr, #0 @ in case target is HANDLER_INTERPRET
+ cmp r0,#0
+ bxne r0 @ continue native execution if so
+ b 2f
/*
* Return from the translation cache and immediately request
* a translation for the exit target. Commonly used following
* invokes.
*/
- .global dvmJitToTraceSelect
-dvmJitToTraceSelect:
+ .global dvmJitToInterpTraceSelect
+dvmJitToInterpTraceSelect:
ldr rPC,[lr, #-1] @ get our target PC
ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
add rINST,lr,#-5 @ save start of chain branch
GET_JIT_PROF_TABLE(r0)
FETCH_INST()
cmp r0, #0
+ movne r2,#kJitTSelectRequestHot @ ask for trace selection
bne common_selectTrace
GET_INST_OPCODE(ip)
GOTO_OPCODE(ip)
cmp r0,#0
#if !defined(WITH_SELF_VERIFICATION)
bxne r0 @ jump to the translation
+ mov r2,#kJitTSelectRequest @ ask for trace selection
+ @ fall-through to common_selectTrace
#else
+ moveq r2,#kJitTSelectRequest @ ask for trace selection
beq common_selectTrace
/*
* At this point, we have a target translation. However, if
/* no return */
#endif
+/*
+ * On entry:
+ * r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
+ */
common_selectTrace:
- mov r2,#kJitTSelectRequest @ ask for trace selection
str r2,[rGLUE,#offGlue_jitState]
mov r2,#kInterpEntryInstr @ normal entry reason
str r2,[rGLUE,#offGlue_entryPoint]
mov r2,#kSVSSingleStep @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
- .global dvmJitToTraceSelect
-dvmJitToTraceSelect:
+ .global dvmJitToInterpTraceSelectNoChain
+dvmJitToInterpTraceSelectNoChain:
+ mov r0,rPC @ pass our target PC
+ mov r2,#kSVSTraceSelectNoChain @ r2<- interpreter entry point
+ b dvmJitSelfVerificationEnd @ doesn't return
+
+ .global dvmJitToInterpTraceSelect
+dvmJitToInterpTraceSelect:
ldr r0,[lr, #-1] @ pass our target PC
mov r2,#kSVSTraceSelect @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
- .global dvmJitToBackwardBranch
-dvmJitToBackwardBranch:
+ .global dvmJitToInterpBackwardBranch
+dvmJitToInterpBackwardBranch:
ldr r0,[lr, #-1] @ pass our target PC
mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point
b dvmJitSelfVerificationEnd @ doesn't return
mov r1,#1 @ set changeInterp to bail to debug interp
b common_gotoBail
+/*
+ * Return from the translation cache and immediately request
+ * a translation for the exit target. Commonly used for callees.
+ */
+ .global dvmJitToInterpTraceSelectNoChain
+dvmJitToInterpTraceSelectNoChain:
+#ifdef EXIT_STATS
+ bl dvmBumpNoChain
+#endif
+ ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
+ mov r0,rPC
+ bl dvmJitGetCodeAddr @ Is there a translation?
+ str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
+ mov r1, rPC @ arg1 of translation may need this
+ mov lr, #0 @ in case target is HANDLER_INTERPRET
+ cmp r0,#0
+ bxne r0 @ continue native execution if so
+ b 2f
/*
* Return from the translation cache and immediately request
* a translation for the exit target. Commonly used following
* invokes.
*/
- .global dvmJitToTraceSelect
-dvmJitToTraceSelect:
+ .global dvmJitToInterpTraceSelect
+dvmJitToInterpTraceSelect:
ldr rPC,[lr, #-1] @ get our target PC
ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
add rINST,lr,#-5 @ save start of chain branch
GET_JIT_PROF_TABLE(r0)
FETCH_INST()
cmp r0, #0
+ movne r2,#kJitTSelectRequestHot @ ask for trace selection
bne common_selectTrace
GET_INST_OPCODE(ip)
GOTO_OPCODE(ip)
cmp r0,#0
#if !defined(WITH_SELF_VERIFICATION)
bxne r0 @ jump to the translation
+ mov r2,#kJitTSelectRequest @ ask for trace selection
+ @ fall-through to common_selectTrace
#else
+ moveq r2,#kJitTSelectRequest @ ask for trace selection
beq common_selectTrace
/*
* At this point, we have a target translation. However, if
/* no return */
#endif
+/*
+ * On entry:
+ * r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
+ */
common_selectTrace:
- mov r2,#kJitTSelectRequest @ ask for trace selection
str r2,[rGLUE,#offGlue_jitState]
mov r2,#kInterpEntryInstr @ normal entry reason
str r2,[rGLUE,#offGlue_entryPoint]