blob: 14aa9cb0861b76e44d8ef50b519d15b61e9cb790 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
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 */
The Android Open Source Project99409882009-03-18 22:20:24 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Thread support.
19 */
20#include "Dalvik.h"
21
22#include "utils/threads.h" // need Android thread priorities
23
24#include <stdlib.h>
25#include <unistd.h>
26#include <sys/time.h>
27#include <sys/resource.h>
28#include <sys/mman.h>
29#include <errno.h>
30
31#if defined(HAVE_PRCTL)
32#include <sys/prctl.h>
33#endif
34
35/* desktop Linux needs a little help with gettid() */
36#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
37#define __KERNEL__
38# include <linux/unistd.h>
39#ifdef _syscall0
40_syscall0(pid_t,gettid)
41#else
42pid_t gettid() { return syscall(__NR_gettid);}
43#endif
44#undef __KERNEL__
45#endif
46
47// change this to LOGV/LOGD to debug thread activity
48#define LOG_THREAD LOGVV
49
50/*
51Notes on Threading
52
53All threads are native pthreads. All threads, except the JDWP debugger
54thread, are visible to code running in the VM and to the debugger. (We
55don't want the debugger to try to manipulate the thread that listens for
56instructions from the debugger.) Internal VM threads are in the "system"
57ThreadGroup, all others are in the "main" ThreadGroup, per convention.
58
59The GC only runs when all threads have been suspended. Threads are
60expected to suspend themselves, using a "safe point" mechanism. We check
61for a suspend request at certain points in the main interpreter loop,
62and on requests coming in from native code (e.g. all JNI functions).
63Certain debugger events may inspire threads to self-suspend.
64
65Native methods must use JNI calls to modify object references to avoid
66clashes with the GC. JNI doesn't provide a way for native code to access
67arrays of objects as such -- code must always get/set individual entries --
68so it should be possible to fully control access through JNI.
69
70Internal native VM threads, such as the finalizer thread, must explicitly
71check for suspension periodically. In most cases they will be sound
72asleep on a condition variable, and won't notice the suspension anyway.
73
74Threads may be suspended by the GC, debugger, or the SIGQUIT listener
75thread. The debugger may suspend or resume individual threads, while the
76GC always suspends all threads. Each thread has a "suspend count" that
77is incremented on suspend requests and decremented on resume requests.
78When the count is zero, the thread is runnable. This allows us to fulfill
79a debugger requirement: if the debugger suspends a thread, the thread is
80not allowed to run again until the debugger resumes it (or disconnects,
81in which case we must resume all debugger-suspended threads).
82
83Paused threads sleep on a condition variable, and are awoken en masse.
84Certain "slow" VM operations, such as starting up a new thread, will be
85done in a separate "VMWAIT" state, so that the rest of the VM doesn't
86freeze up waiting for the operation to finish. Threads must check for
87pending suspension when leaving VMWAIT.
88
89Because threads suspend themselves while interpreting code or when native
90code makes JNI calls, there is no risk of suspending while holding internal
91VM locks. All threads can enter a suspended (or native-code-only) state.
92Also, we don't have to worry about object references existing solely
93in hardware registers.
94
95We do, however, have to worry about objects that were allocated internally
96and aren't yet visible to anything else in the VM. If we allocate an
97object, and then go to sleep on a mutex after changing to a non-RUNNING
98state (e.g. while trying to allocate a second object), the first object
99could be garbage-collected out from under us while we sleep. To manage
100this, we automatically add all allocated objects to an internal object
101tracking list, and only remove them when we know we won't be suspended
102before the object appears in the GC root set.
103
104The debugger may choose to suspend or resume a single thread, which can
105lead to application-level deadlocks; this is expected behavior. The VM
106will only check for suspension of single threads when the debugger is
107active (the java.lang.Thread calls for this are deprecated and hence are
108not supported). Resumption of a single thread is handled by decrementing
109the thread's suspend count and sending a broadcast signal to the condition
110variable. (This will cause all threads to wake up and immediately go back
111to sleep, which isn't tremendously efficient, but neither is having the
112debugger attached.)
113
114The debugger is not allowed to resume threads suspended by the GC. This
115is trivially enforced by ignoring debugger requests while the GC is running
116(the JDWP thread is suspended during GC).
117
118The VM maintains a Thread struct for every pthread known to the VM. There
119is a java/lang/Thread object associated with every Thread. At present,
120there is no safe way to go from a Thread object to a Thread struct except by
121locking and scanning the list; this is necessary because the lifetimes of
122the two are not closely coupled. We may want to change this behavior,
123though at present the only performance impact is on the debugger (see
124threadObjToThread()). See also notes about dvmDetachCurrentThread().
125*/
126/*
127Alternate implementation (signal-based):
128
129Threads run without safe points -- zero overhead. The VM uses a signal
130(e.g. pthread_kill(SIGUSR1)) to notify threads of suspension or resumption.
131
132The trouble with using signals to suspend threads is that it means a thread
133can be in the middle of an operation when garbage collection starts.
134To prevent some sticky situations, we have to introduce critical sections
135to the VM code.
136
137Critical sections temporarily block suspension for a given thread.
138The thread must move to a non-blocked state (and self-suspend) after
139finishing its current task. If the thread blocks on a resource held
140by a suspended thread, we're hosed.
141
142One approach is to require that no blocking operations, notably
143acquisition of mutexes, can be performed within a critical section.
144This is too limiting. For example, if thread A gets suspended while
145holding the thread list lock, it will prevent the GC or debugger from
146being able to safely access the thread list. We need to wrap the critical
147section around the entire operation (enter critical, get lock, do stuff,
148release lock, exit critical).
149
150A better approach is to declare that certain resources can only be held
151within critical sections. A thread that enters a critical section and
152then gets blocked on the thread list lock knows that the thread it is
153waiting for is also in a critical section, and will release the lock
154before suspending itself. Eventually all threads will complete their
155operations and self-suspend. For this to work, the VM must:
156
157 (1) Determine the set of resources that may be accessed from the GC or
158 debugger threads. The mutexes guarding those go into the "critical
159 resource set" (CRS).
160 (2) Ensure that no resource in the CRS can be acquired outside of a
161 critical section. This can be verified with an assert().
162 (3) Ensure that only resources in the CRS can be held while in a critical
163 section. This is harder to enforce.
164
165If any of these conditions are not met, deadlock can ensue when grabbing
166resources in the GC or debugger (#1) or waiting for threads to suspend
167(#2,#3). (You won't actually deadlock in the GC, because if the semantics
168above are followed you don't need to lock anything in the GC. The risk is
169rather that the GC will access data structures in an intermediate state.)
170
171This approach requires more care and awareness in the VM than
172safe-pointing. Because the GC and debugger are fairly intrusive, there
173really aren't any internal VM resources that aren't shared. Thus, the
174enter/exit critical calls can be added to internal mutex wrappers, which
175makes it easy to get #1 and #2 right.
176
177An ordering should be established for all locks to avoid deadlocks.
178
179Monitor locks, which are also implemented with pthread calls, should not
180cause any problems here. Threads fighting over such locks will not be in
181critical sections and can be suspended freely.
182
183This can get tricky if we ever need exclusive access to VM and non-VM
184resources at the same time. It's not clear if this is a real concern.
185
186There are (at least) two ways to handle the incoming signals:
187
188 (a) Always accept signals. If we're in a critical section, the signal
189 handler just returns without doing anything (the "suspend level"
190 should have been incremented before the signal was sent). Otherwise,
191 if the "suspend level" is nonzero, we go to sleep.
192 (b) Block signals in critical sections. This ensures that we can't be
193 interrupted in a critical section, but requires pthread_sigmask()
194 calls on entry and exit.
195
196This is a choice between blocking the message and blocking the messenger.
197Because UNIX signals are unreliable (you can only know that you have been
198signaled, not whether you were signaled once or 10 times), the choice is
199not significant for correctness. The choice depends on the efficiency
200of pthread_sigmask() and the desire to actually block signals. Either way,
201it is best to ensure that there is only one indication of "blocked";
202having two (i.e. block signals and set a flag, then only send a signal
203if the flag isn't set) can lead to race conditions.
204
205The signal handler must take care to copy registers onto the stack (via
206setjmp), so that stack scans find all references. Because we have to scan
207native stacks, "exact" GC is not possible with this approach.
208
209Some other concerns with flinging signals around:
210 - Odd interactions with some debuggers (e.g. gdb on the Mac)
211 - Restrictions on some standard library calls during GC (e.g. don't
212 use printf on stdout to print GC debug messages)
213*/
214
215#define kMaxThreadId ((1<<15) - 1)
216#define kMainThreadId ((1<<1) | 1)
217
218
219static Thread* allocThread(int interpStackSize);
220static bool prepareThread(Thread* thread);
221static void setThreadSelf(Thread* thread);
222static void unlinkThread(Thread* thread);
223static void freeThread(Thread* thread);
224static void assignThreadId(Thread* thread);
225static bool createFakeEntryFrame(Thread* thread);
226static bool createFakeRunFrame(Thread* thread);
227static void* interpThreadStart(void* arg);
228static void* internalThreadStart(void* arg);
229static void threadExitUncaughtException(Thread* thread, Object* group);
230static void threadExitCheck(void* arg);
231static void waitForThreadSuspend(Thread* self, Thread* thread);
232static int getThreadPriorityFromSystem(void);
233
234
235/*
236 * Initialize thread list and main thread's environment. We need to set
237 * up some basic stuff so that dvmThreadSelf() will work when we start
238 * loading classes (e.g. to check for exceptions).
239 */
240bool dvmThreadStartup(void)
241{
242 Thread* thread;
243
244 /* allocate a TLS slot */
245 if (pthread_key_create(&gDvm.pthreadKeySelf, threadExitCheck) != 0) {
246 LOGE("ERROR: pthread_key_create failed\n");
247 return false;
248 }
249
250 /* test our pthread lib */
251 if (pthread_getspecific(gDvm.pthreadKeySelf) != NULL)
252 LOGW("WARNING: newly-created pthread TLS slot is not NULL\n");
253
254 /* prep thread-related locks and conditions */
255 dvmInitMutex(&gDvm.threadListLock);
256 pthread_cond_init(&gDvm.threadStartCond, NULL);
257 //dvmInitMutex(&gDvm.vmExitLock);
258 pthread_cond_init(&gDvm.vmExitCond, NULL);
259 dvmInitMutex(&gDvm._threadSuspendLock);
260 dvmInitMutex(&gDvm.threadSuspendCountLock);
261 pthread_cond_init(&gDvm.threadSuspendCountCond, NULL);
262#ifdef WITH_DEADLOCK_PREDICTION
263 dvmInitMutex(&gDvm.deadlockHistoryLock);
264#endif
265
266 /*
267 * Dedicated monitor for Thread.sleep().
268 * TODO: change this to an Object* so we don't have to expose this
269 * call, and we interact better with JDWP monitor calls. Requires
270 * deferring the object creation to much later (e.g. final "main"
271 * thread prep) or until first use.
272 */
273 gDvm.threadSleepMon = dvmCreateMonitor(NULL);
274
275 gDvm.threadIdMap = dvmAllocBitVector(kMaxThreadId, false);
276
277 thread = allocThread(gDvm.stackSize);
278 if (thread == NULL)
279 return false;
280
281 /* switch mode for when we run initializers */
282 thread->status = THREAD_RUNNING;
283
284 /*
285 * We need to assign the threadId early so we can lock/notify
286 * object monitors. We'll set the "threadObj" field later.
287 */
288 prepareThread(thread);
289 gDvm.threadList = thread;
290
291#ifdef COUNT_PRECISE_METHODS
292 gDvm.preciseMethods = dvmPointerSetAlloc(200);
293#endif
294
295 return true;
296}
297
298/*
299 * We're a little farther up now, and can load some basic classes.
300 *
301 * We're far enough along that we can poke at java.lang.Thread and friends,
302 * but should not assume that static initializers have run (or cause them
303 * to do so). That means no object allocations yet.
304 */
305bool dvmThreadObjStartup(void)
306{
307 /*
308 * Cache the locations of these classes. It's likely that we're the
309 * first to reference them, so they're being loaded now.
310 */
311 gDvm.classJavaLangThread =
312 dvmFindSystemClassNoInit("Ljava/lang/Thread;");
313 gDvm.classJavaLangVMThread =
314 dvmFindSystemClassNoInit("Ljava/lang/VMThread;");
315 gDvm.classJavaLangThreadGroup =
316 dvmFindSystemClassNoInit("Ljava/lang/ThreadGroup;");
317 if (gDvm.classJavaLangThread == NULL ||
318 gDvm.classJavaLangThreadGroup == NULL ||
319 gDvm.classJavaLangThreadGroup == NULL)
320 {
321 LOGE("Could not find one or more essential thread classes\n");
322 return false;
323 }
324
325 /*
326 * Cache field offsets. This makes things a little faster, at the
327 * expense of hard-coding non-public field names into the VM.
328 */
329 gDvm.offJavaLangThread_vmThread =
330 dvmFindFieldOffset(gDvm.classJavaLangThread,
331 "vmThread", "Ljava/lang/VMThread;");
332 gDvm.offJavaLangThread_group =
333 dvmFindFieldOffset(gDvm.classJavaLangThread,
334 "group", "Ljava/lang/ThreadGroup;");
335 gDvm.offJavaLangThread_daemon =
336 dvmFindFieldOffset(gDvm.classJavaLangThread, "daemon", "Z");
337 gDvm.offJavaLangThread_name =
338 dvmFindFieldOffset(gDvm.classJavaLangThread,
339 "name", "Ljava/lang/String;");
340 gDvm.offJavaLangThread_priority =
341 dvmFindFieldOffset(gDvm.classJavaLangThread, "priority", "I");
342
343 if (gDvm.offJavaLangThread_vmThread < 0 ||
344 gDvm.offJavaLangThread_group < 0 ||
345 gDvm.offJavaLangThread_daemon < 0 ||
346 gDvm.offJavaLangThread_name < 0 ||
347 gDvm.offJavaLangThread_priority < 0)
348 {
349 LOGE("Unable to find all fields in java.lang.Thread\n");
350 return false;
351 }
352
353 gDvm.offJavaLangVMThread_thread =
354 dvmFindFieldOffset(gDvm.classJavaLangVMThread,
355 "thread", "Ljava/lang/Thread;");
356 gDvm.offJavaLangVMThread_vmData =
357 dvmFindFieldOffset(gDvm.classJavaLangVMThread, "vmData", "I");
358 if (gDvm.offJavaLangVMThread_thread < 0 ||
359 gDvm.offJavaLangVMThread_vmData < 0)
360 {
361 LOGE("Unable to find all fields in java.lang.VMThread\n");
362 return false;
363 }
364
365 /*
366 * Cache the vtable offset for "run()".
367 *
368 * We don't want to keep the Method* because then we won't find see
369 * methods defined in subclasses.
370 */
371 Method* meth;
372 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThread, "run", "()V");
373 if (meth == NULL) {
374 LOGE("Unable to find run() in java.lang.Thread\n");
375 return false;
376 }
377 gDvm.voffJavaLangThread_run = meth->methodIndex;
378
379 /*
380 * Cache vtable offsets for ThreadGroup methods.
381 */
382 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThreadGroup,
383 "removeThread", "(Ljava/lang/Thread;)V");
384 if (meth == NULL) {
385 LOGE("Unable to find removeThread(Thread) in java.lang.ThreadGroup\n");
386 return false;
387 }
388 gDvm.voffJavaLangThreadGroup_removeThread = meth->methodIndex;
389
390 return true;
391}
392
393/*
394 * All threads should be stopped by now. Clean up some thread globals.
395 */
396void dvmThreadShutdown(void)
397{
398 if (gDvm.threadList != NULL) {
399 assert(gDvm.threadList->next == NULL);
400 assert(gDvm.threadList->prev == NULL);
401 freeThread(gDvm.threadList);
402 gDvm.threadList = NULL;
403 }
404
405 dvmFreeBitVector(gDvm.threadIdMap);
406
407 dvmFreeMonitorList();
408
409 pthread_key_delete(gDvm.pthreadKeySelf);
410}
411
412
413/*
414 * Grab the suspend count global lock.
415 */
416static inline void lockThreadSuspendCount(void)
417{
418 /*
419 * Don't try to change to VMWAIT here. When we change back to RUNNING
420 * we have to check for a pending suspend, which results in grabbing
421 * this lock recursively. Doesn't work with "fast" pthread mutexes.
422 *
423 * This lock is always held for very brief periods, so as long as
424 * mutex ordering is respected we shouldn't stall.
425 */
426 int cc = pthread_mutex_lock(&gDvm.threadSuspendCountLock);
427 assert(cc == 0);
428}
429
430/*
431 * Release the suspend count global lock.
432 */
433static inline void unlockThreadSuspendCount(void)
434{
435 dvmUnlockMutex(&gDvm.threadSuspendCountLock);
436}
437
438/*
439 * Grab the thread list global lock.
440 *
441 * This is held while "suspend all" is trying to make everybody stop. If
442 * the shutdown is in progress, and somebody tries to grab the lock, they'll
443 * have to wait for the GC to finish. Therefore it's important that the
444 * thread not be in RUNNING mode.
445 *
446 * We don't have to check to see if we should be suspended once we have
447 * the lock. Nobody can suspend all threads without holding the thread list
448 * lock while they do it, so by definition there isn't a GC in progress.
449 */
450void dvmLockThreadList(Thread* self)
451{
452 ThreadStatus oldStatus;
453
454 if (self == NULL) /* try to get it from TLS */
455 self = dvmThreadSelf();
456
457 if (self != NULL) {
458 oldStatus = self->status;
459 self->status = THREAD_VMWAIT;
460 } else {
461 /* happens for JNI AttachCurrentThread [not anymore?] */
462 //LOGW("NULL self in dvmLockThreadList\n");
463 oldStatus = -1; // shut up gcc
464 }
465
466 int cc = pthread_mutex_lock(&gDvm.threadListLock);
467 assert(cc == 0);
468
469 if (self != NULL)
470 self->status = oldStatus;
471}
472
473/*
474 * Release the thread list global lock.
475 */
476void dvmUnlockThreadList(void)
477{
478 int cc = pthread_mutex_unlock(&gDvm.threadListLock);
479 assert(cc == 0);
480}
481
The Android Open Source Project99409882009-03-18 22:20:24 -0700482/*
483 * Convert SuspendCause to a string.
484 */
485static const char* getSuspendCauseStr(SuspendCause why)
486{
487 switch (why) {
488 case SUSPEND_NOT: return "NOT?";
489 case SUSPEND_FOR_GC: return "gc";
490 case SUSPEND_FOR_DEBUG: return "debug";
491 case SUSPEND_FOR_DEBUG_EVENT: return "debug-event";
492 case SUSPEND_FOR_STACK_DUMP: return "stack-dump";
493 default: return "UNKNOWN";
494 }
495}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800496
497/*
498 * Grab the "thread suspend" lock. This is required to prevent the
499 * GC and the debugger from simultaneously suspending all threads.
500 *
501 * If we fail to get the lock, somebody else is trying to suspend all
502 * threads -- including us. If we go to sleep on the lock we'll deadlock
503 * the VM. Loop until we get it or somebody puts us to sleep.
504 */
505static void lockThreadSuspend(const char* who, SuspendCause why)
506{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800507 const int kSpinSleepTime = 3*1000*1000; /* 3s */
508 u8 startWhen = 0; // init req'd to placate gcc
509 int sleepIter = 0;
510 int cc;
511
512 do {
513 cc = pthread_mutex_trylock(&gDvm._threadSuspendLock);
514 if (cc != 0) {
515 if (!dvmCheckSuspendPending(NULL)) {
516 /*
The Android Open Source Project99409882009-03-18 22:20:24 -0700517 * Could be we hit the window as the suspend or resume
518 * was started (i.e. the lock has been grabbed but the
519 * other thread hasn't yet set our "please suspend" flag).
520 *
521 * Could be an unusual JNI thread-attach thing.
522 *
523 * Could be the debugger telling us to resume at roughly
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800524 * the same time we're posting an event.
525 */
The Android Open Source Project99409882009-03-18 22:20:24 -0700526 LOGI("threadid=%d ODD: want thread-suspend lock (%s:%s),"
527 " it's held, no suspend pending\n",
528 dvmThreadSelf()->threadId, who, getSuspendCauseStr(why));
529 } else {
530 /* we suspended; reset timeout */
531 sleepIter = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800532 }
533
534 /* give the lock-holder a chance to do some work */
535 if (sleepIter == 0)
536 startWhen = dvmGetRelativeTimeUsec();
537 if (!dvmIterativeSleep(sleepIter++, kSpinSleepTime, startWhen)) {
The Android Open Source Project99409882009-03-18 22:20:24 -0700538 LOGE("threadid=%d: couldn't get thread-suspend lock (%s:%s),"
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800539 " bailing\n",
The Android Open Source Project99409882009-03-18 22:20:24 -0700540 dvmThreadSelf()->threadId, who, getSuspendCauseStr(why));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800541 dvmDumpAllThreads(false);
542 dvmAbort();
543 }
544 }
545 } while (cc != 0);
546 assert(cc == 0);
547}
548
549/*
550 * Release the "thread suspend" lock.
551 */
552static inline void unlockThreadSuspend(void)
553{
554 int cc = pthread_mutex_unlock(&gDvm._threadSuspendLock);
555 assert(cc == 0);
556}
557
558
559/*
560 * Kill any daemon threads that still exist. All of ours should be
561 * stopped, so these should be Thread objects or JNI-attached threads
562 * started by the application. Actively-running threads are likely
563 * to crash the process if they continue to execute while the VM
564 * shuts down, so we really need to kill or suspend them. (If we want
565 * the VM to restart within this process, we need to kill them, but that
566 * leaves open the possibility of orphaned resources.)
567 *
568 * Waiting for the thread to suspend may be unwise at this point, but
569 * if one of these is wedged in a critical section then we probably
570 * would've locked up on the last GC attempt.
571 *
572 * It's possible for this function to get called after a failed
573 * initialization, so be careful with assumptions about the environment.
574 */
575void dvmSlayDaemons(void)
576{
577 Thread* self = dvmThreadSelf();
578 Thread* target;
579 Thread* nextTarget;
580
581 if (self == NULL)
582 return;
583
584 //dvmEnterCritical(self);
585 dvmLockThreadList(self);
586
587 target = gDvm.threadList;
588 while (target != NULL) {
589 if (target == self) {
590 target = target->next;
591 continue;
592 }
593
594 if (!dvmGetFieldBoolean(target->threadObj,
595 gDvm.offJavaLangThread_daemon))
596 {
597 LOGW("threadid=%d: non-daemon id=%d still running at shutdown?!\n",
598 self->threadId, target->threadId);
599 target = target->next;
600 continue;
601 }
602
603 LOGI("threadid=%d: killing leftover daemon threadid=%d [TODO]\n",
604 self->threadId, target->threadId);
605 // TODO: suspend and/or kill the thread
606 // (at the very least, we can "rescind their JNI privileges")
607
608 /* remove from list */
609 nextTarget = target->next;
610 unlinkThread(target);
611
612 freeThread(target);
613 target = nextTarget;
614 }
615
616 dvmUnlockThreadList();
617 //dvmExitCritical(self);
618}
619
620
621/*
622 * Finish preparing the parts of the Thread struct required to support
623 * JNI registration.
624 */
625bool dvmPrepMainForJni(JNIEnv* pEnv)
626{
627 Thread* self;
628
629 /* main thread is always first in list at this point */
630 self = gDvm.threadList;
631 assert(self->threadId == kMainThreadId);
632
633 /* create a "fake" JNI frame at the top of the main thread interp stack */
634 if (!createFakeEntryFrame(self))
635 return false;
636
637 /* fill these in, since they weren't ready at dvmCreateJNIEnv time */
638 dvmSetJniEnvThreadId(pEnv, self);
639 dvmSetThreadJNIEnv(self, (JNIEnv*) pEnv);
640
641 return true;
642}
643
644
645/*
646 * Finish preparing the main thread, allocating some objects to represent
647 * it. As part of doing so, we finish initializing Thread and ThreadGroup.
648 */
649bool dvmPrepMainThread(void)
650{
651 Thread* thread;
652 Object* groupObj;
653 Object* threadObj;
654 Object* vmThreadObj;
655 StringObject* threadNameStr;
656 Method* init;
657 JValue unused;
658
659 LOGV("+++ finishing prep on main VM thread\n");
660
661 /* main thread is always first in list at this point */
662 thread = gDvm.threadList;
663 assert(thread->threadId == kMainThreadId);
664
665 /*
666 * Make sure the classes are initialized. We have to do this before
667 * we create an instance of them.
668 */
669 if (!dvmInitClass(gDvm.classJavaLangClass)) {
670 LOGE("'Class' class failed to initialize\n");
671 return false;
672 }
673 if (!dvmInitClass(gDvm.classJavaLangThreadGroup) ||
674 !dvmInitClass(gDvm.classJavaLangThread) ||
675 !dvmInitClass(gDvm.classJavaLangVMThread))
676 {
677 LOGE("thread classes failed to initialize\n");
678 return false;
679 }
680
681 groupObj = dvmGetMainThreadGroup();
682 if (groupObj == NULL)
683 return false;
684
685 /*
686 * Allocate and construct a Thread with the internal-creation
687 * constructor.
688 */
689 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_DEFAULT);
690 if (threadObj == NULL) {
691 LOGE("unable to allocate main thread object\n");
692 return false;
693 }
694 dvmReleaseTrackedAlloc(threadObj, NULL);
695
696 threadNameStr = dvmCreateStringFromCstr("main", ALLOC_DEFAULT);
697 if (threadNameStr == NULL)
698 return false;
699 dvmReleaseTrackedAlloc((Object*)threadNameStr, NULL);
700
701 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
702 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
703 assert(init != NULL);
704 dvmCallMethod(thread, init, threadObj, &unused, groupObj, threadNameStr,
705 THREAD_NORM_PRIORITY, false);
706 if (dvmCheckException(thread)) {
707 LOGE("exception thrown while constructing main thread object\n");
708 return false;
709 }
710
711 /*
712 * Allocate and construct a VMThread.
713 */
714 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
715 if (vmThreadObj == NULL) {
716 LOGE("unable to allocate main vmthread object\n");
717 return false;
718 }
719 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
720
721 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangVMThread, "<init>",
722 "(Ljava/lang/Thread;)V");
723 dvmCallMethod(thread, init, vmThreadObj, &unused, threadObj);
724 if (dvmCheckException(thread)) {
725 LOGE("exception thrown while constructing main vmthread object\n");
726 return false;
727 }
728
729 /* set the VMThread.vmData field to our Thread struct */
730 assert(gDvm.offJavaLangVMThread_vmData != 0);
731 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)thread);
732
733 /*
734 * Stuff the VMThread back into the Thread. From this point on, other
735 * Threads will see that this Thread is running.
736 */
737 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread,
738 vmThreadObj);
739
740 thread->threadObj = threadObj;
741
742 /*
743 * Finish our thread prep.
744 */
745
746 /* include self in non-daemon threads (mainly for AttachCurrentThread) */
747 gDvm.nonDaemonThreadCount++;
748
749 return true;
750}
751
752
753/*
754 * Alloc and initialize a Thread struct.
755 *
756 * "threadObj" is the java.lang.Thread object. It will be NULL for the
757 * main VM thread, but non-NULL for everything else.
758 *
759 * Does not create any objects, just stuff on the system (malloc) heap. (If
760 * this changes, we need to use ALLOC_NO_GC. And also verify that we're
761 * ready to load classes at the time this is called.)
762 */
763static Thread* allocThread(int interpStackSize)
764{
765 Thread* thread;
766 u1* stackBottom;
767
768 thread = (Thread*) calloc(1, sizeof(Thread));
769 if (thread == NULL)
770 return NULL;
771
772 assert(interpStackSize >= kMinStackSize && interpStackSize <=kMaxStackSize);
773
774 thread->status = THREAD_INITIALIZING;
775 thread->suspendCount = 0;
776
777#ifdef WITH_ALLOC_LIMITS
778 thread->allocLimit = -1;
779#endif
780
781 /*
782 * Allocate and initialize the interpreted code stack. We essentially
783 * "lose" the alloc pointer, which points at the bottom of the stack,
784 * but we can get it back later because we know how big the stack is.
785 *
786 * The stack must be aligned on a 4-byte boundary.
787 */
788#ifdef MALLOC_INTERP_STACK
789 stackBottom = (u1*) malloc(interpStackSize);
790 if (stackBottom == NULL) {
791 free(thread);
792 return NULL;
793 }
794 memset(stackBottom, 0xc5, interpStackSize); // stop valgrind complaints
795#else
796 stackBottom = mmap(NULL, interpStackSize, PROT_READ | PROT_WRITE,
797 MAP_PRIVATE | MAP_ANON, -1, 0);
798 if (stackBottom == MAP_FAILED) {
799 free(thread);
800 return NULL;
801 }
802#endif
803
804 assert(((u4)stackBottom & 0x03) == 0); // looks like our malloc ensures this
805 thread->interpStackSize = interpStackSize;
806 thread->interpStackStart = stackBottom + interpStackSize;
807 thread->interpStackEnd = stackBottom + STACK_OVERFLOW_RESERVE;
808
809 /* give the thread code a chance to set things up */
810 dvmInitInterpStack(thread, interpStackSize);
811
812 return thread;
813}
814
815/*
816 * Get a meaningful thread ID. At present this only has meaning under Linux,
817 * where getpid() and gettid() sometimes agree and sometimes don't depending
818 * on your thread model (try "export LD_ASSUME_KERNEL=2.4.19").
819 */
820pid_t dvmGetSysThreadId(void)
821{
822#ifdef HAVE_GETTID
823 return gettid();
824#else
825 return getpid();
826#endif
827}
828
829/*
830 * Finish initialization of a Thread struct.
831 *
832 * This must be called while executing in the new thread, but before the
833 * thread is added to the thread list.
834 *
835 * *** NOTE: The threadListLock must be held by the caller (needed for
836 * assignThreadId()).
837 */
838static bool prepareThread(Thread* thread)
839{
840 assignThreadId(thread);
841 thread->handle = pthread_self();
842 thread->systemTid = dvmGetSysThreadId();
843
844 //LOGI("SYSTEM TID IS %d (pid is %d)\n", (int) thread->systemTid,
845 // (int) getpid());
846 setThreadSelf(thread);
847
848 LOGV("threadid=%d: interp stack at %p\n",
849 thread->threadId, thread->interpStackStart - thread->interpStackSize);
850
851 /*
852 * Initialize invokeReq.
853 */
854 pthread_mutex_init(&thread->invokeReq.lock, NULL);
855 pthread_cond_init(&thread->invokeReq.cv, NULL);
856
857 /*
858 * Initialize our reference tracking tables.
859 *
860 * The JNI local ref table *must* be fixed-size because we keep pointers
861 * into the table in our stack frames.
862 *
863 * Most threads won't use jniMonitorRefTable, so we clear out the
864 * structure but don't call the init function (which allocs storage).
865 */
866 if (!dvmInitReferenceTable(&thread->jniLocalRefTable,
867 kJniLocalRefMax, kJniLocalRefMax))
868 return false;
869 if (!dvmInitReferenceTable(&thread->internalLocalRefTable,
870 kInternalRefDefault, kInternalRefMax))
871 return false;
872
873 memset(&thread->jniMonitorRefTable, 0, sizeof(thread->jniMonitorRefTable));
874
875 return true;
876}
877
878/*
879 * Remove a thread from the internal list.
880 * Clear out the links to make it obvious that the thread is
881 * no longer on the list. Caller must hold gDvm.threadListLock.
882 */
883static void unlinkThread(Thread* thread)
884{
885 LOG_THREAD("threadid=%d: removing from list\n", thread->threadId);
886 if (thread == gDvm.threadList) {
887 assert(thread->prev == NULL);
888 gDvm.threadList = thread->next;
889 } else {
890 assert(thread->prev != NULL);
891 thread->prev->next = thread->next;
892 }
893 if (thread->next != NULL)
894 thread->next->prev = thread->prev;
895 thread->prev = thread->next = NULL;
896}
897
898/*
899 * Free a Thread struct, and all the stuff allocated within.
900 */
901static void freeThread(Thread* thread)
902{
903 if (thread == NULL)
904 return;
905
906 /* thread->threadId is zero at this point */
907 LOGVV("threadid=%d: freeing\n", thread->threadId);
908
909 if (thread->interpStackStart != NULL) {
910 u1* interpStackBottom;
911
912 interpStackBottom = thread->interpStackStart;
913 interpStackBottom -= thread->interpStackSize;
914#ifdef MALLOC_INTERP_STACK
915 free(interpStackBottom);
916#else
917 if (munmap(interpStackBottom, thread->interpStackSize) != 0)
918 LOGW("munmap(thread stack) failed\n");
919#endif
920 }
921
922 dvmClearReferenceTable(&thread->jniLocalRefTable);
923 dvmClearReferenceTable(&thread->internalLocalRefTable);
924 if (&thread->jniMonitorRefTable.table != NULL)
925 dvmClearReferenceTable(&thread->jniMonitorRefTable);
926
927 free(thread);
928}
929
930/*
931 * Like pthread_self(), but on a Thread*.
932 */
933Thread* dvmThreadSelf(void)
934{
935 return (Thread*) pthread_getspecific(gDvm.pthreadKeySelf);
936}
937
938/*
939 * Explore our sense of self. Stuffs the thread pointer into TLS.
940 */
941static void setThreadSelf(Thread* thread)
942{
943 int cc;
944
945 cc = pthread_setspecific(gDvm.pthreadKeySelf, thread);
946 if (cc != 0) {
947 /*
948 * Sometimes this fails under Bionic with EINVAL during shutdown.
949 * This can happen if the timing is just right, e.g. a thread
950 * fails to attach during shutdown, but the "fail" path calls
951 * here to ensure we clean up after ourselves.
952 */
953 if (thread != NULL) {
954 LOGE("pthread_setspecific(%p) failed, err=%d\n", thread, cc);
955 dvmAbort(); /* the world is fundamentally hosed */
956 }
957 }
958}
959
960/*
961 * This is associated with the pthreadKeySelf key. It's called by the
962 * pthread library when a thread is exiting and the "self" pointer in TLS
963 * is non-NULL, meaning the VM hasn't had a chance to clean up. In normal
964 * operation this should never be called.
965 *
966 * This is mainly of use to ensure that we don't leak resources if, for
967 * example, a thread attaches itself to us with AttachCurrentThread and
968 * then exits without notifying the VM.
Andy McFadden34e25bb2009-04-15 13:27:12 -0700969 *
970 * We could do the detach here instead of aborting, but this will lead to
971 * portability problems. Other implementations do not do this check and
972 * will simply be unaware that the thread has exited, leading to resource
973 * leaks (and, if this is a non-daemon thread, an infinite hang when the
974 * VM tries to shut down).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800975 */
976static void threadExitCheck(void* arg)
977{
978 Thread* thread = (Thread*) arg;
979
980 LOGI("In threadExitCheck %p\n", arg);
981 assert(thread != NULL);
982
983 if (thread->status != THREAD_ZOMBIE) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800984 LOGE("Native thread exited without telling us\n");
985 dvmAbort();
986 }
987}
988
989
990/*
991 * Assign the threadId. This needs to be a small integer so that our
992 * "thin" locks fit in a small number of bits.
993 *
994 * We reserve zero for use as an invalid ID.
995 *
996 * This must be called with threadListLock held (unless we're still
997 * initializing the system).
998 */
999static void assignThreadId(Thread* thread)
1000{
1001 /* Find a small unique integer. threadIdMap is a vector of
1002 * kMaxThreadId bits; dvmAllocBit() returns the index of a
1003 * bit, meaning that it will always be < kMaxThreadId.
1004 *
1005 * The thin locking magic requires that the low bit is always
1006 * set, so we do it once, here.
1007 */
1008 int num = dvmAllocBit(gDvm.threadIdMap);
1009 if (num < 0) {
1010 LOGE("Ran out of thread IDs\n");
1011 dvmAbort(); // TODO: make this a non-fatal error result
1012 }
1013
1014 thread->threadId = ((num + 1) << 1) | 1;
1015
1016 assert(thread->threadId != 0);
1017 assert(thread->threadId != DVM_LOCK_INITIAL_THIN_VALUE);
1018}
1019
1020/*
1021 * Give back the thread ID.
1022 */
1023static void releaseThreadId(Thread* thread)
1024{
1025 assert(thread->threadId > 0);
1026 dvmClearBit(gDvm.threadIdMap, (thread->threadId >> 1) - 1);
1027 thread->threadId = 0;
1028}
1029
1030
1031/*
1032 * Add a stack frame that makes it look like the native code in the main
1033 * thread was originally invoked from interpreted code. This gives us a
1034 * place to hang JNI local references. The VM spec says (v2 5.2) that the
1035 * VM begins by executing "main" in a class, so in a way this brings us
1036 * closer to the spec.
1037 */
1038static bool createFakeEntryFrame(Thread* thread)
1039{
1040 assert(thread->threadId == kMainThreadId); // main thread only
1041
1042 /* find the method on first use */
1043 if (gDvm.methFakeNativeEntry == NULL) {
1044 ClassObject* nativeStart;
1045 Method* mainMeth;
1046
1047 nativeStart = dvmFindSystemClassNoInit(
1048 "Ldalvik/system/NativeStart;");
1049 if (nativeStart == NULL) {
1050 LOGE("Unable to find dalvik.system.NativeStart class\n");
1051 return false;
1052 }
1053
1054 /*
1055 * Because we are creating a frame that represents application code, we
1056 * want to stuff the application class loader into the method's class
1057 * loader field, even though we're using the system class loader to
1058 * load it. This makes life easier over in JNI FindClass (though it
1059 * could bite us in other ways).
1060 *
1061 * Unfortunately this is occurring too early in the initialization,
1062 * of necessity coming before JNI is initialized, and we're not quite
1063 * ready to set up the application class loader.
1064 *
1065 * So we save a pointer to the method in gDvm.methFakeNativeEntry
1066 * and check it in FindClass. The method is private so nobody else
1067 * can call it.
1068 */
1069 //nativeStart->classLoader = dvmGetSystemClassLoader();
1070
1071 mainMeth = dvmFindDirectMethodByDescriptor(nativeStart,
1072 "main", "([Ljava/lang/String;)V");
1073 if (mainMeth == NULL) {
1074 LOGE("Unable to find 'main' in dalvik.system.NativeStart\n");
1075 return false;
1076 }
1077
1078 gDvm.methFakeNativeEntry = mainMeth;
1079 }
1080
1081 return dvmPushJNIFrame(thread, gDvm.methFakeNativeEntry);
1082}
1083
1084
1085/*
1086 * Add a stack frame that makes it look like the native thread has been
1087 * executing interpreted code. This gives us a place to hang JNI local
1088 * references.
1089 */
1090static bool createFakeRunFrame(Thread* thread)
1091{
1092 ClassObject* nativeStart;
1093 Method* runMeth;
1094
1095 assert(thread->threadId != 1); // not for main thread
1096
1097 nativeStart =
1098 dvmFindSystemClassNoInit("Ldalvik/system/NativeStart;");
1099 if (nativeStart == NULL) {
1100 LOGE("Unable to find dalvik.system.NativeStart class\n");
1101 return false;
1102 }
1103
1104 runMeth = dvmFindVirtualMethodByDescriptor(nativeStart, "run", "()V");
1105 if (runMeth == NULL) {
1106 LOGE("Unable to find 'run' in dalvik.system.NativeStart\n");
1107 return false;
1108 }
1109
1110 return dvmPushJNIFrame(thread, runMeth);
1111}
1112
1113/*
1114 * Helper function to set the name of the current thread
1115 */
1116static void setThreadName(const char *threadName)
1117{
1118#if defined(HAVE_PRCTL)
1119 int hasAt = 0;
1120 int hasDot = 0;
1121 const char *s = threadName;
1122 while (*s) {
1123 if (*s == '.') hasDot = 1;
1124 else if (*s == '@') hasAt = 1;
1125 s++;
1126 }
1127 int len = s - threadName;
1128 if (len < 15 || hasAt || !hasDot) {
1129 s = threadName;
1130 } else {
1131 s = threadName + len - 15;
1132 }
1133 prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
1134#endif
1135}
1136
1137/*
1138 * Create a thread as a result of java.lang.Thread.start().
1139 *
1140 * We do have to worry about some concurrency problems, e.g. programs
1141 * that try to call Thread.start() on the same object from multiple threads.
1142 * (This will fail for all but one, but we have to make sure that it succeeds
1143 * for exactly one.)
1144 *
1145 * Some of the complexity here arises from our desire to mimic the
1146 * Thread vs. VMThread class decomposition we inherited. We've been given
1147 * a Thread, and now we need to create a VMThread and then populate both
1148 * objects. We also need to create one of our internal Thread objects.
1149 *
1150 * Pass in a stack size of 0 to get the default.
1151 */
1152bool dvmCreateInterpThread(Object* threadObj, int reqStackSize)
1153{
1154 pthread_attr_t threadAttr;
1155 pthread_t threadHandle;
1156 Thread* self;
1157 Thread* newThread = NULL;
1158 Object* vmThreadObj = NULL;
1159 int stackSize;
1160
1161 assert(threadObj != NULL);
1162
1163 if(gDvm.zygote) {
1164 dvmThrowException("Ljava/lang/IllegalStateException;",
1165 "No new threads in -Xzygote mode");
1166
1167 goto fail;
1168 }
1169
1170 self = dvmThreadSelf();
1171 if (reqStackSize == 0)
1172 stackSize = gDvm.stackSize;
1173 else if (reqStackSize < kMinStackSize)
1174 stackSize = kMinStackSize;
1175 else if (reqStackSize > kMaxStackSize)
1176 stackSize = kMaxStackSize;
1177 else
1178 stackSize = reqStackSize;
1179
1180 pthread_attr_init(&threadAttr);
1181 pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1182
1183 /*
1184 * To minimize the time spent in the critical section, we allocate the
1185 * vmThread object here.
1186 */
1187 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
1188 if (vmThreadObj == NULL)
1189 goto fail;
1190
1191 newThread = allocThread(stackSize);
1192 if (newThread == NULL)
1193 goto fail;
1194 newThread->threadObj = threadObj;
1195
1196 assert(newThread->status == THREAD_INITIALIZING);
1197
1198 /*
1199 * We need to lock out other threads while we test and set the
1200 * "vmThread" field in java.lang.Thread, because we use that to determine
1201 * if this thread has been started before. We use the thread list lock
1202 * because it's handy and we're going to need to grab it again soon
1203 * anyway.
1204 */
1205 dvmLockThreadList(self);
1206
1207 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1208 dvmUnlockThreadList();
1209 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1210 "thread has already been started");
1211 goto fail;
1212 }
1213
1214 /*
1215 * There are actually three data structures: Thread (object), VMThread
1216 * (object), and Thread (C struct). All of them point to at least one
1217 * other.
1218 *
1219 * As soon as "VMThread.vmData" is assigned, other threads can start
1220 * making calls into us (e.g. setPriority).
1221 */
1222 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)newThread);
1223 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1224
1225 /*
1226 * Thread creation might take a while, so release the lock.
1227 */
1228 dvmUnlockThreadList();
1229
1230 if (pthread_create(&threadHandle, &threadAttr, interpThreadStart,
1231 newThread) != 0)
1232 {
1233 /*
1234 * Failure generally indicates that we have exceeded system
1235 * resource limits. VirtualMachineError is probably too severe,
1236 * so use OutOfMemoryError.
1237 */
1238 LOGE("Thread creation failed (err=%s)\n", strerror(errno));
1239
1240 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, NULL);
1241
1242 dvmThrowException("Ljava/lang/OutOfMemoryError;",
1243 "thread creation failed");
1244 goto fail;
1245 }
1246
1247 /*
1248 * We need to wait for the thread to start. Otherwise, depending on
1249 * the whims of the OS scheduler, we could return and the code in our
1250 * thread could try to do operations on the new thread before it had
1251 * finished starting.
1252 *
1253 * The new thread will lock the thread list, change its state to
1254 * THREAD_STARTING, broadcast to gDvm.threadStartCond, and then sleep
1255 * on gDvm.threadStartCond (which uses the thread list lock). This
1256 * thread (the parent) will either see that the thread is already ready
1257 * after we grab the thread list lock, or will be awakened from the
1258 * condition variable on the broadcast.
1259 *
1260 * We don't want to stall the rest of the VM while the new thread
1261 * starts, which can happen if the GC wakes up at the wrong moment.
1262 * So, we change our own status to VMWAIT, and self-suspend if
1263 * necessary after we finish adding the new thread.
1264 *
1265 *
1266 * We have to deal with an odd race with the GC/debugger suspension
1267 * mechanism when creating a new thread. The information about whether
1268 * or not a thread should be suspended is contained entirely within
1269 * the Thread struct; this is usually cleaner to deal with than having
1270 * one or more globally-visible suspension flags. The trouble is that
1271 * we could create the thread while the VM is trying to suspend all
1272 * threads. The suspend-count won't be nonzero for the new thread,
1273 * so dvmChangeStatus(THREAD_RUNNING) won't cause a suspension.
1274 *
1275 * The easiest way to deal with this is to prevent the new thread from
1276 * running until the parent says it's okay. This results in the
1277 * following sequence of events for a "badly timed" GC:
1278 *
1279 * - call pthread_create()
1280 * - lock thread list
1281 * - put self into THREAD_VMWAIT so GC doesn't wait for us
1282 * - sleep on condition var (mutex = thread list lock) until child starts
1283 * + GC triggered by another thread
1284 * + thread list locked; suspend counts updated; thread list unlocked
1285 * + loop waiting for all runnable threads to suspend
1286 * + success, start GC
1287 * o child thread wakes, signals condition var to wake parent
1288 * o child waits for parent ack on condition variable
1289 * - we wake up, locking thread list
1290 * - add child to thread list
1291 * - unlock thread list
1292 * - change our state back to THREAD_RUNNING; GC causes us to suspend
1293 * + GC finishes; all threads in thread list are resumed
1294 * - lock thread list
1295 * - set child to THREAD_VMWAIT, and signal it to start
1296 * - unlock thread list
1297 * o child resumes
1298 * o child changes state to THREAD_RUNNING
1299 *
1300 * The above shows the GC starting up during thread creation, but if
1301 * it starts anywhere after VMThread.create() is called it will
1302 * produce the same series of events.
1303 *
1304 * Once the child is in the thread list, it will be suspended and
1305 * resumed like any other thread. In the above scenario the resume-all
1306 * code will try to resume the new thread, which was never actually
1307 * suspended, and try to decrement the child's thread suspend count to -1.
1308 * We can catch this in the resume-all code.
1309 *
1310 * Bouncing back and forth between threads like this adds a small amount
1311 * of scheduler overhead to thread startup.
1312 *
1313 * One alternative to having the child wait for the parent would be
1314 * to have the child inherit the parents' suspension count. This
1315 * would work for a GC, since we can safely assume that the parent
1316 * thread didn't cause it, but we must only do so if the parent suspension
1317 * was caused by a suspend-all. If the parent was being asked to
1318 * suspend singly by the debugger, the child should not inherit the value.
1319 *
1320 * We could also have a global "new thread suspend count" that gets
1321 * picked up by new threads before changing state to THREAD_RUNNING.
1322 * This would be protected by the thread list lock and set by a
1323 * suspend-all.
1324 */
1325 dvmLockThreadList(self);
1326 assert(self->status == THREAD_RUNNING);
1327 self->status = THREAD_VMWAIT;
1328 while (newThread->status != THREAD_STARTING)
1329 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1330
1331 LOG_THREAD("threadid=%d: adding to list\n", newThread->threadId);
1332 newThread->next = gDvm.threadList->next;
1333 if (newThread->next != NULL)
1334 newThread->next->prev = newThread;
1335 newThread->prev = gDvm.threadList;
1336 gDvm.threadList->next = newThread;
1337
1338 if (!dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon))
1339 gDvm.nonDaemonThreadCount++; // guarded by thread list lock
1340
1341 dvmUnlockThreadList();
1342
1343 /* change status back to RUNNING, self-suspending if necessary */
1344 dvmChangeStatus(self, THREAD_RUNNING);
1345
1346 /*
1347 * Tell the new thread to start.
1348 *
1349 * We must hold the thread list lock before messing with another thread.
1350 * In the general case we would also need to verify that newThread was
1351 * still in the thread list, but in our case the thread has not started
1352 * executing user code and therefore has not had a chance to exit.
1353 *
1354 * We move it to VMWAIT, and it then shifts itself to RUNNING, which
1355 * comes with a suspend-pending check.
1356 */
1357 dvmLockThreadList(self);
1358
1359 assert(newThread->status == THREAD_STARTING);
1360 newThread->status = THREAD_VMWAIT;
1361 pthread_cond_broadcast(&gDvm.threadStartCond);
1362
1363 dvmUnlockThreadList();
1364
1365 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1366 return true;
1367
1368fail:
1369 freeThread(newThread);
1370 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1371 return false;
1372}
1373
1374/*
1375 * pthread entry function for threads started from interpreted code.
1376 */
1377static void* interpThreadStart(void* arg)
1378{
1379 Thread* self = (Thread*) arg;
1380
1381 char *threadName = dvmGetThreadName(self);
1382 setThreadName(threadName);
1383 free(threadName);
1384
1385 /*
1386 * Finish initializing the Thread struct.
1387 */
1388 prepareThread(self);
1389
1390 LOG_THREAD("threadid=%d: created from interp\n", self->threadId);
1391
1392 /*
1393 * Change our status and wake our parent, who will add us to the
1394 * thread list and advance our state to VMWAIT.
1395 */
1396 dvmLockThreadList(self);
1397 self->status = THREAD_STARTING;
1398 pthread_cond_broadcast(&gDvm.threadStartCond);
1399
1400 /*
1401 * Wait until the parent says we can go. Assuming there wasn't a
1402 * suspend pending, this will happen immediately. When it completes,
1403 * we're full-fledged citizens of the VM.
1404 *
1405 * We have to use THREAD_VMWAIT here rather than THREAD_RUNNING
1406 * because the pthread_cond_wait below needs to reacquire a lock that
1407 * suspend-all is also interested in. If we get unlucky, the parent could
1408 * change us to THREAD_RUNNING, then a GC could start before we get
1409 * signaled, and suspend-all will grab the thread list lock and then
1410 * wait for us to suspend. We'll be in the tail end of pthread_cond_wait
1411 * trying to get the lock.
1412 */
1413 while (self->status != THREAD_VMWAIT)
1414 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1415
1416 dvmUnlockThreadList();
1417
1418 /*
1419 * Add a JNI context.
1420 */
1421 self->jniEnv = dvmCreateJNIEnv(self);
1422
1423 /*
1424 * Change our state so the GC will wait for us from now on. If a GC is
1425 * in progress this call will suspend us.
1426 */
1427 dvmChangeStatus(self, THREAD_RUNNING);
1428
1429 /*
1430 * Notify the debugger & DDM. The debugger notification may cause
1431 * us to suspend ourselves (and others).
1432 */
1433 if (gDvm.debuggerConnected)
1434 dvmDbgPostThreadStart(self);
1435
1436 /*
1437 * Set the system thread priority according to the Thread object's
1438 * priority level. We don't usually need to do this, because both the
1439 * Thread object and system thread priorities inherit from parents. The
1440 * tricky case is when somebody creates a Thread object, calls
1441 * setPriority(), and then starts the thread. We could manage this with
1442 * a "needs priority update" flag to avoid the redundant call.
1443 */
1444 int priority = dvmGetFieldBoolean(self->threadObj,
1445 gDvm.offJavaLangThread_priority);
1446 dvmChangeThreadPriority(self, priority);
1447
1448 /*
1449 * Execute the "run" method.
1450 *
1451 * At this point our stack is empty, so somebody who comes looking for
1452 * stack traces right now won't have much to look at. This is normal.
1453 */
1454 Method* run = self->threadObj->clazz->vtable[gDvm.voffJavaLangThread_run];
1455 JValue unused;
1456
1457 LOGV("threadid=%d: calling run()\n", self->threadId);
1458 assert(strcmp(run->name, "run") == 0);
1459 dvmCallMethod(self, run, self->threadObj, &unused);
1460 LOGV("threadid=%d: exiting\n", self->threadId);
1461
1462 /*
1463 * Remove the thread from various lists, report its death, and free
1464 * its resources.
1465 */
1466 dvmDetachCurrentThread();
1467
1468 return NULL;
1469}
1470
1471/*
1472 * The current thread is exiting with an uncaught exception. The
1473 * Java programming language allows the application to provide a
1474 * thread-exit-uncaught-exception handler for the VM, for a specific
1475 * Thread, and for all threads in a ThreadGroup.
1476 *
1477 * Version 1.5 added the per-thread handler. We need to call
1478 * "uncaughtException" in the handler object, which is either the
1479 * ThreadGroup object or the Thread-specific handler.
1480 */
1481static void threadExitUncaughtException(Thread* self, Object* group)
1482{
1483 Object* exception;
1484 Object* handlerObj;
1485 ClassObject* throwable;
1486 Method* uncaughtHandler = NULL;
1487 InstField* threadHandler;
1488
1489 LOGW("threadid=%d: thread exiting with uncaught exception (group=%p)\n",
1490 self->threadId, group);
1491 assert(group != NULL);
1492
1493 /*
1494 * Get a pointer to the exception, then clear out the one in the
1495 * thread. We don't want to have it set when executing interpreted code.
1496 */
1497 exception = dvmGetException(self);
1498 dvmAddTrackedAlloc(exception, self);
1499 dvmClearException(self);
1500
1501 /*
1502 * Get the Thread's "uncaughtHandler" object. Use it if non-NULL;
1503 * else use "group" (which is an instance of UncaughtExceptionHandler).
1504 */
1505 threadHandler = dvmFindInstanceField(gDvm.classJavaLangThread,
1506 "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
1507 if (threadHandler == NULL) {
1508 LOGW("WARNING: no 'uncaughtHandler' field in java/lang/Thread\n");
1509 goto bail;
1510 }
1511 handlerObj = dvmGetFieldObject(self->threadObj, threadHandler->byteOffset);
1512 if (handlerObj == NULL)
1513 handlerObj = group;
1514
1515 /*
1516 * Find the "uncaughtHandler" field in this object.
1517 */
1518 uncaughtHandler = dvmFindVirtualMethodHierByDescriptor(handlerObj->clazz,
1519 "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
1520
1521 if (uncaughtHandler != NULL) {
1522 //LOGI("+++ calling %s.uncaughtException\n",
1523 // handlerObj->clazz->descriptor);
1524 JValue unused;
1525 dvmCallMethod(self, uncaughtHandler, handlerObj, &unused,
1526 self->threadObj, exception);
1527 } else {
1528 /* restore it and dump a stack trace */
1529 LOGW("WARNING: no 'uncaughtException' method in class %s\n",
1530 handlerObj->clazz->descriptor);
1531 dvmSetException(self, exception);
1532 dvmLogExceptionStackTrace();
1533 }
1534
1535bail:
1536 dvmReleaseTrackedAlloc(exception, self);
1537}
1538
1539
1540/*
1541 * Create an internal VM thread, for things like JDWP and finalizers.
1542 *
1543 * The easiest way to do this is create a new thread and then use the
1544 * JNI AttachCurrentThread implementation.
1545 *
1546 * This does not return until after the new thread has begun executing.
1547 */
1548bool dvmCreateInternalThread(pthread_t* pHandle, const char* name,
1549 InternalThreadStart func, void* funcArg)
1550{
1551 InternalStartArgs* pArgs;
1552 Object* systemGroup;
1553 pthread_attr_t threadAttr;
1554 volatile Thread* newThread = NULL;
1555 volatile int createStatus = 0;
1556
1557 systemGroup = dvmGetSystemThreadGroup();
1558 if (systemGroup == NULL)
1559 return false;
1560
1561 pArgs = (InternalStartArgs*) malloc(sizeof(*pArgs));
1562 pArgs->func = func;
1563 pArgs->funcArg = funcArg;
1564 pArgs->name = strdup(name); // storage will be owned by new thread
1565 pArgs->group = systemGroup;
1566 pArgs->isDaemon = true;
1567 pArgs->pThread = &newThread;
1568 pArgs->pCreateStatus = &createStatus;
1569
1570 pthread_attr_init(&threadAttr);
1571 //pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1572
1573 if (pthread_create(pHandle, &threadAttr, internalThreadStart,
1574 pArgs) != 0)
1575 {
1576 LOGE("internal thread creation failed\n");
1577 free(pArgs->name);
1578 free(pArgs);
1579 return false;
1580 }
1581
1582 /*
1583 * Wait for the child to start. This gives us an opportunity to make
1584 * sure that the thread started correctly, and allows our caller to
1585 * assume that the thread has started running.
1586 *
1587 * Because we aren't holding a lock across the thread creation, it's
1588 * possible that the child will already have completed its
1589 * initialization. Because the child only adjusts "createStatus" while
1590 * holding the thread list lock, the initial condition on the "while"
1591 * loop will correctly avoid the wait if this occurs.
1592 *
1593 * It's also possible that we'll have to wait for the thread to finish
1594 * being created, and as part of allocating a Thread object it might
1595 * need to initiate a GC. We switch to VMWAIT while we pause.
1596 */
1597 Thread* self = dvmThreadSelf();
1598 int oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1599 dvmLockThreadList(self);
1600 while (createStatus == 0)
1601 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1602
1603 if (newThread == NULL) {
1604 LOGW("internal thread create failed (createStatus=%d)\n", createStatus);
1605 assert(createStatus < 0);
1606 /* don't free pArgs -- if pthread_create succeeded, child owns it */
1607 dvmUnlockThreadList();
1608 dvmChangeStatus(self, oldStatus);
1609 return false;
1610 }
1611
1612 /* thread could be in any state now (except early init states) */
1613 //assert(newThread->status == THREAD_RUNNING);
1614
1615 dvmUnlockThreadList();
1616 dvmChangeStatus(self, oldStatus);
1617
1618 return true;
1619}
1620
1621/*
1622 * pthread entry function for internally-created threads.
1623 *
1624 * We are expected to free "arg" and its contents. If we're a daemon
1625 * thread, and we get cancelled abruptly when the VM shuts down, the
1626 * storage won't be freed. If this becomes a concern we can make a copy
1627 * on the stack.
1628 */
1629static void* internalThreadStart(void* arg)
1630{
1631 InternalStartArgs* pArgs = (InternalStartArgs*) arg;
1632 JavaVMAttachArgs jniArgs;
1633
1634 jniArgs.version = JNI_VERSION_1_2;
1635 jniArgs.name = pArgs->name;
1636 jniArgs.group = pArgs->group;
1637
1638 setThreadName(pArgs->name);
1639
1640 /* use local jniArgs as stack top */
1641 if (dvmAttachCurrentThread(&jniArgs, pArgs->isDaemon)) {
1642 /*
1643 * Tell the parent of our success.
1644 *
1645 * threadListLock is the mutex for threadStartCond.
1646 */
1647 dvmLockThreadList(dvmThreadSelf());
1648 *pArgs->pCreateStatus = 1;
1649 *pArgs->pThread = dvmThreadSelf();
1650 pthread_cond_broadcast(&gDvm.threadStartCond);
1651 dvmUnlockThreadList();
1652
1653 LOG_THREAD("threadid=%d: internal '%s'\n",
1654 dvmThreadSelf()->threadId, pArgs->name);
1655
1656 /* execute */
1657 (*pArgs->func)(pArgs->funcArg);
1658
1659 /* detach ourselves */
1660 dvmDetachCurrentThread();
1661 } else {
1662 /*
1663 * Tell the parent of our failure. We don't have a Thread struct,
1664 * so we can't be suspended, so we don't need to enter a critical
1665 * section.
1666 */
1667 dvmLockThreadList(dvmThreadSelf());
1668 *pArgs->pCreateStatus = -1;
1669 assert(*pArgs->pThread == NULL);
1670 pthread_cond_broadcast(&gDvm.threadStartCond);
1671 dvmUnlockThreadList();
1672
1673 assert(*pArgs->pThread == NULL);
1674 }
1675
1676 free(pArgs->name);
1677 free(pArgs);
1678 return NULL;
1679}
1680
1681/*
1682 * Attach the current thread to the VM.
1683 *
1684 * Used for internally-created threads and JNI's AttachCurrentThread.
1685 */
1686bool dvmAttachCurrentThread(const JavaVMAttachArgs* pArgs, bool isDaemon)
1687{
1688 Thread* self = NULL;
1689 Object* threadObj = NULL;
1690 Object* vmThreadObj = NULL;
1691 StringObject* threadNameStr = NULL;
1692 Method* init;
1693 bool ok, ret;
1694
1695 /* establish a basic sense of self */
1696 self = allocThread(gDvm.stackSize);
1697 if (self == NULL)
1698 goto fail;
1699 setThreadSelf(self);
1700
1701 /*
1702 * Create Thread and VMThread objects. We have to use ALLOC_NO_GC
1703 * because this thread is not yet visible to the VM. We could also
1704 * just grab the GC lock earlier, but that leaves us executing
1705 * interpreted code with the lock held, which is not prudent.
1706 *
1707 * The alloc calls will block if a GC is in progress, so we don't need
1708 * to check for global suspension here.
1709 *
1710 * It's also possible for the allocation calls to *cause* a GC.
1711 */
1712 //BUG: deadlock if a GC happens here during HeapWorker creation
1713 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_NO_GC);
1714 if (threadObj == NULL)
1715 goto fail;
1716 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_NO_GC);
1717 if (vmThreadObj == NULL)
1718 goto fail;
1719
1720 self->threadObj = threadObj;
1721 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)self);
1722
1723 /*
1724 * Do some java.lang.Thread constructor prep before we lock stuff down.
1725 */
1726 if (pArgs->name != NULL) {
1727 threadNameStr = dvmCreateStringFromCstr(pArgs->name, ALLOC_NO_GC);
1728 if (threadNameStr == NULL) {
1729 assert(dvmCheckException(dvmThreadSelf()));
1730 goto fail;
1731 }
1732 }
1733
1734 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
1735 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
1736 if (init == NULL) {
1737 assert(dvmCheckException(dvmThreadSelf()));
1738 goto fail;
1739 }
1740
1741 /*
1742 * Finish our thread prep. We need to do this before invoking any
1743 * interpreted code. prepareThread() requires that we hold the thread
1744 * list lock.
1745 */
1746 dvmLockThreadList(self);
1747 ok = prepareThread(self);
1748 dvmUnlockThreadList();
1749 if (!ok)
1750 goto fail;
1751
1752 self->jniEnv = dvmCreateJNIEnv(self);
1753 if (self->jniEnv == NULL)
1754 goto fail;
1755
1756 /*
1757 * Create a "fake" JNI frame at the top of the main thread interp stack.
1758 * It isn't really necessary for the internal threads, but it gives
1759 * the debugger something to show. It is essential for the JNI-attached
1760 * threads.
1761 */
1762 if (!createFakeRunFrame(self))
1763 goto fail;
1764
1765 /*
1766 * The native side of the thread is ready; add it to the list.
1767 */
1768 LOG_THREAD("threadid=%d: adding to list (attached)\n", self->threadId);
1769
1770 /* Start off in VMWAIT, because we may be about to block
1771 * on the heap lock, and we don't want any suspensions
1772 * to wait for us.
1773 */
1774 self->status = THREAD_VMWAIT;
1775
1776 /*
1777 * Add ourselves to the thread list. Once we finish here we are
1778 * visible to the debugger and the GC.
1779 */
1780 dvmLockThreadList(self);
1781
1782 self->next = gDvm.threadList->next;
1783 if (self->next != NULL)
1784 self->next->prev = self;
1785 self->prev = gDvm.threadList;
1786 gDvm.threadList->next = self;
1787 if (!isDaemon)
1788 gDvm.nonDaemonThreadCount++;
1789
1790 dvmUnlockThreadList();
1791
1792 /*
1793 * It's possible that a GC is currently running. Our thread
1794 * wasn't in the list when the GC started, so it's not properly
1795 * suspended in that case. Synchronize on the heap lock (held
1796 * when a GC is happening) to guarantee that any GCs from here
1797 * on will see this thread in the list.
1798 */
1799 dvmLockMutex(&gDvm.gcHeapLock);
1800 dvmUnlockMutex(&gDvm.gcHeapLock);
1801
1802 /*
1803 * Switch to the running state now that we're ready for
1804 * suspensions. This call may suspend.
1805 */
1806 dvmChangeStatus(self, THREAD_RUNNING);
1807
1808 /*
1809 * Now we're ready to run some interpreted code.
1810 *
1811 * We need to construct the Thread object and set the VMThread field.
1812 * Setting VMThread tells interpreted code that we're alive.
1813 *
1814 * Call the (group, name, priority, daemon) constructor on the Thread.
1815 * This sets the thread's name and adds it to the specified group, and
1816 * provides values for priority and daemon (which are normally inherited
1817 * from the current thread).
1818 */
1819 JValue unused;
1820 dvmCallMethod(self, init, threadObj, &unused, (Object*)pArgs->group,
1821 threadNameStr, getThreadPriorityFromSystem(), isDaemon);
1822 if (dvmCheckException(self)) {
1823 LOGE("exception thrown while constructing attached thread object\n");
1824 goto fail_unlink;
1825 }
1826 //if (isDaemon)
1827 // dvmSetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon, true);
1828
1829 /*
1830 * Set the VMThread field, which tells interpreted code that we're alive.
1831 *
1832 * The risk of a thread start collision here is very low; somebody
1833 * would have to be deliberately polling the ThreadGroup list and
1834 * trying to start threads against anything it sees, which would
1835 * generally cause problems for all thread creation. However, for
1836 * correctness we test "vmThread" before setting it.
1837 */
1838 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1839 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1840 "thread has already been started");
1841 /* We don't want to free anything associated with the thread
1842 * because someone is obviously interested in it. Just let
1843 * it go and hope it will clean itself up when its finished.
1844 * This case should never happen anyway.
1845 *
1846 * Since we're letting it live, we need to finish setting it up.
1847 * We just have to let the caller know that the intended operation
1848 * has failed.
1849 *
1850 * [ This seems strange -- stepping on the vmThread object that's
1851 * already present seems like a bad idea. TODO: figure this out. ]
1852 */
1853 ret = false;
1854 } else
1855 ret = true;
1856 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1857
1858 /* These are now reachable from the thread groups. */
1859 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
1860 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
1861
1862 /*
1863 * The thread is ready to go; let the debugger see it.
1864 */
1865 self->threadObj = threadObj;
1866
1867 LOG_THREAD("threadid=%d: attached from native, name=%s\n",
1868 self->threadId, pArgs->name);
1869
1870 /* tell the debugger & DDM */
1871 if (gDvm.debuggerConnected)
1872 dvmDbgPostThreadStart(self);
1873
1874 return ret;
1875
1876fail_unlink:
1877 dvmLockThreadList(self);
1878 unlinkThread(self);
1879 if (!isDaemon)
1880 gDvm.nonDaemonThreadCount--;
1881 dvmUnlockThreadList();
1882 /* fall through to "fail" */
1883fail:
1884 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
1885 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
1886 if (self != NULL) {
1887 if (self->jniEnv != NULL) {
1888 dvmDestroyJNIEnv(self->jniEnv);
1889 self->jniEnv = NULL;
1890 }
1891 freeThread(self);
1892 }
1893 setThreadSelf(NULL);
1894 return false;
1895}
1896
1897/*
1898 * Detach the thread from the various data structures, notify other threads
1899 * that are waiting to "join" it, and free up all heap-allocated storage.
1900 *
1901 * Used for all threads.
1902 *
1903 * When we get here the interpreted stack should be empty. The JNI 1.6 spec
1904 * requires us to enforce this for the DetachCurrentThread call, probably
1905 * because it also says that DetachCurrentThread causes all monitors
1906 * associated with the thread to be released. (Because the stack is empty,
1907 * we only have to worry about explicit JNI calls to MonitorEnter.)
1908 *
1909 * THOUGHT:
1910 * We might want to avoid freeing our internal Thread structure until the
1911 * associated Thread/VMThread objects get GCed. Our Thread is impossible to
1912 * get to once the thread shuts down, but there is a small possibility of
1913 * an operation starting in another thread before this thread halts, and
1914 * finishing much later (perhaps the thread got stalled by a weird OS bug).
1915 * We don't want something like Thread.isInterrupted() crawling through
1916 * freed storage. Can do with a Thread finalizer, or by creating a
1917 * dedicated ThreadObject class for java/lang/Thread and moving all of our
1918 * state into that.
1919 */
1920void dvmDetachCurrentThread(void)
1921{
1922 Thread* self = dvmThreadSelf();
1923 Object* vmThread;
1924 Object* group;
1925
1926 /*
1927 * Make sure we're not detaching a thread that's still running. (This
1928 * could happen with an explicit JNI detach call.)
1929 *
1930 * A thread created by interpreted code will finish with a depth of
1931 * zero, while a JNI-attached thread will have the synthetic "stack
1932 * starter" native method at the top.
1933 */
1934 int curDepth = dvmComputeExactFrameDepth(self->curFrame);
1935 if (curDepth != 0) {
1936 bool topIsNative = false;
1937
1938 if (curDepth == 1) {
1939 /* not expecting a lingering break frame; just look at curFrame */
1940 assert(!dvmIsBreakFrame(self->curFrame));
1941 StackSaveArea* ssa = SAVEAREA_FROM_FP(self->curFrame);
1942 if (dvmIsNativeMethod(ssa->method))
1943 topIsNative = true;
1944 }
1945
1946 if (!topIsNative) {
1947 LOGE("ERROR: detaching thread with interp frames (count=%d)\n",
1948 curDepth);
1949 dvmDumpThread(self, false);
1950 dvmAbort();
1951 }
1952 }
1953
1954 group = dvmGetFieldObject(self->threadObj, gDvm.offJavaLangThread_group);
1955 LOG_THREAD("threadid=%d: detach (group=%p)\n", self->threadId, group);
1956
1957 /*
1958 * Release any held monitors. Since there are no interpreted stack
1959 * frames, the only thing left are the monitors held by JNI MonitorEnter
1960 * calls.
1961 */
1962 dvmReleaseJniMonitors(self);
1963
1964 /*
1965 * Do some thread-exit uncaught exception processing if necessary.
1966 */
1967 if (dvmCheckException(self))
1968 threadExitUncaughtException(self, group);
1969
1970 /*
1971 * Remove the thread from the thread group.
1972 */
1973 if (group != NULL) {
1974 Method* removeThread =
1975 group->clazz->vtable[gDvm.voffJavaLangThreadGroup_removeThread];
1976 JValue unused;
1977 dvmCallMethod(self, removeThread, group, &unused, self->threadObj);
1978 }
1979
1980 /*
1981 * Clear the vmThread reference in the Thread object. Interpreted code
1982 * will now see that this Thread is not running. As this may be the
1983 * only reference to the VMThread object that the VM knows about, we
1984 * have to create an internal reference to it first.
1985 */
1986 vmThread = dvmGetFieldObject(self->threadObj,
1987 gDvm.offJavaLangThread_vmThread);
1988 dvmAddTrackedAlloc(vmThread, self);
1989 dvmSetFieldObject(self->threadObj, gDvm.offJavaLangThread_vmThread, NULL);
1990
1991 /* clear out our struct Thread pointer, since it's going away */
1992 dvmSetFieldObject(vmThread, gDvm.offJavaLangVMThread_vmData, NULL);
1993
1994 /*
1995 * Tell the debugger & DDM. This may cause the current thread or all
1996 * threads to suspend.
1997 *
1998 * The JDWP spec is somewhat vague about when this happens, other than
1999 * that it's issued by the dying thread, which may still appear in
2000 * an "all threads" listing.
2001 */
2002 if (gDvm.debuggerConnected)
2003 dvmDbgPostThreadDeath(self);
2004
2005 /*
2006 * Thread.join() is implemented as an Object.wait() on the VMThread
2007 * object. Signal anyone who is waiting.
2008 */
2009 dvmLockObject(self, vmThread);
2010 dvmObjectNotifyAll(self, vmThread);
2011 dvmUnlockObject(self, vmThread);
2012
2013 dvmReleaseTrackedAlloc(vmThread, self);
2014 vmThread = NULL;
2015
2016 /*
2017 * We're done manipulating objects, so it's okay if the GC runs in
2018 * parallel with us from here out. It's important to do this if
2019 * profiling is enabled, since we can wait indefinitely.
2020 */
2021 self->status = THREAD_VMWAIT;
2022
2023#ifdef WITH_PROFILER
2024 /*
2025 * If we're doing method trace profiling, we don't want threads to exit,
2026 * because if they do we'll end up reusing thread IDs. This complicates
2027 * analysis and makes it impossible to have reasonable output in the
2028 * "threads" section of the "key" file.
2029 *
2030 * We need to do this after Thread.join() completes, or other threads
2031 * could get wedged. Since self->threadObj is still valid, the Thread
2032 * object will not get GCed even though we're no longer in the ThreadGroup
2033 * list (which is important since the profiling thread needs to get
2034 * the thread's name).
2035 */
2036 MethodTraceState* traceState = &gDvm.methodTrace;
2037
2038 dvmLockMutex(&traceState->startStopLock);
2039 if (traceState->traceEnabled) {
2040 LOGI("threadid=%d: waiting for method trace to finish\n",
2041 self->threadId);
2042 while (traceState->traceEnabled) {
2043 int cc;
2044 cc = pthread_cond_wait(&traceState->threadExitCond,
2045 &traceState->startStopLock);
2046 assert(cc == 0);
2047 }
2048 }
2049 dvmUnlockMutex(&traceState->startStopLock);
2050#endif
2051
2052 dvmLockThreadList(self);
2053
2054 /*
2055 * Lose the JNI context.
2056 */
2057 dvmDestroyJNIEnv(self->jniEnv);
2058 self->jniEnv = NULL;
2059
2060 self->status = THREAD_ZOMBIE;
2061
2062 /*
2063 * Remove ourselves from the internal thread list.
2064 */
2065 unlinkThread(self);
2066
2067 /*
2068 * If we're the last one standing, signal anybody waiting in
2069 * DestroyJavaVM that it's okay to exit.
2070 */
2071 if (!dvmGetFieldBoolean(self->threadObj, gDvm.offJavaLangThread_daemon)) {
2072 gDvm.nonDaemonThreadCount--; // guarded by thread list lock
2073
2074 if (gDvm.nonDaemonThreadCount == 0) {
2075 int cc;
2076
2077 LOGV("threadid=%d: last non-daemon thread\n", self->threadId);
2078 //dvmDumpAllThreads(false);
2079 // cond var guarded by threadListLock, which we already hold
2080 cc = pthread_cond_signal(&gDvm.vmExitCond);
2081 assert(cc == 0);
2082 }
2083 }
2084
2085 LOGV("threadid=%d: bye!\n", self->threadId);
2086 releaseThreadId(self);
2087 dvmUnlockThreadList();
2088
2089 setThreadSelf(NULL);
2090 freeThread(self);
2091}
2092
2093
2094/*
2095 * Suspend a single thread. Do not use to suspend yourself.
2096 *
2097 * This is used primarily for debugger/DDMS activity. Does not return
2098 * until the thread has suspended or is in a "safe" state (e.g. executing
2099 * native code outside the VM).
2100 *
2101 * The thread list lock should be held before calling here -- it's not
2102 * entirely safe to hang on to a Thread* from another thread otherwise.
2103 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2104 */
2105void dvmSuspendThread(Thread* thread)
2106{
2107 assert(thread != NULL);
2108 assert(thread != dvmThreadSelf());
2109 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2110
2111 lockThreadSuspendCount();
2112 thread->suspendCount++;
2113 thread->dbgSuspendCount++;
2114
2115 LOG_THREAD("threadid=%d: suspend++, now=%d\n",
2116 thread->threadId, thread->suspendCount);
2117 unlockThreadSuspendCount();
2118
2119 waitForThreadSuspend(dvmThreadSelf(), thread);
2120}
2121
2122/*
2123 * Reduce the suspend count of a thread. If it hits zero, tell it to
2124 * resume.
2125 *
2126 * Used primarily for debugger/DDMS activity. The thread in question
2127 * might have been suspended singly or as part of a suspend-all operation.
2128 *
2129 * The thread list lock should be held before calling here -- it's not
2130 * entirely safe to hang on to a Thread* from another thread otherwise.
2131 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2132 */
2133void dvmResumeThread(Thread* thread)
2134{
2135 assert(thread != NULL);
2136 assert(thread != dvmThreadSelf());
2137 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2138
2139 lockThreadSuspendCount();
2140 if (thread->suspendCount > 0) {
2141 thread->suspendCount--;
2142 thread->dbgSuspendCount--;
2143 } else {
2144 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2145 thread->threadId);
2146 }
2147
2148 LOG_THREAD("threadid=%d: suspend--, now=%d\n",
2149 thread->threadId, thread->suspendCount);
2150
2151 if (thread->suspendCount == 0) {
2152 int cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2153 assert(cc == 0);
2154 }
2155
2156 unlockThreadSuspendCount();
2157}
2158
2159/*
2160 * Suspend yourself, as a result of debugger activity.
2161 */
2162void dvmSuspendSelf(bool jdwpActivity)
2163{
2164 Thread* self = dvmThreadSelf();
2165
2166 /* debugger thread may not suspend itself due to debugger activity! */
2167 assert(gDvm.jdwpState != NULL);
2168 if (self->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2169 assert(false);
2170 return;
2171 }
2172
2173 /*
2174 * Collisions with other suspends aren't really interesting. We want
2175 * to ensure that we're the only one fiddling with the suspend count
2176 * though.
2177 */
2178 lockThreadSuspendCount();
2179 self->suspendCount++;
2180 self->dbgSuspendCount++;
2181
2182 /*
2183 * Suspend ourselves.
2184 */
2185 assert(self->suspendCount > 0);
2186 self->isSuspended = true;
2187 LOG_THREAD("threadid=%d: self-suspending (dbg)\n", self->threadId);
2188
2189 /*
2190 * Tell JDWP that we've completed suspension. The JDWP thread can't
2191 * tell us to resume before we're fully asleep because we hold the
2192 * suspend count lock.
2193 *
2194 * If we got here via waitForDebugger(), don't do this part.
2195 */
2196 if (jdwpActivity) {
2197 //LOGI("threadid=%d: clearing wait-for-event (my handle=%08x)\n",
2198 // self->threadId, (int) self->handle);
2199 dvmJdwpClearWaitForEventThread(gDvm.jdwpState);
2200 }
2201
2202 while (self->suspendCount != 0) {
2203 int cc;
2204 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2205 &gDvm.threadSuspendCountLock);
2206 assert(cc == 0);
2207 if (self->suspendCount != 0) {
The Android Open Source Project99409882009-03-18 22:20:24 -07002208 /*
2209 * The condition was signaled but we're still suspended. This
2210 * can happen if the debugger lets go while a SIGQUIT thread
2211 * dump event is pending (assuming SignalCatcher was resumed for
2212 * just long enough to try to grab the thread-suspend lock).
2213 */
2214 LOGD("threadid=%d: still suspended after undo (sc=%d dc=%d s=%c)\n",
2215 self->threadId, self->suspendCount, self->dbgSuspendCount,
2216 self->isSuspended ? 'Y' : 'N');
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002217 }
2218 }
2219 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2220 self->isSuspended = false;
2221 LOG_THREAD("threadid=%d: self-reviving (dbg), status=%d\n",
2222 self->threadId, self->status);
2223
2224 unlockThreadSuspendCount();
2225}
2226
2227
2228#ifdef HAVE_GLIBC
2229# define NUM_FRAMES 20
2230# include <execinfo.h>
2231/*
2232 * glibc-only stack dump function. Requires link with "--export-dynamic".
2233 *
2234 * TODO: move this into libs/cutils and make it work for all platforms.
2235 */
2236static void printBackTrace(void)
2237{
2238 void* array[NUM_FRAMES];
2239 size_t size;
2240 char** strings;
2241 size_t i;
2242
2243 size = backtrace(array, NUM_FRAMES);
2244 strings = backtrace_symbols(array, size);
2245
2246 LOGW("Obtained %zd stack frames.\n", size);
2247
2248 for (i = 0; i < size; i++)
2249 LOGW("%s\n", strings[i]);
2250
2251 free(strings);
2252}
2253#else
2254static void printBackTrace(void) {}
2255#endif
2256
2257/*
2258 * Dump the state of the current thread and that of another thread that
2259 * we think is wedged.
2260 */
2261static void dumpWedgedThread(Thread* thread)
2262{
2263 char exePath[1024];
2264
2265 /*
2266 * The "executablepath" function in libutils is host-side only.
2267 */
2268 strcpy(exePath, "-");
2269#ifdef HAVE_GLIBC
2270 {
2271 char proc[100];
2272 sprintf(proc, "/proc/%d/exe", getpid());
2273 int len;
2274
2275 len = readlink(proc, exePath, sizeof(exePath)-1);
2276 exePath[len] = '\0';
2277 }
2278#endif
2279
2280 LOGW("dumping state: process %s %d\n", exePath, getpid());
2281 dvmDumpThread(dvmThreadSelf(), false);
2282 printBackTrace();
2283
2284 // dumping a running thread is risky, but could be useful
2285 dvmDumpThread(thread, true);
2286
2287
2288 // stop now and get a core dump
2289 //abort();
2290}
2291
2292
2293/*
2294 * Wait for another thread to see the pending suspension and stop running.
2295 * It can either suspend itself or go into a non-running state such as
2296 * VMWAIT or NATIVE in which it cannot interact with the GC.
2297 *
2298 * If we're running at a higher priority, sched_yield() may not do anything,
2299 * so we need to sleep for "long enough" to guarantee that the other
2300 * thread has a chance to finish what it's doing. Sleeping for too short
2301 * a period (e.g. less than the resolution of the sleep clock) might cause
2302 * the scheduler to return immediately, so we want to start with a
2303 * "reasonable" value and expand.
2304 *
2305 * This does not return until the other thread has stopped running.
2306 * Eventually we time out and the VM aborts.
2307 *
2308 * This does not try to detect the situation where two threads are
2309 * waiting for each other to suspend. In normal use this is part of a
2310 * suspend-all, which implies that the suspend-all lock is held, or as
2311 * part of a debugger action in which the JDWP thread is always the one
2312 * doing the suspending. (We may need to re-evaluate this now that
2313 * getThreadStackTrace is implemented as suspend-snapshot-resume.)
2314 *
2315 * TODO: track basic stats about time required to suspend VM.
2316 */
2317static void waitForThreadSuspend(Thread* self, Thread* thread)
2318{
2319 const int kMaxRetries = 10;
2320 const int kSpinSleepTime = 750*1000; /* 0.75s */
2321
2322 int sleepIter = 0;
2323 int retryCount = 0;
2324 u8 startWhen = 0; // init req'd to placate gcc
2325
2326 while (thread->status == THREAD_RUNNING && !thread->isSuspended) {
2327 if (sleepIter == 0) // get current time on first iteration
2328 startWhen = dvmGetRelativeTimeUsec();
2329
2330 if (!dvmIterativeSleep(sleepIter++, kSpinSleepTime, startWhen)) {
2331 LOGW("threadid=%d (h=%d): spin on suspend threadid=%d (handle=%d)\n",
2332 self->threadId, (int)self->handle,
2333 thread->threadId, (int)thread->handle);
2334 dumpWedgedThread(thread);
2335
2336 // keep going; could be slow due to valgrind
2337 sleepIter = 0;
2338
2339 if (retryCount++ == kMaxRetries) {
2340 LOGE("threadid=%d: stuck on threadid=%d, giving up\n",
2341 self->threadId, thread->threadId);
2342 dvmDumpAllThreads(false);
2343 dvmAbort();
2344 }
2345 }
2346 }
2347}
2348
2349/*
2350 * Suspend all threads except the current one. This is used by the GC,
2351 * the debugger, and by any thread that hits a "suspend all threads"
2352 * debugger event (e.g. breakpoint or exception).
2353 *
2354 * If thread N hits a "suspend all threads" breakpoint, we don't want it
2355 * to suspend the JDWP thread. For the GC, we do, because the debugger can
2356 * create objects and even execute arbitrary code. The "why" argument
2357 * allows the caller to say why the suspension is taking place.
2358 *
2359 * This can be called when a global suspend has already happened, due to
2360 * various debugger gymnastics, so keeping an "everybody is suspended" flag
2361 * doesn't work.
2362 *
2363 * DO NOT grab any locks before calling here. We grab & release the thread
2364 * lock and suspend lock here (and we're not using recursive threads), and
2365 * we might have to self-suspend if somebody else beats us here.
2366 *
2367 * The current thread may not be attached to the VM. This can happen if
2368 * we happen to GC as the result of an allocation of a Thread object.
2369 */
2370void dvmSuspendAllThreads(SuspendCause why)
2371{
2372 Thread* self = dvmThreadSelf();
2373 Thread* thread;
2374
2375 assert(why != 0);
2376
2377 /*
2378 * Start by grabbing the thread suspend lock. If we can't get it, most
2379 * likely somebody else is in the process of performing a suspend or
2380 * resume, so lockThreadSuspend() will cause us to self-suspend.
2381 *
2382 * We keep the lock until all other threads are suspended.
2383 */
2384 lockThreadSuspend("susp-all", why);
2385
2386 LOG_THREAD("threadid=%d: SuspendAll starting\n", self->threadId);
2387
2388 /*
2389 * This is possible if the current thread was in VMWAIT mode when a
2390 * suspend-all happened, and then decided to do its own suspend-all.
2391 * This can happen when a couple of threads have simultaneous events
2392 * of interest to the debugger.
2393 */
2394 //assert(self->suspendCount == 0);
2395
2396 /*
2397 * Increment everybody's suspend count (except our own).
2398 */
2399 dvmLockThreadList(self);
2400
2401 lockThreadSuspendCount();
2402 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2403 if (thread == self)
2404 continue;
2405
2406 /* debugger events don't suspend JDWP thread */
2407 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2408 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2409 continue;
2410
2411 thread->suspendCount++;
2412 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2413 thread->dbgSuspendCount++;
2414 }
2415 unlockThreadSuspendCount();
2416
2417 /*
2418 * Wait for everybody in THREAD_RUNNING state to stop. Other states
2419 * indicate the code is either running natively or sleeping quietly.
2420 * Any attempt to transition back to THREAD_RUNNING will cause a check
2421 * for suspension, so it should be impossible for anything to execute
2422 * interpreted code or modify objects (assuming native code plays nicely).
2423 *
2424 * It's also okay if the thread transitions to a non-RUNNING state.
2425 *
2426 * Note we released the threadSuspendCountLock before getting here,
2427 * so if another thread is fiddling with its suspend count (perhaps
2428 * self-suspending for the debugger) it won't block while we're waiting
2429 * in here.
2430 */
2431 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2432 if (thread == self)
2433 continue;
2434
2435 /* debugger events don't suspend JDWP thread */
2436 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2437 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2438 continue;
2439
2440 /* wait for the other thread to see the pending suspend */
2441 waitForThreadSuspend(self, thread);
2442
2443 LOG_THREAD("threadid=%d: threadid=%d status=%d c=%d dc=%d isSusp=%d\n",
2444 self->threadId,
2445 thread->threadId, thread->status, thread->suspendCount,
2446 thread->dbgSuspendCount, thread->isSuspended);
2447 }
2448
2449 dvmUnlockThreadList();
2450 unlockThreadSuspend();
2451
2452 LOG_THREAD("threadid=%d: SuspendAll complete\n", self->threadId);
2453}
2454
2455/*
2456 * Resume all threads that are currently suspended.
2457 *
2458 * The "why" must match with the previous suspend.
2459 */
2460void dvmResumeAllThreads(SuspendCause why)
2461{
2462 Thread* self = dvmThreadSelf();
2463 Thread* thread;
2464 int cc;
2465
2466 lockThreadSuspend("res-all", why); /* one suspend/resume at a time */
2467 LOG_THREAD("threadid=%d: ResumeAll starting\n", self->threadId);
2468
2469 /*
2470 * Decrement the suspend counts for all threads. No need for atomic
2471 * writes, since nobody should be moving until we decrement the count.
2472 * We do need to hold the thread list because of JNI attaches.
2473 */
2474 dvmLockThreadList(self);
2475 lockThreadSuspendCount();
2476 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2477 if (thread == self)
2478 continue;
2479
2480 /* debugger events don't suspend JDWP thread */
2481 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2482 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2483 continue;
2484
2485 if (thread->suspendCount > 0) {
2486 thread->suspendCount--;
2487 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2488 thread->dbgSuspendCount--;
2489 } else {
2490 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2491 thread->threadId);
2492 }
2493 }
2494 unlockThreadSuspendCount();
2495 dvmUnlockThreadList();
2496
2497 /*
2498 * Broadcast a notification to all suspended threads, some or all of
2499 * which may choose to wake up. No need to wait for them.
2500 */
2501 lockThreadSuspendCount();
2502 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2503 assert(cc == 0);
2504 unlockThreadSuspendCount();
2505
2506 unlockThreadSuspend();
2507
2508 LOG_THREAD("threadid=%d: ResumeAll complete\n", self->threadId);
2509}
2510
2511/*
2512 * Undo any debugger suspensions. This is called when the debugger
2513 * disconnects.
2514 */
2515void dvmUndoDebuggerSuspensions(void)
2516{
2517 Thread* self = dvmThreadSelf();
2518 Thread* thread;
2519 int cc;
2520
2521 lockThreadSuspend("undo", SUSPEND_FOR_DEBUG);
2522 LOG_THREAD("threadid=%d: UndoDebuggerSusp starting\n", self->threadId);
2523
2524 /*
2525 * Decrement the suspend counts for all threads. No need for atomic
2526 * writes, since nobody should be moving until we decrement the count.
2527 * We do need to hold the thread list because of JNI attaches.
2528 */
2529 dvmLockThreadList(self);
2530 lockThreadSuspendCount();
2531 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2532 if (thread == self)
2533 continue;
2534
2535 /* debugger events don't suspend JDWP thread */
2536 if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2537 assert(thread->dbgSuspendCount == 0);
2538 continue;
2539 }
2540
2541 assert(thread->suspendCount >= thread->dbgSuspendCount);
2542 thread->suspendCount -= thread->dbgSuspendCount;
2543 thread->dbgSuspendCount = 0;
2544 }
2545 unlockThreadSuspendCount();
2546 dvmUnlockThreadList();
2547
2548 /*
2549 * Broadcast a notification to all suspended threads, some or all of
2550 * which may choose to wake up. No need to wait for them.
2551 */
2552 lockThreadSuspendCount();
2553 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2554 assert(cc == 0);
2555 unlockThreadSuspendCount();
2556
2557 unlockThreadSuspend();
2558
2559 LOG_THREAD("threadid=%d: UndoDebuggerSusp complete\n", self->threadId);
2560}
2561
2562/*
2563 * Determine if a thread is suspended.
2564 *
2565 * As with all operations on foreign threads, the caller should hold
2566 * the thread list lock before calling.
2567 */
2568bool dvmIsSuspended(Thread* thread)
2569{
2570 /*
2571 * The thread could be:
2572 * (1) Running happily. status is RUNNING, isSuspended is false,
2573 * suspendCount is zero. Return "false".
2574 * (2) Pending suspend. status is RUNNING, isSuspended is false,
2575 * suspendCount is nonzero. Return "false".
2576 * (3) Suspended. suspendCount is nonzero, and either (status is
2577 * RUNNING and isSuspended is true) OR (status is !RUNNING).
2578 * Return "true".
2579 * (4) Waking up. suspendCount is zero, status is RUNNING and
2580 * isSuspended is true. Return "false" (since it could change
2581 * out from under us, unless we hold suspendCountLock).
2582 */
2583
2584 return (thread->suspendCount != 0 &&
2585 ((thread->status == THREAD_RUNNING && thread->isSuspended) ||
2586 (thread->status != THREAD_RUNNING)));
2587}
2588
2589/*
2590 * Wait until another thread self-suspends. This is specifically for
2591 * synchronization between the JDWP thread and a thread that has decided
2592 * to suspend itself after sending an event to the debugger.
2593 *
2594 * Threads that encounter "suspend all" events work as well -- the thread
2595 * in question suspends everybody else and then itself.
2596 *
2597 * We can't hold a thread lock here or in the caller, because we could
2598 * get here just before the to-be-waited-for-thread issues a "suspend all".
2599 * There's an opportunity for badness if the thread we're waiting for exits
2600 * and gets cleaned up, but since the thread in question is processing a
2601 * debugger event, that's not really a possibility. (To avoid deadlock,
2602 * it's important that we not be in THREAD_RUNNING while we wait.)
2603 */
2604void dvmWaitForSuspend(Thread* thread)
2605{
2606 Thread* self = dvmThreadSelf();
2607
2608 LOG_THREAD("threadid=%d: waiting for threadid=%d to sleep\n",
2609 self->threadId, thread->threadId);
2610
2611 assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2612 assert(thread != self);
2613 assert(self->status != THREAD_RUNNING);
2614
2615 waitForThreadSuspend(self, thread);
2616
2617 LOG_THREAD("threadid=%d: threadid=%d is now asleep\n",
2618 self->threadId, thread->threadId);
2619}
2620
2621/*
2622 * Check to see if we need to suspend ourselves. If so, go to sleep on
2623 * a condition variable.
2624 *
2625 * Takes "self" as an argument as an optimization. Pass in NULL to have
2626 * it do the lookup.
2627 *
2628 * Returns "true" if we suspended ourselves.
2629 */
2630bool dvmCheckSuspendPending(Thread* self)
2631{
2632 bool didSuspend;
2633
2634 if (self == NULL)
2635 self = dvmThreadSelf();
2636
2637 /* fast path: if count is zero, bail immediately */
2638 if (self->suspendCount == 0)
2639 return false;
2640
2641 lockThreadSuspendCount(); /* grab gDvm.threadSuspendCountLock */
2642
2643 assert(self->suspendCount >= 0); /* XXX: valid? useful? */
2644
2645 didSuspend = (self->suspendCount != 0);
2646 self->isSuspended = true;
2647 LOG_THREAD("threadid=%d: self-suspending\n", self->threadId);
2648 while (self->suspendCount != 0) {
2649 /* wait for wakeup signal; releases lock */
2650 int cc;
2651 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2652 &gDvm.threadSuspendCountLock);
2653 assert(cc == 0);
2654 }
2655 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2656 self->isSuspended = false;
2657 LOG_THREAD("threadid=%d: self-reviving, status=%d\n",
2658 self->threadId, self->status);
2659
2660 unlockThreadSuspendCount();
2661
2662 return didSuspend;
2663}
2664
2665/*
2666 * Update our status.
2667 *
2668 * The "self" argument, which may be NULL, is accepted as an optimization.
2669 *
2670 * Returns the old status.
2671 */
2672ThreadStatus dvmChangeStatus(Thread* self, ThreadStatus newStatus)
2673{
2674 ThreadStatus oldStatus;
2675
2676 if (self == NULL)
2677 self = dvmThreadSelf();
2678
2679 LOGVV("threadid=%d: (status %d -> %d)\n",
2680 self->threadId, self->status, newStatus);
2681
2682 oldStatus = self->status;
2683
2684 if (newStatus == THREAD_RUNNING) {
2685 /*
2686 * Change our status to THREAD_RUNNING. The transition requires
2687 * that we check for pending suspension, because the VM considers
2688 * us to be "asleep" in all other states.
2689 *
2690 * We need to do the "suspend pending" check FIRST, because it grabs
2691 * a lock that could be held by something that wants us to suspend.
2692 * If we're in RUNNING it will wait for us, and we'll be waiting
2693 * for the lock it holds.
2694 */
2695 assert(self->status != THREAD_RUNNING);
2696
2697 dvmCheckSuspendPending(self);
2698 self->status = THREAD_RUNNING;
2699 } else {
2700 /*
2701 * Change from one state to another, neither of which is
2702 * THREAD_RUNNING. This is most common during system or thread
2703 * initialization.
2704 */
2705 self->status = newStatus;
2706 }
2707
2708 return oldStatus;
2709}
2710
2711/*
2712 * Get a statically defined thread group from a field in the ThreadGroup
2713 * Class object. Expected arguments are "mMain" and "mSystem".
2714 */
2715static Object* getStaticThreadGroup(const char* fieldName)
2716{
2717 StaticField* groupField;
2718 Object* groupObj;
2719
2720 groupField = dvmFindStaticField(gDvm.classJavaLangThreadGroup,
2721 fieldName, "Ljava/lang/ThreadGroup;");
2722 if (groupField == NULL) {
2723 LOGE("java.lang.ThreadGroup does not have an '%s' field\n", fieldName);
2724 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", NULL);
2725 return NULL;
2726 }
2727 groupObj = dvmGetStaticFieldObject(groupField);
2728 if (groupObj == NULL) {
2729 LOGE("java.lang.ThreadGroup.%s not initialized\n", fieldName);
2730 dvmThrowException("Ljava/lang/InternalError;", NULL);
2731 return NULL;
2732 }
2733
2734 return groupObj;
2735}
2736Object* dvmGetSystemThreadGroup(void)
2737{
2738 return getStaticThreadGroup("mSystem");
2739}
2740Object* dvmGetMainThreadGroup(void)
2741{
2742 return getStaticThreadGroup("mMain");
2743}
2744
2745/*
2746 * Given a VMThread object, return the associated Thread*.
2747 *
2748 * NOTE: if the thread detaches, the struct Thread will disappear, and
2749 * we will be touching invalid data. For safety, lock the thread list
2750 * before calling this.
2751 */
2752Thread* dvmGetThreadFromThreadObject(Object* vmThreadObj)
2753{
2754 int vmData;
2755
2756 vmData = dvmGetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData);
2757 return (Thread*) vmData;
2758}
2759
2760
2761/*
2762 * Conversion map for "nice" values.
2763 *
2764 * We use Android thread priority constants to be consistent with the rest
2765 * of the system. In some cases adjacent entries may overlap.
2766 */
2767static const int kNiceValues[10] = {
2768 ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
2769 ANDROID_PRIORITY_BACKGROUND + 6,
2770 ANDROID_PRIORITY_BACKGROUND + 3,
2771 ANDROID_PRIORITY_BACKGROUND,
2772 ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
2773 ANDROID_PRIORITY_NORMAL - 2,
2774 ANDROID_PRIORITY_NORMAL - 4,
2775 ANDROID_PRIORITY_URGENT_DISPLAY + 3,
2776 ANDROID_PRIORITY_URGENT_DISPLAY + 2,
2777 ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
2778};
2779
2780/*
2781 * Change the priority of a system thread to match that of the Thread object.
2782 *
2783 * We map a priority value from 1-10 to Linux "nice" values, where lower
2784 * numbers indicate higher priority.
2785 */
2786void dvmChangeThreadPriority(Thread* thread, int newPriority)
2787{
2788 pid_t pid = thread->systemTid;
2789 int newNice;
2790
2791 if (newPriority < 1 || newPriority > 10) {
2792 LOGW("bad priority %d\n", newPriority);
2793 newPriority = 5;
2794 }
2795 newNice = kNiceValues[newPriority-1];
2796
2797 if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
2798 char* str = dvmGetThreadName(thread);
2799 LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s\n",
2800 pid, str, newPriority, newNice, strerror(errno));
2801 free(str);
2802 } else {
2803 LOGV("setPriority(%d) to prio=%d(n=%d)\n",
2804 pid, newPriority, newNice);
2805 }
2806}
2807
2808/*
2809 * Get the thread priority for the current thread by querying the system.
2810 * This is useful when attaching a thread through JNI.
2811 *
2812 * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
2813 */
2814static int getThreadPriorityFromSystem(void)
2815{
2816 int i, sysprio, jprio;
2817
2818 errno = 0;
2819 sysprio = getpriority(PRIO_PROCESS, 0);
2820 if (sysprio == -1 && errno != 0) {
2821 LOGW("getpriority() failed: %s\n", strerror(errno));
2822 return THREAD_NORM_PRIORITY;
2823 }
2824
2825 jprio = THREAD_MIN_PRIORITY;
2826 for (i = 0; i < NELEM(kNiceValues); i++) {
2827 if (sysprio >= kNiceValues[i])
2828 break;
2829 jprio++;
2830 }
2831 if (jprio > THREAD_MAX_PRIORITY)
2832 jprio = THREAD_MAX_PRIORITY;
2833
2834 return jprio;
2835}
2836
2837
2838/*
2839 * Return true if the thread is on gDvm.threadList.
2840 * Caller should not hold gDvm.threadListLock.
2841 */
2842bool dvmIsOnThreadList(const Thread* thread)
2843{
2844 bool ret = false;
2845
2846 dvmLockThreadList(NULL);
2847 if (thread == gDvm.threadList) {
2848 ret = true;
2849 } else {
2850 ret = thread->prev != NULL || thread->next != NULL;
2851 }
2852 dvmUnlockThreadList();
2853
2854 return ret;
2855}
2856
2857/*
2858 * Dump a thread to the log file -- just calls dvmDumpThreadEx() with an
2859 * output target.
2860 */
2861void dvmDumpThread(Thread* thread, bool isRunning)
2862{
2863 DebugOutputTarget target;
2864
2865 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
2866 dvmDumpThreadEx(&target, thread, isRunning);
2867}
2868
2869/*
2870 * Print information about the specified thread.
2871 *
2872 * Works best when the thread in question is "self" or has been suspended.
2873 * When dumping a separate thread that's still running, set "isRunning" to
2874 * use a more cautious thread dump function.
2875 */
2876void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
2877 bool isRunning)
2878{
2879 /* tied to ThreadStatus enum */
2880 static const char* kStatusNames[] = {
2881 "ZOMBIE", "RUNNABLE", "TIMED_WAIT", "MONITOR", "WAIT",
2882 "INITIALIZING", "STARTING", "NATIVE", "VMWAIT"
2883 };
2884 Object* threadObj;
2885 Object* groupObj;
2886 StringObject* nameStr;
2887 char* threadName = NULL;
2888 char* groupName = NULL;
2889 bool isDaemon;
2890 int priority; // java.lang.Thread priority
2891 int policy; // pthread policy
2892 struct sched_param sp; // pthread scheduling parameters
2893
2894 threadObj = thread->threadObj;
2895 if (threadObj == NULL) {
2896 LOGW("Can't dump thread %d: threadObj not set\n", thread->threadId);
2897 return;
2898 }
2899 nameStr = (StringObject*) dvmGetFieldObject(threadObj,
2900 gDvm.offJavaLangThread_name);
2901 threadName = dvmCreateCstrFromString(nameStr);
2902
2903 priority = dvmGetFieldInt(threadObj, gDvm.offJavaLangThread_priority);
2904 isDaemon = dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon);
2905
2906 if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) {
2907 LOGW("Warning: pthread_getschedparam failed\n");
2908 policy = -1;
2909 sp.sched_priority = -1;
2910 }
2911
2912 /* a null value for group is not expected, but deal with it anyway */
2913 groupObj = (Object*) dvmGetFieldObject(threadObj,
2914 gDvm.offJavaLangThread_group);
2915 if (groupObj != NULL) {
2916 int offset = dvmFindFieldOffset(gDvm.classJavaLangThreadGroup,
2917 "name", "Ljava/lang/String;");
2918 if (offset < 0) {
2919 LOGW("Unable to find 'name' field in ThreadGroup\n");
2920 } else {
2921 nameStr = (StringObject*) dvmGetFieldObject(groupObj, offset);
2922 groupName = dvmCreateCstrFromString(nameStr);
2923 }
2924 }
2925 if (groupName == NULL)
2926 groupName = strdup("(BOGUS GROUP)");
2927
2928 assert(thread->status < NELEM(kStatusNames));
2929 dvmPrintDebugMessage(target,
2930 "\"%s\"%s prio=%d tid=%d %s\n",
2931 threadName, isDaemon ? " daemon" : "",
2932 priority, thread->threadId, kStatusNames[thread->status]);
2933 dvmPrintDebugMessage(target,
The Android Open Source Project99409882009-03-18 22:20:24 -07002934 " | group=\"%s\" sCount=%d dsCount=%d s=%c obj=%p\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002935 groupName, thread->suspendCount, thread->dbgSuspendCount,
The Android Open Source Project99409882009-03-18 22:20:24 -07002936 thread->isSuspended ? 'Y' : 'N', thread->threadObj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002937 dvmPrintDebugMessage(target,
2938 " | sysTid=%d nice=%d sched=%d/%d handle=%d\n",
2939 thread->systemTid, getpriority(PRIO_PROCESS, thread->systemTid),
2940 policy, sp.sched_priority, (int)thread->handle);
2941
2942#ifdef WITH_MONITOR_TRACKING
2943 if (!isRunning) {
2944 LockedObjectData* lod = thread->pLockedObjects;
2945 if (lod != NULL)
2946 dvmPrintDebugMessage(target, " | monitors held:\n");
2947 else
2948 dvmPrintDebugMessage(target, " | monitors held: <none>\n");
2949 while (lod != NULL) {
2950 dvmPrintDebugMessage(target, " > %p[%d] (%s)\n",
2951 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
2952 lod = lod->next;
2953 }
2954 }
2955#endif
2956
2957 if (isRunning)
2958 dvmDumpRunningThreadStack(target, thread);
2959 else
2960 dvmDumpThreadStack(target, thread);
2961
2962 free(threadName);
2963 free(groupName);
2964
2965}
2966
2967/*
2968 * Get the name of a thread.
2969 *
2970 * For correctness, the caller should hold the thread list lock to ensure
2971 * that the thread doesn't go away mid-call.
2972 *
2973 * Returns a newly-allocated string, or NULL if the Thread doesn't have a name.
2974 */
2975char* dvmGetThreadName(Thread* thread)
2976{
2977 StringObject* nameObj;
2978
2979 if (thread->threadObj == NULL) {
2980 LOGW("threadObj is NULL, name not available\n");
2981 return strdup("-unknown-");
2982 }
2983
2984 nameObj = (StringObject*)
2985 dvmGetFieldObject(thread->threadObj, gDvm.offJavaLangThread_name);
2986 return dvmCreateCstrFromString(nameObj);
2987}
2988
2989/*
2990 * Dump all threads to the log file -- just calls dvmDumpAllThreadsEx() with
2991 * an output target.
2992 */
2993void dvmDumpAllThreads(bool grabLock)
2994{
2995 DebugOutputTarget target;
2996
2997 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
2998 dvmDumpAllThreadsEx(&target, grabLock);
2999}
3000
3001/*
3002 * Print information about all known threads. Assumes they have been
3003 * suspended (or are in a non-interpreting state, e.g. WAIT or NATIVE).
3004 *
3005 * If "grabLock" is true, we grab the thread lock list. This is important
3006 * to do unless the caller already holds the lock.
3007 */
3008void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock)
3009{
3010 Thread* thread;
3011
3012 dvmPrintDebugMessage(target, "DALVIK THREADS:\n");
3013
3014 if (grabLock)
3015 dvmLockThreadList(dvmThreadSelf());
3016
3017 thread = gDvm.threadList;
3018 while (thread != NULL) {
3019 dvmDumpThreadEx(target, thread, false);
3020
3021 /* verify link */
3022 assert(thread->next == NULL || thread->next->prev == thread);
3023
3024 thread = thread->next;
3025 }
3026
3027 if (grabLock)
3028 dvmUnlockThreadList();
3029}
3030
3031#ifdef WITH_MONITOR_TRACKING
3032/*
3033 * Count up the #of locked objects in the current thread.
3034 */
3035static int getThreadObjectCount(const Thread* self)
3036{
3037 LockedObjectData* lod;
3038 int count = 0;
3039
3040 lod = self->pLockedObjects;
3041 while (lod != NULL) {
3042 count++;
3043 lod = lod->next;
3044 }
3045 return count;
3046}
3047
3048/*
3049 * Add the object to the thread's locked object list if it doesn't already
3050 * exist. The most recently added object is the most likely to be released
3051 * next, so we insert at the head of the list.
3052 *
3053 * If it already exists, we increase the recursive lock count.
3054 *
3055 * The object's lock may be thin or fat.
3056 */
3057void dvmAddToMonitorList(Thread* self, Object* obj, bool withTrace)
3058{
3059 LockedObjectData* newLod;
3060 LockedObjectData* lod;
3061 int* trace;
3062 int depth;
3063
3064 lod = self->pLockedObjects;
3065 while (lod != NULL) {
3066 if (lod->obj == obj) {
3067 lod->recursionCount++;
3068 LOGV("+++ +recursive lock %p -> %d\n", obj, lod->recursionCount);
3069 return;
3070 }
3071 lod = lod->next;
3072 }
3073
3074 newLod = (LockedObjectData*) calloc(1, sizeof(LockedObjectData));
3075 if (newLod == NULL) {
3076 LOGE("malloc failed on %d bytes\n", sizeof(LockedObjectData));
3077 return;
3078 }
3079 newLod->obj = obj;
3080 newLod->recursionCount = 0;
3081
3082 if (withTrace) {
3083 trace = dvmFillInStackTraceRaw(self, &depth);
3084 newLod->rawStackTrace = trace;
3085 newLod->stackDepth = depth;
3086 }
3087
3088 newLod->next = self->pLockedObjects;
3089 self->pLockedObjects = newLod;
3090
3091 LOGV("+++ threadid=%d: added %p, now %d\n",
3092 self->threadId, newLod, getThreadObjectCount(self));
3093}
3094
3095/*
3096 * Remove the object from the thread's locked object list. If the entry
3097 * has a nonzero recursion count, we just decrement the count instead.
3098 */
3099void dvmRemoveFromMonitorList(Thread* self, Object* obj)
3100{
3101 LockedObjectData* lod;
3102 LockedObjectData* prevLod;
3103
3104 lod = self->pLockedObjects;
3105 prevLod = NULL;
3106 while (lod != NULL) {
3107 if (lod->obj == obj) {
3108 if (lod->recursionCount > 0) {
3109 lod->recursionCount--;
3110 LOGV("+++ -recursive lock %p -> %d\n",
3111 obj, lod->recursionCount);
3112 return;
3113 } else {
3114 break;
3115 }
3116 }
3117 prevLod = lod;
3118 lod = lod->next;
3119 }
3120
3121 if (lod == NULL) {
3122 LOGW("BUG: object %p not found in thread's lock list\n", obj);
3123 return;
3124 }
3125 if (prevLod == NULL) {
3126 /* first item in list */
3127 assert(self->pLockedObjects == lod);
3128 self->pLockedObjects = lod->next;
3129 } else {
3130 /* middle/end of list */
3131 prevLod->next = lod->next;
3132 }
3133
3134 LOGV("+++ threadid=%d: removed %p, now %d\n",
3135 self->threadId, lod, getThreadObjectCount(self));
3136 free(lod->rawStackTrace);
3137 free(lod);
3138}
3139
3140/*
3141 * If the specified object is already in the thread's locked object list,
3142 * return the LockedObjectData struct. Otherwise return NULL.
3143 */
3144LockedObjectData* dvmFindInMonitorList(const Thread* self, const Object* obj)
3145{
3146 LockedObjectData* lod;
3147
3148 lod = self->pLockedObjects;
3149 while (lod != NULL) {
3150 if (lod->obj == obj)
3151 return lod;
3152 lod = lod->next;
3153 }
3154 return NULL;
3155}
3156#endif /*WITH_MONITOR_TRACKING*/
3157
3158
3159/*
3160 * GC helper functions
3161 */
3162
The Android Open Source Project99409882009-03-18 22:20:24 -07003163/*
3164 * Add the contents of the registers from the interpreted call stack.
3165 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003166static void gcScanInterpStackReferences(Thread *thread)
3167{
3168 const u4 *framePtr;
The Android Open Source Project99409882009-03-18 22:20:24 -07003169#if WITH_EXTRA_GC_CHECKS > 1
3170 bool first = true;
3171#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003172
3173 framePtr = (const u4 *)thread->curFrame;
3174 while (framePtr != NULL) {
3175 const StackSaveArea *saveArea;
3176 const Method *method;
3177
3178 saveArea = SAVEAREA_FROM_FP(framePtr);
3179 method = saveArea->method;
The Android Open Source Project99409882009-03-18 22:20:24 -07003180 if (method != NULL && !dvmIsNativeMethod(method)) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003181#ifdef COUNT_PRECISE_METHODS
3182 /* the GC is running, so no lock required */
The Android Open Source Project99409882009-03-18 22:20:24 -07003183 if (dvmPointerSetAddEntry(gDvm.preciseMethods, method))
3184 LOGI("PGC: added %s.%s %p\n",
3185 method->clazz->descriptor, method->name, method);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003186#endif
The Android Open Source Project99409882009-03-18 22:20:24 -07003187#if WITH_EXTRA_GC_CHECKS > 1
3188 /*
3189 * May also want to enable the memset() in the "invokeMethod"
3190 * goto target in the portable interpreter. That sets the stack
3191 * to a pattern that makes referring to uninitialized data
3192 * very obvious.
3193 */
3194
3195 if (first) {
3196 /*
3197 * First frame, isn't native, check the "alternate" saved PC
3198 * as a sanity check.
3199 *
3200 * It seems like we could check the second frame if the first
3201 * is native, since the PCs should be the same. It turns out
3202 * this doesn't always work. The problem is that we could
3203 * have calls in the sequence:
3204 * interp method #2
3205 * native method
3206 * interp method #1
3207 *
3208 * and then GC while in the native method after returning
3209 * from interp method #2. The currentPc on the stack is
3210 * for interp method #1, but thread->currentPc2 is still
3211 * set for the last thing interp method #2 did.
3212 *
3213 * This can also happen in normal execution:
3214 * - sget-object on not-yet-loaded class
3215 * - class init updates currentPc2
3216 * - static field init is handled by parsing annotations;
3217 * static String init requires creation of a String object,
3218 * which can cause a GC
3219 *
3220 * Essentially, any pattern that involves executing
3221 * interpreted code and then causes an allocation without
3222 * executing instructions in the original method will hit
3223 * this. These are rare enough that the test still has
3224 * some value.
3225 */
3226 if (saveArea->xtra.currentPc != thread->currentPc2) {
3227 LOGW("PGC: savedPC(%p) != current PC(%p), %s.%s ins=%p\n",
3228 saveArea->xtra.currentPc, thread->currentPc2,
3229 method->clazz->descriptor, method->name, method->insns);
3230 if (saveArea->xtra.currentPc != NULL)
3231 LOGE(" pc inst = 0x%04x\n", *saveArea->xtra.currentPc);
3232 if (thread->currentPc2 != NULL)
3233 LOGE(" pc2 inst = 0x%04x\n", *thread->currentPc2);
3234 dvmDumpThread(thread, false);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003235 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003236 } else {
3237 /*
3238 * It's unusual, but not impossible, for a non-first frame
3239 * to be at something other than a method invocation. For
3240 * example, if we do a new-instance on a nonexistent class,
3241 * we'll have a lot of class loader activity on the stack
3242 * above the frame with the "new" operation. Could also
3243 * happen while we initialize a Throwable when an instruction
3244 * fails.
3245 *
3246 * So there's not much we can do here to verify the PC,
3247 * except to verify that it's a GC point.
3248 */
3249 }
3250 assert(saveArea->xtra.currentPc != NULL);
3251#endif
3252
3253 const RegisterMap* pMap;
3254 const u1* regVector;
3255 int i;
3256
Andy McFaddencf8b55c2009-04-13 15:26:03 -07003257 Method* nonConstMethod = (Method*) method; // quiet gcc
3258 pMap = dvmGetExpandedRegisterMap(nonConstMethod);
The Android Open Source Project99409882009-03-18 22:20:24 -07003259 if (pMap != NULL) {
3260 /* found map, get registers for this address */
3261 int addr = saveArea->xtra.currentPc - method->insns;
Andy McFaddend45a8872009-03-24 20:41:52 -07003262 regVector = dvmRegisterMapGetLine(pMap, addr);
The Android Open Source Project99409882009-03-18 22:20:24 -07003263 if (regVector == NULL) {
3264 LOGW("PGC: map but no entry for %s.%s addr=0x%04x\n",
3265 method->clazz->descriptor, method->name, addr);
3266 } else {
3267 LOGV("PGC: found map for %s.%s 0x%04x (t=%d)\n",
3268 method->clazz->descriptor, method->name, addr,
3269 thread->threadId);
3270 }
3271 } else {
3272 /*
3273 * No map found. If precise GC is disabled this is
3274 * expected -- we don't create pointers to the map data even
3275 * if it's present -- but if it's enabled it means we're
3276 * unexpectedly falling back on a conservative scan, so it's
3277 * worth yelling a little.
3278 *
3279 * TODO: we should be able to remove this for production --
3280 * no need to keep banging on the global.
3281 */
3282 if (gDvm.preciseGc) {
Andy McFaddencf8b55c2009-04-13 15:26:03 -07003283 LOGV("PGC: no map for %s.%s\n",
The Android Open Source Project99409882009-03-18 22:20:24 -07003284 method->clazz->descriptor, method->name);
3285 }
3286 regVector = NULL;
3287 }
3288
3289 if (regVector == NULL) {
3290 /* conservative scan */
3291 for (i = method->registersSize - 1; i >= 0; i--) {
3292 u4 rval = *framePtr++;
3293 if (rval != 0 && (rval & 0x3) == 0) {
3294 dvmMarkIfObject((Object *)rval);
3295 }
3296 }
3297 } else {
3298 /*
3299 * Precise scan. v0 is at the lowest address on the
3300 * interpreted stack, and is the first bit in the register
3301 * vector, so we can walk through the register map and
3302 * memory in the same direction.
3303 *
3304 * A '1' bit indicates a live reference.
3305 */
3306 u2 bits = 1 << 1;
3307 for (i = method->registersSize - 1; i >= 0; i--) {
3308 u4 rval = *framePtr++;
3309
3310 bits >>= 1;
3311 if (bits == 1) {
3312 /* set bit 9 so we can tell when we're empty */
3313 bits = *regVector++ | 0x0100;
3314 LOGVV("loaded bits: 0x%02x\n", bits & 0xff);
3315 }
3316
3317 if (rval != 0 && (bits & 0x01) != 0) {
3318 /*
3319 * Non-null, register marked as live reference. This
3320 * should always be a valid object.
3321 */
3322#if WITH_EXTRA_GC_CHECKS > 0
3323 if ((rval & 0x3) != 0 ||
3324 !dvmIsValidObject((Object*) rval))
3325 {
3326 /* this is very bad */
3327 LOGE("PGC: invalid ref in reg %d: 0x%08x\n",
3328 method->registersSize-1 - i, rval);
3329 } else
3330#endif
3331 {
3332 dvmMarkObjectNonNull((Object *)rval);
3333 }
3334 } else {
3335 /*
3336 * Null or non-reference, do nothing at all.
3337 */
3338#if WITH_EXTRA_GC_CHECKS > 1
3339 if (dvmIsValidObject((Object*) rval)) {
3340 /* this is normal, but we feel chatty */
3341 LOGD("PGC: ignoring valid ref in reg %d: 0x%08x\n",
3342 method->registersSize-1 - i, rval);
3343 }
3344#endif
3345 }
3346 }
3347 dvmReleaseRegisterMapLine(pMap, regVector);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003348 }
3349 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003350 /* else this is a break frame and there is nothing to mark, or
3351 * this is a native method and the registers are just the "ins",
3352 * copied from various registers in the caller's set.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003353 */
3354
The Android Open Source Project99409882009-03-18 22:20:24 -07003355#if WITH_EXTRA_GC_CHECKS > 1
3356 first = false;
3357#endif
3358
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003359 /* Don't fall into an infinite loop if things get corrupted.
3360 */
3361 assert((uintptr_t)saveArea->prevFrame > (uintptr_t)framePtr ||
3362 saveArea->prevFrame == NULL);
3363 framePtr = saveArea->prevFrame;
3364 }
3365}
3366
3367static void gcScanReferenceTable(ReferenceTable *refTable)
3368{
3369 Object **op;
3370
3371 //TODO: these asserts are overkill; turn them off when things stablize.
3372 assert(refTable != NULL);
3373 assert(refTable->table != NULL);
3374 assert(refTable->nextEntry != NULL);
3375 assert((uintptr_t)refTable->nextEntry >= (uintptr_t)refTable->table);
3376 assert(refTable->nextEntry - refTable->table <= refTable->maxEntries);
3377
3378 op = refTable->table;
3379 while ((uintptr_t)op < (uintptr_t)refTable->nextEntry) {
3380 dvmMarkObjectNonNull(*(op++));
3381 }
3382}
3383
3384/*
3385 * Scan a Thread and mark any objects it references.
3386 */
3387static void gcScanThread(Thread *thread)
3388{
3389 assert(thread != NULL);
3390
3391 /*
3392 * The target thread must be suspended or in a state where it can't do
3393 * any harm (e.g. in Object.wait()). The only exception is the current
3394 * thread, which will still be active and in the "running" state.
3395 *
3396 * (Newly-created threads shouldn't be able to shift themselves to
3397 * RUNNING without a suspend-pending check, so this shouldn't cause
3398 * a false-positive.)
3399 */
3400 assert(thread->status != THREAD_RUNNING || thread->isSuspended ||
3401 thread == dvmThreadSelf());
3402
3403 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_THREAD_OBJECT, thread->threadId);
3404
3405 dvmMarkObject(thread->threadObj); // could be NULL, when constructing
3406
3407 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_NATIVE_STACK, thread->threadId);
3408
3409 dvmMarkObject(thread->exception); // usually NULL
3410 gcScanReferenceTable(&thread->internalLocalRefTable);
3411
3412 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_LOCAL, thread->threadId);
3413
3414 gcScanReferenceTable(&thread->jniLocalRefTable);
3415
3416 if (thread->jniMonitorRefTable.table != NULL) {
3417 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_MONITOR, thread->threadId);
3418
3419 gcScanReferenceTable(&thread->jniMonitorRefTable);
3420 }
3421
3422 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JAVA_FRAME, thread->threadId);
3423
3424 gcScanInterpStackReferences(thread);
3425
3426 HPROF_CLEAR_GC_SCAN_STATE();
3427}
3428
3429static void gcScanAllThreads()
3430{
3431 Thread *thread;
3432
3433 /* Lock the thread list so we can safely use the
3434 * next/prev pointers.
3435 */
3436 dvmLockThreadList(dvmThreadSelf());
3437
3438 for (thread = gDvm.threadList; thread != NULL;
3439 thread = thread->next)
3440 {
3441 /* We need to scan our own stack, so don't special-case
3442 * the current thread.
3443 */
3444 gcScanThread(thread);
3445 }
3446
3447 dvmUnlockThreadList();
3448}
3449
3450void dvmGcScanRootThreadGroups()
3451{
3452 /* We scan the VM's list of threads instead of going
3453 * through the actual ThreadGroups, but it should be
3454 * equivalent.
3455 *
3456 * This assumes that the ThreadGroup class object is in
3457 * the root set, which should always be true; it's
3458 * loaded by the built-in class loader, which is part
3459 * of the root set.
3460 */
3461 gcScanAllThreads();
3462}
3463