blob: 0751f372e1f040152e206557c2d34f6d6203bd50 [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.
969 */
970static void threadExitCheck(void* arg)
971{
972 Thread* thread = (Thread*) arg;
973
974 LOGI("In threadExitCheck %p\n", arg);
975 assert(thread != NULL);
976
977 if (thread->status != THREAD_ZOMBIE) {
978 /* TODO: instead of failing, we could call dvmDetachCurrentThread() */
979 LOGE("Native thread exited without telling us\n");
980 dvmAbort();
981 }
982}
983
984
985/*
986 * Assign the threadId. This needs to be a small integer so that our
987 * "thin" locks fit in a small number of bits.
988 *
989 * We reserve zero for use as an invalid ID.
990 *
991 * This must be called with threadListLock held (unless we're still
992 * initializing the system).
993 */
994static void assignThreadId(Thread* thread)
995{
996 /* Find a small unique integer. threadIdMap is a vector of
997 * kMaxThreadId bits; dvmAllocBit() returns the index of a
998 * bit, meaning that it will always be < kMaxThreadId.
999 *
1000 * The thin locking magic requires that the low bit is always
1001 * set, so we do it once, here.
1002 */
1003 int num = dvmAllocBit(gDvm.threadIdMap);
1004 if (num < 0) {
1005 LOGE("Ran out of thread IDs\n");
1006 dvmAbort(); // TODO: make this a non-fatal error result
1007 }
1008
1009 thread->threadId = ((num + 1) << 1) | 1;
1010
1011 assert(thread->threadId != 0);
1012 assert(thread->threadId != DVM_LOCK_INITIAL_THIN_VALUE);
1013}
1014
1015/*
1016 * Give back the thread ID.
1017 */
1018static void releaseThreadId(Thread* thread)
1019{
1020 assert(thread->threadId > 0);
1021 dvmClearBit(gDvm.threadIdMap, (thread->threadId >> 1) - 1);
1022 thread->threadId = 0;
1023}
1024
1025
1026/*
1027 * Add a stack frame that makes it look like the native code in the main
1028 * thread was originally invoked from interpreted code. This gives us a
1029 * place to hang JNI local references. The VM spec says (v2 5.2) that the
1030 * VM begins by executing "main" in a class, so in a way this brings us
1031 * closer to the spec.
1032 */
1033static bool createFakeEntryFrame(Thread* thread)
1034{
1035 assert(thread->threadId == kMainThreadId); // main thread only
1036
1037 /* find the method on first use */
1038 if (gDvm.methFakeNativeEntry == NULL) {
1039 ClassObject* nativeStart;
1040 Method* mainMeth;
1041
1042 nativeStart = dvmFindSystemClassNoInit(
1043 "Ldalvik/system/NativeStart;");
1044 if (nativeStart == NULL) {
1045 LOGE("Unable to find dalvik.system.NativeStart class\n");
1046 return false;
1047 }
1048
1049 /*
1050 * Because we are creating a frame that represents application code, we
1051 * want to stuff the application class loader into the method's class
1052 * loader field, even though we're using the system class loader to
1053 * load it. This makes life easier over in JNI FindClass (though it
1054 * could bite us in other ways).
1055 *
1056 * Unfortunately this is occurring too early in the initialization,
1057 * of necessity coming before JNI is initialized, and we're not quite
1058 * ready to set up the application class loader.
1059 *
1060 * So we save a pointer to the method in gDvm.methFakeNativeEntry
1061 * and check it in FindClass. The method is private so nobody else
1062 * can call it.
1063 */
1064 //nativeStart->classLoader = dvmGetSystemClassLoader();
1065
1066 mainMeth = dvmFindDirectMethodByDescriptor(nativeStart,
1067 "main", "([Ljava/lang/String;)V");
1068 if (mainMeth == NULL) {
1069 LOGE("Unable to find 'main' in dalvik.system.NativeStart\n");
1070 return false;
1071 }
1072
1073 gDvm.methFakeNativeEntry = mainMeth;
1074 }
1075
1076 return dvmPushJNIFrame(thread, gDvm.methFakeNativeEntry);
1077}
1078
1079
1080/*
1081 * Add a stack frame that makes it look like the native thread has been
1082 * executing interpreted code. This gives us a place to hang JNI local
1083 * references.
1084 */
1085static bool createFakeRunFrame(Thread* thread)
1086{
1087 ClassObject* nativeStart;
1088 Method* runMeth;
1089
1090 assert(thread->threadId != 1); // not for main thread
1091
1092 nativeStart =
1093 dvmFindSystemClassNoInit("Ldalvik/system/NativeStart;");
1094 if (nativeStart == NULL) {
1095 LOGE("Unable to find dalvik.system.NativeStart class\n");
1096 return false;
1097 }
1098
1099 runMeth = dvmFindVirtualMethodByDescriptor(nativeStart, "run", "()V");
1100 if (runMeth == NULL) {
1101 LOGE("Unable to find 'run' in dalvik.system.NativeStart\n");
1102 return false;
1103 }
1104
1105 return dvmPushJNIFrame(thread, runMeth);
1106}
1107
1108/*
1109 * Helper function to set the name of the current thread
1110 */
1111static void setThreadName(const char *threadName)
1112{
1113#if defined(HAVE_PRCTL)
1114 int hasAt = 0;
1115 int hasDot = 0;
1116 const char *s = threadName;
1117 while (*s) {
1118 if (*s == '.') hasDot = 1;
1119 else if (*s == '@') hasAt = 1;
1120 s++;
1121 }
1122 int len = s - threadName;
1123 if (len < 15 || hasAt || !hasDot) {
1124 s = threadName;
1125 } else {
1126 s = threadName + len - 15;
1127 }
1128 prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
1129#endif
1130}
1131
1132/*
1133 * Create a thread as a result of java.lang.Thread.start().
1134 *
1135 * We do have to worry about some concurrency problems, e.g. programs
1136 * that try to call Thread.start() on the same object from multiple threads.
1137 * (This will fail for all but one, but we have to make sure that it succeeds
1138 * for exactly one.)
1139 *
1140 * Some of the complexity here arises from our desire to mimic the
1141 * Thread vs. VMThread class decomposition we inherited. We've been given
1142 * a Thread, and now we need to create a VMThread and then populate both
1143 * objects. We also need to create one of our internal Thread objects.
1144 *
1145 * Pass in a stack size of 0 to get the default.
1146 */
1147bool dvmCreateInterpThread(Object* threadObj, int reqStackSize)
1148{
1149 pthread_attr_t threadAttr;
1150 pthread_t threadHandle;
1151 Thread* self;
1152 Thread* newThread = NULL;
1153 Object* vmThreadObj = NULL;
1154 int stackSize;
1155
1156 assert(threadObj != NULL);
1157
1158 if(gDvm.zygote) {
1159 dvmThrowException("Ljava/lang/IllegalStateException;",
1160 "No new threads in -Xzygote mode");
1161
1162 goto fail;
1163 }
1164
1165 self = dvmThreadSelf();
1166 if (reqStackSize == 0)
1167 stackSize = gDvm.stackSize;
1168 else if (reqStackSize < kMinStackSize)
1169 stackSize = kMinStackSize;
1170 else if (reqStackSize > kMaxStackSize)
1171 stackSize = kMaxStackSize;
1172 else
1173 stackSize = reqStackSize;
1174
1175 pthread_attr_init(&threadAttr);
1176 pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1177
1178 /*
1179 * To minimize the time spent in the critical section, we allocate the
1180 * vmThread object here.
1181 */
1182 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
1183 if (vmThreadObj == NULL)
1184 goto fail;
1185
1186 newThread = allocThread(stackSize);
1187 if (newThread == NULL)
1188 goto fail;
1189 newThread->threadObj = threadObj;
1190
1191 assert(newThread->status == THREAD_INITIALIZING);
1192
1193 /*
1194 * We need to lock out other threads while we test and set the
1195 * "vmThread" field in java.lang.Thread, because we use that to determine
1196 * if this thread has been started before. We use the thread list lock
1197 * because it's handy and we're going to need to grab it again soon
1198 * anyway.
1199 */
1200 dvmLockThreadList(self);
1201
1202 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1203 dvmUnlockThreadList();
1204 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1205 "thread has already been started");
1206 goto fail;
1207 }
1208
1209 /*
1210 * There are actually three data structures: Thread (object), VMThread
1211 * (object), and Thread (C struct). All of them point to at least one
1212 * other.
1213 *
1214 * As soon as "VMThread.vmData" is assigned, other threads can start
1215 * making calls into us (e.g. setPriority).
1216 */
1217 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)newThread);
1218 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1219
1220 /*
1221 * Thread creation might take a while, so release the lock.
1222 */
1223 dvmUnlockThreadList();
1224
1225 if (pthread_create(&threadHandle, &threadAttr, interpThreadStart,
1226 newThread) != 0)
1227 {
1228 /*
1229 * Failure generally indicates that we have exceeded system
1230 * resource limits. VirtualMachineError is probably too severe,
1231 * so use OutOfMemoryError.
1232 */
1233 LOGE("Thread creation failed (err=%s)\n", strerror(errno));
1234
1235 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, NULL);
1236
1237 dvmThrowException("Ljava/lang/OutOfMemoryError;",
1238 "thread creation failed");
1239 goto fail;
1240 }
1241
1242 /*
1243 * We need to wait for the thread to start. Otherwise, depending on
1244 * the whims of the OS scheduler, we could return and the code in our
1245 * thread could try to do operations on the new thread before it had
1246 * finished starting.
1247 *
1248 * The new thread will lock the thread list, change its state to
1249 * THREAD_STARTING, broadcast to gDvm.threadStartCond, and then sleep
1250 * on gDvm.threadStartCond (which uses the thread list lock). This
1251 * thread (the parent) will either see that the thread is already ready
1252 * after we grab the thread list lock, or will be awakened from the
1253 * condition variable on the broadcast.
1254 *
1255 * We don't want to stall the rest of the VM while the new thread
1256 * starts, which can happen if the GC wakes up at the wrong moment.
1257 * So, we change our own status to VMWAIT, and self-suspend if
1258 * necessary after we finish adding the new thread.
1259 *
1260 *
1261 * We have to deal with an odd race with the GC/debugger suspension
1262 * mechanism when creating a new thread. The information about whether
1263 * or not a thread should be suspended is contained entirely within
1264 * the Thread struct; this is usually cleaner to deal with than having
1265 * one or more globally-visible suspension flags. The trouble is that
1266 * we could create the thread while the VM is trying to suspend all
1267 * threads. The suspend-count won't be nonzero for the new thread,
1268 * so dvmChangeStatus(THREAD_RUNNING) won't cause a suspension.
1269 *
1270 * The easiest way to deal with this is to prevent the new thread from
1271 * running until the parent says it's okay. This results in the
1272 * following sequence of events for a "badly timed" GC:
1273 *
1274 * - call pthread_create()
1275 * - lock thread list
1276 * - put self into THREAD_VMWAIT so GC doesn't wait for us
1277 * - sleep on condition var (mutex = thread list lock) until child starts
1278 * + GC triggered by another thread
1279 * + thread list locked; suspend counts updated; thread list unlocked
1280 * + loop waiting for all runnable threads to suspend
1281 * + success, start GC
1282 * o child thread wakes, signals condition var to wake parent
1283 * o child waits for parent ack on condition variable
1284 * - we wake up, locking thread list
1285 * - add child to thread list
1286 * - unlock thread list
1287 * - change our state back to THREAD_RUNNING; GC causes us to suspend
1288 * + GC finishes; all threads in thread list are resumed
1289 * - lock thread list
1290 * - set child to THREAD_VMWAIT, and signal it to start
1291 * - unlock thread list
1292 * o child resumes
1293 * o child changes state to THREAD_RUNNING
1294 *
1295 * The above shows the GC starting up during thread creation, but if
1296 * it starts anywhere after VMThread.create() is called it will
1297 * produce the same series of events.
1298 *
1299 * Once the child is in the thread list, it will be suspended and
1300 * resumed like any other thread. In the above scenario the resume-all
1301 * code will try to resume the new thread, which was never actually
1302 * suspended, and try to decrement the child's thread suspend count to -1.
1303 * We can catch this in the resume-all code.
1304 *
1305 * Bouncing back and forth between threads like this adds a small amount
1306 * of scheduler overhead to thread startup.
1307 *
1308 * One alternative to having the child wait for the parent would be
1309 * to have the child inherit the parents' suspension count. This
1310 * would work for a GC, since we can safely assume that the parent
1311 * thread didn't cause it, but we must only do so if the parent suspension
1312 * was caused by a suspend-all. If the parent was being asked to
1313 * suspend singly by the debugger, the child should not inherit the value.
1314 *
1315 * We could also have a global "new thread suspend count" that gets
1316 * picked up by new threads before changing state to THREAD_RUNNING.
1317 * This would be protected by the thread list lock and set by a
1318 * suspend-all.
1319 */
1320 dvmLockThreadList(self);
1321 assert(self->status == THREAD_RUNNING);
1322 self->status = THREAD_VMWAIT;
1323 while (newThread->status != THREAD_STARTING)
1324 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1325
1326 LOG_THREAD("threadid=%d: adding to list\n", newThread->threadId);
1327 newThread->next = gDvm.threadList->next;
1328 if (newThread->next != NULL)
1329 newThread->next->prev = newThread;
1330 newThread->prev = gDvm.threadList;
1331 gDvm.threadList->next = newThread;
1332
1333 if (!dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon))
1334 gDvm.nonDaemonThreadCount++; // guarded by thread list lock
1335
1336 dvmUnlockThreadList();
1337
1338 /* change status back to RUNNING, self-suspending if necessary */
1339 dvmChangeStatus(self, THREAD_RUNNING);
1340
1341 /*
1342 * Tell the new thread to start.
1343 *
1344 * We must hold the thread list lock before messing with another thread.
1345 * In the general case we would also need to verify that newThread was
1346 * still in the thread list, but in our case the thread has not started
1347 * executing user code and therefore has not had a chance to exit.
1348 *
1349 * We move it to VMWAIT, and it then shifts itself to RUNNING, which
1350 * comes with a suspend-pending check.
1351 */
1352 dvmLockThreadList(self);
1353
1354 assert(newThread->status == THREAD_STARTING);
1355 newThread->status = THREAD_VMWAIT;
1356 pthread_cond_broadcast(&gDvm.threadStartCond);
1357
1358 dvmUnlockThreadList();
1359
1360 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1361 return true;
1362
1363fail:
1364 freeThread(newThread);
1365 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1366 return false;
1367}
1368
1369/*
1370 * pthread entry function for threads started from interpreted code.
1371 */
1372static void* interpThreadStart(void* arg)
1373{
1374 Thread* self = (Thread*) arg;
1375
1376 char *threadName = dvmGetThreadName(self);
1377 setThreadName(threadName);
1378 free(threadName);
1379
1380 /*
1381 * Finish initializing the Thread struct.
1382 */
1383 prepareThread(self);
1384
1385 LOG_THREAD("threadid=%d: created from interp\n", self->threadId);
1386
1387 /*
1388 * Change our status and wake our parent, who will add us to the
1389 * thread list and advance our state to VMWAIT.
1390 */
1391 dvmLockThreadList(self);
1392 self->status = THREAD_STARTING;
1393 pthread_cond_broadcast(&gDvm.threadStartCond);
1394
1395 /*
1396 * Wait until the parent says we can go. Assuming there wasn't a
1397 * suspend pending, this will happen immediately. When it completes,
1398 * we're full-fledged citizens of the VM.
1399 *
1400 * We have to use THREAD_VMWAIT here rather than THREAD_RUNNING
1401 * because the pthread_cond_wait below needs to reacquire a lock that
1402 * suspend-all is also interested in. If we get unlucky, the parent could
1403 * change us to THREAD_RUNNING, then a GC could start before we get
1404 * signaled, and suspend-all will grab the thread list lock and then
1405 * wait for us to suspend. We'll be in the tail end of pthread_cond_wait
1406 * trying to get the lock.
1407 */
1408 while (self->status != THREAD_VMWAIT)
1409 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1410
1411 dvmUnlockThreadList();
1412
1413 /*
1414 * Add a JNI context.
1415 */
1416 self->jniEnv = dvmCreateJNIEnv(self);
1417
1418 /*
1419 * Change our state so the GC will wait for us from now on. If a GC is
1420 * in progress this call will suspend us.
1421 */
1422 dvmChangeStatus(self, THREAD_RUNNING);
1423
1424 /*
1425 * Notify the debugger & DDM. The debugger notification may cause
1426 * us to suspend ourselves (and others).
1427 */
1428 if (gDvm.debuggerConnected)
1429 dvmDbgPostThreadStart(self);
1430
1431 /*
1432 * Set the system thread priority according to the Thread object's
1433 * priority level. We don't usually need to do this, because both the
1434 * Thread object and system thread priorities inherit from parents. The
1435 * tricky case is when somebody creates a Thread object, calls
1436 * setPriority(), and then starts the thread. We could manage this with
1437 * a "needs priority update" flag to avoid the redundant call.
1438 */
1439 int priority = dvmGetFieldBoolean(self->threadObj,
1440 gDvm.offJavaLangThread_priority);
1441 dvmChangeThreadPriority(self, priority);
1442
1443 /*
1444 * Execute the "run" method.
1445 *
1446 * At this point our stack is empty, so somebody who comes looking for
1447 * stack traces right now won't have much to look at. This is normal.
1448 */
1449 Method* run = self->threadObj->clazz->vtable[gDvm.voffJavaLangThread_run];
1450 JValue unused;
1451
1452 LOGV("threadid=%d: calling run()\n", self->threadId);
1453 assert(strcmp(run->name, "run") == 0);
1454 dvmCallMethod(self, run, self->threadObj, &unused);
1455 LOGV("threadid=%d: exiting\n", self->threadId);
1456
1457 /*
1458 * Remove the thread from various lists, report its death, and free
1459 * its resources.
1460 */
1461 dvmDetachCurrentThread();
1462
1463 return NULL;
1464}
1465
1466/*
1467 * The current thread is exiting with an uncaught exception. The
1468 * Java programming language allows the application to provide a
1469 * thread-exit-uncaught-exception handler for the VM, for a specific
1470 * Thread, and for all threads in a ThreadGroup.
1471 *
1472 * Version 1.5 added the per-thread handler. We need to call
1473 * "uncaughtException" in the handler object, which is either the
1474 * ThreadGroup object or the Thread-specific handler.
1475 */
1476static void threadExitUncaughtException(Thread* self, Object* group)
1477{
1478 Object* exception;
1479 Object* handlerObj;
1480 ClassObject* throwable;
1481 Method* uncaughtHandler = NULL;
1482 InstField* threadHandler;
1483
1484 LOGW("threadid=%d: thread exiting with uncaught exception (group=%p)\n",
1485 self->threadId, group);
1486 assert(group != NULL);
1487
1488 /*
1489 * Get a pointer to the exception, then clear out the one in the
1490 * thread. We don't want to have it set when executing interpreted code.
1491 */
1492 exception = dvmGetException(self);
1493 dvmAddTrackedAlloc(exception, self);
1494 dvmClearException(self);
1495
1496 /*
1497 * Get the Thread's "uncaughtHandler" object. Use it if non-NULL;
1498 * else use "group" (which is an instance of UncaughtExceptionHandler).
1499 */
1500 threadHandler = dvmFindInstanceField(gDvm.classJavaLangThread,
1501 "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
1502 if (threadHandler == NULL) {
1503 LOGW("WARNING: no 'uncaughtHandler' field in java/lang/Thread\n");
1504 goto bail;
1505 }
1506 handlerObj = dvmGetFieldObject(self->threadObj, threadHandler->byteOffset);
1507 if (handlerObj == NULL)
1508 handlerObj = group;
1509
1510 /*
1511 * Find the "uncaughtHandler" field in this object.
1512 */
1513 uncaughtHandler = dvmFindVirtualMethodHierByDescriptor(handlerObj->clazz,
1514 "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
1515
1516 if (uncaughtHandler != NULL) {
1517 //LOGI("+++ calling %s.uncaughtException\n",
1518 // handlerObj->clazz->descriptor);
1519 JValue unused;
1520 dvmCallMethod(self, uncaughtHandler, handlerObj, &unused,
1521 self->threadObj, exception);
1522 } else {
1523 /* restore it and dump a stack trace */
1524 LOGW("WARNING: no 'uncaughtException' method in class %s\n",
1525 handlerObj->clazz->descriptor);
1526 dvmSetException(self, exception);
1527 dvmLogExceptionStackTrace();
1528 }
1529
1530bail:
1531 dvmReleaseTrackedAlloc(exception, self);
1532}
1533
1534
1535/*
1536 * Create an internal VM thread, for things like JDWP and finalizers.
1537 *
1538 * The easiest way to do this is create a new thread and then use the
1539 * JNI AttachCurrentThread implementation.
1540 *
1541 * This does not return until after the new thread has begun executing.
1542 */
1543bool dvmCreateInternalThread(pthread_t* pHandle, const char* name,
1544 InternalThreadStart func, void* funcArg)
1545{
1546 InternalStartArgs* pArgs;
1547 Object* systemGroup;
1548 pthread_attr_t threadAttr;
1549 volatile Thread* newThread = NULL;
1550 volatile int createStatus = 0;
1551
1552 systemGroup = dvmGetSystemThreadGroup();
1553 if (systemGroup == NULL)
1554 return false;
1555
1556 pArgs = (InternalStartArgs*) malloc(sizeof(*pArgs));
1557 pArgs->func = func;
1558 pArgs->funcArg = funcArg;
1559 pArgs->name = strdup(name); // storage will be owned by new thread
1560 pArgs->group = systemGroup;
1561 pArgs->isDaemon = true;
1562 pArgs->pThread = &newThread;
1563 pArgs->pCreateStatus = &createStatus;
1564
1565 pthread_attr_init(&threadAttr);
1566 //pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1567
1568 if (pthread_create(pHandle, &threadAttr, internalThreadStart,
1569 pArgs) != 0)
1570 {
1571 LOGE("internal thread creation failed\n");
1572 free(pArgs->name);
1573 free(pArgs);
1574 return false;
1575 }
1576
1577 /*
1578 * Wait for the child to start. This gives us an opportunity to make
1579 * sure that the thread started correctly, and allows our caller to
1580 * assume that the thread has started running.
1581 *
1582 * Because we aren't holding a lock across the thread creation, it's
1583 * possible that the child will already have completed its
1584 * initialization. Because the child only adjusts "createStatus" while
1585 * holding the thread list lock, the initial condition on the "while"
1586 * loop will correctly avoid the wait if this occurs.
1587 *
1588 * It's also possible that we'll have to wait for the thread to finish
1589 * being created, and as part of allocating a Thread object it might
1590 * need to initiate a GC. We switch to VMWAIT while we pause.
1591 */
1592 Thread* self = dvmThreadSelf();
1593 int oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1594 dvmLockThreadList(self);
1595 while (createStatus == 0)
1596 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1597
1598 if (newThread == NULL) {
1599 LOGW("internal thread create failed (createStatus=%d)\n", createStatus);
1600 assert(createStatus < 0);
1601 /* don't free pArgs -- if pthread_create succeeded, child owns it */
1602 dvmUnlockThreadList();
1603 dvmChangeStatus(self, oldStatus);
1604 return false;
1605 }
1606
1607 /* thread could be in any state now (except early init states) */
1608 //assert(newThread->status == THREAD_RUNNING);
1609
1610 dvmUnlockThreadList();
1611 dvmChangeStatus(self, oldStatus);
1612
1613 return true;
1614}
1615
1616/*
1617 * pthread entry function for internally-created threads.
1618 *
1619 * We are expected to free "arg" and its contents. If we're a daemon
1620 * thread, and we get cancelled abruptly when the VM shuts down, the
1621 * storage won't be freed. If this becomes a concern we can make a copy
1622 * on the stack.
1623 */
1624static void* internalThreadStart(void* arg)
1625{
1626 InternalStartArgs* pArgs = (InternalStartArgs*) arg;
1627 JavaVMAttachArgs jniArgs;
1628
1629 jniArgs.version = JNI_VERSION_1_2;
1630 jniArgs.name = pArgs->name;
1631 jniArgs.group = pArgs->group;
1632
1633 setThreadName(pArgs->name);
1634
1635 /* use local jniArgs as stack top */
1636 if (dvmAttachCurrentThread(&jniArgs, pArgs->isDaemon)) {
1637 /*
1638 * Tell the parent of our success.
1639 *
1640 * threadListLock is the mutex for threadStartCond.
1641 */
1642 dvmLockThreadList(dvmThreadSelf());
1643 *pArgs->pCreateStatus = 1;
1644 *pArgs->pThread = dvmThreadSelf();
1645 pthread_cond_broadcast(&gDvm.threadStartCond);
1646 dvmUnlockThreadList();
1647
1648 LOG_THREAD("threadid=%d: internal '%s'\n",
1649 dvmThreadSelf()->threadId, pArgs->name);
1650
1651 /* execute */
1652 (*pArgs->func)(pArgs->funcArg);
1653
1654 /* detach ourselves */
1655 dvmDetachCurrentThread();
1656 } else {
1657 /*
1658 * Tell the parent of our failure. We don't have a Thread struct,
1659 * so we can't be suspended, so we don't need to enter a critical
1660 * section.
1661 */
1662 dvmLockThreadList(dvmThreadSelf());
1663 *pArgs->pCreateStatus = -1;
1664 assert(*pArgs->pThread == NULL);
1665 pthread_cond_broadcast(&gDvm.threadStartCond);
1666 dvmUnlockThreadList();
1667
1668 assert(*pArgs->pThread == NULL);
1669 }
1670
1671 free(pArgs->name);
1672 free(pArgs);
1673 return NULL;
1674}
1675
1676/*
1677 * Attach the current thread to the VM.
1678 *
1679 * Used for internally-created threads and JNI's AttachCurrentThread.
1680 */
1681bool dvmAttachCurrentThread(const JavaVMAttachArgs* pArgs, bool isDaemon)
1682{
1683 Thread* self = NULL;
1684 Object* threadObj = NULL;
1685 Object* vmThreadObj = NULL;
1686 StringObject* threadNameStr = NULL;
1687 Method* init;
1688 bool ok, ret;
1689
1690 /* establish a basic sense of self */
1691 self = allocThread(gDvm.stackSize);
1692 if (self == NULL)
1693 goto fail;
1694 setThreadSelf(self);
1695
1696 /*
1697 * Create Thread and VMThread objects. We have to use ALLOC_NO_GC
1698 * because this thread is not yet visible to the VM. We could also
1699 * just grab the GC lock earlier, but that leaves us executing
1700 * interpreted code with the lock held, which is not prudent.
1701 *
1702 * The alloc calls will block if a GC is in progress, so we don't need
1703 * to check for global suspension here.
1704 *
1705 * It's also possible for the allocation calls to *cause* a GC.
1706 */
1707 //BUG: deadlock if a GC happens here during HeapWorker creation
1708 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_NO_GC);
1709 if (threadObj == NULL)
1710 goto fail;
1711 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_NO_GC);
1712 if (vmThreadObj == NULL)
1713 goto fail;
1714
1715 self->threadObj = threadObj;
1716 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)self);
1717
1718 /*
1719 * Do some java.lang.Thread constructor prep before we lock stuff down.
1720 */
1721 if (pArgs->name != NULL) {
1722 threadNameStr = dvmCreateStringFromCstr(pArgs->name, ALLOC_NO_GC);
1723 if (threadNameStr == NULL) {
1724 assert(dvmCheckException(dvmThreadSelf()));
1725 goto fail;
1726 }
1727 }
1728
1729 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
1730 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
1731 if (init == NULL) {
1732 assert(dvmCheckException(dvmThreadSelf()));
1733 goto fail;
1734 }
1735
1736 /*
1737 * Finish our thread prep. We need to do this before invoking any
1738 * interpreted code. prepareThread() requires that we hold the thread
1739 * list lock.
1740 */
1741 dvmLockThreadList(self);
1742 ok = prepareThread(self);
1743 dvmUnlockThreadList();
1744 if (!ok)
1745 goto fail;
1746
1747 self->jniEnv = dvmCreateJNIEnv(self);
1748 if (self->jniEnv == NULL)
1749 goto fail;
1750
1751 /*
1752 * Create a "fake" JNI frame at the top of the main thread interp stack.
1753 * It isn't really necessary for the internal threads, but it gives
1754 * the debugger something to show. It is essential for the JNI-attached
1755 * threads.
1756 */
1757 if (!createFakeRunFrame(self))
1758 goto fail;
1759
1760 /*
1761 * The native side of the thread is ready; add it to the list.
1762 */
1763 LOG_THREAD("threadid=%d: adding to list (attached)\n", self->threadId);
1764
1765 /* Start off in VMWAIT, because we may be about to block
1766 * on the heap lock, and we don't want any suspensions
1767 * to wait for us.
1768 */
1769 self->status = THREAD_VMWAIT;
1770
1771 /*
1772 * Add ourselves to the thread list. Once we finish here we are
1773 * visible to the debugger and the GC.
1774 */
1775 dvmLockThreadList(self);
1776
1777 self->next = gDvm.threadList->next;
1778 if (self->next != NULL)
1779 self->next->prev = self;
1780 self->prev = gDvm.threadList;
1781 gDvm.threadList->next = self;
1782 if (!isDaemon)
1783 gDvm.nonDaemonThreadCount++;
1784
1785 dvmUnlockThreadList();
1786
1787 /*
1788 * It's possible that a GC is currently running. Our thread
1789 * wasn't in the list when the GC started, so it's not properly
1790 * suspended in that case. Synchronize on the heap lock (held
1791 * when a GC is happening) to guarantee that any GCs from here
1792 * on will see this thread in the list.
1793 */
1794 dvmLockMutex(&gDvm.gcHeapLock);
1795 dvmUnlockMutex(&gDvm.gcHeapLock);
1796
1797 /*
1798 * Switch to the running state now that we're ready for
1799 * suspensions. This call may suspend.
1800 */
1801 dvmChangeStatus(self, THREAD_RUNNING);
1802
1803 /*
1804 * Now we're ready to run some interpreted code.
1805 *
1806 * We need to construct the Thread object and set the VMThread field.
1807 * Setting VMThread tells interpreted code that we're alive.
1808 *
1809 * Call the (group, name, priority, daemon) constructor on the Thread.
1810 * This sets the thread's name and adds it to the specified group, and
1811 * provides values for priority and daemon (which are normally inherited
1812 * from the current thread).
1813 */
1814 JValue unused;
1815 dvmCallMethod(self, init, threadObj, &unused, (Object*)pArgs->group,
1816 threadNameStr, getThreadPriorityFromSystem(), isDaemon);
1817 if (dvmCheckException(self)) {
1818 LOGE("exception thrown while constructing attached thread object\n");
1819 goto fail_unlink;
1820 }
1821 //if (isDaemon)
1822 // dvmSetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon, true);
1823
1824 /*
1825 * Set the VMThread field, which tells interpreted code that we're alive.
1826 *
1827 * The risk of a thread start collision here is very low; somebody
1828 * would have to be deliberately polling the ThreadGroup list and
1829 * trying to start threads against anything it sees, which would
1830 * generally cause problems for all thread creation. However, for
1831 * correctness we test "vmThread" before setting it.
1832 */
1833 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1834 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1835 "thread has already been started");
1836 /* We don't want to free anything associated with the thread
1837 * because someone is obviously interested in it. Just let
1838 * it go and hope it will clean itself up when its finished.
1839 * This case should never happen anyway.
1840 *
1841 * Since we're letting it live, we need to finish setting it up.
1842 * We just have to let the caller know that the intended operation
1843 * has failed.
1844 *
1845 * [ This seems strange -- stepping on the vmThread object that's
1846 * already present seems like a bad idea. TODO: figure this out. ]
1847 */
1848 ret = false;
1849 } else
1850 ret = true;
1851 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1852
1853 /* These are now reachable from the thread groups. */
1854 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
1855 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
1856
1857 /*
1858 * The thread is ready to go; let the debugger see it.
1859 */
1860 self->threadObj = threadObj;
1861
1862 LOG_THREAD("threadid=%d: attached from native, name=%s\n",
1863 self->threadId, pArgs->name);
1864
1865 /* tell the debugger & DDM */
1866 if (gDvm.debuggerConnected)
1867 dvmDbgPostThreadStart(self);
1868
1869 return ret;
1870
1871fail_unlink:
1872 dvmLockThreadList(self);
1873 unlinkThread(self);
1874 if (!isDaemon)
1875 gDvm.nonDaemonThreadCount--;
1876 dvmUnlockThreadList();
1877 /* fall through to "fail" */
1878fail:
1879 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
1880 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
1881 if (self != NULL) {
1882 if (self->jniEnv != NULL) {
1883 dvmDestroyJNIEnv(self->jniEnv);
1884 self->jniEnv = NULL;
1885 }
1886 freeThread(self);
1887 }
1888 setThreadSelf(NULL);
1889 return false;
1890}
1891
1892/*
1893 * Detach the thread from the various data structures, notify other threads
1894 * that are waiting to "join" it, and free up all heap-allocated storage.
1895 *
1896 * Used for all threads.
1897 *
1898 * When we get here the interpreted stack should be empty. The JNI 1.6 spec
1899 * requires us to enforce this for the DetachCurrentThread call, probably
1900 * because it also says that DetachCurrentThread causes all monitors
1901 * associated with the thread to be released. (Because the stack is empty,
1902 * we only have to worry about explicit JNI calls to MonitorEnter.)
1903 *
1904 * THOUGHT:
1905 * We might want to avoid freeing our internal Thread structure until the
1906 * associated Thread/VMThread objects get GCed. Our Thread is impossible to
1907 * get to once the thread shuts down, but there is a small possibility of
1908 * an operation starting in another thread before this thread halts, and
1909 * finishing much later (perhaps the thread got stalled by a weird OS bug).
1910 * We don't want something like Thread.isInterrupted() crawling through
1911 * freed storage. Can do with a Thread finalizer, or by creating a
1912 * dedicated ThreadObject class for java/lang/Thread and moving all of our
1913 * state into that.
1914 */
1915void dvmDetachCurrentThread(void)
1916{
1917 Thread* self = dvmThreadSelf();
1918 Object* vmThread;
1919 Object* group;
1920
1921 /*
1922 * Make sure we're not detaching a thread that's still running. (This
1923 * could happen with an explicit JNI detach call.)
1924 *
1925 * A thread created by interpreted code will finish with a depth of
1926 * zero, while a JNI-attached thread will have the synthetic "stack
1927 * starter" native method at the top.
1928 */
1929 int curDepth = dvmComputeExactFrameDepth(self->curFrame);
1930 if (curDepth != 0) {
1931 bool topIsNative = false;
1932
1933 if (curDepth == 1) {
1934 /* not expecting a lingering break frame; just look at curFrame */
1935 assert(!dvmIsBreakFrame(self->curFrame));
1936 StackSaveArea* ssa = SAVEAREA_FROM_FP(self->curFrame);
1937 if (dvmIsNativeMethod(ssa->method))
1938 topIsNative = true;
1939 }
1940
1941 if (!topIsNative) {
1942 LOGE("ERROR: detaching thread with interp frames (count=%d)\n",
1943 curDepth);
1944 dvmDumpThread(self, false);
1945 dvmAbort();
1946 }
1947 }
1948
1949 group = dvmGetFieldObject(self->threadObj, gDvm.offJavaLangThread_group);
1950 LOG_THREAD("threadid=%d: detach (group=%p)\n", self->threadId, group);
1951
1952 /*
1953 * Release any held monitors. Since there are no interpreted stack
1954 * frames, the only thing left are the monitors held by JNI MonitorEnter
1955 * calls.
1956 */
1957 dvmReleaseJniMonitors(self);
1958
1959 /*
1960 * Do some thread-exit uncaught exception processing if necessary.
1961 */
1962 if (dvmCheckException(self))
1963 threadExitUncaughtException(self, group);
1964
1965 /*
1966 * Remove the thread from the thread group.
1967 */
1968 if (group != NULL) {
1969 Method* removeThread =
1970 group->clazz->vtable[gDvm.voffJavaLangThreadGroup_removeThread];
1971 JValue unused;
1972 dvmCallMethod(self, removeThread, group, &unused, self->threadObj);
1973 }
1974
1975 /*
1976 * Clear the vmThread reference in the Thread object. Interpreted code
1977 * will now see that this Thread is not running. As this may be the
1978 * only reference to the VMThread object that the VM knows about, we
1979 * have to create an internal reference to it first.
1980 */
1981 vmThread = dvmGetFieldObject(self->threadObj,
1982 gDvm.offJavaLangThread_vmThread);
1983 dvmAddTrackedAlloc(vmThread, self);
1984 dvmSetFieldObject(self->threadObj, gDvm.offJavaLangThread_vmThread, NULL);
1985
1986 /* clear out our struct Thread pointer, since it's going away */
1987 dvmSetFieldObject(vmThread, gDvm.offJavaLangVMThread_vmData, NULL);
1988
1989 /*
1990 * Tell the debugger & DDM. This may cause the current thread or all
1991 * threads to suspend.
1992 *
1993 * The JDWP spec is somewhat vague about when this happens, other than
1994 * that it's issued by the dying thread, which may still appear in
1995 * an "all threads" listing.
1996 */
1997 if (gDvm.debuggerConnected)
1998 dvmDbgPostThreadDeath(self);
1999
2000 /*
2001 * Thread.join() is implemented as an Object.wait() on the VMThread
2002 * object. Signal anyone who is waiting.
2003 */
2004 dvmLockObject(self, vmThread);
2005 dvmObjectNotifyAll(self, vmThread);
2006 dvmUnlockObject(self, vmThread);
2007
2008 dvmReleaseTrackedAlloc(vmThread, self);
2009 vmThread = NULL;
2010
2011 /*
2012 * We're done manipulating objects, so it's okay if the GC runs in
2013 * parallel with us from here out. It's important to do this if
2014 * profiling is enabled, since we can wait indefinitely.
2015 */
2016 self->status = THREAD_VMWAIT;
2017
2018#ifdef WITH_PROFILER
2019 /*
2020 * If we're doing method trace profiling, we don't want threads to exit,
2021 * because if they do we'll end up reusing thread IDs. This complicates
2022 * analysis and makes it impossible to have reasonable output in the
2023 * "threads" section of the "key" file.
2024 *
2025 * We need to do this after Thread.join() completes, or other threads
2026 * could get wedged. Since self->threadObj is still valid, the Thread
2027 * object will not get GCed even though we're no longer in the ThreadGroup
2028 * list (which is important since the profiling thread needs to get
2029 * the thread's name).
2030 */
2031 MethodTraceState* traceState = &gDvm.methodTrace;
2032
2033 dvmLockMutex(&traceState->startStopLock);
2034 if (traceState->traceEnabled) {
2035 LOGI("threadid=%d: waiting for method trace to finish\n",
2036 self->threadId);
2037 while (traceState->traceEnabled) {
2038 int cc;
2039 cc = pthread_cond_wait(&traceState->threadExitCond,
2040 &traceState->startStopLock);
2041 assert(cc == 0);
2042 }
2043 }
2044 dvmUnlockMutex(&traceState->startStopLock);
2045#endif
2046
2047 dvmLockThreadList(self);
2048
2049 /*
2050 * Lose the JNI context.
2051 */
2052 dvmDestroyJNIEnv(self->jniEnv);
2053 self->jniEnv = NULL;
2054
2055 self->status = THREAD_ZOMBIE;
2056
2057 /*
2058 * Remove ourselves from the internal thread list.
2059 */
2060 unlinkThread(self);
2061
2062 /*
2063 * If we're the last one standing, signal anybody waiting in
2064 * DestroyJavaVM that it's okay to exit.
2065 */
2066 if (!dvmGetFieldBoolean(self->threadObj, gDvm.offJavaLangThread_daemon)) {
2067 gDvm.nonDaemonThreadCount--; // guarded by thread list lock
2068
2069 if (gDvm.nonDaemonThreadCount == 0) {
2070 int cc;
2071
2072 LOGV("threadid=%d: last non-daemon thread\n", self->threadId);
2073 //dvmDumpAllThreads(false);
2074 // cond var guarded by threadListLock, which we already hold
2075 cc = pthread_cond_signal(&gDvm.vmExitCond);
2076 assert(cc == 0);
2077 }
2078 }
2079
2080 LOGV("threadid=%d: bye!\n", self->threadId);
2081 releaseThreadId(self);
2082 dvmUnlockThreadList();
2083
2084 setThreadSelf(NULL);
2085 freeThread(self);
2086}
2087
2088
2089/*
2090 * Suspend a single thread. Do not use to suspend yourself.
2091 *
2092 * This is used primarily for debugger/DDMS activity. Does not return
2093 * until the thread has suspended or is in a "safe" state (e.g. executing
2094 * native code outside the VM).
2095 *
2096 * The thread list lock should be held before calling here -- it's not
2097 * entirely safe to hang on to a Thread* from another thread otherwise.
2098 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2099 */
2100void dvmSuspendThread(Thread* thread)
2101{
2102 assert(thread != NULL);
2103 assert(thread != dvmThreadSelf());
2104 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2105
2106 lockThreadSuspendCount();
2107 thread->suspendCount++;
2108 thread->dbgSuspendCount++;
2109
2110 LOG_THREAD("threadid=%d: suspend++, now=%d\n",
2111 thread->threadId, thread->suspendCount);
2112 unlockThreadSuspendCount();
2113
2114 waitForThreadSuspend(dvmThreadSelf(), thread);
2115}
2116
2117/*
2118 * Reduce the suspend count of a thread. If it hits zero, tell it to
2119 * resume.
2120 *
2121 * Used primarily for debugger/DDMS activity. The thread in question
2122 * might have been suspended singly or as part of a suspend-all operation.
2123 *
2124 * The thread list lock should be held before calling here -- it's not
2125 * entirely safe to hang on to a Thread* from another thread otherwise.
2126 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2127 */
2128void dvmResumeThread(Thread* thread)
2129{
2130 assert(thread != NULL);
2131 assert(thread != dvmThreadSelf());
2132 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2133
2134 lockThreadSuspendCount();
2135 if (thread->suspendCount > 0) {
2136 thread->suspendCount--;
2137 thread->dbgSuspendCount--;
2138 } else {
2139 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2140 thread->threadId);
2141 }
2142
2143 LOG_THREAD("threadid=%d: suspend--, now=%d\n",
2144 thread->threadId, thread->suspendCount);
2145
2146 if (thread->suspendCount == 0) {
2147 int cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2148 assert(cc == 0);
2149 }
2150
2151 unlockThreadSuspendCount();
2152}
2153
2154/*
2155 * Suspend yourself, as a result of debugger activity.
2156 */
2157void dvmSuspendSelf(bool jdwpActivity)
2158{
2159 Thread* self = dvmThreadSelf();
2160
2161 /* debugger thread may not suspend itself due to debugger activity! */
2162 assert(gDvm.jdwpState != NULL);
2163 if (self->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2164 assert(false);
2165 return;
2166 }
2167
2168 /*
2169 * Collisions with other suspends aren't really interesting. We want
2170 * to ensure that we're the only one fiddling with the suspend count
2171 * though.
2172 */
2173 lockThreadSuspendCount();
2174 self->suspendCount++;
2175 self->dbgSuspendCount++;
2176
2177 /*
2178 * Suspend ourselves.
2179 */
2180 assert(self->suspendCount > 0);
2181 self->isSuspended = true;
2182 LOG_THREAD("threadid=%d: self-suspending (dbg)\n", self->threadId);
2183
2184 /*
2185 * Tell JDWP that we've completed suspension. The JDWP thread can't
2186 * tell us to resume before we're fully asleep because we hold the
2187 * suspend count lock.
2188 *
2189 * If we got here via waitForDebugger(), don't do this part.
2190 */
2191 if (jdwpActivity) {
2192 //LOGI("threadid=%d: clearing wait-for-event (my handle=%08x)\n",
2193 // self->threadId, (int) self->handle);
2194 dvmJdwpClearWaitForEventThread(gDvm.jdwpState);
2195 }
2196
2197 while (self->suspendCount != 0) {
2198 int cc;
2199 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2200 &gDvm.threadSuspendCountLock);
2201 assert(cc == 0);
2202 if (self->suspendCount != 0) {
The Android Open Source Project99409882009-03-18 22:20:24 -07002203 /*
2204 * The condition was signaled but we're still suspended. This
2205 * can happen if the debugger lets go while a SIGQUIT thread
2206 * dump event is pending (assuming SignalCatcher was resumed for
2207 * just long enough to try to grab the thread-suspend lock).
2208 */
2209 LOGD("threadid=%d: still suspended after undo (sc=%d dc=%d s=%c)\n",
2210 self->threadId, self->suspendCount, self->dbgSuspendCount,
2211 self->isSuspended ? 'Y' : 'N');
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002212 }
2213 }
2214 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2215 self->isSuspended = false;
2216 LOG_THREAD("threadid=%d: self-reviving (dbg), status=%d\n",
2217 self->threadId, self->status);
2218
2219 unlockThreadSuspendCount();
2220}
2221
2222
2223#ifdef HAVE_GLIBC
2224# define NUM_FRAMES 20
2225# include <execinfo.h>
2226/*
2227 * glibc-only stack dump function. Requires link with "--export-dynamic".
2228 *
2229 * TODO: move this into libs/cutils and make it work for all platforms.
2230 */
2231static void printBackTrace(void)
2232{
2233 void* array[NUM_FRAMES];
2234 size_t size;
2235 char** strings;
2236 size_t i;
2237
2238 size = backtrace(array, NUM_FRAMES);
2239 strings = backtrace_symbols(array, size);
2240
2241 LOGW("Obtained %zd stack frames.\n", size);
2242
2243 for (i = 0; i < size; i++)
2244 LOGW("%s\n", strings[i]);
2245
2246 free(strings);
2247}
2248#else
2249static void printBackTrace(void) {}
2250#endif
2251
2252/*
2253 * Dump the state of the current thread and that of another thread that
2254 * we think is wedged.
2255 */
2256static void dumpWedgedThread(Thread* thread)
2257{
2258 char exePath[1024];
2259
2260 /*
2261 * The "executablepath" function in libutils is host-side only.
2262 */
2263 strcpy(exePath, "-");
2264#ifdef HAVE_GLIBC
2265 {
2266 char proc[100];
2267 sprintf(proc, "/proc/%d/exe", getpid());
2268 int len;
2269
2270 len = readlink(proc, exePath, sizeof(exePath)-1);
2271 exePath[len] = '\0';
2272 }
2273#endif
2274
2275 LOGW("dumping state: process %s %d\n", exePath, getpid());
2276 dvmDumpThread(dvmThreadSelf(), false);
2277 printBackTrace();
2278
2279 // dumping a running thread is risky, but could be useful
2280 dvmDumpThread(thread, true);
2281
2282
2283 // stop now and get a core dump
2284 //abort();
2285}
2286
2287
2288/*
2289 * Wait for another thread to see the pending suspension and stop running.
2290 * It can either suspend itself or go into a non-running state such as
2291 * VMWAIT or NATIVE in which it cannot interact with the GC.
2292 *
2293 * If we're running at a higher priority, sched_yield() may not do anything,
2294 * so we need to sleep for "long enough" to guarantee that the other
2295 * thread has a chance to finish what it's doing. Sleeping for too short
2296 * a period (e.g. less than the resolution of the sleep clock) might cause
2297 * the scheduler to return immediately, so we want to start with a
2298 * "reasonable" value and expand.
2299 *
2300 * This does not return until the other thread has stopped running.
2301 * Eventually we time out and the VM aborts.
2302 *
2303 * This does not try to detect the situation where two threads are
2304 * waiting for each other to suspend. In normal use this is part of a
2305 * suspend-all, which implies that the suspend-all lock is held, or as
2306 * part of a debugger action in which the JDWP thread is always the one
2307 * doing the suspending. (We may need to re-evaluate this now that
2308 * getThreadStackTrace is implemented as suspend-snapshot-resume.)
2309 *
2310 * TODO: track basic stats about time required to suspend VM.
2311 */
2312static void waitForThreadSuspend(Thread* self, Thread* thread)
2313{
2314 const int kMaxRetries = 10;
2315 const int kSpinSleepTime = 750*1000; /* 0.75s */
2316
2317 int sleepIter = 0;
2318 int retryCount = 0;
2319 u8 startWhen = 0; // init req'd to placate gcc
2320
2321 while (thread->status == THREAD_RUNNING && !thread->isSuspended) {
2322 if (sleepIter == 0) // get current time on first iteration
2323 startWhen = dvmGetRelativeTimeUsec();
2324
2325 if (!dvmIterativeSleep(sleepIter++, kSpinSleepTime, startWhen)) {
2326 LOGW("threadid=%d (h=%d): spin on suspend threadid=%d (handle=%d)\n",
2327 self->threadId, (int)self->handle,
2328 thread->threadId, (int)thread->handle);
2329 dumpWedgedThread(thread);
2330
2331 // keep going; could be slow due to valgrind
2332 sleepIter = 0;
2333
2334 if (retryCount++ == kMaxRetries) {
2335 LOGE("threadid=%d: stuck on threadid=%d, giving up\n",
2336 self->threadId, thread->threadId);
2337 dvmDumpAllThreads(false);
2338 dvmAbort();
2339 }
2340 }
2341 }
2342}
2343
2344/*
2345 * Suspend all threads except the current one. This is used by the GC,
2346 * the debugger, and by any thread that hits a "suspend all threads"
2347 * debugger event (e.g. breakpoint or exception).
2348 *
2349 * If thread N hits a "suspend all threads" breakpoint, we don't want it
2350 * to suspend the JDWP thread. For the GC, we do, because the debugger can
2351 * create objects and even execute arbitrary code. The "why" argument
2352 * allows the caller to say why the suspension is taking place.
2353 *
2354 * This can be called when a global suspend has already happened, due to
2355 * various debugger gymnastics, so keeping an "everybody is suspended" flag
2356 * doesn't work.
2357 *
2358 * DO NOT grab any locks before calling here. We grab & release the thread
2359 * lock and suspend lock here (and we're not using recursive threads), and
2360 * we might have to self-suspend if somebody else beats us here.
2361 *
2362 * The current thread may not be attached to the VM. This can happen if
2363 * we happen to GC as the result of an allocation of a Thread object.
2364 */
2365void dvmSuspendAllThreads(SuspendCause why)
2366{
2367 Thread* self = dvmThreadSelf();
2368 Thread* thread;
2369
2370 assert(why != 0);
2371
2372 /*
2373 * Start by grabbing the thread suspend lock. If we can't get it, most
2374 * likely somebody else is in the process of performing a suspend or
2375 * resume, so lockThreadSuspend() will cause us to self-suspend.
2376 *
2377 * We keep the lock until all other threads are suspended.
2378 */
2379 lockThreadSuspend("susp-all", why);
2380
2381 LOG_THREAD("threadid=%d: SuspendAll starting\n", self->threadId);
2382
2383 /*
2384 * This is possible if the current thread was in VMWAIT mode when a
2385 * suspend-all happened, and then decided to do its own suspend-all.
2386 * This can happen when a couple of threads have simultaneous events
2387 * of interest to the debugger.
2388 */
2389 //assert(self->suspendCount == 0);
2390
2391 /*
2392 * Increment everybody's suspend count (except our own).
2393 */
2394 dvmLockThreadList(self);
2395
2396 lockThreadSuspendCount();
2397 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2398 if (thread == self)
2399 continue;
2400
2401 /* debugger events don't suspend JDWP thread */
2402 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2403 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2404 continue;
2405
2406 thread->suspendCount++;
2407 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2408 thread->dbgSuspendCount++;
2409 }
2410 unlockThreadSuspendCount();
2411
2412 /*
2413 * Wait for everybody in THREAD_RUNNING state to stop. Other states
2414 * indicate the code is either running natively or sleeping quietly.
2415 * Any attempt to transition back to THREAD_RUNNING will cause a check
2416 * for suspension, so it should be impossible for anything to execute
2417 * interpreted code or modify objects (assuming native code plays nicely).
2418 *
2419 * It's also okay if the thread transitions to a non-RUNNING state.
2420 *
2421 * Note we released the threadSuspendCountLock before getting here,
2422 * so if another thread is fiddling with its suspend count (perhaps
2423 * self-suspending for the debugger) it won't block while we're waiting
2424 * in here.
2425 */
2426 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2427 if (thread == self)
2428 continue;
2429
2430 /* debugger events don't suspend JDWP thread */
2431 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2432 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2433 continue;
2434
2435 /* wait for the other thread to see the pending suspend */
2436 waitForThreadSuspend(self, thread);
2437
2438 LOG_THREAD("threadid=%d: threadid=%d status=%d c=%d dc=%d isSusp=%d\n",
2439 self->threadId,
2440 thread->threadId, thread->status, thread->suspendCount,
2441 thread->dbgSuspendCount, thread->isSuspended);
2442 }
2443
2444 dvmUnlockThreadList();
2445 unlockThreadSuspend();
2446
2447 LOG_THREAD("threadid=%d: SuspendAll complete\n", self->threadId);
2448}
2449
2450/*
2451 * Resume all threads that are currently suspended.
2452 *
2453 * The "why" must match with the previous suspend.
2454 */
2455void dvmResumeAllThreads(SuspendCause why)
2456{
2457 Thread* self = dvmThreadSelf();
2458 Thread* thread;
2459 int cc;
2460
2461 lockThreadSuspend("res-all", why); /* one suspend/resume at a time */
2462 LOG_THREAD("threadid=%d: ResumeAll starting\n", self->threadId);
2463
2464 /*
2465 * Decrement the suspend counts for all threads. No need for atomic
2466 * writes, since nobody should be moving until we decrement the count.
2467 * We do need to hold the thread list because of JNI attaches.
2468 */
2469 dvmLockThreadList(self);
2470 lockThreadSuspendCount();
2471 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2472 if (thread == self)
2473 continue;
2474
2475 /* debugger events don't suspend JDWP thread */
2476 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2477 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2478 continue;
2479
2480 if (thread->suspendCount > 0) {
2481 thread->suspendCount--;
2482 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2483 thread->dbgSuspendCount--;
2484 } else {
2485 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2486 thread->threadId);
2487 }
2488 }
2489 unlockThreadSuspendCount();
2490 dvmUnlockThreadList();
2491
2492 /*
2493 * Broadcast a notification to all suspended threads, some or all of
2494 * which may choose to wake up. No need to wait for them.
2495 */
2496 lockThreadSuspendCount();
2497 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2498 assert(cc == 0);
2499 unlockThreadSuspendCount();
2500
2501 unlockThreadSuspend();
2502
2503 LOG_THREAD("threadid=%d: ResumeAll complete\n", self->threadId);
2504}
2505
2506/*
2507 * Undo any debugger suspensions. This is called when the debugger
2508 * disconnects.
2509 */
2510void dvmUndoDebuggerSuspensions(void)
2511{
2512 Thread* self = dvmThreadSelf();
2513 Thread* thread;
2514 int cc;
2515
2516 lockThreadSuspend("undo", SUSPEND_FOR_DEBUG);
2517 LOG_THREAD("threadid=%d: UndoDebuggerSusp starting\n", self->threadId);
2518
2519 /*
2520 * Decrement the suspend counts for all threads. No need for atomic
2521 * writes, since nobody should be moving until we decrement the count.
2522 * We do need to hold the thread list because of JNI attaches.
2523 */
2524 dvmLockThreadList(self);
2525 lockThreadSuspendCount();
2526 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2527 if (thread == self)
2528 continue;
2529
2530 /* debugger events don't suspend JDWP thread */
2531 if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2532 assert(thread->dbgSuspendCount == 0);
2533 continue;
2534 }
2535
2536 assert(thread->suspendCount >= thread->dbgSuspendCount);
2537 thread->suspendCount -= thread->dbgSuspendCount;
2538 thread->dbgSuspendCount = 0;
2539 }
2540 unlockThreadSuspendCount();
2541 dvmUnlockThreadList();
2542
2543 /*
2544 * Broadcast a notification to all suspended threads, some or all of
2545 * which may choose to wake up. No need to wait for them.
2546 */
2547 lockThreadSuspendCount();
2548 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2549 assert(cc == 0);
2550 unlockThreadSuspendCount();
2551
2552 unlockThreadSuspend();
2553
2554 LOG_THREAD("threadid=%d: UndoDebuggerSusp complete\n", self->threadId);
2555}
2556
2557/*
2558 * Determine if a thread is suspended.
2559 *
2560 * As with all operations on foreign threads, the caller should hold
2561 * the thread list lock before calling.
2562 */
2563bool dvmIsSuspended(Thread* thread)
2564{
2565 /*
2566 * The thread could be:
2567 * (1) Running happily. status is RUNNING, isSuspended is false,
2568 * suspendCount is zero. Return "false".
2569 * (2) Pending suspend. status is RUNNING, isSuspended is false,
2570 * suspendCount is nonzero. Return "false".
2571 * (3) Suspended. suspendCount is nonzero, and either (status is
2572 * RUNNING and isSuspended is true) OR (status is !RUNNING).
2573 * Return "true".
2574 * (4) Waking up. suspendCount is zero, status is RUNNING and
2575 * isSuspended is true. Return "false" (since it could change
2576 * out from under us, unless we hold suspendCountLock).
2577 */
2578
2579 return (thread->suspendCount != 0 &&
2580 ((thread->status == THREAD_RUNNING && thread->isSuspended) ||
2581 (thread->status != THREAD_RUNNING)));
2582}
2583
2584/*
2585 * Wait until another thread self-suspends. This is specifically for
2586 * synchronization between the JDWP thread and a thread that has decided
2587 * to suspend itself after sending an event to the debugger.
2588 *
2589 * Threads that encounter "suspend all" events work as well -- the thread
2590 * in question suspends everybody else and then itself.
2591 *
2592 * We can't hold a thread lock here or in the caller, because we could
2593 * get here just before the to-be-waited-for-thread issues a "suspend all".
2594 * There's an opportunity for badness if the thread we're waiting for exits
2595 * and gets cleaned up, but since the thread in question is processing a
2596 * debugger event, that's not really a possibility. (To avoid deadlock,
2597 * it's important that we not be in THREAD_RUNNING while we wait.)
2598 */
2599void dvmWaitForSuspend(Thread* thread)
2600{
2601 Thread* self = dvmThreadSelf();
2602
2603 LOG_THREAD("threadid=%d: waiting for threadid=%d to sleep\n",
2604 self->threadId, thread->threadId);
2605
2606 assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2607 assert(thread != self);
2608 assert(self->status != THREAD_RUNNING);
2609
2610 waitForThreadSuspend(self, thread);
2611
2612 LOG_THREAD("threadid=%d: threadid=%d is now asleep\n",
2613 self->threadId, thread->threadId);
2614}
2615
2616/*
2617 * Check to see if we need to suspend ourselves. If so, go to sleep on
2618 * a condition variable.
2619 *
2620 * Takes "self" as an argument as an optimization. Pass in NULL to have
2621 * it do the lookup.
2622 *
2623 * Returns "true" if we suspended ourselves.
2624 */
2625bool dvmCheckSuspendPending(Thread* self)
2626{
2627 bool didSuspend;
2628
2629 if (self == NULL)
2630 self = dvmThreadSelf();
2631
2632 /* fast path: if count is zero, bail immediately */
2633 if (self->suspendCount == 0)
2634 return false;
2635
2636 lockThreadSuspendCount(); /* grab gDvm.threadSuspendCountLock */
2637
2638 assert(self->suspendCount >= 0); /* XXX: valid? useful? */
2639
2640 didSuspend = (self->suspendCount != 0);
2641 self->isSuspended = true;
2642 LOG_THREAD("threadid=%d: self-suspending\n", self->threadId);
2643 while (self->suspendCount != 0) {
2644 /* wait for wakeup signal; releases lock */
2645 int cc;
2646 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2647 &gDvm.threadSuspendCountLock);
2648 assert(cc == 0);
2649 }
2650 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2651 self->isSuspended = false;
2652 LOG_THREAD("threadid=%d: self-reviving, status=%d\n",
2653 self->threadId, self->status);
2654
2655 unlockThreadSuspendCount();
2656
2657 return didSuspend;
2658}
2659
2660/*
2661 * Update our status.
2662 *
2663 * The "self" argument, which may be NULL, is accepted as an optimization.
2664 *
2665 * Returns the old status.
2666 */
2667ThreadStatus dvmChangeStatus(Thread* self, ThreadStatus newStatus)
2668{
2669 ThreadStatus oldStatus;
2670
2671 if (self == NULL)
2672 self = dvmThreadSelf();
2673
2674 LOGVV("threadid=%d: (status %d -> %d)\n",
2675 self->threadId, self->status, newStatus);
2676
2677 oldStatus = self->status;
2678
2679 if (newStatus == THREAD_RUNNING) {
2680 /*
2681 * Change our status to THREAD_RUNNING. The transition requires
2682 * that we check for pending suspension, because the VM considers
2683 * us to be "asleep" in all other states.
2684 *
2685 * We need to do the "suspend pending" check FIRST, because it grabs
2686 * a lock that could be held by something that wants us to suspend.
2687 * If we're in RUNNING it will wait for us, and we'll be waiting
2688 * for the lock it holds.
2689 */
2690 assert(self->status != THREAD_RUNNING);
2691
2692 dvmCheckSuspendPending(self);
2693 self->status = THREAD_RUNNING;
2694 } else {
2695 /*
2696 * Change from one state to another, neither of which is
2697 * THREAD_RUNNING. This is most common during system or thread
2698 * initialization.
2699 */
2700 self->status = newStatus;
2701 }
2702
2703 return oldStatus;
2704}
2705
2706/*
2707 * Get a statically defined thread group from a field in the ThreadGroup
2708 * Class object. Expected arguments are "mMain" and "mSystem".
2709 */
2710static Object* getStaticThreadGroup(const char* fieldName)
2711{
2712 StaticField* groupField;
2713 Object* groupObj;
2714
2715 groupField = dvmFindStaticField(gDvm.classJavaLangThreadGroup,
2716 fieldName, "Ljava/lang/ThreadGroup;");
2717 if (groupField == NULL) {
2718 LOGE("java.lang.ThreadGroup does not have an '%s' field\n", fieldName);
2719 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", NULL);
2720 return NULL;
2721 }
2722 groupObj = dvmGetStaticFieldObject(groupField);
2723 if (groupObj == NULL) {
2724 LOGE("java.lang.ThreadGroup.%s not initialized\n", fieldName);
2725 dvmThrowException("Ljava/lang/InternalError;", NULL);
2726 return NULL;
2727 }
2728
2729 return groupObj;
2730}
2731Object* dvmGetSystemThreadGroup(void)
2732{
2733 return getStaticThreadGroup("mSystem");
2734}
2735Object* dvmGetMainThreadGroup(void)
2736{
2737 return getStaticThreadGroup("mMain");
2738}
2739
2740/*
2741 * Given a VMThread object, return the associated Thread*.
2742 *
2743 * NOTE: if the thread detaches, the struct Thread will disappear, and
2744 * we will be touching invalid data. For safety, lock the thread list
2745 * before calling this.
2746 */
2747Thread* dvmGetThreadFromThreadObject(Object* vmThreadObj)
2748{
2749 int vmData;
2750
2751 vmData = dvmGetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData);
2752 return (Thread*) vmData;
2753}
2754
2755
2756/*
2757 * Conversion map for "nice" values.
2758 *
2759 * We use Android thread priority constants to be consistent with the rest
2760 * of the system. In some cases adjacent entries may overlap.
2761 */
2762static const int kNiceValues[10] = {
2763 ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
2764 ANDROID_PRIORITY_BACKGROUND + 6,
2765 ANDROID_PRIORITY_BACKGROUND + 3,
2766 ANDROID_PRIORITY_BACKGROUND,
2767 ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
2768 ANDROID_PRIORITY_NORMAL - 2,
2769 ANDROID_PRIORITY_NORMAL - 4,
2770 ANDROID_PRIORITY_URGENT_DISPLAY + 3,
2771 ANDROID_PRIORITY_URGENT_DISPLAY + 2,
2772 ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
2773};
2774
2775/*
2776 * Change the priority of a system thread to match that of the Thread object.
2777 *
2778 * We map a priority value from 1-10 to Linux "nice" values, where lower
2779 * numbers indicate higher priority.
2780 */
2781void dvmChangeThreadPriority(Thread* thread, int newPriority)
2782{
2783 pid_t pid = thread->systemTid;
2784 int newNice;
2785
2786 if (newPriority < 1 || newPriority > 10) {
2787 LOGW("bad priority %d\n", newPriority);
2788 newPriority = 5;
2789 }
2790 newNice = kNiceValues[newPriority-1];
2791
2792 if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
2793 char* str = dvmGetThreadName(thread);
2794 LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s\n",
2795 pid, str, newPriority, newNice, strerror(errno));
2796 free(str);
2797 } else {
2798 LOGV("setPriority(%d) to prio=%d(n=%d)\n",
2799 pid, newPriority, newNice);
2800 }
2801}
2802
2803/*
2804 * Get the thread priority for the current thread by querying the system.
2805 * This is useful when attaching a thread through JNI.
2806 *
2807 * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
2808 */
2809static int getThreadPriorityFromSystem(void)
2810{
2811 int i, sysprio, jprio;
2812
2813 errno = 0;
2814 sysprio = getpriority(PRIO_PROCESS, 0);
2815 if (sysprio == -1 && errno != 0) {
2816 LOGW("getpriority() failed: %s\n", strerror(errno));
2817 return THREAD_NORM_PRIORITY;
2818 }
2819
2820 jprio = THREAD_MIN_PRIORITY;
2821 for (i = 0; i < NELEM(kNiceValues); i++) {
2822 if (sysprio >= kNiceValues[i])
2823 break;
2824 jprio++;
2825 }
2826 if (jprio > THREAD_MAX_PRIORITY)
2827 jprio = THREAD_MAX_PRIORITY;
2828
2829 return jprio;
2830}
2831
2832
2833/*
2834 * Return true if the thread is on gDvm.threadList.
2835 * Caller should not hold gDvm.threadListLock.
2836 */
2837bool dvmIsOnThreadList(const Thread* thread)
2838{
2839 bool ret = false;
2840
2841 dvmLockThreadList(NULL);
2842 if (thread == gDvm.threadList) {
2843 ret = true;
2844 } else {
2845 ret = thread->prev != NULL || thread->next != NULL;
2846 }
2847 dvmUnlockThreadList();
2848
2849 return ret;
2850}
2851
2852/*
2853 * Dump a thread to the log file -- just calls dvmDumpThreadEx() with an
2854 * output target.
2855 */
2856void dvmDumpThread(Thread* thread, bool isRunning)
2857{
2858 DebugOutputTarget target;
2859
2860 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
2861 dvmDumpThreadEx(&target, thread, isRunning);
2862}
2863
2864/*
2865 * Print information about the specified thread.
2866 *
2867 * Works best when the thread in question is "self" or has been suspended.
2868 * When dumping a separate thread that's still running, set "isRunning" to
2869 * use a more cautious thread dump function.
2870 */
2871void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
2872 bool isRunning)
2873{
2874 /* tied to ThreadStatus enum */
2875 static const char* kStatusNames[] = {
2876 "ZOMBIE", "RUNNABLE", "TIMED_WAIT", "MONITOR", "WAIT",
2877 "INITIALIZING", "STARTING", "NATIVE", "VMWAIT"
2878 };
2879 Object* threadObj;
2880 Object* groupObj;
2881 StringObject* nameStr;
2882 char* threadName = NULL;
2883 char* groupName = NULL;
2884 bool isDaemon;
2885 int priority; // java.lang.Thread priority
2886 int policy; // pthread policy
2887 struct sched_param sp; // pthread scheduling parameters
2888
2889 threadObj = thread->threadObj;
2890 if (threadObj == NULL) {
2891 LOGW("Can't dump thread %d: threadObj not set\n", thread->threadId);
2892 return;
2893 }
2894 nameStr = (StringObject*) dvmGetFieldObject(threadObj,
2895 gDvm.offJavaLangThread_name);
2896 threadName = dvmCreateCstrFromString(nameStr);
2897
2898 priority = dvmGetFieldInt(threadObj, gDvm.offJavaLangThread_priority);
2899 isDaemon = dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon);
2900
2901 if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) {
2902 LOGW("Warning: pthread_getschedparam failed\n");
2903 policy = -1;
2904 sp.sched_priority = -1;
2905 }
2906
2907 /* a null value for group is not expected, but deal with it anyway */
2908 groupObj = (Object*) dvmGetFieldObject(threadObj,
2909 gDvm.offJavaLangThread_group);
2910 if (groupObj != NULL) {
2911 int offset = dvmFindFieldOffset(gDvm.classJavaLangThreadGroup,
2912 "name", "Ljava/lang/String;");
2913 if (offset < 0) {
2914 LOGW("Unable to find 'name' field in ThreadGroup\n");
2915 } else {
2916 nameStr = (StringObject*) dvmGetFieldObject(groupObj, offset);
2917 groupName = dvmCreateCstrFromString(nameStr);
2918 }
2919 }
2920 if (groupName == NULL)
2921 groupName = strdup("(BOGUS GROUP)");
2922
2923 assert(thread->status < NELEM(kStatusNames));
2924 dvmPrintDebugMessage(target,
2925 "\"%s\"%s prio=%d tid=%d %s\n",
2926 threadName, isDaemon ? " daemon" : "",
2927 priority, thread->threadId, kStatusNames[thread->status]);
2928 dvmPrintDebugMessage(target,
The Android Open Source Project99409882009-03-18 22:20:24 -07002929 " | group=\"%s\" sCount=%d dsCount=%d s=%c obj=%p\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002930 groupName, thread->suspendCount, thread->dbgSuspendCount,
The Android Open Source Project99409882009-03-18 22:20:24 -07002931 thread->isSuspended ? 'Y' : 'N', thread->threadObj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002932 dvmPrintDebugMessage(target,
2933 " | sysTid=%d nice=%d sched=%d/%d handle=%d\n",
2934 thread->systemTid, getpriority(PRIO_PROCESS, thread->systemTid),
2935 policy, sp.sched_priority, (int)thread->handle);
2936
2937#ifdef WITH_MONITOR_TRACKING
2938 if (!isRunning) {
2939 LockedObjectData* lod = thread->pLockedObjects;
2940 if (lod != NULL)
2941 dvmPrintDebugMessage(target, " | monitors held:\n");
2942 else
2943 dvmPrintDebugMessage(target, " | monitors held: <none>\n");
2944 while (lod != NULL) {
2945 dvmPrintDebugMessage(target, " > %p[%d] (%s)\n",
2946 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
2947 lod = lod->next;
2948 }
2949 }
2950#endif
2951
2952 if (isRunning)
2953 dvmDumpRunningThreadStack(target, thread);
2954 else
2955 dvmDumpThreadStack(target, thread);
2956
2957 free(threadName);
2958 free(groupName);
2959
2960}
2961
2962/*
2963 * Get the name of a thread.
2964 *
2965 * For correctness, the caller should hold the thread list lock to ensure
2966 * that the thread doesn't go away mid-call.
2967 *
2968 * Returns a newly-allocated string, or NULL if the Thread doesn't have a name.
2969 */
2970char* dvmGetThreadName(Thread* thread)
2971{
2972 StringObject* nameObj;
2973
2974 if (thread->threadObj == NULL) {
2975 LOGW("threadObj is NULL, name not available\n");
2976 return strdup("-unknown-");
2977 }
2978
2979 nameObj = (StringObject*)
2980 dvmGetFieldObject(thread->threadObj, gDvm.offJavaLangThread_name);
2981 return dvmCreateCstrFromString(nameObj);
2982}
2983
2984/*
2985 * Dump all threads to the log file -- just calls dvmDumpAllThreadsEx() with
2986 * an output target.
2987 */
2988void dvmDumpAllThreads(bool grabLock)
2989{
2990 DebugOutputTarget target;
2991
2992 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
2993 dvmDumpAllThreadsEx(&target, grabLock);
2994}
2995
2996/*
2997 * Print information about all known threads. Assumes they have been
2998 * suspended (or are in a non-interpreting state, e.g. WAIT or NATIVE).
2999 *
3000 * If "grabLock" is true, we grab the thread lock list. This is important
3001 * to do unless the caller already holds the lock.
3002 */
3003void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock)
3004{
3005 Thread* thread;
3006
3007 dvmPrintDebugMessage(target, "DALVIK THREADS:\n");
3008
3009 if (grabLock)
3010 dvmLockThreadList(dvmThreadSelf());
3011
3012 thread = gDvm.threadList;
3013 while (thread != NULL) {
3014 dvmDumpThreadEx(target, thread, false);
3015
3016 /* verify link */
3017 assert(thread->next == NULL || thread->next->prev == thread);
3018
3019 thread = thread->next;
3020 }
3021
3022 if (grabLock)
3023 dvmUnlockThreadList();
3024}
3025
3026#ifdef WITH_MONITOR_TRACKING
3027/*
3028 * Count up the #of locked objects in the current thread.
3029 */
3030static int getThreadObjectCount(const Thread* self)
3031{
3032 LockedObjectData* lod;
3033 int count = 0;
3034
3035 lod = self->pLockedObjects;
3036 while (lod != NULL) {
3037 count++;
3038 lod = lod->next;
3039 }
3040 return count;
3041}
3042
3043/*
3044 * Add the object to the thread's locked object list if it doesn't already
3045 * exist. The most recently added object is the most likely to be released
3046 * next, so we insert at the head of the list.
3047 *
3048 * If it already exists, we increase the recursive lock count.
3049 *
3050 * The object's lock may be thin or fat.
3051 */
3052void dvmAddToMonitorList(Thread* self, Object* obj, bool withTrace)
3053{
3054 LockedObjectData* newLod;
3055 LockedObjectData* lod;
3056 int* trace;
3057 int depth;
3058
3059 lod = self->pLockedObjects;
3060 while (lod != NULL) {
3061 if (lod->obj == obj) {
3062 lod->recursionCount++;
3063 LOGV("+++ +recursive lock %p -> %d\n", obj, lod->recursionCount);
3064 return;
3065 }
3066 lod = lod->next;
3067 }
3068
3069 newLod = (LockedObjectData*) calloc(1, sizeof(LockedObjectData));
3070 if (newLod == NULL) {
3071 LOGE("malloc failed on %d bytes\n", sizeof(LockedObjectData));
3072 return;
3073 }
3074 newLod->obj = obj;
3075 newLod->recursionCount = 0;
3076
3077 if (withTrace) {
3078 trace = dvmFillInStackTraceRaw(self, &depth);
3079 newLod->rawStackTrace = trace;
3080 newLod->stackDepth = depth;
3081 }
3082
3083 newLod->next = self->pLockedObjects;
3084 self->pLockedObjects = newLod;
3085
3086 LOGV("+++ threadid=%d: added %p, now %d\n",
3087 self->threadId, newLod, getThreadObjectCount(self));
3088}
3089
3090/*
3091 * Remove the object from the thread's locked object list. If the entry
3092 * has a nonzero recursion count, we just decrement the count instead.
3093 */
3094void dvmRemoveFromMonitorList(Thread* self, Object* obj)
3095{
3096 LockedObjectData* lod;
3097 LockedObjectData* prevLod;
3098
3099 lod = self->pLockedObjects;
3100 prevLod = NULL;
3101 while (lod != NULL) {
3102 if (lod->obj == obj) {
3103 if (lod->recursionCount > 0) {
3104 lod->recursionCount--;
3105 LOGV("+++ -recursive lock %p -> %d\n",
3106 obj, lod->recursionCount);
3107 return;
3108 } else {
3109 break;
3110 }
3111 }
3112 prevLod = lod;
3113 lod = lod->next;
3114 }
3115
3116 if (lod == NULL) {
3117 LOGW("BUG: object %p not found in thread's lock list\n", obj);
3118 return;
3119 }
3120 if (prevLod == NULL) {
3121 /* first item in list */
3122 assert(self->pLockedObjects == lod);
3123 self->pLockedObjects = lod->next;
3124 } else {
3125 /* middle/end of list */
3126 prevLod->next = lod->next;
3127 }
3128
3129 LOGV("+++ threadid=%d: removed %p, now %d\n",
3130 self->threadId, lod, getThreadObjectCount(self));
3131 free(lod->rawStackTrace);
3132 free(lod);
3133}
3134
3135/*
3136 * If the specified object is already in the thread's locked object list,
3137 * return the LockedObjectData struct. Otherwise return NULL.
3138 */
3139LockedObjectData* dvmFindInMonitorList(const Thread* self, const Object* obj)
3140{
3141 LockedObjectData* lod;
3142
3143 lod = self->pLockedObjects;
3144 while (lod != NULL) {
3145 if (lod->obj == obj)
3146 return lod;
3147 lod = lod->next;
3148 }
3149 return NULL;
3150}
3151#endif /*WITH_MONITOR_TRACKING*/
3152
3153
3154/*
3155 * GC helper functions
3156 */
3157
The Android Open Source Project99409882009-03-18 22:20:24 -07003158/*
3159 * Add the contents of the registers from the interpreted call stack.
3160 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003161static void gcScanInterpStackReferences(Thread *thread)
3162{
3163 const u4 *framePtr;
The Android Open Source Project99409882009-03-18 22:20:24 -07003164#if WITH_EXTRA_GC_CHECKS > 1
3165 bool first = true;
3166#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003167
3168 framePtr = (const u4 *)thread->curFrame;
3169 while (framePtr != NULL) {
3170 const StackSaveArea *saveArea;
3171 const Method *method;
3172
3173 saveArea = SAVEAREA_FROM_FP(framePtr);
3174 method = saveArea->method;
The Android Open Source Project99409882009-03-18 22:20:24 -07003175 if (method != NULL && !dvmIsNativeMethod(method)) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003176#ifdef COUNT_PRECISE_METHODS
3177 /* the GC is running, so no lock required */
The Android Open Source Project99409882009-03-18 22:20:24 -07003178 if (dvmPointerSetAddEntry(gDvm.preciseMethods, method))
3179 LOGI("PGC: added %s.%s %p\n",
3180 method->clazz->descriptor, method->name, method);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003181#endif
The Android Open Source Project99409882009-03-18 22:20:24 -07003182#if WITH_EXTRA_GC_CHECKS > 1
3183 /*
3184 * May also want to enable the memset() in the "invokeMethod"
3185 * goto target in the portable interpreter. That sets the stack
3186 * to a pattern that makes referring to uninitialized data
3187 * very obvious.
3188 */
3189
3190 if (first) {
3191 /*
3192 * First frame, isn't native, check the "alternate" saved PC
3193 * as a sanity check.
3194 *
3195 * It seems like we could check the second frame if the first
3196 * is native, since the PCs should be the same. It turns out
3197 * this doesn't always work. The problem is that we could
3198 * have calls in the sequence:
3199 * interp method #2
3200 * native method
3201 * interp method #1
3202 *
3203 * and then GC while in the native method after returning
3204 * from interp method #2. The currentPc on the stack is
3205 * for interp method #1, but thread->currentPc2 is still
3206 * set for the last thing interp method #2 did.
3207 *
3208 * This can also happen in normal execution:
3209 * - sget-object on not-yet-loaded class
3210 * - class init updates currentPc2
3211 * - static field init is handled by parsing annotations;
3212 * static String init requires creation of a String object,
3213 * which can cause a GC
3214 *
3215 * Essentially, any pattern that involves executing
3216 * interpreted code and then causes an allocation without
3217 * executing instructions in the original method will hit
3218 * this. These are rare enough that the test still has
3219 * some value.
3220 */
3221 if (saveArea->xtra.currentPc != thread->currentPc2) {
3222 LOGW("PGC: savedPC(%p) != current PC(%p), %s.%s ins=%p\n",
3223 saveArea->xtra.currentPc, thread->currentPc2,
3224 method->clazz->descriptor, method->name, method->insns);
3225 if (saveArea->xtra.currentPc != NULL)
3226 LOGE(" pc inst = 0x%04x\n", *saveArea->xtra.currentPc);
3227 if (thread->currentPc2 != NULL)
3228 LOGE(" pc2 inst = 0x%04x\n", *thread->currentPc2);
3229 dvmDumpThread(thread, false);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003230 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003231 } else {
3232 /*
3233 * It's unusual, but not impossible, for a non-first frame
3234 * to be at something other than a method invocation. For
3235 * example, if we do a new-instance on a nonexistent class,
3236 * we'll have a lot of class loader activity on the stack
3237 * above the frame with the "new" operation. Could also
3238 * happen while we initialize a Throwable when an instruction
3239 * fails.
3240 *
3241 * So there's not much we can do here to verify the PC,
3242 * except to verify that it's a GC point.
3243 */
3244 }
3245 assert(saveArea->xtra.currentPc != NULL);
3246#endif
3247
3248 const RegisterMap* pMap;
3249 const u1* regVector;
3250 int i;
3251
Andy McFaddencf8b55c2009-04-13 15:26:03 -07003252 Method* nonConstMethod = (Method*) method; // quiet gcc
3253 pMap = dvmGetExpandedRegisterMap(nonConstMethod);
The Android Open Source Project99409882009-03-18 22:20:24 -07003254 if (pMap != NULL) {
3255 /* found map, get registers for this address */
3256 int addr = saveArea->xtra.currentPc - method->insns;
Andy McFaddend45a8872009-03-24 20:41:52 -07003257 regVector = dvmRegisterMapGetLine(pMap, addr);
The Android Open Source Project99409882009-03-18 22:20:24 -07003258 if (regVector == NULL) {
3259 LOGW("PGC: map but no entry for %s.%s addr=0x%04x\n",
3260 method->clazz->descriptor, method->name, addr);
3261 } else {
3262 LOGV("PGC: found map for %s.%s 0x%04x (t=%d)\n",
3263 method->clazz->descriptor, method->name, addr,
3264 thread->threadId);
3265 }
3266 } else {
3267 /*
3268 * No map found. If precise GC is disabled this is
3269 * expected -- we don't create pointers to the map data even
3270 * if it's present -- but if it's enabled it means we're
3271 * unexpectedly falling back on a conservative scan, so it's
3272 * worth yelling a little.
3273 *
3274 * TODO: we should be able to remove this for production --
3275 * no need to keep banging on the global.
3276 */
3277 if (gDvm.preciseGc) {
Andy McFaddencf8b55c2009-04-13 15:26:03 -07003278 LOGV("PGC: no map for %s.%s\n",
The Android Open Source Project99409882009-03-18 22:20:24 -07003279 method->clazz->descriptor, method->name);
3280 }
3281 regVector = NULL;
3282 }
3283
3284 if (regVector == NULL) {
3285 /* conservative scan */
3286 for (i = method->registersSize - 1; i >= 0; i--) {
3287 u4 rval = *framePtr++;
3288 if (rval != 0 && (rval & 0x3) == 0) {
3289 dvmMarkIfObject((Object *)rval);
3290 }
3291 }
3292 } else {
3293 /*
3294 * Precise scan. v0 is at the lowest address on the
3295 * interpreted stack, and is the first bit in the register
3296 * vector, so we can walk through the register map and
3297 * memory in the same direction.
3298 *
3299 * A '1' bit indicates a live reference.
3300 */
3301 u2 bits = 1 << 1;
3302 for (i = method->registersSize - 1; i >= 0; i--) {
3303 u4 rval = *framePtr++;
3304
3305 bits >>= 1;
3306 if (bits == 1) {
3307 /* set bit 9 so we can tell when we're empty */
3308 bits = *regVector++ | 0x0100;
3309 LOGVV("loaded bits: 0x%02x\n", bits & 0xff);
3310 }
3311
3312 if (rval != 0 && (bits & 0x01) != 0) {
3313 /*
3314 * Non-null, register marked as live reference. This
3315 * should always be a valid object.
3316 */
3317#if WITH_EXTRA_GC_CHECKS > 0
3318 if ((rval & 0x3) != 0 ||
3319 !dvmIsValidObject((Object*) rval))
3320 {
3321 /* this is very bad */
3322 LOGE("PGC: invalid ref in reg %d: 0x%08x\n",
3323 method->registersSize-1 - i, rval);
3324 } else
3325#endif
3326 {
3327 dvmMarkObjectNonNull((Object *)rval);
3328 }
3329 } else {
3330 /*
3331 * Null or non-reference, do nothing at all.
3332 */
3333#if WITH_EXTRA_GC_CHECKS > 1
3334 if (dvmIsValidObject((Object*) rval)) {
3335 /* this is normal, but we feel chatty */
3336 LOGD("PGC: ignoring valid ref in reg %d: 0x%08x\n",
3337 method->registersSize-1 - i, rval);
3338 }
3339#endif
3340 }
3341 }
3342 dvmReleaseRegisterMapLine(pMap, regVector);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003343 }
3344 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003345 /* else this is a break frame and there is nothing to mark, or
3346 * this is a native method and the registers are just the "ins",
3347 * copied from various registers in the caller's set.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003348 */
3349
The Android Open Source Project99409882009-03-18 22:20:24 -07003350#if WITH_EXTRA_GC_CHECKS > 1
3351 first = false;
3352#endif
3353
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003354 /* Don't fall into an infinite loop if things get corrupted.
3355 */
3356 assert((uintptr_t)saveArea->prevFrame > (uintptr_t)framePtr ||
3357 saveArea->prevFrame == NULL);
3358 framePtr = saveArea->prevFrame;
3359 }
3360}
3361
3362static void gcScanReferenceTable(ReferenceTable *refTable)
3363{
3364 Object **op;
3365
3366 //TODO: these asserts are overkill; turn them off when things stablize.
3367 assert(refTable != NULL);
3368 assert(refTable->table != NULL);
3369 assert(refTable->nextEntry != NULL);
3370 assert((uintptr_t)refTable->nextEntry >= (uintptr_t)refTable->table);
3371 assert(refTable->nextEntry - refTable->table <= refTable->maxEntries);
3372
3373 op = refTable->table;
3374 while ((uintptr_t)op < (uintptr_t)refTable->nextEntry) {
3375 dvmMarkObjectNonNull(*(op++));
3376 }
3377}
3378
3379/*
3380 * Scan a Thread and mark any objects it references.
3381 */
3382static void gcScanThread(Thread *thread)
3383{
3384 assert(thread != NULL);
3385
3386 /*
3387 * The target thread must be suspended or in a state where it can't do
3388 * any harm (e.g. in Object.wait()). The only exception is the current
3389 * thread, which will still be active and in the "running" state.
3390 *
3391 * (Newly-created threads shouldn't be able to shift themselves to
3392 * RUNNING without a suspend-pending check, so this shouldn't cause
3393 * a false-positive.)
3394 */
3395 assert(thread->status != THREAD_RUNNING || thread->isSuspended ||
3396 thread == dvmThreadSelf());
3397
3398 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_THREAD_OBJECT, thread->threadId);
3399
3400 dvmMarkObject(thread->threadObj); // could be NULL, when constructing
3401
3402 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_NATIVE_STACK, thread->threadId);
3403
3404 dvmMarkObject(thread->exception); // usually NULL
3405 gcScanReferenceTable(&thread->internalLocalRefTable);
3406
3407 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_LOCAL, thread->threadId);
3408
3409 gcScanReferenceTable(&thread->jniLocalRefTable);
3410
3411 if (thread->jniMonitorRefTable.table != NULL) {
3412 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_MONITOR, thread->threadId);
3413
3414 gcScanReferenceTable(&thread->jniMonitorRefTable);
3415 }
3416
3417 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JAVA_FRAME, thread->threadId);
3418
3419 gcScanInterpStackReferences(thread);
3420
3421 HPROF_CLEAR_GC_SCAN_STATE();
3422}
3423
3424static void gcScanAllThreads()
3425{
3426 Thread *thread;
3427
3428 /* Lock the thread list so we can safely use the
3429 * next/prev pointers.
3430 */
3431 dvmLockThreadList(dvmThreadSelf());
3432
3433 for (thread = gDvm.threadList; thread != NULL;
3434 thread = thread->next)
3435 {
3436 /* We need to scan our own stack, so don't special-case
3437 * the current thread.
3438 */
3439 gcScanThread(thread);
3440 }
3441
3442 dvmUnlockThreadList();
3443}
3444
3445void dvmGcScanRootThreadGroups()
3446{
3447 /* We scan the VM's list of threads instead of going
3448 * through the actual ThreadGroups, but it should be
3449 * equivalent.
3450 *
3451 * This assumes that the ThreadGroup class object is in
3452 * the root set, which should always be true; it's
3453 * loaded by the built-in class loader, which is part
3454 * of the root set.
3455 */
3456 gcScanAllThreads();
3457}
3458