• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
40 static BreakpointSet* dvmBreakpointSetAlloc();
41 static void dvmBreakpointSetFree(BreakpointSet* pSet);
42 
43 #if defined(WITH_JIT)
44 /* Target-specific save/restore */
45 extern "C" void dvmJitCalleeSave(double *saveArea);
46 extern "C" void dvmJitCalleeRestore(double *saveArea);
47 /* Interpreter entry points from compiled code */
48 extern "C" void dvmJitToInterpNormal();
49 extern "C" void dvmJitToInterpNoChain();
50 extern "C" void dvmJitToInterpPunt();
51 extern "C" void dvmJitToInterpSingleStep();
52 extern "C" void dvmJitToInterpTraceSelect();
53 #if defined(WITH_SELF_VERIFICATION)
54 extern "C" void dvmJitToInterpBackwardBranch();
55 #endif
56 #endif
57 
58 /*
59  * Initialize global breakpoint structures.
60  */
dvmBreakpointStartup()61 bool dvmBreakpointStartup()
62 {
63     gDvm.breakpointSet = dvmBreakpointSetAlloc();
64     return (gDvm.breakpointSet != NULL);
65 }
66 
67 /*
68  * Free resources.
69  */
dvmBreakpointShutdown()70 void dvmBreakpointShutdown()
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  */
82 struct Breakpoint {
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 };
88 
89 /*
90  * Set of breakpoints.
91  */
92 struct 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  */
dvmBreakpointSetAlloc()105 static BreakpointSet* dvmBreakpointSetAlloc()
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  */
dvmBreakpointSetFree(BreakpointSet * pSet)118 static 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  */
dvmBreakpointSetLock(BreakpointSet * pSet)135 static 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  */
dvmBreakpointSetUnlock(BreakpointSet * pSet)148 static void dvmBreakpointSetUnlock(BreakpointSet* pSet)
149 {
150     dvmUnlockMutex(&pSet->lock);
151 }
152 
153 /*
154  * Return the #of breakpoints.
155  */
dvmBreakpointSetCount(const BreakpointSet * pSet)156 static 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  */
dvmBreakpointSetFind(const BreakpointSet * pSet,const u2 * addr)168 static 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  */
dvmBreakpointSetOriginalOpcode(const BreakpointSet * pSet,const u2 * addr,u1 * pOrig)188 static 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  */
instructionIsMagicNop(const u2 * addr)216 static 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  */
dvmBreakpointSetAdd(BreakpointSet * pSet,Method * method,unsigned int instrOffset)233 static 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             ALOGV("+++ increasing breakpoint set size to %d", 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             ALOGV("Class %s verified, adding breakpoint at %p",
279                 method->clazz->descriptor, addr);
280             if (instructionIsMagicNop(addr)) {
281                 ALOGV("Refusing to set breakpoint on %04x at %s.%s + %#x",
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             ALOGV("Class %s NOT verified, deferring breakpoint at %p",
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  */
dvmBreakpointSetRemove(BreakpointSet * pSet,Method * method,unsigned int instrOffset)311 static 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             ALOGE("Unable to restore breakpoint opcode (%s.%s +%#x)",
321                 method->clazz->descriptor, method->name, instrOffset);
322             dvmAbort();
323         } else {
324             ALOGW("Breakpoint was already restored? (%s.%s +%#x)",
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  */
dvmBreakpointSetFlush(BreakpointSet * pSet,ClassObject * clazz)364 static 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             ALOGV("Flushing breakpoint at %p for %s",
376                 pBreak->addr, clazz->descriptor);
377             if (instructionIsMagicNop(pBreak->addr)) {
378                 ALOGV("Refusing to flush breakpoint on %04x at %s.%s + %#x",
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  */
dvmInitBreakpoints()393 void dvmInitBreakpoints()
394 {
395     /* quick sanity check */
396     BreakpointSet* pSet = gDvm.breakpointSet;
397     dvmBreakpointSetLock(pSet);
398     if (dvmBreakpointSetCount(pSet) != 0) {
399         ALOGW("WARNING: %d leftover breakpoints", 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  */
dvmAddBreakAddr(Method * method,unsigned int instrOffset)419 void 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  */
dvmClearBreakAddr(Method * method,unsigned int instrOffset)437 void 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  */
dvmGetOriginalOpcode(const u2 * addr)456 u1 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             ALOGE("GLITCH: can't find breakpoint, opcode is still set");
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  */
dvmFlushBreakpoints(ClassObject * clazz)481 void 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  */
dvmAddSingleStep(Thread * thread,int size,int depth)503 bool dvmAddSingleStep(Thread* thread, int size, int depth)
504 {
505     StepControl* pCtrl = &gDvm.stepControl;
506 
507     if (pCtrl->active && thread != pCtrl->thread) {
508         ALOGW("WARNING: single-step active for %p; adding %p",
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     u4* fp;
541     u4* prevFp = NULL;
542 
543     for (fp = thread->interpSave.curFrame; fp != NULL;
544          fp = saveArea->prevFrame) {
545         const Method* method;
546 
547         saveArea = SAVEAREA_FROM_FP(fp);
548         method = saveArea->method;
549 
550         if (!dvmIsBreakFrame((u4*)fp) && !dvmIsNativeMethod(method))
551             break;
552         prevFp = fp;
553     }
554     if (fp == NULL) {
555         ALOGW("Unexpected: step req in native-only threadid=%d",
556             thread->threadId);
557         return false;
558     }
559     if (prevFp != NULL) {
560         /*
561          * First interpreted frame wasn't the one at the bottom.  Break
562          * frames are only inserted when calling from native->interp, so we
563          * don't need to worry about one being here.
564          */
565         ALOGV("##### init step while in native method");
566         fp = prevFp;
567         assert(!dvmIsBreakFrame((u4*)fp));
568         assert(dvmIsNativeMethod(SAVEAREA_FROM_FP(fp)->method));
569         saveArea = SAVEAREA_FROM_FP(fp);
570     }
571 
572     /*
573      * Pull the goodies out.  "xtra.currentPc" should be accurate since
574      * we update it on every instruction while the debugger is connected.
575      */
576     pCtrl->method = saveArea->method;
577     // Clear out any old address set
578     if (pCtrl->pAddressSet != NULL) {
579         // (discard const)
580         free((void *)pCtrl->pAddressSet);
581         pCtrl->pAddressSet = NULL;
582     }
583     if (dvmIsNativeMethod(pCtrl->method)) {
584         pCtrl->line = -1;
585     } else {
586         pCtrl->line = dvmLineNumFromPC(saveArea->method,
587                         saveArea->xtra.currentPc - saveArea->method->insns);
588         pCtrl->pAddressSet
589                 = dvmAddressSetForLine(saveArea->method, pCtrl->line);
590     }
591     pCtrl->frameDepth =
592         dvmComputeVagueFrameDepth(thread, thread->interpSave.curFrame);
593     pCtrl->active = true;
594 
595     ALOGV("##### step init: thread=%p meth=%p '%s' line=%d frameDepth=%d depth=%s size=%s",
596         pCtrl->thread, pCtrl->method, pCtrl->method->name,
597         pCtrl->line, pCtrl->frameDepth,
598         dvmJdwpStepDepthStr(pCtrl->depth),
599         dvmJdwpStepSizeStr(pCtrl->size));
600 
601     return true;
602 }
603 
604 /*
605  * Disable a single step event.
606  */
dvmClearSingleStep(Thread * thread)607 void dvmClearSingleStep(Thread* thread)
608 {
609     UNUSED_PARAMETER(thread);
610 
611     gDvm.stepControl.active = false;
612 }
613 
614 /*
615  * The interpreter just threw.  Handle any special subMode requirements.
616  * All interpSave state must be valid on entry.
617  */
dvmReportExceptionThrow(Thread * self,Object * exception)618 void dvmReportExceptionThrow(Thread* self, Object* exception)
619 {
620     const Method* curMethod = self->interpSave.method;
621 #if defined(WITH_JIT)
622     if (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) {
623         dvmJitEndTraceSelect(self, self->interpSave.pc);
624     }
625     if (self->interpBreak.ctl.breakFlags & kInterpSingleStep) {
626         /* Discard any single-step native returns to translation */
627         self->jitResumeNPC = NULL;
628     }
629 #endif
630     if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
631         void *catchFrame;
632         int offset = self->interpSave.pc - curMethod->insns;
633         int catchRelPc = dvmFindCatchBlock(self, offset, exception,
634                                            true, &catchFrame);
635         dvmDbgPostException(self->interpSave.curFrame, offset, catchFrame,
636                             catchRelPc, exception);
637     }
638 }
639 
640 /*
641  * The interpreter is preparing to do an invoke (both native & normal).
642  * Handle any special subMode requirements.  All interpSave state
643  * must be valid on entry.
644  */
dvmReportInvoke(Thread * self,const Method * methodToCall)645 void dvmReportInvoke(Thread* self, const Method* methodToCall)
646 {
647     TRACE_METHOD_ENTER(self, methodToCall);
648 }
649 
650 /*
651  * The interpreter is preparing to do a native invoke. Handle any
652  * special subMode requirements.  NOTE: for a native invoke,
653  * dvmReportInvoke() and dvmReportPreNativeInvoke() will both
654  * be called prior to the invoke.  fp is the Dalvik FP of the calling
655  * method.
656  */
dvmReportPreNativeInvoke(const Method * methodToCall,Thread * self,u4 * fp)657 void dvmReportPreNativeInvoke(const Method* methodToCall, Thread* self, u4* fp)
658 {
659 #if defined(WITH_JIT)
660     /*
661      * Actively building a trace?  If so, end it now.   The trace
662      * builder can't follow into or through a native method.
663      */
664     if (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) {
665         dvmCheckJit(self->interpSave.pc, self);
666     }
667 #endif
668     if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
669         Object* thisPtr = dvmGetThisPtr(self->interpSave.method, fp);
670         assert(thisPtr == NULL || dvmIsHeapAddress(thisPtr));
671         dvmDbgPostLocationEvent(methodToCall, -1, thisPtr, DBG_METHOD_ENTRY);
672     }
673 }
674 
675 /*
676  * The interpreter has returned from a native invoke. Handle any
677  * special subMode requirements.  fp is the Dalvik FP of the calling
678  * method.
679  */
dvmReportPostNativeInvoke(const Method * methodToCall,Thread * self,u4 * fp)680 void dvmReportPostNativeInvoke(const Method* methodToCall, Thread* self, u4* fp)
681 {
682     if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
683         Object* thisPtr = dvmGetThisPtr(self->interpSave.method, fp);
684         assert(thisPtr == NULL || dvmIsHeapAddress(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  */
dvmReportReturn(Thread * self)696 void dvmReportReturn(Thread* self)
697 {
698     TRACE_METHOD_EXIT(self, self->interpSave.method);
699 #if defined(WITH_JIT)
700     if (dvmIsBreakFrame(self->interpSave.curFrame) &&
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  */
updateDebugger(const Method * method,const u2 * pc,const u4 * fp,Thread * self)731 static 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         ALOGV("+++ breakpoint hit at %p", 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             ALOGV("#####S %s", 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 || opcode == OP_RETURN_VOID_BARRIER ||
850         opcode == OP_RETURN_OBJECT || opcode == OP_RETURN_WIDE)
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 && !dvmIsHeapAddress(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             ALOGE("HEY: invalid 'this' ptr %p (%s.%s %s)", 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  */
dvmGetThisPtr(const Method * method,const u4 * fp)895 Object* 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  */
dvmInterpCheckTrackedRefs(Thread * self,const Method * method,int debugTrackedRefStart)911 void 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         ALOGE("TRACK: unreleased internal reference (prev=%d total=%d)",
924             debugTrackedRefStart, count);
925         desc = dexProtoCopyMethodDescriptor(&method->prototype);
926         ALOGE("       current method is %s.%s %s", method->clazz->descriptor,
927             method->name, desc);
928         free(desc);
929         top = self->internalLocalRefTable.table + debugTrackedRefStart;
930         while (top < self->internalLocalRefTable.nextEntry) {
931             ALOGE("  %p (%s)",
932                  *top,
933                  ((*top)->clazz != NULL) ? (*top)->clazz->descriptor : "");
934             top++;
935         }
936         dvmDumpThread(self, false);
937 
938         dvmAbort();
939     }
940     //ALOGI("TRACK OK");
941 }
942 #endif
943 
944 
945 #ifdef LOG_INSTR
946 /*
947  * Dump the v-registers.  Sent to the ILOG log tag.
948  */
dvmDumpRegs(const Method * method,const u4 * framePtr,bool inOnly)949 void dvmDumpRegs(const Method* method, const u4* framePtr, bool inOnly)
950 {
951     int i, localCount;
952 
953     localCount = method->registersSize - method->insSize;
954 
955     ALOG(LOG_VERBOSE, LOG_TAG"i", "Registers (fp=%p):", framePtr);
956     for (i = method->registersSize-1; i >= 0; i--) {
957         if (i >= localCount) {
958             ALOG(LOG_VERBOSE, LOG_TAG"i", "  v%-2d in%-2d : 0x%08x",
959                 i, i-localCount, framePtr[i]);
960         } else {
961             if (inOnly) {
962                 ALOG(LOG_VERBOSE, LOG_TAG"i", "  [...]");
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             ALOG(LOG_VERBOSE, LOG_TAG"i", "  v%-2d      : 0x%08x %s",
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  * Find the matching case.  Returns the offset to the handler instructions.
995  *
996  * Returns 3 if we don't find a match (it's the size of the packed-switch
997  * instruction).
998  */
dvmInterpHandlePackedSwitch(const u2 * switchData,s4 testVal)999 s4 dvmInterpHandlePackedSwitch(const u2* switchData, s4 testVal)
1000 {
1001     const int kInstrLen = 3;
1002 
1003     /*
1004      * Packed switch data format:
1005      *  ushort ident = 0x0100   magic value
1006      *  ushort size             number of entries in the table
1007      *  int first_key           first (and lowest) switch case value
1008      *  int targets[size]       branch targets, relative to switch opcode
1009      *
1010      * Total size is (4+size*2) 16-bit code units.
1011      */
1012     if (*switchData++ != kPackedSwitchSignature) {
1013         /* should have been caught by verifier */
1014         dvmThrowInternalError("bad packed switch magic");
1015         return kInstrLen;
1016     }
1017 
1018     u2 size = *switchData++;
1019     assert(size > 0);
1020 
1021     s4 firstKey = *switchData++;
1022     firstKey |= (*switchData++) << 16;
1023 
1024     int index = testVal - firstKey;
1025     if (index < 0 || index >= size) {
1026         LOGVV("Value %d not found in switch (%d-%d)",
1027             testVal, firstKey, firstKey+size-1);
1028         return kInstrLen;
1029     }
1030 
1031     /* The entries are guaranteed to be aligned on a 32-bit boundary;
1032      * we can treat them as a native int array.
1033      */
1034     const s4* entries = (const s4*) switchData;
1035     assert(((u4)entries & 0x3) == 0);
1036 
1037     assert(index >= 0 && index < size);
1038     LOGVV("Value %d found in slot %d (goto 0x%02x)",
1039         testVal, index,
1040         s4FromSwitchData(&entries[index]));
1041     return s4FromSwitchData(&entries[index]);
1042 }
1043 
1044 /*
1045  * Find the matching case.  Returns the offset to the handler instructions.
1046  *
1047  * Returns 3 if we don't find a match (it's the size of the sparse-switch
1048  * instruction).
1049  */
dvmInterpHandleSparseSwitch(const u2 * switchData,s4 testVal)1050 s4 dvmInterpHandleSparseSwitch(const u2* switchData, s4 testVal)
1051 {
1052     const int kInstrLen = 3;
1053     u2 size;
1054     const s4* keys;
1055     const s4* entries;
1056 
1057     /*
1058      * Sparse switch data format:
1059      *  ushort ident = 0x0200   magic value
1060      *  ushort size             number of entries in the table; > 0
1061      *  int keys[size]          keys, sorted low-to-high; 32-bit aligned
1062      *  int targets[size]       branch targets, relative to switch opcode
1063      *
1064      * Total size is (2+size*4) 16-bit code units.
1065      */
1066 
1067     if (*switchData++ != kSparseSwitchSignature) {
1068         /* should have been caught by verifier */
1069         dvmThrowInternalError("bad sparse switch magic");
1070         return kInstrLen;
1071     }
1072 
1073     size = *switchData++;
1074     assert(size > 0);
1075 
1076     /* The keys are guaranteed to be aligned on a 32-bit boundary;
1077      * we can treat them as a native int array.
1078      */
1079     keys = (const s4*) switchData;
1080     assert(((u4)keys & 0x3) == 0);
1081 
1082     /* The entries are guaranteed to be aligned on a 32-bit boundary;
1083      * we can treat them as a native int array.
1084      */
1085     entries = keys + size;
1086     assert(((u4)entries & 0x3) == 0);
1087 
1088     /*
1089      * Binary-search through the array of keys, which are guaranteed to
1090      * be sorted low-to-high.
1091      */
1092     int lo = 0;
1093     int hi = size - 1;
1094     while (lo <= hi) {
1095         int mid = (lo + hi) >> 1;
1096 
1097         s4 foundVal = s4FromSwitchData(&keys[mid]);
1098         if (testVal < foundVal) {
1099             hi = mid - 1;
1100         } else if (testVal > foundVal) {
1101             lo = mid + 1;
1102         } else {
1103             LOGVV("Value %d found in entry %d (goto 0x%02x)",
1104                 testVal, mid, s4FromSwitchData(&entries[mid]));
1105             return s4FromSwitchData(&entries[mid]);
1106         }
1107     }
1108 
1109     LOGVV("Value %d not found in switch", testVal);
1110     return kInstrLen;
1111 }
1112 
1113 /*
1114  * Copy data for a fill-array-data instruction.  On a little-endian machine
1115  * we can just do a memcpy(), on a big-endian system we have work to do.
1116  *
1117  * The trick here is that dexopt has byte-swapped each code unit, which is
1118  * exactly what we want for short/char data.  For byte data we need to undo
1119  * the swap, and for 4- or 8-byte values we need to swap pieces within
1120  * each word.
1121  */
copySwappedArrayData(void * dest,const u2 * src,u4 size,u2 width)1122 static void copySwappedArrayData(void* dest, const u2* src, u4 size, u2 width)
1123 {
1124 #if __BYTE_ORDER == __LITTLE_ENDIAN
1125     memcpy(dest, src, size*width);
1126 #else
1127     int i;
1128 
1129     switch (width) {
1130     case 1:
1131         /* un-swap pairs of bytes as we go */
1132         for (i = (size-1) & ~1; i >= 0; i -= 2) {
1133             ((u1*)dest)[i] = ((u1*)src)[i+1];
1134             ((u1*)dest)[i+1] = ((u1*)src)[i];
1135         }
1136         /*
1137          * "src" is padded to end on a two-byte boundary, but we don't want to
1138          * assume "dest" is, so we handle odd length specially.
1139          */
1140         if ((size & 1) != 0) {
1141             ((u1*)dest)[size-1] = ((u1*)src)[size];
1142         }
1143         break;
1144     case 2:
1145         /* already swapped correctly */
1146         memcpy(dest, src, size*width);
1147         break;
1148     case 4:
1149         /* swap word halves */
1150         for (i = 0; i < (int) size; i++) {
1151             ((u4*)dest)[i] = (src[(i << 1) + 1] << 16) | src[i << 1];
1152         }
1153         break;
1154     case 8:
1155         /* swap word halves and words */
1156         for (i = 0; i < (int) (size << 1); i += 2) {
1157             ((int*)dest)[i] = (src[(i << 1) + 3] << 16) | src[(i << 1) + 2];
1158             ((int*)dest)[i+1] = (src[(i << 1) + 1] << 16) | src[i << 1];
1159         }
1160         break;
1161     default:
1162         ALOGE("Unexpected width %d in copySwappedArrayData", width);
1163         dvmAbort();
1164         break;
1165     }
1166 #endif
1167 }
1168 
1169 /*
1170  * Fill the array with predefined constant values.
1171  *
1172  * Returns true if job is completed, otherwise false to indicate that
1173  * an exception has been thrown.
1174  */
dvmInterpHandleFillArrayData(ArrayObject * arrayObj,const u2 * arrayData)1175 bool dvmInterpHandleFillArrayData(ArrayObject* arrayObj, const u2* arrayData)
1176 {
1177     u2 width;
1178     u4 size;
1179 
1180     if (arrayObj == NULL) {
1181         dvmThrowNullPointerException(NULL);
1182         return false;
1183     }
1184     assert (!IS_CLASS_FLAG_SET(((Object *)arrayObj)->clazz,
1185                                CLASS_ISOBJECTARRAY));
1186 
1187     /*
1188      * Array data table format:
1189      *  ushort ident = 0x0300   magic value
1190      *  ushort width            width of each element in the table
1191      *  uint   size             number of elements in the table
1192      *  ubyte  data[size*width] table of data values (may contain a single-byte
1193      *                          padding at the end)
1194      *
1195      * Total size is 4+(width * size + 1)/2 16-bit code units.
1196      */
1197     if (arrayData[0] != kArrayDataSignature) {
1198         dvmThrowInternalError("bad array data magic");
1199         return false;
1200     }
1201 
1202     width = arrayData[1];
1203     size = arrayData[2] | (((u4)arrayData[3]) << 16);
1204 
1205     if (size > arrayObj->length) {
1206         dvmThrowArrayIndexOutOfBoundsException(arrayObj->length, size);
1207         return false;
1208     }
1209     copySwappedArrayData(arrayObj->contents, &arrayData[4], size, width);
1210     return true;
1211 }
1212 
1213 /*
1214  * Find the concrete method that corresponds to "methodIdx".  The code in
1215  * "method" is executing invoke-method with "thisClass" as its first argument.
1216  *
1217  * Returns NULL with an exception raised on failure.
1218  */
dvmInterpFindInterfaceMethod(ClassObject * thisClass,u4 methodIdx,const Method * method,DvmDex * methodClassDex)1219 Method* dvmInterpFindInterfaceMethod(ClassObject* thisClass, u4 methodIdx,
1220     const Method* method, DvmDex* methodClassDex)
1221 {
1222     Method* absMethod;
1223     Method* methodToCall;
1224     int i, vtableIndex;
1225 
1226     /*
1227      * Resolve the method.  This gives us the abstract method from the
1228      * interface class declaration.
1229      */
1230     absMethod = dvmDexGetResolvedMethod(methodClassDex, methodIdx);
1231     if (absMethod == NULL) {
1232         absMethod = dvmResolveInterfaceMethod(method->clazz, methodIdx);
1233         if (absMethod == NULL) {
1234             ALOGV("+ unknown method");
1235             return NULL;
1236         }
1237     }
1238 
1239     /* make sure absMethod->methodIndex means what we think it means */
1240     assert(dvmIsAbstractMethod(absMethod));
1241 
1242     /*
1243      * Run through the "this" object's iftable.  Find the entry for
1244      * absMethod's class, then use absMethod->methodIndex to find
1245      * the method's entry.  The value there is the offset into our
1246      * vtable of the actual method to execute.
1247      *
1248      * The verifier does not guarantee that objects stored into
1249      * interface references actually implement the interface, so this
1250      * check cannot be eliminated.
1251      */
1252     for (i = 0; i < thisClass->iftableCount; i++) {
1253         if (thisClass->iftable[i].clazz == absMethod->clazz)
1254             break;
1255     }
1256     if (i == thisClass->iftableCount) {
1257         /* impossible in verified DEX, need to check for it in unverified */
1258         dvmThrowIncompatibleClassChangeError("interface not implemented");
1259         return NULL;
1260     }
1261 
1262     assert(absMethod->methodIndex <
1263         thisClass->iftable[i].clazz->virtualMethodCount);
1264 
1265     vtableIndex =
1266         thisClass->iftable[i].methodIndexArray[absMethod->methodIndex];
1267     assert(vtableIndex >= 0 && vtableIndex < thisClass->vtableCount);
1268     methodToCall = thisClass->vtable[vtableIndex];
1269 
1270 #if 0
1271     /* this can happen when there's a stale class file */
1272     if (dvmIsAbstractMethod(methodToCall)) {
1273         dvmThrowAbstractMethodError("interface method not implemented");
1274         return NULL;
1275     }
1276 #else
1277     assert(!dvmIsAbstractMethod(methodToCall) ||
1278         methodToCall->nativeFunc != NULL);
1279 #endif
1280 
1281     LOGVV("+++ interface=%s.%s concrete=%s.%s",
1282         absMethod->clazz->descriptor, absMethod->name,
1283         methodToCall->clazz->descriptor, methodToCall->name);
1284     assert(methodToCall != NULL);
1285 
1286     return methodToCall;
1287 }
1288 
1289 
1290 
1291 /*
1292  * Helpers for dvmThrowVerificationError().
1293  *
1294  * Each returns a newly-allocated string.
1295  */
1296 #define kThrowShow_accessFromClass     1
classNameFromIndex(const Method * method,int ref,VerifyErrorRefType refType,int flags)1297 static std::string classNameFromIndex(const Method* method, int ref,
1298     VerifyErrorRefType refType, int flags)
1299 {
1300     const DvmDex* pDvmDex = method->clazz->pDvmDex;
1301     if (refType == VERIFY_ERROR_REF_FIELD) {
1302         /* get class ID from field ID */
1303         const DexFieldId* pFieldId = dexGetFieldId(pDvmDex->pDexFile, ref);
1304         ref = pFieldId->classIdx;
1305     } else if (refType == VERIFY_ERROR_REF_METHOD) {
1306         /* get class ID from method ID */
1307         const DexMethodId* pMethodId = dexGetMethodId(pDvmDex->pDexFile, ref);
1308         ref = pMethodId->classIdx;
1309     }
1310 
1311     const char* className = dexStringByTypeIdx(pDvmDex->pDexFile, ref);
1312     std::string dotClassName(dvmHumanReadableDescriptor(className));
1313     if (flags == 0) {
1314         return dotClassName;
1315     }
1316 
1317     std::string result;
1318     if ((flags & kThrowShow_accessFromClass) != 0) {
1319         result += "tried to access class " + dotClassName;
1320         result += " from class " + dvmHumanReadableDescriptor(method->clazz->descriptor);
1321     } else {
1322         assert(false);      // should've been caught above
1323     }
1324 
1325     return result;
1326 }
fieldNameFromIndex(const Method * method,int ref,VerifyErrorRefType refType,int flags)1327 static std::string fieldNameFromIndex(const Method* method, int ref,
1328     VerifyErrorRefType refType, int flags)
1329 {
1330     if (refType != VERIFY_ERROR_REF_FIELD) {
1331         ALOGW("Expected ref type %d, got %d", VERIFY_ERROR_REF_FIELD, refType);
1332         return NULL;    /* no message */
1333     }
1334 
1335     const DvmDex* pDvmDex = method->clazz->pDvmDex;
1336     const DexFieldId* pFieldId = dexGetFieldId(pDvmDex->pDexFile, ref);
1337     const char* className = dexStringByTypeIdx(pDvmDex->pDexFile, pFieldId->classIdx);
1338     const char* fieldName = dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx);
1339 
1340     std::string dotName(dvmHumanReadableDescriptor(className));
1341 
1342     if ((flags & kThrowShow_accessFromClass) != 0) {
1343         std::string result;
1344         result += "tried to access field ";
1345         result += dotName + "." + fieldName;
1346         result += " from class ";
1347         result += dvmHumanReadableDescriptor(method->clazz->descriptor);
1348         return result;
1349     }
1350     return dotName + "." + fieldName;
1351 }
methodNameFromIndex(const Method * method,int ref,VerifyErrorRefType refType,int flags)1352 static std::string methodNameFromIndex(const Method* method, int ref,
1353     VerifyErrorRefType refType, int flags)
1354 {
1355     if (refType != VERIFY_ERROR_REF_METHOD) {
1356         ALOGW("Expected ref type %d, got %d", VERIFY_ERROR_REF_METHOD,refType);
1357         return NULL;    /* no message */
1358     }
1359 
1360     const DvmDex* pDvmDex = method->clazz->pDvmDex;
1361     const DexMethodId* pMethodId = dexGetMethodId(pDvmDex->pDexFile, ref);
1362     const char* className = dexStringByTypeIdx(pDvmDex->pDexFile, pMethodId->classIdx);
1363     const char* methodName = dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx);
1364 
1365     std::string dotName(dvmHumanReadableDescriptor(className));
1366 
1367     if ((flags & kThrowShow_accessFromClass) != 0) {
1368         char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
1369         std::string result;
1370         result += "tried to access method ";
1371         result += dotName + "." + methodName + ":" + desc;
1372         result += " from class " + dvmHumanReadableDescriptor(method->clazz->descriptor);
1373         free(desc);
1374         return result;
1375     }
1376     return dotName + "." + methodName;
1377 }
1378 
1379 /*
1380  * Throw an exception for a problem identified by the verifier.
1381  *
1382  * This is used by the invoke-verification-error instruction.  It always
1383  * throws an exception.
1384  *
1385  * "kind" indicates the kind of failure encountered by the verifier.  It
1386  * has two parts, an error code and an indication of the reference type.
1387  */
dvmThrowVerificationError(const Method * method,int kind,int ref)1388 void dvmThrowVerificationError(const Method* method, int kind, int ref)
1389 {
1390     int errorPart = kind & ~(0xff << kVerifyErrorRefTypeShift);
1391     int errorRefPart = kind >> kVerifyErrorRefTypeShift;
1392     VerifyError errorKind = static_cast<VerifyError>(errorPart);
1393     VerifyErrorRefType refType = static_cast<VerifyErrorRefType>(errorRefPart);
1394     ClassObject* exceptionClass = gDvm.exVerifyError;
1395     std::string msg;
1396 
1397     switch ((VerifyError) errorKind) {
1398     case VERIFY_ERROR_NO_CLASS:
1399         exceptionClass = gDvm.exNoClassDefFoundError;
1400         msg = classNameFromIndex(method, ref, refType, 0);
1401         break;
1402     case VERIFY_ERROR_NO_FIELD:
1403         exceptionClass = gDvm.exNoSuchFieldError;
1404         msg = fieldNameFromIndex(method, ref, refType, 0);
1405         break;
1406     case VERIFY_ERROR_NO_METHOD:
1407         exceptionClass = gDvm.exNoSuchMethodError;
1408         msg = methodNameFromIndex(method, ref, refType, 0);
1409         break;
1410     case VERIFY_ERROR_ACCESS_CLASS:
1411         exceptionClass = gDvm.exIllegalAccessError;
1412         msg = classNameFromIndex(method, ref, refType,
1413             kThrowShow_accessFromClass);
1414         break;
1415     case VERIFY_ERROR_ACCESS_FIELD:
1416         exceptionClass = gDvm.exIllegalAccessError;
1417         msg = fieldNameFromIndex(method, ref, refType,
1418             kThrowShow_accessFromClass);
1419         break;
1420     case VERIFY_ERROR_ACCESS_METHOD:
1421         exceptionClass = gDvm.exIllegalAccessError;
1422         msg = methodNameFromIndex(method, ref, refType,
1423             kThrowShow_accessFromClass);
1424         break;
1425     case VERIFY_ERROR_CLASS_CHANGE:
1426         exceptionClass = gDvm.exIncompatibleClassChangeError;
1427         msg = classNameFromIndex(method, ref, refType, 0);
1428         break;
1429     case VERIFY_ERROR_INSTANTIATION:
1430         exceptionClass = gDvm.exInstantiationError;
1431         msg = classNameFromIndex(method, ref, refType, 0);
1432         break;
1433 
1434     case VERIFY_ERROR_GENERIC:
1435         /* generic VerifyError; use default exception, no message */
1436         break;
1437     case VERIFY_ERROR_NONE:
1438         /* should never happen; use default exception */
1439         assert(false);
1440         msg = "weird - no error specified";
1441         break;
1442 
1443     /* no default clause -- want warning if enum updated */
1444     }
1445 
1446     dvmThrowException(exceptionClass, msg.c_str());
1447 }
1448 
1449 /*
1450  * Update interpBreak for a single thread.
1451  */
updateInterpBreak(Thread * thread,ExecutionSubModes subMode,bool enable)1452 void updateInterpBreak(Thread* thread, ExecutionSubModes subMode, bool enable)
1453 {
1454     InterpBreak oldValue, newValue;
1455     do {
1456         oldValue = newValue = thread->interpBreak;
1457         newValue.ctl.breakFlags = kInterpNoBreak;  // Assume full reset
1458         if (enable)
1459             newValue.ctl.subMode |= subMode;
1460         else
1461             newValue.ctl.subMode &= ~subMode;
1462         if (newValue.ctl.subMode & SINGLESTEP_BREAK_MASK)
1463             newValue.ctl.breakFlags |= kInterpSingleStep;
1464         if (newValue.ctl.subMode & SAFEPOINT_BREAK_MASK)
1465             newValue.ctl.breakFlags |= kInterpSafePoint;
1466 #ifndef DVM_NO_ASM_INTERP
1467         newValue.ctl.curHandlerTable = (newValue.ctl.breakFlags) ?
1468             thread->altHandlerTable : thread->mainHandlerTable;
1469 #endif
1470     } while (dvmQuasiAtomicCas64(oldValue.all, newValue.all,
1471              &thread->interpBreak.all) != 0);
1472 }
1473 
1474 /*
1475  * Update interpBreak for all threads.
1476  */
updateAllInterpBreak(ExecutionSubModes subMode,bool enable)1477 void updateAllInterpBreak(ExecutionSubModes subMode, bool enable)
1478 {
1479     Thread* self = dvmThreadSelf();
1480     Thread* thread;
1481 
1482     dvmLockThreadList(self);
1483     for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
1484         updateInterpBreak(thread, subMode, enable);
1485     }
1486     dvmUnlockThreadList();
1487 }
1488 
1489 /*
1490  * Update the normal and debugger suspend counts for a thread.
1491  * threadSuspendCount must be acquired before calling this to
1492  * ensure a clean update of suspendCount, dbgSuspendCount and
1493  * sumThreadSuspendCount.
1494  *
1495  * CLEANUP TODO: Currently only the JIT is using sumThreadSuspendCount.
1496  * Move under WITH_JIT ifdefs.
1497 */
dvmAddToSuspendCounts(Thread * thread,int delta,int dbgDelta)1498 void dvmAddToSuspendCounts(Thread* thread, int delta, int dbgDelta)
1499 {
1500     thread->suspendCount += delta;
1501     thread->dbgSuspendCount += dbgDelta;
1502     updateInterpBreak(thread, kSubModeSuspendPending,
1503                       (thread->suspendCount != 0));
1504     // Update the global suspend count total
1505     gDvm.sumThreadSuspendCount += delta;
1506 }
1507 
1508 
dvmDisableSubMode(Thread * thread,ExecutionSubModes subMode)1509 void dvmDisableSubMode(Thread* thread, ExecutionSubModes subMode)
1510 {
1511     updateInterpBreak(thread, subMode, false);
1512 }
1513 
dvmEnableSubMode(Thread * thread,ExecutionSubModes subMode)1514 void dvmEnableSubMode(Thread* thread, ExecutionSubModes subMode)
1515 {
1516     updateInterpBreak(thread, subMode, true);
1517 }
1518 
dvmEnableAllSubMode(ExecutionSubModes subMode)1519 void dvmEnableAllSubMode(ExecutionSubModes subMode)
1520 {
1521     updateAllInterpBreak(subMode, true);
1522 }
1523 
dvmDisableAllSubMode(ExecutionSubModes subMode)1524 void dvmDisableAllSubMode(ExecutionSubModes subMode)
1525 {
1526     updateAllInterpBreak(subMode, false);
1527 }
1528 
1529 /*
1530  * Do a sanity check on interpreter state saved to Thread.
1531  * A failure here doesn't necessarily mean that something is wrong,
1532  * so this code should only be used during development to suggest
1533  * a possible problem.
1534  */
dvmCheckInterpStateConsistency()1535 void dvmCheckInterpStateConsistency()
1536 {
1537     Thread* self = dvmThreadSelf();
1538     Thread* thread;
1539     uint8_t breakFlags;
1540     uint8_t subMode;
1541 #ifndef DVM_NO_ASM_INTERP
1542     void* handlerTable;
1543 #endif
1544 
1545     dvmLockThreadList(self);
1546     breakFlags = self->interpBreak.ctl.breakFlags;
1547     subMode = self->interpBreak.ctl.subMode;
1548 #ifndef DVM_NO_ASM_INTERP
1549     handlerTable = self->interpBreak.ctl.curHandlerTable;
1550 #endif
1551     for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
1552         if (subMode != thread->interpBreak.ctl.subMode) {
1553             ALOGD("Warning: subMode mismatch - %#x:%#x, tid[%d]",
1554                 subMode,thread->interpBreak.ctl.subMode,thread->threadId);
1555          }
1556         if (breakFlags != thread->interpBreak.ctl.breakFlags) {
1557             ALOGD("Warning: breakFlags mismatch - %#x:%#x, tid[%d]",
1558                 breakFlags,thread->interpBreak.ctl.breakFlags,thread->threadId);
1559          }
1560 #ifndef DVM_NO_ASM_INTERP
1561         if (handlerTable != thread->interpBreak.ctl.curHandlerTable) {
1562             ALOGD("Warning: curHandlerTable mismatch - %#x:%#x, tid[%d]",
1563                 (int)handlerTable,(int)thread->interpBreak.ctl.curHandlerTable,
1564                 thread->threadId);
1565          }
1566 #endif
1567 #if defined(WITH_JIT)
1568          if (thread->pJitProfTable != gDvmJit.pProfTable) {
1569              ALOGD("Warning: pJitProfTable mismatch - %#x:%#x, tid[%d]",
1570                   (int)thread->pJitProfTable,(int)gDvmJit.pProfTable,
1571                   thread->threadId);
1572          }
1573          if (thread->jitThreshold != gDvmJit.threshold) {
1574              ALOGD("Warning: jitThreshold mismatch - %#x:%#x, tid[%d]",
1575                   (int)thread->jitThreshold,(int)gDvmJit.threshold,
1576                   thread->threadId);
1577          }
1578 #endif
1579     }
1580     dvmUnlockThreadList();
1581 }
1582 
1583 /*
1584  * Arm a safepoint callback for a thread.  If funct is null,
1585  * clear any pending callback.
1586  * TODO: only gc is currently using this feature, and will have
1587  * at most a single outstanding callback request.  Until we need
1588  * something more capable and flexible, enforce this limit.
1589  */
dvmArmSafePointCallback(Thread * thread,SafePointCallback funct,void * arg)1590 void dvmArmSafePointCallback(Thread* thread, SafePointCallback funct,
1591                              void* arg)
1592 {
1593     dvmLockMutex(&thread->callbackMutex);
1594     if ((funct == NULL) || (thread->callback == NULL)) {
1595         thread->callback = funct;
1596         thread->callbackArg = arg;
1597         if (funct != NULL) {
1598             dvmEnableSubMode(thread, kSubModeCallbackPending);
1599         } else {
1600             dvmDisableSubMode(thread, kSubModeCallbackPending);
1601         }
1602     } else {
1603         // Already armed.  Different?
1604         if ((funct != thread->callback) ||
1605             (arg != thread->callbackArg)) {
1606             // Yes - report failure and die
1607             ALOGE("ArmSafePointCallback failed, thread %d", thread->threadId);
1608             dvmUnlockMutex(&thread->callbackMutex);
1609             dvmAbort();
1610         }
1611     }
1612     dvmUnlockMutex(&thread->callbackMutex);
1613 }
1614 
1615 /*
1616  * One-time initialization at thread creation.  Here we initialize
1617  * useful constants.
1618  */
dvmInitInterpreterState(Thread * self)1619 void dvmInitInterpreterState(Thread* self)
1620 {
1621 #if defined(WITH_JIT)
1622     /*
1623      * Reserve a static entity here to quickly setup runtime contents as
1624      * gcc will issue block copy instructions.
1625      */
1626     static struct JitToInterpEntries jitToInterpEntries = {
1627         dvmJitToInterpNormal,
1628         dvmJitToInterpNoChain,
1629         dvmJitToInterpPunt,
1630         dvmJitToInterpSingleStep,
1631         dvmJitToInterpTraceSelect,
1632 #if defined(WITH_SELF_VERIFICATION)
1633         dvmJitToInterpBackwardBranch,
1634 #else
1635         NULL,
1636 #endif
1637     };
1638 #endif
1639 
1640     // Begin initialization
1641     self->cardTable = gDvm.biasedCardTableBase;
1642 #if defined(WITH_JIT)
1643     // One-time initializations
1644     self->jitToInterpEntries = jitToInterpEntries;
1645     self->icRechainCount = PREDICTED_CHAIN_COUNTER_RECHAIN;
1646     self->pProfileCountdown = &gDvmJit.profileCountdown;
1647     // Jit state that can change
1648     dvmJitUpdateThreadStateSingle(self);
1649 #endif
1650     dvmInitializeInterpBreak(self);
1651 }
1652 
1653 /*
1654  * For a newly-created thread, we need to start off with interpBreak
1655  * set to any existing global modes.  The caller must hold the
1656  * thread list lock.
1657  */
dvmInitializeInterpBreak(Thread * thread)1658 void dvmInitializeInterpBreak(Thread* thread)
1659 {
1660     if (gDvm.instructionCountEnableCount > 0) {
1661         dvmEnableSubMode(thread, kSubModeInstCounting);
1662     }
1663     if (dvmIsMethodTraceActive()) {
1664         dvmEnableSubMode(thread, kSubModeMethodTrace);
1665     }
1666     if (gDvm.emulatorTraceEnableCount > 0) {
1667         dvmEnableSubMode(thread, kSubModeEmulatorTrace);
1668     }
1669     if (gDvm.debuggerActive) {
1670         dvmEnableSubMode(thread, kSubModeDebuggerActive);
1671     }
1672 #if defined(WITH_JIT)
1673     dvmJitUpdateThreadStateSingle(thread);
1674 #endif
1675 #if 0
1676     // Debugging stress mode - force checkBefore
1677     dvmEnableSubMode(thread, kSubModeCheckAlways);
1678 #endif
1679 }
1680 
1681 /*
1682  * Inter-instruction handler invoked in between instruction interpretations
1683  * to handle exceptional events such as debugging housekeeping, instruction
1684  * count profiling, JIT trace building, etc.  Dalvik PC has been exported
1685  * prior to call, but Thread copy of dPC & fp are not current.
1686  */
dvmCheckBefore(const u2 * pc,u4 * fp,Thread * self)1687 void dvmCheckBefore(const u2 *pc, u4 *fp, Thread* self)
1688 {
1689     const Method* method = self->interpSave.method;
1690     assert(pc >= method->insns && pc <
1691            method->insns + dvmGetMethodInsnsSize(method));
1692 
1693 #if 0
1694     /*
1695      * When we hit a specific method, enable verbose instruction logging.
1696      * Sometimes it's helpful to use the debugger attach as a trigger too.
1697      */
1698     if (*pIsMethodEntry) {
1699         static const char* cd = "Landroid/test/Arithmetic;";
1700         static const char* mn = "shiftTest2";
1701         static const char* sg = "()V";
1702 
1703         if (/*self->interpBreak.ctl.subMode & kSubModeDebuggerActive &&*/
1704             strcmp(method->clazz->descriptor, cd) == 0 &&
1705             strcmp(method->name, mn) == 0 &&
1706             strcmp(method->shorty, sg) == 0)
1707         {
1708             ALOGW("Reached %s.%s, enabling verbose mode",
1709                 method->clazz->descriptor, method->name);
1710             android_setMinPriority(LOG_TAG"i", ANDROID_LOG_VERBOSE);
1711             dumpRegs(method, fp, true);
1712         }
1713 
1714         if (!gDvm.debuggerActive)
1715             *pIsMethodEntry = false;
1716     }
1717 #endif
1718 
1719     /* Safe point handling */
1720     if (self->suspendCount ||
1721         (self->interpBreak.ctl.subMode & kSubModeCallbackPending)) {
1722         // Are we are a safe point?
1723         int flags;
1724         flags = dexGetFlagsFromOpcode(dexOpcodeFromCodeUnit(*pc));
1725         if (flags & (VERIFY_GC_INST_MASK & ~kInstrCanThrow)) {
1726             // Yes, at a safe point.  Pending callback?
1727             if (self->interpBreak.ctl.subMode & kSubModeCallbackPending) {
1728                 SafePointCallback callback;
1729                 void* arg;
1730                 // Get consistent funct/arg pair
1731                 dvmLockMutex(&self->callbackMutex);
1732                 callback = self->callback;
1733                 arg = self->callbackArg;
1734                 dvmUnlockMutex(&self->callbackMutex);
1735                 // Update Thread structure
1736                 self->interpSave.pc = pc;
1737                 self->interpSave.curFrame = fp;
1738                 if (callback != NULL) {
1739                     // Do the callback
1740                     if (!callback(self,arg)) {
1741                         // disarm
1742                         dvmArmSafePointCallback(self, NULL, NULL);
1743                     }
1744                 }
1745             }
1746             // Need to suspend?
1747             if (self->suspendCount) {
1748                 dvmExportPC(pc, fp);
1749                 dvmCheckSuspendPending(self);
1750             }
1751         }
1752     }
1753 
1754     if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) {
1755         updateDebugger(method, pc, fp, self);
1756     }
1757     if (gDvm.instructionCountEnableCount != 0) {
1758         /*
1759          * Count up the #of executed instructions.  This isn't synchronized
1760          * for thread-safety; if we need that we should make this
1761          * thread-local and merge counts into the global area when threads
1762          * exit (perhaps suspending all other threads GC-style and pulling
1763          * the data out of them).
1764          */
1765         gDvm.executedInstrCounts[GET_OPCODE(*pc)]++;
1766     }
1767 
1768 
1769 #if defined(WITH_TRACKREF_CHECKS)
1770     dvmInterpCheckTrackedRefs(self, method,
1771                               self->interpSave.debugTrackedRefStart);
1772 #endif
1773 
1774 #if defined(WITH_JIT)
1775     // Does the JIT need anything done now?
1776     if (self->interpBreak.ctl.subMode &
1777             (kSubModeJitTraceBuild | kSubModeJitSV)) {
1778         // Are we building a trace?
1779         if (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) {
1780             dvmCheckJit(pc, self);
1781         }
1782 
1783 #if defined(WITH_SELF_VERIFICATION)
1784         // Are we replaying a trace?
1785         if (self->interpBreak.ctl.subMode & kSubModeJitSV) {
1786             dvmCheckSelfVerification(pc, self);
1787         }
1788 #endif
1789     }
1790 #endif
1791 
1792     /*
1793      * CountedStep processing.  NOTE: must be the last here to allow
1794      * preceeding special case handler to manipulate single-step count.
1795      */
1796     if (self->interpBreak.ctl.subMode & kSubModeCountedStep) {
1797         if (self->singleStepCount == 0) {
1798             // We've exhausted our single step count
1799             dvmDisableSubMode(self, kSubModeCountedStep);
1800 #if defined(WITH_JIT)
1801 #if 0
1802             /*
1803              * For debugging.  If jitResumeDPC is non-zero, then
1804              * we expect to return to a trace in progress.   There
1805              * are valid reasons why we wouldn't (such as an exception
1806              * throw), but here we can keep track.
1807              */
1808             if (self->jitResumeDPC != NULL) {
1809                 if (self->jitResumeDPC == pc) {
1810                     if (self->jitResumeNPC != NULL) {
1811                         ALOGD("SS return to trace - pc:%#x to 0x:%x",
1812                              (int)pc, (int)self->jitResumeNPC);
1813                     } else {
1814                         ALOGD("SS return to interp - pc:%#x",(int)pc);
1815                     }
1816                 } else {
1817                     ALOGD("SS failed to return.  Expected %#x, now at %#x",
1818                          (int)self->jitResumeDPC, (int)pc);
1819                 }
1820             }
1821 #endif
1822 #if 0
1823             // TODO - fix JIT single-stepping resume mode (b/5551114)
1824             // self->jitResumeNPC needs to be cleared in callPrep
1825 
1826             // If we've got a native return and no other reasons to
1827             // remain in singlestep/break mode, do a long jump
1828             if (self->jitResumeNPC != NULL &&
1829                 self->interpBreak.ctl.breakFlags == 0) {
1830                 assert(self->jitResumeDPC == pc);
1831                 self->jitResumeDPC = NULL;
1832                 dvmJitResumeTranslation(self, pc, fp);
1833                 // Doesn't return
1834                 dvmAbort();
1835             }
1836             // In case resume is blocked by non-zero breakFlags, clear
1837             // jitResumeNPC here.
1838             self->jitResumeNPC = NULL;
1839             self->jitResumeDPC = NULL;
1840             self->inJitCodeCache = NULL;
1841 #endif
1842 #endif
1843         } else {
1844             self->singleStepCount--;
1845 #if defined(WITH_JIT)
1846             if ((self->singleStepCount > 0) && (self->jitResumeNPC != NULL)) {
1847                 /*
1848                  * Direct return to an existing translation following a
1849                  * single step is valid only if we step once.  If we're
1850                  * here, an additional step was added so we need to invalidate
1851                  * the return to translation.
1852                  */
1853                 self->jitResumeNPC = NULL;
1854                 self->inJitCodeCache = NULL;
1855             }
1856 #endif
1857         }
1858     }
1859 }
1860 
1861 /*
1862  * Main interpreter loop entry point.
1863  *
1864  * This begins executing code at the start of "method".  On exit, "pResult"
1865  * holds the return value of the method (or, if "method" returns NULL, it
1866  * holds an undefined value).
1867  *
1868  * The interpreted stack frame, which holds the method arguments, has
1869  * already been set up.
1870  */
dvmInterpret(Thread * self,const Method * method,JValue * pResult)1871 void dvmInterpret(Thread* self, const Method* method, JValue* pResult)
1872 {
1873     InterpSaveState interpSaveState;
1874     ExecutionSubModes savedSubModes;
1875 
1876 #if defined(WITH_JIT)
1877     /* Target-specific save/restore */
1878     double calleeSave[JIT_CALLEE_SAVE_DOUBLE_COUNT];
1879     /*
1880      * If the previous VM left the code cache through single-stepping the
1881      * inJitCodeCache flag will be set when the VM is re-entered (for example,
1882      * in self-verification mode we single-step NEW_INSTANCE which may re-enter
1883      * the VM through findClassFromLoaderNoInit). Because of that, we cannot
1884      * assert that self->inJitCodeCache is NULL here.
1885      */
1886 #endif
1887 
1888     /*
1889      * Save interpreter state from previous activation, linking
1890      * new to last.
1891      */
1892     interpSaveState = self->interpSave;
1893     self->interpSave.prev = &interpSaveState;
1894     /*
1895      * Strip out and save any flags that should not be inherited by
1896      * nested interpreter activation.
1897      */
1898     savedSubModes = (ExecutionSubModes)(
1899               self->interpBreak.ctl.subMode & LOCAL_SUBMODE);
1900     if (savedSubModes != kSubModeNormal) {
1901         dvmDisableSubMode(self, savedSubModes);
1902     }
1903 #if defined(WITH_JIT)
1904     dvmJitCalleeSave(calleeSave);
1905 #endif
1906 
1907 
1908 #if defined(WITH_TRACKREF_CHECKS)
1909     self->interpSave.debugTrackedRefStart =
1910         dvmReferenceTableEntries(&self->internalLocalRefTable);
1911 #endif
1912     self->debugIsMethodEntry = true;
1913 #if defined(WITH_JIT)
1914     /* Initialize the state to kJitNot */
1915     self->jitState = kJitNot;
1916 #endif
1917 
1918     /*
1919      * Initialize working state.
1920      *
1921      * No need to initialize "retval".
1922      */
1923     self->interpSave.method = method;
1924     self->interpSave.curFrame = (u4*) self->interpSave.curFrame;
1925     self->interpSave.pc = method->insns;
1926 
1927     assert(!dvmIsNativeMethod(method));
1928 
1929     /*
1930      * Make sure the class is ready to go.  Shouldn't be possible to get
1931      * here otherwise.
1932      */
1933     if (method->clazz->status < CLASS_INITIALIZING ||
1934         method->clazz->status == CLASS_ERROR)
1935     {
1936         ALOGE("ERROR: tried to execute code in unprepared class '%s' (%d)",
1937             method->clazz->descriptor, method->clazz->status);
1938         dvmDumpThread(self, false);
1939         dvmAbort();
1940     }
1941 
1942     typedef void (*Interpreter)(Thread*);
1943     Interpreter stdInterp;
1944     if (gDvm.executionMode == kExecutionModeInterpFast)
1945         stdInterp = dvmMterpStd;
1946 #if defined(WITH_JIT)
1947     else if (gDvm.executionMode == kExecutionModeJit ||
1948              gDvm.executionMode == kExecutionModeNcgO0 ||
1949              gDvm.executionMode == kExecutionModeNcgO1)
1950         stdInterp = dvmMterpStd;
1951 #endif
1952     else
1953         stdInterp = dvmInterpretPortable;
1954 
1955     // Call the interpreter
1956     (*stdInterp)(self);
1957 
1958     *pResult = self->interpSave.retval;
1959 
1960     /* Restore interpreter state from previous activation */
1961     self->interpSave = interpSaveState;
1962 #if defined(WITH_JIT)
1963     dvmJitCalleeRestore(calleeSave);
1964 #endif
1965     if (savedSubModes != kSubModeNormal) {
1966         dvmEnableSubMode(self, savedSubModes);
1967     }
1968 }
1969