1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Main interpreter loop.
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This was written with an ARM implementation in mind.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool INTERP_FUNC_NAME(Thread* self, InterpState* interpState)
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(EASY_GDB)
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StackSaveArea* debugSaveArea = SAVEAREA_FROM_FP(self->curFrame);
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if INTERP_TYPE == INTERP_DBG
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool debugIsMethodEntry = interpState->debugIsMethodEntry;
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(WITH_TRACKREF_CHECKS)
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int debugTrackedRefStart = interpState->debugTrackedRefStart;
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DvmDex* methodClassDex;     // curMethod->clazz->pDvmDex
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue retval;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* core state */
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* curMethod;    // method we're interpreting
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u2* pc;               // program counter
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4* fp;                     // frame pointer
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u2 inst;                    // current instruction
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* instruction decoding */
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u2 ref;                     // 16-bit quantity fetched directly
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u2 vsrc1, vsrc2, vdst;      // usually used for register indexes
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* method call setup */
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* methodToCall;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool methodCallRange;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(THREADED_INTERP)
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* static computed goto table */
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DEFINE_GOTO_TABLE(handlerTable);
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
38ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#if defined(WITH_JIT)
39ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#if 0
40ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LOGD("*DebugInterp - entrypoint is %d, tgt is 0x%x, %s\n",
41ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng         interpState->entryPoint,
42ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng         interpState->pc,
43ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng         interpState->method->name);
44ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#endif
45ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#if INTERP_TYPE == INTERP_DBG
4606bb83906737fec543c86ab36f450cc62066b58aBill Buzbee    /* Check to see if we've got a trace selection request. */
4706bb83906737fec543c86ab36f450cc62066b58aBill Buzbee    if (
4895cd9ac6c308008b6bd48e6e516c118fce0e6a1fBen Cheng         /*
49a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng          * Only perform dvmJitCheckTraceRequest if the entry point is
50a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng          * EntryInstr and the jit state is either kJitTSelectRequest or
51a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng          * kJitTSelectRequestHot. If debugger/profiler happens to be attached,
52a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng          * dvmJitCheckTraceRequest will change the jitState to kJitDone but
53a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng          * but stay in the dbg interpreter.
5495cd9ac6c308008b6bd48e6e516c118fce0e6a1fBen Cheng          */
55a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng         (interpState->entryPoint == kInterpEntryInstr) &&
56a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng         (interpState->jitState == kJitTSelectRequest ||
57a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng          interpState->jitState == kJitTSelectRequestHot) &&
5806bb83906737fec543c86ab36f450cc62066b58aBill Buzbee         dvmJitCheckTraceRequest(self, interpState)) {
5997319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao        interpState->nextMode = INTERP_STD;
6006bb83906737fec543c86ab36f450cc62066b58aBill Buzbee        //LOGD("Invalid trace request, exiting\n");
6197319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao        return true;
6297319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao    }
6397319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#endif /* INTERP_TYPE == INTERP_DBG */
6497319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#endif /* WITH_JIT */
65ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* copy state in */
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    curMethod = interpState->method;
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pc = interpState->pc;
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    fp = interpState->fp;
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    retval = interpState->retval;   /* only need for kInterpEntryReturn? */
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    methodClassDex = curMethod->clazz->pDvmDex;
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGVV("threadid=%d: entry(%s) %s.%s pc=0x%x fp=%p ep=%d\n",
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        self->threadId, (interpState->nextMode == INTERP_STD) ? "STD" : "DBG",
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        curMethod->clazz->descriptor, curMethod->name, pc - curMethod->insns,
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fp, interpState->entryPoint);
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * DEBUG: scramble this to ensure we're not relying on it.
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    methodToCall = (const Method*) -1;
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if INTERP_TYPE == INTERP_DBG
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (debugIsMethodEntry) {
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor,
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                curMethod->name);
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DUMP_REGS(curMethod, interpState->fp, false);
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (interpState->entryPoint) {
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kInterpEntryInstr:
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* just fall through to instruction loop or threaded kickstart */
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kInterpEntryReturn:
979c147b84ff7fe2c39228742b06a9ef180d39b48fBen Cheng        CHECK_JIT();
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto returnFromMethod;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kInterpEntryThrow:
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto exceptionThrown;
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef THREADED_INTERP
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(0);                  /* fetch and execute first instruction */
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (1) {
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_DEBUG_AND_PROF(); /* service debugger and profiling */
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_TRACKED_REFS();   /* check local reference tracking */
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* fetch the next 16 bits from the instruction stream */
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        inst = FETCH(0);
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (INST_INST(inst)) {
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*--- start of opcodes ---*/
119