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