1/* 2 * Main interpreter loop. 3 * 4 * This was written with an ARM implementation in mind. 5 */ 6bool 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