thread.h revision 0399dde18753aa9bd2bd0d7cf60beef154d164a4
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
170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#ifndef ART_SRC_THREAD_H_
180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#define ART_SRC_THREAD_H_
190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
20b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro#include <pthread.h>
21a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
2202b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes#include <bitset>
23a09576416788b916095739e43a16917e7948f3a4Elliott Hughes#include <iosfwd>
24b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include <list>
258daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <string>
26e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include <vector>
27b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
281f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "dex_file.h"
29578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h"
3069f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes#include "jni_internal.h"
31578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "logging.h"
32578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "macros.h"
338daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "mutex.h"
34b765be0d656c3073402693aeaf64e95a0e49f218Brian Carlstrom#include "mem_map.h"
3557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers#include "oat/runtime/oat_support_entrypoints.h"
36578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h"
379d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "runtime_stats.h"
3868e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes#include "stack.h"
39e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "trace.h"
40bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers#include "UniquePtr.h"
41b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art {
430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
4469f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughesclass Array;
4537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughesclass Class;
461f87008b165d26541d832ff805250afdc89c253dBrian Carlstromclass ClassLinker;
47edcc09c737b00462881f147602656739d029571eElliott Hughesclass ClassLoader;
48bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersclass Context;
49475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughesclass DebugInvokeReq;
50a40f9bc48afe3a9d38be2fa298fece13ed82ba28Brian Carlstromclass Method;
518daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesclass Monitor;
520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Object;
53b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass Runtime;
54f7ad17e108b9357d7c94c6218a8521140a667f3dLogan Chienclass ShadowFrame;
5568e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughesclass StackIndirectReferenceTable;
5655df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaoclass StackTraceElement;
571da522de18ac6e4c2913c3233529e9dd115059f8buzbeeclass StaticStorageBase;
5840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass Thread;
5940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass ThreadList;
6040381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass Throwable;
611da522de18ac6e4c2913c3233529e9dd115059f8buzbee
6255df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaotemplate<class T> class ObjectArray;
634417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotemplate<class T> class PrimitiveArray;
644417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotypedef PrimitiveArray<int32_t> IntArray;
650e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
6634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes// Thread priorities. These must match the Thread.MIN_PRIORITY,
6734e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes// Thread.NORM_PRIORITY, and Thread.MAX_PRIORITY constants.
6834e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesenum ThreadPriority {
6934e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kMinThreadPriority = 1,
7034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kNormThreadPriority = 5,
7134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kMaxThreadPriority = 10,
7234e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes};
73fc1d9f581592d54cc14240b9909824af38656931Elliott Hughes
7434e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesenum ThreadState {
7534e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kTerminated   = 0, // Thread.TERMINATED     JDWP TS_ZOMBIE
7634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kRunnable     = 1, // Thread.RUNNABLE       JDWP TS_RUNNING
7734e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kTimedWaiting = 2, // Thread.TIMED_WAITING  JDWP TS_WAIT    - in Object.wait() with a timeout
7834e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kBlocked      = 3, // Thread.BLOCKED        JDWP TS_MONITOR - blocked on a monitor
7934e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kWaiting      = 4, // Thread.WAITING        JDWP TS_WAIT    - in Object.wait()
8034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kStarting     = 5, // Thread.NEW                            - native thread started, not yet ready to run managed code
8134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kNative       = 6, //                                       - running in a JNI native method
8234e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kVmWait       = 7, //                                       - waiting on an internal runtime resource
8334e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  kSuspended    = 8, //                                       - suspended by GC or debugger
8434e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes};
85b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
8634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesclass PACKED Thread {
8734e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes public:
88932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Space to throw a StackOverflowError in.
894165a83d250165c839850651e1b2a69e06128000TDYa#if !defined(ART_USE_LLVM_COMPILER)
90aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  static const size_t kStackOverflowReservedBytes = 4 * KB;
914165a83d250165c839850651e1b2a69e06128000TDYa#else  // LLVM_x86 requires more memory to throw stack overflow exception.
924165a83d250165c839850651e1b2a69e06128000TDYa  static const size_t kStackOverflowReservedBytes = 8 * KB;
934165a83d250165c839850651e1b2a69e06128000TDYa#endif
94c143c55718342519db5398e41dda31422cf16c79buzbee
95462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  // Creates a new native thread corresponding to the given managed peer.
96462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  // Used to implement Thread.start.
9757aba86f29d7e795bf7e68c65cc464d2291b6af1Elliott Hughes  static void CreateNativeThread(Object* peer, size_t stack_size);
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.
101462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  static Thread* Attach(const char* thread_name, bool as_daemon, Object* thread_group);
102b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
103caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  // Reset internal state of child thread after fork.
104caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  void InitAfterFork();
105caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom
1060399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  static Thread* Current() __attribute__ ((pure)) {
107e0447357fa8dece635c213d360cd03160cc2d8a0Elliott Hughes    // We rely on Thread::Current returning NULL for a detached thread, so it's not obvious
108e0447357fa8dece635c213d360cd03160cc2d8a0Elliott Hughes    // that we can replace this with a direct %fs access on x86.
109d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro    void* thread = pthread_getspecific(Thread::pthread_key_self_);
110d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro    return reinterpret_cast<Thread*>(thread);
1110e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
1120e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
113761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  static Thread* FromManagedThread(Object* thread_peer);
11401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  static Thread* FromManagedThread(JNIEnv* env, jobject thread);
1158e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  static uint32_t LockOwnerFromThreadLock(Object* thread_lock);
1168daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
11728fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes  // Translates 172 to pAllocArrayFromCode and so on.
11828fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes  static void DumpThreadOffset(std::ostream& os, uint32_t offset, size_t size_of_pointers);
11928fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes
120899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  // When full == true, dumps the detailed thread state and the thread stack (used for SIGQUIT).
121899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  // When full == false, dumps a one-line summary of thread state (used for operator<<).
122899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  void Dump(std::ostream& os, bool full = true) const;
123a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
124abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes  // Dumps the SIGQUIT per-thread header. 'thread' can be NULL for a non-attached thread, in which
125abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes  // case we use 'tid' to identify the thread, and we'll include as much information as we can.
126abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes  static void DumpState(std::ostream& os, const Thread* thread, pid_t tid);
127abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes
12834e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  ThreadState GetState() const {
1290cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    return state_;
1300cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
1310cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
13234e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  ThreadState SetState(ThreadState new_state);
13334e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  void SetStateWithoutSuspendCheck(ThreadState new_state);
1348d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes
135038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes  bool IsDaemon();
136761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  bool IsSuspended();
137038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes
1388d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes  void WaitUntilSuspended();
1390cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
1400399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Once called thread suspension will cause an assertion failure.
1410399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  void StartAssertNoThreadSuspension() {
1420399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#ifndef NDEBUG
1430399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    no_thread_suspension_++;
1440399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#endif
1450399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
1460399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // End region where no thread suspension is expected.
1470399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  void EndAssertNoThreadSuspension() {
1480399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#ifndef NDEBUG
1490399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    DCHECK_GT(no_thread_suspension_, 0U);
1500399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    no_thread_suspension_--;
1510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#endif
1520399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
1530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
1540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  void AssertThreadSuspensionIsAllowable() const {
1550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    DCHECK_EQ(0u, no_thread_suspension_);
1560399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
1570399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
1580399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  bool CanAccessDirectReferences() const {
1590399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#ifdef MOVING_GARBAGE_COLLECTOR
1600399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    // TODO: when we have a moving collector, we'll need: return state_ == kRunnable;
1610399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#endif
1620399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return true;
1630399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
1640399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
1655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  bool HoldsLock(Object*);
1665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
1678daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /*
1688daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Changes the priority of this thread to match that of the java.lang.Thread object.
1698daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   *
1708daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * We map a priority value from 1-10 to Linux "nice" values, where lower
1718daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * numbers indicate higher priority.
1728daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   */
1738daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  void SetNativePriority(int newPriority);
1748daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
1758daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /*
1768daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Returns the thread priority for the current thread by querying the system.
1778daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * This is useful when attaching a thread through JNI.
1788daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   *
1798daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
1808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   */
1818daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  static int GetNativePriority();
1828daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
183462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  // Returns the "main" ThreadGroup, used when attaching user threads.
184462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  static Object* GetMainThreadGroup();
185462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  // Returns the "system" ThreadGroup, used when attaching our internal threads.
186462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  static Object* GetSystemThreadGroup();
187462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes
188dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  uint32_t GetThinLockId() const {
189dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes    return thin_lock_id_;
190b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  }
191b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
192d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  pid_t GetTid() const {
193d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes    return tid_;
194d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  }
195e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes
196ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  // Returns the java.lang.Thread's name, or NULL if this Thread* doesn't have a peer.
197899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  String* GetThreadName() const;
198899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes
199ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  // Sets 'name' to the java.lang.Thread's name. This requires no transition to managed code,
200ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  // allocation, or locking.
201ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  void GetThreadName(std::string& name) const;
202ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes
203899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  // Sets the thread's name.
204899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  void SetThreadName(const char* name);
205fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes
206d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes  Object* GetPeer() const {
2078daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return peer_;
2088daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
2098daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
210a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes  Object* GetThreadGroup() const;
211a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes
2129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  RuntimeStats* GetStats() {
2139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes    return &stats_;
2149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  }
2159d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
216d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes  int GetSuspendCount() const {
217d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes    return suspend_count_;
218d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes  }
2190cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
2207dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes  bool IsStillStarting() const;
2217dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes
2220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool IsExceptionPending() const {
223b20a554613609dc372073d2ebd9fbc3925a429f5Elliott Hughes    return exception_ != NULL;
2240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
2250e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
226e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  Throwable* GetException() const {
2270cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(CanAccessDirectReferences());
2280e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro    return exception_;
2290e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
2300e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2310cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void SetException(Throwable* new_exception) {
2320cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(CanAccessDirectReferences());
2330cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    CHECK(new_exception != NULL);
2340cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // TODO: CHECK(exception_ == NULL);
2350cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    exception_ = new_exception;  // TODO
2360cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
2370cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
2380cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void ClearException() {
2390cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    exception_ = NULL;
240a09576416788b916095739e43a16917e7948f3a4Elliott Hughes  }
241a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
242bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Find catch block and perform long jump to appropriate exception handle
243ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers  void DeliverException();
244bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
245bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  Context* GetLongJumpContext();
2460399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  void ReleaseLongJumpContext(Context* context) {
2470399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    DCHECK(long_jump_context_ == NULL);
2480399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    long_jump_context_ = context;
2491a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
2501a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
2510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  Method* GetCurrentMethod(uint32_t* dex_pc = NULL, size_t* frame_id = NULL) const;
2520399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
253bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void SetTopOfStack(void* stack, uintptr_t pc) {
2540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    Method** top_method = reinterpret_cast<Method**>(stack);
2550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    managed_stack_.SetTopQuickFrame(top_method);
2560399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    managed_stack_.SetTopQuickFramePc(pc);
2570e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
2580e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2590399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  bool HasManagedStack() const {
2600399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return managed_stack_.GetTopQuickFrame() != NULL || managed_stack_.GetTopShadowFrame() != NULL;
261bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
262bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
263a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes  // If 'msg' is NULL, no detail message is set.
2645cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  void ThrowNewException(const char* exception_class_descriptor, const char* msg);
2655cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
266a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes  // If 'msg' is NULL, no detail message is set. An exception must be pending, and will be
267a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes  // used as the new exception's cause.
268a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes  void ThrowNewWrappedException(const char* exception_class_descriptor, const char* msg);
269a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes
2705cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  void ThrowNewExceptionF(const char* exception_class_descriptor, const char* fmt, ...)
271362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes      __attribute__((format(printf, 3, 4)));
272a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
2734a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes  void ThrowNewExceptionV(const char* exception_class_descriptor, const char* fmt, va_list ap);
2744a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes
2752ced6a534157d5d963693346904389c19775d2daElliott Hughes  // OutOfMemoryError is special, because we need to pre-allocate an instance.
2768a8b9cbe158ee13477f2381f164c519762a06fefElliott Hughes  // Only the GC should call this.
2772ced6a534157d5d963693346904389c19775d2daElliott Hughes  void ThrowOutOfMemoryError(const char* msg);
27879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
2790399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  //QuickFrameIterator FindExceptionHandler(void* throw_pc, void** handler_pc);
2801a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
2811a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  void* FindExceptionHandlerInMethod(const Method* method,
2821a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     void* throw_pc,
2831a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     const DexFile& dex_file,
2841a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     ClassLinker* class_linker);
285c143c55718342519db5398e41dda31422cf16c79buzbee
286be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static void Startup();
287038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes  static void FinishStartup();
288c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes  static void Shutdown();
289b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
290b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // JNI methods
29169f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes  JNIEnvExt* GetJniEnv() const {
292b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return jni_env_;
293b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
294b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
295408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Convert a jobject into a Object*
296408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  Object* DecodeJObject(jobject obj);
297b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
2988daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Implements java.lang.Thread.interrupted.
2998daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  bool Interrupted() {
30085d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
3018daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    bool interrupted = interrupted_;
3028daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    interrupted_ = false;
3038daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return interrupted;
3048daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
3058daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
3068daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Implements java.lang.Thread.isInterrupted.
3078daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  bool IsInterrupted() {
30885d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
3098daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return interrupted_;
3108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
3118daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
3125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void Interrupt() {
31385d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
3145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (interrupted_) {
3155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return;
3165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
3175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    interrupted_ = true;
3185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    NotifyLocked();
3195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
3205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void Notify() {
32285d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
3235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    NotifyLocked();
3245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
3255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
326bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom  const ClassLoader* GetClassLoaderOverride() {
3270cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // TODO: need to place the class_loader_override_ in a handle
3280cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // DCHECK(CanAccessDirectReferences());
329c143c55718342519db5398e41dda31422cf16c79buzbee    return class_loader_override_;
330c143c55718342519db5398e41dda31422cf16c79buzbee  }
331c143c55718342519db5398e41dda31422cf16c79buzbee
332bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom  void SetClassLoaderOverride(const ClassLoader* class_loader_override) {
333c143c55718342519db5398e41dda31422cf16c79buzbee    class_loader_override_ = class_loader_override;
334c143c55718342519db5398e41dda31422cf16c79buzbee  }
335c143c55718342519db5398e41dda31422cf16c79buzbee
336aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  // Create the internal representation of a stack trace, that is more time
337aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  // and space efficient to compute than the StackTraceElement[]
33801158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  jobject CreateInternalStackTrace(JNIEnv* env) const;
33901158d7a57c8321370667a6045220237d16e0da8Elliott Hughes
34001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // Convert an internal stack trace representation (returned by CreateInternalStackTrace) to a
34101158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // StackTraceElement[]. If output_array is NULL, a new array is created, otherwise as many
34201158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // frames as will fit are written into the given array. If stack_depth is non-NULL, it's updated
34301158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // with the number of valid frames in the returned array.
34401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  static jobjectArray InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal,
34501158d7a57c8321370667a6045220237d16e0da8Elliott Hughes      jobjectArray output_array = NULL, int* stack_depth = NULL);
34655df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao
347d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers  void VisitRoots(Heap::RootVisitor* visitor, void* arg);
348410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes
349250455229aa0cc07bbd18174efe510bd52631a99jeffhao#if VERIFY_OBJECT_ENABLED
350250455229aa0cc07bbd18174efe510bd52631a99jeffhao  void VerifyStack();
351250455229aa0cc07bbd18174efe510bd52631a99jeffhao#else
352250455229aa0cc07bbd18174efe510bd52631a99jeffhao  void VerifyStack() {}
353250455229aa0cc07bbd18174efe510bd52631a99jeffhao#endif
354250455229aa0cc07bbd18174efe510bd52631a99jeffhao
355be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  //
356be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  // Offsets of various members of native Thread class, used by compiled code.
357be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  //
358be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
359be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset SelfOffset() {
360be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, self_));
361be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
362be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
363be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset ExceptionOffset() {
364be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_));
365be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
366be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
36754e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes  static ThreadOffset ThinLockIdOffset() {
368be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_));
369be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
370be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
371be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset CardTableOffset() {
372be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_));
373be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
374be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
375be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset SuspendCountOffset() {
376be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_));
377be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
378be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
379be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset StateOffset() {
38093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    return ThreadOffset(OFFSETOF_VOLATILE_MEMBER(Thread, state_));
381be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
382be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
383932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Size of stack less any space reserved for stack overflow
384932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  size_t GetStackSize() {
38530fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    return stack_size_ - (stack_end_ - stack_begin_);
386932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
387932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
388932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Set the stack end to that to be used during a stack overflow
389932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  void SetStackEndForStackOverflow() {
390932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // During stack overflow we allow use of the full stack
39130fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    if (stack_end_ == stack_begin_) {
3923b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes      DumpStack(std::cerr);
3933b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes      LOG(FATAL) << "Need to increase kStackOverflowReservedBytes (currently "
3943b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes                 << kStackOverflowReservedBytes << ")";
3953b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes    }
3963b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes
39730fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    stack_end_ = stack_begin_;
398932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
399932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
400932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Set the stack end to that to be used during regular execution
401932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  void ResetDefaultStackEnd() {
402932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room
403932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // to throw a StackOverflowError.
40430fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    stack_end_ = stack_begin_ + kStackOverflowReservedBytes;
405932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
406932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
407449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  static ThreadOffset StackEndOffset() {
408449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, stack_end_));
409be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
410be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
411be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset JniEnvOffset() {
412be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_));
413be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
414be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
415be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset TopOfManagedStackOffset() {
4160399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) +
4170399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers                        ManagedStack::TopQuickFrameOffset());
418be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
419be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
420bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  static ThreadOffset TopOfManagedStackPcOffset() {
4210399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) +
4220399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers                        ManagedStack::TopQuickFramePcOffset());
4230399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
4240399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
4250399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  const ManagedStack* GetManagedStack() const {
4260399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return &managed_stack_;
4270399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
4280399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
4290399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Linked list recording fragments of managed stack.
4300399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  void PushManagedStackFragment(ManagedStack* fragment) {
4310399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    managed_stack_.PushManagedStackFragment(fragment);
4320399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
4330399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  void PopManagedStackFragment(const ManagedStack& fragment) {
4340399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    managed_stack_.PopManagedStackFragment(fragment);
435bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
436bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
4370399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  ShadowFrame* PushShadowFrame(ShadowFrame* new_top_frame) {
4380399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return managed_stack_.PushShadowFrame(new_top_frame);
439de479be99328d2113bf483e082c9ecf235a34d69TDYa  }
440de479be99328d2113bf483e082c9ecf235a34d69TDYa
441de479be99328d2113bf483e082c9ecf235a34d69TDYa  ShadowFrame* PopShadowFrame() {
4420399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return managed_stack_.PopShadowFrame();
443de479be99328d2113bf483e082c9ecf235a34d69TDYa  }
444f7ad17e108b9357d7c94c6218a8521140a667f3dLogan Chien
445d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa  static ThreadOffset TopShadowFrameOffset() {
4460399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) +
4470399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers                        ManagedStack::TopShadowFrameOffset());
448d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa  }
449d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa
4500399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Number of references allocated in ShadowFrames on this thread
4510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  size_t NumShadowFrameReferences() const {
4520399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return managed_stack_.NumShadowFrameReferences();
4530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  }
4540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
4550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Number of references in SIRTs on this thread
4560399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  size_t NumSirtReferences();
4570399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
4580399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Number of references allocated in SIRTs & shadow frames on this thread
4590399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  size_t NumStackReferences() {
4600399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return NumSirtReferences() + NumShadowFrameReferences();
4610399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  };
4620399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
4630399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Is the given obj in this thread's stack indirect reference table?
4640399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  bool SirtContains(jobject obj);
4650399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
4660399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  void SirtVisitRoots(Heap::RootVisitor* visitor, void* arg);
4670399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
46840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void PushSirt(StackIndirectReferenceTable* sirt);
46940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  StackIndirectReferenceTable* PopSirt();
47040381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom
471be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset TopSirtOffset() {
472be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_));
473be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
474be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
475475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  DebugInvokeReq* GetInvokeReq() {
476475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes    return debug_invoke_req_;
477475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  }
478475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes
479c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes  void SetDebuggerUpdatesEnabled(bool enabled);
480c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes
4810399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  const std::vector<TraceStackFrame>* GetTraceStack() const {
4820399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return trace_stack_;
483e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  }
484e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
4850399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  bool IsTraceStackEmpty() const {
4860399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers    return trace_stack_->empty();
487a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao  }
488a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao
489e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  void PushTraceStackFrame(const TraceStackFrame& frame) {
490e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    trace_stack_->push_back(frame);
491e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  }
492e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
493e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  TraceStackFrame PopTraceStackFrame() {
494e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    TraceStackFrame frame = trace_stack_->back();
495e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    trace_stack_->pop_back();
496e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    return frame;
497e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  }
498e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
499a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes  void CheckSafeToLockOrUnlock(MutexRank rank, bool is_locking);
500a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes  void CheckSafeToWait(MutexRank rank);
501ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes
5020e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private:
503dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  Thread();
504c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes  ~Thread();
505c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes  void Destroy();
506c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes  friend class ThreadList;  // For ~Thread and Destroy.
5070e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
508462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  void CreatePeer(const char* name, bool as_daemon, Object* thread_group);
5095fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes  friend class Runtime; // For CreatePeer.
5105fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes
511d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  void DumpState(std::ostream& os) const;
512d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  void DumpStack(std::ostream& os) const;
513d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
514accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes  // Out-of-line conveniences for debugging in gdb.
515498508c1187dc07d3eae5476784cde20f5224d93Elliott Hughes  static Thread* CurrentFromGdb(); // Like Thread::Current.
516accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes  void DumpFromGdb() const; // Like Thread::Dump(std::cerr).
517accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes
51893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  static void* CreateCallback(void* arg);
51993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes
520accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes  void HandleUncaughtExceptions();
5214514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom  void RemoveFromThreadGroup();
522accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes
523462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  void Init();
5245d76c435082332ef79a22962386fa92a0870e378Ian Rogers  void InitCardTable();
525b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void InitCpu();
5263ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee  void InitFunctionPointers();
527caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  void InitTid();
528caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  void InitPthreadKeySelf();
529be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  void InitStackHwm();
530be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
5315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void NotifyLocked() {
5325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (wait_monitor_ != NULL) {
53385d1545e985ac689db4bad7849880e843707c862Elliott Hughes      wait_cond_->Signal();
5345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
5355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
5365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
537be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static void ThreadExitCallback(void* arg);
538b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
5390399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // TLS key used to retrieve the Thread*.
5400399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  static pthread_key_t pthread_key_self_;
5410399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5420399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // --- Frequently accessed fields first for short offsets ---
5430399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5440399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // A non-zero value is used to tell the current thread to enter a safe point
5450399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // at the next poll.
5460399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  int suspend_count_;
5470399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5480399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // The biased card table, see CardTable for details
5490399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  byte* card_table_;
5500399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // The pending exception or NULL.
5520399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  Throwable* exception_;
5530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // The end of this thread's stack. This is the lowest safely-addressable address on the stack.
5550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // We leave extra space so there's room for the code that throws StackOverflowError.
5560399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  byte* stack_end_;
5570399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5580399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // The top of the managed stack often manipulated directly by compiler generated code.
5590399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  ManagedStack managed_stack_;
5600399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5610399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Every thread may have an associated JNI environment
5620399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  JNIEnvExt* jni_env_;
5630399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5640399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Initialized to "this". On certain architectures (such as x86) reading
5650399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // off of Thread::Current is easy but getting the address of Thread::Current
5660399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // is hard. This field can be read off of Thread::Current to give the address.
5670399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  Thread* self_;
5680399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5690399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  volatile ThreadState state_;
5700399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5710399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Our managed peer (an instance of java.lang.Thread).
5720399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  Object* peer_;
5730399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5740399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // The "lowest addressable byte" of the stack
5750399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  byte* stack_begin_;
5760399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
5770399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Size of the stack
5780399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  size_t stack_size_;
5790399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
580dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // Thin lock thread id. This is a small integer used by the thin lock implementation.
581dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // This is not to be confused with the native thread's tid, nor is it the value returned
582dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One
583dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // important difference between this id and the ids visible to managed code is that these
584dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // ones get reused (to ensure that they fit in the number of bits available).
585dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  uint32_t thin_lock_id_;
586b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
587d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  // System thread id.
588d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  pid_t tid_;
589d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
5908daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Guards the 'interrupted_' and 'wait_monitor_' members.
59185d1545e985ac689db4bad7849880e843707c862Elliott Hughes  mutable Mutex* wait_mutex_;
59285d1545e985ac689db4bad7849880e843707c862Elliott Hughes  ConditionVariable* wait_cond_;
5938daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Pointer to the monitor lock we're currently waiting on (or NULL), guarded by wait_mutex_.
5948daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  Monitor* wait_monitor_;
5958daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Thread "interrupted" status; stays raised until queried or thrown, guarded by wait_mutex_.
5968e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  uint32_t interrupted_;
5975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // The next thread in the wait set this thread is part of.
5985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  Thread* wait_next_;
5998e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // If we're blocked in MonitorEnter, this is the object we're trying to lock.
6008e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  Object* monitor_enter_object_;
6015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
6025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  friend class Monitor;
603dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes
604408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Top of linked list of stack indirect reference tables or NULL for none
605408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable* top_sirt_;
606b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
60769759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  Runtime* runtime_;
60869759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro
6090399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  RuntimeStats stats_;
61045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
611edcc09c737b00462881f147602656739d029571eElliott Hughes  // Needed to get the right ClassLoader in JNI_OnLoad, but also
612edcc09c737b00462881f147602656739d029571eElliott Hughes  // useful for testing.
613bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom  const ClassLoader* class_loader_override_;
614c143c55718342519db5398e41dda31422cf16c79buzbee
615bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Thread local, lazily allocated, long jump context. Used to deliver exceptions.
61685d1545e985ac689db4bad7849880e843707c862Elliott Hughes  Context* long_jump_context_;
617bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
618418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes  // A boolean telling us whether we're recursively throwing OOME.
619726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes  uint32_t throwing_OutOfMemoryError_;
620726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes
6210399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // How much of 'suspend_count_' is by request of the debugger, used to set things right
6220399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // when the debugger detaches. Must be <= suspend_count_.
6230399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  int debug_suspend_count_;
6240399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers
625475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  // JDWP invoke-during-breakpoint support.
626475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  DebugInvokeReq* debug_invoke_req_;
627475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes
628e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  // Additional stack used by method tracer to store method and return pc values.
629e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  // Stored as a pointer since std::vector is not PACKED.
630e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  std::vector<TraceStackFrame>* trace_stack_;
631e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
632899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  // A cached copy of the java.lang.Thread's name.
633899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  std::string* name_;
634899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes
6350d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes  // A cached pthread_t for the pthread underlying this Thread*.
6360d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes  pthread_t pthread_self_;
6370d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes
6380399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // Mutexes held by this thread, see CheckSafeToLockOrUnlock.
639ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  uint32_t held_mutexes_[kMaxMutexRank + 1];
640ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes
6410399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  // A positive value implies we're in a region where thread suspension isn't expected.
6420399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers  uint32_t no_thread_suspension_;
643a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers public:
644a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  // Runtime support function pointers
64557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  EntryPoints entrypoints_;
646a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
647a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers private:
64806f7987f1013638a172715986e8fce3fe884e47aMathieu Chartier  friend class ScopedThreadListLockReleaser;
6490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(Thread);
6500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro};
651bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
652330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Thread& thread);
65334e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesstd::ostream& operator<<(std::ostream& os, const ThreadState& state);
6540e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
655ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughesclass ScopedThreadStateChange {
656ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes public:
65734e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  ScopedThreadStateChange(Thread* thread, ThreadState new_state) : thread_(thread) {
658ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes    old_thread_state_ = thread_->SetState(new_state);
659ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  }
660ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
661ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  ~ScopedThreadStateChange() {
662ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes    thread_->SetState(old_thread_state_);
663ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  }
664ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
665ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes private:
666ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  Thread* thread_;
66734e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  ThreadState old_thread_state_;
668ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  DISALLOW_COPY_AND_ASSIGN(ScopedThreadStateChange);
669ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes};
670ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
6710e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}  // namespace art
6720e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
6730e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif  // ART_SRC_THREAD_H_
674