1 /* 2 * Main interpreter loop. 3 * 4 * This was written with an ARM implementation in mind. 5 */ 6 void dvmInterpretPortable(Thread* self) 7 { 8 #if defined(EASY_GDB) 9 StackSaveArea* debugSaveArea = SAVEAREA_FROM_FP(self->interpSave.curFrame); 10 #endif 11 DvmDex* methodClassDex; // curMethod->clazz->pDvmDex 12 JValue retval; 13 14 /* core state */ 15 const Method* curMethod; // method we're interpreting 16 const u2* pc; // program counter 17 u4* fp; // frame pointer 18 u2 inst; // current instruction 19 /* instruction decoding */ 20 u4 ref; // 16 or 32-bit quantity fetched directly 21 u2 vsrc1, vsrc2, vdst; // usually used for register indexes 22 /* method call setup */ 23 const Method* methodToCall; 24 bool methodCallRange; 25 bool jumboFormat; 26 27 28 /* static computed goto table */ 29 DEFINE_GOTO_TABLE(handlerTable); 30 31 /* copy state in */ 32 curMethod = self->interpSave.method; 33 pc = self->interpSave.pc; 34 fp = self->interpSave.curFrame; 35 retval = self->interpSave.retval; /* only need for kInterpEntryReturn? */ 36 37 methodClassDex = curMethod->clazz->pDvmDex; 38 39 LOGVV("threadid=%d: %s.%s pc=%#x fp=%p", 40 self->threadId, curMethod->clazz->descriptor, curMethod->name, 41 pc - curMethod->insns, fp); 42 43 /* 44 * Handle any ongoing profiling and prep for debugging. 45 */ 46 if (self->interpBreak.ctl.subMode != 0) { 47 TRACE_METHOD_ENTER(self, curMethod); 48 self->debugIsMethodEntry = true; // Always true on startup 49 } 50 /* 51 * DEBUG: scramble this to ensure we're not relying on it. 52 */ 53 methodToCall = (const Method*) -1; 54 55 #if 0 56 if (self->debugIsMethodEntry) { 57 ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor, 58 curMethod->name); 59 DUMP_REGS(curMethod, self->interpSave.curFrame, false); 60 } 61 #endif 62 63 FINISH(0); /* fetch and execute first instruction */ 64 65 /*--- start of opcodes ---*/ 66