• 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 = false;
13     debugIsMethodEntry = interpState->debugIsMethodEntry;
14 #endif
15 #if defined(WITH_TRACKREF_CHECKS)
16     int debugTrackedRefStart = interpState->debugTrackedRefStart;
17 #endif
18     DvmDex* methodClassDex;     // curMethod->clazz->pDvmDex
19     JValue retval;
20 
21     /* core state */
22     const Method* curMethod;    // method we're interpreting
23     const u2* pc;               // program counter
24     u4* fp;                     // frame pointer
25     u2 inst;                    // current instruction
26     /* instruction decoding */
27     u2 ref;                     // 16-bit quantity fetched directly
28     u2 vsrc1, vsrc2, vdst;      // usually used for register indexes
29     /* method call setup */
30     const Method* methodToCall;
31     bool methodCallRange;
32 
33 
34 #if defined(THREADED_INTERP)
35     /* static computed goto table */
36     DEFINE_GOTO_TABLE(handlerTable);
37 #endif
38 
39 #if defined(WITH_JIT)
40 #if 0
41     LOGD("*DebugInterp - entrypoint is %d, tgt is 0x%x, %s\n",
42          interpState->entryPoint,
43          interpState->pc,
44          interpState->method->name);
45 #endif
46 #if INTERP_TYPE == INTERP_DBG
47     const ClassObject* callsiteClass = NULL;
48 
49 #if defined(WITH_SELF_VERIFICATION)
50     if (interpState->jitState != kJitSelfVerification) {
51         interpState->self->shadowSpace->jitExitState = kSVSIdle;
52     }
53 #endif
54 
55     /* Check to see if we've got a trace selection request. */
56     if (
57          /*
58           * Only perform dvmJitCheckTraceRequest if the entry point is
59           * EntryInstr and the jit state is either kJitTSelectRequest or
60           * kJitTSelectRequestHot. If debugger/profiler happens to be attached,
61           * dvmJitCheckTraceRequest will change the jitState to kJitDone but
62           * but stay in the dbg interpreter.
63           */
64          (interpState->entryPoint == kInterpEntryInstr) &&
65          (interpState->jitState == kJitTSelectRequest ||
66           interpState->jitState == kJitTSelectRequestHot) &&
67          dvmJitCheckTraceRequest(self, interpState)) {
68         interpState->nextMode = INTERP_STD;
69         //LOGD("Invalid trace request, exiting\n");
70         return true;
71     }
72 #endif /* INTERP_TYPE == INTERP_DBG */
73 #endif /* WITH_JIT */
74 
75     /* copy state in */
76     curMethod = interpState->method;
77     pc = interpState->pc;
78     fp = interpState->fp;
79     retval = interpState->retval;   /* only need for kInterpEntryReturn? */
80 
81     methodClassDex = curMethod->clazz->pDvmDex;
82 
83     LOGVV("threadid=%d: entry(%s) %s.%s pc=0x%x fp=%p ep=%d\n",
84         self->threadId, (interpState->nextMode == INTERP_STD) ? "STD" : "DBG",
85         curMethod->clazz->descriptor, curMethod->name, pc - curMethod->insns,
86         fp, interpState->entryPoint);
87 
88     /*
89      * DEBUG: scramble this to ensure we're not relying on it.
90      */
91     methodToCall = (const Method*) -1;
92 
93 #if INTERP_TYPE == INTERP_DBG
94     if (debugIsMethodEntry) {
95         ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor,
96                 curMethod->name);
97         DUMP_REGS(curMethod, interpState->fp, false);
98     }
99 #endif
100 
101     switch (interpState->entryPoint) {
102     case kInterpEntryInstr:
103         /* just fall through to instruction loop or threaded kickstart */
104         break;
105     case kInterpEntryReturn:
106         CHECK_JIT_VOID();
107         goto returnFromMethod;
108     case kInterpEntryThrow:
109         goto exceptionThrown;
110     default:
111         dvmAbort();
112     }
113 
114 #ifdef THREADED_INTERP
115     FINISH(0);                  /* fetch and execute first instruction */
116 #else
117     while (1) {
118         CHECK_DEBUG_AND_PROF(); /* service debugger and profiling */
119         CHECK_TRACKED_REFS();   /* check local reference tracking */
120 
121         /* fetch the next 16 bits from the instruction stream */
122         inst = FETCH(0);
123 
124         switch (INST_INST(inst)) {
125 #endif
126 
127 /*--- start of opcodes ---*/
128