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