1 /*
2 * Main interpreter loop.
3 *
4 * This was written with an ARM implementation in mind.
5 */
INTERP_FUNC_NAME(Thread * self,InterpState * interpState)6 bool INTERP_FUNC_NAME(Thread* self, InterpState* interpState)
7 {
8 #if defined(EASY_GDB)
9 StackSaveArea* debugSaveArea = SAVEAREA_FROM_FP(self->curFrame);
10 #endif
11 #if INTERP_TYPE == INTERP_DBG
12 bool debugIsMethodEntry = interpState->debugIsMethodEntry;
13 #endif
14 #if defined(WITH_TRACKREF_CHECKS)
15 int debugTrackedRefStart = interpState->debugTrackedRefStart;
16 #endif
17 DvmDex* methodClassDex; // curMethod->clazz->pDvmDex
18 JValue retval;
19
20 /* core state */
21 const Method* curMethod; // method we're interpreting
22 const u2* pc; // program counter
23 u4* fp; // frame pointer
24 u2 inst; // current instruction
25 /* instruction decoding */
26 u2 ref; // 16-bit quantity fetched directly
27 u2 vsrc1, vsrc2, vdst; // usually used for register indexes
28 /* method call setup */
29 const Method* methodToCall;
30 bool methodCallRange;
31
32
33 #if defined(THREADED_INTERP)
34 /* static computed goto table */
35 DEFINE_GOTO_TABLE(handlerTable);
36 #endif
37
38 #if defined(WITH_JIT)
39 #if 0
40 LOGD("*DebugInterp - entrypoint is %d, tgt is 0x%x, %s\n",
41 interpState->entryPoint,
42 interpState->pc,
43 interpState->method->name);
44 #endif
45
46 #if INTERP_TYPE == INTERP_DBG
47 /* Check to see if we've got a trace selection request. If we do,
48 * but something is amiss, revert to the fast interpreter.
49 */
50 if (dvmJitCheckTraceRequest(self,interpState)) {
51 interpState->nextMode = INTERP_STD;
52 //LOGD("** something wrong, exiting\n");
53 return true;
54 }
55 #endif
56 #endif
57
58 /* copy state in */
59 curMethod = interpState->method;
60 pc = interpState->pc;
61 fp = interpState->fp;
62 retval = interpState->retval; /* only need for kInterpEntryReturn? */
63
64 methodClassDex = curMethod->clazz->pDvmDex;
65
66 LOGVV("threadid=%d: entry(%s) %s.%s pc=0x%x fp=%p ep=%d\n",
67 self->threadId, (interpState->nextMode == INTERP_STD) ? "STD" : "DBG",
68 curMethod->clazz->descriptor, curMethod->name, pc - curMethod->insns,
69 fp, interpState->entryPoint);
70
71 /*
72 * DEBUG: scramble this to ensure we're not relying on it.
73 */
74 methodToCall = (const Method*) -1;
75
76 #if INTERP_TYPE == INTERP_DBG
77 if (debugIsMethodEntry) {
78 ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor,
79 curMethod->name);
80 DUMP_REGS(curMethod, interpState->fp, false);
81 }
82 #endif
83
84 switch (interpState->entryPoint) {
85 case kInterpEntryInstr:
86 /* just fall through to instruction loop or threaded kickstart */
87 break;
88 case kInterpEntryReturn:
89 goto returnFromMethod;
90 case kInterpEntryThrow:
91 goto exceptionThrown;
92 default:
93 dvmAbort();
94 }
95
96 #ifdef THREADED_INTERP
97 FINISH(0); /* fetch and execute first instruction */
98 #else
99 while (1) {
100 CHECK_DEBUG_AND_PROF(); /* service debugger and profiling */
101 CHECK_TRACKED_REFS(); /* check local reference tracking */
102
103 /* fetch the next 16 bits from the instruction stream */
104 inst = FETCH(0);
105
106 switch (INST_INST(inst)) {
107 #endif
108
109 /*--- start of opcodes ---*/
110