• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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