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