OSDN Git Service

Jit: 2nd attempt at fix for [Issue 2302318] Crash during spin-on-suspend
[android-x86/dalvik.git] / vm / interp / Jit.c
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifdef WITH_JIT
17
18 /*
19  * Target independent portion of Android's Jit
20  */
21
22 #include "Dalvik.h"
23 #include "Jit.h"
24
25
26 #include "dexdump/OpCodeNames.h"
27 #include <unistd.h>
28 #include <pthread.h>
29 #include <sys/time.h>
30 #include <signal.h>
31 #include "compiler/Compiler.h"
32 #include "compiler/CompilerUtility.h"
33 #include "compiler/CompilerIR.h"
34 #include <errno.h>
35
36 #if defined(WITH_SELF_VERIFICATION)
37 /* Allocate space for per-thread ShadowSpace data structures */
38 void* dvmSelfVerificationShadowSpaceAlloc(Thread* self)
39 {
40     self->shadowSpace = (ShadowSpace*) calloc(1, sizeof(ShadowSpace));
41     if (self->shadowSpace == NULL)
42         return NULL;
43
44     self->shadowSpace->registerSpaceSize = REG_SPACE;
45     self->shadowSpace->registerSpace =
46         (int*) calloc(self->shadowSpace->registerSpaceSize, sizeof(int));
47
48     return self->shadowSpace->registerSpace;
49 }
50
51 /* Free per-thread ShadowSpace data structures */
52 void dvmSelfVerificationShadowSpaceFree(Thread* self)
53 {
54     free(self->shadowSpace->registerSpace);
55     free(self->shadowSpace);
56 }
57
58 /*
59  * Save out PC, FP, InterpState, and registers to shadow space.
60  * Return a pointer to the shadow space for JIT to use.
61  */
62 void* dvmSelfVerificationSaveState(const u2* pc, const void* fp,
63                                    InterpState* interpState, int targetTrace)
64 {
65     Thread *self = dvmThreadSelf();
66     ShadowSpace *shadowSpace = self->shadowSpace;
67     int preBytes = interpState->method->outsSize*4 + sizeof(StackSaveArea);
68     int postBytes = interpState->method->registersSize*4;
69
70     //LOGD("### selfVerificationSaveState(%d) pc: 0x%x fp: 0x%x",
71     //    self->threadId, (int)pc, (int)fp);
72
73     if (shadowSpace->selfVerificationState != kSVSIdle) {
74         LOGD("~~~ Save: INCORRECT PREVIOUS STATE(%d): %d",
75             self->threadId, shadowSpace->selfVerificationState);
76         LOGD("********** SHADOW STATE DUMP **********");
77         LOGD("PC: 0x%x FP: 0x%x", (int)pc, (int)fp);
78     }
79     shadowSpace->selfVerificationState = kSVSStart;
80
81     // Dynamically grow shadow register space if necessary
82     while (preBytes + postBytes > shadowSpace->registerSpaceSize) {
83         shadowSpace->registerSpaceSize *= 2;
84         free(shadowSpace->registerSpace);
85         shadowSpace->registerSpace =
86             (int*) calloc(shadowSpace->registerSpaceSize, sizeof(int));
87     }
88
89     // Remember original state
90     shadowSpace->startPC = pc;
91     shadowSpace->fp = fp;
92     shadowSpace->glue = interpState;
93     /*
94      * Store the original method here in case the trace ends with a
95      * return/invoke, the last method.
96      */
97     shadowSpace->method = interpState->method;
98     shadowSpace->shadowFP = shadowSpace->registerSpace +
99                             shadowSpace->registerSpaceSize - postBytes/4;
100
101     // Create a copy of the InterpState
102     //shadowSpace->interpState = *interpState;
103     memcpy(&(shadowSpace->interpState), interpState, sizeof(InterpState));
104     shadowSpace->interpState.fp = shadowSpace->shadowFP;
105     shadowSpace->interpState.interpStackEnd = (u1*)shadowSpace->registerSpace;
106
107     // Create a copy of the stack
108     memcpy(((char*)shadowSpace->shadowFP)-preBytes, ((char*)fp)-preBytes,
109         preBytes+postBytes);
110
111     // Setup the shadowed heap space
112     shadowSpace->heapSpaceTail = shadowSpace->heapSpace;
113
114     // Reset trace length
115     shadowSpace->traceLength = 0;
116
117     return shadowSpace;
118 }
119
120 /*
121  * Save ending PC, FP and compiled code exit point to shadow space.
122  * Return a pointer to the shadow space for JIT to restore state.
123  */
124 void* dvmSelfVerificationRestoreState(const u2* pc, const void* fp,
125                                       SelfVerificationState exitPoint)
126 {
127     Thread *self = dvmThreadSelf();
128     ShadowSpace *shadowSpace = self->shadowSpace;
129     shadowSpace->endPC = pc;
130     shadowSpace->endShadowFP = fp;
131
132     //LOGD("### selfVerificationRestoreState(%d) pc: 0x%x fp: 0x%x endPC: 0x%x",
133     //    self->threadId, (int)shadowSpace->startPC, (int)shadowSpace->fp,
134     //    (int)pc);
135
136     if (shadowSpace->selfVerificationState != kSVSStart) {
137         LOGD("~~~ Restore: INCORRECT PREVIOUS STATE(%d): %d",
138             self->threadId, shadowSpace->selfVerificationState);
139         LOGD("********** SHADOW STATE DUMP **********");
140         LOGD("Dalvik PC: 0x%x endPC: 0x%x", (int)shadowSpace->startPC,
141             (int)shadowSpace->endPC);
142         LOGD("Interp FP: 0x%x", (int)shadowSpace->fp);
143         LOGD("Shadow FP: 0x%x endFP: 0x%x", (int)shadowSpace->shadowFP,
144             (int)shadowSpace->endShadowFP);
145     }
146
147     // Special case when punting after a single instruction
148     if (exitPoint == kSVSPunt && pc == shadowSpace->startPC) {
149         shadowSpace->selfVerificationState = kSVSIdle;
150     } else {
151         shadowSpace->selfVerificationState = exitPoint;
152     }
153
154     return shadowSpace;
155 }
156
157 /* Print contents of virtual registers */
158 static void selfVerificationPrintRegisters(int* addr, int* addrRef,
159                                            int numWords)
160 {
161     int i;
162     for (i = 0; i < numWords; i++) {
163         LOGD("(v%d) 0x%8x%s", i, addr[i], addr[i] != addrRef[i] ? " X" : "");
164     }
165 }
166
167 /* Print values maintained in shadowSpace */
168 static void selfVerificationDumpState(const u2* pc, Thread* self)
169 {
170     ShadowSpace* shadowSpace = self->shadowSpace;
171     StackSaveArea* stackSave = SAVEAREA_FROM_FP(self->curFrame);
172     int frameBytes = (int) shadowSpace->registerSpace +
173                      shadowSpace->registerSpaceSize*4 -
174                      (int) shadowSpace->shadowFP;
175     int localRegs = 0;
176     int frameBytes2 = 0;
177     if (self->curFrame < shadowSpace->fp) {
178         localRegs = (stackSave->method->registersSize -
179                      stackSave->method->insSize)*4;
180         frameBytes2 = (int) shadowSpace->fp - (int) self->curFrame - localRegs;
181     }
182     LOGD("********** SHADOW STATE DUMP **********");
183     LOGD("CurrentPC: 0x%x, Offset: 0x%04x", (int)pc,
184         (int)(pc - stackSave->method->insns));
185     LOGD("Class: %s", shadowSpace->method->clazz->descriptor);
186     LOGD("Method: %s", shadowSpace->method->name);
187     LOGD("Dalvik PC: 0x%x endPC: 0x%x", (int)shadowSpace->startPC,
188         (int)shadowSpace->endPC);
189     LOGD("Interp FP: 0x%x endFP: 0x%x", (int)shadowSpace->fp,
190         (int)self->curFrame);
191     LOGD("Shadow FP: 0x%x endFP: 0x%x", (int)shadowSpace->shadowFP,
192         (int)shadowSpace->endShadowFP);
193     LOGD("Frame1 Bytes: %d Frame2 Local: %d Bytes: %d", frameBytes,
194         localRegs, frameBytes2);
195     LOGD("Trace length: %d State: %d", shadowSpace->traceLength,
196         shadowSpace->selfVerificationState);
197 }
198
199 /* Print decoded instructions in the current trace */
200 static void selfVerificationDumpTrace(const u2* pc, Thread* self)
201 {
202     ShadowSpace* shadowSpace = self->shadowSpace;
203     StackSaveArea* stackSave = SAVEAREA_FROM_FP(self->curFrame);
204     int i, addr, offset;
205     DecodedInstruction *decInsn;
206
207     LOGD("********** SHADOW TRACE DUMP **********");
208     for (i = 0; i < shadowSpace->traceLength; i++) {
209         addr = shadowSpace->trace[i].addr;
210         offset =  (int)((u2*)addr - stackSave->method->insns);
211         decInsn = &(shadowSpace->trace[i].decInsn);
212         /* Not properly decoding instruction, some registers may be garbage */
213         LOGD("0x%x: (0x%04x) %s", addr, offset, getOpcodeName(decInsn->opCode));
214     }
215 }
216
217 /* Code is forced into this spin loop when a divergence is detected */
218 static void selfVerificationSpinLoop(ShadowSpace *shadowSpace)
219 {
220     const u2 *startPC = shadowSpace->startPC;
221     JitTraceDescription* desc = dvmCopyTraceDescriptor(startPC);
222     if (desc) {
223         dvmCompilerWorkEnqueue(startPC, kWorkOrderTraceDebug, desc);
224     }
225     gDvmJit.selfVerificationSpin = true;
226     while(gDvmJit.selfVerificationSpin) sleep(10);
227 }
228
229 /* Manage self verification while in the debug interpreter */
230 static bool selfVerificationDebugInterp(const u2* pc, Thread* self)
231 {
232     ShadowSpace *shadowSpace = self->shadowSpace;
233     SelfVerificationState state = shadowSpace->selfVerificationState;
234
235     DecodedInstruction decInsn;
236     dexDecodeInstruction(gDvm.instrFormat, pc, &decInsn);
237
238     //LOGD("### DbgIntp(%d): PC: 0x%x endPC: 0x%x state: %d len: %d %s",
239     //    self->threadId, (int)pc, (int)shadowSpace->endPC, state,
240     //    shadowSpace->traceLength, getOpcodeName(decInsn.opCode));
241
242     if (state == kSVSIdle || state == kSVSStart) {
243         LOGD("~~~ DbgIntrp: INCORRECT PREVIOUS STATE(%d): %d",
244             self->threadId, state);
245         selfVerificationDumpState(pc, self);
246         selfVerificationDumpTrace(pc, self);
247     }
248
249     /* Skip endPC once when trace has a backward branch */
250     if ((state == kSVSBackwardBranch && pc == shadowSpace->endPC) ||
251         state != kSVSBackwardBranch) {
252         shadowSpace->selfVerificationState = kSVSDebugInterp;
253     }
254
255     /* Check that the current pc is the end of the trace */
256     if ((state == kSVSSingleStep || state == kSVSDebugInterp) &&
257         pc == shadowSpace->endPC) {
258
259         shadowSpace->selfVerificationState = kSVSIdle;
260
261         /* Check register space */
262         int frameBytes = (int) shadowSpace->registerSpace +
263                          shadowSpace->registerSpaceSize*4 -
264                          (int) shadowSpace->shadowFP;
265         if (memcmp(shadowSpace->fp, shadowSpace->shadowFP, frameBytes)) {
266             LOGD("~~~ DbgIntp(%d): REGISTERS DIVERGENCE!", self->threadId);
267             selfVerificationDumpState(pc, self);
268             selfVerificationDumpTrace(pc, self);
269             LOGD("*** Interp Registers: addr: 0x%x bytes: %d",
270                 (int)shadowSpace->fp, frameBytes);
271             selfVerificationPrintRegisters((int*)shadowSpace->fp,
272                                            (int*)shadowSpace->shadowFP,
273                                            frameBytes/4);
274             LOGD("*** Shadow Registers: addr: 0x%x bytes: %d",
275                 (int)shadowSpace->shadowFP, frameBytes);
276             selfVerificationPrintRegisters((int*)shadowSpace->shadowFP,
277                                            (int*)shadowSpace->fp,
278                                            frameBytes/4);
279             selfVerificationSpinLoop(shadowSpace);
280         }
281         /* Check new frame if it exists (invokes only) */
282         if (self->curFrame < shadowSpace->fp) {
283             StackSaveArea* stackSave = SAVEAREA_FROM_FP(self->curFrame);
284             int localRegs = (stackSave->method->registersSize -
285                              stackSave->method->insSize)*4;
286             int frameBytes2 = (int) shadowSpace->fp -
287                               (int) self->curFrame - localRegs;
288             if (memcmp(((char*)self->curFrame)+localRegs,
289                 ((char*)shadowSpace->endShadowFP)+localRegs, frameBytes2)) {
290                 LOGD("~~~ DbgIntp(%d): REGISTERS (FRAME2) DIVERGENCE!",
291                     self->threadId);
292                 selfVerificationDumpState(pc, self);
293                 selfVerificationDumpTrace(pc, self);
294                 LOGD("*** Interp Registers: addr: 0x%x l: %d bytes: %d",
295                     (int)self->curFrame, localRegs, frameBytes2);
296                 selfVerificationPrintRegisters((int*)self->curFrame,
297                                                (int*)shadowSpace->endShadowFP,
298                                                (frameBytes2+localRegs)/4);
299                 LOGD("*** Shadow Registers: addr: 0x%x l: %d bytes: %d",
300                     (int)shadowSpace->endShadowFP, localRegs, frameBytes2);
301                 selfVerificationPrintRegisters((int*)shadowSpace->endShadowFP,
302                                                (int*)self->curFrame,
303                                                (frameBytes2+localRegs)/4);
304                 selfVerificationSpinLoop(shadowSpace);
305             }
306         }
307
308         /* Check memory space */
309         bool memDiff = false;
310         ShadowHeap* heapSpacePtr;
311         for (heapSpacePtr = shadowSpace->heapSpace;
312              heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
313             int memData = *((unsigned int*) heapSpacePtr->addr);
314             if (heapSpacePtr->data != memData) {
315                 LOGD("~~~ DbgIntp(%d): MEMORY DIVERGENCE!", self->threadId);
316                 LOGD("Addr: 0x%x Intrp Data: 0x%x Jit Data: 0x%x",
317                     heapSpacePtr->addr, memData, heapSpacePtr->data);
318                 selfVerificationDumpState(pc, self);
319                 selfVerificationDumpTrace(pc, self);
320                 memDiff = true;
321             }
322         }
323         if (memDiff) selfVerificationSpinLoop(shadowSpace);
324         return true;
325
326     /* If end not been reached, make sure max length not exceeded */
327     } else if (shadowSpace->traceLength >= JIT_MAX_TRACE_LEN) {
328         LOGD("~~~ DbgIntp(%d): CONTROL DIVERGENCE!", self->threadId);
329         LOGD("startPC: 0x%x endPC: 0x%x currPC: 0x%x",
330             (int)shadowSpace->startPC, (int)shadowSpace->endPC, (int)pc);
331         selfVerificationDumpState(pc, self);
332         selfVerificationDumpTrace(pc, self);
333         selfVerificationSpinLoop(shadowSpace);
334
335         return true;
336     }
337     /* Log the instruction address and decoded instruction for debug */
338     shadowSpace->trace[shadowSpace->traceLength].addr = (int)pc;
339     shadowSpace->trace[shadowSpace->traceLength].decInsn = decInsn;
340     shadowSpace->traceLength++;
341
342     return false;
343 }
344 #endif
345
346 int dvmJitStartup(void)
347 {
348     unsigned int i;
349     bool res = true;  /* Assume success */
350
351 #if defined(WITH_SELF_VERIFICATION)
352     // Force JIT into blocking, translate everything mode
353     gDvmJit.threshold = 1;
354     gDvmJit.blockingMode = true;
355 #endif
356
357     // Create the compiler thread and setup miscellaneous chores */
358     res &= dvmCompilerStartup();
359
360     dvmInitMutex(&gDvmJit.tableLock);
361     if (res && gDvm.executionMode == kExecutionModeJit) {
362         JitEntry *pJitTable = NULL;
363         unsigned char *pJitProfTable = NULL;
364         // Power of 2?
365         assert(gDvmJit.jitTableSize &&
366                !(gDvmJit.jitTableSize & (gDvmJit.jitTableSize - 1)));
367         dvmLockMutex(&gDvmJit.tableLock);
368         pJitTable = (JitEntry*)
369                     calloc(gDvmJit.jitTableSize, sizeof(*pJitTable));
370         if (!pJitTable) {
371             LOGE("jit table allocation failed\n");
372             res = false;
373             goto done;
374         }
375         /*
376          * NOTE: the profile table must only be allocated once, globally.
377          * Profiling is turned on and off by nulling out gDvm.pJitProfTable
378          * and then restoring its original value.  However, this action
379          * is not syncronized for speed so threads may continue to hold
380          * and update the profile table after profiling has been turned
381          * off by null'ng the global pointer.  Be aware.
382          */
383         pJitProfTable = (unsigned char *)malloc(JIT_PROF_SIZE);
384         if (!pJitProfTable) {
385             LOGE("jit prof table allocation failed\n");
386             res = false;
387             goto done;
388         }
389         memset(pJitProfTable,gDvmJit.threshold,JIT_PROF_SIZE);
390         for (i=0; i < gDvmJit.jitTableSize; i++) {
391            pJitTable[i].u.info.chain = gDvmJit.jitTableSize;
392         }
393         /* Is chain field wide enough for termination pattern? */
394         assert(pJitTable[0].u.info.chain == gDvmJit.jitTableSize);
395
396 done:
397         gDvmJit.pJitEntryTable = pJitTable;
398         gDvmJit.jitTableMask = gDvmJit.jitTableSize - 1;
399         gDvmJit.jitTableEntriesUsed = 0;
400         gDvmJit.pProfTableCopy = gDvmJit.pProfTable = pJitProfTable;
401         dvmUnlockMutex(&gDvmJit.tableLock);
402     }
403     return res;
404 }
405
406 /*
407  * If one of our fixed tables or the translation buffer fills up,
408  * call this routine to avoid wasting cycles on future translation requests.
409  */
410 void dvmJitStopTranslationRequests()
411 {
412     /*
413      * Note 1: This won't necessarily stop all translation requests, and
414      * operates on a delayed mechanism.  Running threads look to the copy
415      * of this value in their private InterpState structures and won't see
416      * this change until it is refreshed (which happens on interpreter
417      * entry).
418      * Note 2: This is a one-shot memory leak on this table. Because this is a
419      * permanent off switch for Jit profiling, it is a one-time leak of 1K
420      * bytes, and no further attempt will be made to re-allocate it.  Can't
421      * free it because some thread may be holding a reference.
422      */
423     gDvmJit.pProfTable = gDvmJit.pProfTableCopy = NULL;
424 }
425
426 #if defined(EXIT_STATS)
427 /* Convenience function to increment counter from assembly code */
428 void dvmBumpNoChain(int from)
429 {
430     gDvmJit.noChainExit[from]++;
431 }
432
433 /* Convenience function to increment counter from assembly code */
434 void dvmBumpNormal()
435 {
436     gDvmJit.normalExit++;
437 }
438
439 /* Convenience function to increment counter from assembly code */
440 void dvmBumpPunt(int from)
441 {
442     gDvmJit.puntExit++;
443 }
444 #endif
445
446 /* Dumps debugging & tuning stats to the log */
447 void dvmJitStats()
448 {
449     int i;
450     int hit;
451     int not_hit;
452     int chains;
453     int stubs;
454     if (gDvmJit.pJitEntryTable) {
455         for (i=0, stubs=chains=hit=not_hit=0;
456              i < (int) gDvmJit.jitTableSize;
457              i++) {
458             if (gDvmJit.pJitEntryTable[i].dPC != 0) {
459                 hit++;
460                 if (gDvmJit.pJitEntryTable[i].codeAddress ==
461                       gDvmJit.interpretTemplate)
462                     stubs++;
463             } else
464                 not_hit++;
465             if (gDvmJit.pJitEntryTable[i].u.info.chain != gDvmJit.jitTableSize)
466                 chains++;
467         }
468         LOGD(
469          "JIT: %d traces, %d slots, %d chains, %d maxQ, %d thresh, %s",
470          hit, not_hit + hit, chains, gDvmJit.compilerMaxQueued,
471          gDvmJit.threshold, gDvmJit.blockingMode ? "Blocking" : "Non-blocking");
472 #if defined(EXIT_STATS)
473         LOGD(
474          "JIT: Lookups: %d hits, %d misses; %d normal, %d punt",
475          gDvmJit.addrLookupsFound, gDvmJit.addrLookupsNotFound,
476          gDvmJit.normalExit, gDvmJit.puntExit);
477         LOGD(
478          "JIT: noChainExit: %d IC miss, %d interp callsite, %d switch overflow",
479          gDvmJit.noChainExit[kInlineCacheMiss],
480          gDvmJit.noChainExit[kCallsiteInterpreted],
481          gDvmJit.noChainExit[kSwitchOverflow]);
482 #endif
483         LOGD("JIT: %d Translation chains, %d interp stubs",
484              gDvmJit.translationChains, stubs);
485 #if defined(INVOKE_STATS)
486         LOGD("JIT: Invoke: %d chainable, %d pred. chain, %d native, "
487              "%d return",
488              gDvmJit.invokeChain, gDvmJit.invokePredictedChain,
489              gDvmJit.invokeNative, gDvmJit.returnOp);
490 #endif
491         if (gDvmJit.profile) {
492             dvmCompilerSortAndPrintTraceProfiles();
493         }
494     }
495 }
496
497
498 /*
499  * Final JIT shutdown.  Only do this once, and do not attempt to restart
500  * the JIT later.
501  */
502 void dvmJitShutdown(void)
503 {
504     /* Shutdown the compiler thread */
505
506     dvmCompilerShutdown();
507
508     dvmCompilerDumpStats();
509
510     dvmDestroyMutex(&gDvmJit.tableLock);
511
512     if (gDvmJit.pJitEntryTable) {
513         free(gDvmJit.pJitEntryTable);
514         gDvmJit.pJitEntryTable = NULL;
515     }
516
517     if (gDvmJit.pProfTable) {
518         free(gDvmJit.pProfTable);
519         gDvmJit.pProfTable = NULL;
520     }
521 }
522
523 void setTraceConstruction(JitEntry *slot, bool value)
524 {
525
526     JitEntryInfoUnion oldValue;
527     JitEntryInfoUnion newValue;
528     do {
529         oldValue = slot->u;
530         newValue = oldValue;
531         newValue.info.traceConstruction = value;
532     } while (!ATOMIC_CMP_SWAP( &slot->u.infoWord,
533              oldValue.infoWord, newValue.infoWord));
534 }
535
536 void resetTracehead(InterpState* interpState, JitEntry *slot)
537 {
538     slot->codeAddress = gDvmJit.interpretTemplate;
539     setTraceConstruction(slot, false);
540 }
541
542 /* Clean up any pending trace builds */
543 void dvmJitAbortTraceSelect(InterpState* interpState)
544 {
545     if (interpState->jitState == kJitTSelect)
546         interpState->jitState = kJitTSelectAbort;
547 }
548
549 #if defined(WITH_SELF_VERIFICATION)
550 static bool selfVerificationPuntOps(DecodedInstruction *decInsn)
551 {
552     OpCode op = decInsn->opCode;
553     int flags =  dexGetInstrFlags(gDvm.instrFlags, op);
554     return (op == OP_MONITOR_ENTER || op == OP_MONITOR_EXIT ||
555             op == OP_NEW_INSTANCE || op == OP_NEW_ARRAY ||
556             op == OP_CHECK_CAST || op == OP_MOVE_EXCEPTION ||
557             (flags & kInstrInvoke));
558 }
559 #endif
560
561 /*
562  * Adds to the current trace request one instruction at a time, just
563  * before that instruction is interpreted.  This is the primary trace
564  * selection function.  NOTE: return instruction are handled a little
565  * differently.  In general, instructions are "proposed" to be added
566  * to the current trace prior to interpretation.  If the interpreter
567  * then successfully completes the instruction, is will be considered
568  * part of the request.  This allows us to examine machine state prior
569  * to interpretation, and also abort the trace request if the instruction
570  * throws or does something unexpected.  However, return instructions
571  * will cause an immediate end to the translation request - which will
572  * be passed to the compiler before the return completes.  This is done
573  * in response to special handling of returns by the interpreter (and
574  * because returns cannot throw in a way that causes problems for the
575  * translated code.
576  */
577 int dvmCheckJit(const u2* pc, Thread* self, InterpState* interpState)
578 {
579     int flags,i,len;
580     int switchInterp = false;
581     int debugOrProfile = (gDvm.debuggerActive || self->suspendCount
582 #if defined(WITH_PROFILER)
583                           || gDvm.activeProfilers
584 #endif
585             );
586
587     /* Prepare to handle last PC and stage the current PC */
588     const u2 *lastPC = interpState->lastPC;
589     interpState->lastPC = pc;
590
591 #if defined(WITH_SELF_VERIFICATION)
592     /*
593      * We can't allow some instructions to be executed twice, and so they
594      * must not appear in any translations.  End the trace before they
595      * are inlcluded.
596      */
597     if (lastPC && interpState->jitState == kJitTSelect) {
598         DecodedInstruction decInsn;
599         dexDecodeInstruction(gDvm.instrFormat, lastPC, &decInsn);
600         if (selfVerificationPuntOps(&decInsn)) {
601             interpState->jitState = kJitTSelectEnd;
602         }
603     }
604 #endif
605
606     switch (interpState->jitState) {
607         char* nopStr;
608         int target;
609         int offset;
610         DecodedInstruction decInsn;
611         case kJitTSelect:
612             /* First instruction - just remember the PC and exit */
613             if (lastPC == NULL) break;
614             /* Grow the trace around the last PC if jitState is kJitTSelect */
615             dexDecodeInstruction(gDvm.instrFormat, lastPC, &decInsn);
616
617             /*
618              * Treat {PACKED,SPARSE}_SWITCH as trace-ending instructions due
619              * to the amount of space it takes to generate the chaining
620              * cells.
621              */
622             if (interpState->totalTraceLen != 0 &&
623                 (decInsn.opCode == OP_PACKED_SWITCH ||
624                  decInsn.opCode == OP_SPARSE_SWITCH)) {
625                 interpState->jitState = kJitTSelectEnd;
626                 break;
627             }
628
629
630 #if defined(SHOW_TRACE)
631             LOGD("TraceGen: adding %s",getOpcodeName(decInsn.opCode));
632 #endif
633             flags = dexGetInstrFlags(gDvm.instrFlags, decInsn.opCode);
634             len = dexGetInstrOrTableWidthAbs(gDvm.instrWidth, lastPC);
635             offset = lastPC - interpState->method->insns;
636             assert((unsigned) offset <
637                    dvmGetMethodInsnsSize(interpState->method));
638             if (lastPC != interpState->currRunHead + interpState->currRunLen) {
639                 int currTraceRun;
640                 /* We need to start a new trace run */
641                 currTraceRun = ++interpState->currTraceRun;
642                 interpState->currRunLen = 0;
643                 interpState->currRunHead = (u2*)lastPC;
644                 interpState->trace[currTraceRun].frag.startOffset = offset;
645                 interpState->trace[currTraceRun].frag.numInsts = 0;
646                 interpState->trace[currTraceRun].frag.runEnd = false;
647                 interpState->trace[currTraceRun].frag.hint = kJitHintNone;
648             }
649             interpState->trace[interpState->currTraceRun].frag.numInsts++;
650             interpState->totalTraceLen++;
651             interpState->currRunLen += len;
652
653             /* Will probably never hit this with the current trace buildier */
654             if (interpState->currTraceRun == (MAX_JIT_RUN_LEN - 1)) {
655                 interpState->jitState = kJitTSelectEnd;
656             }
657
658             if (  ((flags & kInstrUnconditional) == 0) &&
659                   /* don't end trace on INVOKE_DIRECT_EMPTY  */
660                   (decInsn.opCode != OP_INVOKE_DIRECT_EMPTY) &&
661                   ((flags & (kInstrCanBranch |
662                              kInstrCanSwitch |
663                              kInstrCanReturn |
664                              kInstrInvoke)) != 0)) {
665                     interpState->jitState = kJitTSelectEnd;
666 #if defined(SHOW_TRACE)
667             LOGD("TraceGen: ending on %s, basic block end",
668                  getOpcodeName(decInsn.opCode));
669 #endif
670             }
671             /* Break on throw or self-loop */
672             if ((decInsn.opCode == OP_THROW) || (lastPC == pc)){
673                 interpState->jitState = kJitTSelectEnd;
674             }
675             if (interpState->totalTraceLen >= JIT_MAX_TRACE_LEN) {
676                 interpState->jitState = kJitTSelectEnd;
677             }
678             if (debugOrProfile) {
679                 interpState->jitState = kJitTSelectAbort;
680                 switchInterp = !debugOrProfile;
681                 break;
682             }
683             if ((flags & kInstrCanReturn) != kInstrCanReturn) {
684                 break;
685             }
686             /* NOTE: intentional fallthrough for returns */
687         case kJitTSelectEnd:
688             {
689                 if (interpState->totalTraceLen == 0) {
690                     /* Bad trace - mark as untranslatable */
691                     dvmJitAbortTraceSelect(interpState);
692                     switchInterp = !debugOrProfile;
693                     break;
694                 }
695                 JitTraceDescription* desc =
696                    (JitTraceDescription*)malloc(sizeof(JitTraceDescription) +
697                      sizeof(JitTraceRun) * (interpState->currTraceRun+1));
698                 if (desc == NULL) {
699                     LOGE("Out of memory in trace selection");
700                     dvmJitStopTranslationRequests();
701                     interpState->jitState = kJitTSelectAbort;
702                     dvmJitAbortTraceSelect(interpState);
703                     switchInterp = !debugOrProfile;
704                     break;
705                 }
706                 interpState->trace[interpState->currTraceRun].frag.runEnd =
707                      true;
708                 interpState->jitState = kJitNormal;
709                 desc->method = interpState->method;
710                 memcpy((char*)&(desc->trace[0]),
711                     (char*)&(interpState->trace[0]),
712                     sizeof(JitTraceRun) * (interpState->currTraceRun+1));
713 #if defined(SHOW_TRACE)
714                 LOGD("TraceGen:  trace done, adding to queue");
715 #endif
716                 dvmCompilerWorkEnqueue(
717                        interpState->currTraceHead,kWorkOrderTrace,desc);
718                 setTraceConstruction(
719                      dvmJitLookupAndAdd(interpState->currTraceHead), false);
720                 if (gDvmJit.blockingMode) {
721                     dvmCompilerDrainQueue();
722                 }
723                 switchInterp = !debugOrProfile;
724             }
725             break;
726         case kJitSingleStep:
727             interpState->jitState = kJitSingleStepEnd;
728             break;
729         case kJitSingleStepEnd:
730             interpState->entryPoint = kInterpEntryResume;
731             switchInterp = !debugOrProfile;
732             break;
733         case kJitTSelectAbort:
734 #if defined(SHOW_TRACE)
735             LOGD("TraceGen:  trace abort");
736 #endif
737             dvmJitAbortTraceSelect(interpState);
738             interpState->jitState = kJitNormal;
739             switchInterp = !debugOrProfile;
740             break;
741         case kJitNormal:
742             switchInterp = !debugOrProfile;
743             break;
744 #if defined(WITH_SELF_VERIFICATION)
745         case kJitSelfVerification:
746             if (selfVerificationDebugInterp(pc, self)) {
747                 interpState->jitState = kJitNormal;
748                 switchInterp = !debugOrProfile;
749             }
750             break;
751 #endif
752         /* If JIT is off stay out of interpreter selections */
753         case kJitOff:
754             break;
755         default:
756             if (!debugOrProfile) {
757                 LOGE("Unexpected JIT state: %d", interpState->jitState);
758                 dvmAbort();
759             }
760             break;
761     }
762     return switchInterp;
763 }
764
765 JitEntry *dvmFindJitEntry(const u2* pc)
766 {
767     int idx = dvmJitHash(pc);
768
769     /* Expect a high hit rate on 1st shot */
770     if (gDvmJit.pJitEntryTable[idx].dPC == pc)
771         return &gDvmJit.pJitEntryTable[idx];
772     else {
773         int chainEndMarker = gDvmJit.jitTableSize;
774         while (gDvmJit.pJitEntryTable[idx].u.info.chain != chainEndMarker) {
775             idx = gDvmJit.pJitEntryTable[idx].u.info.chain;
776             if (gDvmJit.pJitEntryTable[idx].dPC == pc)
777                 return &gDvmJit.pJitEntryTable[idx];
778         }
779     }
780     return NULL;
781 }
782
783 /*
784  * If a translated code address exists for the davik byte code
785  * pointer return it.  This routine needs to be fast.
786  */
787 void* dvmJitGetCodeAddr(const u2* dPC)
788 {
789     int idx = dvmJitHash(dPC);
790
791     /* If anything is suspended, don't re-enter the code cache */
792     if (gDvm.sumThreadSuspendCount > 0) {
793         return NULL;
794     }
795
796     /* Expect a high hit rate on 1st shot */
797     if (gDvmJit.pJitEntryTable[idx].dPC == dPC) {
798 #if defined(EXIT_STATS)
799         gDvmJit.addrLookupsFound++;
800 #endif
801         return gDvmJit.pJitEntryTable[idx].codeAddress;
802     } else {
803         int chainEndMarker = gDvmJit.jitTableSize;
804         while (gDvmJit.pJitEntryTable[idx].u.info.chain != chainEndMarker) {
805             idx = gDvmJit.pJitEntryTable[idx].u.info.chain;
806             if (gDvmJit.pJitEntryTable[idx].dPC == dPC) {
807 #if defined(EXIT_STATS)
808                 gDvmJit.addrLookupsFound++;
809 #endif
810                 return gDvmJit.pJitEntryTable[idx].codeAddress;
811             }
812         }
813     }
814 #if defined(EXIT_STATS)
815     gDvmJit.addrLookupsNotFound++;
816 #endif
817     return NULL;
818 }
819
820 /*
821  * Find an entry in the JitTable, creating if necessary.
822  * Returns null if table is full.
823  */
824 JitEntry *dvmJitLookupAndAdd(const u2* dPC)
825 {
826     u4 chainEndMarker = gDvmJit.jitTableSize;
827     u4 idx = dvmJitHash(dPC);
828
829     /* Walk the bucket chain to find an exact match for our PC */
830     while ((gDvmJit.pJitEntryTable[idx].u.info.chain != chainEndMarker) &&
831            (gDvmJit.pJitEntryTable[idx].dPC != dPC)) {
832         idx = gDvmJit.pJitEntryTable[idx].u.info.chain;
833     }
834
835     if (gDvmJit.pJitEntryTable[idx].dPC != dPC) {
836         /*
837          * No match.  Aquire jitTableLock and find the last
838          * slot in the chain. Possibly continue the chain walk in case
839          * some other thread allocated the slot we were looking
840          * at previuosly (perhaps even the dPC we're trying to enter).
841          */
842         dvmLockMutex(&gDvmJit.tableLock);
843         /*
844          * At this point, if .dPC is NULL, then the slot we're
845          * looking at is the target slot from the primary hash
846          * (the simple, and common case).  Otherwise we're going
847          * to have to find a free slot and chain it.
848          */
849         MEM_BARRIER(); /* Make sure we reload [].dPC after lock */
850         if (gDvmJit.pJitEntryTable[idx].dPC != NULL) {
851             u4 prev;
852             while (gDvmJit.pJitEntryTable[idx].u.info.chain != chainEndMarker) {
853                 if (gDvmJit.pJitEntryTable[idx].dPC == dPC) {
854                     /* Another thread got there first for this dPC */
855                     dvmUnlockMutex(&gDvmJit.tableLock);
856                     return &gDvmJit.pJitEntryTable[idx];
857                 }
858                 idx = gDvmJit.pJitEntryTable[idx].u.info.chain;
859             }
860             /* Here, idx should be pointing to the last cell of an
861              * active chain whose last member contains a valid dPC */
862             assert(gDvmJit.pJitEntryTable[idx].dPC != NULL);
863             /* Linear walk to find a free cell and add it to the end */
864             prev = idx;
865             while (true) {
866                 idx++;
867                 if (idx == chainEndMarker)
868                     idx = 0;  /* Wraparound */
869                 if ((gDvmJit.pJitEntryTable[idx].dPC == NULL) ||
870                     (idx == prev))
871                     break;
872             }
873             if (idx != prev) {
874                 JitEntryInfoUnion oldValue;
875                 JitEntryInfoUnion newValue;
876                 /*
877                  * Although we hold the lock so that noone else will
878                  * be trying to update a chain field, the other fields
879                  * packed into the word may be in use by other threads.
880                  */
881                 do {
882                     oldValue = gDvmJit.pJitEntryTable[prev].u;
883                     newValue = oldValue;
884                     newValue.info.chain = idx;
885                 } while (!ATOMIC_CMP_SWAP(
886                          &gDvmJit.pJitEntryTable[prev].u.infoWord,
887                          oldValue.infoWord, newValue.infoWord));
888             }
889         }
890         if (gDvmJit.pJitEntryTable[idx].dPC == NULL) {
891             /*
892              * Initialize codeAddress and allocate the slot.  Must
893              * happen in this order (ince dPC is set, the entry is live.
894              */
895             gDvmJit.pJitEntryTable[idx].dPC = dPC;
896             gDvmJit.jitTableEntriesUsed++;
897         } else {
898             /* Table is full */
899             idx = chainEndMarker;
900         }
901         dvmUnlockMutex(&gDvmJit.tableLock);
902     }
903     return (idx == chainEndMarker) ? NULL : &gDvmJit.pJitEntryTable[idx];
904 }
905 /*
906  * Register the translated code pointer into the JitTable.
907  * NOTE: Once a codeAddress field transitions from initial state to
908  * JIT'd code, it must not be altered without first halting all
909  * threads.  This routine should only be called by the compiler
910  * thread.
911  */
912 void dvmJitSetCodeAddr(const u2* dPC, void *nPC, JitInstructionSetType set) {
913     JitEntryInfoUnion oldValue;
914     JitEntryInfoUnion newValue;
915     JitEntry *jitEntry = dvmJitLookupAndAdd(dPC);
916     assert(jitEntry);
917     /* Note: order of update is important */
918     do {
919         oldValue = jitEntry->u;
920         newValue = oldValue;
921         newValue.info.instructionSet = set;
922     } while (!ATOMIC_CMP_SWAP(
923              &jitEntry->u.infoWord,
924              oldValue.infoWord, newValue.infoWord));
925     jitEntry->codeAddress = nPC;
926 }
927
928 /*
929  * Determine if valid trace-bulding request is active.  Return true
930  * if we need to abort and switch back to the fast interpreter, false
931  * otherwise.  NOTE: may be called even when trace selection is not being
932  * requested
933  */
934 bool dvmJitCheckTraceRequest(Thread* self, InterpState* interpState)
935 {
936     bool res = false;         /* Assume success */
937     int i;
938     /*
939      * If previous trace-building attempt failed, force it's head to be
940      * interpret-only.
941      */
942     if (gDvmJit.pJitEntryTable != NULL) {
943         /* Two-level filtering scheme */
944         for (i=0; i< JIT_TRACE_THRESH_FILTER_SIZE; i++) {
945             if (interpState->pc == interpState->threshFilter[i]) {
946                 break;
947             }
948         }
949         if (i == JIT_TRACE_THRESH_FILTER_SIZE) {
950             /*
951              * Use random replacement policy - otherwise we could miss a large
952              * loop that contains more traces than the size of our filter array.
953              */
954             i = rand() % JIT_TRACE_THRESH_FILTER_SIZE;
955             interpState->threshFilter[i] = interpState->pc;
956             res = true;
957         }
958
959         /* If stress mode (threshold <= 6), always translate */
960         res &= (gDvmJit.threshold > 6);
961
962         /*
963          * If the compiler is backlogged, or if a debugger or profiler is
964          * active, cancel any JIT actions
965          */
966         if (res || (gDvmJit.compilerQueueLength >= gDvmJit.compilerHighWater)
967             || gDvm.debuggerActive || self->suspendCount
968 #if defined(WITH_PROFILER)
969                  || gDvm.activeProfilers
970 #endif
971                                              ) {
972             if (interpState->jitState != kJitOff) {
973                 interpState->jitState = kJitNormal;
974             }
975         } else if (interpState->jitState == kJitTSelectRequest) {
976             JitEntry *slot = dvmJitLookupAndAdd(interpState->pc);
977             if (slot == NULL) {
978                 /*
979                  * Table is full.  This should have been
980                  * detected by the compiler thread and the table
981                  * resized before we run into it here.  Assume bad things
982                  * are afoot and disable profiling.
983                  */
984                 interpState->jitState = kJitTSelectAbort;
985                 LOGD("JIT: JitTable full, disabling profiling");
986                 dvmJitStopTranslationRequests();
987             } else if (slot->u.info.traceConstruction) {
988                 /*
989                  * Trace already request in progress, but most likely it
990                  * aborted without cleaning up.  Assume the worst and
991                  * mark trace head as untranslatable.  If we're wrong,
992                  * the compiler thread will correct the entry when the
993                  * translation is completed.  The downside here is that
994                  * some existing translation may chain to the interpret-only
995                  * template instead of the real translation during this
996                  * window.  Performance, but not correctness, issue.
997                  */
998                 interpState->jitState = kJitTSelectAbort;
999                 resetTracehead(interpState, slot);
1000             } else if (slot->codeAddress) {
1001                  /* Nothing to do here - just return */
1002                 interpState->jitState = kJitTSelectAbort;
1003             } else {
1004                 /*
1005                  * Mark request.  Note, we are not guaranteed exclusivity
1006                  * here.  A window exists for another thread to be
1007                  * attempting to build this same trace.  Rather than
1008                  * bear the cost of locking, we'll just allow that to
1009                  * happen.  The compiler thread, if it chooses, can
1010                  * discard redundant requests.
1011                  */
1012                 setTraceConstruction(slot, true);
1013             }
1014         }
1015         switch (interpState->jitState) {
1016             case kJitTSelectRequest:
1017                  interpState->jitState = kJitTSelect;
1018                  interpState->currTraceHead = interpState->pc;
1019                  interpState->currTraceRun = 0;
1020                  interpState->totalTraceLen = 0;
1021                  interpState->currRunHead = interpState->pc;
1022                  interpState->currRunLen = 0;
1023                  interpState->trace[0].frag.startOffset =
1024                        interpState->pc - interpState->method->insns;
1025                  interpState->trace[0].frag.numInsts = 0;
1026                  interpState->trace[0].frag.runEnd = false;
1027                  interpState->trace[0].frag.hint = kJitHintNone;
1028                  interpState->lastPC = 0;
1029                  break;
1030             case kJitTSelect:
1031             case kJitTSelectAbort:
1032                  res = true;
1033             case kJitSingleStep:
1034             case kJitSingleStepEnd:
1035             case kJitOff:
1036             case kJitNormal:
1037 #if defined(WITH_SELF_VERIFICATION)
1038             case kJitSelfVerification:
1039 #endif
1040                 break;
1041             default:
1042                 LOGE("Unexpected JIT state: %d", interpState->jitState);
1043                 dvmAbort();
1044         }
1045     }
1046     return res;
1047 }
1048
1049 /*
1050  * Resizes the JitTable.  Must be a power of 2, and returns true on failure.
1051  * Stops all threads, and thus is a heavyweight operation.
1052  */
1053 bool dvmJitResizeJitTable( unsigned int size )
1054 {
1055     JitEntry *pNewTable;
1056     JitEntry *pOldTable;
1057     u4 newMask;
1058     unsigned int oldSize;
1059     unsigned int i;
1060
1061     assert(gDvmJit.pJitEntryTable != NULL);
1062     assert(size && !(size & (size - 1)));   /* Is power of 2? */
1063
1064     LOGD("Jit: resizing JitTable from %d to %d", gDvmJit.jitTableSize, size);
1065
1066     newMask = size - 1;
1067
1068     if (size <= gDvmJit.jitTableSize) {
1069         return true;
1070     }
1071
1072     pNewTable = (JitEntry*)calloc(size, sizeof(*pNewTable));
1073     if (pNewTable == NULL) {
1074         return true;
1075     }
1076     for (i=0; i< size; i++) {
1077         pNewTable[i].u.info.chain = size;  /* Initialize chain termination */
1078     }
1079
1080     /* Stop all other interpreting/jit'ng threads */
1081     dvmSuspendAllThreads(SUSPEND_FOR_TBL_RESIZE);
1082
1083     pOldTable = gDvmJit.pJitEntryTable;
1084     oldSize = gDvmJit.jitTableSize;
1085
1086     dvmLockMutex(&gDvmJit.tableLock);
1087     gDvmJit.pJitEntryTable = pNewTable;
1088     gDvmJit.jitTableSize = size;
1089     gDvmJit.jitTableMask = size - 1;
1090     gDvmJit.jitTableEntriesUsed = 0;
1091     dvmUnlockMutex(&gDvmJit.tableLock);
1092
1093     for (i=0; i < oldSize; i++) {
1094         if (pOldTable[i].dPC) {
1095             JitEntry *p;
1096             u2 chain;
1097             p = dvmJitLookupAndAdd(pOldTable[i].dPC);
1098             p->dPC = pOldTable[i].dPC;
1099             /*
1100              * Compiler thread may have just updated the new entry's
1101              * code address field, so don't blindly copy null.
1102              */
1103             if (pOldTable[i].codeAddress != NULL) {
1104                 p->codeAddress = pOldTable[i].codeAddress;
1105             }
1106             /* We need to preserve the new chain field, but copy the rest */
1107             dvmLockMutex(&gDvmJit.tableLock);
1108             chain = p->u.info.chain;
1109             p->u = pOldTable[i].u;
1110             p->u.info.chain = chain;
1111             dvmUnlockMutex(&gDvmJit.tableLock);
1112         }
1113     }
1114
1115     free(pOldTable);
1116
1117     /* Restart the world */
1118     dvmResumeAllThreads(SUSPEND_FOR_TBL_RESIZE);
1119
1120     return false;
1121 }
1122
1123 /*
1124  * Float/double conversion requires clamping to min and max of integer form.  If
1125  * target doesn't support this normally, use these.
1126  */
1127 s8 dvmJitd2l(double d)
1128 {
1129     static const double kMaxLong = (double)(s8)0x7fffffffffffffffULL;
1130     static const double kMinLong = (double)(s8)0x8000000000000000ULL;
1131     if (d >= kMaxLong)
1132         return (s8)0x7fffffffffffffffULL;
1133     else if (d <= kMinLong)
1134         return (s8)0x8000000000000000ULL;
1135     else if (d != d) // NaN case
1136         return 0;
1137     else
1138         return (s8)d;
1139 }
1140
1141 s8 dvmJitf2l(float f)
1142 {
1143     static const float kMaxLong = (float)(s8)0x7fffffffffffffffULL;
1144     static const float kMinLong = (float)(s8)0x8000000000000000ULL;
1145     if (f >= kMaxLong)
1146         return (s8)0x7fffffffffffffffULL;
1147     else if (f <= kMinLong)
1148         return (s8)0x8000000000000000ULL;
1149     else if (f != f) // NaN case
1150         return 0;
1151     else
1152         return (s8)f;
1153 }
1154
1155
1156 #endif /* WITH_JIT */