2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Main interpreter entry point and support functions.
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.
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.
29 #include "interp/InterpDefs.h"
33 * ===========================================================================
35 * ===========================================================================
39 static BreakpointSet* dvmBreakpointSetAlloc(void);
40 static void dvmBreakpointSetFree(BreakpointSet* pSet);
43 * Initialize global breakpoint structures.
45 bool dvmBreakpointStartup(void)
48 gDvm.breakpointSet = dvmBreakpointSetAlloc();
49 return (gDvm.breakpointSet != NULL);
58 void dvmBreakpointShutdown(void)
61 dvmBreakpointSetFree(gDvm.breakpointSet);
68 * This represents a breakpoint inserted in the instruction stream.
70 * The debugger may ask us to create the same breakpoint multiple times.
71 * We only remove the breakpoint when the last instance is cleared.
74 Method* method; /* method we're associated with */
75 u2* addr; /* absolute memory address */
76 u1 originalOpCode; /* original 8-bit opcode value */
77 int setCount; /* #of times this breakpoint was set */
83 struct BreakpointSet {
84 /* grab lock before reading or writing anything else in here */
87 /* vector of breakpoint structures */
90 Breakpoint* breakpoints;
94 * Initialize a BreakpointSet. Initially empty.
96 static BreakpointSet* dvmBreakpointSetAlloc(void)
98 BreakpointSet* pSet = (BreakpointSet*) calloc(1, sizeof(*pSet));
100 dvmInitMutex(&pSet->lock);
101 /* leave the rest zeroed -- will alloc on first use */
107 * Free storage associated with a BreakpointSet.
109 static void dvmBreakpointSetFree(BreakpointSet* pSet)
114 free(pSet->breakpoints);
119 * Lock the breakpoint set.
121 * It's not currently necessary to switch to VMWAIT in the event of
122 * contention, because nothing in here can block. However, it's possible
123 * that the bytecode-updater code could become fancier in the future, so
124 * we do the trylock dance as a bit of future-proofing.
126 static void dvmBreakpointSetLock(BreakpointSet* pSet)
128 if (dvmTryLockMutex(&pSet->lock) != 0) {
129 Thread* self = dvmThreadSelf();
130 ThreadStatus oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
131 dvmLockMutex(&pSet->lock);
132 dvmChangeStatus(self, oldStatus);
137 * Unlock the breakpoint set.
139 static void dvmBreakpointSetUnlock(BreakpointSet* pSet)
141 dvmUnlockMutex(&pSet->lock);
145 * Return the #of breakpoints.
147 static int dvmBreakpointSetCount(const BreakpointSet* pSet)
153 * See if we already have an entry for this address.
155 * The BreakpointSet's lock must be acquired before calling here.
157 * Returns the index of the breakpoint entry, or -1 if not found.
159 static int dvmBreakpointSetFind(const BreakpointSet* pSet, const u2* addr)
163 for (i = 0; i < pSet->count; i++) {
164 Breakpoint* pBreak = &pSet->breakpoints[i];
165 if (pBreak->addr == addr)
173 * Retrieve the opcode that was originally at the specified location.
175 * The BreakpointSet's lock must be acquired before calling here.
177 * Returns "true" with the opcode in *pOrig on success.
179 static bool dvmBreakpointSetOriginalOpCode(const BreakpointSet* pSet,
180 const u2* addr, u1* pOrig)
182 int idx = dvmBreakpointSetFind(pSet, addr);
186 *pOrig = pSet->breakpoints[idx].originalOpCode;
191 * Check the opcode. If it's a "magic" NOP, indicating the start of
192 * switch or array data in the instruction stream, we don't want to set
195 * This can happen because the line number information dx generates
196 * associates the switch data with the switch statement's line number,
197 * and some debuggers put breakpoints at every address associated with
198 * a given line. The result is that the breakpoint stomps on the NOP
199 * instruction that doubles as a data table magic number, and an explicit
200 * check in the interpreter results in an exception being thrown.
202 * We don't want to simply refuse to add the breakpoint to the table,
203 * because that confuses the housekeeping. We don't want to reject the
204 * debugger's event request, and we want to be sure that there's exactly
205 * one un-set operation for every set op.
207 static bool instructionIsMagicNop(const u2* addr)
210 return ((curVal & 0xff) == OP_NOP && (curVal >> 8) != 0);
214 * Add a breakpoint at a specific address. If the address is already
215 * present in the table, this just increments the count.
217 * For a new entry, this will extract and preserve the current opcode from
218 * the instruction stream, and replace it with a breakpoint opcode.
220 * The BreakpointSet's lock must be acquired before calling here.
222 * Returns "true" on success.
224 static bool dvmBreakpointSetAdd(BreakpointSet* pSet, Method* method,
225 unsigned int instrOffset)
227 const int kBreakpointGrowth = 10;
228 const u2* addr = method->insns + instrOffset;
229 int idx = dvmBreakpointSetFind(pSet, addr);
233 if (pSet->count == pSet->alloc) {
234 int newSize = pSet->alloc + kBreakpointGrowth;
237 LOGV("+++ increasing breakpoint set size to %d\n", newSize);
239 /* pSet->breakpoints will be NULL on first entry */
240 newVec = realloc(pSet->breakpoints, newSize * sizeof(Breakpoint));
244 pSet->breakpoints = newVec;
245 pSet->alloc = newSize;
248 pBreak = &pSet->breakpoints[pSet->count++];
249 pBreak->method = method;
250 pBreak->addr = (u2*)addr;
251 pBreak->originalOpCode = *(u1*)addr;
252 pBreak->setCount = 1;
255 * Change the opcode. We must ensure that the BreakpointSet
256 * updates happen before we change the opcode.
258 * If the method has not been verified, we do NOT insert the
259 * breakpoint yet, since that will screw up the verifier. The
260 * debugger is allowed to insert breakpoints in unverified code,
261 * but since we don't execute unverified code we don't need to
262 * alter the bytecode yet.
264 * The class init code will "flush" all pending opcode writes
265 * before verification completes.
267 assert(*(u1*)addr != OP_BREAKPOINT);
268 if (dvmIsClassVerified(method->clazz)) {
269 LOGV("Class %s verified, adding breakpoint at %p\n",
270 method->clazz->descriptor, addr);
271 if (instructionIsMagicNop(addr)) {
272 LOGV("Refusing to set breakpoint on %04x at %s.%s + 0x%x\n",
273 *addr, method->clazz->descriptor, method->name,
276 ANDROID_MEMBAR_FULL();
277 dvmDexChangeDex1(method->clazz->pDvmDex, (u1*)addr,
281 LOGV("Class %s NOT verified, deferring breakpoint at %p\n",
282 method->clazz->descriptor, addr);
286 * Breakpoint already exists, just increase the count.
288 pBreak = &pSet->breakpoints[idx];
296 * Remove one instance of the specified breakpoint. When the count
297 * reaches zero, the entry is removed from the table, and the original
298 * opcode is restored.
300 * The BreakpointSet's lock must be acquired before calling here.
302 static void dvmBreakpointSetRemove(BreakpointSet* pSet, Method* method,
303 unsigned int instrOffset)
305 const u2* addr = method->insns + instrOffset;
306 int idx = dvmBreakpointSetFind(pSet, addr);
309 /* breakpoint not found in set -- unexpected */
310 if (*(u1*)addr == OP_BREAKPOINT) {
311 LOGE("Unable to restore breakpoint opcode (%s.%s +0x%x)\n",
312 method->clazz->descriptor, method->name, instrOffset);
315 LOGW("Breakpoint was already restored? (%s.%s +0x%x)\n",
316 method->clazz->descriptor, method->name, instrOffset);
319 Breakpoint* pBreak = &pSet->breakpoints[idx];
320 if (pBreak->setCount == 1) {
322 * Must restore opcode before removing set entry.
324 * If the breakpoint was never flushed, we could be ovewriting
325 * a value with the same value. Not a problem, though we
326 * could end up causing a copy-on-write here when we didn't
327 * need to. (Not worth worrying about.)
329 dvmDexChangeDex1(method->clazz->pDvmDex, (u1*)addr,
330 pBreak->originalOpCode);
331 ANDROID_MEMBAR_FULL();
333 if (idx != pSet->count-1) {
335 memmove(&pSet->breakpoints[idx], &pSet->breakpoints[idx+1],
336 (pSet->count-1 - idx) * sizeof(pSet->breakpoints[0]));
339 pSet->breakpoints[pSet->count].addr = (u2*) 0xdecadead; // debug
342 assert(pBreak->setCount > 0);
348 * Flush any breakpoints associated with methods in "clazz". We want to
349 * change the opcode, which might not have happened when the breakpoint
350 * was initially set because the class was in the process of being
353 * The BreakpointSet's lock must be acquired before calling here.
355 static void dvmBreakpointSetFlush(BreakpointSet* pSet, ClassObject* clazz)
358 for (i = 0; i < pSet->count; i++) {
359 Breakpoint* pBreak = &pSet->breakpoints[i];
360 if (pBreak->method->clazz == clazz) {
362 * The breakpoint is associated with a method in this class.
363 * It might already be there or it might not; either way,
366 LOGV("Flushing breakpoint at %p for %s\n",
367 pBreak->addr, clazz->descriptor);
368 if (instructionIsMagicNop(pBreak->addr)) {
369 LOGV("Refusing to flush breakpoint on %04x at %s.%s + 0x%x\n",
370 *pBreak->addr, pBreak->method->clazz->descriptor,
371 pBreak->method->name, pBreak->addr - pBreak->method->insns);
373 dvmDexChangeDex1(clazz->pDvmDex, (u1*)pBreak->addr,
379 #endif /*WITH_DEBUGGER*/
383 * Do any debugger-attach-time initialization.
385 void dvmInitBreakpoints(void)
388 /* quick sanity check */
389 BreakpointSet* pSet = gDvm.breakpointSet;
390 dvmBreakpointSetLock(pSet);
391 if (dvmBreakpointSetCount(pSet) != 0) {
392 LOGW("WARNING: %d leftover breakpoints\n", dvmBreakpointSetCount(pSet));
393 /* generally not good, but we can keep going */
395 dvmBreakpointSetUnlock(pSet);
402 * Add an address to the list, putting it in the first non-empty slot.
404 * Sometimes the debugger likes to add two entries for one breakpoint.
405 * We add two entries here, so that we get the right behavior when it's
408 * This will only be run from the JDWP thread, and it will happen while
409 * we are updating the event list, which is synchronized. We're guaranteed
410 * to be the only one adding entries, and the lock ensures that nobody
411 * will be trying to remove them while we're in here.
413 * "addr" is the absolute address of the breakpoint bytecode.
415 void dvmAddBreakAddr(Method* method, unsigned int instrOffset)
418 BreakpointSet* pSet = gDvm.breakpointSet;
419 dvmBreakpointSetLock(pSet);
420 dvmBreakpointSetAdd(pSet, method, instrOffset);
421 dvmBreakpointSetUnlock(pSet);
428 * Remove an address from the list by setting the entry to NULL.
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.
437 void dvmClearBreakAddr(Method* method, unsigned int instrOffset)
440 BreakpointSet* pSet = gDvm.breakpointSet;
441 dvmBreakpointSetLock(pSet);
442 dvmBreakpointSetRemove(pSet, method, instrOffset);
443 dvmBreakpointSetUnlock(pSet);
452 * Get the original opcode from under a breakpoint.
454 u1 dvmGetOriginalOpCode(const u2* addr)
456 BreakpointSet* pSet = gDvm.breakpointSet;
459 dvmBreakpointSetLock(pSet);
460 if (!dvmBreakpointSetOriginalOpCode(pSet, addr, &orig)) {
462 if (orig == OP_BREAKPOINT) {
463 LOGE("GLITCH: can't find breakpoint, opcode is still set\n");
467 dvmBreakpointSetUnlock(pSet);
473 * Flush any breakpoints associated with methods in "clazz".
475 * We don't want to modify the bytecode of a method before the verifier
476 * gets a chance to look at it, so we postpone opcode replacement until
477 * after verification completes.
479 void dvmFlushBreakpoints(ClassObject* clazz)
481 BreakpointSet* pSet = gDvm.breakpointSet;
486 assert(dvmIsClassVerified(clazz));
487 dvmBreakpointSetLock(pSet);
488 dvmBreakpointSetFlush(pSet, clazz);
489 dvmBreakpointSetUnlock(pSet);
494 * Add a single step event. Currently this is a global item.
496 * We set up some initial values based on the thread's current state. This
497 * won't work well if the thread is running, so it's up to the caller to
498 * verify that it's suspended.
500 * This is only called from the JDWP thread.
502 bool dvmAddSingleStep(Thread* thread, int size, int depth)
505 StepControl* pCtrl = &gDvm.stepControl;
507 if (pCtrl->active && thread != pCtrl->thread) {
508 LOGW("WARNING: single-step active for %p; adding %p\n",
509 pCtrl->thread, thread);
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.
517 * TODO: consider making single-step per-thread. Adds to the
518 * overhead, but could be useful in rare situations.
523 pCtrl->depth = depth;
524 pCtrl->thread = thread;
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.
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.
539 const StackSaveArea* saveArea;
543 for (fp = thread->curFrame; fp != NULL; fp = saveArea->prevFrame) {
544 const Method* method;
546 saveArea = SAVEAREA_FROM_FP(fp);
547 method = saveArea->method;
549 if (!dvmIsBreakFrame(fp) && !dvmIsNativeMethod(method))
554 LOGW("Unexpected: step req in native-only threadid=%d\n",
558 if (prevFp != NULL) {
560 * First interpreted frame wasn't the one at the bottom. Break
561 * frames are only inserted when calling from native->interp, so we
562 * don't need to worry about one being here.
564 LOGV("##### init step while in native method\n");
566 assert(!dvmIsBreakFrame(fp));
567 assert(dvmIsNativeMethod(SAVEAREA_FROM_FP(fp)->method));
568 saveArea = SAVEAREA_FROM_FP(fp);
572 * Pull the goodies out. "xtra.currentPc" should be accurate since
573 * we update it on every instruction while the debugger is connected.
575 pCtrl->method = saveArea->method;
576 // Clear out any old address set
577 if (pCtrl->pAddressSet != NULL) {
579 free((void *)pCtrl->pAddressSet);
580 pCtrl->pAddressSet = NULL;
582 if (dvmIsNativeMethod(pCtrl->method)) {
585 pCtrl->line = dvmLineNumFromPC(saveArea->method,
586 saveArea->xtra.currentPc - saveArea->method->insns);
588 = dvmAddressSetForLine(saveArea->method, pCtrl->line);
590 pCtrl->frameDepth = dvmComputeVagueFrameDepth(thread, thread->curFrame);
591 pCtrl->active = true;
593 LOGV("##### step init: thread=%p meth=%p '%s' line=%d frameDepth=%d depth=%s size=%s\n",
594 pCtrl->thread, pCtrl->method, pCtrl->method->name,
595 pCtrl->line, pCtrl->frameDepth,
596 dvmJdwpStepDepthStr(pCtrl->depth),
597 dvmJdwpStepSizeStr(pCtrl->size));
607 * Disable a single step event.
609 void dvmClearSingleStep(Thread* thread)
612 UNUSED_PARAMETER(thread);
614 gDvm.stepControl.active = false;
622 * Recover the "this" pointer from the current interpreted method. "this"
623 * is always in "in0" for non-static methods.
625 * The "ins" start at (#of registers - #of ins). Note in0 != v0.
627 * This works because "dx" guarantees that it will work. It's probably
628 * fairly common to have a virtual method that doesn't use its "this"
629 * pointer, in which case we're potentially wasting a register. However,
630 * the debugger doesn't treat "this" as just another argument. For
631 * example, events (such as breakpoints) can be enabled for specific
632 * values of "this". There is also a separate StackFrame.ThisObject call
633 * in JDWP that is expected to work for any non-native non-static method.
635 * Because we need it when setting up debugger event filters, we want to
636 * be able to do this quickly.
638 Object* dvmGetThisPtr(const Method* method, const u4* fp)
640 if (dvmIsStaticMethod(method))
642 return (Object*)fp[method->registersSize - method->insSize];
646 #if defined(WITH_TRACKREF_CHECKS)
648 * Verify that all internally-tracked references have been released. If
649 * they haven't, print them and abort the VM.
651 * "debugTrackedRefStart" indicates how many refs were on the list when
652 * we were first invoked.
654 void dvmInterpCheckTrackedRefs(Thread* self, const Method* method,
655 int debugTrackedRefStart)
657 if (dvmReferenceTableEntries(&self->internalLocalRefTable)
658 != (size_t) debugTrackedRefStart)
664 count = dvmReferenceTableEntries(&self->internalLocalRefTable);
666 LOGE("TRACK: unreleased internal reference (prev=%d total=%d)\n",
667 debugTrackedRefStart, count);
668 desc = dexProtoCopyMethodDescriptor(&method->prototype);
669 LOGE(" current method is %s.%s %s\n", method->clazz->descriptor,
672 top = self->internalLocalRefTable.table + debugTrackedRefStart;
673 while (top < self->internalLocalRefTable.nextEntry) {
676 ((*top)->clazz != NULL) ? (*top)->clazz->descriptor : "");
679 dvmDumpThread(self, false);
683 //LOGI("TRACK OK\n");
690 * Dump the v-registers. Sent to the ILOG log tag.
692 void dvmDumpRegs(const Method* method, const u4* framePtr, bool inOnly)
696 localCount = method->registersSize - method->insSize;
698 LOG(LOG_VERBOSE, LOG_TAG"i", "Registers (fp=%p):\n", framePtr);
699 for (i = method->registersSize-1; i >= 0; i--) {
700 if (i >= localCount) {
701 LOG(LOG_VERBOSE, LOG_TAG"i", " v%-2d in%-2d : 0x%08x\n",
702 i, i-localCount, framePtr[i]);
705 LOG(LOG_VERBOSE, LOG_TAG"i", " [...]\n");
708 const char* name = "";
709 #if 0 // "locals" structure has changed -- need to rewrite this
711 DexFile* pDexFile = method->clazz->pDexFile;
712 const DexCode* pDexCode = dvmGetMethodCode(method);
713 int localsSize = dexGetLocalsSize(pDexFile, pDexCode);
714 const DexLocal* locals = dvmDexGetLocals(pDexFile, pDexCode);
715 for (j = 0; j < localsSize, j++) {
716 if (locals[j].registerNum == (u4) i) {
717 name = dvmDexStringStr(locals[j].pName);
722 LOG(LOG_VERBOSE, LOG_TAG"i", " v%-2d : 0x%08x %s\n",
723 i, framePtr[i], name);
731 * ===========================================================================
732 * Entry point and general support functions
733 * ===========================================================================
737 * Construct an s4 from two consecutive half-words of switch data.
738 * This needs to check endianness because the DEX optimizer only swaps
739 * half-words in instruction stream.
741 * "switchData" must be 32-bit aligned.
743 #if __BYTE_ORDER == __LITTLE_ENDIAN
744 static inline s4 s4FromSwitchData(const void* switchData) {
745 return *(s4*) switchData;
748 static inline s4 s4FromSwitchData(const void* switchData) {
749 u2* data = switchData;
750 return data[0] | (((s4) data[1]) << 16);
755 * Find the matching case. Returns the offset to the handler instructions.
757 * Returns 3 if we don't find a match (it's the size of the packed-switch
760 s4 dvmInterpHandlePackedSwitch(const u2* switchData, s4 testVal)
762 const int kInstrLen = 3;
768 * Packed switch data format:
769 * ushort ident = 0x0100 magic value
770 * ushort size number of entries in the table
771 * int first_key first (and lowest) switch case value
772 * int targets[size] branch targets, relative to switch opcode
774 * Total size is (4+size*2) 16-bit code units.
776 if (*switchData++ != kPackedSwitchSignature) {
777 /* should have been caught by verifier */
778 dvmThrowException("Ljava/lang/InternalError;",
779 "bad packed switch magic");
783 size = *switchData++;
786 firstKey = *switchData++;
787 firstKey |= (*switchData++) << 16;
789 if (testVal < firstKey || testVal >= firstKey + size) {
790 LOGVV("Value %d not found in switch (%d-%d)\n",
791 testVal, firstKey, firstKey+size-1);
795 /* The entries are guaranteed to be aligned on a 32-bit boundary;
796 * we can treat them as a native int array.
798 entries = (const s4*) switchData;
799 assert(((u4)entries & 0x3) == 0);
801 assert(testVal - firstKey >= 0 && testVal - firstKey < size);
802 LOGVV("Value %d found in slot %d (goto 0x%02x)\n",
803 testVal, testVal - firstKey,
804 s4FromSwitchData(&entries[testVal - firstKey]));
805 return s4FromSwitchData(&entries[testVal - firstKey]);
809 * Find the matching case. Returns the offset to the handler instructions.
811 * Returns 3 if we don't find a match (it's the size of the sparse-switch
814 s4 dvmInterpHandleSparseSwitch(const u2* switchData, s4 testVal)
816 const int kInstrLen = 3;
822 * Sparse switch data format:
823 * ushort ident = 0x0200 magic value
824 * ushort size number of entries in the table; > 0
825 * int keys[size] keys, sorted low-to-high; 32-bit aligned
826 * int targets[size] branch targets, relative to switch opcode
828 * Total size is (2+size*4) 16-bit code units.
831 if (*switchData++ != kSparseSwitchSignature) {
832 /* should have been caught by verifier */
833 dvmThrowException("Ljava/lang/InternalError;",
834 "bad sparse switch magic");
838 size = *switchData++;
841 /* The keys are guaranteed to be aligned on a 32-bit boundary;
842 * we can treat them as a native int array.
844 keys = (const s4*) switchData;
845 assert(((u4)keys & 0x3) == 0);
847 /* The entries are guaranteed to be aligned on a 32-bit boundary;
848 * we can treat them as a native int array.
850 entries = keys + size;
851 assert(((u4)entries & 0x3) == 0);
854 * Binary-search through the array of keys, which are guaranteed to
855 * be sorted low-to-high.
860 int mid = (lo + hi) >> 1;
862 s4 foundVal = s4FromSwitchData(&keys[mid]);
863 if (testVal < foundVal) {
865 } else if (testVal > foundVal) {
868 LOGVV("Value %d found in entry %d (goto 0x%02x)\n",
869 testVal, mid, s4FromSwitchData(&entries[mid]));
870 return s4FromSwitchData(&entries[mid]);
874 LOGVV("Value %d not found in switch\n", testVal);
879 * Copy data for a fill-array-data instruction. On a little-endian machine
880 * we can just do a memcpy(), on a big-endian system we have work to do.
882 * The trick here is that dexopt has byte-swapped each code unit, which is
883 * exactly what we want for short/char data. For byte data we need to undo
884 * the swap, and for 4- or 8-byte values we need to swap pieces within
887 static void copySwappedArrayData(void* dest, const u2* src, u4 size, u2 width)
889 #if __BYTE_ORDER == __LITTLE_ENDIAN
890 memcpy(dest, src, size*width);
896 /* un-swap pairs of bytes as we go */
897 for (i = (size-1) & ~1; i >= 0; i -= 2) {
898 ((u1*)dest)[i] = ((u1*)src)[i+1];
899 ((u1*)dest)[i+1] = ((u1*)src)[i];
902 * "src" is padded to end on a two-byte boundary, but we don't want to
903 * assume "dest" is, so we handle odd length specially.
905 if ((size & 1) != 0) {
906 ((u1*)dest)[size-1] = ((u1*)src)[size];
910 /* already swapped correctly */
911 memcpy(dest, src, size*width);
914 /* swap word halves */
915 for (i = 0; i < (int) size; i++) {
916 ((u4*)dest)[i] = (src[(i << 1) + 1] << 16) | src[i << 1];
920 /* swap word halves and words */
921 for (i = 0; i < (int) (size << 1); i += 2) {
922 ((int*)dest)[i] = (src[(i << 1) + 3] << 16) | src[(i << 1) + 2];
923 ((int*)dest)[i+1] = (src[(i << 1) + 1] << 16) | src[i << 1];
927 LOGE("Unexpected width %d in copySwappedArrayData\n", width);
935 * Fill the array with predefined constant values.
937 * Returns true if job is completed, otherwise false to indicate that
938 * an exception has been thrown.
940 bool dvmInterpHandleFillArrayData(ArrayObject* arrayObj, const u2* arrayData)
945 if (arrayObj == NULL) {
946 dvmThrowException("Ljava/lang/NullPointerException;", NULL);
949 assert (!IS_CLASS_FLAG_SET(((Object *)arrayObj)->clazz,
950 CLASS_ISOBJECTARRAY));
953 * Array data table format:
954 * ushort ident = 0x0300 magic value
955 * ushort width width of each element in the table
956 * uint size number of elements in the table
957 * ubyte data[size*width] table of data values (may contain a single-byte
958 * padding at the end)
960 * Total size is 4+(width * size + 1)/2 16-bit code units.
962 if (arrayData[0] != kArrayDataSignature) {
963 dvmThrowException("Ljava/lang/InternalError;", "bad array data magic");
967 width = arrayData[1];
968 size = arrayData[2] | (((u4)arrayData[3]) << 16);
970 if (size > arrayObj->length) {
971 dvmThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", NULL);
974 copySwappedArrayData(arrayObj->contents, &arrayData[4], size, width);
979 * Find the concrete method that corresponds to "methodIdx". The code in
980 * "method" is executing invoke-method with "thisClass" as its first argument.
982 * Returns NULL with an exception raised on failure.
984 Method* dvmInterpFindInterfaceMethod(ClassObject* thisClass, u4 methodIdx,
985 const Method* method, DvmDex* methodClassDex)
988 Method* methodToCall;
992 * Resolve the method. This gives us the abstract method from the
993 * interface class declaration.
995 absMethod = dvmDexGetResolvedMethod(methodClassDex, methodIdx);
996 if (absMethod == NULL) {
997 absMethod = dvmResolveInterfaceMethod(method->clazz, methodIdx);
998 if (absMethod == NULL) {
999 LOGV("+ unknown method\n");
1004 /* make sure absMethod->methodIndex means what we think it means */
1005 assert(dvmIsAbstractMethod(absMethod));
1008 * Run through the "this" object's iftable. Find the entry for
1009 * absMethod's class, then use absMethod->methodIndex to find
1010 * the method's entry. The value there is the offset into our
1011 * vtable of the actual method to execute.
1013 * The verifier does not guarantee that objects stored into
1014 * interface references actually implement the interface, so this
1015 * check cannot be eliminated.
1017 for (i = 0; i < thisClass->iftableCount; i++) {
1018 if (thisClass->iftable[i].clazz == absMethod->clazz)
1021 if (i == thisClass->iftableCount) {
1022 /* impossible in verified DEX, need to check for it in unverified */
1023 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;",
1024 "interface not implemented");
1028 assert(absMethod->methodIndex <
1029 thisClass->iftable[i].clazz->virtualMethodCount);
1032 thisClass->iftable[i].methodIndexArray[absMethod->methodIndex];
1033 assert(vtableIndex >= 0 && vtableIndex < thisClass->vtableCount);
1034 methodToCall = thisClass->vtable[vtableIndex];
1037 /* this can happen when there's a stale class file */
1038 if (dvmIsAbstractMethod(methodToCall)) {
1039 dvmThrowException("Ljava/lang/AbstractMethodError;",
1040 "interface method not implemented");
1044 assert(!dvmIsAbstractMethod(methodToCall) ||
1045 methodToCall->nativeFunc != NULL);
1048 LOGVV("+++ interface=%s.%s concrete=%s.%s\n",
1049 absMethod->clazz->descriptor, absMethod->name,
1050 methodToCall->clazz->descriptor, methodToCall->name);
1051 assert(methodToCall != NULL);
1053 return methodToCall;
1059 * Helpers for dvmThrowVerificationError().
1061 * Each returns a newly-allocated string.
1063 #define kThrowShow_accessFromClass 1
1064 static char* classNameFromIndex(const Method* method, int ref,
1065 VerifyErrorRefType refType, int flags)
1067 static const int kBufLen = 256;
1068 const DvmDex* pDvmDex = method->clazz->pDvmDex;
1070 if (refType == VERIFY_ERROR_REF_FIELD) {
1071 /* get class ID from field ID */
1072 const DexFieldId* pFieldId = dexGetFieldId(pDvmDex->pDexFile, ref);
1073 ref = pFieldId->classIdx;
1074 } else if (refType == VERIFY_ERROR_REF_METHOD) {
1075 /* get class ID from method ID */
1076 const DexMethodId* pMethodId = dexGetMethodId(pDvmDex->pDexFile, ref);
1077 ref = pMethodId->classIdx;
1080 const char* className = dexStringByTypeIdx(pDvmDex->pDexFile, ref);
1081 char* dotClassName = dvmDescriptorToDot(className);
1083 return dotClassName;
1085 char* result = (char*) malloc(kBufLen);
1087 if ((flags & kThrowShow_accessFromClass) != 0) {
1088 char* dotFromName = dvmDescriptorToDot(method->clazz->descriptor);
1089 snprintf(result, kBufLen, "tried to access class %s from class %s",
1090 dotClassName, dotFromName);
1093 assert(false); // should've been caught above
1100 static char* fieldNameFromIndex(const Method* method, int ref,
1101 VerifyErrorRefType refType, int flags)
1103 static const int kBufLen = 256;
1104 const DvmDex* pDvmDex = method->clazz->pDvmDex;
1105 const DexFieldId* pFieldId;
1106 const char* className;
1107 const char* fieldName;
1109 if (refType != VERIFY_ERROR_REF_FIELD) {
1110 LOGW("Expected ref type %d, got %d\n", VERIFY_ERROR_REF_FIELD, refType);
1111 return NULL; /* no message */
1114 pFieldId = dexGetFieldId(pDvmDex->pDexFile, ref);
1115 className = dexStringByTypeIdx(pDvmDex->pDexFile, pFieldId->classIdx);
1116 fieldName = dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx);
1118 char* dotName = dvmDescriptorToDot(className);
1119 char* result = (char*) malloc(kBufLen);
1121 if ((flags & kThrowShow_accessFromClass) != 0) {
1122 char* dotFromName = dvmDescriptorToDot(method->clazz->descriptor);
1123 snprintf(result, kBufLen, "tried to access field %s.%s from class %s",
1124 dotName, fieldName, dotFromName);
1127 snprintf(result, kBufLen, "%s.%s", dotName, fieldName);
1133 static char* methodNameFromIndex(const Method* method, int ref,
1134 VerifyErrorRefType refType, int flags)
1136 static const int kBufLen = 384;
1137 const DvmDex* pDvmDex = method->clazz->pDvmDex;
1138 const DexMethodId* pMethodId;
1139 const char* className;
1140 const char* methodName;
1142 if (refType != VERIFY_ERROR_REF_METHOD) {
1143 LOGW("Expected ref type %d, got %d\n", VERIFY_ERROR_REF_METHOD,refType);
1144 return NULL; /* no message */
1147 pMethodId = dexGetMethodId(pDvmDex->pDexFile, ref);
1148 className = dexStringByTypeIdx(pDvmDex->pDexFile, pMethodId->classIdx);
1149 methodName = dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx);
1151 char* dotName = dvmDescriptorToDot(className);
1152 char* result = (char*) malloc(kBufLen);
1154 if ((flags & kThrowShow_accessFromClass) != 0) {
1155 char* dotFromName = dvmDescriptorToDot(method->clazz->descriptor);
1156 char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
1157 snprintf(result, kBufLen,
1158 "tried to access method %s.%s:%s from class %s",
1159 dotName, methodName, desc, dotFromName);
1163 snprintf(result, kBufLen, "%s.%s", dotName, methodName);
1171 * Throw an exception for a problem identified by the verifier.
1173 * This is used by the invoke-verification-error instruction. It always
1174 * throws an exception.
1176 * "kind" indicates the kind of failure encountered by the verifier. It
1177 * has two parts, an error code and an indication of the reference type.
1179 void dvmThrowVerificationError(const Method* method, int kind, int ref)
1181 const int typeMask = 0xff << kVerifyErrorRefTypeShift;
1182 VerifyError errorKind = kind & ~typeMask;
1183 VerifyErrorRefType refType = kind >> kVerifyErrorRefTypeShift;
1184 const char* exceptionName = "Ljava/lang/VerifyError;";
1187 switch ((VerifyError) errorKind) {
1188 case VERIFY_ERROR_NO_CLASS:
1189 exceptionName = "Ljava/lang/NoClassDefFoundError;";
1190 msg = classNameFromIndex(method, ref, refType, 0);
1192 case VERIFY_ERROR_NO_FIELD:
1193 exceptionName = "Ljava/lang/NoSuchFieldError;";
1194 msg = fieldNameFromIndex(method, ref, refType, 0);
1196 case VERIFY_ERROR_NO_METHOD:
1197 exceptionName = "Ljava/lang/NoSuchMethodError;";
1198 msg = methodNameFromIndex(method, ref, refType, 0);
1200 case VERIFY_ERROR_ACCESS_CLASS:
1201 exceptionName = "Ljava/lang/IllegalAccessError;";
1202 msg = classNameFromIndex(method, ref, refType,
1203 kThrowShow_accessFromClass);
1205 case VERIFY_ERROR_ACCESS_FIELD:
1206 exceptionName = "Ljava/lang/IllegalAccessError;";
1207 msg = fieldNameFromIndex(method, ref, refType,
1208 kThrowShow_accessFromClass);
1210 case VERIFY_ERROR_ACCESS_METHOD:
1211 exceptionName = "Ljava/lang/IllegalAccessError;";
1212 msg = methodNameFromIndex(method, ref, refType,
1213 kThrowShow_accessFromClass);
1215 case VERIFY_ERROR_CLASS_CHANGE:
1216 exceptionName = "Ljava/lang/IncompatibleClassChangeError;";
1217 msg = classNameFromIndex(method, ref, refType, 0);
1219 case VERIFY_ERROR_INSTANTIATION:
1220 exceptionName = "Ljava/lang/InstantiationError;";
1221 msg = classNameFromIndex(method, ref, refType, 0);
1224 case VERIFY_ERROR_GENERIC:
1225 /* generic VerifyError; use default exception, no message */
1227 case VERIFY_ERROR_NONE:
1228 /* should never happen; use default exception */
1230 msg = strdup("weird - no error specified");
1233 /* no default clause -- want warning if enum updated */
1236 dvmThrowException(exceptionName, msg);
1241 * Main interpreter loop entry point. Select "standard" or "debug"
1242 * interpreter and switch between them as required.
1244 * This begins executing code at the start of "method". On exit, "pResult"
1245 * holds the return value of the method (or, if "method" returns NULL, it
1246 * holds an undefined value).
1248 * The interpreted stack frame, which holds the method arguments, has
1249 * already been set up.
1251 void dvmInterpret(Thread* self, const Method* method, JValue* pResult)
1253 InterpState interpState;
1255 #if defined(WITH_JIT)
1256 /* Target-specific save/restore */
1257 extern void dvmJitCalleeSave(double *saveArea);
1258 extern void dvmJitCalleeRestore(double *saveArea);
1259 /* Interpreter entry points from compiled code */
1260 extern void dvmJitToInterpNormal();
1261 extern void dvmJitToInterpNoChain();
1262 extern void dvmJitToInterpPunt();
1263 extern void dvmJitToInterpSingleStep();
1264 extern void dvmJitToInterpTraceSelectNoChain();
1265 extern void dvmJitToInterpTraceSelect();
1266 extern void dvmJitToPatchPredictedChain();
1267 #if defined(WITH_SELF_VERIFICATION)
1268 extern void dvmJitToInterpBackwardBranch();
1272 * Reserve a static entity here to quickly setup runtime contents as
1273 * gcc will issue block copy instructions.
1275 static struct JitToInterpEntries jitToInterpEntries = {
1276 dvmJitToInterpNormal,
1277 dvmJitToInterpNoChain,
1279 dvmJitToInterpSingleStep,
1280 dvmJitToInterpTraceSelectNoChain,
1281 dvmJitToInterpTraceSelect,
1282 dvmJitToPatchPredictedChain,
1283 #if defined(WITH_SELF_VERIFICATION)
1284 dvmJitToInterpBackwardBranch,
1289 * If the previous VM left the code cache through single-stepping the
1290 * inJitCodeCache flag will be set when the VM is re-entered (for example,
1291 * in self-verification mode we single-step NEW_INSTANCE which may re-enter
1292 * the VM through findClassFromLoaderNoInit). Because of that, we cannot
1293 * assert that self->inJitCodeCache is NULL here.
1298 #if defined(WITH_TRACKREF_CHECKS)
1299 interpState.debugTrackedRefStart =
1300 dvmReferenceTableEntries(&self->internalLocalRefTable);
1302 #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER)
1303 interpState.debugIsMethodEntry = true;
1305 #if defined(WITH_JIT)
1306 dvmJitCalleeSave(interpState.calleeSave);
1307 /* Initialize the state to kJitNot */
1308 interpState.jitState = kJitNot;
1310 /* Setup the Jit-to-interpreter entry points */
1311 interpState.jitToInterpEntries = jitToInterpEntries;
1314 * Initialize the threshold filter [don't bother to zero out the
1315 * actual table. We're looking for matches, and an occasional
1316 * false positive is acceptible.
1318 interpState.lastThreshFilter = 0;
1320 interpState.icRechainCount = PREDICTED_CHAIN_COUNTER_RECHAIN;
1324 * Initialize working state.
1326 * No need to initialize "retval".
1328 interpState.method = method;
1329 interpState.fp = (u4*) self->curFrame;
1330 interpState.pc = method->insns;
1331 interpState.entryPoint = kInterpEntryInstr;
1333 if (dvmDebuggerOrProfilerActive())
1334 interpState.nextMode = INTERP_DBG;
1336 interpState.nextMode = INTERP_STD;
1338 assert(!dvmIsNativeMethod(method));
1341 * Make sure the class is ready to go. Shouldn't be possible to get
1344 if (method->clazz->status < CLASS_INITIALIZING ||
1345 method->clazz->status == CLASS_ERROR)
1347 LOGE("ERROR: tried to execute code in unprepared class '%s' (%d)\n",
1348 method->clazz->descriptor, method->clazz->status);
1349 dvmDumpThread(self, false);
1353 typedef bool (*Interpreter)(Thread*, InterpState*);
1354 Interpreter stdInterp;
1355 if (gDvm.executionMode == kExecutionModeInterpFast)
1356 stdInterp = dvmMterpStd;
1357 #if defined(WITH_JIT)
1358 else if (gDvm.executionMode == kExecutionModeJit)
1359 /* If profiling overhead can be kept low enough, we can use a profiling
1360 * mterp fast for both Jit and "fast" modes. If overhead is too high,
1361 * create a specialized profiling interpreter.
1363 stdInterp = dvmMterpStd;
1366 stdInterp = dvmInterpretStd;
1370 switch (interpState.nextMode) {
1372 LOGVV("threadid=%d: interp STD\n", self->threadId);
1373 change = (*stdInterp)(self, &interpState);
1375 #if defined(WITH_PROFILER) || defined(WITH_DEBUGGER) || defined(WITH_JIT)
1377 LOGVV("threadid=%d: interp DBG\n", self->threadId);
1378 change = dvmInterpretDbg(self, &interpState);
1386 /* Never on the heap, so no write barrier needed. */
1387 assert(!dvmIsValidObjectAddress(pResult));
1388 *pResult = interpState.retval;
1389 #if defined(WITH_JIT)
1390 dvmJitCalleeRestore(interpState.calleeSave);