Interp.cpp revision 1813ab265f691e93401c7307c0b34247842ab35e
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#if defined(WITH_JIT)
29#include "interp/Jit.h"
30#endif
31
32
33/*
34 * ===========================================================================
35 *      Debugger support
36 * ===========================================================================
37 */
38
39// fwd
40static BreakpointSet* dvmBreakpointSetAlloc(void);
41static void dvmBreakpointSetFree(BreakpointSet* pSet);
42
43#if defined(WITH_JIT)
44/* Target-specific save/restore */
45extern "C" void dvmJitCalleeSave(double *saveArea);
46extern "C" void dvmJitCalleeRestore(double *saveArea);
47/* Interpreter entry points from compiled code */
48extern "C" void dvmJitToInterpNormal();
49extern "C" void dvmJitToInterpNoChain();
50extern "C" void dvmJitToInterpPunt();
51extern "C" void dvmJitToInterpSingleStep();
52extern "C" void dvmJitToInterpTraceSelect();
53#if defined(WITH_SELF_VERIFICATION)
54extern "C" void dvmJitToInterpBackwardBranch();
55#endif
56#endif
57
58/*
59 * Initialize global breakpoint structures.
60 */
61bool dvmBreakpointStartup(void)
62{
63    gDvm.breakpointSet = dvmBreakpointSetAlloc();
64    return (gDvm.breakpointSet != NULL);
65}
66
67/*
68 * Free resources.
69 */
70void dvmBreakpointShutdown(void)
71{
72    dvmBreakpointSetFree(gDvm.breakpointSet);
73}
74
75
76/*
77 * This represents a breakpoint inserted in the instruction stream.
78 *
79 * The debugger may ask us to create the same breakpoint multiple times.
80 * We only remove the breakpoint when the last instance is cleared.
81 */
82typedef struct {
83    Method*     method;                 /* method we're associated with */
84    u2*         addr;                   /* absolute memory address */
85    u1          originalOpcode;         /* original 8-bit opcode value */
86    int         setCount;               /* #of times this breakpoint was set */
87} Breakpoint;
88
89/*
90 * Set of breakpoints.
91 */
92struct BreakpointSet {
93    /* grab lock before reading or writing anything else in here */
94    pthread_mutex_t lock;
95
96    /* vector of breakpoint structures */
97    int         alloc;
98    int         count;
99    Breakpoint* breakpoints;
100};
101
102/*
103 * Initialize a BreakpointSet.  Initially empty.
104 */
105static BreakpointSet* dvmBreakpointSetAlloc(void)
106{
107    BreakpointSet* pSet = (BreakpointSet*) calloc(1, sizeof(*pSet));
108
109    dvmInitMutex(&pSet->lock);
110    /* leave the rest zeroed -- will alloc on first use */
111
112    return pSet;
113}
114
115/*
116 * Free storage associated with a BreakpointSet.
117 */
118static void dvmBreakpointSetFree(BreakpointSet* pSet)
119{
120    if (pSet == NULL)
121        return;
122
123    free(pSet->breakpoints);
124    free(pSet);
125}
126
127/*
128 * Lock the breakpoint set.
129 *
130 * It's not currently necessary to switch to VMWAIT in the event of
131 * contention, because nothing in here can block.  However, it's possible
132 * that the bytecode-updater code could become fancier in the future, so
133 * we do the trylock dance as a bit of future-proofing.
134 */
135static void dvmBreakpointSetLock(BreakpointSet* pSet)
136{
137    if (dvmTryLockMutex(&pSet->lock) != 0) {
138        Thread* self = dvmThreadSelf();
139        ThreadStatus oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
140        dvmLockMutex(&pSet->lock);
141        dvmChangeStatus(self, oldStatus);
142    }
143}
144
145/*
146 * Unlock the breakpoint set.
147 */
148static void dvmBreakpointSetUnlock(BreakpointSet* pSet)
149{
150    dvmUnlockMutex(&pSet->lock);
151}
152
153/*
154 * Return the #of breakpoints.
155 */
156static int dvmBreakpointSetCount(const BreakpointSet* pSet)
157{
158    return pSet->count;
159}
160
161/*
162 * See if we already have an entry for this address.
163 *
164 * The BreakpointSet's lock must be acquired before calling here.
165 *
166 * Returns the index of the breakpoint entry, or -1 if not found.
167 */
168static int dvmBreakpointSetFind(const BreakpointSet* pSet, const u2* addr)
169{
170    int i;
171
172    for (i = 0; i < pSet->count; i++) {
173        Breakpoint* pBreak = &pSet->breakpoints[i];
174        if (pBreak->addr == addr)
175            return i;
176    }
177
178    return -1;
179}
180
181/*
182 * Retrieve the opcode that was originally at the specified location.
183 *
184 * The BreakpointSet's lock must be acquired before calling here.
185 *
186 * Returns "true" with the opcode in *pOrig on success.
187 */
188static bool dvmBreakpointSetOriginalOpcode(const BreakpointSet* pSet,
189    const u2* addr, u1* pOrig)
190{
191    int idx = dvmBreakpointSetFind(pSet, addr);
192    if (idx < 0)
193        return false;
194
195    *pOrig = pSet->breakpoints[idx].originalOpcode;
196    return true;
197}
198
199/*
200 * Check the opcode.  If it's a "magic" NOP, indicating the start of
201 * switch or array data in the instruction stream, we don't want to set
202 * a breakpoint.
203 *
204 * This can happen because the line number information dx generates
205 * associates the switch data with the switch statement's line number,
206 * and some debuggers put breakpoints at every address associated with
207 * a given line.  The result is that the breakpoint stomps on the NOP
208 * instruction that doubles as a data table magic number, and an explicit
209 * check in the interpreter results in an exception being thrown.
210 *
211 * We don't want to simply refuse to add the breakpoint to the table,
212 * because that confuses the housekeeping.  We don't want to reject the
213 * debugger's event request, and we want to be sure that there's exactly
214 * one un-set operation for every set op.
215 */
216static bool instructionIsMagicNop(const u2* addr)
217{
218    u2 curVal = *addr;
219    return ((GET_OPCODE(curVal)) == OP_NOP && (curVal >> 8) != 0);
220}
221
222/*
223 * Add a breakpoint at a specific address.  If the address is already
224 * present in the table, this just increments the count.
225 *
226 * For a new entry, this will extract and preserve the current opcode from
227 * the instruction stream, and replace it with a breakpoint opcode.
228 *
229 * The BreakpointSet's lock must be acquired before calling here.
230 *
231 * Returns "true" on success.
232 */
233static bool dvmBreakpointSetAdd(BreakpointSet* pSet, Method* method,
234    unsigned int instrOffset)
235{
236    const int kBreakpointGrowth = 10;
237    const u2* addr = method->insns + instrOffset;
238    int idx = dvmBreakpointSetFind(pSet, addr);
239    Breakpoint* pBreak;
240
241    if (idx < 0) {
242        if (pSet->count == pSet->alloc) {
243            int newSize = pSet->alloc + kBreakpointGrowth;
244            Breakpoint* newVec;
245
246            LOGV("+++ increasing breakpoint set size to %d\n", newSize);
247
248            /* pSet->breakpoints will be NULL on first entry */
249            newVec = (Breakpoint*)realloc(pSet->breakpoints, newSize * sizeof(Breakpoint));
250            if (newVec == NULL)
251                return false;
252
253            pSet->breakpoints = newVec;
254            pSet->alloc = newSize;
255        }
256
257        pBreak = &pSet->breakpoints[pSet->count++];
258        pBreak->method = method;
259        pBreak->addr = (u2*)addr;
260        pBreak->originalOpcode = *(u1*)addr;
261        pBreak->setCount = 1;
262
263        /*
264         * Change the opcode.  We must ensure that the BreakpointSet
265         * updates happen before we change the opcode.
266         *
267         * If the method has not been verified, we do NOT insert the
268         * breakpoint yet, since that will screw up the verifier.  The
269         * debugger is allowed to insert breakpoints in unverified code,
270         * but since we don't execute unverified code we don't need to
271         * alter the bytecode yet.
272         *
273         * The class init code will "flush" all pending opcode writes
274         * before verification completes.
275         */
276        assert(*(u1*)addr != OP_BREAKPOINT);
277        if (dvmIsClassVerified(method->clazz)) {
278            LOGV("Class %s verified, adding breakpoint at %p\n",
279                method->clazz->descriptor, addr);
280            if (instructionIsMagicNop(addr)) {
281                LOGV("Refusing to set breakpoint on %04x at %s.%s + 0x%x\n",
282                    *addr, method->clazz->descriptor, method->name,
283                    instrOffset);
284            } else {
285                ANDROID_MEMBAR_FULL();
286                dvmDexChangeDex1(method->clazz->pDvmDex, (u1*)addr,
287                    OP_BREAKPOINT);
288            }
289        } else {
290            LOGV("Class %s NOT verified, deferring breakpoint at %p\n",
291                method->clazz->descriptor, addr);
292        }
293    } else {
294        /*
295         * Breakpoint already exists, just increase the count.
296         */
297        pBreak = &pSet->breakpoints[idx];
298        pBreak->setCount++;
299    }
300
301    return true;
302}
303
304/*
305 * Remove one instance of the specified breakpoint.  When the count
306 * reaches zero, the entry is removed from the table, and the original
307 * opcode is restored.
308 *
309 * The BreakpointSet's lock must be acquired before calling here.
310 */
311static void dvmBreakpointSetRemove(BreakpointSet* pSet, Method* method,
312    unsigned int instrOffset)
313{
314    const u2* addr = method->insns + instrOffset;
315    int idx = dvmBreakpointSetFind(pSet, addr);
316
317    if (idx < 0) {
318        /* breakpoint not found in set -- unexpected */
319        if (*(u1*)addr == OP_BREAKPOINT) {
320            LOGE("Unable to restore breakpoint opcode (%s.%s +0x%x)\n",
321                method->clazz->descriptor, method->name, instrOffset);
322            dvmAbort();
323        } else {
324            LOGW("Breakpoint was already restored? (%s.%s +0x%x)\n",
325                method->clazz->descriptor, method->name, instrOffset);
326        }
327    } else {
328        Breakpoint* pBreak = &pSet->breakpoints[idx];
329        if (pBreak->setCount == 1) {
330            /*
331             * Must restore opcode before removing set entry.
332             *
333             * If the breakpoint was never flushed, we could be ovewriting
334             * a value with the same value.  Not a problem, though we
335             * could end up causing a copy-on-write here when we didn't
336             * need to.  (Not worth worrying about.)
337             */
338            dvmDexChangeDex1(method->clazz->pDvmDex, (u1*)addr,
339                pBreak->originalOpcode);
340            ANDROID_MEMBAR_FULL();
341
342            if (idx != pSet->count-1) {
343                /* shift down */
344                memmove(&pSet->breakpoints[idx], &pSet->breakpoints[idx+1],
345                    (pSet->count-1 - idx) * sizeof(pSet->breakpoints[0]));
346            }
347            pSet->count--;
348            pSet->breakpoints[pSet->count].addr = (u2*) 0xdecadead; // debug
349        } else {
350            pBreak->setCount--;
351            assert(pBreak->setCount > 0);
352        }
353    }
354}
355
356/*
357 * Flush any breakpoints associated with methods in "clazz".  We want to
358 * change the opcode, which might not have happened when the breakpoint
359 * was initially set because the class was in the process of being
360 * verified.
361 *
362 * The BreakpointSet's lock must be acquired before calling here.
363 */
364static void dvmBreakpointSetFlush(BreakpointSet* pSet, ClassObject* clazz)
365{
366    int i;
367    for (i = 0; i < pSet->count; i++) {
368        Breakpoint* pBreak = &pSet->breakpoints[i];
369        if (pBreak->method->clazz == clazz) {
370            /*
371             * The breakpoint is associated with a method in this class.
372             * It might already be there or it might not; either way,
373             * flush it out.
374             */
375            LOGV("Flushing breakpoint at %p for %s\n",
376                pBreak->addr, clazz->descriptor);
377            if (instructionIsMagicNop(pBreak->addr)) {
378                LOGV("Refusing to flush breakpoint on %04x at %s.%s + 0x%x\n",
379                    *pBreak->addr, pBreak->method->clazz->descriptor,
380                    pBreak->method->name, pBreak->addr - pBreak->method->insns);
381            } else {
382                dvmDexChangeDex1(clazz->pDvmDex, (u1*)pBreak->addr,
383                    OP_BREAKPOINT);
384            }
385        }
386    }
387}
388
389
390/*
391 * Do any debugger-attach-time initialization.
392 */
393void dvmInitBreakpoints(void)
394{
395    /* quick sanity check */
396    BreakpointSet* pSet = gDvm.breakpointSet;
397    dvmBreakpointSetLock(pSet);
398    if (dvmBreakpointSetCount(pSet) != 0) {
399        LOGW("WARNING: %d leftover breakpoints\n", dvmBreakpointSetCount(pSet));
400        /* generally not good, but we can keep going */
401    }
402    dvmBreakpointSetUnlock(pSet);
403}
404
405/*
406 * Add an address to the list, putting it in the first non-empty slot.
407 *
408 * Sometimes the debugger likes to add two entries for one breakpoint.
409 * We add two entries here, so that we get the right behavior when it's
410 * removed twice.
411 *
412 * This will only be run from the JDWP thread, and it will happen while
413 * we are updating the event list, which is synchronized.  We're guaranteed
414 * to be the only one adding entries, and the lock ensures that nobody
415 * will be trying to remove them while we're in here.
416 *
417 * "addr" is the absolute address of the breakpoint bytecode.
418 */
419void dvmAddBreakAddr(Method* method, unsigned int instrOffset)
420{
421    BreakpointSet* pSet = gDvm.breakpointSet;
422    dvmBreakpointSetLock(pSet);
423    dvmBreakpointSetAdd(pSet, method, instrOffset);
424    dvmBreakpointSetUnlock(pSet);
425}
426
427/*
428 * Remove an address from the list by setting the entry to NULL.
429 *
430 * This can be called from the JDWP thread (because the debugger has
431 * cancelled the breakpoint) or from an event thread (because it's a
432 * single-shot breakpoint, e.g. "run to line").  We only get here as
433 * the result of removing an entry from the event list, which is
434 * synchronized, so it should not be possible for two threads to be
435 * updating breakpoints at the same time.
436 */
437void dvmClearBreakAddr(Method* method, unsigned int instrOffset)
438{
439    BreakpointSet* pSet = gDvm.breakpointSet;
440    dvmBreakpointSetLock(pSet);
441    dvmBreakpointSetRemove(pSet, method, instrOffset);
442    dvmBreakpointSetUnlock(pSet);
443}
444
445/*
446 * Get the original opcode from under a breakpoint.
447 *
448 * On SMP hardware it's possible one core might try to execute a breakpoint
449 * after another core has cleared it.  We need to handle the case where
450 * there's no entry in the breakpoint set.  (The memory barriers in the
451 * locks and in the breakpoint update code should ensure that, once we've
452 * observed the absence of a breakpoint entry, we will also now observe
453 * the restoration of the original opcode.  The fact that we're holding
454 * the lock prevents other threads from confusing things further.)
455 */
456u1 dvmGetOriginalOpcode(const u2* addr)
457{
458    BreakpointSet* pSet = gDvm.breakpointSet;
459    u1 orig = 0;
460
461    dvmBreakpointSetLock(pSet);
462    if (!dvmBreakpointSetOriginalOpcode(pSet, addr, &orig)) {
463        orig = *(u1*)addr;
464        if (orig == OP_BREAKPOINT) {
465            LOGE("GLITCH: can't find breakpoint, opcode is still set\n");
466            dvmAbort();
467        }
468    }
469    dvmBreakpointSetUnlock(pSet);
470
471    return orig;
472}
473
474/*
475 * Flush any breakpoints associated with methods in "clazz".
476 *
477 * We don't want to modify the bytecode of a method before the verifier
478 * gets a chance to look at it, so we postpone opcode replacement until
479 * after verification completes.
480 */
481void dvmFlushBreakpoints(ClassObject* clazz)
482{
483    BreakpointSet* pSet = gDvm.breakpointSet;
484
485    if (pSet == NULL)
486        return;
487
488    assert(dvmIsClassVerified(clazz));
489    dvmBreakpointSetLock(pSet);
490    dvmBreakpointSetFlush(pSet, clazz);
491    dvmBreakpointSetUnlock(pSet);
492}
493
494/*
495 * Add a single step event.  Currently this is a global item.
496 *
497 * We set up some initial values based on the thread's current state.  This
498 * won't work well if the thread is running, so it's up to the caller to
499 * verify that it's suspended.
500 *
501 * This is only called from the JDWP thread.
502 */
503bool dvmAddSingleStep(Thread* thread, int size, int depth)
504{
505    StepControl* pCtrl = &gDvm.stepControl;
506
507    if (pCtrl->active && thread != pCtrl->thread) {
508        LOGW("WARNING: single-step active for %p; adding %p\n",
509            pCtrl->thread, thread);
510
511        /*
512         * Keep going, overwriting previous.  This can happen if you
513         * suspend a thread in Object.wait, hit the single-step key, then
514         * switch to another thread and do the same thing again.
515         * The first thread's step is still pending.
516         *
517         * TODO: consider making single-step per-thread.  Adds to the
518         * overhead, but could be useful in rare situations.
519         */
520    }
521
522    pCtrl->size = static_cast<JdwpStepSize>(size);
523    pCtrl->depth = static_cast<JdwpStepDepth>(depth);
524    pCtrl->thread = thread;
525
526    /*
527     * We may be stepping into or over method calls, or running until we
528     * return from the current method.  To make this work we need to track
529     * the current line, current method, and current stack depth.  We need
530     * to be checking these after most instructions, notably those that
531     * call methods, return from methods, or are on a different line from the
532     * previous instruction.
533     *
534     * We have to start with a snapshot of the current state.  If we're in
535     * an interpreted method, everything we need is in the current frame.  If
536     * we're in a native method, possibly with some extra JNI frames pushed
537     * on by PushLocalFrame, we want to use the topmost native method.
538     */
539    const StackSaveArea* saveArea;
540    void* fp;
541    void* prevFp = NULL;
542
543    for (fp = thread->curFrame; fp != NULL; fp = saveArea->prevFrame) {
544        const Method* method;
545
546        saveArea = SAVEAREA_FROM_FP(fp);
547        method = saveArea->method;
548
549        if (!dvmIsBreakFrame((u4*)fp) && !dvmIsNativeMethod(method))
550            break;
551        prevFp = fp;
552    }
553    if (fp == NULL) {
554        LOGW("Unexpected: step req in native-only threadid=%d\n",
555            thread->threadId);
556        return false;
557    }
558    if (prevFp != NULL) {
559        /*
560         * First interpreted frame wasn't the one at the bottom.  Break
561         * frames are only inserted when calling from native->interp, so we
562         * don't need to worry about one being here.
563         */
564        LOGV("##### init step while in native method\n");
565        fp = prevFp;
566        assert(!dvmIsBreakFrame((u4*)fp));
567        assert(dvmIsNativeMethod(SAVEAREA_FROM_FP(fp)->method));
568        saveArea = SAVEAREA_FROM_FP(fp);
569    }
570
571    /*
572     * Pull the goodies out.  "xtra.currentPc" should be accurate since
573     * we update it on every instruction while the debugger is connected.
574     */
575    pCtrl->method = saveArea->method;
576    // Clear out any old address set
577    if (pCtrl->pAddressSet != NULL) {
578        // (discard const)
579        free((void *)pCtrl->pAddressSet);
580        pCtrl->pAddressSet = NULL;
581    }
582    if (dvmIsNativeMethod(pCtrl->method)) {
583        pCtrl->line = -1;
584    } else {
585        pCtrl->line = dvmLineNumFromPC(saveArea->method,
586                        saveArea->xtra.currentPc - saveArea->method->insns);
587        pCtrl->pAddressSet
588                = dvmAddressSetForLine(saveArea->method, pCtrl->line);
589    }
590    pCtrl->frameDepth = dvmComputeVagueFrameDepth(thread, thread->curFrame);
591    pCtrl->active = true;
592
593    LOGV("##### step init: thread=%p meth=%p '%s' line=%d frameDepth=%d depth=%s size=%s\n",
594        pCtrl->thread, pCtrl->method, pCtrl->method->name,
595        pCtrl->line, pCtrl->frameDepth,
596        dvmJdwpStepDepthStr(pCtrl->depth),
597        dvmJdwpStepSizeStr(pCtrl->size));
598
599    return true;
600}
601
602/*
603 * Disable a single step event.
604 */
605void dvmClearSingleStep(Thread* thread)
606{
607    UNUSED_PARAMETER(thread);
608
609    gDvm.stepControl.active = false;
610}
611
612/*
613 * The interpreter just threw.  Handle any special subMode requirements.
614 * All interpSave state must be valid on entry.
615 */
616void dvmReportExceptionThrow(Thread* self, Object* exception)
617{
618    const Method* curMethod = self->interpSave.method;
619#if defined(WITH_JIT)
620    if (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) {
621        dvmJitEndTraceSelect(self, self->interpSave.pc);
622    }
623    if (self->interpBreak.ctl.breakFlags & kInterpSingleStep) {
624        /* Discard any single-step native returns to translation */
625        self->jitResumeNPC = NULL;
626    }
627#endif
628    if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
629        void *catchFrame;
630        int offset = self->interpSave.pc - curMethod->insns;
631        int catchRelPc = dvmFindCatchBlock(self, offset, exception,
632                                           true, &catchFrame);
633        dvmDbgPostException(self->interpSave.fp, offset, catchFrame,
634                            catchRelPc, exception);
635    }
636}
637
638/*
639 * The interpreter is preparing to do an invoke (both native & normal).
640 * Handle any special subMode requirements.  All interpSave state
641 * must be valid on entry.
642 */
643void dvmReportInvoke(Thread* self, const Method* methodToCall)
644{
645    TRACE_METHOD_ENTER(self, methodToCall);
646}
647
648/*
649 * The interpreter is preparing to do a native invoke. Handle any
650 * special subMode requirements.  NOTE: for a native invoke,
651 * dvmReportInvoke() and dvmReportPreNativeInvoke() will both
652 * be called prior to the invoke.  All interpSave state must
653 * be valid on entry.
654 */
655void dvmReportPreNativeInvoke(const Method* methodToCall, Thread* self)
656{
657#if defined(WITH_JIT)
658    /*
659     * Actively building a trace?  If so, end it now.   The trace
660     * builder can't follow into or through a native method.
661     */
662    if (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) {
663        dvmCheckJit(self->interpSave.pc, self);
664    }
665#endif
666    if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
667        Object* thisPtr = dvmGetThisPtr(self->interpSave.method,
668                                        self->interpSave.fp);
669        assert(thisPtr == NULL || dvmIsValidObject(thisPtr));
670        dvmDbgPostLocationEvent(methodToCall, -1, thisPtr, DBG_METHOD_ENTRY);
671    }
672}
673
674/*
675 * The interpreter has returned from a native invoke. Handle any
676 * special subMode requirements.  All interpSave state must be
677 * valid on entry.
678 */
679void dvmReportPostNativeInvoke(const Method* methodToCall, Thread* self)
680{
681    if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
682        Object* thisPtr = dvmGetThisPtr(self->interpSave.method,
683                                        self->interpSave.fp);
684        assert(thisPtr == NULL || dvmIsValidObject(thisPtr));
685        dvmDbgPostLocationEvent(methodToCall, -1, thisPtr, DBG_METHOD_EXIT);
686    }
687    if (self->interpBreak.ctl.subMode & kSubModeMethodTrace) {
688        dvmFastNativeMethodTraceExit(methodToCall, self);
689    }
690}
691
692/*
693 * The interpreter has returned from a normal method.  Handle any special
694 * subMode requirements.  All interpSave state must be valid on entry.
695 */
696void dvmReportReturn(Thread* self)
697{
698    TRACE_METHOD_EXIT(self, self->interpSave.method);
699#if defined(WITH_JIT)
700    if (dvmIsBreakFrame(self->interpSave.fp) &&
701        (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild)) {
702        dvmCheckJit(self->interpSave.pc, self);
703    }
704#endif
705}
706
707/*
708 * Update the debugger on interesting events, such as hitting a breakpoint
709 * or a single-step point.  This is called from the top of the interpreter
710 * loop, before the current instruction is processed.
711 *
712 * Set "methodEntry" if we've just entered the method.  This detects
713 * method exit by checking to see if the next instruction is "return".
714 *
715 * This can't catch native method entry/exit, so we have to handle that
716 * at the point of invocation.  We also need to catch it in dvmCallMethod
717 * if we want to capture native->native calls made through JNI.
718 *
719 * Notes to self:
720 * - Don't want to switch to VMWAIT while posting events to the debugger.
721 *   Let the debugger code decide if we need to change state.
722 * - We may want to check for debugger-induced thread suspensions on
723 *   every instruction.  That would make a "suspend all" more responsive
724 *   and reduce the chances of multiple simultaneous events occurring.
725 *   However, it could change the behavior some.
726 *
727 * TODO: method entry/exit events are probably less common than location
728 * breakpoints.  We may be able to speed things up a bit if we don't query
729 * the event list unless we know there's at least one lurking within.
730 */
731static void updateDebugger(const Method* method, const u2* pc, const u4* fp,
732                           Thread* self)
733{
734    int eventFlags = 0;
735
736    /*
737     * Update xtra.currentPc on every instruction.  We need to do this if
738     * there's a chance that we could get suspended.  This can happen if
739     * eventFlags != 0 here, or somebody manually requests a suspend
740     * (which gets handled at PERIOD_CHECKS time).  One place where this
741     * needs to be correct is in dvmAddSingleStep().
742     */
743    dvmExportPC(pc, fp);
744
745    if (self->debugIsMethodEntry) {
746        eventFlags |= DBG_METHOD_ENTRY;
747        self->debugIsMethodEntry = false;
748    }
749
750    /*
751     * See if we have a breakpoint here.
752     *
753     * Depending on the "mods" associated with event(s) on this address,
754     * we may or may not actually send a message to the debugger.
755     */
756    if (GET_OPCODE(*pc) == OP_BREAKPOINT) {
757        LOGV("+++ breakpoint hit at %p\n", pc);
758        eventFlags |= DBG_BREAKPOINT;
759    }
760
761    /*
762     * If the debugger is single-stepping one of our threads, check to
763     * see if we're that thread and we've reached a step point.
764     */
765    const StepControl* pCtrl = &gDvm.stepControl;
766    if (pCtrl->active && pCtrl->thread == self) {
767        int frameDepth;
768        bool doStop = false;
769        const char* msg = NULL;
770
771        assert(!dvmIsNativeMethod(method));
772
773        if (pCtrl->depth == SD_INTO) {
774            /*
775             * Step into method calls.  We break when the line number
776             * or method pointer changes.  If we're in SS_MIN mode, we
777             * always stop.
778             */
779            if (pCtrl->method != method) {
780                doStop = true;
781                msg = "new method";
782            } else if (pCtrl->size == SS_MIN) {
783                doStop = true;
784                msg = "new instruction";
785            } else if (!dvmAddressSetGet(
786                    pCtrl->pAddressSet, pc - method->insns)) {
787                doStop = true;
788                msg = "new line";
789            }
790        } else if (pCtrl->depth == SD_OVER) {
791            /*
792             * Step over method calls.  We break when the line number is
793             * different and the frame depth is <= the original frame
794             * depth.  (We can't just compare on the method, because we
795             * might get unrolled past it by an exception, and it's tricky
796             * to identify recursion.)
797             */
798            frameDepth = dvmComputeVagueFrameDepth(self, fp);
799            if (frameDepth < pCtrl->frameDepth) {
800                /* popped up one or more frames, always trigger */
801                doStop = true;
802                msg = "method pop";
803            } else if (frameDepth == pCtrl->frameDepth) {
804                /* same depth, see if we moved */
805                if (pCtrl->size == SS_MIN) {
806                    doStop = true;
807                    msg = "new instruction";
808                } else if (!dvmAddressSetGet(pCtrl->pAddressSet,
809                            pc - method->insns)) {
810                    doStop = true;
811                    msg = "new line";
812                }
813            }
814        } else {
815            assert(pCtrl->depth == SD_OUT);
816            /*
817             * Return from the current method.  We break when the frame
818             * depth pops up.
819             *
820             * This differs from the "method exit" break in that it stops
821             * with the PC at the next instruction in the returned-to
822             * function, rather than the end of the returning function.
823             */
824            frameDepth = dvmComputeVagueFrameDepth(self, fp);
825            if (frameDepth < pCtrl->frameDepth) {
826                doStop = true;
827                msg = "method pop";
828            }
829        }
830
831        if (doStop) {
832            LOGV("#####S %s\n", msg);
833            eventFlags |= DBG_SINGLE_STEP;
834        }
835    }
836
837    /*
838     * Check to see if this is a "return" instruction.  JDWP says we should
839     * send the event *after* the code has been executed, but it also says
840     * the location we provide is the last instruction.  Since the "return"
841     * instruction has no interesting side effects, we should be safe.
842     * (We can't just move this down to the returnFromMethod label because
843     * we potentially need to combine it with other events.)
844     *
845     * We're also not supposed to generate a method exit event if the method
846     * terminates "with a thrown exception".
847     */
848    u2 opcode = GET_OPCODE(*pc);
849    if (opcode == OP_RETURN_VOID || opcode == OP_RETURN ||
850        opcode == OP_RETURN_WIDE ||opcode == OP_RETURN_OBJECT)
851    {
852        eventFlags |= DBG_METHOD_EXIT;
853    }
854
855    /*
856     * If there's something interesting going on, see if it matches one
857     * of the debugger filters.
858     */
859    if (eventFlags != 0) {
860        Object* thisPtr = dvmGetThisPtr(method, fp);
861        if (thisPtr != NULL && !dvmIsValidObject(thisPtr)) {
862            /*
863             * TODO: remove this check if we're confident that the "this"
864             * pointer is where it should be -- slows us down, especially
865             * during single-step.
866             */
867            char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
868            LOGE("HEY: invalid 'this' ptr %p (%s.%s %s)\n", thisPtr,
869                method->clazz->descriptor, method->name, desc);
870            free(desc);
871            dvmAbort();
872        }
873        dvmDbgPostLocationEvent(method, pc - method->insns, thisPtr,
874            eventFlags);
875    }
876}
877
878/*
879 * Recover the "this" pointer from the current interpreted method.  "this"
880 * is always in "in0" for non-static methods.
881 *
882 * The "ins" start at (#of registers - #of ins).  Note in0 != v0.
883 *
884 * This works because "dx" guarantees that it will work.  It's probably
885 * fairly common to have a virtual method that doesn't use its "this"
886 * pointer, in which case we're potentially wasting a register.  However,
887 * the debugger doesn't treat "this" as just another argument.  For
888 * example, events (such as breakpoints) can be enabled for specific
889 * values of "this".  There is also a separate StackFrame.ThisObject call
890 * in JDWP that is expected to work for any non-native non-static method.
891 *
892 * Because we need it when setting up debugger event filters, we want to
893 * be able to do this quickly.
894 */
895Object* dvmGetThisPtr(const Method* method, const u4* fp)
896{
897    if (dvmIsStaticMethod(method))
898        return NULL;
899    return (Object*)fp[method->registersSize - method->insSize];
900}
901
902
903#if defined(WITH_TRACKREF_CHECKS)
904/*
905 * Verify that all internally-tracked references have been released.  If
906 * they haven't, print them and abort the VM.
907 *
908 * "debugTrackedRefStart" indicates how many refs were on the list when
909 * we were first invoked.
910 */
911void dvmInterpCheckTrackedRefs(Thread* self, const Method* method,
912    int debugTrackedRefStart)
913{
914    if (dvmReferenceTableEntries(&self->internalLocalRefTable)
915        != (size_t) debugTrackedRefStart)
916    {
917        char* desc;
918        Object** top;
919        int count;
920
921        count = dvmReferenceTableEntries(&self->internalLocalRefTable);
922
923        LOGE("TRACK: unreleased internal reference (prev=%d total=%d)\n",
924            debugTrackedRefStart, count);
925        desc = dexProtoCopyMethodDescriptor(&method->prototype);
926        LOGE("       current method is %s.%s %s\n", method->clazz->descriptor,
927            method->name, desc);
928        free(desc);
929        top = self->internalLocalRefTable.table + debugTrackedRefStart;
930        while (top < self->internalLocalRefTable.nextEntry) {
931            LOGE("  %p (%s)\n",
932                 *top,
933                 ((*top)->clazz != NULL) ? (*top)->clazz->descriptor : "");
934            top++;
935        }
936        dvmDumpThread(self, false);
937
938        dvmAbort();
939    }
940    //LOGI("TRACK OK\n");
941}
942#endif
943
944
945#ifdef LOG_INSTR
946/*
947 * Dump the v-registers.  Sent to the ILOG log tag.
948 */
949void dvmDumpRegs(const Method* method, const u4* framePtr, bool inOnly)
950{
951    int i, localCount;
952
953    localCount = method->registersSize - method->insSize;
954
955    LOG(LOG_VERBOSE, LOG_TAG"i", "Registers (fp=%p):\n", framePtr);
956    for (i = method->registersSize-1; i >= 0; i--) {
957        if (i >= localCount) {
958            LOG(LOG_VERBOSE, LOG_TAG"i", "  v%-2d in%-2d : 0x%08x\n",
959                i, i-localCount, framePtr[i]);
960        } else {
961            if (inOnly) {
962                LOG(LOG_VERBOSE, LOG_TAG"i", "  [...]\n");
963                break;
964            }
965            const char* name = "";
966#if 0   // "locals" structure has changed -- need to rewrite this
967            int j;
968            DexFile* pDexFile = method->clazz->pDexFile;
969            const DexCode* pDexCode = dvmGetMethodCode(method);
970            int localsSize = dexGetLocalsSize(pDexFile, pDexCode);
971            const DexLocal* locals = dvmDexGetLocals(pDexFile, pDexCode);
972            for (j = 0; j < localsSize, j++) {
973                if (locals[j].registerNum == (u4) i) {
974                    name = dvmDexStringStr(locals[j].pName);
975                    break;
976                }
977            }
978#endif
979            LOG(LOG_VERBOSE, LOG_TAG"i", "  v%-2d      : 0x%08x %s\n",
980                i, framePtr[i], name);
981        }
982    }
983}
984#endif
985
986
987/*
988 * ===========================================================================
989 *      Entry point and general support functions
990 * ===========================================================================
991 */
992
993/*
994 * Construct an s4 from two consecutive half-words of switch data.
995 * This needs to check endianness because the DEX optimizer only swaps
996 * half-words in instruction stream.
997 *
998 * "switchData" must be 32-bit aligned.
999 */
1000#if __BYTE_ORDER == __LITTLE_ENDIAN
1001static inline s4 s4FromSwitchData(const void* switchData) {
1002    return *(s4*) switchData;
1003}
1004#else
1005static inline s4 s4FromSwitchData(const void* switchData) {
1006    u2* data = switchData;
1007    return data[0] | (((s4) data[1]) << 16);
1008}
1009#endif
1010
1011/*
1012 * Find the matching case.  Returns the offset to the handler instructions.
1013 *
1014 * Returns 3 if we don't find a match (it's the size of the packed-switch
1015 * instruction).
1016 */
1017s4 dvmInterpHandlePackedSwitch(const u2* switchData, s4 testVal)
1018{
1019    const int kInstrLen = 3;
1020    u2 size;
1021    s4 firstKey;
1022    const s4* entries;
1023
1024    /*
1025     * Packed switch data format:
1026     *  ushort ident = 0x0100   magic value
1027     *  ushort size             number of entries in the table
1028     *  int first_key           first (and lowest) switch case value
1029     *  int targets[size]       branch targets, relative to switch opcode
1030     *
1031     * Total size is (4+size*2) 16-bit code units.
1032     */
1033    if (*switchData++ != kPackedSwitchSignature) {
1034        /* should have been caught by verifier */
1035        dvmThrowInternalError("bad packed switch magic");
1036        return kInstrLen;
1037    }
1038
1039    size = *switchData++;
1040    assert(size > 0);
1041
1042    firstKey = *switchData++;
1043    firstKey |= (*switchData++) << 16;
1044
1045    if (testVal < firstKey || testVal >= firstKey + size) {
1046        LOGVV("Value %d not found in switch (%d-%d)\n",
1047            testVal, firstKey, firstKey+size-1);
1048        return kInstrLen;
1049    }
1050
1051    /* The entries are guaranteed to be aligned on a 32-bit boundary;
1052     * we can treat them as a native int array.
1053     */
1054    entries = (const s4*) switchData;
1055    assert(((u4)entries & 0x3) == 0);
1056
1057    assert(testVal - firstKey >= 0 && testVal - firstKey < size);
1058    LOGVV("Value %d found in slot %d (goto 0x%02x)\n",
1059        testVal, testVal - firstKey,
1060        s4FromSwitchData(&entries[testVal - firstKey]));
1061    return s4FromSwitchData(&entries[testVal - firstKey]);
1062}
1063
1064/*
1065 * Find the matching case.  Returns the offset to the handler instructions.
1066 *
1067 * Returns 3 if we don't find a match (it's the size of the sparse-switch
1068 * instruction).
1069 */
1070s4 dvmInterpHandleSparseSwitch(const u2* switchData, s4 testVal)
1071{
1072    const int kInstrLen = 3;
1073    u2 size;
1074    const s4* keys;
1075    const s4* entries;
1076
1077    /*
1078     * Sparse switch data format:
1079     *  ushort ident = 0x0200   magic value
1080     *  ushort size             number of entries in the table; > 0
1081     *  int keys[size]          keys, sorted low-to-high; 32-bit aligned
1082     *  int targets[size]       branch targets, relative to switch opcode
1083     *
1084     * Total size is (2+size*4) 16-bit code units.
1085     */
1086
1087    if (*switchData++ != kSparseSwitchSignature) {
1088        /* should have been caught by verifier */
1089        dvmThrowInternalError("bad sparse switch magic");
1090        return kInstrLen;
1091    }
1092
1093    size = *switchData++;
1094    assert(size > 0);
1095
1096    /* The keys are guaranteed to be aligned on a 32-bit boundary;
1097     * we can treat them as a native int array.
1098     */
1099    keys = (const s4*) switchData;
1100    assert(((u4)keys & 0x3) == 0);
1101
1102    /* The entries are guaranteed to be aligned on a 32-bit boundary;
1103     * we can treat them as a native int array.
1104     */
1105    entries = keys + size;
1106    assert(((u4)entries & 0x3) == 0);
1107
1108    /*
1109     * Binary-search through the array of keys, which are guaranteed to
1110     * be sorted low-to-high.
1111     */
1112    int lo = 0;
1113    int hi = size - 1;
1114    while (lo <= hi) {
1115        int mid = (lo + hi) >> 1;
1116
1117        s4 foundVal = s4FromSwitchData(&keys[mid]);
1118        if (testVal < foundVal) {
1119            hi = mid - 1;
1120        } else if (testVal > foundVal) {
1121            lo = mid + 1;
1122        } else {
1123            LOGVV("Value %d found in entry %d (goto 0x%02x)\n",
1124                testVal, mid, s4FromSwitchData(&entries[mid]));
1125            return s4FromSwitchData(&entries[mid]);
1126        }
1127    }
1128
1129    LOGVV("Value %d not found in switch\n", testVal);
1130    return kInstrLen;
1131}
1132
1133/*
1134 * Copy data for a fill-array-data instruction.  On a little-endian machine
1135 * we can just do a memcpy(), on a big-endian system we have work to do.
1136 *
1137 * The trick here is that dexopt has byte-swapped each code unit, which is
1138 * exactly what we want for short/char data.  For byte data we need to undo
1139 * the swap, and for 4- or 8-byte values we need to swap pieces within
1140 * each word.
1141 */
1142static void copySwappedArrayData(void* dest, const u2* src, u4 size, u2 width)
1143{
1144#if __BYTE_ORDER == __LITTLE_ENDIAN
1145    memcpy(dest, src, size*width);
1146#else
1147    int i;
1148
1149    switch (width) {
1150    case 1:
1151        /* un-swap pairs of bytes as we go */
1152        for (i = (size-1) & ~1; i >= 0; i -= 2) {
1153            ((u1*)dest)[i] = ((u1*)src)[i+1];
1154            ((u1*)dest)[i+1] = ((u1*)src)[i];
1155        }
1156        /*
1157         * "src" is padded to end on a two-byte boundary, but we don't want to
1158         * assume "dest" is, so we handle odd length specially.
1159         */
1160        if ((size & 1) != 0) {
1161            ((u1*)dest)[size-1] = ((u1*)src)[size];
1162        }
1163        break;
1164    case 2:
1165        /* already swapped correctly */
1166        memcpy(dest, src, size*width);
1167        break;
1168    case 4:
1169        /* swap word halves */
1170        for (i = 0; i < (int) size; i++) {
1171            ((u4*)dest)[i] = (src[(i << 1) + 1] << 16) | src[i << 1];
1172        }
1173        break;
1174    case 8:
1175        /* swap word halves and words */
1176        for (i = 0; i < (int) (size << 1); i += 2) {
1177            ((int*)dest)[i] = (src[(i << 1) + 3] << 16) | src[(i << 1) + 2];
1178            ((int*)dest)[i+1] = (src[(i << 1) + 1] << 16) | src[i << 1];
1179        }
1180        break;
1181    default:
1182        LOGE("Unexpected width %d in copySwappedArrayData\n", width);
1183        dvmAbort();
1184        break;
1185    }
1186#endif
1187}
1188
1189/*
1190 * Fill the array with predefined constant values.
1191 *
1192 * Returns true if job is completed, otherwise false to indicate that
1193 * an exception has been thrown.
1194 */
1195bool dvmInterpHandleFillArrayData(ArrayObject* arrayObj, const u2* arrayData)
1196{
1197    u2 width;
1198    u4 size;
1199
1200    if (arrayObj == NULL) {
1201        dvmThrowNullPointerException(NULL);
1202        return false;
1203    }
1204    assert (!IS_CLASS_FLAG_SET(((Object *)arrayObj)->clazz,
1205                               CLASS_ISOBJECTARRAY));
1206
1207    /*
1208     * Array data table format:
1209     *  ushort ident = 0x0300   magic value
1210     *  ushort width            width of each element in the table
1211     *  uint   size             number of elements in the table
1212     *  ubyte  data[size*width] table of data values (may contain a single-byte
1213     *                          padding at the end)
1214     *
1215     * Total size is 4+(width * size + 1)/2 16-bit code units.
1216     */
1217    if (arrayData[0] != kArrayDataSignature) {
1218        dvmThrowInternalError("bad array data magic");
1219        return false;
1220    }
1221
1222    width = arrayData[1];
1223    size = arrayData[2] | (((u4)arrayData[3]) << 16);
1224
1225    if (size > arrayObj->length) {
1226        dvmThrowArrayIndexOutOfBoundsException(arrayObj->length, size);
1227        return false;
1228    }
1229    copySwappedArrayData(arrayObj->contents, &arrayData[4], size, width);
1230    return true;
1231}
1232
1233/*
1234 * Find the concrete method that corresponds to "methodIdx".  The code in
1235 * "method" is executing invoke-method with "thisClass" as its first argument.
1236 *
1237 * Returns NULL with an exception raised on failure.
1238 */
1239Method* dvmInterpFindInterfaceMethod(ClassObject* thisClass, u4 methodIdx,
1240    const Method* method, DvmDex* methodClassDex)
1241{
1242    Method* absMethod;
1243    Method* methodToCall;
1244    int i, vtableIndex;
1245
1246    /*
1247     * Resolve the method.  This gives us the abstract method from the
1248     * interface class declaration.
1249     */
1250    absMethod = dvmDexGetResolvedMethod(methodClassDex, methodIdx);
1251    if (absMethod == NULL) {
1252        absMethod = dvmResolveInterfaceMethod(method->clazz, methodIdx);
1253        if (absMethod == NULL) {
1254            LOGV("+ unknown method\n");
1255            return NULL;
1256        }
1257    }
1258
1259    /* make sure absMethod->methodIndex means what we think it means */
1260    assert(dvmIsAbstractMethod(absMethod));
1261
1262    /*
1263     * Run through the "this" object's iftable.  Find the entry for
1264     * absMethod's class, then use absMethod->methodIndex to find
1265     * the method's entry.  The value there is the offset into our
1266     * vtable of the actual method to execute.
1267     *
1268     * The verifier does not guarantee that objects stored into
1269     * interface references actually implement the interface, so this
1270     * check cannot be eliminated.
1271     */
1272    for (i = 0; i < thisClass->iftableCount; i++) {
1273        if (thisClass->iftable[i].clazz == absMethod->clazz)
1274            break;
1275    }
1276    if (i == thisClass->iftableCount) {
1277        /* impossible in verified DEX, need to check for it in unverified */
1278        dvmThrowIncompatibleClassChangeError("interface not implemented");
1279        return NULL;
1280    }
1281
1282    assert(absMethod->methodIndex <
1283        thisClass->iftable[i].clazz->virtualMethodCount);
1284
1285    vtableIndex =
1286        thisClass->iftable[i].methodIndexArray[absMethod->methodIndex];
1287    assert(vtableIndex >= 0 && vtableIndex < thisClass->vtableCount);
1288    methodToCall = thisClass->vtable[vtableIndex];
1289
1290#if 0
1291    /* this can happen when there's a stale class file */
1292    if (dvmIsAbstractMethod(methodToCall)) {
1293        dvmThrowAbstractMethodError("interface method not implemented");
1294        return NULL;
1295    }
1296#else
1297    assert(!dvmIsAbstractMethod(methodToCall) ||
1298        methodToCall->nativeFunc != NULL);
1299#endif
1300
1301    LOGVV("+++ interface=%s.%s concrete=%s.%s\n",
1302        absMethod->clazz->descriptor, absMethod->name,
1303        methodToCall->clazz->descriptor, methodToCall->name);
1304    assert(methodToCall != NULL);
1305
1306    return methodToCall;
1307}
1308
1309
1310
1311/*
1312 * Helpers for dvmThrowVerificationError().
1313 *
1314 * Each returns a newly-allocated string.
1315 */
1316#define kThrowShow_accessFromClass     1
1317static char* classNameFromIndex(const Method* method, int ref,
1318    VerifyErrorRefType refType, int flags)
1319{
1320    static const int kBufLen = 256;
1321    const DvmDex* pDvmDex = method->clazz->pDvmDex;
1322
1323    if (refType == VERIFY_ERROR_REF_FIELD) {
1324        /* get class ID from field ID */
1325        const DexFieldId* pFieldId = dexGetFieldId(pDvmDex->pDexFile, ref);
1326        ref = pFieldId->classIdx;
1327    } else if (refType == VERIFY_ERROR_REF_METHOD) {
1328        /* get class ID from method ID */
1329        const DexMethodId* pMethodId = dexGetMethodId(pDvmDex->pDexFile, ref);
1330        ref = pMethodId->classIdx;
1331    }
1332
1333    const char* className = dexStringByTypeIdx(pDvmDex->pDexFile, ref);
1334    char* dotClassName = dvmHumanReadableDescriptor(className);
1335    if (flags == 0)
1336        return dotClassName;
1337
1338    char* result = (char*) malloc(kBufLen);
1339
1340    if ((flags & kThrowShow_accessFromClass) != 0) {
1341        char* dotFromName =
1342            dvmHumanReadableDescriptor(method->clazz->descriptor);
1343        snprintf(result, kBufLen, "tried to access class %s from class %s",
1344            dotClassName, dotFromName);
1345        free(dotFromName);
1346    } else {
1347        assert(false);      // should've been caught above
1348        result[0] = '\0';
1349    }
1350
1351    free(dotClassName);
1352    return result;
1353}
1354static char* fieldNameFromIndex(const Method* method, int ref,
1355    VerifyErrorRefType refType, int flags)
1356{
1357    static const int kBufLen = 256;
1358    const DvmDex* pDvmDex = method->clazz->pDvmDex;
1359    const DexFieldId* pFieldId;
1360    const char* className;
1361    const char* fieldName;
1362
1363    if (refType != VERIFY_ERROR_REF_FIELD) {
1364        LOGW("Expected ref type %d, got %d\n", VERIFY_ERROR_REF_FIELD, refType);
1365        return NULL;    /* no message */
1366    }
1367
1368    pFieldId = dexGetFieldId(pDvmDex->pDexFile, ref);
1369    className = dexStringByTypeIdx(pDvmDex->pDexFile, pFieldId->classIdx);
1370    fieldName = dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx);
1371
1372    char* dotName = dvmHumanReadableDescriptor(className);
1373    char* result = (char*) malloc(kBufLen);
1374
1375    if ((flags & kThrowShow_accessFromClass) != 0) {
1376        char* dotFromName =
1377            dvmHumanReadableDescriptor(method->clazz->descriptor);
1378        snprintf(result, kBufLen, "tried to access field %s.%s from class %s",
1379            dotName, fieldName, dotFromName);
1380        free(dotFromName);
1381    } else {
1382        snprintf(result, kBufLen, "%s.%s", dotName, fieldName);
1383    }
1384
1385    free(dotName);
1386    return result;
1387}
1388static char* methodNameFromIndex(const Method* method, int ref,
1389    VerifyErrorRefType refType, int flags)
1390{
1391    static const int kBufLen = 384;
1392    const DvmDex* pDvmDex = method->clazz->pDvmDex;
1393    const DexMethodId* pMethodId;
1394    const char* className;
1395    const char* methodName;
1396
1397    if (refType != VERIFY_ERROR_REF_METHOD) {
1398        LOGW("Expected ref type %d, got %d\n", VERIFY_ERROR_REF_METHOD,refType);
1399        return NULL;    /* no message */
1400    }
1401
1402    pMethodId = dexGetMethodId(pDvmDex->pDexFile, ref);
1403    className = dexStringByTypeIdx(pDvmDex->pDexFile, pMethodId->classIdx);
1404    methodName = dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx);
1405
1406    char* dotName = dvmHumanReadableDescriptor(className);
1407    char* result = (char*) malloc(kBufLen);
1408
1409    if ((flags & kThrowShow_accessFromClass) != 0) {
1410        char* dotFromName =
1411            dvmHumanReadableDescriptor(method->clazz->descriptor);
1412        char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
1413        snprintf(result, kBufLen,
1414            "tried to access method %s.%s:%s from class %s",
1415            dotName, methodName, desc, dotFromName);
1416        free(dotFromName);
1417        free(desc);
1418    } else {
1419        snprintf(result, kBufLen, "%s.%s", dotName, methodName);
1420    }
1421
1422    free(dotName);
1423    return result;
1424}
1425
1426/*
1427 * Throw an exception for a problem identified by the verifier.
1428 *
1429 * This is used by the invoke-verification-error instruction.  It always
1430 * throws an exception.
1431 *
1432 * "kind" indicates the kind of failure encountered by the verifier.  It
1433 * has two parts, an error code and an indication of the reference type.
1434 */
1435void dvmThrowVerificationError(const Method* method, int kind, int ref)
1436{
1437    int errorPart = kind & ~(0xff << kVerifyErrorRefTypeShift);
1438    int errorRefPart = kind >> kVerifyErrorRefTypeShift;
1439    VerifyError errorKind = static_cast<VerifyError>(errorPart);
1440    VerifyErrorRefType refType = static_cast<VerifyErrorRefType>(errorRefPart);
1441    ClassObject* exceptionClass = gDvm.exVerifyError;
1442    char* msg = NULL;
1443
1444    switch ((VerifyError) errorKind) {
1445    case VERIFY_ERROR_NO_CLASS:
1446        exceptionClass = gDvm.exNoClassDefFoundError;
1447        msg = classNameFromIndex(method, ref, refType, 0);
1448        break;
1449    case VERIFY_ERROR_NO_FIELD:
1450        exceptionClass = gDvm.exNoSuchFieldError;
1451        msg = fieldNameFromIndex(method, ref, refType, 0);
1452        break;
1453    case VERIFY_ERROR_NO_METHOD:
1454        exceptionClass = gDvm.exNoSuchMethodError;
1455        msg = methodNameFromIndex(method, ref, refType, 0);
1456        break;
1457    case VERIFY_ERROR_ACCESS_CLASS:
1458        exceptionClass = gDvm.exIllegalAccessError;
1459        msg = classNameFromIndex(method, ref, refType,
1460            kThrowShow_accessFromClass);
1461        break;
1462    case VERIFY_ERROR_ACCESS_FIELD:
1463        exceptionClass = gDvm.exIllegalAccessError;
1464        msg = fieldNameFromIndex(method, ref, refType,
1465            kThrowShow_accessFromClass);
1466        break;
1467    case VERIFY_ERROR_ACCESS_METHOD:
1468        exceptionClass = gDvm.exIllegalAccessError;
1469        msg = methodNameFromIndex(method, ref, refType,
1470            kThrowShow_accessFromClass);
1471        break;
1472    case VERIFY_ERROR_CLASS_CHANGE:
1473        exceptionClass = gDvm.exIncompatibleClassChangeError;
1474        msg = classNameFromIndex(method, ref, refType, 0);
1475        break;
1476    case VERIFY_ERROR_INSTANTIATION:
1477        exceptionClass = gDvm.exInstantiationError;
1478        msg = classNameFromIndex(method, ref, refType, 0);
1479        break;
1480
1481    case VERIFY_ERROR_GENERIC:
1482        /* generic VerifyError; use default exception, no message */
1483        break;
1484    case VERIFY_ERROR_NONE:
1485        /* should never happen; use default exception */
1486        assert(false);
1487        msg = strdup("weird - no error specified");
1488        break;
1489
1490    /* no default clause -- want warning if enum updated */
1491    }
1492
1493    dvmThrowException(exceptionClass, msg);
1494    free(msg);
1495}
1496
1497/*
1498 * Update interpBreak.  If there is an active break when
1499 * we're done, set altHandlerTable.  Otherwise, revert to
1500 * the non-breaking table base.
1501 */
1502void dvmUpdateInterpBreak(Thread* thread, int newBreak, int newMode,
1503                          bool enable)
1504{
1505    InterpBreak oldValue, newValue;
1506
1507    // Do not use this routine for suspend updates.  See below.
1508    assert((newBreak & kInterpSuspendBreak) == 0);
1509
1510    do {
1511        oldValue = newValue = thread->interpBreak;
1512        if (enable) {
1513            newValue.ctl.breakFlags |= newBreak;
1514            newValue.ctl.subMode |= newMode;
1515        } else {
1516            newValue.ctl.breakFlags &= ~newBreak;
1517            newValue.ctl.subMode &= ~newMode;
1518        }
1519        newValue.ctl.curHandlerTable = (newValue.ctl.breakFlags) ?
1520            thread->altHandlerTable : thread->mainHandlerTable;
1521    } while (dvmQuasiAtomicCas64(oldValue.all, newValue.all,
1522             &thread->interpBreak.all) != 0);
1523}
1524
1525/*
1526 * Update the normal and debugger suspend counts for a thread.
1527 * threadSuspendCount must be acquired before calling this to
1528 * ensure a clean update of suspendCount, dbgSuspendCount and
1529 * sumThreadSuspendCount.  suspendCount & dbgSuspendCount must
1530 * use the atomic update to avoid conflict with writes to the
1531 * other fields in interpBreak.
1532 *
1533 * CLEANUP TODO: Currently only the JIT is using sumThreadSuspendCount.
1534 * Move under WITH_JIT ifdefs.
1535*/
1536void dvmAddToSuspendCounts(Thread* thread, int delta, int dbgDelta)
1537{
1538    InterpBreak oldValue, newValue;
1539
1540    do {
1541        oldValue = newValue = thread->interpBreak;
1542        newValue.ctl.suspendCount += delta;
1543        newValue.ctl.dbgSuspendCount += dbgDelta;
1544        assert(newValue.ctl.suspendCount >= newValue.ctl.dbgSuspendCount);
1545        if (newValue.ctl.suspendCount > 0) {
1546            newValue.ctl.breakFlags |= kInterpSuspendBreak;
1547        } else {
1548            newValue.ctl.breakFlags &= ~kInterpSuspendBreak;
1549        }
1550        newValue.ctl.curHandlerTable = (newValue.ctl.breakFlags) ?
1551            thread->altHandlerTable : thread->mainHandlerTable;
1552    } while (dvmQuasiAtomicCas64(oldValue.all, newValue.all,
1553             &thread->interpBreak.all) != 0);
1554
1555    // Update the global suspend count total
1556    gDvm.sumThreadSuspendCount += delta;
1557}
1558
1559/*
1560 * Update interpBreak for all threads.
1561 */
1562void dvmUpdateAllInterpBreak(int newBreak, int newMode, bool enable)
1563{
1564    Thread* self = dvmThreadSelf();
1565    Thread* thread;
1566
1567    dvmLockThreadList(self);
1568    for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
1569        dvmUpdateInterpBreak(thread, newBreak, newMode, enable);
1570    }
1571    dvmUnlockThreadList();
1572}
1573
1574/*
1575 * Do a sanity check on interpreter state saved to Thread.
1576 * A failure here doesn't necessarily mean that something is wrong,
1577 * so this code should only be used during development to suggest
1578 * a possible problem.
1579 */
1580void dvmCheckInterpStateConsistency()
1581{
1582    Thread* self = dvmThreadSelf();
1583    Thread* thread;
1584    uint8_t breakFlags;
1585    uint8_t subMode;
1586    void* handlerTable;
1587
1588    dvmLockThreadList(self);
1589    breakFlags = self->interpBreak.ctl.breakFlags;
1590    subMode = self->interpBreak.ctl.subMode;
1591    handlerTable = self->interpBreak.ctl.curHandlerTable;
1592    for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
1593        if (subMode != thread->interpBreak.ctl.subMode) {
1594            LOGD("Warning: subMode mismatch - 0x%x:0x%x, tid[%d]",
1595                subMode,thread->interpBreak.ctl.subMode,thread->threadId);
1596         }
1597        if (breakFlags != thread->interpBreak.ctl.breakFlags) {
1598            LOGD("Warning: breakFlags mismatch - 0x%x:0x%x, tid[%d]",
1599                breakFlags,thread->interpBreak.ctl.breakFlags,thread->threadId);
1600         }
1601        if (handlerTable != thread->interpBreak.ctl.curHandlerTable) {
1602            LOGD("Warning: curHandlerTable mismatch - 0x%x:0x%x, tid[%d]",
1603                (int)handlerTable,(int)thread->interpBreak.ctl.curHandlerTable,
1604                thread->threadId);
1605         }
1606#if defined(WITH_JIT)
1607         if (thread->pJitProfTable != gDvmJit.pProfTable) {
1608             LOGD("Warning: pJitProfTable mismatch - 0x%x:0x%x, tid[%d]",
1609                  (int)thread->pJitProfTable,(int)gDvmJit.pProfTable,
1610                  thread->threadId);
1611         }
1612         if (thread->jitThreshold != gDvmJit.threshold) {
1613             LOGD("Warning: jitThreshold mismatch - 0x%x:0x%x, tid[%d]",
1614                  (int)thread->jitThreshold,(int)gDvmJit.threshold,
1615                  thread->threadId);
1616         }
1617#endif
1618    }
1619    dvmUnlockThreadList();
1620}
1621
1622/*
1623 * Arm a safepoint callback for a thread.  If funct is null,
1624 * clear any pending callback.
1625 * TODO: only gc is currently using this feature, and will have
1626 * at most a single outstanding callback request.  Until we need
1627 * something more capable and flexible, enforce this limit.
1628 */
1629void dvmArmSafePointCallback(Thread* thread, SafePointCallback funct,
1630                             void* arg)
1631{
1632    dvmLockMutex(&thread->callbackMutex);
1633    if ((funct == NULL) || (thread->callback == NULL)) {
1634        thread->callback = funct;
1635        thread->callbackArg = arg;
1636        dvmUpdateInterpBreak(thread, kInterpSafePointCallback,
1637                             kSubModeNormal, (funct != NULL));
1638    } else {
1639        // Already armed.  Different?
1640        if ((funct != thread->callback) ||
1641            (arg != thread->callbackArg)) {
1642            // Yes - report failure and die
1643            LOGE("ArmSafePointCallback failed, thread %d", thread->threadId);
1644            dvmUnlockMutex(&thread->callbackMutex);
1645            dvmAbort();
1646        }
1647    }
1648    dvmUnlockMutex(&thread->callbackMutex);
1649}
1650
1651/*
1652 * One-time initialization at thread creation.  Here we initialize
1653 * useful constants.
1654 */
1655void dvmInitInterpreterState(Thread* self)
1656{
1657#if defined(WITH_JIT)
1658    /*
1659     * Reserve a static entity here to quickly setup runtime contents as
1660     * gcc will issue block copy instructions.
1661     */
1662    static struct JitToInterpEntries jitToInterpEntries = {
1663        dvmJitToInterpNormal,
1664        dvmJitToInterpNoChain,
1665        dvmJitToInterpPunt,
1666        dvmJitToInterpSingleStep,
1667        dvmJitToInterpTraceSelect,
1668#if defined(WITH_SELF_VERIFICATION)
1669        dvmJitToInterpBackwardBranch,
1670#else
1671        NULL,
1672#endif
1673    };
1674#endif
1675
1676    // Begin initialization
1677    self->cardTable = gDvm.biasedCardTableBase;
1678#if defined(WITH_JIT)
1679    // One-time initializations
1680    self->jitToInterpEntries = jitToInterpEntries;
1681    self->icRechainCount = PREDICTED_CHAIN_COUNTER_RECHAIN;
1682    self->pProfileCountdown = &gDvmJit.profileCountdown;
1683    // Jit state that can change
1684    dvmJitUpdateThreadStateSingle(self);
1685#endif
1686}
1687
1688/*
1689 * For a newly-created thread, we need to start off with interpBreak
1690 * set to any existing global modes.  The caller must hold the
1691 * thread list lock.
1692 */
1693void dvmInitializeInterpBreak(Thread* thread)
1694{
1695    u1 flags = 0;
1696    u1 subModes = 0;
1697
1698    if (gDvm.instructionCountEnableCount > 0) {
1699        flags |= kInterpInstCountBreak;
1700        subModes |= kSubModeInstCounting;
1701    }
1702    if (dvmIsMethodTraceActive()) {
1703        subModes |= kSubModeMethodTrace;
1704    }
1705    if (gDvm.debuggerActive) {
1706        flags |= kInterpDebugBreak;
1707        subModes |= kSubModeDebuggerActive;
1708    }
1709    dvmUpdateInterpBreak(thread, flags, subModes, true);
1710}
1711
1712/*
1713 * Inter-instruction handler invoked in between instruction interpretations
1714 * to handle exceptional events such as debugging housekeeping, instruction
1715 * count profiling, JIT trace building, etc.  Dalvik PC has been exported
1716 * prior to call, but Thread copy of dPC & fp are not current.
1717 */
1718void dvmCheckBefore(const u2 *pc, u4 *fp, Thread* self)
1719{
1720    const Method* method = self->interpSave.method;
1721    assert(self->interpBreak.ctl.breakFlags != 0);
1722    assert(pc >= method->insns && pc <
1723           method->insns + dvmGetMethodInsnsSize(method));
1724
1725#if 0
1726    /*
1727     * When we hit a specific method, enable verbose instruction logging.
1728     * Sometimes it's helpful to use the debugger attach as a trigger too.
1729     */
1730    if (*pIsMethodEntry) {
1731        static const char* cd = "Landroid/test/Arithmetic;";
1732        static const char* mn = "shiftTest2";
1733        static const char* sg = "()V";
1734
1735        if (/*self->interpBreak.ctl.subMode & kSubModeDebuggerActive &&*/
1736            strcmp(method->clazz->descriptor, cd) == 0 &&
1737            strcmp(method->name, mn) == 0 &&
1738            strcmp(method->shorty, sg) == 0)
1739        {
1740            LOGW("Reached %s.%s, enabling verbose mode\n",
1741                method->clazz->descriptor, method->name);
1742            android_setMinPriority(LOG_TAG"i", ANDROID_LOG_VERBOSE);
1743            dumpRegs(method, fp, true);
1744        }
1745
1746        if (!gDvm.debuggerActive)
1747            *pIsMethodEntry = false;
1748    }
1749#endif
1750
1751    /* Safe point handling */
1752    if (self->interpBreak.ctl.suspendCount ||
1753        (self->interpBreak.ctl.breakFlags & kInterpSafePointCallback)) {
1754        // Are we are a safe point?
1755        int flags;
1756        flags = dexGetFlagsFromOpcode(dexOpcodeFromCodeUnit(*pc));
1757        if (flags & VERIFY_GC_INST_MASK) {
1758            // Yes, at a safe point.  Pending callback?
1759            if (self->interpBreak.ctl.breakFlags & kInterpSafePointCallback) {
1760                SafePointCallback callback;
1761                void* arg;
1762                // Get consistent funct/arg pair
1763                dvmLockMutex(&self->callbackMutex);
1764                callback = self->callback;
1765                arg = self->callbackArg;
1766                dvmUnlockMutex(&self->callbackMutex);
1767                // Update Thread structure
1768                self->interpSave.pc = pc;
1769                self->interpSave.fp = fp;
1770                if (callback != NULL) {
1771                    // Do the callback
1772                    if (!callback(self,arg)) {
1773                        // disarm
1774                        dvmArmSafePointCallback(self, NULL, NULL);
1775                    }
1776                }
1777            }
1778            // Need to suspend?
1779            if (self->interpBreak.ctl.suspendCount) {
1780                dvmExportPC(pc, fp);
1781                dvmCheckSuspendPending(self);
1782            }
1783        }
1784    }
1785
1786    if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
1787        updateDebugger(method, pc, fp, self);
1788    }
1789    if (gDvm.instructionCountEnableCount != 0) {
1790        /*
1791         * Count up the #of executed instructions.  This isn't synchronized
1792         * for thread-safety; if we need that we should make this
1793         * thread-local and merge counts into the global area when threads
1794         * exit (perhaps suspending all other threads GC-style and pulling
1795         * the data out of them).
1796         */
1797        gDvm.executedInstrCounts[GET_OPCODE(*pc)]++;
1798    }
1799
1800
1801#if defined(WITH_TRACKREF_CHECKS)
1802    dvmInterpCheckTrackedRefs(self, method,
1803                              self->interpSave.debugTrackedRefStart);
1804#endif
1805
1806#if defined(WITH_JIT)
1807    // Does the JIT need anything done now?
1808    if (self->interpBreak.ctl.breakFlags & kInterpJitBreak) {
1809        // Are we building a trace?
1810        if (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) {
1811            dvmCheckJit(pc, self);
1812        }
1813
1814#if defined(WITH_SELF_VERIFICATION)
1815        // Are we replaying a trace?
1816        if (self->interpBreak.ctl.subMode & kSubModeJitSV) {
1817            dvmCheckSelfVerification(pc, self);
1818        }
1819#endif
1820    }
1821#endif
1822
1823    /*
1824     * SingleStep processing.  NOTE: must be the last here to allow
1825     * preceeding special case handler to manipulate single-step count.
1826     */
1827    if (self->interpBreak.ctl.breakFlags & kInterpSingleStep) {
1828        if (self->singleStepCount == 0) {
1829            // We've exhausted our single step count
1830            dvmUpdateInterpBreak(self, kInterpSingleStep, kSubModeNormal,
1831                                 false /* remove */);
1832#if defined(WITH_JIT)
1833#if 0
1834            /*
1835             * For debugging.  If jitResumeDPC is non-zero, then
1836             * we expect to return to a trace in progress.   There
1837             * are valid reasons why we wouldn't (such as an exception
1838             * throw), but here we can keep track.
1839             */
1840            if (self->jitResumeDPC != NULL) {
1841                if (self->jitResumeDPC == pc) {
1842                    if (self->jitResumeNPC != NULL) {
1843                        LOGD("SS return to trace - pc:0x%x to 0x:%x",
1844                             (int)pc, (int)self->jitResumeNPC);
1845                    } else {
1846                        LOGD("SS return to interp - pc:0x%x",(int)pc);
1847                    }
1848                } else {
1849                    LOGD("SS failed to return.  Expected 0x%x, now at 0x%x",
1850                         (int)self->jitResumeDPC, (int)pc);
1851                }
1852            }
1853#endif
1854            // If we've got a native return and no other reasons to
1855            // remain in singlestep/break mode, do a long jump
1856            if (self->jitResumeNPC != NULL &&
1857                self->interpBreak.ctl.breakFlags == 0) {
1858                assert(self->jitResumeDPC == pc);
1859                self->jitResumeDPC = NULL;
1860                dvmJitResumeTranslation(self, pc, fp);
1861                // Doesn't return
1862                dvmAbort();
1863            }
1864            self->jitResumeDPC = NULL;
1865            self->inJitCodeCache = NULL;
1866#endif
1867        } else {
1868            self->singleStepCount--;
1869#if defined(WITH_JIT)
1870            if ((self->singleStepCount > 0) && (self->jitResumeNPC != NULL)) {
1871                /*
1872                 * Direct return to an existing translation following a
1873                 * single step is valid only if we step once.  If we're
1874                 * here, an additional step was added so we need to invalidate
1875                 * the return to translation.
1876                 */
1877                self->jitResumeNPC = NULL;
1878                self->inJitCodeCache = NULL;
1879            }
1880#endif
1881        }
1882    }
1883}
1884
1885/*
1886 * Main interpreter loop entry point.
1887 *
1888 * This begins executing code at the start of "method".  On exit, "pResult"
1889 * holds the return value of the method (or, if "method" returns NULL, it
1890 * holds an undefined value).
1891 *
1892 * The interpreted stack frame, which holds the method arguments, has
1893 * already been set up.
1894 */
1895void dvmInterpret(Thread* self, const Method* method, JValue* pResult)
1896{
1897    InterpSaveState interpSaveState;
1898    int savedBreakFlags;
1899    int savedSubModes;
1900
1901#if defined(WITH_JIT)
1902    /* Target-specific save/restore */
1903    double calleeSave[JIT_CALLEE_SAVE_DOUBLE_COUNT];
1904    /*
1905     * If the previous VM left the code cache through single-stepping the
1906     * inJitCodeCache flag will be set when the VM is re-entered (for example,
1907     * in self-verification mode we single-step NEW_INSTANCE which may re-enter
1908     * the VM through findClassFromLoaderNoInit). Because of that, we cannot
1909     * assert that self->inJitCodeCache is NULL here.
1910     */
1911#endif
1912
1913    /*
1914     * Save interpreter state from previous activation, linking
1915     * new to last.
1916     */
1917    interpSaveState = self->interpSave;
1918    self->interpSave.prev = &interpSaveState;
1919    /*
1920     * Strip out and save any flags that should not be inherited by
1921     * nested interpreter activation.
1922     */
1923    savedBreakFlags = self->interpBreak.ctl.breakFlags & LOCAL_BREAKFLAGS;
1924    savedSubModes = self->interpBreak.ctl.subMode & LOCAL_SUBMODE;
1925    if (savedBreakFlags | savedSubModes) {
1926        dvmUpdateInterpBreak(self, savedBreakFlags, savedSubModes,
1927                             false /*disable*/);
1928    }
1929#if defined(WITH_JIT)
1930    dvmJitCalleeSave(calleeSave);
1931#endif
1932
1933
1934#if defined(WITH_TRACKREF_CHECKS)
1935    self->interpSave.debugTrackedRefStart =
1936        dvmReferenceTableEntries(&self->internalLocalRefTable);
1937#endif
1938    self->debugIsMethodEntry = true;
1939#if defined(WITH_JIT)
1940    dvmJitCalleeSave(calleeSave);
1941    /* Initialize the state to kJitNot */
1942    self->jitState = kJitNot;
1943#endif
1944
1945    /*
1946     * Initialize working state.
1947     *
1948     * No need to initialize "retval".
1949     */
1950    self->interpSave.method = method;
1951    self->interpSave.fp = (u4*) self->curFrame;
1952    self->interpSave.pc = method->insns;
1953
1954    assert(!dvmIsNativeMethod(method));
1955
1956    /*
1957     * Make sure the class is ready to go.  Shouldn't be possible to get
1958     * here otherwise.
1959     */
1960    if (method->clazz->status < CLASS_INITIALIZING ||
1961        method->clazz->status == CLASS_ERROR)
1962    {
1963        LOGE("ERROR: tried to execute code in unprepared class '%s' (%d)\n",
1964            method->clazz->descriptor, method->clazz->status);
1965        dvmDumpThread(self, false);
1966        dvmAbort();
1967    }
1968
1969    typedef void (*Interpreter)(Thread*);
1970    Interpreter stdInterp;
1971    if (gDvm.executionMode == kExecutionModeInterpFast)
1972        stdInterp = dvmMterpStd;
1973#if defined(WITH_JIT)
1974    else if (gDvm.executionMode == kExecutionModeJit)
1975        stdInterp = dvmMterpStd;
1976#endif
1977    else
1978        stdInterp = dvmInterpretPortable;
1979
1980    // Call the interpreter
1981    (*stdInterp)(self);
1982
1983    *pResult = self->retval;
1984
1985    /* Restore interpreter state from previous activation */
1986    self->interpSave = interpSaveState;
1987#if defined(WITH_JIT)
1988    dvmJitCalleeRestore(calleeSave);
1989#endif
1990    if (savedBreakFlags | savedSubModes) {
1991        dvmUpdateInterpBreak(self, savedBreakFlags, savedSubModes,
1992                             true /*enable*/);
1993    }
1994}
1995