Home | History | Annotate | Download | only in interp
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  * Main interpreter entry point and support functions.
     19  *
     20  * The entry point selects the "standard" or "debug" interpreter and
     21  * facilitates switching between them.  The standard interpreter may
     22  * use the "fast" or "portable" implementation.
     23  *
     24  * Some debugger support functions are included here.
     25  */
     26 #include "Dalvik.h"
     27 #include "interp/InterpDefs.h"
     28 
     29 
     30 /*
     31  * ===========================================================================
     32  *      Debugger support
     33  * ===========================================================================
     34  */
     35 
     36 // fwd
     37 static BreakpointSet* dvmBreakpointSetAlloc(void);
     38 static void dvmBreakpointSetFree(BreakpointSet* pSet);
     39 
     40 /*
     41  * Initialize global breakpoint structures.
     42  */
     43 bool dvmBreakpointStartup(void)
     44 {
     45     gDvm.breakpointSet = dvmBreakpointSetAlloc();
     46     return (gDvm.breakpointSet != NULL);
     47 }
     48 
     49 /*
     50  * Free resources.
     51  */
     52 void dvmBreakpointShutdown(void)
     53 {
     54     dvmBreakpointSetFree(gDvm.breakpointSet);
     55 }
     56 
     57 
     58 /*
     59  * This represents a breakpoint inserted in the instruction stream.
     60  *
     61  * The debugger may ask us to create the same breakpoint multiple times.
     62  * We only remove the breakpoint when the last instance is cleared.
     63  */
     64 typedef struct {
     65     Method*     method;                 /* method we're associated with */
     66     u2*         addr;                   /* absolute memory address */
     67     u1          originalOpCode;         /* original 8-bit opcode value */
     68     int         setCount;               /* #of times this breakpoint was set */
     69 } Breakpoint;
     70 
     71 /*
     72  * Set of breakpoints.
     73  */
     74 struct BreakpointSet {
     75     /* grab lock before reading or writing anything else in here */
     76     pthread_mutex_t lock;
     77 
     78     /* vector of breakpoint structures */
     79     int         alloc;
     80     int         count;
     81     Breakpoint* breakpoints;
     82 };
     83 
     84 /*
     85  * Initialize a BreakpointSet.  Initially empty.
     86  */
     87 static BreakpointSet* dvmBreakpointSetAlloc(void)
     88 {
     89     BreakpointSet* pSet = (BreakpointSet*) calloc(1, sizeof(*pSet));
     90 
     91     dvmInitMutex(&pSet->lock);
     92     /* leave the rest zeroed -- will alloc on first use */
     93 
     94     return pSet;
     95 }
     96 
     97 /*
     98  * Free storage associated with a BreakpointSet.
     99  */
    100 static void dvmBreakpointSetFree(BreakpointSet* pSet)
    101 {
    102     if (pSet == NULL)
    103         return;
    104 
    105     free(pSet->breakpoints);
    106     free(pSet);
    107 }
    108 
    109 /*
    110  * Lock the breakpoint set.
    111  *
    112  * It's not currently necessary to switch to VMWAIT in the event of
    113  * contention, because nothing in here can block.  However, it's possible
    114  * that the bytecode-updater code could become fancier in the future, so
    115  * we do the trylock dance as a bit of future-proofing.
    116  */
    117 static void dvmBreakpointSetLock(BreakpointSet* pSet)
    118 {
    119     if (dvmTryLockMutex(&pSet->lock) != 0) {
    120         Thread* self = dvmThreadSelf();
    121         ThreadStatus oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
    122         dvmLockMutex(&pSet->lock);
    123         dvmChangeStatus(self, oldStatus);
    124     }
    125 }
    126 
    127 /*
    128  * Unlock the breakpoint set.
    129  */
    130 static void dvmBreakpointSetUnlock(BreakpointSet* pSet)
    131 {
    132     dvmUnlockMutex(&pSet->lock);
    133 }
    134 
    135 /*
    136  * Return the #of breakpoints.
    137  */
    138 static int dvmBreakpointSetCount(const BreakpointSet* pSet)
    139 {
    140     return pSet->count;
    141 }
    142 
    143 /*
    144  * See if we already have an entry for this address.
    145  *
    146  * The BreakpointSet's lock must be acquired before calling here.
    147  *
    148  * Returns the index of the breakpoint entry, or -1 if not found.
    149  */
    150 static int dvmBreakpointSetFind(const BreakpointSet* pSet, const u2* addr)
    151 {
    152     int i;
    153 
    154     for (i = 0; i < pSet->count; i++) {
    155         Breakpoint* pBreak = &pSet->breakpoints[i];
    156         if (pBreak->addr == addr)
    157             return i;
    158     }
    159 
    160     return -1;
    161 }
    162 
    163 /*
    164  * Retrieve the opcode that was originally at the specified location.
    165  *
    166  * The BreakpointSet's lock must be acquired before calling here.
    167  *
    168  * Returns "true" with the opcode in *pOrig on success.
    169  */
    170 static bool dvmBreakpointSetOriginalOpCode(const BreakpointSet* pSet,
    171     const u2* addr, u1* pOrig)
    172 {
    173     int idx = dvmBreakpointSetFind(pSet, addr);
    174     if (idx < 0)
    175         return false;
    176 
    177     *pOrig = pSet->breakpoints[idx].originalOpCode;
    178     return true;
    179 }
    180 
    181 /*
    182  * Check the opcode.  If it's a "magic" NOP, indicating the start of
    183  * switch or array data in the instruction stream, we don't want to set
    184  * a breakpoint.
    185  *
    186  * This can happen because the line number information dx generates
    187  * associates the switch data with the switch statement's line number,
    188  * and some debuggers put breakpoints at every address associated with
    189  * a given line.  The result is that the breakpoint stomps on the NOP
    190  * instruction that doubles as a data table magic number, and an explicit
    191  * check in the interpreter results in an exception being thrown.
    192  *
    193  * We don't want to simply refuse to add the breakpoint to the table,
    194  * because that confuses the housekeeping.  We don't want to reject the
    195  * debugger's event request, and we want to be sure that there's exactly
    196  * one un-set operation for every set op.
    197  */
    198 static bool instructionIsMagicNop(const u2* addr)
    199 {
    200     u2 curVal = *addr;
    201     return ((curVal & 0xff) == OP_NOP && (curVal >> 8) != 0);
    202 }
    203 
    204 /*
    205  * Add a breakpoint at a specific address.  If the address is already
    206  * present in the table, this just increments the count.
    207  *
    208  * For a new entry, this will extract and preserve the current opcode from
    209  * the instruction stream, and replace it with a breakpoint opcode.
    210  *
    211  * The BreakpointSet's lock must be acquired before calling here.
    212  *
    213  * Returns "true" on success.
    214  */
    215 static bool dvmBreakpointSetAdd(BreakpointSet* pSet, Method* method,
    216     unsigned int instrOffset)
    217 {
    218     const int kBreakpointGrowth = 10;
    219     const u2* addr = method->insns + instrOffset;
    220     int idx = dvmBreakpointSetFind(pSet, addr);
    221     Breakpoint* pBreak;
    222 
    223     if (idx < 0) {
    224         if (pSet->count == pSet->alloc) {
    225             int newSize = pSet->alloc + kBreakpointGrowth;
    226             Breakpoint* newVec;
    227 
    228             LOGV("+++ increasing breakpoint set size to %d\n", newSize);
    229 
    230             /* pSet->breakpoints will be NULL on first entry */
    231             newVec = realloc(pSet->breakpoints, newSize * sizeof(Breakpoint));
    232             if (newVec == NULL)
    233                 return false;
    234 
    235             pSet->breakpoints = newVec;
    236             pSet->alloc = newSize;
    237         }
    238 
    239         pBreak = &pSet->breakpoints[pSet->count++];
    240         pBreak->method = method;
    241         pBreak->addr = (u2*)addr;
    242         pBreak->originalOpCode = *(u1*)addr;
    243         pBreak->setCount = 1;
    244 
    245         /*
    246          * Change the opcode.  We must ensure that the BreakpointSet
    247          * updates happen before we change the opcode.
    248          *
    249          * If the method has not been verified, we do NOT insert the
    250          * breakpoint yet, since that will screw up the verifier.  The
    251          * debugger is allowed to insert breakpoints in unverified code,
    252          * but since we don't execute unverified code we don't need to
    253          * alter the bytecode yet.
    254          *
    255          * The class init code will "flush" all pending opcode writes
    256          * before verification completes.
    257          */
    258         assert(*(u1*)addr != OP_BREAKPOINT);
    259         if (dvmIsClassVerified(method->clazz)) {
    260             LOGV("Class %s verified, adding breakpoint at %p\n",
    261                 method->clazz->descriptor, addr);
    262             if (instructionIsMagicNop(addr)) {
    263                 LOGV("Refusing to set breakpoint on %04x at %s.%s + 0x%x\n",
    264                     *addr, method->clazz->descriptor, method->name,
    265                     instrOffset);
    266             } else {
    267                 ANDROID_MEMBAR_FULL();
    268                 dvmDexChangeDex1(method->clazz->pDvmDex, (u1*)addr,
    269                     OP_BREAKPOINT);
    270             }
    271         } else {
    272             LOGV("Class %s NOT verified, deferring breakpoint at %p\n",
    273                 method->clazz->descriptor, addr);
    274         }
    275     } else {
    276         /*
    277          * Breakpoint already exists, just increase the count.
    278          */
    279         pBreak = &pSet->breakpoints[idx];
    280         pBreak->setCount++;
    281     }
    282 
    283     return true;
    284 }
    285 
    286 /*
    287  * Remove one instance of the specified breakpoint.  When the count
    288  * reaches zero, the entry is removed from the table, and the original
    289  * opcode is restored.
    290  *
    291  * The BreakpointSet's lock must be acquired before calling here.
    292  */
    293 static void dvmBreakpointSetRemove(BreakpointSet* pSet, Method* method,
    294     unsigned int instrOffset)
    295 {
    296     const u2* addr = method->insns + instrOffset;
    297     int idx = dvmBreakpointSetFind(pSet, addr);
    298 
    299     if (idx < 0) {
    300         /* breakpoint not found in set -- unexpected */
    301         if (*(u1*)addr == OP_BREAKPOINT) {
    302             LOGE("Unable to restore breakpoint opcode (%s.%s +0x%x)\n",
    303                 method->clazz->descriptor, method->name, instrOffset);
    304             dvmAbort();
    305         } else {
    306             LOGW("Breakpoint was already restored? (%s.%s +0x%x)\n",
    307                 method->clazz->descriptor, method->name, instrOffset);
    308         }
    309     } else {
    310         Breakpoint* pBreak = &pSet->breakpoints[idx];
    311         if (pBreak->setCount == 1) {
    312             /*
    313              * Must restore opcode before removing set entry.
    314              *
    315              * If the breakpoint was never flushed, we could be ovewriting
    316              * a value with the same value.  Not a problem, though we
    317              * could end up causing a copy-on-write here when we didn't
    318              * need to.  (Not worth worrying about.)
    319              */
    320             dvmDexChangeDex1(method->clazz->pDvmDex, (u1*)addr,
    321                 pBreak->originalOpCode);
    322             ANDROID_MEMBAR_FULL();
    323 
    324             if (idx != pSet->count-1) {
    325                 /* shift down */
    326                 memmove(&pSet->breakpoints[idx], &pSet->breakpoints[idx+1],
    327                     (pSet->count-1 - idx) * sizeof(pSet->breakpoints[0]));
    328             }
    329             pSet->count--;
    330             pSet->breakpoints[pSet->count].addr = (u2*) 0xdecadead; // debug
    331         } else {
    332             pBreak->setCount--;
    333             assert(pBreak->setCount > 0);
    334         }
    335     }
    336 }
    337 
    338 /*
    339  * Flush any breakpoints associated with methods in "clazz".  We want to
    340  * change the opcode, which might not have happened when the breakpoint
    341  * was initially set because the class was in the process of being
    342  * verified.
    343  *
    344  * The BreakpointSet's lock must be acquired before calling here.
    345  */
    346 static void dvmBreakpointSetFlush(BreakpointSet* pSet, ClassObject* clazz)
    347 {
    348     int i;
    349     for (i = 0; i < pSet->count; i++) {
    350         Breakpoint* pBreak = &pSet->breakpoints[i];
    351         if (pBreak->method->clazz == clazz) {
    352             /*
    353              * The breakpoint is associated with a method in this class.
    354              * It might already be there or it might not; either way,
    355              * flush it out.
    356              */
    357             LOGV("Flushing breakpoint at %p for %s\n",
    358                 pBreak->addr, clazz->descriptor);
    359             if (instructionIsMagicNop(pBreak->addr)) {
    360                 LOGV("Refusing to flush breakpoint on %04x at %s.%s + 0x%x\n",
    361                     *pBreak->addr, pBreak->method->clazz->descriptor,
    362                     pBreak->method->name, pBreak->addr - pBreak->method->insns);
    363             } else {
    364                 dvmDexChangeDex1(clazz->pDvmDex, (u1*)pBreak->addr,
    365                     OP_BREAKPOINT);
    366             }
    367         }
    368     }
    369 }
    370 
    371 
    372 /*
    373  * Do any debugger-attach-time initialization.
    374  */
    375 void dvmInitBreakpoints(void)
    376 {
    377     /* quick sanity check */
    378     BreakpointSet* pSet = gDvm.breakpointSet;
    379     dvmBreakpointSetLock(pSet);
    380     if (dvmBreakpointSetCount(pSet) != 0) {
    381         LOGW("WARNING: %d leftover breakpoints\n", dvmBreakpointSetCount(pSet));
    382         /* generally not good, but we can keep going */
    383     }
    384     dvmBreakpointSetUnlock(pSet);
    385 }
    386 
    387 /*
    388  * Add an address to the list, putting it in the first non-empty slot.
    389  *
    390  * Sometimes the debugger likes to add two entries for one breakpoint.
    391  * We add two entries here, so that we get the right behavior when it's
    392  * removed twice.
    393  *
    394  * This will only be run from the JDWP thread, and it will happen while
    395  * we are updating the event list, which is synchronized.  We're guaranteed
    396  * to be the only one adding entries, and the lock ensures that nobody
    397  * will be trying to remove them while we're in here.
    398  *
    399  * "addr" is the absolute address of the breakpoint bytecode.
    400  */
    401 void dvmAddBreakAddr(Method* method, unsigned int instrOffset)
    402 {
    403     BreakpointSet* pSet = gDvm.breakpointSet;
    404     dvmBreakpointSetLock(pSet);
    405     dvmBreakpointSetAdd(pSet, method, instrOffset);
    406     dvmBreakpointSetUnlock(pSet);
    407 }
    408 
    409 /*
    410  * Remove an address from the list by setting the entry to NULL.
    411  *
    412  * This can be called from the JDWP thread (because the debugger has
    413  * cancelled the breakpoint) or from an event thread (because it's a
    414  * single-shot breakpoint, e.g. "run to line").  We only get here as
    415  * the result of removing an entry from the event list, which is
    416  * synchronized, so it should not be possible for two threads to be
    417  * updating breakpoints at the same time.
    418  */
    419 void dvmClearBreakAddr(Method* method, unsigned int instrOffset)
    420 {
    421     BreakpointSet* pSet = gDvm.breakpointSet;
    422     dvmBreakpointSetLock(pSet);
    423     dvmBreakpointSetRemove(pSet, method, instrOffset);
    424     dvmBreakpointSetUnlock(pSet);
    425 }
    426 
    427 /*
    428  * Get the original opcode from under a breakpoint.
    429  *
    430  * On SMP hardware it's possible one core might try to execute a breakpoint
    431  * after another core has cleared it.  We need to handle the case where
    432  * there's no entry in the breakpoint set.  (The memory barriers in the
    433  * locks and in the breakpoint update code should ensure that, once we've
    434  * observed the absence of a breakpoint entry, we will also now observe
    435  * the restoration of the original opcode.  The fact that we're holding
    436  * the lock prevents other threads from confusing things further.)
    437  */
    438 u1 dvmGetOriginalOpCode(const u2* addr)
    439 {
    440     BreakpointSet* pSet = gDvm.breakpointSet;
    441     u1 orig = 0;
    442 
    443     dvmBreakpointSetLock(pSet);
    444     if (!dvmBreakpointSetOriginalOpCode(pSet, addr, &orig)) {
    445         orig = *(u1*)addr;
    446         if (orig == OP_BREAKPOINT) {
    447             LOGE("GLITCH: can't find breakpoint, opcode is still set\n");
    448             dvmAbort();
    449         }
    450     }
    451     dvmBreakpointSetUnlock(pSet);
    452 
    453     return orig;
    454 }
    455 
    456 /*
    457  * Flush any breakpoints associated with methods in "clazz".
    458  *
    459  * We don't want to modify the bytecode of a method before the verifier
    460  * gets a chance to look at it, so we postpone opcode replacement until
    461  * after verification completes.
    462  */
    463 void dvmFlushBreakpoints(ClassObject* clazz)
    464 {
    465     BreakpointSet* pSet = gDvm.breakpointSet;
    466 
    467     if (pSet == NULL)
    468         return;
    469 
    470     assert(dvmIsClassVerified(clazz));
    471     dvmBreakpointSetLock(pSet);
    472     dvmBreakpointSetFlush(pSet, clazz);
    473     dvmBreakpointSetUnlock(pSet);
    474 }
    475 
    476 /*
    477  * Add a single step event.  Currently this is a global item.
    478  *
    479  * We set up some initial values based on the thread's current state.  This
    480  * won't work well if the thread is running, so it's up to the caller to
    481  * verify that it's suspended.
    482  *
    483  * This is only called from the JDWP thread.
    484  */
    485 bool dvmAddSingleStep(Thread* thread, int size, int depth)
    486 {
    487     StepControl* pCtrl = &gDvm.stepControl;
    488 
    489     if (pCtrl->active && thread != pCtrl->thread) {
    490         LOGW("WARNING: single-step active for %p; adding %p\n",
    491             pCtrl->thread, thread);
    492 
    493         /*
    494          * Keep going, overwriting previous.  This can happen if you
    495          * suspend a thread in Object.wait, hit the single-step key, then
    496          * switch to another thread and do the same thing again.
    497          * The first thread's step is still pending.
    498          *
    499          * TODO: consider making single-step per-thread.  Adds to the
    500          * overhead, but could be useful in rare situations.
    501          */
    502     }
    503 
    504     pCtrl->size = size;
    505     pCtrl->depth = depth;
    506     pCtrl->thread = thread;
    507 
    508     /*
    509      * We may be stepping into or over method calls, or running until we
    510      * return from the current method.  To make this work we need to track
    511      * the current line, current method, and current stack depth.  We need
    512      * to be checking these after most instructions, notably those that
    513      * call methods, return from methods, or are on a different line from the
    514      * previous instruction.
    515      *
    516      * We have to start with a snapshot of the current state.  If we're in
    517      * an interpreted method, everything we need is in the current frame.  If
    518      * we're in a native method, possibly with some extra JNI frames pushed
    519      * on by PushLocalFrame, we want to use the topmost native method.
    520      */
    521     const StackSaveArea* saveArea;
    522     void* fp;
    523     void* prevFp = NULL;
    524 
    525     for (fp = thread->curFrame; fp != NULL; fp = saveArea->prevFrame) {
    526         const Method* method;
    527 
    528         saveArea = SAVEAREA_FROM_FP(fp);
    529         method = saveArea->method;
    530 
    531         if (!dvmIsBreakFrame(fp) && !dvmIsNativeMethod(method))
    532             break;
    533         prevFp = fp;
    534     }
    535     if (fp == NULL) {
    536         LOGW("Unexpected: step req in native-only threadid=%d\n",
    537             thread->threadId);
    538         return false;
    539     }
    540     if (prevFp != NULL) {
    541         /*
    542          * First interpreted frame wasn't the one at the bottom.  Break
    543          * frames are only inserted when calling from native->interp, so we
    544          * don't need to worry about one being here.
    545          */
    546         LOGV("##### init step while in native method\n");
    547         fp = prevFp;
    548         assert(!dvmIsBreakFrame(fp));
    549         assert(dvmIsNativeMethod(SAVEAREA_FROM_FP(fp)->method));
    550         saveArea = SAVEAREA_FROM_FP(fp);
    551     }
    552 
    553     /*
    554      * Pull the goodies out.  "xtra.currentPc" should be accurate since
    555      * we update it on every instruction while the debugger is connected.
    556      */
    557     pCtrl->method = saveArea->method;
    558     // Clear out any old address set
    559     if (pCtrl->pAddressSet != NULL) {
    560         // (discard const)
    561         free((void *)pCtrl->pAddressSet);
    562         pCtrl->pAddressSet = NULL;
    563     }
    564     if (dvmIsNativeMethod(pCtrl->method)) {
    565         pCtrl->line = -1;
    566     } else {
    567         pCtrl->line = dvmLineNumFromPC(saveArea->method,
    568                         saveArea->xtra.currentPc - saveArea->method->insns);
    569         pCtrl->pAddressSet
    570                 = dvmAddressSetForLine(saveArea->method, pCtrl->line);
    571     }
    572     pCtrl->frameDepth = dvmComputeVagueFrameDepth(thread, thread->curFrame);
    573     pCtrl->active = true;
    574 
    575     LOGV("##### step init: thread=%p meth=%p '%s' line=%d frameDepth=%d depth=%s size=%s\n",
    576         pCtrl->thread, pCtrl->method, pCtrl->method->name,
    577         pCtrl->line, pCtrl->frameDepth,
    578         dvmJdwpStepDepthStr(pCtrl->depth),
    579         dvmJdwpStepSizeStr(pCtrl->size));
    580 
    581     return true;
    582 }
    583 
    584 /*
    585  * Disable a single step event.
    586  */
    587 void dvmClearSingleStep(Thread* thread)
    588 {
    589     UNUSED_PARAMETER(thread);
    590 
    591     gDvm.stepControl.active = false;
    592 }
    593 
    594 
    595 /*
    596  * Recover the "this" pointer from the current interpreted method.  "this"
    597  * is always in "in0" for non-static methods.
    598  *
    599  * The "ins" start at (#of registers - #of ins).  Note in0 != v0.
    600  *
    601  * This works because "dx" guarantees that it will work.  It's probably
    602  * fairly common to have a virtual method that doesn't use its "this"
    603  * pointer, in which case we're potentially wasting a register.  However,
    604  * the debugger doesn't treat "this" as just another argument.  For
    605  * example, events (such as breakpoints) can be enabled for specific
    606  * values of "this".  There is also a separate StackFrame.ThisObject call
    607  * in JDWP that is expected to work for any non-native non-static method.
    608  *
    609  * Because we need it when setting up debugger event filters, we want to
    610  * be able to do this quickly.
    611  */
    612 Object* dvmGetThisPtr(const Method* method, const u4* fp)
    613 {
    614     if (dvmIsStaticMethod(method))
    615         return NULL;
    616     return (Object*)fp[method->registersSize - method->insSize];
    617 }
    618 
    619 
    620 #if defined(WITH_TRACKREF_CHECKS)
    621 /*
    622  * Verify that all internally-tracked references have been released.  If
    623  * they haven't, print them and abort the VM.
    624  *
    625  * "debugTrackedRefStart" indicates how many refs were on the list when
    626  * we were first invoked.
    627  */
    628 void dvmInterpCheckTrackedRefs(Thread* self, const Method* method,
    629     int debugTrackedRefStart)
    630 {
    631     if (dvmReferenceTableEntries(&self->internalLocalRefTable)
    632         != (size_t) debugTrackedRefStart)
    633     {
    634         char* desc;
    635         Object** top;
    636         int count;
    637 
    638         count = dvmReferenceTableEntries(&self->internalLocalRefTable);
    639 
    640         LOGE("TRACK: unreleased internal reference (prev=%d total=%d)\n",
    641             debugTrackedRefStart, count);
    642         desc = dexProtoCopyMethodDescriptor(&method->prototype);
    643         LOGE("       current method is %s.%s %s\n", method->clazz->descriptor,
    644             method->name, desc);
    645         free(desc);
    646         top = self->internalLocalRefTable.table + debugTrackedRefStart;
    647         while (top < self->internalLocalRefTable.nextEntry) {
    648             LOGE("  %p (%s)\n",
    649                  *top,
    650                  ((*top)->clazz != NULL) ? (*top)->clazz->descriptor : "");
    651             top++;
    652         }
    653         dvmDumpThread(self, false);
    654 
    655         dvmAbort();
    656     }
    657     //LOGI("TRACK OK\n");
    658 }
    659 #endif
    660 
    661 
    662 #ifdef LOG_INSTR
    663 /*
    664  * Dump the v-registers.  Sent to the ILOG log tag.
    665  */
    666 void dvmDumpRegs(const Method* method, const u4* framePtr, bool inOnly)
    667 {
    668     int i, localCount;
    669 
    670     localCount = method->registersSize - method->insSize;
    671 
    672     LOG(LOG_VERBOSE, LOG_TAG"i", "Registers (fp=%p):\n", framePtr);
    673     for (i = method->registersSize-1; i >= 0; i--) {
    674         if (i >= localCount) {
    675             LOG(LOG_VERBOSE, LOG_TAG"i", "  v%-2d in%-2d : 0x%08x\n",
    676                 i, i-localCount, framePtr[i]);
    677         } else {
    678             if (inOnly) {
    679                 LOG(LOG_VERBOSE, LOG_TAG"i", "  [...]\n");
    680                 break;
    681             }
    682             const char* name = "";
    683 #if 0   // "locals" structure has changed -- need to rewrite this
    684             int j;
    685             DexFile* pDexFile = method->clazz->pDexFile;
    686             const DexCode* pDexCode = dvmGetMethodCode(method);
    687             int localsSize = dexGetLocalsSize(pDexFile, pDexCode);
    688             const DexLocal* locals = dvmDexGetLocals(pDexFile, pDexCode);
    689             for (j = 0; j < localsSize, j++) {
    690                 if (locals[j].registerNum == (u4) i) {
    691                     name = dvmDexStringStr(locals[j].pName);
    692                     break;
    693                 }
    694             }
    695 #endif
    696             LOG(LOG_VERBOSE, LOG_TAG"i", "  v%-2d      : 0x%08x %s\n",
    697                 i, framePtr[i], name);
    698         }
    699     }
    700 }
    701 #endif
    702 
    703 
    704 /*
    705  * ===========================================================================
    706  *      Entry point and general support functions
    707  * ===========================================================================
    708  */
    709 
    710 /*
    711  * Construct an s4 from two consecutive half-words of switch data.
    712  * This needs to check endianness because the DEX optimizer only swaps
    713  * half-words in instruction stream.
    714  *
    715  * "switchData" must be 32-bit aligned.
    716  */
    717 #if __BYTE_ORDER == __LITTLE_ENDIAN
    718 static inline s4 s4FromSwitchData(const void* switchData) {
    719     return *(s4*) switchData;
    720 }
    721 #else
    722 static inline s4 s4FromSwitchData(const void* switchData) {
    723     u2* data = switchData;
    724     return data[0] | (((s4) data[1]) << 16);
    725 }
    726 #endif
    727 
    728 /*
    729  * Find the matching case.  Returns the offset to the handler instructions.
    730  *
    731  * Returns 3 if we don't find a match (it's the size of the packed-switch
    732  * instruction).
    733  */
    734 s4 dvmInterpHandlePackedSwitch(const u2* switchData, s4 testVal)
    735 {
    736     const int kInstrLen = 3;
    737     u2 size;
    738     s4 firstKey;
    739     const s4* entries;
    740 
    741     /*
    742      * Packed switch data format:
    743      *  ushort ident = 0x0100   magic value
    744      *  ushort size             number of entries in the table
    745      *  int first_key           first (and lowest) switch case value
    746      *  int targets[size]       branch targets, relative to switch opcode
    747      *
    748      * Total size is (4+size*2) 16-bit code units.
    749      */
    750     if (*switchData++ != kPackedSwitchSignature) {
    751         /* should have been caught by verifier */
    752         dvmThrowException("Ljava/lang/InternalError;",
    753             "bad packed switch magic");
    754         return kInstrLen;
    755     }
    756 
    757     size = *switchData++;
    758     assert(size > 0);
    759 
    760     firstKey = *switchData++;
    761     firstKey |= (*switchData++) << 16;
    762 
    763     if (testVal < firstKey || testVal >= firstKey + size) {
    764         LOGVV("Value %d not found in switch (%d-%d)\n",
    765             testVal, firstKey, firstKey+size-1);
    766         return kInstrLen;
    767     }
    768 
    769     /* The entries are guaranteed to be aligned on a 32-bit boundary;
    770      * we can treat them as a native int array.
    771      */
    772     entries = (const s4*) switchData;
    773     assert(((u4)entries & 0x3) == 0);
    774 
    775     assert(testVal - firstKey >= 0 && testVal - firstKey < size);
    776     LOGVV("Value %d found in slot %d (goto 0x%02x)\n",
    777         testVal, testVal - firstKey,
    778         s4FromSwitchData(&entries[testVal - firstKey]));
    779     return s4FromSwitchData(&entries[testVal - firstKey]);
    780 }
    781 
    782 /*
    783  * Find the matching case.  Returns the offset to the handler instructions.
    784  *
    785  * Returns 3 if we don't find a match (it's the size of the sparse-switch
    786  * instruction).
    787  */
    788 s4 dvmInterpHandleSparseSwitch(const u2* switchData, s4 testVal)
    789 {
    790     const int kInstrLen = 3;
    791     u2 size;
    792     const s4* keys;
    793     const s4* entries;
    794 
    795     /*
    796      * Sparse switch data format:
    797      *  ushort ident = 0x0200   magic value
    798      *  ushort size             number of entries in the table; > 0
    799      *  int keys[size]          keys, sorted low-to-high; 32-bit aligned
    800      *  int targets[size]       branch targets, relative to switch opcode
    801      *
    802      * Total size is (2+size*4) 16-bit code units.
    803      */
    804 
    805     if (*switchData++ != kSparseSwitchSignature) {
    806         /* should have been caught by verifier */
    807         dvmThrowException("Ljava/lang/InternalError;",
    808             "bad sparse switch magic");
    809         return kInstrLen;
    810     }
    811 
    812     size = *switchData++;
    813     assert(size > 0);
    814 
    815     /* The keys are guaranteed to be aligned on a 32-bit boundary;
    816      * we can treat them as a native int array.
    817      */
    818     keys = (const s4*) switchData;
    819     assert(((u4)keys & 0x3) == 0);
    820 
    821     /* The entries are guaranteed to be aligned on a 32-bit boundary;
    822      * we can treat them as a native int array.
    823      */
    824     entries = keys + size;
    825     assert(((u4)entries & 0x3) == 0);
    826 
    827     /*
    828      * Binary-search through the array of keys, which are guaranteed to
    829      * be sorted low-to-high.
    830      */
    831     int lo = 0;
    832     int hi = size - 1;
    833     while (lo <= hi) {
    834         int mid = (lo + hi) >> 1;
    835 
    836         s4 foundVal = s4FromSwitchData(&keys[mid]);
    837         if (testVal < foundVal) {
    838             hi = mid - 1;
    839         } else if (testVal > foundVal) {
    840             lo = mid + 1;
    841         } else {
    842             LOGVV("Value %d found in entry %d (goto 0x%02x)\n",
    843                 testVal, mid, s4FromSwitchData(&entries[mid]));
    844             return s4FromSwitchData(&entries[mid]);
    845         }
    846     }
    847 
    848     LOGVV("Value %d not found in switch\n", testVal);
    849     return kInstrLen;
    850 }
    851 
    852 /*
    853  * Copy data for a fill-array-data instruction.  On a little-endian machine
    854  * we can just do a memcpy(), on a big-endian system we have work to do.
    855  *
    856  * The trick here is that dexopt has byte-swapped each code unit, which is
    857  * exactly what we want for short/char data.  For byte data we need to undo
    858  * the swap, and for 4- or 8-byte values we need to swap pieces within
    859  * each word.
    860  */
    861 static void copySwappedArrayData(void* dest, const u2* src, u4 size, u2 width)
    862 {
    863 #if __BYTE_ORDER == __LITTLE_ENDIAN
    864     memcpy(dest, src, size*width);
    865 #else
    866     int i;
    867 
    868     switch (width) {
    869     case 1:
    870         /* un-swap pairs of bytes as we go */
    871         for (i = (size-1) & ~1; i >= 0; i -= 2) {
    872             ((u1*)dest)[i] = ((u1*)src)[i+1];
    873             ((u1*)dest)[i+1] = ((u1*)src)[i];
    874         }
    875         /*
    876          * "src" is padded to end on a two-byte boundary, but we don't want to
    877          * assume "dest" is, so we handle odd length specially.
    878          */
    879         if ((size & 1) != 0) {
    880             ((u1*)dest)[size-1] = ((u1*)src)[size];
    881         }
    882         break;
    883     case 2:
    884         /* already swapped correctly */
    885         memcpy(dest, src, size*width);
    886         break;
    887     case 4:
    888         /* swap word halves */
    889         for (i = 0; i < (int) size; i++) {
    890             ((u4*)dest)[i] = (src[(i << 1) + 1] << 16) | src[i << 1];
    891         }
    892         break;
    893     case 8:
    894         /* swap word halves and words */
    895         for (i = 0; i < (int) (size << 1); i += 2) {
    896             ((int*)dest)[i] = (src[(i << 1) + 3] << 16) | src[(i << 1) + 2];
    897             ((int*)dest)[i+1] = (src[(i << 1) + 1] << 16) | src[i << 1];
    898         }
    899         break;
    900     default:
    901         LOGE("Unexpected width %d in copySwappedArrayData\n", width);
    902         dvmAbort();
    903         break;
    904     }
    905 #endif
    906 }
    907 
    908 /*
    909  * Fill the array with predefined constant values.
    910  *
    911  * Returns true if job is completed, otherwise false to indicate that
    912  * an exception has been thrown.
    913  */
    914 bool dvmInterpHandleFillArrayData(ArrayObject* arrayObj, const u2* arrayData)
    915 {
    916     u2 width;
    917     u4 size;
    918 
    919     if (arrayObj == NULL) {
    920         dvmThrowException("Ljava/lang/NullPointerException;", NULL);
    921         return false;
    922     }
    923     assert (!IS_CLASS_FLAG_SET(((Object *)arrayObj)->clazz,
    924                                CLASS_ISOBJECTARRAY));
    925 
    926     /*
    927      * Array data table format:
    928      *  ushort ident = 0x0300   magic value
    929      *  ushort width            width of each element in the table
    930      *  uint   size             number of elements in the table
    931      *  ubyte  data[size*width] table of data values (may contain a single-byte
    932      *                          padding at the end)
    933      *
    934      * Total size is 4+(width * size + 1)/2 16-bit code units.
    935      */
    936     if (arrayData[0] != kArrayDataSignature) {
    937         dvmThrowException("Ljava/lang/InternalError;", "bad array data magic");
    938         return false;
    939     }
    940 
    941     width = arrayData[1];
    942     size = arrayData[2] | (((u4)arrayData[3]) << 16);
    943 
    944     if (size > arrayObj->length) {
    945         dvmThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", NULL);
    946         return false;
    947     }
    948     copySwappedArrayData(arrayObj->contents, &arrayData[4], size, width);
    949     return true;
    950 }
    951 
    952 /*
    953  * Find the concrete method that corresponds to "methodIdx".  The code in
    954  * "method" is executing invoke-method with "thisClass" as its first argument.
    955  *
    956  * Returns NULL with an exception raised on failure.
    957  */
    958 Method* dvmInterpFindInterfaceMethod(ClassObject* thisClass, u4 methodIdx,
    959     const Method* method, DvmDex* methodClassDex)
    960 {
    961     Method* absMethod;
    962     Method* methodToCall;
    963     int i, vtableIndex;
    964 
    965     /*
    966      * Resolve the method.  This gives us the abstract method from the
    967      * interface class declaration.
    968      */
    969     absMethod = dvmDexGetResolvedMethod(methodClassDex, methodIdx);
    970     if (absMethod == NULL) {
    971         absMethod = dvmResolveInterfaceMethod(method->clazz, methodIdx);
    972         if (absMethod == NULL) {
    973             LOGV("+ unknown method\n");
    974             return NULL;
    975         }
    976     }
    977 
    978     /* make sure absMethod->methodIndex means what we think it means */
    979     assert(dvmIsAbstractMethod(absMethod));
    980 
    981     /*
    982      * Run through the "this" object's iftable.  Find the entry for
    983      * absMethod's class, then use absMethod->methodIndex to find
    984      * the method's entry.  The value there is the offset into our
    985      * vtable of the actual method to execute.
    986      *
    987      * The verifier does not guarantee that objects stored into
    988      * interface references actually implement the interface, so this
    989      * check cannot be eliminated.
    990      */
    991     for (i = 0; i < thisClass->iftableCount; i++) {
    992         if (thisClass->iftable[i].clazz == absMethod->clazz)
    993             break;
    994     }
    995     if (i == thisClass->iftableCount) {
    996         /* impossible in verified DEX, need to check for it in unverified */
    997         dvmThrowException("Ljava/lang/IncompatibleClassChangeError;",
    998             "interface not implemented");
    999         return NULL;
   1000     }
   1001 
   1002     assert(absMethod->methodIndex <
   1003         thisClass->iftable[i].clazz->virtualMethodCount);
   1004 
   1005     vtableIndex =
   1006         thisClass->iftable[i].methodIndexArray[absMethod->methodIndex];
   1007     assert(vtableIndex >= 0 && vtableIndex < thisClass->vtableCount);
   1008     methodToCall = thisClass->vtable[vtableIndex];
   1009 
   1010 #if 0
   1011     /* this can happen when there's a stale class file */
   1012     if (dvmIsAbstractMethod(methodToCall)) {
   1013         dvmThrowException("Ljava/lang/AbstractMethodError;",
   1014             "interface method not implemented");
   1015         return NULL;
   1016     }
   1017 #else
   1018     assert(!dvmIsAbstractMethod(methodToCall) ||
   1019         methodToCall->nativeFunc != NULL);
   1020 #endif
   1021 
   1022     LOGVV("+++ interface=%s.%s concrete=%s.%s\n",
   1023         absMethod->clazz->descriptor, absMethod->name,
   1024         methodToCall->clazz->descriptor, methodToCall->name);
   1025     assert(methodToCall != NULL);
   1026 
   1027     return methodToCall;
   1028 }
   1029 
   1030 
   1031 
   1032 /*
   1033  * Helpers for dvmThrowVerificationError().
   1034  *
   1035  * Each returns a newly-allocated string.
   1036  */
   1037 #define kThrowShow_accessFromClass     1
   1038 static char* classNameFromIndex(const Method* method, int ref,
   1039     VerifyErrorRefType refType, int flags)
   1040 {
   1041     static const int kBufLen = 256;
   1042     const DvmDex* pDvmDex = method->clazz->pDvmDex;
   1043 
   1044     if (refType == VERIFY_ERROR_REF_FIELD) {
   1045         /* get class ID from field ID */
   1046         const DexFieldId* pFieldId = dexGetFieldId(pDvmDex->pDexFile, ref);
   1047         ref = pFieldId->classIdx;
   1048     } else if (refType == VERIFY_ERROR_REF_METHOD) {
   1049         /* get class ID from method ID */
   1050         const DexMethodId* pMethodId = dexGetMethodId(pDvmDex->pDexFile, ref);
   1051         ref = pMethodId->classIdx;
   1052     }
   1053 
   1054     const char* className = dexStringByTypeIdx(pDvmDex->pDexFile, ref);
   1055     char* dotClassName = dvmDescriptorToDot(className);
   1056     if (flags == 0)
   1057         return dotClassName;
   1058 
   1059     char* result = (char*) malloc(kBufLen);
   1060 
   1061     if ((flags & kThrowShow_accessFromClass) != 0) {
   1062         char* dotFromName = dvmDescriptorToDot(method->clazz->descriptor);
   1063         snprintf(result, kBufLen, "tried to access class %s from class %s",
   1064             dotClassName, dotFromName);
   1065         free(dotFromName);
   1066     } else {
   1067         assert(false);      // should've been caught above
   1068         result[0] = '\0';
   1069     }
   1070 
   1071     free(dotClassName);
   1072     return result;
   1073 }
   1074 static char* fieldNameFromIndex(const Method* method, int ref,
   1075     VerifyErrorRefType refType, int flags)
   1076 {
   1077     static const int kBufLen = 256;
   1078     const DvmDex* pDvmDex = method->clazz->pDvmDex;
   1079     const DexFieldId* pFieldId;
   1080     const char* className;
   1081     const char* fieldName;
   1082 
   1083     if (refType != VERIFY_ERROR_REF_FIELD) {
   1084         LOGW("Expected ref type %d, got %d\n", VERIFY_ERROR_REF_FIELD, refType);
   1085         return NULL;    /* no message */
   1086     }
   1087 
   1088     pFieldId = dexGetFieldId(pDvmDex->pDexFile, ref);
   1089     className = dexStringByTypeIdx(pDvmDex->pDexFile, pFieldId->classIdx);
   1090     fieldName = dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx);
   1091 
   1092     char* dotName = dvmDescriptorToDot(className);
   1093     char* result = (char*) malloc(kBufLen);
   1094 
   1095     if ((flags & kThrowShow_accessFromClass) != 0) {
   1096         char* dotFromName = dvmDescriptorToDot(method->clazz->descriptor);
   1097         snprintf(result, kBufLen, "tried to access field %s.%s from class %s",
   1098             dotName, fieldName, dotFromName);
   1099         free(dotFromName);
   1100     } else {
   1101         snprintf(result, kBufLen, "%s.%s", dotName, fieldName);
   1102     }
   1103 
   1104     free(dotName);
   1105     return result;
   1106 }
   1107 static char* methodNameFromIndex(const Method* method, int ref,
   1108     VerifyErrorRefType refType, int flags)
   1109 {
   1110     static const int kBufLen = 384;
   1111     const DvmDex* pDvmDex = method->clazz->pDvmDex;
   1112     const DexMethodId* pMethodId;
   1113     const char* className;
   1114     const char* methodName;
   1115 
   1116     if (refType != VERIFY_ERROR_REF_METHOD) {
   1117         LOGW("Expected ref type %d, got %d\n", VERIFY_ERROR_REF_METHOD,refType);
   1118         return NULL;    /* no message */
   1119     }
   1120 
   1121     pMethodId = dexGetMethodId(pDvmDex->pDexFile, ref);
   1122     className = dexStringByTypeIdx(pDvmDex->pDexFile, pMethodId->classIdx);
   1123     methodName = dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx);
   1124 
   1125     char* dotName = dvmDescriptorToDot(className);
   1126     char* result = (char*) malloc(kBufLen);
   1127 
   1128     if ((flags & kThrowShow_accessFromClass) != 0) {
   1129         char* dotFromName = dvmDescriptorToDot(method->clazz->descriptor);
   1130         char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
   1131         snprintf(result, kBufLen,
   1132             "tried to access method %s.%s:%s from class %s",
   1133             dotName, methodName, desc, dotFromName);
   1134         free(dotFromName);
   1135         free(desc);
   1136     } else {
   1137         snprintf(result, kBufLen, "%s.%s", dotName, methodName);
   1138     }
   1139 
   1140     free(dotName);
   1141     return result;
   1142 }
   1143 
   1144 /*
   1145  * Throw an exception for a problem identified by the verifier.
   1146  *
   1147  * This is used by the invoke-verification-error instruction.  It always
   1148  * throws an exception.
   1149  *
   1150  * "kind" indicates the kind of failure encountered by the verifier.  It
   1151  * has two parts, an error code and an indication of the reference type.
   1152  */
   1153 void dvmThrowVerificationError(const Method* method, int kind, int ref)
   1154 {
   1155     const int typeMask = 0xff << kVerifyErrorRefTypeShift;
   1156     VerifyError errorKind = kind & ~typeMask;
   1157     VerifyErrorRefType refType = kind >> kVerifyErrorRefTypeShift;
   1158     const char* exceptionName = "Ljava/lang/VerifyError;";
   1159     char* msg = NULL;
   1160 
   1161     switch ((VerifyError) errorKind) {
   1162     case VERIFY_ERROR_NO_CLASS:
   1163         exceptionName = "Ljava/lang/NoClassDefFoundError;";
   1164         msg = classNameFromIndex(method, ref, refType, 0);
   1165         break;
   1166     case VERIFY_ERROR_NO_FIELD:
   1167         exceptionName = "Ljava/lang/NoSuchFieldError;";
   1168         msg = fieldNameFromIndex(method, ref, refType, 0);
   1169         break;
   1170     case VERIFY_ERROR_NO_METHOD:
   1171         exceptionName = "Ljava/lang/NoSuchMethodError;";
   1172         msg = methodNameFromIndex(method, ref, refType, 0);
   1173         break;
   1174     case VERIFY_ERROR_ACCESS_CLASS:
   1175         exceptionName = "Ljava/lang/IllegalAccessError;";
   1176         msg = classNameFromIndex(method, ref, refType,
   1177             kThrowShow_accessFromClass);
   1178         break;
   1179     case VERIFY_ERROR_ACCESS_FIELD:
   1180         exceptionName = "Ljava/lang/IllegalAccessError;";
   1181         msg = fieldNameFromIndex(method, ref, refType,
   1182             kThrowShow_accessFromClass);
   1183         break;
   1184     case VERIFY_ERROR_ACCESS_METHOD:
   1185         exceptionName = "Ljava/lang/IllegalAccessError;";
   1186         msg = methodNameFromIndex(method, ref, refType,
   1187             kThrowShow_accessFromClass);
   1188         break;
   1189     case VERIFY_ERROR_CLASS_CHANGE:
   1190         exceptionName = "Ljava/lang/IncompatibleClassChangeError;";
   1191         msg = classNameFromIndex(method, ref, refType, 0);
   1192         break;
   1193     case VERIFY_ERROR_INSTANTIATION:
   1194         exceptionName = "Ljava/lang/InstantiationError;";
   1195         msg = classNameFromIndex(method, ref, refType, 0);
   1196         break;
   1197 
   1198     case VERIFY_ERROR_GENERIC:
   1199         /* generic VerifyError; use default exception, no message */
   1200         break;
   1201     case VERIFY_ERROR_NONE:
   1202         /* should never happen; use default exception */
   1203         assert(false);
   1204         msg = strdup("weird - no error specified");
   1205         break;
   1206 
   1207     /* no default clause -- want warning if enum updated */
   1208     }
   1209 
   1210     dvmThrowException(exceptionName, msg);
   1211     free(msg);
   1212 }
   1213 
   1214 /*
   1215  * Main interpreter loop entry point.  Select "standard" or "debug"
   1216  * interpreter and switch between them as required.
   1217  *
   1218  * This begins executing code at the start of "method".  On exit, "pResult"
   1219  * holds the return value of the method (or, if "method" returns NULL, it
   1220  * holds an undefined value).
   1221  *
   1222  * The interpreted stack frame, which holds the method arguments, has
   1223  * already been set up.
   1224  */
   1225 void dvmInterpret(Thread* self, const Method* method, JValue* pResult)
   1226 {
   1227     InterpState interpState;
   1228     bool change;
   1229 #if defined(WITH_JIT)
   1230     /* Target-specific save/restore */
   1231     extern void dvmJitCalleeSave(double *saveArea);
   1232     extern void dvmJitCalleeRestore(double *saveArea);
   1233     /* Interpreter entry points from compiled code */
   1234     extern void dvmJitToInterpNormal();
   1235     extern void dvmJitToInterpNoChain();
   1236     extern void dvmJitToInterpPunt();
   1237     extern void dvmJitToInterpSingleStep();
   1238     extern void dvmJitToInterpTraceSelectNoChain();
   1239     extern void dvmJitToInterpTraceSelect();
   1240     extern void dvmJitToPatchPredictedChain();
   1241 #if defined(WITH_SELF_VERIFICATION)
   1242     extern void dvmJitToInterpBackwardBranch();
   1243 #endif
   1244 
   1245     /*
   1246      * Reserve a static entity here to quickly setup runtime contents as
   1247      * gcc will issue block copy instructions.
   1248      */
   1249     static struct JitToInterpEntries jitToInterpEntries = {
   1250         dvmJitToInterpNormal,
   1251         dvmJitToInterpNoChain,
   1252         dvmJitToInterpPunt,
   1253         dvmJitToInterpSingleStep,
   1254         dvmJitToInterpTraceSelectNoChain,
   1255         dvmJitToInterpTraceSelect,
   1256         dvmJitToPatchPredictedChain,
   1257 #if defined(WITH_SELF_VERIFICATION)
   1258         dvmJitToInterpBackwardBranch,
   1259 #endif
   1260     };
   1261 
   1262     /*
   1263      * If the previous VM left the code cache through single-stepping the
   1264      * inJitCodeCache flag will be set when the VM is re-entered (for example,
   1265      * in self-verification mode we single-step NEW_INSTANCE which may re-enter
   1266      * the VM through findClassFromLoaderNoInit). Because of that, we cannot
   1267      * assert that self->inJitCodeCache is NULL here.
   1268      */
   1269 #endif
   1270 
   1271 
   1272 #if defined(WITH_TRACKREF_CHECKS)
   1273     interpState.debugTrackedRefStart =
   1274         dvmReferenceTableEntries(&self->internalLocalRefTable);
   1275 #endif
   1276     interpState.debugIsMethodEntry = true;
   1277 #if defined(WITH_JIT)
   1278     dvmJitCalleeSave(interpState.calleeSave);
   1279     /* Initialize the state to kJitNot */
   1280     interpState.jitState = kJitNot;
   1281 
   1282     /* Setup the Jit-to-interpreter entry points */
   1283     interpState.jitToInterpEntries = jitToInterpEntries;
   1284 
   1285     /*
   1286      * Initialize the threshold filter [don't bother to zero out the
   1287      * actual table.  We're looking for matches, and an occasional
   1288      * false positive is acceptible.
   1289      */
   1290     interpState.lastThreshFilter = 0;
   1291 
   1292     interpState.icRechainCount = PREDICTED_CHAIN_COUNTER_RECHAIN;
   1293 #endif
   1294 
   1295     /*
   1296      * Initialize working state.
   1297      *
   1298      * No need to initialize "retval".
   1299      */
   1300     interpState.method = method;
   1301     interpState.fp = (u4*) self->curFrame;
   1302     interpState.pc = method->insns;
   1303     interpState.entryPoint = kInterpEntryInstr;
   1304 
   1305     if (dvmDebuggerOrProfilerActive())
   1306         interpState.nextMode = INTERP_DBG;
   1307     else
   1308         interpState.nextMode = INTERP_STD;
   1309 
   1310     assert(!dvmIsNativeMethod(method));
   1311 
   1312     /*
   1313      * Make sure the class is ready to go.  Shouldn't be possible to get
   1314      * here otherwise.
   1315      */
   1316     if (method->clazz->status < CLASS_INITIALIZING ||
   1317         method->clazz->status == CLASS_ERROR)
   1318     {
   1319         LOGE("ERROR: tried to execute code in unprepared class '%s' (%d)\n",
   1320             method->clazz->descriptor, method->clazz->status);
   1321         dvmDumpThread(self, false);
   1322         dvmAbort();
   1323     }
   1324 
   1325     typedef bool (*Interpreter)(Thread*, InterpState*);
   1326     Interpreter stdInterp;
   1327     if (gDvm.executionMode == kExecutionModeInterpFast)
   1328         stdInterp = dvmMterpStd;
   1329 #if defined(WITH_JIT)
   1330     else if (gDvm.executionMode == kExecutionModeJit)
   1331 /* If profiling overhead can be kept low enough, we can use a profiling
   1332  * mterp fast for both Jit and "fast" modes.  If overhead is too high,
   1333  * create a specialized profiling interpreter.
   1334  */
   1335         stdInterp = dvmMterpStd;
   1336 #endif
   1337     else
   1338         stdInterp = dvmInterpretStd;
   1339 
   1340     change = true;
   1341     while (change) {
   1342         switch (interpState.nextMode) {
   1343         case INTERP_STD:
   1344             LOGVV("threadid=%d: interp STD\n", self->threadId);
   1345             change = (*stdInterp)(self, &interpState);
   1346             break;
   1347         case INTERP_DBG:
   1348             LOGVV("threadid=%d: interp DBG\n", self->threadId);
   1349             change = dvmInterpretDbg(self, &interpState);
   1350             break;
   1351         default:
   1352             dvmAbort();
   1353         }
   1354     }
   1355 
   1356     *pResult = interpState.retval;
   1357 #if defined(WITH_JIT)
   1358     dvmJitCalleeRestore(interpState.calleeSave);
   1359 #endif
   1360 }
   1361