• 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.  Ideally their
25  * entire existence would be "#ifdef WITH_DEBUGGER", but we're not that
26  * aggressive in other parts of the code yet.
27  */
28 #include "Dalvik.h"
29 #include "interp/InterpDefs.h"
30 
31 
32 /*
33  * ===========================================================================
34  *      Debugger support
35  * ===========================================================================
36  */
37 
38 /*
39  * Initialize the breakpoint address lookup table when the debugger attaches.
40  *
41  * This shouldn't be necessary -- the global area is initially zeroed out,
42  * and the events should be cleaning up after themselves.
43  */
dvmInitBreakpoints(void)44 void dvmInitBreakpoints(void)
45 {
46 #ifdef WITH_DEBUGGER
47     memset(gDvm.debugBreakAddr, 0, sizeof(gDvm.debugBreakAddr));
48 #else
49     assert(false);
50 #endif
51 }
52 
53 /*
54  * Add an address to the list, putting it in the first non-empty slot.
55  *
56  * Sometimes the debugger likes to add two entries for one breakpoint.
57  * We add two entries here, so that we get the right behavior when it's
58  * removed twice.
59  *
60  * This will only be run from the JDWP thread, and it will happen while
61  * we are updating the event list, which is synchronized.  We're guaranteed
62  * to be the only one adding entries, and the lock ensures that nobody
63  * will be trying to remove them while we're in here.
64  *
65  * "addr" is the absolute address of the breakpoint bytecode.
66  */
dvmAddBreakAddr(Method * method,int instrOffset)67 void dvmAddBreakAddr(Method* method, int instrOffset)
68 {
69 #ifdef WITH_DEBUGGER
70     const u2* addr = method->insns + instrOffset;
71     const u2** ptr = gDvm.debugBreakAddr;
72     int i;
73 
74     LOGV("BKP: add %p %s.%s (%s:%d)\n",
75         addr, method->clazz->descriptor, method->name,
76         dvmGetMethodSourceFile(method), dvmLineNumFromPC(method, instrOffset));
77 
78     method->debugBreakpointCount++;
79     for (i = 0; i < MAX_BREAKPOINTS; i++, ptr++) {
80         if (*ptr == NULL) {
81             *ptr = addr;
82             break;
83         }
84     }
85     if (i == MAX_BREAKPOINTS) {
86         /* no room; size is too small or we're not cleaning up properly */
87         LOGE("ERROR: max breakpoints exceeded\n");
88         assert(false);
89     }
90 #else
91     assert(false);
92 #endif
93 }
94 
95 /*
96  * Remove an address from the list by setting the entry to NULL.
97  *
98  * This can be called from the JDWP thread (because the debugger has
99  * cancelled the breakpoint) or from an event thread (because it's a
100  * single-shot breakpoint, e.g. "run to line").  We only get here as
101  * the result of removing an entry from the event list, which is
102  * synchronized, so it should not be possible for two threads to be
103  * updating breakpoints at the same time.
104  */
dvmClearBreakAddr(Method * method,int instrOffset)105 void dvmClearBreakAddr(Method* method, int instrOffset)
106 {
107 #ifdef WITH_DEBUGGER
108     const u2* addr = method->insns + instrOffset;
109     const u2** ptr = gDvm.debugBreakAddr;
110     int i;
111 
112     LOGV("BKP: clear %p %s.%s (%s:%d)\n",
113         addr, method->clazz->descriptor, method->name,
114         dvmGetMethodSourceFile(method), dvmLineNumFromPC(method, instrOffset));
115 
116     method->debugBreakpointCount--;
117     assert(method->debugBreakpointCount >= 0);
118     for (i = 0; i < MAX_BREAKPOINTS; i++, ptr++) {
119         if (*ptr == addr) {
120             *ptr = NULL;
121             break;
122         }
123     }
124     if (i == MAX_BREAKPOINTS) {
125         /* didn't find it */
126         LOGE("ERROR: breakpoint on %p not found\n", addr);
127         assert(false);
128     }
129 #else
130     assert(false);
131 #endif
132 }
133 
134 /*
135  * Add a single step event.  Currently this is a global item.
136  *
137  * We set up some initial values based on the thread's current state.  This
138  * won't work well if the thread is running, so it's up to the caller to
139  * verify that it's suspended.
140  *
141  * This is only called from the JDWP thread.
142  */
dvmAddSingleStep(Thread * thread,int size,int depth)143 bool dvmAddSingleStep(Thread* thread, int size, int depth)
144 {
145 #ifdef WITH_DEBUGGER
146     StepControl* pCtrl = &gDvm.stepControl;
147 
148     if (pCtrl->active && thread != pCtrl->thread) {
149         LOGW("WARNING: single-step active for %p; adding %p\n",
150             pCtrl->thread, thread);
151 
152         /*
153          * Keep going, overwriting previous.  This can happen if you
154          * suspend a thread in Object.wait, hit the single-step key, then
155          * switch to another thread and do the same thing again.
156          * The first thread's step is still pending.
157          *
158          * TODO: consider making single-step per-thread.  Adds to the
159          * overhead, but could be useful in rare situations.
160          */
161     }
162 
163     pCtrl->size = size;
164     pCtrl->depth = depth;
165     pCtrl->thread = thread;
166 
167     /*
168      * We may be stepping into or over method calls, or running until we
169      * return from the current method.  To make this work we need to track
170      * the current line, current method, and current stack depth.  We need
171      * to be checking these after most instructions, notably those that
172      * call methods, return from methods, or are on a different line from the
173      * previous instruction.
174      *
175      * We have to start with a snapshot of the current state.  If we're in
176      * an interpreted method, everything we need is in the current frame.  If
177      * we're in a native method, possibly with some extra JNI frames pushed
178      * on by PushLocalFrame, we want to use the topmost native method.
179      */
180     const StackSaveArea* saveArea;
181     void* fp;
182     void* prevFp = NULL;
183 
184     for (fp = thread->curFrame; fp != NULL; fp = saveArea->prevFrame) {
185         const Method* method;
186 
187         saveArea = SAVEAREA_FROM_FP(fp);
188         method = saveArea->method;
189 
190         if (!dvmIsBreakFrame(fp) && !dvmIsNativeMethod(method))
191             break;
192         prevFp = fp;
193     }
194     if (fp == NULL) {
195         LOGW("Unexpected: step req in native-only threadid=%d\n",
196             thread->threadId);
197         return false;
198     }
199     if (prevFp != NULL) {
200         /*
201          * First interpreted frame wasn't the one at the bottom.  Break
202          * frames are only inserted when calling from native->interp, so we
203          * don't need to worry about one being here.
204          */
205         LOGV("##### init step while in native method\n");
206         fp = prevFp;
207         assert(!dvmIsBreakFrame(fp));
208         assert(dvmIsNativeMethod(SAVEAREA_FROM_FP(fp)->method));
209         saveArea = SAVEAREA_FROM_FP(fp);
210     }
211 
212     /*
213      * Pull the goodies out.  "xtra.currentPc" should be accurate since
214      * we update it on every instruction while the debugger is connected.
215      */
216     pCtrl->method = saveArea->method;
217     // Clear out any old address set
218     if (pCtrl->pAddressSet != NULL) {
219         // (discard const)
220         free((void *)pCtrl->pAddressSet);
221         pCtrl->pAddressSet = NULL;
222     }
223     if (dvmIsNativeMethod(pCtrl->method)) {
224         pCtrl->line = -1;
225     } else {
226         pCtrl->line = dvmLineNumFromPC(saveArea->method,
227                         saveArea->xtra.currentPc - saveArea->method->insns);
228         pCtrl->pAddressSet
229                 = dvmAddressSetForLine(saveArea->method, pCtrl->line);
230     }
231     pCtrl->frameDepth = dvmComputeVagueFrameDepth(thread, thread->curFrame);
232     pCtrl->active = true;
233 
234     LOGV("##### step init: thread=%p meth=%p '%s' line=%d frameDepth=%d depth=%s size=%s\n",
235         pCtrl->thread, pCtrl->method, pCtrl->method->name,
236         pCtrl->line, pCtrl->frameDepth,
237         dvmJdwpStepDepthStr(pCtrl->depth),
238         dvmJdwpStepSizeStr(pCtrl->size));
239 
240     return true;
241 #else
242     assert(false);
243     return false;
244 #endif
245 }
246 
247 /*
248  * Disable a single step event.
249  */
dvmClearSingleStep(Thread * thread)250 void dvmClearSingleStep(Thread* thread)
251 {
252 #ifdef WITH_DEBUGGER
253     UNUSED_PARAMETER(thread);
254 
255     gDvm.stepControl.active = false;
256 #else
257     assert(false);
258 #endif
259 }
260 
261 
262 /*
263  * Recover the "this" pointer from the current interpreted method.  "this"
264  * is always in "in0" for non-static methods.
265  *
266  * The "ins" start at (#of registers - #of ins).  Note in0 != v0.
267  *
268  * This works because "dx" guarantees that it will work.  It's probably
269  * fairly common to have a virtual method that doesn't use its "this"
270  * pointer, in which case we're potentially wasting a register.  However,
271  * the debugger doesn't treat "this" as just another argument.  For
272  * example, events (such as breakpoints) can be enabled for specific
273  * values of "this".  There is also a separate StackFrame.ThisObject call
274  * in JDWP that is expected to work for any non-native non-static method.
275  *
276  * Because we need it when setting up debugger event filters, we want to
277  * be able to do this quickly.
278  */
dvmGetThisPtr(const Method * method,const u4 * fp)279 Object* dvmGetThisPtr(const Method* method, const u4* fp)
280 {
281     if (dvmIsStaticMethod(method))
282         return NULL;
283     return (Object*)fp[method->registersSize - method->insSize];
284 }
285 
286 
287 #if defined(WITH_TRACKREF_CHECKS)
288 /*
289  * Verify that all internally-tracked references have been released.  If
290  * they haven't, print them and abort the VM.
291  *
292  * "debugTrackedRefStart" indicates how many refs were on the list when
293  * we were first invoked.
294  */
dvmInterpCheckTrackedRefs(Thread * self,const Method * method,int debugTrackedRefStart)295 void dvmInterpCheckTrackedRefs(Thread* self, const Method* method,
296     int debugTrackedRefStart)
297 {
298     if (dvmReferenceTableEntries(&self->internalLocalRefTable)
299         != (size_t) debugTrackedRefStart)
300     {
301         char* desc;
302         Object** top;
303         int count;
304 
305         count = dvmReferenceTableEntries(&self->internalLocalRefTable);
306 
307         LOGE("TRACK: unreleased internal reference (prev=%d total=%d)\n",
308             debugTrackedRefStart, count);
309         desc = dexProtoCopyMethodDescriptor(&method->prototype);
310         LOGE("       current method is %s.%s %s\n", method->clazz->descriptor,
311             method->name, desc);
312         free(desc);
313         top = self->internalLocalRefTable.table + debugTrackedRefStart;
314         while (top < self->internalLocalRefTable.nextEntry) {
315             LOGE("  %p (%s)\n",
316                  *top,
317                  ((*top)->clazz != NULL) ? (*top)->clazz->descriptor : "");
318             top++;
319         }
320         dvmDumpThread(self, false);
321 
322         dvmAbort();
323     }
324     //LOGI("TRACK OK\n");
325 }
326 #endif
327 
328 
329 #ifdef LOG_INSTR
330 /*
331  * Dump the v-registers.  Sent to the ILOG log tag.
332  */
dvmDumpRegs(const Method * method,const u4 * framePtr,bool inOnly)333 void dvmDumpRegs(const Method* method, const u4* framePtr, bool inOnly)
334 {
335     int i, localCount;
336 
337     localCount = method->registersSize - method->insSize;
338 
339     LOG(LOG_VERBOSE, LOG_TAG"i", "Registers (fp=%p):\n", framePtr);
340     for (i = method->registersSize-1; i >= 0; i--) {
341         if (i >= localCount) {
342             LOG(LOG_VERBOSE, LOG_TAG"i", "  v%-2d in%-2d : 0x%08x\n",
343                 i, i-localCount, framePtr[i]);
344         } else {
345             if (inOnly) {
346                 LOG(LOG_VERBOSE, LOG_TAG"i", "  [...]\n");
347                 break;
348             }
349             const char* name = "";
350             int j;
351 #if 0   // "locals" structure has changed -- need to rewrite this
352             DexFile* pDexFile = method->clazz->pDexFile;
353             const DexCode* pDexCode = dvmGetMethodCode(method);
354             int localsSize = dexGetLocalsSize(pDexFile, pDexCode);
355             const DexLocal* locals = dvmDexGetLocals(pDexFile, pDexCode);
356             for (j = 0; j < localsSize, j++) {
357                 if (locals[j].registerNum == (u4) i) {
358                     name = dvmDexStringStr(locals[j].pName);
359                     break;
360                 }
361             }
362 #endif
363             LOG(LOG_VERBOSE, LOG_TAG"i", "  v%-2d      : 0x%08x %s\n",
364                 i, framePtr[i], name);
365         }
366     }
367 }
368 #endif
369 
370 
371 /*
372  * ===========================================================================
373  *      Entry point and general support functions
374  * ===========================================================================
375  */
376 
377 /*
378  * Construct an s4 from two consecutive half-words of switch data.
379  * This needs to check endianness because the DEX optimizer only swaps
380  * half-words in instruction stream.
381  *
382  * "switchData" must be 32-bit aligned.
383  */
384 #if __BYTE_ORDER == __LITTLE_ENDIAN
s4FromSwitchData(const void * switchData)385 static inline s4 s4FromSwitchData(const void* switchData) {
386     return *(s4*) switchData;
387 }
388 #else
s4FromSwitchData(const void * switchData)389 static inline s4 s4FromSwitchData(const void* switchData) {
390     u2* data = switchData;
391     return data[0] | (((s4) data[1]) << 16);
392 }
393 #endif
394 
395 /*
396  * Find the matching case.  Returns the offset to the handler instructions.
397  *
398  * Returns 3 if we don't find a match (it's the size of the packed-switch
399  * instruction).
400  */
dvmInterpHandlePackedSwitch(const u2 * switchData,s4 testVal)401 s4 dvmInterpHandlePackedSwitch(const u2* switchData, s4 testVal)
402 {
403     const int kInstrLen = 3;
404     u2 size;
405     s4 firstKey;
406     const s4* entries;
407 
408     /*
409      * Packed switch data format:
410      *  ushort ident = 0x0100   magic value
411      *  ushort size             number of entries in the table
412      *  int first_key           first (and lowest) switch case value
413      *  int targets[size]       branch targets, relative to switch opcode
414      *
415      * Total size is (4+size*2) 16-bit code units.
416      */
417     if (*switchData++ != kPackedSwitchSignature) {
418         /* should have been caught by verifier */
419         dvmThrowException("Ljava/lang/InternalError;",
420             "bad packed switch magic");
421         return kInstrLen;
422     }
423 
424     size = *switchData++;
425     assert(size > 0);
426 
427     firstKey = *switchData++;
428     firstKey |= (*switchData++) << 16;
429 
430     if (testVal < firstKey || testVal >= firstKey + size) {
431         LOGVV("Value %d not found in switch (%d-%d)\n",
432             testVal, firstKey, firstKey+size-1);
433         return kInstrLen;
434     }
435 
436     /* The entries are guaranteed to be aligned on a 32-bit boundary;
437      * we can treat them as a native int array.
438      */
439     entries = (const s4*) switchData;
440     assert(((u4)entries & 0x3) == 0);
441 
442     assert(testVal - firstKey >= 0 && testVal - firstKey < size);
443     LOGVV("Value %d found in slot %d (goto 0x%02x)\n",
444         testVal, testVal - firstKey,
445         s4FromSwitchData(&entries[testVal - firstKey]));
446     return s4FromSwitchData(&entries[testVal - firstKey]);
447 }
448 
449 /*
450  * Find the matching case.  Returns the offset to the handler instructions.
451  *
452  * Returns 3 if we don't find a match (it's the size of the sparse-switch
453  * instruction).
454  */
dvmInterpHandleSparseSwitch(const u2 * switchData,s4 testVal)455 s4 dvmInterpHandleSparseSwitch(const u2* switchData, s4 testVal)
456 {
457     const int kInstrLen = 3;
458     u2 ident, size;
459     const s4* keys;
460     const s4* entries;
461     int i;
462 
463     /*
464      * Sparse switch data format:
465      *  ushort ident = 0x0200   magic value
466      *  ushort size             number of entries in the table; > 0
467      *  int keys[size]          keys, sorted low-to-high; 32-bit aligned
468      *  int targets[size]       branch targets, relative to switch opcode
469      *
470      * Total size is (2+size*4) 16-bit code units.
471      */
472 
473     if (*switchData++ != kSparseSwitchSignature) {
474         /* should have been caught by verifier */
475         dvmThrowException("Ljava/lang/InternalError;",
476             "bad sparse switch magic");
477         return kInstrLen;
478     }
479 
480     size = *switchData++;
481     assert(size > 0);
482 
483     /* The keys are guaranteed to be aligned on a 32-bit boundary;
484      * we can treat them as a native int array.
485      */
486     keys = (const s4*) switchData;
487     assert(((u4)keys & 0x3) == 0);
488 
489     /* The entries are guaranteed to be aligned on a 32-bit boundary;
490      * we can treat them as a native int array.
491      */
492     entries = keys + size;
493     assert(((u4)entries & 0x3) == 0);
494 
495     /*
496      * Run through the list of keys, which are guaranteed to
497      * be sorted low-to-high.
498      *
499      * Most tables have 3-4 entries.  Few have more than 10.  A binary
500      * search here is probably not useful.
501      */
502     for (i = 0; i < size; i++) {
503         s4 k = s4FromSwitchData(&keys[i]);
504         if (k == testVal) {
505             LOGVV("Value %d found in entry %d (goto 0x%02x)\n",
506                 testVal, i, s4FromSwitchData(&entries[i]));
507             return s4FromSwitchData(&entries[i]);
508         } else if (k > testVal) {
509             break;
510         }
511     }
512 
513     LOGVV("Value %d not found in switch\n", testVal);
514     return kInstrLen;
515 }
516 
517 /*
518  * Copy data for a fill-array-data instruction.  On a little-endian machine
519  * we can just do a memcpy(), on a big-endian system we have work to do.
520  *
521  * The trick here is that dexopt has byte-swapped each code unit, which is
522  * exactly what we want for short/char data.  For byte data we need to undo
523  * the swap, and for 4- or 8-byte values we need to swap pieces within
524  * each word.
525  */
copySwappedArrayData(void * dest,const u2 * src,u4 size,u2 width)526 static void copySwappedArrayData(void* dest, const u2* src, u4 size, u2 width)
527 {
528 #if __BYTE_ORDER == __LITTLE_ENDIAN
529     memcpy(dest, src, size*width);
530 #else
531     int i;
532 
533     switch (width) {
534     case 1:
535         /* un-swap pairs of bytes as we go */
536         for (i = (size-1) & ~1; i >= 0; i -= 2) {
537             ((u1*)dest)[i] = ((u1*)src)[i+1];
538             ((u1*)dest)[i+1] = ((u1*)src)[i];
539         }
540         /*
541          * "src" is padded to end on a two-byte boundary, but we don't want to
542          * assume "dest" is, so we handle odd length specially.
543          */
544         if ((size & 1) != 0) {
545             ((u1*)dest)[size-1] = ((u1*)src)[size];
546         }
547         break;
548     case 2:
549         /* already swapped correctly */
550         memcpy(dest, src, size*width);
551         break;
552     case 4:
553         /* swap word halves */
554         for (i = 0; i < (int) size; i++) {
555             ((u4*)dest)[i] = (src[(i << 1) + 1] << 16) | src[i << 1];
556         }
557         break;
558     case 8:
559         /* swap word halves and words */
560         for (i = 0; i < (int) (size << 1); i += 2) {
561             ((int*)dest)[i] = (src[(i << 1) + 3] << 16) | src[(i << 1) + 2];
562             ((int*)dest)[i+1] = (src[(i << 1) + 1] << 16) | src[i << 1];
563         }
564         break;
565     default:
566         LOGE("Unexpected width %d in copySwappedArrayData\n", width);
567         dvmAbort();
568         break;
569     }
570 #endif
571 }
572 
573 /*
574  * Fill the array with predefined constant values.
575  *
576  * Returns true if job is completed, otherwise false to indicate that
577  * an exception has been thrown.
578  */
dvmInterpHandleFillArrayData(ArrayObject * arrayObj,const u2 * arrayData)579 bool dvmInterpHandleFillArrayData(ArrayObject* arrayObj, const u2* arrayData)
580 {
581     u2 width;
582     u4 size;
583 
584     if (arrayObj == NULL) {
585         dvmThrowException("Ljava/lang/NullPointerException;", NULL);
586         return false;
587     }
588 
589     /*
590      * Array data table format:
591      *  ushort ident = 0x0300   magic value
592      *  ushort width            width of each element in the table
593      *  uint   size             number of elements in the table
594      *  ubyte  data[size*width] table of data values (may contain a single-byte
595      *                          padding at the end)
596      *
597      * Total size is 4+(width * size + 1)/2 16-bit code units.
598      */
599     if (arrayData[0] != kArrayDataSignature) {
600         dvmThrowException("Ljava/lang/InternalError;", "bad array data magic");
601         return false;
602     }
603 
604     width = arrayData[1];
605     size = arrayData[2] | (((u4)arrayData[3]) << 16);
606 
607     if (size > arrayObj->length) {
608         dvmThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", NULL);
609         return false;
610     }
611     copySwappedArrayData(arrayObj->contents, &arrayData[4], size, width);
612     return true;
613 }
614 
615 /*
616  * Find the concrete method that corresponds to "methodIdx".  The code in
617  * "method" is executing invoke-method with "thisClass" as its first argument.
618  *
619  * Returns NULL with an exception raised on failure.
620  */
dvmInterpFindInterfaceMethod(ClassObject * thisClass,u4 methodIdx,const Method * method,DvmDex * methodClassDex)621 Method* dvmInterpFindInterfaceMethod(ClassObject* thisClass, u4 methodIdx,
622     const Method* method, DvmDex* methodClassDex)
623 {
624     Method* absMethod;
625     Method* methodToCall;
626     int i, vtableIndex;
627 
628     /*
629      * Resolve the method.  This gives us the abstract method from the
630      * interface class declaration.
631      */
632     absMethod = dvmDexGetResolvedMethod(methodClassDex, methodIdx);
633     if (absMethod == NULL) {
634         absMethod = dvmResolveInterfaceMethod(method->clazz, methodIdx);
635         if (absMethod == NULL) {
636             LOGV("+ unknown method\n");
637             return NULL;
638         }
639     }
640 
641     /* make sure absMethod->methodIndex means what we think it means */
642     assert(dvmIsAbstractMethod(absMethod));
643 
644     /*
645      * Run through the "this" object's iftable.  Find the entry for
646      * absMethod's class, then use absMethod->methodIndex to find
647      * the method's entry.  The value there is the offset into our
648      * vtable of the actual method to execute.
649      *
650      * The verifier does not guarantee that objects stored into
651      * interface references actually implement the interface, so this
652      * check cannot be eliminated.
653      */
654     for (i = 0; i < thisClass->iftableCount; i++) {
655         if (thisClass->iftable[i].clazz == absMethod->clazz)
656             break;
657     }
658     if (i == thisClass->iftableCount) {
659         /* impossible in verified DEX, need to check for it in unverified */
660         dvmThrowException("Ljava/lang/IncompatibleClassChangeError;",
661             "interface not implemented");
662         return NULL;
663     }
664 
665     assert(absMethod->methodIndex <
666         thisClass->iftable[i].clazz->virtualMethodCount);
667 
668     vtableIndex =
669         thisClass->iftable[i].methodIndexArray[absMethod->methodIndex];
670     assert(vtableIndex >= 0 && vtableIndex < thisClass->vtableCount);
671     methodToCall = thisClass->vtable[vtableIndex];
672 
673 #if 0
674     /* this can happen when there's a stale class file */
675     if (dvmIsAbstractMethod(methodToCall)) {
676         dvmThrowException("Ljava/lang/AbstractMethodError;",
677             "interface method not implemented");
678         return NULL;
679     }
680 #else
681     assert(!dvmIsAbstractMethod(methodToCall) ||
682         methodToCall->nativeFunc != NULL);
683 #endif
684 
685     LOGVV("+++ interface=%s.%s concrete=%s.%s\n",
686         absMethod->clazz->descriptor, absMethod->name,
687         methodToCall->clazz->descriptor, methodToCall->name);
688     assert(methodToCall != NULL);
689 
690     return methodToCall;
691 }
692 
693 
694 
695 /*
696  * Helpers for dvmThrowVerificationError().
697  *
698  * Each returns a newly-allocated string.
699  */
700 #define kThrowShow_accessFromClass     1
classNameFromIndex(const Method * method,int ref,VerifyErrorRefType refType,int flags)701 static char* classNameFromIndex(const Method* method, int ref,
702     VerifyErrorRefType refType, int flags)
703 {
704     static const int kBufLen = 256;
705     const DvmDex* pDvmDex = method->clazz->pDvmDex;
706 
707     if (refType == VERIFY_ERROR_REF_FIELD) {
708         /* get class ID from field ID */
709         const DexFieldId* pFieldId = dexGetFieldId(pDvmDex->pDexFile, ref);
710         ref = pFieldId->classIdx;
711     } else if (refType == VERIFY_ERROR_REF_METHOD) {
712         /* get class ID from method ID */
713         const DexMethodId* pMethodId = dexGetMethodId(pDvmDex->pDexFile, ref);
714         ref = pMethodId->classIdx;
715     }
716 
717     const char* className = dexStringByTypeIdx(pDvmDex->pDexFile, ref);
718     char* dotClassName = dvmDescriptorToDot(className);
719     if (flags == 0)
720         return dotClassName;
721 
722     char* result = (char*) malloc(kBufLen);
723 
724     if ((flags & kThrowShow_accessFromClass) != 0) {
725         char* dotFromName = dvmDescriptorToDot(method->clazz->descriptor);
726         snprintf(result, kBufLen, "tried to access class %s from class %s",
727             dotClassName, dotFromName);
728         free(dotFromName);
729     } else {
730         assert(false);      // should've been caught above
731         result[0] = '\0';
732     }
733 
734     free(dotClassName);
735     return result;
736 }
fieldNameFromIndex(const Method * method,int ref,VerifyErrorRefType refType,int flags)737 static char* fieldNameFromIndex(const Method* method, int ref,
738     VerifyErrorRefType refType, int flags)
739 {
740     static const int kBufLen = 256;
741     const DvmDex* pDvmDex = method->clazz->pDvmDex;
742     const DexFieldId* pFieldId;
743     const char* className;
744     const char* fieldName;
745 
746     if (refType != VERIFY_ERROR_REF_FIELD) {
747         LOGW("Expected ref type %d, got %d\n", VERIFY_ERROR_REF_FIELD, refType);
748         return NULL;    /* no message */
749     }
750 
751     pFieldId = dexGetFieldId(pDvmDex->pDexFile, ref);
752     className = dexStringByTypeIdx(pDvmDex->pDexFile, pFieldId->classIdx);
753     fieldName = dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx);
754 
755     char* dotName = dvmDescriptorToDot(className);
756     char* result = (char*) malloc(kBufLen);
757 
758     if ((flags & kThrowShow_accessFromClass) != 0) {
759         char* dotFromName = dvmDescriptorToDot(method->clazz->descriptor);
760         snprintf(result, kBufLen, "tried to access field %s.%s from class %s",
761             dotName, fieldName, dotFromName);
762         free(dotFromName);
763     } else {
764         snprintf(result, kBufLen, "%s.%s", dotName, fieldName);
765     }
766 
767     free(dotName);
768     return result;
769 }
methodNameFromIndex(const Method * method,int ref,VerifyErrorRefType refType,int flags)770 static char* methodNameFromIndex(const Method* method, int ref,
771     VerifyErrorRefType refType, int flags)
772 {
773     static const int kBufLen = 384;
774     const DvmDex* pDvmDex = method->clazz->pDvmDex;
775     const DexMethodId* pMethodId;
776     const char* className;
777     const char* methodName;
778 
779     if (refType != VERIFY_ERROR_REF_METHOD) {
780         LOGW("Expected ref type %d, got %d\n", VERIFY_ERROR_REF_METHOD,refType);
781         return NULL;    /* no message */
782     }
783 
784     pMethodId = dexGetMethodId(pDvmDex->pDexFile, ref);
785     className = dexStringByTypeIdx(pDvmDex->pDexFile, pMethodId->classIdx);
786     methodName = dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx);
787 
788     char* dotName = dvmDescriptorToDot(className);
789     char* result = (char*) malloc(kBufLen);
790 
791     if ((flags & kThrowShow_accessFromClass) != 0) {
792         char* dotFromName = dvmDescriptorToDot(method->clazz->descriptor);
793         char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
794         snprintf(result, kBufLen,
795             "tried to access method %s.%s:%s from class %s",
796             dotName, methodName, desc, dotFromName);
797         free(dotFromName);
798         free(desc);
799     } else {
800         snprintf(result, kBufLen, "%s.%s", dotName, methodName);
801     }
802 
803     free(dotName);
804     return result;
805 }
806 
807 /*
808  * Throw an exception for a problem identified by the verifier.
809  *
810  * This is used by the invoke-verification-error instruction.  It always
811  * throws an exception.
812  *
813  * "kind" indicates the kind of failure encountered by the verifier.  It
814  * has two parts, an error code and an indication of the reference type.
815  */
dvmThrowVerificationError(const Method * method,int kind,int ref)816 void dvmThrowVerificationError(const Method* method, int kind, int ref)
817 {
818     const int typeMask = 0xff << kVerifyErrorRefTypeShift;
819     VerifyError errorKind = kind & ~typeMask;
820     VerifyErrorRefType refType = kind >> kVerifyErrorRefTypeShift;
821     const char* exceptionName = "Ljava/lang/VerifyError;";
822     char* msg = NULL;
823 
824     switch ((VerifyError) errorKind) {
825     case VERIFY_ERROR_NO_CLASS:
826         exceptionName = "Ljava/lang/NoClassDefFoundError;";
827         msg = classNameFromIndex(method, ref, refType, 0);
828         break;
829     case VERIFY_ERROR_NO_FIELD:
830         exceptionName = "Ljava/lang/NoSuchFieldError;";
831         msg = fieldNameFromIndex(method, ref, refType, 0);
832         break;
833     case VERIFY_ERROR_NO_METHOD:
834         exceptionName = "Ljava/lang/NoSuchMethodError;";
835         msg = methodNameFromIndex(method, ref, refType, 0);
836         break;
837     case VERIFY_ERROR_ACCESS_CLASS:
838         exceptionName = "Ljava/lang/IllegalAccessError;";
839         msg = classNameFromIndex(method, ref, refType,
840             kThrowShow_accessFromClass);
841         break;
842     case VERIFY_ERROR_ACCESS_FIELD:
843         exceptionName = "Ljava/lang/IllegalAccessError;";
844         msg = fieldNameFromIndex(method, ref, refType,
845             kThrowShow_accessFromClass);
846         break;
847     case VERIFY_ERROR_ACCESS_METHOD:
848         exceptionName = "Ljava/lang/IllegalAccessError;";
849         msg = methodNameFromIndex(method, ref, refType,
850             kThrowShow_accessFromClass);
851         break;
852     case VERIFY_ERROR_CLASS_CHANGE:
853         exceptionName = "Ljava/lang/IncompatibleClassChangeError;";
854         msg = classNameFromIndex(method, ref, refType, 0);
855         break;
856     case VERIFY_ERROR_INSTANTIATION:
857         exceptionName = "Ljava/lang/InstantiationError;";
858         msg = classNameFromIndex(method, ref, refType, 0);
859         break;
860 
861     case VERIFY_ERROR_GENERIC:
862         /* generic VerifyError; use default exception, no message */
863         break;
864     case VERIFY_ERROR_NONE:
865         /* should never happen; use default exception */
866         assert(false);
867         msg = strdup("weird - no error specified");
868         break;
869 
870     /* no default clause -- want warning if enum updated */
871     }
872 
873     dvmThrowException(exceptionName, msg);
874     free(msg);
875 }
876 
877 /*
878  * Main interpreter loop entry point.  Select "standard" or "debug"
879  * interpreter and switch between them as required.
880  *
881  * This begins executing code at the start of "method".  On exit, "pResult"
882  * holds the return value of the method (or, if "method" returns NULL, it
883  * holds an undefined value).
884  *
885  * The interpreted stack frame, which holds the method arguments, has
886  * already been set up.
887  */
dvmInterpret(Thread * self,const Method * method,JValue * pResult)888 void dvmInterpret(Thread* self, const Method* method, JValue* pResult)
889 {
890     InterpState interpState;
891     bool change;
892 #if defined(WITH_JIT)
893     /* Interpreter entry points from compiled code */
894     extern void dvmJitToInterpNormal();
895     extern void dvmJitToInterpNoChain();
896     extern void dvmJitToInterpPunt();
897     extern void dvmJitToInterpSingleStep();
898     extern void dvmJitToTraceSelect();
899     extern void dvmJitToPatchPredictedChain();
900 
901     /*
902      * Reserve a static entity here to quickly setup runtime contents as
903      * gcc will issue block copy instructions.
904      */
905     static struct JitToInterpEntries jitToInterpEntries = {
906         dvmJitToInterpNormal,
907         dvmJitToInterpNoChain,
908         dvmJitToInterpPunt,
909         dvmJitToInterpSingleStep,
910         dvmJitToTraceSelect,
911         dvmJitToPatchPredictedChain,
912     };
913 #endif
914 
915 
916 #if defined(WITH_TRACKREF_CHECKS)
917     interpState.debugTrackedRefStart =
918         dvmReferenceTableEntries(&self->internalLocalRefTable);
919 #endif
920 #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER)
921     interpState.debugIsMethodEntry = true;
922 #endif
923 #if defined(WITH_JIT)
924     interpState.jitState = gDvmJit.pJitEntryTable ? kJitNormal : kJitOff;
925 
926     /* Setup the Jit-to-interpreter entry points */
927     interpState.jitToInterpEntries = jitToInterpEntries;
928 
929     /*
930      * Initialize the threshold filter [don't bother to zero out the
931      * actual table.  We're looking for matches, and an occasional
932      * false positive is acceptible.
933      */
934     interpState.lastThreshFilter = 0;
935 #endif
936 
937     /*
938      * Initialize working state.
939      *
940      * No need to initialize "retval".
941      */
942     interpState.method = method;
943     interpState.fp = (u4*) self->curFrame;
944     interpState.pc = method->insns;
945     interpState.entryPoint = kInterpEntryInstr;
946 
947     if (dvmDebuggerOrProfilerActive())
948         interpState.nextMode = INTERP_DBG;
949     else
950         interpState.nextMode = INTERP_STD;
951 
952     assert(!dvmIsNativeMethod(method));
953 
954     /*
955      * Make sure the class is ready to go.  Shouldn't be possible to get
956      * here otherwise.
957      */
958     if (method->clazz->status < CLASS_INITIALIZING ||
959         method->clazz->status == CLASS_ERROR)
960     {
961         LOGE("ERROR: tried to execute code in unprepared class '%s' (%d)\n",
962             method->clazz->descriptor, method->clazz->status);
963         dvmDumpThread(self, false);
964         dvmAbort();
965     }
966 
967     typedef bool (*Interpreter)(Thread*, InterpState*);
968     Interpreter stdInterp;
969     if (gDvm.executionMode == kExecutionModeInterpFast)
970         stdInterp = dvmMterpStd;
971 #if defined(WITH_JIT)
972     else if (gDvm.executionMode == kExecutionModeJit)
973 /* If profiling overhead can be kept low enough, we can use a profiling
974  * mterp fast for both Jit and "fast" modes.  If overhead is too high,
975  * create a specialized profiling interpreter.
976  */
977         stdInterp = dvmMterpStd;
978 #endif
979     else
980         stdInterp = dvmInterpretStd;
981 
982     change = true;
983     while (change) {
984         switch (interpState.nextMode) {
985         case INTERP_STD:
986             LOGVV("threadid=%d: interp STD\n", self->threadId);
987             change = (*stdInterp)(self, &interpState);
988             break;
989 #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER) || defined(WITH_JIT)
990         case INTERP_DBG:
991             LOGVV("threadid=%d: interp DBG\n", self->threadId);
992             change = dvmInterpretDbg(self, &interpState);
993             break;
994 #endif
995         default:
996             dvmAbort();
997         }
998     }
999 
1000     *pResult = interpState.retval;
1001 }
1002