blob: 41c5cf56ba1799078751bb0353bef7f0e7a97329 [file] [log] [blame]
The Android Open Source Project2ad60cf2008-10-21 07:00:00 -07001/*
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 * Main interpreter entry point and support functions.
18 *
19 * The entry point selects the "standard" or "debug" interpreter and
20 * facilitates switching between them. The standard interpreter may
21 * use the "fast" or "portable" implementation.
22 *
23 * Some debugger support functions are included here. Ideally their
24 * entire existence would be "#ifdef WITH_DEBUGGER", but we're not that
25 * aggressive in other parts of the code yet.
26 */
27#include "Dalvik.h"
28#include "interp/InterpDefs.h"
29
30
31/*
32 * ===========================================================================
33 * Debugger support
34 * ===========================================================================
35 */
36
37/*
38 * Initialize the breakpoint address lookup table when the debugger attaches.
39 *
40 * This shouldn't be necessary -- the global area is initially zeroed out,
41 * and the events should be cleaning up after themselves.
42 */
43void dvmInitBreakpoints(void)
44{
45#ifdef WITH_DEBUGGER
46 memset(gDvm.debugBreakAddr, 0, sizeof(gDvm.debugBreakAddr));
47#else
48 assert(false);
49#endif
50}
51
52/*
53 * Add an address to the list, putting it in the first non-empty slot.
54 *
55 * Sometimes the debugger likes to add two entries for one breakpoint.
56 * We add two entries here, so that we get the right behavior when it's
57 * removed twice.
58 *
59 * This will only be run from the JDWP thread, and it will happen while
60 * we are updating the event list, which is synchronized. We're guaranteed
61 * to be the only one adding entries, and the lock ensures that nobody
62 * will be trying to remove them while we're in here.
63 *
64 * "addr" is the absolute address of the breakpoint bytecode.
65 */
66void dvmAddBreakAddr(Method* method, int instrOffset)
67{
68#ifdef WITH_DEBUGGER
69 const u2* addr = method->insns + instrOffset;
70 const u2** ptr = gDvm.debugBreakAddr;
71 int i;
72
73 LOGV("BKP: add %p %s.%s (%s:%d)\n",
74 addr, method->clazz->descriptor, method->name,
75 dvmGetMethodSourceFile(method), dvmLineNumFromPC(method, instrOffset));
76
77 method->debugBreakpointCount++;
78 for (i = 0; i < MAX_BREAKPOINTS; i++, ptr++) {
79 if (*ptr == NULL) {
80 *ptr = addr;
81 break;
82 }
83 }
84 if (i == MAX_BREAKPOINTS) {
85 /* no room; size is too small or we're not cleaning up properly */
86 LOGE("ERROR: max breakpoints exceeded\n");
87 assert(false);
88 }
89#else
90 assert(false);
91#endif
92}
93
94/*
95 * Remove an address from the list by setting the entry to NULL.
96 *
97 * This can be called from the JDWP thread (because the debugger has
98 * cancelled the breakpoint) or from an event thread (because it's a
99 * single-shot breakpoint, e.g. "run to line"). We only get here as
100 * the result of removing an entry from the event list, which is
101 * synchronized, so it should not be possible for two threads to be
102 * updating breakpoints at the same time.
103 */
104void dvmClearBreakAddr(Method* method, int instrOffset)
105{
106#ifdef WITH_DEBUGGER
107 const u2* addr = method->insns + instrOffset;
108 const u2** ptr = gDvm.debugBreakAddr;
109 int i;
110
111 LOGV("BKP: clear %p %s.%s (%s:%d)\n",
112 addr, method->clazz->descriptor, method->name,
113 dvmGetMethodSourceFile(method), dvmLineNumFromPC(method, instrOffset));
114
115 method->debugBreakpointCount--;
116 assert(method->debugBreakpointCount >= 0);
117 for (i = 0; i < MAX_BREAKPOINTS; i++, ptr++) {
118 if (*ptr == addr) {
119 *ptr = NULL;
120 break;
121 }
122 }
123 if (i == MAX_BREAKPOINTS) {
124 /* didn't find it */
125 LOGE("ERROR: breakpoint on %p not found\n", addr);
126 assert(false);
127 }
128#else
129 assert(false);
130#endif
131}
132
133/*
134 * Add a single step event. Currently this is a global item.
135 *
136 * We set up some initial values based on the thread's current state. This
137 * won't work well if the thread is running, so it's up to the caller to
138 * verify that it's suspended.
139 *
140 * This is only called from the JDWP thread.
141 */
142bool dvmAddSingleStep(Thread* thread, int size, int depth)
143{
144#ifdef WITH_DEBUGGER
145 StepControl* pCtrl = &gDvm.stepControl;
146
147 if (pCtrl->active && thread != pCtrl->thread) {
148 LOGW("WARNING: single-step active for %p; adding %p\n",
149 pCtrl->thread, thread);
150
151 /*
152 * Keep going, overwriting previous. This can happen if you
153 * suspend a thread in Object.wait, hit the single-step key, then
154 * switch to another thread and do the same thing again.
155 * The first thread's step is still pending.
156 *
157 * TODO: consider making single-step per-thread. Adds to the
158 * overhead, but could be useful in rare situations.
159 */
160 }
161
162 pCtrl->size = size;
163 pCtrl->depth = depth;
164 pCtrl->thread = thread;
165
166 /*
167 * We may be stepping into or over method calls, or running until we
168 * return from the current method. To make this work we need to track
169 * the current line, current method, and current stack depth. We need
170 * to be checking these after most instructions, notably those that
171 * call methods, return from methods, or are on a different line from the
172 * previous instruction.
173 *
174 * We have to start with a snapshot of the current state. If we're in
175 * an interpreted method, everything we need is in the current frame. If
176 * we're in a native method, possibly with some extra JNI frames pushed
177 * on by PushLocalFrame, we want to use the topmost native method.
178 */
179 const StackSaveArea* saveArea;
180 void* fp;
181 void* prevFp = NULL;
182
183 for (fp = thread->curFrame; fp != NULL; fp = saveArea->prevFrame) {
184 const Method* method;
185
186 saveArea = SAVEAREA_FROM_FP(fp);
187 method = saveArea->method;
188
189 if (!dvmIsBreakFrame(fp) && !dvmIsNativeMethod(method))
190 break;
191 prevFp = fp;
192 }
193 if (fp == NULL) {
194 LOGW("Unexpected: step req in native-only threadid=%d\n",
195 thread->threadId);
196 return false;
197 }
198 if (prevFp != NULL) {
199 /*
200 * First interpreted frame wasn't the one at the bottom. Break
201 * frames are only inserted when calling from native->interp, so we
202 * don't need to worry about one being here.
203 */
204 LOGV("##### init step while in native method\n");
205 fp = prevFp;
206 assert(!dvmIsBreakFrame(fp));
207 assert(dvmIsNativeMethod(SAVEAREA_FROM_FP(fp)->method));
208 saveArea = SAVEAREA_FROM_FP(fp);
209 }
210
211 /*
212 * Pull the goodies out. "xtra.currentPc" should be accurate since
213 * we update it on every instruction while the debugger is connected.
214 */
215 pCtrl->method = saveArea->method;
216 // Clear out any old address set
217 if (pCtrl->pAddressSet != NULL) {
218 // (discard const)
219 free((void *)pCtrl->pAddressSet);
220 pCtrl->pAddressSet = NULL;
221 }
222 if (dvmIsNativeMethod(pCtrl->method)) {
223 pCtrl->line = -1;
224 } else {
225 pCtrl->line = dvmLineNumFromPC(saveArea->method,
226 saveArea->xtra.currentPc - saveArea->method->insns);
227 pCtrl->pAddressSet
228 = dvmAddressSetForLine(saveArea->method, pCtrl->line);
229 }
230 pCtrl->frameDepth = dvmComputeVagueFrameDepth(thread, thread->curFrame);
231 pCtrl->active = true;
232
233 LOGV("##### step init: thread=%p meth=%p '%s' line=%d frameDepth=%d depth=%s size=%s\n",
234 pCtrl->thread, pCtrl->method, pCtrl->method->name,
235 pCtrl->line, pCtrl->frameDepth,
236 dvmJdwpStepDepthStr(pCtrl->depth),
237 dvmJdwpStepSizeStr(pCtrl->size));
238
239 return true;
240#else
241 assert(false);
242 return false;
243#endif
244}
245
246/*
247 * Disable a single step event.
248 */
249void dvmClearSingleStep(Thread* thread)
250{
251#ifdef WITH_DEBUGGER
252 UNUSED_PARAMETER(thread);
253
254 gDvm.stepControl.active = false;
255#else
256 assert(false);
257#endif
258}
259
260
261/*
262 * Recover the "this" pointer from the current interpreted method. "this"
263 * is always in "in0" for non-static methods.
264 *
265 * The "ins" start at (#of registers - #of ins). Note in0 != v0.
266 *
267 * This works because "dx" guarantees that it will work. It's probably
268 * fairly common to have a virtual method that doesn't use its "this"
269 * pointer, in which case we're potentially wasting a register. However,
270 * the debugger doesn't treat "this" as just another argument. For
271 * example, events (such as breakpoints) can be enabled for specific
272 * values of "this". There is also a separate StackFrame.ThisObject call
273 * in JDWP that is expected to work for any non-native non-static method.
274 *
275 * Because we need it when setting up debugger event filters, we want to
276 * be able to do this quickly.
277 */
278Object* dvmGetThisPtr(const Method* method, const u4* fp)
279{
280 if (dvmIsStaticMethod(method))
281 return NULL;
282 return (Object*)fp[method->registersSize - method->insSize];
283}
284
285
286#if defined(WITH_TRACKREF_CHECKS)
287/*
288 * Verify that all internally-tracked references have been released. If
289 * they haven't, print them and abort the VM.
290 *
291 * "debugTrackedRefStart" indicates how many refs were on the list when
292 * we were first invoked.
293 */
294void dvmInterpCheckTrackedRefs(Thread* self, const Method* method,
295 int debugTrackedRefStart)
296{
297 if (dvmReferenceTableEntries(&self->internalLocalRefTable)
298 != (size_t) debugTrackedRefStart)
299 {
300 char* desc;
301 Object** top;
302 int count;
303
304 count = dvmReferenceTableEntries(&self->internalLocalRefTable);
305
306 LOGE("TRACK: unreleased internal reference (prev=%d total=%d)\n",
307 debugTrackedRefStart, count);
308 desc = dexProtoCopyMethodDescriptor(&method->prototype);
309 LOGE(" current method is %s.%s %s\n", method->clazz->descriptor,
310 method->name, desc);
311 free(desc);
312 top = self->internalLocalRefTable.table + debugTrackedRefStart;
313 while (top < self->internalLocalRefTable.nextEntry) {
314 LOGE(" %p (%s)\n",
315 *top,
316 ((*top)->clazz != NULL) ? (*top)->clazz->descriptor : "");
317 top++;
318 }
319 dvmDumpThread(self, false);
320
321 dvmAbort();
322 }
323 //LOGI("TRACK OK\n");
324}
325#endif
326
327
328#ifdef LOG_INSTR
329/*
330 * Dump the v-registers. Sent to the ILOG log tag.
331 */
332void dvmDumpRegs(const Method* method, const u4* framePtr, bool inOnly)
333{
334 int i, localCount;
335
336 localCount = method->registersSize - method->insSize;
337
338 LOG(LOG_VERBOSE, LOG_TAG"i", "Registers (fp=%p):\n", framePtr);
339 for (i = method->registersSize-1; i >= 0; i--) {
340 if (i >= localCount) {
341 LOG(LOG_VERBOSE, LOG_TAG"i", " v%-2d in%-2d : 0x%08x\n",
342 i, i-localCount, framePtr[i]);
343 } else {
344 if (inOnly) {
345 LOG(LOG_VERBOSE, LOG_TAG"i", " [...]\n");
346 break;
347 }
348 const char* name = "";
349 int j;
350#if 0 // "locals" structure has changed -- need to rewrite this
351 DexFile* pDexFile = method->clazz->pDexFile;
352 const DexCode* pDexCode = dvmGetMethodCode(method);
353 int localsSize = dexGetLocalsSize(pDexFile, pDexCode);
354 const DexLocal* locals = dvmDexGetLocals(pDexFile, pDexCode);
355 for (j = 0; j < localsSize, j++) {
356 if (locals[j].registerNum == (u4) i) {
357 name = dvmDexStringStr(locals[j].pName);
358 break;
359 }
360 }
361#endif
362 LOG(LOG_VERBOSE, LOG_TAG"i", " v%-2d : 0x%08x %s\n",
363 i, framePtr[i], name);
364 }
365 }
366}
367#endif
368
369
370/*
371 * ===========================================================================
372 * Entry point and general support functions
373 * ===========================================================================
374 */
375
376/*
377 * Construct an s4 from two consecutive half-words of switch data.
378 * This needs to check endianness because the DEX optimizer only swaps
379 * half-words in instruction stream.
380 *
381 * "switchData" must be 32-bit aligned.
382 */
383#if __BYTE_ORDER == __LITTLE_ENDIAN
384static inline s4 s4FromSwitchData(const void* switchData) {
385 return *(s4*) switchData;
386}
387#else
388static inline s4 s4FromSwitchData(const void* switchData) {
389 u2* data = switchData;
390 return data[0] | (((s4) data[1]) << 16);
391#endif
392
393/*
394 * Find the matching case. Returns the offset to the handler instructions.
395 *
396 * Returns 3 if we don't find a match (it's the size of the packed-switch
397 * instruction).
398 */
399s4 dvmInterpHandlePackedSwitch(const u2* switchData, s4 testVal)
400{
401 const int kInstrLen = 3;
402 u2 size;
403 s4 firstKey;
404 const s4* entries;
405
406 /*
407 * Packed switch data format:
408 * ushort ident = 0x0100 magic value
409 * ushort size number of entries in the table
410 * int first_key first (and lowest) switch case value
411 * int targets[size] branch targets, relative to switch opcode
412 *
413 * Total size is (4+size*2) 16-bit code units.
414 */
415 if (*switchData++ != kPackedSwitchSignature) {
416 /* should have been caught by verifier */
417 dvmThrowException("Ljava/lang/InternalError;",
418 "bad packed switch magic");
419 return kInstrLen;
420 }
421
422 size = *switchData++;
423 assert(size > 0);
424
425 firstKey = *switchData++;
426 firstKey |= (*switchData++) << 16;
427
428 if (testVal < firstKey || testVal >= firstKey + size) {
429 LOGVV("Value %d not found in switch (%d-%d)\n",
430 testVal, firstKey, firstKey+size-1);
431 return kInstrLen;
432 }
433
434 /* The entries are guaranteed to be aligned on a 32-bit boundary;
435 * we can treat them as a native int array.
436 */
437 entries = (const s4*) switchData;
438 assert(((u4)entries & 0x3) == 0);
439
440 assert(testVal - firstKey >= 0 && testVal - firstKey < size);
441 LOGVV("Value %d found in slot %d (goto 0x%02x)\n",
442 testVal, testVal - firstKey,
443 s4FromSwitchData(&entries[testVal - firstKey]));
444 return s4FromSwitchData(&entries[testVal - firstKey]);
445}
446
447/*
448 * Find the matching case. Returns the offset to the handler instructions.
449 *
450 * Returns 3 if we don't find a match (it's the size of the sparse-switch
451 * instruction).
452 */
453s4 dvmInterpHandleSparseSwitch(const u2* switchData, s4 testVal)
454{
455 const int kInstrLen = 3;
456 u2 ident, size;
457 const s4* keys;
458 const s4* entries;
459 int i;
460
461 /*
462 * Sparse switch data format:
463 * ushort ident = 0x0200 magic value
464 * ushort size number of entries in the table; > 0
465 * int keys[size] keys, sorted low-to-high; 32-bit aligned
466 * int targets[size] branch targets, relative to switch opcode
467 *
468 * Total size is (2+size*4) 16-bit code units.
469 */
470
471 if (*switchData++ != kSparseSwitchSignature) {
472 /* should have been caught by verifier */
473 dvmThrowException("Ljava/lang/InternalError;",
474 "bad sparse switch magic");
475 return kInstrLen;
476 }
477
478 size = *switchData++;
479 assert(size > 0);
480
481 /* The keys are guaranteed to be aligned on a 32-bit boundary;
482 * we can treat them as a native int array.
483 */
484 keys = (const s4*) switchData;
485 assert(((u4)keys & 0x3) == 0);
486
487 /* The entries are guaranteed to be aligned on a 32-bit boundary;
488 * we can treat them as a native int array.
489 */
490 entries = keys + size;
491 assert(((u4)entries & 0x3) == 0);
492
493 /*
494 * Run through the list of keys, which are guaranteed to
495 * be sorted low-to-high.
496 *
497 * Most tables have 3-4 entries. Few have more than 10. A binary
498 * search here is probably not useful.
499 */
500 for (i = 0; i < size; i++) {
501 s4 k = s4FromSwitchData(&keys[i]);
502 if (k == testVal) {
503 LOGVV("Value %d found in entry %d (goto 0x%02x)\n",
504 testVal, i, s4FromSwitchData(&entries[i]));
505 return s4FromSwitchData(&entries[i]);
506 } else if (k > testVal) {
507 break;
508 }
509 }
510
511 LOGVV("Value %d not found in switch\n", testVal);
512 return kInstrLen;
513}
514
515/*
516 * Fill the array with predefined constant values.
517 *
518 * Returns true if job is completed, otherwise false to indicate that
519 * an exception has been thrown.
520 */
521bool dvmInterpHandleFillArrayData(ArrayObject* arrayObj,
522 const u2* arrayData)
523{
524 u2 width;
525 u4 size;
526
527 if (!checkForNull((Object*) arrayObj)) {
528 return false;
529 }
530 /*
531 * Array data table format:
532 * ushort ident = 0x0300 magic value
533 * ushort width width of each element in the table
534 * uint size number of elements in the table
535 * ubyte data[size*width] table of data values (may contain a single-byte
536 * padding at the end)
537 *
538 * Total size is 4+(width * size + 1)/2 16-bit code units.
539 */
540 if (arrayData[0] != kArrayDataSignature) {
541 dvmThrowException("Ljava/lang/InternalError;", "bad array data magic");
542 return false;
543 }
544
545 width = arrayData[1];
546 size = arrayData[2] | (((u4)arrayData[3]) << 16);
547
548 if (size != arrayObj->length) {
549 dvmThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", NULL);
550 return false;
551 }
552 memcpy(arrayObj->contents, &arrayData[4], size*width);
553 return true;
554}
555
556/*
557 * Find the concrete method that corresponds to "methodIdx". The code in
558 * "method" is executing invoke-method with "thisClass" as its first argument.
559 *
560 * Returns NULL with an exception raised on failure.
561 */
562Method* dvmInterpFindInterfaceMethod(ClassObject* thisClass, u4 methodIdx,
563 const Method* method, DvmDex* methodClassDex)
564{
565 Method* absMethod;
566 Method* methodToCall;
567 int i, vtableIndex;
568
569 /*
570 * Resolve the method. This gives us the abstract method from the
571 * interface class declaration.
572 */
573 absMethod = dvmDexGetResolvedMethod(methodClassDex, methodIdx);
574 if (absMethod == NULL) {
575 absMethod = dvmResolveInterfaceMethod(method->clazz, methodIdx);
576 if (absMethod == NULL) {
577 LOGV("+ unknown method\n");
578 return NULL;
579 }
580 }
581
582 /* make sure absMethod->methodIndex means what we think it means */
583 assert(dvmIsAbstractMethod(absMethod));
584
585 /*
586 * Run through the "this" object's iftable. Find the entry for
587 * absMethod's class, then use absMethod->methodIndex to find
588 * the method's entry. The value there is the offset into our
589 * vtable of the actual method to execute.
590 *
591 * The verifier does not guarantee that objects stored into
592 * interface references actually implement the interface, so this
593 * check cannot be eliminated.
594 */
595 for (i = 0; i < thisClass->iftableCount; i++) {
596 if (thisClass->iftable[i].clazz == absMethod->clazz)
597 break;
598 }
599 if (i == thisClass->iftableCount) {
600 /* impossible in verified DEX, need to check for it in unverified */
601 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;",
602 "interface not implemented");
603 return NULL;
604 }
605
606 assert(absMethod->methodIndex <
607 thisClass->iftable[i].clazz->virtualMethodCount);
608
609 vtableIndex =
610 thisClass->iftable[i].methodIndexArray[absMethod->methodIndex];
611 assert(vtableIndex >= 0 && vtableIndex < thisClass->vtableCount);
612 methodToCall = thisClass->vtable[vtableIndex];
613
614#if 0
615 /* this can happen when there's a stale class file */
616 if (dvmIsAbstractMethod(methodToCall)) {
617 dvmThrowException("Ljava/lang/AbstractMethodError;",
618 "interface method not implemented");
619 return NULL;
620 }
621#else
622 assert(!dvmIsAbstractMethod(methodToCall) ||
623 methodToCall->nativeFunc != NULL);
624#endif
625
626 LOGVV("+++ interface=%s.%s concrete=%s.%s\n",
627 absMethod->clazz->descriptor, absMethod->name,
628 methodToCall->clazz->descriptor, methodToCall->name);
629 assert(methodToCall != NULL);
630
631 return methodToCall;
632}
633
634
635/*
636 * Main interpreter loop entry point. Select "standard" or "debug"
637 * interpreter and switch between them as required.
638 *
639 * This begins executing code at the start of "method". On exit, "pResult"
640 * holds the return value of the method (or, if "method" returns NULL, it
641 * holds an undefined value).
642 *
643 * The interpreted stack frame, which holds the method arguments, has
644 * already been set up.
645 */
646void dvmInterpret(Thread* self, const Method* method, JValue* pResult)
647{
648 InterpState interpState;
649 bool change;
650
651#if defined(WITH_TRACKREF_CHECKS)
652 interpState.debugTrackedRefStart =
653 dvmReferenceTableEntries(&self->internalLocalRefTable);
654#endif
655#if defined(WITH_PROFILER) || defined(WITH_DEBUGGER)
656 interpState.debugIsMethodEntry = true;
657#endif
658
659 /*
660 * Initialize working state.
661 *
662 * No need to initialize "retval".
663 */
664 interpState.method = method;
665 interpState.fp = (u4*) self->curFrame;
666 interpState.pc = method->insns;
667 interpState.entryPoint = kInterpEntryInstr;
668
669 if (dvmDebuggerOrProfilerActive())
670 interpState.nextMode = INTERP_DBG;
671 else
672 interpState.nextMode = INTERP_STD;
673
674 assert(!dvmIsNativeMethod(method));
675
676 /*
677 * Make sure the class is ready to go. Shouldn't be possible to get
678 * here otherwise.
679 */
680 if (method->clazz->status < CLASS_INITIALIZING ||
681 method->clazz->status == CLASS_ERROR)
682 {
683 LOGE("ERROR: tried to execute code in unprepared class '%s' (%d)\n",
684 method->clazz->descriptor, method->clazz->status);
685 dvmDumpThread(self, false);
686 dvmAbort();
687 }
688
689 typedef bool (*Interpreter)(Thread*, InterpState*);
690 Interpreter stdInterp;
691 if (gDvm.executionMode == kExecutionModeInterpFast)
692 stdInterp = dvmMterpStd;
693 else
694 stdInterp = dvmInterpretStd;
695
696 change = true;
697 while (change) {
698 switch (interpState.nextMode) {
699 case INTERP_STD:
700 LOGVV("threadid=%d: interp STD\n", self->threadId);
701 change = (*stdInterp)(self, &interpState);
702 break;
703#if defined(WITH_PROFILER) || defined(WITH_DEBUGGER)
704 case INTERP_DBG:
705 LOGVV("threadid=%d: interp DBG\n", self->threadId);
706 change = dvmInterpretDbg(self, &interpState);
707 break;
708#endif
709 default:
710 dvmAbort();
711 }
712 }
713
714 *pResult = interpState.retval;
715}