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