| 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 |
| Ben Cheng | ba4fc8b | 2009-06-01 13:00:29 -0700 | [diff] [blame] | 45 | #if INTERP_TYPE == INTERP_DBG |
| Bill Buzbee | 06bb839 | 2010-01-31 18:53:15 -0800 | [diff] [blame] | 46 | /* Check to see if we've got a trace selection request. */ |
| 47 | if ( |
| 48 | #if defined(WITH_SELF_VERIFICATION) |
| 49 | (interpState->jitState != kJitSelfVerification) && |
| 50 | #endif |
| Ben Cheng | 95cd9ac | 2010-03-12 16:58:24 -0800 | [diff] [blame] | 51 | /* |
| 52 | * Don't bail out of the dbg interpreter if the entry reason is to |
| 53 | * deal with a thrown exception. |
| 54 | */ |
| 55 | (interpState->entryPoint != kInterpEntryThrow) && |
| Bill Buzbee | 06bb839 | 2010-01-31 18:53:15 -0800 | [diff] [blame] | 56 | !gDvm.debuggerActive && |
| 57 | #if defined(WITH_PROFILER) |
| 58 | (gDvm.activeProfilers == 0) && |
| 59 | #endif |
| 60 | dvmJitCheckTraceRequest(self, interpState)) { |
| Ben Cheng | ba4fc8b | 2009-06-01 13:00:29 -0700 | [diff] [blame] | 61 | interpState->nextMode = INTERP_STD; |
| Bill Buzbee | 06bb839 | 2010-01-31 18:53:15 -0800 | [diff] [blame] | 62 | //LOGD("Invalid trace request, exiting\n"); |
| Ben Cheng | ba4fc8b | 2009-06-01 13:00:29 -0700 | [diff] [blame] | 63 | return true; |
| 64 | } |
| Jeff Hao | 97319a8 | 2009-08-12 16:57:15 -0700 | [diff] [blame] | 65 | #endif /* INTERP_TYPE == INTERP_DBG */ |
| 66 | #endif /* WITH_JIT */ |
| Ben Cheng | ba4fc8b | 2009-06-01 13:00:29 -0700 | [diff] [blame] | 67 | |
| The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 68 | /* copy state in */ |
| 69 | curMethod = interpState->method; |
| 70 | pc = interpState->pc; |
| 71 | fp = interpState->fp; |
| 72 | retval = interpState->retval; /* only need for kInterpEntryReturn? */ |
| 73 | |
| 74 | methodClassDex = curMethod->clazz->pDvmDex; |
| 75 | |
| 76 | LOGVV("threadid=%d: entry(%s) %s.%s pc=0x%x fp=%p ep=%d\n", |
| 77 | self->threadId, (interpState->nextMode == INTERP_STD) ? "STD" : "DBG", |
| 78 | curMethod->clazz->descriptor, curMethod->name, pc - curMethod->insns, |
| 79 | fp, interpState->entryPoint); |
| 80 | |
| 81 | /* |
| 82 | * DEBUG: scramble this to ensure we're not relying on it. |
| 83 | */ |
| 84 | methodToCall = (const Method*) -1; |
| 85 | |
| 86 | #if INTERP_TYPE == INTERP_DBG |
| 87 | if (debugIsMethodEntry) { |
| 88 | ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor, |
| 89 | curMethod->name); |
| 90 | DUMP_REGS(curMethod, interpState->fp, false); |
| 91 | } |
| 92 | #endif |
| 93 | |
| 94 | switch (interpState->entryPoint) { |
| 95 | case kInterpEntryInstr: |
| 96 | /* just fall through to instruction loop or threaded kickstart */ |
| 97 | break; |
| 98 | case kInterpEntryReturn: |
| Ben Cheng | 9c147b8 | 2009-10-07 16:41:46 -0700 | [diff] [blame] | 99 | CHECK_JIT(); |
| The Android Open Source Project | f6c3871 | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 100 | goto returnFromMethod; |
| 101 | case kInterpEntryThrow: |
| 102 | goto exceptionThrown; |
| 103 | default: |
| 104 | dvmAbort(); |
| 105 | } |
| 106 | |
| 107 | #ifdef THREADED_INTERP |
| 108 | FINISH(0); /* fetch and execute first instruction */ |
| 109 | #else |
| 110 | while (1) { |
| 111 | CHECK_DEBUG_AND_PROF(); /* service debugger and profiling */ |
| 112 | CHECK_TRACKED_REFS(); /* check local reference tracking */ |
| 113 | |
| 114 | /* fetch the next 16 bits from the instruction stream */ |
| 115 | inst = FETCH(0); |
| 116 | |
| 117 | switch (INST_INST(inst)) { |
| 118 | #endif |
| 119 | |
| 120 | /*--- start of opcodes ---*/ |