18d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes/*
28d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Copyright (C) 2011 The Android Open Source Project
38d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *
48d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
58d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * you may not use this file except in compliance with the License.
68d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * You may obtain a copy of the License at
78d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *
88d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
98d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *
108d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Unless required by applicable law or agreed to in writing, software
118d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
128d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * See the License for the specific language governing permissions and
148d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * limitations under the License.
158d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes */
160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_THREAD_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_THREAD_H_
190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
20b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro#include <pthread.h>
21a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
2202b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes#include <bitset>
23306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers#include <deque>
24a09576416788b916095739e43a16917e7948f3a4Elliott Hughes#include <iosfwd>
25b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include <list>
268daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <string>
27b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
28761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
29848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers#include "entrypoints/interpreter/interpreter_entrypoints.h"
30848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers#include "entrypoints/jni/jni_entrypoints.h"
317655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "entrypoints/portable/portable_entrypoints.h"
327655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "entrypoints/quick/quick_entrypoints.h"
33578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h"
34306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers#include "jvalue.h"
3581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers#include "locks.h"
36578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h"
372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "root_visitor.h"
389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "runtime_stats.h"
3968e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes#include "stack.h"
401f5393447b9f45be7918042d9ee7b521376de866Ian Rogers#include "stack_indirect_reference_table.h"
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "thread_state.h"
4262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "throw_location.h"
43bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers#include "UniquePtr.h"
44b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art {
460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
48ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  class ArtMethod;
49848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  class Array;
50848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  class Class;
51848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  class ClassLoader;
52848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  class Object;
53848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  template<class T> class ObjectArray;
54848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  template<class T> class PrimitiveArray;
55848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  typedef PrimitiveArray<int32_t> IntArray;
56848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  class StackTraceElement;
57848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  class StaticStorageBase;
58848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  class Throwable;
592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass BaseMutex;
612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass ClassLinker;
627a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogersclass Closure;
63bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersclass Context;
641b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogersstruct DebugInvokeReq;
6581d425b0b232962441616f8b14f73620bffef5e5Ian Rogersclass DexFile;
66120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogersstruct JavaVMExt;
6781d425b0b232962441616f8b14f73620bffef5e5Ian Rogersstruct JNIEnvExt;
688daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesclass Monitor;
69b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass Runtime;
7000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass ScopedObjectAccess;
7100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass ScopedObjectAccessUnchecked;
72f7ad17e108b9357d7c94c6218a8521140a667f3dLogan Chienclass ShadowFrame;
7340381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass Thread;
7440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass ThreadList;
750e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
7634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes// Thread priorities. These must match the Thread.MIN_PRIORITY,
7734e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes// Thread.NORM_PRIORITY, and Thread.MAX_PRIORITY constants.
7834e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesenum ThreadPriority {
7934e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kMinThreadPriority = 1,
8034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kNormThreadPriority = 5,
8134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kMaxThreadPriority = 10,
8234e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes};
83fc1d9f581592d54cc14240b9909824af38656931Elliott Hughes
84474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogersenum ThreadFlag {
8550ffee20ced9c0c7ac68889c86be8844cf120cf2Ian Rogers  kSuspendRequest   = 1,  // If set implies that suspend_count_ > 0 and the Thread should enter the
8650ffee20ced9c0c7ac68889c86be8844cf120cf2Ian Rogers                          // safepoint handler.
8762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  kCheckpointRequest = 2  // Request that the thread do some checkpoint work and then continue.
88474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers};
89474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers
90df1ce91ba97bc79a0637e5504b39318fb1c9f577Ian Rogersclass PACKED(4) Thread {
9134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes public:
92932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Space to throw a StackOverflowError in.
9362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static const size_t kStackOverflowReservedBytes = 16 * KB;
94c143c55718342519db5398e41dda31422cf16c79buzbee
95462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  // Creates a new native thread corresponding to the given managed peer.
96462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  // Used to implement Thread.start.
9752673ffae0025d86f4023735581f19ebcc477487Ian Rogers  static void CreateNativeThread(JNIEnv* env, jobject peer, size_t stack_size, bool daemon);
9861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
99462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  // Attaches the calling native thread to the runtime, returning the new native peer.
100462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  // Used to implement JNI AttachCurrentThread and AttachCurrentThreadAsDaemon calls.
101664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier  static Thread* Attach(const char* thread_name, bool as_daemon, jobject thread_group,
102664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier                        bool create_peer);
103b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
104caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  // Reset internal state of child thread after fork.
105caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  void InitAfterFork();
106caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom
1070878d654e7be8c9666579e22522704d8887415ccIan Rogers  static Thread* Current() {
108e0447357fa8dece635c213d360cd03160cc2d8a0Elliott Hughes    // We rely on Thread::Current returning NULL for a detached thread, so it's not obvious
109e0447357fa8dece635c213d360cd03160cc2d8a0Elliott Hughes    // that we can replace this with a direct %fs access on x86.
110df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom    if (!is_started_) {
1110878d654e7be8c9666579e22522704d8887415ccIan Rogers      return NULL;
1120878d654e7be8c9666579e22522704d8887415ccIan Rogers    } else {
1130878d654e7be8c9666579e22522704d8887415ccIan Rogers      void* thread = pthread_getspecific(Thread::pthread_key_self_);
1140878d654e7be8c9666579e22522704d8887415ccIan Rogers      return reinterpret_cast<Thread*>(thread);
1150878d654e7be8c9666579e22522704d8887415ccIan Rogers    }
1160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
1170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
1182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts,
1192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                   mirror::Object* thread_peer)
120a77f0f68a59870ff027dad654fe31eb3fdaf3d5djeffhao      EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_)
121b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
122b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
12300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts, jobject thread)
124a77f0f68a59870ff027dad654fe31eb3fdaf3d5djeffhao      EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_)
125b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
126b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1278daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
12828fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes  // Translates 172 to pAllocArrayFromCode and so on.
12928fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes  static void DumpThreadOffset(std::ostream& os, uint32_t offset, size_t size_of_pointers);
13028fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes
13100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Dumps a one-line summary of thread state (used for operator<<).
13200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void ShortDump(std::ostream& os) const;
13300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
13400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Dumps the detailed thread state and the thread stack (used for SIGQUIT).
13500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void Dump(std::ostream& os) const
136b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
137b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
138a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
139abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes  // Dumps the SIGQUIT per-thread header. 'thread' can be NULL for a non-attached thread, in which
140abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes  // case we use 'tid' to identify the thread, and we'll include as much information as we can.
14100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static void DumpState(std::ostream& os, const Thread* thread, pid_t tid)
142cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
143cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
144abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes
145474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  ThreadState GetState() const {
14630e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers    return static_cast<ThreadState>(state_and_flags_.as_struct.state);
1470cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
1480cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
149474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  ThreadState SetState(ThreadState new_state);
1508d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes
15181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  int GetSuspendCount() const EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_suspend_count_lock_) {
15200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return suspend_count_;
15352673ffae0025d86f4023735581f19ebcc477487Ian Rogers  }
15452673ffae0025d86f4023735581f19ebcc477487Ian Rogers
15581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  int GetDebugSuspendCount() const EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_suspend_count_lock_) {
15600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return debug_suspend_count_;
15700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
15800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
159858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  bool IsSuspended() const {
160858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier    union StateAndFlags state_and_flags = state_and_flags_;
161858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier    return state_and_flags.as_struct.state != kRunnable &&
162858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier        (state_and_flags.as_struct.flags & kSuspendRequest) != 0;
16300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
16400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
16501ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers  void ModifySuspendCount(Thread* self, int delta, bool for_debugger)
166b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_suspend_count_lock_);
16700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
1680e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  bool RequestCheckpoint(Closure* function);
169858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier
17000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Called when thread detected that the thread_suspend_count_ was non-zero. Gives up share of
17100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // mutator_lock_ and waits until it is resumed and thread_suspend_count_ is zero.
1729da7f59c9059397182b9a97e898a42ec06d4d646Ian Rogers  void FullSuspendCheck()
173b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
174b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
17500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
17600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Transition from non-runnable to runnable state acquiring share on mutator_lock_.
17700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ThreadState TransitionFromSuspendedToRunnable()
178b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
179693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers      SHARED_LOCK_FUNCTION(Locks::mutator_lock_)
1801ffa32f0be7becec4907b26ead353e4b17e1219cIan Rogers      ALWAYS_INLINE;
18100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
18200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Transition from runnable into a state where mutator privileges are denied. Releases share of
18300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // mutator lock.
18400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void TransitionFromRunnableToSuspended(ThreadState new_state)
185b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
186693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers      UNLOCK_FUNCTION(Locks::mutator_lock_)
1871ffa32f0be7becec4907b26ead353e4b17e1219cIan Rogers      ALWAYS_INLINE;
188038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes
18900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Wait for a debugger suspension on the thread associated with the given peer. Returns the
19000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // thread on success, else NULL. If the thread should be suspended then request_suspension should
19100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // be true on entry. If the suspension times out then *timeout is set to true.
192f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes  static Thread* SuspendForDebugger(jobject peer,  bool request_suspension, bool* timed_out)
193b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::mutator_lock_,
194b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                     Locks::thread_list_lock_,
195b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                     Locks::thread_suspend_count_lock_);
1960cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
1970399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Once called thread suspension will cause an assertion failure.
1980399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#ifndef NDEBUG
19952673ffae0025d86f4023735581f19ebcc477487Ian Rogers  const char* StartAssertNoThreadSuspension(const char* cause) {
20052673ffae0025d86f4023735581f19ebcc477487Ian Rogers    CHECK(cause != NULL);
20152673ffae0025d86f4023735581f19ebcc477487Ian Rogers    const char* previous_cause = last_no_thread_suspension_cause_;
2020399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    no_thread_suspension_++;
20352673ffae0025d86f4023735581f19ebcc477487Ian Rogers    last_no_thread_suspension_cause_ = cause;
20452673ffae0025d86f4023735581f19ebcc477487Ian Rogers    return previous_cause;
2050399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
20652673ffae0025d86f4023735581f19ebcc477487Ian Rogers#else
20752673ffae0025d86f4023735581f19ebcc477487Ian Rogers  const char* StartAssertNoThreadSuspension(const char* cause) {
20852673ffae0025d86f4023735581f19ebcc477487Ian Rogers    CHECK(cause != NULL);
20952673ffae0025d86f4023735581f19ebcc477487Ian Rogers    return NULL;
21052673ffae0025d86f4023735581f19ebcc477487Ian Rogers  }
21152673ffae0025d86f4023735581f19ebcc477487Ian Rogers#endif
21252673ffae0025d86f4023735581f19ebcc477487Ian Rogers
2130399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // End region where no thread suspension is expected.
2140399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#ifndef NDEBUG
21552673ffae0025d86f4023735581f19ebcc477487Ian Rogers  void EndAssertNoThreadSuspension(const char* old_cause) {
21652673ffae0025d86f4023735581f19ebcc477487Ian Rogers    CHECK(old_cause != NULL || no_thread_suspension_ == 1);
21752673ffae0025d86f4023735581f19ebcc477487Ian Rogers    CHECK_GT(no_thread_suspension_, 0U);
2180399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    no_thread_suspension_--;
21952673ffae0025d86f4023735581f19ebcc477487Ian Rogers    last_no_thread_suspension_cause_ = old_cause;
22052673ffae0025d86f4023735581f19ebcc477487Ian Rogers  }
22152673ffae0025d86f4023735581f19ebcc477487Ian Rogers#else
22252673ffae0025d86f4023735581f19ebcc477487Ian Rogers  void EndAssertNoThreadSuspension(const char*) {
2230399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
22452673ffae0025d86f4023735581f19ebcc477487Ian Rogers#endif
2250399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
22600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
22700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void AssertThreadSuspensionIsAllowable(bool check_locks = true) const;
2280399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
22900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  bool IsDaemon() const {
23000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return daemon_;
23100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
23200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
2332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  bool HoldsLock(mirror::Object*);
2345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
2358daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /*
2368daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Changes the priority of this thread to match that of the java.lang.Thread object.
2378daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   *
2388daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * We map a priority value from 1-10 to Linux "nice" values, where lower
2398daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * numbers indicate higher priority.
2408daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   */
2418daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  void SetNativePriority(int newPriority);
2428daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
2438daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /*
2448daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Returns the thread priority for the current thread by querying the system.
2458daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * This is useful when attaching a thread through JNI.
2468daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   *
2478daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
2488daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   */
2498daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  static int GetNativePriority();
2508daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
251dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  uint32_t GetThinLockId() const {
252dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes    return thin_lock_id_;
253b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  }
254b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
255d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  pid_t GetTid() const {
256d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes    return tid_;
257d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  }
258e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes
259ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  // Returns the java.lang.Thread's name, or NULL if this Thread* doesn't have a peer.
2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::String* GetThreadName(const ScopedObjectAccessUnchecked& ts) const
261b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
262899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes
263ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  // Sets 'name' to the java.lang.Thread's name. This requires no transition to managed code,
264ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  // allocation, or locking.
265ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  void GetThreadName(std::string& name) const;
266ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes
267899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  // Sets the thread's name.
268b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void SetThreadName(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
269fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes
27057dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao  // Returns the thread-specific CPU-time clock in microseconds or -1 if unavailable.
27157dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao  uint64_t GetCpuMicroTime() const;
27257dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao
2732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* GetPeer() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
274cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers    CHECK(jpeer_ == NULL);
275cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers    return opeer_;
2768daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
2778daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
27800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  bool HasPeer() const {
27980537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    return jpeer_ != NULL || opeer_ != NULL;
28000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
28100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
2829d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  RuntimeStats* GetStats() {
2839d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes    return &stats_;
2849d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  }
2859d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
2867dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes  bool IsStillStarting() const;
2877dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes
2880e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool IsExceptionPending() const {
2891eab958cde39a7e2f0e5ce01730f4e2e75c72519jeffhao    return exception_ != NULL;
2900e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
2910e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
29262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  mirror::Throwable* GetException(ThrowLocation* throw_location) const
29362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
29462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    if (throw_location != NULL) {
29562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      *throw_location = throw_location_;
29662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    }
2970e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro    return exception_;
2980e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
2990e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
30000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void AssertNoPendingException() const;
30100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
30262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void SetException(const ThrowLocation& throw_location, mirror::Throwable* new_exception)
30362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
3040cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    CHECK(new_exception != NULL);
305474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers    // TODO: DCHECK(!IsExceptionPending());
306474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers    exception_ = new_exception;
30762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    throw_location_ = throw_location;
3080cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
3090cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3100cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void ClearException() {
3110cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    exception_ = NULL;
31262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    throw_location_.Clear();
31394d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao  }
31494d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao
315bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Find catch block and perform long jump to appropriate exception handle
31694d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao  void QuickDeliverException() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
317bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
318bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  Context* GetLongJumpContext();
3190399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  void ReleaseLongJumpContext(Context* context) {
3200399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    DCHECK(long_jump_context_ == NULL);
3210399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    long_jump_context_ = context;
3221a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
3231a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
324ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  mirror::ArtMethod* GetCurrentMethod(uint32_t* dex_pc) const
325b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
3260399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
32762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  ThrowLocation GetCurrentLocationForThrow() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
32862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
329bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void SetTopOfStack(void* stack, uintptr_t pc) {
330ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    mirror::ArtMethod** top_method = reinterpret_cast<mirror::ArtMethod**>(stack);
3310399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    managed_stack_.SetTopQuickFrame(top_method);
3320399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    managed_stack_.SetTopQuickFramePc(pc);
3330e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
3340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
33511ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao  void SetTopOfShadowStack(ShadowFrame* top) {
33611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao    managed_stack_.SetTopShadowFrame(top);
33711ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao  }
33811ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao
3390399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  bool HasManagedStack() const {
3400399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return managed_stack_.GetTopQuickFrame() != NULL || managed_stack_.GetTopShadowFrame() != NULL;
341bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
342bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
343a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes  // If 'msg' is NULL, no detail message is set.
34462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void ThrowNewException(const ThrowLocation& throw_location,
34562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                         const char* exception_class_descriptor, const char* msg)
346b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
3475cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
348a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes  // If 'msg' is NULL, no detail message is set. An exception must be pending, and will be
349a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes  // used as the new exception's cause.
35062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void ThrowNewWrappedException(const ThrowLocation& throw_location,
35162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                const char* exception_class_descriptor,
35262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                const char* msg)
353b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
354a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes
35562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void ThrowNewExceptionF(const ThrowLocation& throw_location,
35662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                          const char* exception_class_descriptor, const char* fmt, ...)
35762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      __attribute__((format(printf, 4, 5)))
358b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
359a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
36062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void ThrowNewExceptionV(const ThrowLocation& throw_location,
36162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                          const char* exception_class_descriptor, const char* fmt, va_list ap)
362b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
3634a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes
3642ced6a534157d5d963693346904389c19775d2daElliott Hughes  // OutOfMemoryError is special, because we need to pre-allocate an instance.
3658a8b9cbe158ee13477f2381f164c519762a06fefElliott Hughes  // Only the GC should call this.
366120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers  void ThrowOutOfMemoryError(const char* msg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
36779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
368be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static void Startup();
369038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes  static void FinishStartup();
370c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes  static void Shutdown();
371b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
372b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // JNI methods
37369f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes  JNIEnvExt* GetJniEnv() const {
374b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return jni_env_;
375b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
376b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
377408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Convert a jobject into a Object*
3782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* DecodeJObject(jobject obj) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
379b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
3808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Implements java.lang.Thread.interrupted.
38181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  bool Interrupted();
3828daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Implements java.lang.Thread.isInterrupted.
38381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  bool IsInterrupted();
38481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void Interrupt();
38581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void Notify();
3865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::ClassLoader* GetClassLoaderOverride() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
388c143c55718342519db5398e41dda31422cf16c79buzbee    return class_loader_override_;
389c143c55718342519db5398e41dda31422cf16c79buzbee  }
390c143c55718342519db5398e41dda31422cf16c79buzbee
3912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void SetClassLoaderOverride(mirror::ClassLoader* class_loader_override) {
392c143c55718342519db5398e41dda31422cf16c79buzbee    class_loader_override_ = class_loader_override;
393c143c55718342519db5398e41dda31422cf16c79buzbee  }
394c143c55718342519db5398e41dda31422cf16c79buzbee
395aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  // Create the internal representation of a stack trace, that is more time
396aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  // and space efficient to compute than the StackTraceElement[]
39764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  jobject CreateInternalStackTrace(const ScopedObjectAccessUnchecked& soa) const
398b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
39901158d7a57c8321370667a6045220237d16e0da8Elliott Hughes
40001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // Convert an internal stack trace representation (returned by CreateInternalStackTrace) to a
40101158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // StackTraceElement[]. If output_array is NULL, a new array is created, otherwise as many
40201158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // frames as will fit are written into the given array. If stack_depth is non-NULL, it's updated
40301158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // with the number of valid frames in the returned array.
40401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  static jobjectArray InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal,
40501158d7a57c8321370667a6045220237d16e0da8Elliott Hughes      jobjectArray output_array = NULL, int* stack_depth = NULL);
40655df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao
40762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void VisitRoots(RootVisitor* visitor, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
4086f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier
4092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void VerifyRoots(VerifyRootVisitor* visitor, void* arg)
4106f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
411410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes
412b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void VerifyStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
413250455229aa0cc07bbd18174efe510bd52631a99jeffhao
414be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  //
415be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  // Offsets of various members of native Thread class, used by compiled code.
416be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  //
417be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
418be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset SelfOffset() {
419be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, self_));
420be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
421be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
422be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset ExceptionOffset() {
423be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_));
424be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
425be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
42607ec8e17c978e3bda0202693e6432b56349a5867Ian Rogers  static ThreadOffset PeerOffset() {
42707ec8e17c978e3bda0202693e6432b56349a5867Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, opeer_));
42807ec8e17c978e3bda0202693e6432b56349a5867Ian Rogers  }
42907ec8e17c978e3bda0202693e6432b56349a5867Ian Rogers
43054e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes  static ThreadOffset ThinLockIdOffset() {
431be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_));
432be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
433be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
434be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset CardTableOffset() {
435be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_));
436be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
437be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
438474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  static ThreadOffset ThreadFlagsOffset() {
439474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, state_and_flags_));
440be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
441be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
442932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Size of stack less any space reserved for stack overflow
443d752132c73072084a3def9257cca4fcee76047b6jeffhao  size_t GetStackSize() const {
44430fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    return stack_size_ - (stack_end_ - stack_begin_);
445932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
446932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
447d752132c73072084a3def9257cca4fcee76047b6jeffhao  byte* GetStackEnd() const {
448d752132c73072084a3def9257cca4fcee76047b6jeffhao    return stack_end_;
449d752132c73072084a3def9257cca4fcee76047b6jeffhao  }
450d752132c73072084a3def9257cca4fcee76047b6jeffhao
451932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Set the stack end to that to be used during a stack overflow
452b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void SetStackEndForStackOverflow() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
453932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
454932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Set the stack end to that to be used during regular execution
455932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  void ResetDefaultStackEnd() {
456932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room
457932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // to throw a StackOverflowError.
45830fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    stack_end_ = stack_begin_ + kStackOverflowReservedBytes;
459932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
460932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
461120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers  bool IsHandlingStackOverflow() const {
462120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers    return stack_end_ == stack_begin_;
463120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers  }
464120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers
465449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  static ThreadOffset StackEndOffset() {
466449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, stack_end_));
467be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
468be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
469be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset JniEnvOffset() {
470be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_));
471be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
472be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
473be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset TopOfManagedStackOffset() {
4740399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) +
4750399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers                        ManagedStack::TopQuickFrameOffset());
476be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
477be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
478bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  static ThreadOffset TopOfManagedStackPcOffset() {
4790399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) +
4800399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers                        ManagedStack::TopQuickFramePcOffset());
4810399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
4820399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
4830399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  const ManagedStack* GetManagedStack() const {
4840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return &managed_stack_;
4850399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
4860399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
4870399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Linked list recording fragments of managed stack.
4880399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  void PushManagedStackFragment(ManagedStack* fragment) {
4890399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    managed_stack_.PushManagedStackFragment(fragment);
4900399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
4910399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  void PopManagedStackFragment(const ManagedStack& fragment) {
4920399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    managed_stack_.PopManagedStackFragment(fragment);
493bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
494bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
4950399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  ShadowFrame* PushShadowFrame(ShadowFrame* new_top_frame) {
4960399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return managed_stack_.PushShadowFrame(new_top_frame);
497de479be99328d2113bf483e082c9ecf235a34d69TDYa  }
498de479be99328d2113bf483e082c9ecf235a34d69TDYa
499de479be99328d2113bf483e082c9ecf235a34d69TDYa  ShadowFrame* PopShadowFrame() {
5000399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return managed_stack_.PopShadowFrame();
501de479be99328d2113bf483e082c9ecf235a34d69TDYa  }
502f7ad17e108b9357d7c94c6218a8521140a667f3dLogan Chien
503d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa  static ThreadOffset TopShadowFrameOffset() {
5040399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) +
5050399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers                        ManagedStack::TopShadowFrameOffset());
506d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa  }
507d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa
508ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  // Number of references allocated in JNI ShadowFrames on this thread
509ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  size_t NumJniShadowFrameReferences() const {
510ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa    return managed_stack_.NumJniShadowFrameReferences();
5110399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
5120399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5130399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Number of references in SIRTs on this thread
5140399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  size_t NumSirtReferences();
5150399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
516ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  // Number of references allocated in SIRTs & JNI shadow frames on this thread
5170399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  size_t NumStackReferences() {
518ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa    return NumSirtReferences() + NumJniShadowFrameReferences();
5190399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  };
5200399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5210399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Is the given obj in this thread's stack indirect reference table?
522cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  bool SirtContains(jobject obj) const;
5230399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void SirtVisitRoots(RootVisitor* visitor, void* arg);
5250399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5261f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  void PushSirt(StackIndirectReferenceTable* sirt) {
5271f5393447b9f45be7918042d9ee7b521376de866Ian Rogers    sirt->SetLink(top_sirt_);
5281f5393447b9f45be7918042d9ee7b521376de866Ian Rogers    top_sirt_ = sirt;
5291f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  }
5301f5393447b9f45be7918042d9ee7b521376de866Ian Rogers
5311f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  StackIndirectReferenceTable* PopSirt() {
5321f5393447b9f45be7918042d9ee7b521376de866Ian Rogers    StackIndirectReferenceTable* sirt = top_sirt_;
5331f5393447b9f45be7918042d9ee7b521376de866Ian Rogers    DCHECK(sirt != NULL);
5341f5393447b9f45be7918042d9ee7b521376de866Ian Rogers    top_sirt_ = top_sirt_->GetLink();
5351f5393447b9f45be7918042d9ee7b521376de866Ian Rogers    return sirt;
5361f5393447b9f45be7918042d9ee7b521376de866Ian Rogers  }
53740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom
538be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset TopSirtOffset() {
539be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_));
540be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
541be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
542475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  DebugInvokeReq* GetInvokeReq() {
543475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes    return debug_invoke_req_;
544475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  }
545475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes
54662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void SetDeoptimizationShadowFrame(ShadowFrame* sf);
54762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void SetDeoptimizationReturnValue(const JValue& ret_val);
548306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers
549306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers  ShadowFrame* GetAndClearDeoptimizationShadowFrame(JValue* ret_val);
550306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers
55162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  std::deque<instrumentation::InstrumentationStackFrame>* GetInstrumentationStack() {
552725a957985171d712d5c048cc3d00ff14968784bjeffhao    return instrumentation_stack_;
553e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  }
554e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
5555ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  std::vector<mirror::ArtMethod*>* GetStackTraceSample() const {
5565ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao    return stack_trace_sample_;
5575ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  }
5585ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao
5595ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  void SetStackTraceSample(std::vector<mirror::ArtMethod*>* sample) {
5605ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao    stack_trace_sample_ = sample;
5615ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  }
5625ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao
5635ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  uint64_t GetTraceClockBase() const {
5645ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao    return trace_clock_base_;
5655ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  }
5665ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao
5675ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  void SetTraceClockBase(uint64_t clock_base) {
5685ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao    trace_clock_base_ = clock_base;
5695ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  }
5705ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao
57181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  BaseMutex* GetHeldMutex(LockLevel level) const {
57200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return held_mutexes_[level];
57300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
57400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
57581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  void SetHeldMutex(LockLevel level, BaseMutex* mutex) {
57600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    held_mutexes_[level] = mutex;
57700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
578ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes
579752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu Chartier  void RunCheckpointFunction();
580858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier
581858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  bool ReadFlag(ThreadFlag flag) const {
582858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier    return (state_and_flags_.as_struct.flags & flag) != 0;
583858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  }
584858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier
5859cec247849c248f6c45a14eae5414b69eb8fc67dJeff Hao  bool TestAllFlags() const {
5869cec247849c248f6c45a14eae5414b69eb8fc67dJeff Hao    return (state_and_flags_.as_struct.flags != 0);
5879cec247849c248f6c45a14eae5414b69eb8fc67dJeff Hao  }
5889cec247849c248f6c45a14eae5414b69eb8fc67dJeff Hao
589858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  void AtomicSetFlag(ThreadFlag flag);
590858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier
591858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  void AtomicClearFlag(ThreadFlag flag);
592858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier
5930e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private:
5945d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes  // We have no control over the size of 'bool', but want our boolean fields
5955d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes  // to be 4-byte quantities.
5965d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes  typedef uint32_t bool32_t;
5975d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes
59852673ffae0025d86f4023735581f19ebcc477487Ian Rogers  explicit Thread(bool daemon);
599b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  ~Thread() LOCKS_EXCLUDED(Locks::mutator_lock_,
600b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                           Locks::thread_suspend_count_lock_);
601c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes  void Destroy();
602c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes  friend class ThreadList;  // For ~Thread and Destroy.
6030e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
604365c10235438607541fa2259a5fec48061b90bd8Ian Rogers  void CreatePeer(const char* name, bool as_daemon, jobject thread_group);
6057934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  friend class Runtime;  // For CreatePeer.
6065fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes
60762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Avoid use, callers should use SetState. Used only by SignalCatcher::HandleSigQuit, ~Thread and
60862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Dbg::Disconnected.
609474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  ThreadState SetStateUnsafe(ThreadState new_state) {
610474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers    ThreadState old_state = GetState();
61130e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers    state_and_flags_.as_struct.state = new_state;
612c747cffa950b8398cb8844d47e2253214c855750Ian Rogers    return old_state;
613c747cffa950b8398cb8844d47e2253214c855750Ian Rogers  }
614474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  friend class SignalCatcher;  // For SetStateUnsafe.
6157934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  friend class Dbg;  // F or SetStateUnsafe.
616c747cffa950b8398cb8844d47e2253214c855750Ian Rogers
61704d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers  void VerifyStackImpl() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
61804d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers
619cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  void DumpState(std::ostream& os) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
62000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void DumpStack(std::ostream& os) const
621b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
622b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
623d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
624accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes  // Out-of-line conveniences for debugging in gdb.
6257934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  static Thread* CurrentFromGdb();  // Like Thread::Current.
62600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Like Thread::Dump(std::cerr).
627b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void DumpFromGdb() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
628accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes
62993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  static void* CreateCallback(void* arg);
63093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes
631cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  void HandleUncaughtExceptions(ScopedObjectAccess& soa)
632cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
633cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  void RemoveFromThreadGroup(ScopedObjectAccess& soa) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
634accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes
635120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers  void Init(ThreadList*, JavaVMExt*) EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_);
6365d76c435082332ef79a22962386fa92a0870e378Ian Rogers  void InitCardTable();
637b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void InitCpu();
638848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  void InitTlsEntryPoints();
639caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  void InitTid();
640caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  void InitPthreadKeySelf();
641be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  void InitStackHwm();
642be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
643d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  void SetUpAlternateSignalStack();
644d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  void TearDownAlternateSignalStack();
645d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes
646c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  void NotifyLocked(Thread* self) EXCLUSIVE_LOCKS_REQUIRED(wait_mutex_);
6475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
648be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static void ThreadExitCallback(void* arg);
649b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
6500878d654e7be8c9666579e22522704d8887415ccIan Rogers  // Has Thread::Startup been called?
6510878d654e7be8c9666579e22522704d8887415ccIan Rogers  static bool is_started_;
6520878d654e7be8c9666579e22522704d8887415ccIan Rogers
6530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // TLS key used to retrieve the Thread*.
6540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  static pthread_key_t pthread_key_self_;
6550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
65600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Used to notify threads that they should attempt to resume, they will suspend again if
65700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // their suspend count is > 0.
658c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  static ConditionVariable* resume_cond_ GUARDED_BY(Locks::thread_suspend_count_lock_);
65900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
6600399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // --- Frequently accessed fields first for short offsets ---
6610399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
662474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  // 32 bits of atomically changed state and flags. Keeping as 32 bits allows and atomic CAS to
663474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  // change from being Suspended to Runnable without a suspend request occurring.
66430e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers  union StateAndFlags {
665df1ce91ba97bc79a0637e5504b39318fb1c9f577Ian Rogers    struct PACKED(4) {
66630e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers      // Bitfield of flag values. Must be changed atomically so that flag values aren't lost. See
66730e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers      // ThreadFlags for bit field meanings.
66830e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers      volatile uint16_t flags;
66930e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers      // Holds the ThreadState. May be changed non-atomically between Suspended (ie not Runnable)
67030e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers      // transitions. Changing to Runnable requires that the suspend_request be part of the atomic
67130e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers      // operation. If a thread is suspended and a suspend_request is present, a thread may not
67230e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers      // change to Runnable as a GC or other operation is in progress.
67301ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers      volatile uint16_t state;
67430e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers    } as_struct;
67501ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers    volatile int32_t as_int;
676474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers  };
67730e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers  union StateAndFlags state_and_flags_;
67830e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers  COMPILE_ASSERT(sizeof(union StateAndFlags) == sizeof(int32_t),
679474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers                 sizeof_state_and_flags_and_int32_are_different);
680474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers
6810399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // A non-zero value is used to tell the current thread to enter a safe point
6820399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // at the next poll.
683b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  int suspend_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
6840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
6850399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // The biased card table, see CardTable for details
6860399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  byte* card_table_;
6870399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
6880399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // The pending exception or NULL.
6892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Throwable* exception_;
6900399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
6910399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // The end of this thread's stack. This is the lowest safely-addressable address on the stack.
6920399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // We leave extra space so there's room for the code that throws StackOverflowError.
6930399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  byte* stack_end_;
6940399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
6950399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // The top of the managed stack often manipulated directly by compiler generated code.
6960399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  ManagedStack managed_stack_;
6970399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
6980399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Every thread may have an associated JNI environment
6990399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  JNIEnvExt* jni_env_;
7000399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
7010399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Initialized to "this". On certain architectures (such as x86) reading
7020399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // off of Thread::Current is easy but getting the address of Thread::Current
7030399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // is hard. This field can be read off of Thread::Current to give the address.
7040399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  Thread* self_;
7050399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
706cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  // Our managed peer (an instance of java.lang.Thread). The jobject version is used during thread
707cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  // start up, until the thread is registered and the local opeer_ is used.
7082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* opeer_;
709cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  jobject jpeer_;
7100399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
7110399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // The "lowest addressable byte" of the stack
7120399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  byte* stack_begin_;
7130399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
7140399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Size of the stack
7150399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  size_t stack_size_;
7160399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
7175ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  // Pointer to previous stack trace captured by sampling profiler.
7185ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  std::vector<mirror::ArtMethod*>* stack_trace_sample_;
7195ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao
7205ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  // The clock base used for tracing.
7215ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  uint64_t trace_clock_base_;
7225ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao
723dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // Thin lock thread id. This is a small integer used by the thin lock implementation.
724dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // This is not to be confused with the native thread's tid, nor is it the value returned
725dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One
726dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // important difference between this id and the ids visible to managed code is that these
727dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // ones get reused (to ensure that they fit in the number of bits available).
728dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  uint32_t thin_lock_id_;
729b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
730d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  // System thread id.
731d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  pid_t tid_;
732d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
73362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  ThrowLocation throw_location_;
73462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
7358daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Guards the 'interrupted_' and 'wait_monitor_' members.
73600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  mutable Mutex* wait_mutex_ DEFAULT_MUTEX_ACQUIRED_AFTER;
73700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ConditionVariable* wait_cond_ GUARDED_BY(wait_mutex_);
73800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Pointer to the monitor lock we're currently waiting on (or NULL).
73900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Monitor* wait_monitor_ GUARDED_BY(wait_mutex_);
74000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Thread "interrupted" status; stays raised until queried or thrown.
74100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  bool32_t interrupted_ GUARDED_BY(wait_mutex_);
7425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // The next thread in the wait set this thread is part of.
7435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  Thread* wait_next_;
7448e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // If we're blocked in MonitorEnter, this is the object we're trying to lock.
7452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::Object* monitor_enter_object_;
7465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
7475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  friend class Monitor;
748f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes  friend class MonitorInfo;
749dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes
750408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Top of linked list of stack indirect reference tables or NULL for none
751408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable* top_sirt_;
752b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
75369759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  Runtime* runtime_;
75469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro
7550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  RuntimeStats stats_;
75645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
757edcc09c737b00462881f147602656739d029571eElliott Hughes  // Needed to get the right ClassLoader in JNI_OnLoad, but also
758edcc09c737b00462881f147602656739d029571eElliott Hughes  // useful for testing.
7592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  mirror::ClassLoader* class_loader_override_;
760c143c55718342519db5398e41dda31422cf16c79buzbee
761bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Thread local, lazily allocated, long jump context. Used to deliver exceptions.
76285d1545e985ac689db4bad7849880e843707c862Elliott Hughes  Context* long_jump_context_;
763bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
764418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes  // A boolean telling us whether we're recursively throwing OOME.
7655d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes  bool32_t throwing_OutOfMemoryError_;
766726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes
7670399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // How much of 'suspend_count_' is by request of the debugger, used to set things right
7680399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // when the debugger detaches. Must be <= suspend_count_.
769b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  int debug_suspend_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
7700399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
771475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  // JDWP invoke-during-breakpoint support.
772475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  DebugInvokeReq* debug_invoke_req_;
773475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes
774306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers  // Shadow frame that is used temporarily during the deoptimization of a method.
775306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers  ShadowFrame* deoptimization_shadow_frame_;
776306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers  JValue deoptimization_return_value_;
777306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers
778725a957985171d712d5c048cc3d00ff14968784bjeffhao  // Additional stack used by method instrumentation to store method and return pc values.
779306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers  // Stored as a pointer since std::deque is not PACKED.
78062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  std::deque<instrumentation::InstrumentationStackFrame>* instrumentation_stack_;
781e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
782899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  // A cached copy of the java.lang.Thread's name.
783899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  std::string* name_;
784899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes
78552673ffae0025d86f4023735581f19ebcc477487Ian Rogers  // Is the thread a daemon?
7865d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes  const bool32_t daemon_;
78752673ffae0025d86f4023735581f19ebcc477487Ian Rogers
7880d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes  // A cached pthread_t for the pthread underlying this Thread*.
7890d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes  pthread_t pthread_self_;
7900d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes
79100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Support for Mutex lock hierarchy bug detection.
7920f827169742aad6209d830db773a101849c32a83Elliott Hughes  BaseMutex* held_mutexes_[kLockLevelCount];
793ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes
7940399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // A positive value implies we're in a region where thread suspension isn't expected.
7950399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  uint32_t no_thread_suspension_;
79652673ffae0025d86f4023735581f19ebcc477487Ian Rogers
79752673ffae0025d86f4023735581f19ebcc477487Ian Rogers  // Cause for last suspension.
79852673ffae0025d86f4023735581f19ebcc477487Ian Rogers  const char* last_no_thread_suspension_cause_;
7995d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes
800858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  // Pending checkpoint functions.
8010e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  Closure* checkpoint_function_;
802858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier
803a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers public:
8047655f29fabc0a12765de828914a18314382e5a35Ian Rogers  // Entrypoint function pointers
8056a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes  // TODO: move this near the top, since changing its offset requires all oats to be recompiled!
806848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  InterpreterEntryPoints interpreter_entrypoints_;
807848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  JniEntryPoints jni_entrypoints_;
8087655f29fabc0a12765de828914a18314382e5a35Ian Rogers  PortableEntryPoints portable_entrypoints_;
809848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  QuickEntryPoints quick_entrypoints_;
810a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
811a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers private:
8126a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes  // How many times has our pthread key's destructor been called?
8136a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes  uint32_t thread_exit_check_count_;
8146a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes
81522f454c7d349c439c774c5d79b32514b190fd531Ian Rogers  friend class ScopedThreadStateChange;
81622f454c7d349c439c774c5d79b32514b190fd531Ian Rogers
8170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(Thread);
8180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro};
819bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
820330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Thread& thread);
82134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesstd::ostream& operator<<(std::ostream& os, const ThreadState& state);
8220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
8230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}  // namespace art
8240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
825fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_THREAD_H_
826