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