thread.h revision 9da7f59c9059397182b9a97e898a42ec06d4d646
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; 491b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogersstruct DebugInvokeReq; 50a40f9bc48afe3a9d38be2fa298fece13ed82ba28Brian Carlstromclass Method; 518daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesclass Monitor; 520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Object; 53b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass Runtime; 5400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass ScopedObjectAccess; 5500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersclass ScopedObjectAccessUnchecked; 56f7ad17e108b9357d7c94c6218a8521140a667f3dLogan Chienclass ShadowFrame; 5768e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughesclass StackIndirectReferenceTable; 5855df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaoclass StackTraceElement; 591da522de18ac6e4c2913c3233529e9dd115059f8buzbeeclass StaticStorageBase; 6040381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass Thread; 6140381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass ThreadList; 6240381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass Throwable; 631da522de18ac6e4c2913c3233529e9dd115059f8buzbee 6455df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaotemplate<class T> class ObjectArray; 654417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotemplate<class T> class PrimitiveArray; 664417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotypedef PrimitiveArray<int32_t> IntArray; 670e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 6834e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes// Thread priorities. These must match the Thread.MIN_PRIORITY, 6934e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes// Thread.NORM_PRIORITY, and Thread.MAX_PRIORITY constants. 7034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesenum ThreadPriority { 7134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes kMinThreadPriority = 1, 7234e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes kNormThreadPriority = 5, 7334e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes kMaxThreadPriority = 10, 7434e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes}; 75fc1d9f581592d54cc14240b9909824af38656931Elliott Hughes 7634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesenum ThreadState { 7700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kTerminated = 0, // Thread.TERMINATED JDWP TS_ZOMBIE 7800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kRunnable = 1, // Thread.RUNNABLE JDWP TS_RUNNING 7900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kTimedWaiting = 2, // Thread.TIMED_WAITING JDWP TS_WAIT - in Object.wait() with a timeout 8000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kBlocked = 3, // Thread.BLOCKED JDWP TS_MONITOR - blocked on a monitor 8100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kWaiting = 4, // Thread.WAITING JDWP TS_WAIT - in Object.wait() 8200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kWaitingForGcToComplete = 5, // Thread.WAITING JDWP TS_WAIT - blocked waiting for GC 8300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kWaitingPerformingGc = 6, // Thread.WAITING JDWP TS_WAIT - performing GC 8400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kWaitingForDebuggerSend = 7, // Thread.WAITING JDWP TS_WAIT - blocked waiting for events to be sent 8500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kWaitingForDebuggerToAttach = 8, // Thread.WAITING JDWP TS_WAIT - blocked waiting for debugger to attach 8600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kWaitingInMainDebuggerLoop = 9, // Thread.WAITING JDWP TS_WAIT - blocking/reading/processing debugger events 8700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kWaitingForDebuggerSuspension = 10, // Thread.WAITING JDWP TS_WAIT - waiting for debugger suspend all 8800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kWaitingForJniOnLoad = 11, // Thread.WAITING JDWP TS_WAIT - waiting for execution of dlopen and JNI on load code 8900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kWaitingForSignalCatcherOutput = 12, // Thread.WAITING JDWP TS_WAIT - waiting for signal catcher IO to complete 9000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kWaitingInMainSignalCatcherLoop = 13, // Thread.WAITING JDWP TS_WAIT - blocking/reading/processing signals 9100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kStarting = 14, // Thread.NEW JDWP TS_WAIT - native thread started, not yet ready to run managed code 9200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kNative = 15, // Thread.RUNNABLE JDWP TS_RUNNING - running in a JNI native method 9300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers kSuspended = 16, // Thread.RUNNABLE JDWP TS_RUNNING - suspended by GC or debugger 9434e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes}; 95b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 9634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesclass PACKED Thread { 9734e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes public: 98932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Space to throw a StackOverflowError in. 994165a83d250165c839850651e1b2a69e06128000TDYa#if !defined(ART_USE_LLVM_COMPILER) 100aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom static const size_t kStackOverflowReservedBytes = 4 * KB; 1014165a83d250165c839850651e1b2a69e06128000TDYa#else // LLVM_x86 requires more memory to throw stack overflow exception. 1024165a83d250165c839850651e1b2a69e06128000TDYa static const size_t kStackOverflowReservedBytes = 8 * KB; 1034165a83d250165c839850651e1b2a69e06128000TDYa#endif 104c143c55718342519db5398e41dda31422cf16c79buzbee 105462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // Creates a new native thread corresponding to the given managed peer. 106462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // Used to implement Thread.start. 10752673ffae0025d86f4023735581f19ebcc477487Ian Rogers static void CreateNativeThread(JNIEnv* env, jobject peer, size_t stack_size, bool daemon); 10861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 109462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // Attaches the calling native thread to the runtime, returning the new native peer. 110462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // Used to implement JNI AttachCurrentThread and AttachCurrentThreadAsDaemon calls. 111365c10235438607541fa2259a5fec48061b90bd8Ian Rogers static Thread* Attach(const char* thread_name, bool as_daemon, jobject thread_group); 112b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 113caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom // Reset internal state of child thread after fork. 114caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom void InitAfterFork(); 115caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom 1160399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers static Thread* Current() __attribute__ ((pure)) { 117e0447357fa8dece635c213d360cd03160cc2d8a0Elliott Hughes // We rely on Thread::Current returning NULL for a detached thread, so it's not obvious 118e0447357fa8dece635c213d360cd03160cc2d8a0Elliott Hughes // that we can replace this with a direct %fs access on x86. 119d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro void* thread = pthread_getspecific(Thread::pthread_key_self_); 120d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro return reinterpret_cast<Thread*>(thread); 1210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 1220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 12300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts, Object* thread_peer) 12400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(GlobalSynchronization::thread_suspend_count_lock_) 12500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 12600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts, jobject thread) 12700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(GlobalSynchronization::thread_suspend_count_lock_) 12800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 1298daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 13028fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes // Translates 172 to pAllocArrayFromCode and so on. 13128fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes static void DumpThreadOffset(std::ostream& os, uint32_t offset, size_t size_of_pointers); 13228fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes 13300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Dumps a one-line summary of thread state (used for operator<<). 13400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void ShortDump(std::ostream& os) const; 13500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 13600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Dumps the detailed thread state and the thread stack (used for SIGQUIT). 13700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void Dump(std::ostream& os) const 13800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(GlobalSynchronization::thread_suspend_count_lock_) 13900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 140a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 141abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes // Dumps the SIGQUIT per-thread header. 'thread' can be NULL for a non-attached thread, in which 142abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes // case we use 'tid' to identify the thread, and we'll include as much information as we can. 14300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static void DumpState(std::ostream& os, const Thread* thread, pid_t tid) 14400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(GlobalSynchronization::thread_suspend_count_lock_); 145abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes 14600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThreadState GetState() const 14700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXCLUSIVE_LOCKS_REQUIRED(GlobalSynchronization::thread_suspend_count_lock_) { 14800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GlobalSynchronization::thread_suspend_count_lock_->AssertHeld(); 1490cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers return state_; 1500cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 1510cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 15200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThreadState SetState(ThreadState new_state) 15300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXCLUSIVE_LOCKS_REQUIRED(GlobalSynchronization::thread_suspend_count_lock_) { 15400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GlobalSynchronization::thread_suspend_count_lock_->AssertHeld(); 15500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThreadState old_state = state_; 15600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (new_state == kRunnable) { 15700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Sanity, should never become runnable with a pending suspension and should always hold 15800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // share of mutator_lock_. 15900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers CHECK_EQ(GetSuspendCount(), 0); 16000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GlobalSynchronization::mutator_lock_->AssertSharedHeld(); 16100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 16200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers state_ = new_state; 16300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return old_state; 16400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 1658d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes 16600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers int GetSuspendCount() const 16700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXCLUSIVE_LOCKS_REQUIRED(GlobalSynchronization::thread_suspend_count_lock_) { 16800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GlobalSynchronization::thread_suspend_count_lock_->AssertHeld(); 16900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return suspend_count_; 17052673ffae0025d86f4023735581f19ebcc477487Ian Rogers } 17152673ffae0025d86f4023735581f19ebcc477487Ian Rogers 17200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers int GetDebugSuspendCount() const 17300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXCLUSIVE_LOCKS_REQUIRED(GlobalSynchronization::thread_suspend_count_lock_) { 17400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GlobalSynchronization::thread_suspend_count_lock_->AssertHeld(); 17500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return debug_suspend_count_; 17600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 17700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 17800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool IsSuspended() const 17900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXCLUSIVE_LOCKS_REQUIRED(GlobalSynchronization::thread_suspend_count_lock_) { 18000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers int suspend_count = GetSuspendCount(); 18100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return suspend_count != 0 && GetState() != kRunnable; 18200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 18300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 18400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void ModifySuspendCount(int delta, bool for_debugger) 18500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXCLUSIVE_LOCKS_REQUIRED(GlobalSynchronization::thread_suspend_count_lock_); 18600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 18700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Called when thread detected that the thread_suspend_count_ was non-zero. Gives up share of 18800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // mutator_lock_ and waits until it is resumed and thread_suspend_count_ is zero. 1899da7f59c9059397182b9a97e898a42ec06d4d646Ian Rogers void FullSuspendCheck() 1909da7f59c9059397182b9a97e898a42ec06d4d646Ian Rogers LOCKS_EXCLUDED(GlobalSynchronization::thread_suspend_count_lock_) 1919da7f59c9059397182b9a97e898a42ec06d4d646Ian Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 19200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 19300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Transition from non-runnable to runnable state acquiring share on mutator_lock_. 19400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThreadState TransitionFromSuspendedToRunnable() 1959da7f59c9059397182b9a97e898a42ec06d4d646Ian Rogers LOCKS_EXCLUDED(GlobalSynchronization::thread_suspend_count_lock_) 19600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCK_FUNCTION(GlobalSynchronization::mutator_lock_); 19700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 19800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Transition from runnable into a state where mutator privileges are denied. Releases share of 19900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // mutator lock. 20000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void TransitionFromRunnableToSuspended(ThreadState new_state) 2019da7f59c9059397182b9a97e898a42ec06d4d646Ian Rogers LOCKS_EXCLUDED(GlobalSynchronization::thread_suspend_count_lock_) 20200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers UNLOCK_FUNCTION(GlobalSynchronization::mutator_lock_); 203038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes 20400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Wait for a debugger suspension on the thread associated with the given peer. Returns the 20500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // thread on success, else NULL. If the thread should be suspended then request_suspension should 20600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // be true on entry. If the suspension times out then *timeout is set to true. 20700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static Thread* SuspendForDebugger(jobject peer, bool request_suspension, bool* timeout) 20800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(GlobalSynchronization::mutator_lock_, 20900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GlobalSynchronization::thread_list_lock_, 21000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GlobalSynchronization::thread_suspend_count_lock_); 2110cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 2120399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Once called thread suspension will cause an assertion failure. 2130399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#ifndef NDEBUG 21452673ffae0025d86f4023735581f19ebcc477487Ian Rogers const char* StartAssertNoThreadSuspension(const char* cause) { 21552673ffae0025d86f4023735581f19ebcc477487Ian Rogers CHECK(cause != NULL); 21652673ffae0025d86f4023735581f19ebcc477487Ian Rogers const char* previous_cause = last_no_thread_suspension_cause_; 2170399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers no_thread_suspension_++; 21852673ffae0025d86f4023735581f19ebcc477487Ian Rogers last_no_thread_suspension_cause_ = cause; 21952673ffae0025d86f4023735581f19ebcc477487Ian Rogers return previous_cause; 2200399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 22152673ffae0025d86f4023735581f19ebcc477487Ian Rogers#else 22252673ffae0025d86f4023735581f19ebcc477487Ian Rogers const char* StartAssertNoThreadSuspension(const char* cause) { 22352673ffae0025d86f4023735581f19ebcc477487Ian Rogers CHECK(cause != NULL); 22452673ffae0025d86f4023735581f19ebcc477487Ian Rogers return NULL; 22552673ffae0025d86f4023735581f19ebcc477487Ian Rogers } 22652673ffae0025d86f4023735581f19ebcc477487Ian Rogers#endif 22752673ffae0025d86f4023735581f19ebcc477487Ian Rogers 2280399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // End region where no thread suspension is expected. 2290399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#ifndef NDEBUG 23052673ffae0025d86f4023735581f19ebcc477487Ian Rogers void EndAssertNoThreadSuspension(const char* old_cause) { 23152673ffae0025d86f4023735581f19ebcc477487Ian Rogers CHECK(old_cause != NULL || no_thread_suspension_ == 1); 23252673ffae0025d86f4023735581f19ebcc477487Ian Rogers CHECK_GT(no_thread_suspension_, 0U); 2330399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers no_thread_suspension_--; 23452673ffae0025d86f4023735581f19ebcc477487Ian Rogers last_no_thread_suspension_cause_ = old_cause; 23552673ffae0025d86f4023735581f19ebcc477487Ian Rogers } 23652673ffae0025d86f4023735581f19ebcc477487Ian Rogers#else 23752673ffae0025d86f4023735581f19ebcc477487Ian Rogers void EndAssertNoThreadSuspension(const char*) { 2380399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 23952673ffae0025d86f4023735581f19ebcc477487Ian Rogers#endif 2400399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 24100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 24200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#ifndef NDEBUG 24300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void AssertThreadSuspensionIsAllowable(bool check_locks = true) const; 24400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#else 24500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void AssertThreadSuspensionIsAllowable(bool check_locks = true) const { 24600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers check_locks = !check_locks; // Keep GCC happy about unused parameters. 2470399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 24800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#endif 2490399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 2500399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers bool CanAccessDirectReferences() const { 2510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#ifdef MOVING_GARBAGE_COLLECTOR 2520399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // TODO: when we have a moving collector, we'll need: return state_ == kRunnable; 2530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers#endif 2540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return true; 2550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 2560399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 25700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool IsDaemon() const { 25800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return daemon_; 25900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 26000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 2615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes bool HoldsLock(Object*); 2625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 2638daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes /* 2648daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Changes the priority of this thread to match that of the java.lang.Thread object. 2658daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * 2668daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * We map a priority value from 1-10 to Linux "nice" values, where lower 2678daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * numbers indicate higher priority. 2688daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes */ 2698daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes void SetNativePriority(int newPriority); 2708daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 2718daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes /* 2728daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Returns the thread priority for the current thread by querying the system. 2738daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * This is useful when attaching a thread through JNI. 2748daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * 2758daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Returns a value from 1 to 10 (compatible with java.lang.Thread values). 2768daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes */ 2778daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes static int GetNativePriority(); 2788daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 279dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes uint32_t GetThinLockId() const { 280dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes return thin_lock_id_; 281b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 282b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 283d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes pid_t GetTid() const { 284d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes return tid_; 285d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } 286e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes 287ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes // Returns the java.lang.Thread's name, or NULL if this Thread* doesn't have a peer. 28800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers String* GetThreadName(const ScopedObjectAccessUnchecked& ts) const 28900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 290899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes 291ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes // Sets 'name' to the java.lang.Thread's name. This requires no transition to managed code, 292ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes // allocation, or locking. 293ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes void GetThreadName(std::string& name) const; 294ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes 295899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes // Sets the thread's name. 29600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void SetThreadName(const char* name) SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 297fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes 29800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* GetPeer() const SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) { 2998daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes return peer_; 3008daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes } 3018daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 30200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool HasPeer() const { 30300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return peer_ != NULL; 30400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 30500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 30600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* GetThreadGroup(const ScopedObjectAccessUnchecked& ts) const 30700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 308a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes 3099d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes RuntimeStats* GetStats() { 3109d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return &stats_; 3119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 3129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 3137dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes bool IsStillStarting() const; 3147dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes 3150e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool IsExceptionPending() const { 316b20a554613609dc372073d2ebd9fbc3925a429f5Elliott Hughes return exception_ != NULL; 3170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 3180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 31900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Throwable* GetException() const SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) { 3200cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(CanAccessDirectReferences()); 3210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro return exception_; 3220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 3230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 32400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void AssertNoPendingException() const; 32500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 32600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void SetException(Throwable* new_exception) 32700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) { 3280cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(CanAccessDirectReferences()); 3290cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers CHECK(new_exception != NULL); 3300cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // TODO: CHECK(exception_ == NULL); 3310cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers exception_ = new_exception; // TODO 3320cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 3330cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 3340cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers void ClearException() { 3350cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers exception_ = NULL; 336a09576416788b916095739e43a16917e7948f3a4Elliott Hughes } 337a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 338bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Find catch block and perform long jump to appropriate exception handle 33900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void DeliverException() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 340bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 341bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers Context* GetLongJumpContext(); 3420399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers void ReleaseLongJumpContext(Context* context) { 3430399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers DCHECK(long_jump_context_ == NULL); 3440399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers long_jump_context_ = context; 3451a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 3461a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 34700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Method* GetCurrentMethod(uint32_t* dex_pc = NULL, size_t* frame_id = NULL) const 34800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 3490399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 350bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers void SetTopOfStack(void* stack, uintptr_t pc) { 3510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method** top_method = reinterpret_cast<Method**>(stack); 3520399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers managed_stack_.SetTopQuickFrame(top_method); 3530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers managed_stack_.SetTopQuickFramePc(pc); 3540e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 3550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 3560399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers bool HasManagedStack() const { 3570399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return managed_stack_.GetTopQuickFrame() != NULL || managed_stack_.GetTopShadowFrame() != NULL; 358bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 359bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 360a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes // If 'msg' is NULL, no detail message is set. 36100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void ThrowNewException(const char* exception_class_descriptor, const char* msg) 36200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 3635cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes 364a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes // If 'msg' is NULL, no detail message is set. An exception must be pending, and will be 365a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes // used as the new exception's cause. 36600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void ThrowNewWrappedException(const char* exception_class_descriptor, const char* msg) 36700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 368a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes 3695cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes void ThrowNewExceptionF(const char* exception_class_descriptor, const char* fmt, ...) 37000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers __attribute__((format(printf, 3, 4))) 37100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 372a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes 37300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void ThrowNewExceptionV(const char* exception_class_descriptor, const char* fmt, va_list ap) 37400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 3754a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes 3762ced6a534157d5d963693346904389c19775d2daElliott Hughes // OutOfMemoryError is special, because we need to pre-allocate an instance. 3778a8b9cbe158ee13477f2381f164c519762a06fefElliott Hughes // Only the GC should call this. 37800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void ThrowOutOfMemoryError(const char* msg) 37900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 38079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 3810399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers //QuickFrameIterator FindExceptionHandler(void* throw_pc, void** handler_pc); 3821a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 3831a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao void* FindExceptionHandlerInMethod(const Method* method, 3841a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao void* throw_pc, 3851a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao const DexFile& dex_file, 3861a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao ClassLinker* class_linker); 387c143c55718342519db5398e41dda31422cf16c79buzbee 388be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static void Startup(); 389038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes static void FinishStartup(); 390c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes static void Shutdown(); 391b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 392b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // JNI methods 39369f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes JNIEnvExt* GetJniEnv() const { 394b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return jni_env_; 395b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 396b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 397408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Convert a jobject into a Object* 39800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* DecodeJObject(jobject obj) 39900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(JavaVMExt::globals_lock, 40000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaVMExt::weak_globals_lock) 40100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 402b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 4038daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // Implements java.lang.Thread.interrupted. 4048daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes bool Interrupted() { 40585d1545e985ac689db4bad7849880e843707c862Elliott Hughes MutexLock mu(*wait_mutex_); 4068daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes bool interrupted = interrupted_; 4078daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes interrupted_ = false; 4088daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes return interrupted; 4098daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes } 4108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 4118daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // Implements java.lang.Thread.isInterrupted. 4128daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes bool IsInterrupted() { 41385d1545e985ac689db4bad7849880e843707c862Elliott Hughes MutexLock mu(*wait_mutex_); 4148daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes return interrupted_; 4158daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes } 4168daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 4175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes void Interrupt() { 41885d1545e985ac689db4bad7849880e843707c862Elliott Hughes MutexLock mu(*wait_mutex_); 4195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (interrupted_) { 4205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 4215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes interrupted_ = true; 4235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes NotifyLocked(); 4245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes void Notify() { 42785d1545e985ac689db4bad7849880e843707c862Elliott Hughes MutexLock mu(*wait_mutex_); 4285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes NotifyLocked(); 4295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 43100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ClassLoader* GetClassLoaderOverride() 43200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) { 43300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers DCHECK(CanAccessDirectReferences()); 434c143c55718342519db5398e41dda31422cf16c79buzbee return class_loader_override_; 435c143c55718342519db5398e41dda31422cf16c79buzbee } 436c143c55718342519db5398e41dda31422cf16c79buzbee 437365c10235438607541fa2259a5fec48061b90bd8Ian Rogers void SetClassLoaderOverride(ClassLoader* class_loader_override) { 438c143c55718342519db5398e41dda31422cf16c79buzbee class_loader_override_ = class_loader_override; 439c143c55718342519db5398e41dda31422cf16c79buzbee } 440c143c55718342519db5398e41dda31422cf16c79buzbee 441aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Create the internal representation of a stack trace, that is more time 442aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // and space efficient to compute than the StackTraceElement[] 44300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject CreateInternalStackTrace(const ScopedObjectAccess& soa) const 44400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 44501158d7a57c8321370667a6045220237d16e0da8Elliott Hughes 44601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // Convert an internal stack trace representation (returned by CreateInternalStackTrace) to a 44701158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // StackTraceElement[]. If output_array is NULL, a new array is created, otherwise as many 44801158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // frames as will fit are written into the given array. If stack_depth is non-NULL, it's updated 44901158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // with the number of valid frames in the returned array. 45001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes static jobjectArray InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal, 45101158d7a57c8321370667a6045220237d16e0da8Elliott Hughes jobjectArray output_array = NULL, int* stack_depth = NULL); 45255df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao 45300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void VisitRoots(Heap::RootVisitor* visitor, void* arg) 45400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 455410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes 456250455229aa0cc07bbd18174efe510bd52631a99jeffhao#if VERIFY_OBJECT_ENABLED 457357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier void VerifyStack() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 458250455229aa0cc07bbd18174efe510bd52631a99jeffhao#else 459357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier void VerifyStack() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_){} 460250455229aa0cc07bbd18174efe510bd52631a99jeffhao#endif 461250455229aa0cc07bbd18174efe510bd52631a99jeffhao 462be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes // 463be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes // Offsets of various members of native Thread class, used by compiled code. 464be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes // 465be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 466be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset SelfOffset() { 467be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, self_)); 468be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 469be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 470be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset ExceptionOffset() { 471be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_)); 472be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 473be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 47454e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes static ThreadOffset ThinLockIdOffset() { 475be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_)); 476be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 477be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 478be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset CardTableOffset() { 479be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_)); 480be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 481be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 482be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset SuspendCountOffset() { 483be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_)); 484be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 485be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 486be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset StateOffset() { 48793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes return ThreadOffset(OFFSETOF_VOLATILE_MEMBER(Thread, state_)); 488be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 489be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 490932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Size of stack less any space reserved for stack overflow 491932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers size_t GetStackSize() { 49230fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers return stack_size_ - (stack_end_ - stack_begin_); 493932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers } 494932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers 495932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Set the stack end to that to be used during a stack overflow 49600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void SetStackEndForStackOverflow() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 497932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers 498932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Set the stack end to that to be used during regular execution 499932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers void ResetDefaultStackEnd() { 500932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room 501932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // to throw a StackOverflowError. 50230fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers stack_end_ = stack_begin_ + kStackOverflowReservedBytes; 503932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers } 504932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers 505449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes static ThreadOffset StackEndOffset() { 506449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, stack_end_)); 507be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 508be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 509be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset JniEnvOffset() { 510be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_)); 511be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 512be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 513be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset TopOfManagedStackOffset() { 5140399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) + 5150399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ManagedStack::TopQuickFrameOffset()); 516be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 517be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 518bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers static ThreadOffset TopOfManagedStackPcOffset() { 5190399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) + 5200399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ManagedStack::TopQuickFramePcOffset()); 5210399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 5220399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 5230399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const ManagedStack* GetManagedStack() const { 5240399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return &managed_stack_; 5250399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 5260399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 5270399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Linked list recording fragments of managed stack. 5280399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers void PushManagedStackFragment(ManagedStack* fragment) { 5290399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers managed_stack_.PushManagedStackFragment(fragment); 5300399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 5310399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers void PopManagedStackFragment(const ManagedStack& fragment) { 5320399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers managed_stack_.PopManagedStackFragment(fragment); 533bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 534bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 5350399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ShadowFrame* PushShadowFrame(ShadowFrame* new_top_frame) { 5360399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return managed_stack_.PushShadowFrame(new_top_frame); 537de479be99328d2113bf483e082c9ecf235a34d69TDYa } 538de479be99328d2113bf483e082c9ecf235a34d69TDYa 539de479be99328d2113bf483e082c9ecf235a34d69TDYa ShadowFrame* PopShadowFrame() { 5400399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return managed_stack_.PopShadowFrame(); 541de479be99328d2113bf483e082c9ecf235a34d69TDYa } 542f7ad17e108b9357d7c94c6218a8521140a667f3dLogan Chien 543d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa static ThreadOffset TopShadowFrameOffset() { 5440399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) + 5450399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ManagedStack::TopShadowFrameOffset()); 546d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa } 547d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa 5480399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Number of references allocated in ShadowFrames on this thread 5490399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers size_t NumShadowFrameReferences() const { 5500399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return managed_stack_.NumShadowFrameReferences(); 5510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 5520399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 5530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Number of references in SIRTs on this thread 5540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers size_t NumSirtReferences(); 5550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 5560399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Number of references allocated in SIRTs & shadow frames on this thread 5570399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers size_t NumStackReferences() { 5580399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return NumSirtReferences() + NumShadowFrameReferences(); 5590399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers }; 5600399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 5610399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Is the given obj in this thread's stack indirect reference table? 5620399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers bool SirtContains(jobject obj); 5630399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 5640399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers void SirtVisitRoots(Heap::RootVisitor* visitor, void* arg); 5650399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 56640381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom void PushSirt(StackIndirectReferenceTable* sirt); 56740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom StackIndirectReferenceTable* PopSirt(); 56840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom 569be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset TopSirtOffset() { 570be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_)); 571be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 572be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 573475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes DebugInvokeReq* GetInvokeReq() { 574475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes return debug_invoke_req_; 575475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes } 576475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes 577c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes void SetDebuggerUpdatesEnabled(bool enabled); 578c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes 5790399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const std::vector<TraceStackFrame>* GetTraceStack() const { 5800399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return trace_stack_; 581e343b76af81a005ef64f5e75a555389fd9147dabjeffhao } 582e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 5830399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers bool IsTraceStackEmpty() const { 5840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return trace_stack_->empty(); 585a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao } 586a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 587e343b76af81a005ef64f5e75a555389fd9147dabjeffhao void PushTraceStackFrame(const TraceStackFrame& frame) { 588e343b76af81a005ef64f5e75a555389fd9147dabjeffhao trace_stack_->push_back(frame); 589e343b76af81a005ef64f5e75a555389fd9147dabjeffhao } 590e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 591e343b76af81a005ef64f5e75a555389fd9147dabjeffhao TraceStackFrame PopTraceStackFrame() { 592e343b76af81a005ef64f5e75a555389fd9147dabjeffhao TraceStackFrame frame = trace_stack_->back(); 593e343b76af81a005ef64f5e75a555389fd9147dabjeffhao trace_stack_->pop_back(); 594e343b76af81a005ef64f5e75a555389fd9147dabjeffhao return frame; 595e343b76af81a005ef64f5e75a555389fd9147dabjeffhao } 596e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 59700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers BaseMutex* GetHeldMutex(MutexLevel level) const { 59800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return held_mutexes_[level]; 59900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 60000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 60100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void SetHeldMutex(MutexLevel level, BaseMutex* mutex) { 60200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers held_mutexes_[level] = mutex; 60300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 604ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes 6050e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 6065d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes // We have no control over the size of 'bool', but want our boolean fields 6075d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes // to be 4-byte quantities. 6085d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes typedef uint32_t bool32_t; 6095d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes 61052673ffae0025d86f4023735581f19ebcc477487Ian Rogers explicit Thread(bool daemon); 61100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ~Thread() LOCKS_EXCLUDED(GlobalSynchronization::mutator_lock_, 61200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GlobalSynchronization::thread_suspend_count_lock_); 613c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes void Destroy(); 614c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes friend class ThreadList; // For ~Thread and Destroy. 6150e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 616365c10235438607541fa2259a5fec48061b90bd8Ian Rogers void CreatePeer(const char* name, bool as_daemon, jobject thread_group); 6175fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes friend class Runtime; // For CreatePeer. 6185fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 61900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // TODO: remove, callers should use GetState and hold the appropriate locks. Used only by 62000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // ShortDump. 62100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThreadState GetStateUnsafe() const NO_THREAD_SAFETY_ANALYSIS { 62200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return state_; 62300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 62400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 625d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes void DumpState(std::ostream& os) const; 62600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void DumpStack(std::ostream& os) const 62700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(GlobalSynchronization::thread_suspend_count_lock_) 62800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 629d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 630accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // Out-of-line conveniences for debugging in gdb. 631498508c1187dc07d3eae5476784cde20f5224d93Elliott Hughes static Thread* CurrentFromGdb(); // Like Thread::Current. 63200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Like Thread::Dump(std::cerr). 63300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void DumpFromGdb() const SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 634accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 63593e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes static void* CreateCallback(void* arg); 63693e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 63700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void HandleUncaughtExceptions(const ScopedObjectAccess& soa) 63800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 63900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void RemoveFromThreadGroup(const ScopedObjectAccess& soa) 64000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 641accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 642462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes void Init(); 6435d76c435082332ef79a22962386fa92a0870e378Ian Rogers void InitCardTable(); 644b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void InitCpu(); 6453ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee void InitFunctionPointers(); 646caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom void InitTid(); 647caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom void InitPthreadKeySelf(); 648be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes void InitStackHwm(); 649be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 65000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void NotifyLocked() EXCLUSIVE_LOCKS_REQUIRED(wait_mutex_) { 6515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (wait_monitor_ != NULL) { 65285d1545e985ac689db4bad7849880e843707c862Elliott Hughes wait_cond_->Signal(); 6535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 6545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 6555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 656be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static void ThreadExitCallback(void* arg); 657b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 6580399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // TLS key used to retrieve the Thread*. 6590399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers static pthread_key_t pthread_key_self_; 6600399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 66100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Used to notify threads that they should attempt to resume, they will suspend again if 66200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // their suspend count is > 0. 66300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static ConditionVariable* resume_cond_ 66400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GUARDED_BY(GlobalSynchronization::thread_suspend_count_lock_); 66500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 6660399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // --- Frequently accessed fields first for short offsets --- 6670399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 6680399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // A non-zero value is used to tell the current thread to enter a safe point 6690399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // at the next poll. 67000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers int suspend_count_ GUARDED_BY(GlobalSynchronization::thread_suspend_count_lock_); 6710399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 6720399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // The biased card table, see CardTable for details 6730399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers byte* card_table_; 6740399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 6750399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // The pending exception or NULL. 6760399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Throwable* exception_; 6770399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 6780399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // The end of this thread's stack. This is the lowest safely-addressable address on the stack. 6790399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // We leave extra space so there's room for the code that throws StackOverflowError. 6800399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers byte* stack_end_; 6810399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 6820399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // The top of the managed stack often manipulated directly by compiler generated code. 6830399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ManagedStack managed_stack_; 6840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 6850399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Every thread may have an associated JNI environment 6860399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers JNIEnvExt* jni_env_; 6870399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 6880399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Initialized to "this". On certain architectures (such as x86) reading 6890399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // off of Thread::Current is easy but getting the address of Thread::Current 6900399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // is hard. This field can be read off of Thread::Current to give the address. 6910399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Thread* self_; 6920399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 69300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers volatile ThreadState state_ GUARDED_BY(GlobalSynchronization::thread_suspend_count_lock_); 6940399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 6950399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Our managed peer (an instance of java.lang.Thread). 6960399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Object* peer_; 6970399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 6980399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // The "lowest addressable byte" of the stack 6990399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers byte* stack_begin_; 7000399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 7010399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Size of the stack 7020399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers size_t stack_size_; 7030399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 704dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // Thin lock thread id. This is a small integer used by the thin lock implementation. 705dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // This is not to be confused with the native thread's tid, nor is it the value returned 706dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One 707dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // important difference between this id and the ids visible to managed code is that these 708dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // ones get reused (to ensure that they fit in the number of bits available). 709dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes uint32_t thin_lock_id_; 710b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 711d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes // System thread id. 712d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes pid_t tid_; 713d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 7148daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // Guards the 'interrupted_' and 'wait_monitor_' members. 71500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers mutable Mutex* wait_mutex_ DEFAULT_MUTEX_ACQUIRED_AFTER; 71600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ConditionVariable* wait_cond_ GUARDED_BY(wait_mutex_); 71700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Pointer to the monitor lock we're currently waiting on (or NULL). 71800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Monitor* wait_monitor_ GUARDED_BY(wait_mutex_); 71900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Thread "interrupted" status; stays raised until queried or thrown. 72000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool32_t interrupted_ GUARDED_BY(wait_mutex_); 7215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // The next thread in the wait set this thread is part of. 7225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Thread* wait_next_; 7238e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // If we're blocked in MonitorEnter, this is the object we're trying to lock. 7248e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes Object* monitor_enter_object_; 7255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 7265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes friend class Monitor; 727dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 728408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Top of linked list of stack indirect reference tables or NULL for none 729408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers StackIndirectReferenceTable* top_sirt_; 730b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 73169759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Runtime* runtime_; 73269759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro 7330399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers RuntimeStats stats_; 73445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 735edcc09c737b00462881f147602656739d029571eElliott Hughes // Needed to get the right ClassLoader in JNI_OnLoad, but also 736edcc09c737b00462881f147602656739d029571eElliott Hughes // useful for testing. 737365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ClassLoader* class_loader_override_; 738c143c55718342519db5398e41dda31422cf16c79buzbee 739bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Thread local, lazily allocated, long jump context. Used to deliver exceptions. 74085d1545e985ac689db4bad7849880e843707c862Elliott Hughes Context* long_jump_context_; 741bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 742418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes // A boolean telling us whether we're recursively throwing OOME. 7435d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes bool32_t throwing_OutOfMemoryError_; 744726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes 7450399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // How much of 'suspend_count_' is by request of the debugger, used to set things right 7460399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // when the debugger detaches. Must be <= suspend_count_. 74700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers int debug_suspend_count_ GUARDED_BY(GlobalSynchronization::thread_suspend_count_lock_); 7480399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 749475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes // JDWP invoke-during-breakpoint support. 750475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes DebugInvokeReq* debug_invoke_req_; 751475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes 752e343b76af81a005ef64f5e75a555389fd9147dabjeffhao // Additional stack used by method tracer to store method and return pc values. 753e343b76af81a005ef64f5e75a555389fd9147dabjeffhao // Stored as a pointer since std::vector is not PACKED. 754e343b76af81a005ef64f5e75a555389fd9147dabjeffhao std::vector<TraceStackFrame>* trace_stack_; 755e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 756899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes // A cached copy of the java.lang.Thread's name. 757899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes std::string* name_; 758899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes 75952673ffae0025d86f4023735581f19ebcc477487Ian Rogers // Is the thread a daemon? 7605d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes const bool32_t daemon_; 76152673ffae0025d86f4023735581f19ebcc477487Ian Rogers 7620d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes // A cached pthread_t for the pthread underlying this Thread*. 7630d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes pthread_t pthread_self_; 7640d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes 76500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Support for Mutex lock hierarchy bug detection. 76600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers BaseMutex* held_mutexes_[kMaxMutexLevel + 1]; 767ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes 7680399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // A positive value implies we're in a region where thread suspension isn't expected. 7690399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t no_thread_suspension_; 77052673ffae0025d86f4023735581f19ebcc477487Ian Rogers 77152673ffae0025d86f4023735581f19ebcc477487Ian Rogers // Cause for last suspension. 77252673ffae0025d86f4023735581f19ebcc477487Ian Rogers const char* last_no_thread_suspension_cause_; 7735d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes 774a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers public: 775a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers // Runtime support function pointers 7766a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes // TODO: move this near the top, since changing its offset requires all oats to be recompiled! 77757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers EntryPoints entrypoints_; 778a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers 779a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers private: 7806a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes // How many times has our pthread key's destructor been called? 7816a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes uint32_t thread_exit_check_count_; 7826a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes 7830e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(Thread); 7840e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 785bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 786330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Thread& thread); 78734e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesstd::ostream& operator<<(std::ostream& os, const ThreadState& state); 7880e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 7890e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro} // namespace art 7900e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 7910e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif // ART_SRC_THREAD_H_ 792