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 26 /* static computed goto table */ 27 DEFINE_GOTO_TABLE(handlerTable); 28 29 /* copy state in */ 30 curMethod = self->interpSave.method; 31 pc = self->interpSave.pc; 32 fp = self->interpSave.curFrame; 33 retval = self->interpSave.retval; /* only need for kInterpEntryReturn? */ 34 35 methodClassDex = curMethod->clazz->pDvmDex; 36 37 LOGVV("threadid=%d: %s.%s pc=%#x fp=%p", 38 self->threadId, curMethod->clazz->descriptor, curMethod->name, 39 pc - curMethod->insns, fp); 40 41 /* 42 * Handle any ongoing profiling and prep for debugging. 43 */ 44 if (self->interpBreak.ctl.subMode != 0) { 45 TRACE_METHOD_ENTER(self, curMethod); 46 self->debugIsMethodEntry = true; // Always true on startup 47 } 48 /* 49 * DEBUG: scramble this to ensure we're not relying on it. 50 */ 51 methodToCall = (const Method*) -1; 52 53 #if 0 54 if (self->debugIsMethodEntry) { 55 ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor, 56 curMethod->name); 57 DUMP_REGS(curMethod, self->interpSave.curFrame, false); 58 } 59 #endif 60 61 FINISH(0); /* fetch and execute first instruction */ 62 63 /*--- start of opcodes ---*/ 64