blob: fa1b4a8d8b02bf89ff285835fc60bda3f7096274 [file] [log] [blame]
/*
* Main interpreter loop.
*
* This was written with an ARM implementation in mind.
*/
void dvmInterpretPortable(Thread* self)
{
#if defined(EASY_GDB)
StackSaveArea* debugSaveArea = SAVEAREA_FROM_FP(self->curFrame);
#endif
#if defined(WITH_TRACKREF_CHECKS)
int debugTrackedRefStart = self->interpSave.debugTrackedRefStart;
#endif
DvmDex* methodClassDex; // curMethod->clazz->pDvmDex
JValue retval;
/* core state */
const Method* curMethod; // method we're interpreting
const u2* pc; // program counter
u4* fp; // frame pointer
u2 inst; // current instruction
/* instruction decoding */
u4 ref; // 16 or 32-bit quantity fetched directly
u2 vsrc1, vsrc2, vdst; // usually used for register indexes
/* method call setup */
const Method* methodToCall;
bool methodCallRange;
bool jumboFormat;
/* static computed goto table */
DEFINE_GOTO_TABLE(handlerTable);
/* copy state in */
curMethod = self->interpSave.method;
pc = self->interpSave.pc;
fp = self->interpSave.fp;
retval = self->retval; /* only need for kInterpEntryReturn? */
methodClassDex = curMethod->clazz->pDvmDex;
LOGVV("threadid=%d: %s.%s pc=0x%x fp=%p\n",
self->threadId, curMethod->clazz->descriptor, curMethod->name,
pc - curMethod->insns, fp);
/*
* DEBUG: scramble this to ensure we're not relying on it.
*/
methodToCall = (const Method*) -1;
#if 0
if (self->debugIsMethodEntry) {
ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor,
curMethod->name);
DUMP_REGS(curMethod, self->interpSave.fp, false);
}
#endif
FINISH(0); /* fetch and execute first instruction */
/*--- start of opcodes ---*/