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