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