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