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