thread.h revision df1ce91ba97bc79a0637e5504b39318fb1c9f577
1561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes/*
2561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * Copyright (C) 2011 The Android Open Source Project
3561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *
4561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * you may not use this file except in compliance with the License.
6561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * You may obtain a copy of the License at
7fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes *
8561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes *
10561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * Unless required by applicable law or agreed to in writing, software
11561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * See the License for the specific language governing permissions and
14561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * limitations under the License.
15561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes */
16561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
17561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#ifndef ART_SRC_THREAD_H_
18561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#define ART_SRC_THREAD_H_
19561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
20561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <pthread.h>
21561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
22561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <bitset>
23561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <iosfwd>
24561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <list>
25561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <string>
26561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <vector>
27561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
28561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "closure.h"
29561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "globals.h"
30561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "instrumentation.h"
31561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "macros.h"
32561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "oat/runtime/oat_support_entrypoints.h"
33561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "locks.h"
34561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "offsets.h"
35561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "runtime_stats.h"
36561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "stack.h"
37561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "stack_indirect_reference_table.h"
38561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "UniquePtr.h"
39561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
40561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesnamespace art {
41561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
42561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass AbstractMethod;
43561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Array;
44561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass BaseMutex;
45561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Class;
46561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass ClassLinker;
47561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass ClassLoader;
48561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Context;
49561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesstruct DebugInvokeReq;
50561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass DexFile;
51561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesstruct JavaVMExt;
52561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesstruct JNIEnvExt;
53561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Monitor;
54561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Object;
55561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Runtime;
56561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass ScopedObjectAccess;
57561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass ScopedObjectAccessUnchecked;
58fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughesclass ShadowFrame;
59561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass StackIndirectReferenceTable;
60fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughesclass StackTraceElement;
61561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass StaticStorageBase;
62fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughesclass Thread;
63561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass ThreadList;
64561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Throwable;
65561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
66561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughestemplate<class T> class ObjectArray;
67561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughestemplate<class T> class PrimitiveArray;
68561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughestypedef PrimitiveArray<int32_t> IntArray;
69561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
70561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes// Thread priorities. These must match the Thread.MIN_PRIORITY,
71561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes// Thread.NORM_PRIORITY, and Thread.MAX_PRIORITY constants.
72561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesenum ThreadPriority {
73561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kMinThreadPriority = 1,
74561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kNormThreadPriority = 5,
75561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kMaxThreadPriority = 10,
76561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes};
77561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
78561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesenum ThreadState {
79561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kTerminated                     = 0,   // Thread.TERMINATED     JDWP TS_ZOMBIE
80561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kRunnable                       = 1,   // Thread.RUNNABLE       JDWP TS_RUNNING
81561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kTimedWaiting                   = 2,   // Thread.TIMED_WAITING  JDWP TS_WAIT    - in Object.wait() with a timeout
82561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kBlocked                        = 3,   // Thread.BLOCKED        JDWP TS_MONITOR - blocked on a monitor
83561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kWaiting                        = 4,   // Thread.WAITING        JDWP TS_WAIT    - in Object.wait()
84561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kWaitingForGcToComplete         = 5,   // Thread.WAITING        JDWP TS_WAIT    - blocked waiting for GC
85561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kWaitingPerformingGc            = 6,   // Thread.WAITING        JDWP TS_WAIT    - performing GC
86561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kWaitingForDebuggerSend         = 7,   // Thread.WAITING        JDWP TS_WAIT    - blocked waiting for events to be sent
87561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kWaitingForDebuggerToAttach     = 8,   // Thread.WAITING        JDWP TS_WAIT    - blocked waiting for debugger to attach
88561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kWaitingInMainDebuggerLoop      = 9,   // Thread.WAITING        JDWP TS_WAIT    - blocking/reading/processing debugger events
89561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kWaitingForDebuggerSuspension   = 10,  // Thread.WAITING        JDWP TS_WAIT    - waiting for debugger suspend all
90561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kWaitingForJniOnLoad            = 11,  // Thread.WAITING        JDWP TS_WAIT    - waiting for execution of dlopen and JNI on load code
91561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kWaitingForSignalCatcherOutput  = 12,  // Thread.WAITING        JDWP TS_WAIT    - waiting for signal catcher IO to complete
92561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kWaitingInMainSignalCatcherLoop = 13,  // Thread.WAITING        JDWP TS_WAIT    - blocking/reading/processing signals
93561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kStarting                       = 14,  // Thread.NEW            JDWP TS_WAIT    - native thread started, not yet ready to run managed code
94561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kNative                         = 15,  // Thread.RUNNABLE       JDWP TS_RUNNING - running in a JNI native method
95561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kSuspended                      = 16,  // Thread.RUNNABLE       JDWP TS_RUNNING - suspended by GC or debugger
96561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes};
97561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
98561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesenum ThreadFlag {
99561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kSuspendRequest   = 1,  // If set implies that suspend_count_ > 0 and the Thread should enter the
100561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                          // safepoint handler.
101561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kCheckpointRequest = 2, // Request that the thread do some checkpoint work and then continue.
102561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kExceptionPending = 4,  // If set implies that exception_ != NULL.
103561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  kEnterInterpreter = 8,  // Instruct managed code it should enter the interpreter.
104561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes};
105561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
106561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass PACKED(4) Thread {
107561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes public:
108561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Space to throw a StackOverflowError in.
109561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static const size_t kStackOverflowReservedBytes = 10 * KB;
110561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
111561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Creates a new native thread corresponding to the given managed peer.
112561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Used to implement Thread.start.
113561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static void CreateNativeThread(JNIEnv* env, jobject peer, size_t stack_size, bool daemon);
114561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
115561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Attaches the calling native thread to the runtime, returning the new native peer.
116561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Used to implement JNI AttachCurrentThread and AttachCurrentThreadAsDaemon calls.
117561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static Thread* Attach(const char* thread_name, bool as_daemon, jobject thread_group,
118561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        bool create_peer);
119561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
120561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Reset internal state of child thread after fork.
121561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void InitAfterFork();
122561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
123561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static Thread* Current() __attribute__ ((pure)) {
124561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // We rely on Thread::Current returning NULL for a detached thread, so it's not obvious
125561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // that we can replace this with a direct %fs access on x86.
126561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    void* thread = pthread_getspecific(Thread::pthread_key_self_);
127561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return reinterpret_cast<Thread*>(thread);
128561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
129561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
130561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts, Object* thread_peer)
131561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
132561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
133561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts, jobject thread)
134fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
135561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
136561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
137fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes  // Translates 172 to pAllocArrayFromCode and so on.
138561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static void DumpThreadOffset(std::ostream& os, uint32_t offset, size_t size_of_pointers);
139561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
140561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Dumps a one-line summary of thread state (used for operator<<).
141561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void ShortDump(std::ostream& os) const;
142fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes
143561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Dumps the detailed thread state and the thread stack (used for SIGQUIT).
144561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void Dump(std::ostream& os) const
145561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
146561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
147561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
148561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Dumps the SIGQUIT per-thread header. 'thread' can be NULL for a non-attached thread, in which
149561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // case we use 'tid' to identify the thread, and we'll include as much information as we can.
150561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static void DumpState(std::ostream& os, const Thread* thread, pid_t tid)
151561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_);
152561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
153561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  ThreadState GetState() const {
154561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return static_cast<ThreadState>(state_and_flags_.as_struct.state);
155561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
156fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes
157561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  ThreadState SetState(ThreadState new_state);
158561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
159561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  int GetSuspendCount() const EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_suspend_count_lock_) {
160561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return suspend_count_;
161561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
162561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
163561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  int GetDebugSuspendCount() const EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_suspend_count_lock_) {
164561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return debug_suspend_count_;
165561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
166561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
167561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool IsSuspended() const {
168561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    union StateAndFlags state_and_flags = state_and_flags_;
169561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return state_and_flags.as_struct.state != kRunnable &&
170561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        (state_and_flags.as_struct.flags & kSuspendRequest) != 0;
171561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
172561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
173561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void ModifySuspendCount(Thread* self, int delta, bool for_debugger)
174561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_suspend_count_lock_);
175561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
176561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool RequestCheckpoint(Closure* function);
177561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
178561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Called when thread detected that the thread_suspend_count_ was non-zero. Gives up share of
179561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // mutator_lock_ and waits until it is resumed and thread_suspend_count_ is zero.
180561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void FullSuspendCheck()
181561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
182561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
183561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
184561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Transition from non-runnable to runnable state acquiring share on mutator_lock_.
185561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  ThreadState TransitionFromSuspendedToRunnable()
186561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
187fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes      SHARED_LOCK_FUNCTION(Locks::mutator_lock_);
188561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
189561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Transition from runnable into a state where mutator privileges are denied. Releases share of
190561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // mutator lock.
191561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void TransitionFromRunnableToSuspended(ThreadState new_state)
192561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
193561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      UNLOCK_FUNCTION(Locks::mutator_lock_);
194561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
195561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Wait for a debugger suspension on the thread associated with the given peer. Returns the
196561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // thread on success, else NULL. If the thread should be suspended then request_suspension should
197561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // be true on entry. If the suspension times out then *timeout is set to true.
198561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static Thread* SuspendForDebugger(jobject peer,  bool request_suspension, bool* timeout)
199561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      LOCKS_EXCLUDED(Locks::mutator_lock_,
200561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                     Locks::thread_list_lock_,
201561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                     Locks::thread_suspend_count_lock_);
202561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
203561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Once called thread suspension will cause an assertion failure.
204561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#ifndef NDEBUG
205561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  const char* StartAssertNoThreadSuspension(const char* cause) {
206561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    CHECK(cause != NULL);
207561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    const char* previous_cause = last_no_thread_suspension_cause_;
208561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    no_thread_suspension_++;
209561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    last_no_thread_suspension_cause_ = cause;
210561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return previous_cause;
211561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
212561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#else
213561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  const char* StartAssertNoThreadSuspension(const char* cause) {
214561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    CHECK(cause != NULL);
215561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return NULL;
216561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
217561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#endif
218561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
219561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // End region where no thread suspension is expected.
220561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#ifndef NDEBUG
221561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void EndAssertNoThreadSuspension(const char* old_cause) {
222561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    CHECK(old_cause != NULL || no_thread_suspension_ == 1);
223561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    CHECK_GT(no_thread_suspension_, 0U);
224561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    no_thread_suspension_--;
225561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    last_no_thread_suspension_cause_ = old_cause;
226561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
227561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#else
228fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes  void EndAssertNoThreadSuspension(const char*) {
229561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
230561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#endif
231fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes
232561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
233561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#ifndef NDEBUG
234561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void AssertThreadSuspensionIsAllowable(bool check_locks = true) const;
235561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#else
236561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void AssertThreadSuspensionIsAllowable(bool check_locks = true) const {
237561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    UNUSED(check_locks);  // Keep GCC happy about unused parameters.
238561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
239561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#endif
240561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
241561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool IsDaemon() const {
242561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return daemon_;
243fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes  }
244561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
245561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool HoldsLock(Object*);
246561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
247561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  /*
248561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes   * Changes the priority of this thread to match that of the java.lang.Thread object.
249561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes   *
250561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes   * We map a priority value from 1-10 to Linux "nice" values, where lower
251561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes   * numbers indicate higher priority.
252561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes   */
253561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void SetNativePriority(int newPriority);
254561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
255561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  /*
256561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes   * Returns the thread priority for the current thread by querying the system.
257561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes   * This is useful when attaching a thread through JNI.
258561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes   *
259561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes   * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
260561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes   */
261561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static int GetNativePriority();
262561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
263561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  uint32_t GetThinLockId() const {
264561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return thin_lock_id_;
265561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
266561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
267561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  pid_t GetTid() const {
268561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return tid_;
269561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
270561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
271561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Returns the java.lang.Thread's name, or NULL if this Thread* doesn't have a peer.
272561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  String* GetThreadName(const ScopedObjectAccessUnchecked& ts) const
273fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
274561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
275561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Sets 'name' to the java.lang.Thread's name. This requires no transition to managed code,
276561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // allocation, or locking.
277561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void GetThreadName(std::string& name) const;
278fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes
279561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Sets the thread's name.
280561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void SetThreadName(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
281561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
282561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  jobject GetPeer() const {
283561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return peer_;
284561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
285fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes
286561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool HasPeer() const {
287561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return peer_ != NULL;
288561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
289561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
290561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  RuntimeStats* GetStats() {
291561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return &stats_;
292561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
293561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
294561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool IsStillStarting() const;
295561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
296561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool IsExceptionPending() const {
297561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    bool result = ReadFlag(kExceptionPending);
298561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    DCHECK_EQ(result, exception_ != NULL);
299561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return result;
300561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
301561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
302561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  Throwable* GetException() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
303561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return exception_;
304561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
305561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
306561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void AssertNoPendingException() const;
307561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
308561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void SetException(Throwable* new_exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
309561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    CHECK(new_exception != NULL);
310561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // TODO: DCHECK(!IsExceptionPending());
311561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    exception_ = new_exception;
312561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    AtomicSetFlag(kExceptionPending);
313561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    DCHECK(IsExceptionPending());
314561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
315561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
316561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void ClearException() {
317561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    exception_ = NULL;
318561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    AtomicClearFlag(kExceptionPending);
319561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    DCHECK(!IsExceptionPending());
320561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
321561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
322561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void DeliverException(Throwable* exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
323561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    if (exception == NULL) {
324561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      ThrowNewException("Ljava/lang/NullPointerException;", "throw with null exception");
325561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    } else {
326561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SetException(exception);
327561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
328561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
329561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
330561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Find catch block and perform long jump to appropriate exception handle
331561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void QuickDeliverException() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
332561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
333561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  Context* GetLongJumpContext();
334561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void ReleaseLongJumpContext(Context* context) {
335561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    DCHECK(long_jump_context_ == NULL);
336561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    long_jump_context_ = context;
337561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
338561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
339561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  AbstractMethod* GetCurrentMethod(uint32_t* dex_pc = NULL, size_t* frame_id = NULL) const
340561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
341561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
342561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void SetTopOfStack(void* stack, uintptr_t pc) {
343561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    AbstractMethod** top_method = reinterpret_cast<AbstractMethod**>(stack);
344561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    managed_stack_.SetTopQuickFrame(top_method);
345561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    managed_stack_.SetTopQuickFramePc(pc);
346561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
347561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
348561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool HasManagedStack() const {
349561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return managed_stack_.GetTopQuickFrame() != NULL || managed_stack_.GetTopShadowFrame() != NULL;
350561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
351561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
352561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // If 'msg' is NULL, no detail message is set.
353561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void ThrowNewException(const char* exception_class_descriptor, const char* msg)
354561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
355561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
356561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // If 'msg' is NULL, no detail message is set. An exception must be pending, and will be
357561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // used as the new exception's cause.
358561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void ThrowNewWrappedException(const char* exception_class_descriptor, const char* msg)
359561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
360561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
361561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void ThrowNewExceptionF(const char* exception_class_descriptor, const char* fmt, ...)
362561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      __attribute__((format(printf, 3, 4)))
363561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
364561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
365561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void ThrowNewExceptionV(const char* exception_class_descriptor, const char* fmt, va_list ap)
366561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
367561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
368561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // OutOfMemoryError is special, because we need to pre-allocate an instance.
369561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Only the GC should call this.
370561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void ThrowOutOfMemoryError(const char* msg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
371561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
372561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  //QuickFrameIterator FindExceptionHandler(void* throw_pc, void** handler_pc);
373561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
374561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void* FindExceptionHandlerInMethod(const AbstractMethod* method,
375561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                     void* throw_pc,
376561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                     const DexFile& dex_file,
377561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                     ClassLinker* class_linker);
378561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
379561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static void Startup();
380561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static void FinishStartup();
381561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static void Shutdown();
382561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
383561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // JNI methods
384561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  JNIEnvExt* GetJniEnv() const {
385561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return jni_env_;
386561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
387561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
388561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Convert a jobject into a Object*
389561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  Object* DecodeJObject(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
390561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
391561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Implements java.lang.Thread.interrupted.
392561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool Interrupted();
393561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Implements java.lang.Thread.isInterrupted.
394561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool IsInterrupted();
395561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void Interrupt();
396561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void Notify();
397561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
398561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  ClassLoader* GetClassLoaderOverride() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
399561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return class_loader_override_;
400561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
401561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
402561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void SetClassLoaderOverride(ClassLoader* class_loader_override) {
403561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    class_loader_override_ = class_loader_override;
404561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
405561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
406561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Create the internal representation of a stack trace, that is more time
407561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // and space efficient to compute than the StackTraceElement[]
408561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  jobject CreateInternalStackTrace(const ScopedObjectAccessUnchecked& soa) const
409561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
410561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
411561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Convert an internal stack trace representation (returned by CreateInternalStackTrace) to a
412561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // StackTraceElement[]. If output_array is NULL, a new array is created, otherwise as many
413561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // frames as will fit are written into the given array. If stack_depth is non-NULL, it's updated
414561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // with the number of valid frames in the returned array.
415561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static jobjectArray InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal,
416561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      jobjectArray output_array = NULL, int* stack_depth = NULL);
417561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
418561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void VisitRoots(Heap::RootVisitor* visitor, void* arg)
419561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
420561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
421561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void VerifyRoots(Heap::VerifyRootVisitor* visitor, void* arg)
422561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
423561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
424561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#if VERIFY_OBJECT_ENABLED
425561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void VerifyStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
426561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#else
427561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void VerifyStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){}
428561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#endif
429561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
430561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  //
431561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Offsets of various members of native Thread class, used by compiled code.
432561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  //
433561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
434561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset SelfOffset() {
435561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, self_));
436561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
437561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
438561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset ExceptionOffset() {
439561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_));
440561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
441561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
442561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset ThinLockIdOffset() {
443561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_));
444561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
445561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
446561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset CardTableOffset() {
447561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_));
448561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
449561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
450561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset ThreadFlagsOffset() {
451561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, state_and_flags_));
452561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
453561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
454561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Size of stack less any space reserved for stack overflow
455561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  size_t GetStackSize() const {
456561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return stack_size_ - (stack_end_ - stack_begin_);
457561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
458561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
459561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  byte* GetStackEnd() const {
460561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return stack_end_;
461561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
462561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
463561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Set the stack end to that to be used during a stack overflow
464561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void SetStackEndForStackOverflow() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
465561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
466561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Set the stack end to that to be used during regular execution
467561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void ResetDefaultStackEnd() {
468561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room
469561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // to throw a StackOverflowError.
470561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    stack_end_ = stack_begin_ + kStackOverflowReservedBytes;
471561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
472561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
473561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool IsHandlingStackOverflow() const {
474561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return stack_end_ == stack_begin_;
475561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
476561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
477561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset StackEndOffset() {
478561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, stack_end_));
479561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
480561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
481561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset JniEnvOffset() {
482561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_));
483561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
484561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
485561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset TopOfManagedStackOffset() {
486561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) +
487561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        ManagedStack::TopQuickFrameOffset());
488561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
489561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
490561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset TopOfManagedStackPcOffset() {
491561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) +
492561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        ManagedStack::TopQuickFramePcOffset());
493561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
494561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
495561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  const ManagedStack* GetManagedStack() const {
496561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return &managed_stack_;
497561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
498561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
499561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Linked list recording fragments of managed stack.
500561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void PushManagedStackFragment(ManagedStack* fragment) {
501561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    managed_stack_.PushManagedStackFragment(fragment);
502561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
503561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void PopManagedStackFragment(const ManagedStack& fragment) {
504561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    managed_stack_.PopManagedStackFragment(fragment);
505561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
506561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
507561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  ShadowFrame* PushShadowFrame(ShadowFrame* new_top_frame) {
508561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return managed_stack_.PushShadowFrame(new_top_frame);
509561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
510561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
511561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  ShadowFrame* PopShadowFrame() {
512561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return managed_stack_.PopShadowFrame();
513561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
514561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
515561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset TopShadowFrameOffset() {
516561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) +
517561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        ManagedStack::TopShadowFrameOffset());
518fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes  }
519561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
520561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Number of references allocated in ShadowFrames on this thread
521561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  size_t NumShadowFrameReferences() const {
522561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return managed_stack_.NumShadowFrameReferences();
523561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
524561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
525561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Number of references in SIRTs on this thread
526561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  size_t NumSirtReferences();
527561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
528561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Number of references allocated in SIRTs & shadow frames on this thread
529561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  size_t NumStackReferences() {
530fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes    return NumSirtReferences() + NumShadowFrameReferences();
531561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  };
532561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
533561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  // Is the given obj in this thread's stack indirect reference table?
534561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  bool SirtContains(jobject obj);
535561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
536561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void SirtVisitRoots(Heap::RootVisitor* visitor, void* arg);
537561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
538561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void PushSirt(StackIndirectReferenceTable* sirt) {
539561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    sirt->SetLink(top_sirt_);
540561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    top_sirt_ = sirt;
541561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
542561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
543561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  StackIndirectReferenceTable* PopSirt() {
544561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    StackIndirectReferenceTable* sirt = top_sirt_;
545561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    DCHECK(sirt != NULL);
546561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    top_sirt_ = top_sirt_->GetLink();
547561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return sirt;
548561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
549561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
550561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  static ThreadOffset TopSirtOffset() {
551561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_));
552561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
553561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
554561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  DebugInvokeReq* GetInvokeReq() {
555561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return debug_invoke_req_;
556561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
557561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
558561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  void SetDebuggerUpdatesEnabled(bool enabled);
559561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
560561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  const std::vector<InstrumentationStackFrame>* GetInstrumentationStack() const {
561561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    return instrumentation_stack_;
562561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes  }
563
564  bool IsInstrumentationStackEmpty() const {
565    return instrumentation_stack_->empty();
566  }
567
568  void PushInstrumentationStackFrame(const InstrumentationStackFrame& frame) {
569    instrumentation_stack_->push_back(frame);
570  }
571
572  InstrumentationStackFrame PopInstrumentationStackFrame() {
573    InstrumentationStackFrame frame = instrumentation_stack_->back();
574    instrumentation_stack_->pop_back();
575    return frame;
576  }
577
578  BaseMutex* GetHeldMutex(LockLevel level) const {
579    return held_mutexes_[level];
580  }
581
582  void SetHeldMutex(LockLevel level, BaseMutex* mutex) {
583    held_mutexes_[level] = mutex;
584  }
585
586  void RunCheckpointFunction() {
587    CHECK(checkpoint_function_ != NULL);
588    checkpoint_function_->Run(this);
589  }
590
591  bool ReadFlag(ThreadFlag flag) const {
592    return (state_and_flags_.as_struct.flags & flag) != 0;
593  }
594
595  void AtomicSetFlag(ThreadFlag flag);
596
597  void AtomicClearFlag(ThreadFlag flag);
598
599 private:
600  // We have no control over the size of 'bool', but want our boolean fields
601  // to be 4-byte quantities.
602  typedef uint32_t bool32_t;
603
604  explicit Thread(bool daemon);
605  ~Thread() LOCKS_EXCLUDED(Locks::mutator_lock_,
606                           Locks::thread_suspend_count_lock_);
607  void Destroy();
608  friend class ThreadList;  // For ~Thread and Destroy.
609
610  void CreatePeer(const char* name, bool as_daemon, jobject thread_group);
611  friend class Runtime; // For CreatePeer.
612
613  // Avoid use, callers should use SetState. Used only by SignalCatcher::HandleSigQuit and ~Thread.
614  ThreadState SetStateUnsafe(ThreadState new_state) {
615    ThreadState old_state = GetState();
616    state_and_flags_.as_struct.state = new_state;
617    return old_state;
618  }
619  friend class SignalCatcher;  // For SetStateUnsafe.
620
621  void DumpState(std::ostream& os) const;
622  void DumpStack(std::ostream& os) const
623      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
624      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
625
626  // Out-of-line conveniences for debugging in gdb.
627  static Thread* CurrentFromGdb(); // Like Thread::Current.
628  // Like Thread::Dump(std::cerr).
629  void DumpFromGdb() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
630
631  static void* CreateCallback(void* arg);
632
633  void HandleUncaughtExceptions();
634  void RemoveFromThreadGroup();
635
636  void Init(ThreadList*, JavaVMExt*) EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_);
637  void InitCardTable();
638  void InitCpu();
639  void InitFunctionPointers();
640  void InitTid();
641  void InitPthreadKeySelf();
642  void InitStackHwm();
643
644  void NotifyLocked(Thread* self) EXCLUSIVE_LOCKS_REQUIRED(wait_mutex_);
645
646  static void ThreadExitCallback(void* arg);
647
648  // TLS key used to retrieve the Thread*.
649  static pthread_key_t pthread_key_self_;
650
651  // Used to notify threads that they should attempt to resume, they will suspend again if
652  // their suspend count is > 0.
653  static ConditionVariable* resume_cond_ GUARDED_BY(Locks::thread_suspend_count_lock_);
654
655  // --- Frequently accessed fields first for short offsets ---
656
657  // 32 bits of atomically changed state and flags. Keeping as 32 bits allows and atomic CAS to
658  // change from being Suspended to Runnable without a suspend request occurring.
659  union StateAndFlags {
660    struct PACKED(4) {
661      // Bitfield of flag values. Must be changed atomically so that flag values aren't lost. See
662      // ThreadFlags for bit field meanings.
663      volatile uint16_t flags;
664      // Holds the ThreadState. May be changed non-atomically between Suspended (ie not Runnable)
665      // transitions. Changing to Runnable requires that the suspend_request be part of the atomic
666      // operation. If a thread is suspended and a suspend_request is present, a thread may not
667      // change to Runnable as a GC or other operation is in progress.
668      volatile uint16_t state;
669    } as_struct;
670    volatile int32_t as_int;
671  };
672  union StateAndFlags state_and_flags_;
673  COMPILE_ASSERT(sizeof(union StateAndFlags) == sizeof(int32_t),
674                 sizeof_state_and_flags_and_int32_are_different);
675
676  // A non-zero value is used to tell the current thread to enter a safe point
677  // at the next poll.
678  int suspend_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
679
680  // The biased card table, see CardTable for details
681  byte* card_table_;
682
683  // The pending exception or NULL.
684  Throwable* exception_;
685
686  // The end of this thread's stack. This is the lowest safely-addressable address on the stack.
687  // We leave extra space so there's room for the code that throws StackOverflowError.
688  byte* stack_end_;
689
690  // The top of the managed stack often manipulated directly by compiler generated code.
691  ManagedStack managed_stack_;
692
693  // Every thread may have an associated JNI environment
694  JNIEnvExt* jni_env_;
695
696  // Initialized to "this". On certain architectures (such as x86) reading
697  // off of Thread::Current is easy but getting the address of Thread::Current
698  // is hard. This field can be read off of Thread::Current to give the address.
699  Thread* self_;
700
701  // Our managed peer (an instance of java.lang.Thread).
702  jobject peer_;
703
704  // The "lowest addressable byte" of the stack
705  byte* stack_begin_;
706
707  // Size of the stack
708  size_t stack_size_;
709
710  // Thin lock thread id. This is a small integer used by the thin lock implementation.
711  // This is not to be confused with the native thread's tid, nor is it the value returned
712  // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One
713  // important difference between this id and the ids visible to managed code is that these
714  // ones get reused (to ensure that they fit in the number of bits available).
715  uint32_t thin_lock_id_;
716
717  // System thread id.
718  pid_t tid_;
719
720  // Guards the 'interrupted_' and 'wait_monitor_' members.
721  mutable Mutex* wait_mutex_ DEFAULT_MUTEX_ACQUIRED_AFTER;
722  ConditionVariable* wait_cond_ GUARDED_BY(wait_mutex_);
723  // Pointer to the monitor lock we're currently waiting on (or NULL).
724  Monitor* wait_monitor_ GUARDED_BY(wait_mutex_);
725  // Thread "interrupted" status; stays raised until queried or thrown.
726  bool32_t interrupted_ GUARDED_BY(wait_mutex_);
727  // The next thread in the wait set this thread is part of.
728  Thread* wait_next_;
729  // If we're blocked in MonitorEnter, this is the object we're trying to lock.
730  Object* monitor_enter_object_;
731
732  friend class Monitor;
733
734  // Top of linked list of stack indirect reference tables or NULL for none
735  StackIndirectReferenceTable* top_sirt_;
736
737  Runtime* runtime_;
738
739  RuntimeStats stats_;
740
741  // Needed to get the right ClassLoader in JNI_OnLoad, but also
742  // useful for testing.
743  ClassLoader* class_loader_override_;
744
745  // Thread local, lazily allocated, long jump context. Used to deliver exceptions.
746  Context* long_jump_context_;
747
748  // A boolean telling us whether we're recursively throwing OOME.
749  bool32_t throwing_OutOfMemoryError_;
750
751  // How much of 'suspend_count_' is by request of the debugger, used to set things right
752  // when the debugger detaches. Must be <= suspend_count_.
753  int debug_suspend_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
754
755  // JDWP invoke-during-breakpoint support.
756  DebugInvokeReq* debug_invoke_req_;
757
758  // Additional stack used by method instrumentation to store method and return pc values.
759  // Stored as a pointer since std::vector is not PACKED.
760  std::vector<InstrumentationStackFrame>* instrumentation_stack_;
761
762  // A cached copy of the java.lang.Thread's name.
763  std::string* name_;
764
765  // Is the thread a daemon?
766  const bool32_t daemon_;
767
768  // A cached pthread_t for the pthread underlying this Thread*.
769  pthread_t pthread_self_;
770
771  // Support for Mutex lock hierarchy bug detection.
772  BaseMutex* held_mutexes_[kMaxMutexLevel + 1];
773
774  // A positive value implies we're in a region where thread suspension isn't expected.
775  uint32_t no_thread_suspension_;
776
777  // Cause for last suspension.
778  const char* last_no_thread_suspension_cause_;
779
780  // Pending checkpoint functions.
781  Closure* checkpoint_function_;
782
783 public:
784  // Runtime support function pointers
785  // TODO: move this near the top, since changing its offset requires all oats to be recompiled!
786  EntryPoints entrypoints_;
787
788 private:
789  // How many times has our pthread key's destructor been called?
790  uint32_t thread_exit_check_count_;
791
792  friend class ScopedThreadStateChange;
793
794  DISALLOW_COPY_AND_ASSIGN(Thread);
795};
796
797std::ostream& operator<<(std::ostream& os, const Thread& thread);
798std::ostream& operator<<(std::ostream& os, const ThreadState& state);
799
800}  // namespace art
801
802#endif  // ART_SRC_THREAD_H_
803