| The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Main interpreter loop. |
| 3 | * |
| 4 | * This was written with an ARM implementation in mind. |
| 5 | */ |
| 6 | bool 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 = interpState->debugIsMethodEntry; |
| 13 | #endif |
| 14 | #if defined(WITH_TRACKREF_CHECKS) |
| 15 | int debugTrackedRefStart = interpState->debugTrackedRefStart; |
| 16 | #endif |
| 17 | DvmDex* methodClassDex; // curMethod->clazz->pDvmDex |
| 18 | JValue retval; |
| 19 | |
| 20 | /* core state */ |
| 21 | const Method* curMethod; // method we're interpreting |
| 22 | const u2* pc; // program counter |
| 23 | u4* fp; // frame pointer |
| 24 | u2 inst; // current instruction |
| 25 | /* instruction decoding */ |
| 26 | u2 ref; // 16-bit quantity fetched directly |
| 27 | u2 vsrc1, vsrc2, vdst; // usually used for register indexes |
| 28 | /* method call setup */ |
| 29 | const Method* methodToCall; |
| 30 | bool methodCallRange; |
| 31 | |
| Ben Cheng | ba4fc8b | 2009-06-01 13:00:29 -0700 | [diff] [blame] | 32 | |
| The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 33 | #if defined(THREADED_INTERP) |
| 34 | /* static computed goto table */ |
| 35 | DEFINE_GOTO_TABLE(handlerTable); |
| 36 | #endif |
| 37 | |
| Ben Cheng | ba4fc8b | 2009-06-01 13:00:29 -0700 | [diff] [blame] | 38 | #if defined(WITH_JIT) |
| 39 | #if 0 |
| 40 | LOGD("*DebugInterp - entrypoint is %d, tgt is 0x%x, %s\n", |
| 41 | interpState->entryPoint, |
| 42 | interpState->pc, |
| 43 | interpState->method->name); |
| 44 | #endif |
| 45 | |
| 46 | #if INTERP_TYPE == INTERP_DBG |
| 47 | /* Check to see if we've got a trace selection request. If we do, |
| 48 | * but something is amiss, revert to the fast interpreter. |
| 49 | */ |
| Jeff Hao | 97319a8 | 2009-08-12 16:57:15 -0700 | [diff] [blame] | 50 | #if !defined(WITH_SELF_VERIFICATION) |
| Ben Cheng | ba4fc8b | 2009-06-01 13:00:29 -0700 | [diff] [blame] | 51 | if (dvmJitCheckTraceRequest(self,interpState)) { |
| 52 | interpState->nextMode = INTERP_STD; |
| 53 | //LOGD("** something wrong, exiting\n"); |
| 54 | return true; |
| 55 | } |
| Jeff Hao | 97319a8 | 2009-08-12 16:57:15 -0700 | [diff] [blame] | 56 | #else |
| 57 | if (interpState->jitState != kJitSelfVerification && |
| 58 | dvmJitCheckTraceRequest(self,interpState)) { |
| 59 | interpState->nextMode = INTERP_STD; |
| 60 | //LOGD("** something wrong, exiting\n"); |
| 61 | return true; |
| 62 | } |
| 63 | #endif /* WITH_SELF_VERIFICATION */ |
| 64 | #endif /* INTERP_TYPE == INTERP_DBG */ |
| 65 | #endif /* WITH_JIT */ |
| Ben Cheng | ba4fc8b | 2009-06-01 13:00:29 -0700 | [diff] [blame] | 66 | |
| The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 67 | /* copy state in */ |
| 68 | curMethod = interpState->method; |
| 69 | pc = interpState->pc; |
| 70 | fp = interpState->fp; |
| 71 | retval = interpState->retval; /* only need for kInterpEntryReturn? */ |
| 72 | |
| 73 | methodClassDex = curMethod->clazz->pDvmDex; |
| 74 | |
| 75 | LOGVV("threadid=%d: entry(%s) %s.%s pc=0x%x fp=%p ep=%d\n", |
| 76 | self->threadId, (interpState->nextMode == INTERP_STD) ? "STD" : "DBG", |
| 77 | curMethod->clazz->descriptor, curMethod->name, pc - curMethod->insns, |
| 78 | fp, interpState->entryPoint); |
| 79 | |
| 80 | /* |
| 81 | * DEBUG: scramble this to ensure we're not relying on it. |
| 82 | */ |
| 83 | methodToCall = (const Method*) -1; |
| 84 | |
| 85 | #if INTERP_TYPE == INTERP_DBG |
| 86 | if (debugIsMethodEntry) { |
| 87 | ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor, |
| 88 | curMethod->name); |
| 89 | DUMP_REGS(curMethod, interpState->fp, false); |
| 90 | } |
| 91 | #endif |
| 92 | |
| 93 | switch (interpState->entryPoint) { |
| 94 | case kInterpEntryInstr: |
| 95 | /* just fall through to instruction loop or threaded kickstart */ |
| 96 | break; |
| 97 | case kInterpEntryReturn: |
| Ben Cheng | 9c147b8 | 2009-10-07 16:41:46 -0700 | [diff] [blame^] | 98 | CHECK_JIT(); |
| The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 99 | goto returnFromMethod; |
| 100 | case kInterpEntryThrow: |
| 101 | goto exceptionThrown; |
| 102 | default: |
| 103 | dvmAbort(); |
| 104 | } |
| 105 | |
| 106 | #ifdef THREADED_INTERP |
| 107 | FINISH(0); /* fetch and execute first instruction */ |
| 108 | #else |
| 109 | while (1) { |
| 110 | CHECK_DEBUG_AND_PROF(); /* service debugger and profiling */ |
| 111 | CHECK_TRACKED_REFS(); /* check local reference tracking */ |
| 112 | |
| 113 | /* fetch the next 16 bits from the instruction stream */ |
| 114 | inst = FETCH(0); |
| 115 | |
| 116 | switch (INST_INST(inst)) { |
| 117 | #endif |
| 118 | |
| 119 | /*--- start of opcodes ---*/ |