thread.h revision df1ce91ba97bc79a0637e5504b39318fb1c9f577
1561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes/* 2561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * Copyright (C) 2011 The Android Open Source Project 3561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * 4561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * you may not use this file except in compliance with the License. 6561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * You may obtain a copy of the License at 7fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes * 8561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes * 10561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * See the License for the specific language governing permissions and 14561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * limitations under the License. 15561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes */ 16561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 17561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#ifndef ART_SRC_THREAD_H_ 18561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#define ART_SRC_THREAD_H_ 19561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 20561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <pthread.h> 21561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 22561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <bitset> 23561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <iosfwd> 24561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <list> 25561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <string> 26561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include <vector> 27561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 28561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "closure.h" 29561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "globals.h" 30561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "instrumentation.h" 31561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "macros.h" 32561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "oat/runtime/oat_support_entrypoints.h" 33561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "locks.h" 34561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "offsets.h" 35561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "runtime_stats.h" 36561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "stack.h" 37561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "stack_indirect_reference_table.h" 38561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#include "UniquePtr.h" 39561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 40561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesnamespace art { 41561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 42561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass AbstractMethod; 43561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Array; 44561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass BaseMutex; 45561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Class; 46561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass ClassLinker; 47561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass ClassLoader; 48561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Context; 49561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesstruct DebugInvokeReq; 50561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass DexFile; 51561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesstruct JavaVMExt; 52561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesstruct JNIEnvExt; 53561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Monitor; 54561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Object; 55561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Runtime; 56561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass ScopedObjectAccess; 57561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass ScopedObjectAccessUnchecked; 58fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughesclass ShadowFrame; 59561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass StackIndirectReferenceTable; 60fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughesclass StackTraceElement; 61561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass StaticStorageBase; 62fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughesclass Thread; 63561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass ThreadList; 64561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass Throwable; 65561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 66561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughestemplate<class T> class ObjectArray; 67561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughestemplate<class T> class PrimitiveArray; 68561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughestypedef PrimitiveArray<int32_t> IntArray; 69561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 70561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes// Thread priorities. These must match the Thread.MIN_PRIORITY, 71561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes// Thread.NORM_PRIORITY, and Thread.MAX_PRIORITY constants. 72561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesenum ThreadPriority { 73561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kMinThreadPriority = 1, 74561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kNormThreadPriority = 5, 75561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kMaxThreadPriority = 10, 76561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes}; 77561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 78561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesenum ThreadState { 79561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kTerminated = 0, // Thread.TERMINATED JDWP TS_ZOMBIE 80561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kRunnable = 1, // Thread.RUNNABLE JDWP TS_RUNNING 81561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kTimedWaiting = 2, // Thread.TIMED_WAITING JDWP TS_WAIT - in Object.wait() with a timeout 82561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kBlocked = 3, // Thread.BLOCKED JDWP TS_MONITOR - blocked on a monitor 83561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kWaiting = 4, // Thread.WAITING JDWP TS_WAIT - in Object.wait() 84561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kWaitingForGcToComplete = 5, // Thread.WAITING JDWP TS_WAIT - blocked waiting for GC 85561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kWaitingPerformingGc = 6, // Thread.WAITING JDWP TS_WAIT - performing GC 86561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kWaitingForDebuggerSend = 7, // Thread.WAITING JDWP TS_WAIT - blocked waiting for events to be sent 87561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kWaitingForDebuggerToAttach = 8, // Thread.WAITING JDWP TS_WAIT - blocked waiting for debugger to attach 88561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kWaitingInMainDebuggerLoop = 9, // Thread.WAITING JDWP TS_WAIT - blocking/reading/processing debugger events 89561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kWaitingForDebuggerSuspension = 10, // Thread.WAITING JDWP TS_WAIT - waiting for debugger suspend all 90561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kWaitingForJniOnLoad = 11, // Thread.WAITING JDWP TS_WAIT - waiting for execution of dlopen and JNI on load code 91561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kWaitingForSignalCatcherOutput = 12, // Thread.WAITING JDWP TS_WAIT - waiting for signal catcher IO to complete 92561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kWaitingInMainSignalCatcherLoop = 13, // Thread.WAITING JDWP TS_WAIT - blocking/reading/processing signals 93561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kStarting = 14, // Thread.NEW JDWP TS_WAIT - native thread started, not yet ready to run managed code 94561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kNative = 15, // Thread.RUNNABLE JDWP TS_RUNNING - running in a JNI native method 95561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kSuspended = 16, // Thread.RUNNABLE JDWP TS_RUNNING - suspended by GC or debugger 96561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes}; 97561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 98561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesenum ThreadFlag { 99561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kSuspendRequest = 1, // If set implies that suspend_count_ > 0 and the Thread should enter the 100561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // safepoint handler. 101561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kCheckpointRequest = 2, // Request that the thread do some checkpoint work and then continue. 102561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kExceptionPending = 4, // If set implies that exception_ != NULL. 103561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes kEnterInterpreter = 8, // Instruct managed code it should enter the interpreter. 104561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes}; 105561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 106561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesclass PACKED(4) Thread { 107561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes public: 108561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Space to throw a StackOverflowError in. 109561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static const size_t kStackOverflowReservedBytes = 10 * KB; 110561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 111561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Creates a new native thread corresponding to the given managed peer. 112561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Used to implement Thread.start. 113561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static void CreateNativeThread(JNIEnv* env, jobject peer, size_t stack_size, bool daemon); 114561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 115561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Attaches the calling native thread to the runtime, returning the new native peer. 116561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Used to implement JNI AttachCurrentThread and AttachCurrentThreadAsDaemon calls. 117561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static Thread* Attach(const char* thread_name, bool as_daemon, jobject thread_group, 118561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool create_peer); 119561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 120561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Reset internal state of child thread after fork. 121561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void InitAfterFork(); 122561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 123561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static Thread* Current() __attribute__ ((pure)) { 124561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // We rely on Thread::Current returning NULL for a detached thread, so it's not obvious 125561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // that we can replace this with a direct %fs access on x86. 126561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void* thread = pthread_getspecific(Thread::pthread_key_self_); 127561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return reinterpret_cast<Thread*>(thread); 128561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 129561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 130561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts, Object* thread_peer) 131561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_) 132561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 133561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts, jobject thread) 134fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_) 135561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 136561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 137fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes // Translates 172 to pAllocArrayFromCode and so on. 138561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static void DumpThreadOffset(std::ostream& os, uint32_t offset, size_t size_of_pointers); 139561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 140561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Dumps a one-line summary of thread state (used for operator<<). 141561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void ShortDump(std::ostream& os) const; 142fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes 143561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Dumps the detailed thread state and the thread stack (used for SIGQUIT). 144561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void Dump(std::ostream& os) const 145561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_) 146561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 147561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 148561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Dumps the SIGQUIT per-thread header. 'thread' can be NULL for a non-attached thread, in which 149561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // case we use 'tid' to identify the thread, and we'll include as much information as we can. 150561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static void DumpState(std::ostream& os, const Thread* thread, pid_t tid) 151561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_); 152561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 153561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ThreadState GetState() const { 154561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return static_cast<ThreadState>(state_and_flags_.as_struct.state); 155561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 156fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes 157561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ThreadState SetState(ThreadState new_state); 158561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 159561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes int GetSuspendCount() const EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_suspend_count_lock_) { 160561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return suspend_count_; 161561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 162561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 163561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes int GetDebugSuspendCount() const EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_suspend_count_lock_) { 164561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return debug_suspend_count_; 165561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 166561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 167561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool IsSuspended() const { 168561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes union StateAndFlags state_and_flags = state_and_flags_; 169561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return state_and_flags.as_struct.state != kRunnable && 170561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes (state_and_flags.as_struct.flags & kSuspendRequest) != 0; 171561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 172561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 173561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void ModifySuspendCount(Thread* self, int delta, bool for_debugger) 174561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_suspend_count_lock_); 175561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 176561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool RequestCheckpoint(Closure* function); 177561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 178561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Called when thread detected that the thread_suspend_count_ was non-zero. Gives up share of 179561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // mutator_lock_ and waits until it is resumed and thread_suspend_count_ is zero. 180561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void FullSuspendCheck() 181561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_) 182561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 183561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 184561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Transition from non-runnable to runnable state acquiring share on mutator_lock_. 185561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ThreadState TransitionFromSuspendedToRunnable() 186561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_) 187fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes SHARED_LOCK_FUNCTION(Locks::mutator_lock_); 188561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 189561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Transition from runnable into a state where mutator privileges are denied. Releases share of 190561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // mutator lock. 191561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void TransitionFromRunnableToSuspended(ThreadState new_state) 192561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_) 193561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes UNLOCK_FUNCTION(Locks::mutator_lock_); 194561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 195561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Wait for a debugger suspension on the thread associated with the given peer. Returns the 196561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // thread on success, else NULL. If the thread should be suspended then request_suspension should 197561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // be true on entry. If the suspension times out then *timeout is set to true. 198561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static Thread* SuspendForDebugger(jobject peer, bool request_suspension, bool* timeout) 199561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes LOCKS_EXCLUDED(Locks::mutator_lock_, 200561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes Locks::thread_list_lock_, 201561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes Locks::thread_suspend_count_lock_); 202561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 203561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Once called thread suspension will cause an assertion failure. 204561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#ifndef NDEBUG 205561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes const char* StartAssertNoThreadSuspension(const char* cause) { 206561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes CHECK(cause != NULL); 207561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes const char* previous_cause = last_no_thread_suspension_cause_; 208561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes no_thread_suspension_++; 209561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes last_no_thread_suspension_cause_ = cause; 210561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return previous_cause; 211561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 212561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#else 213561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes const char* StartAssertNoThreadSuspension(const char* cause) { 214561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes CHECK(cause != NULL); 215561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return NULL; 216561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 217561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#endif 218561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 219561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // End region where no thread suspension is expected. 220561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#ifndef NDEBUG 221561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void EndAssertNoThreadSuspension(const char* old_cause) { 222561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes CHECK(old_cause != NULL || no_thread_suspension_ == 1); 223561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes CHECK_GT(no_thread_suspension_, 0U); 224561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes no_thread_suspension_--; 225561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes last_no_thread_suspension_cause_ = old_cause; 226561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 227561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#else 228fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes void EndAssertNoThreadSuspension(const char*) { 229561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 230561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#endif 231fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes 232561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 233561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#ifndef NDEBUG 234561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void AssertThreadSuspensionIsAllowable(bool check_locks = true) const; 235561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#else 236561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void AssertThreadSuspensionIsAllowable(bool check_locks = true) const { 237561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes UNUSED(check_locks); // Keep GCC happy about unused parameters. 238561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 239561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#endif 240561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 241561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool IsDaemon() const { 242561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return daemon_; 243fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes } 244561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 245561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool HoldsLock(Object*); 246561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 247561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes /* 248561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * Changes the priority of this thread to match that of the java.lang.Thread object. 249561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * 250561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * We map a priority value from 1-10 to Linux "nice" values, where lower 251561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * numbers indicate higher priority. 252561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes */ 253561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void SetNativePriority(int newPriority); 254561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 255561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes /* 256561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * Returns the thread priority for the current thread by querying the system. 257561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * This is useful when attaching a thread through JNI. 258561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * 259561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * Returns a value from 1 to 10 (compatible with java.lang.Thread values). 260561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes */ 261561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static int GetNativePriority(); 262561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 263561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes uint32_t GetThinLockId() const { 264561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return thin_lock_id_; 265561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 266561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 267561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes pid_t GetTid() const { 268561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return tid_; 269561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 270561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 271561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Returns the java.lang.Thread's name, or NULL if this Thread* doesn't have a peer. 272561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes String* GetThreadName(const ScopedObjectAccessUnchecked& ts) const 273fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 274561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 275561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Sets 'name' to the java.lang.Thread's name. This requires no transition to managed code, 276561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // allocation, or locking. 277561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void GetThreadName(std::string& name) const; 278fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes 279561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Sets the thread's name. 280561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void SetThreadName(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 281561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 282561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes jobject GetPeer() const { 283561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return peer_; 284561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 285fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes 286561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool HasPeer() const { 287561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return peer_ != NULL; 288561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 289561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 290561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes RuntimeStats* GetStats() { 291561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return &stats_; 292561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 293561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 294561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool IsStillStarting() const; 295561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 296561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool IsExceptionPending() const { 297561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool result = ReadFlag(kExceptionPending); 298561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes DCHECK_EQ(result, exception_ != NULL); 299561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return result; 300561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 301561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 302561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes Throwable* GetException() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 303561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return exception_; 304561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 305561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 306561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void AssertNoPendingException() const; 307561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 308561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void SetException(Throwable* new_exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 309561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes CHECK(new_exception != NULL); 310561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // TODO: DCHECK(!IsExceptionPending()); 311561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes exception_ = new_exception; 312561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes AtomicSetFlag(kExceptionPending); 313561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes DCHECK(IsExceptionPending()); 314561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 315561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 316561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void ClearException() { 317561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes exception_ = NULL; 318561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes AtomicClearFlag(kExceptionPending); 319561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes DCHECK(!IsExceptionPending()); 320561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 321561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 322561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void DeliverException(Throwable* exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 323561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes if (exception == NULL) { 324561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ThrowNewException("Ljava/lang/NullPointerException;", "throw with null exception"); 325561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } else { 326561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SetException(exception); 327561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 328561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 329561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 330561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Find catch block and perform long jump to appropriate exception handle 331561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void QuickDeliverException() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 332561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 333561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes Context* GetLongJumpContext(); 334561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void ReleaseLongJumpContext(Context* context) { 335561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes DCHECK(long_jump_context_ == NULL); 336561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes long_jump_context_ = context; 337561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 338561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 339561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes AbstractMethod* GetCurrentMethod(uint32_t* dex_pc = NULL, size_t* frame_id = NULL) const 340561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 341561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 342561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void SetTopOfStack(void* stack, uintptr_t pc) { 343561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes AbstractMethod** top_method = reinterpret_cast<AbstractMethod**>(stack); 344561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes managed_stack_.SetTopQuickFrame(top_method); 345561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes managed_stack_.SetTopQuickFramePc(pc); 346561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 347561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 348561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool HasManagedStack() const { 349561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return managed_stack_.GetTopQuickFrame() != NULL || managed_stack_.GetTopShadowFrame() != NULL; 350561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 351561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 352561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // If 'msg' is NULL, no detail message is set. 353561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void ThrowNewException(const char* exception_class_descriptor, const char* msg) 354561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 355561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 356561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // If 'msg' is NULL, no detail message is set. An exception must be pending, and will be 357561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // used as the new exception's cause. 358561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void ThrowNewWrappedException(const char* exception_class_descriptor, const char* msg) 359561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 360561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 361561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void ThrowNewExceptionF(const char* exception_class_descriptor, const char* fmt, ...) 362561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes __attribute__((format(printf, 3, 4))) 363561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 364561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 365561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void ThrowNewExceptionV(const char* exception_class_descriptor, const char* fmt, va_list ap) 366561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 367561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 368561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // OutOfMemoryError is special, because we need to pre-allocate an instance. 369561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Only the GC should call this. 370561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void ThrowOutOfMemoryError(const char* msg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 371561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 372561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes //QuickFrameIterator FindExceptionHandler(void* throw_pc, void** handler_pc); 373561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 374561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void* FindExceptionHandlerInMethod(const AbstractMethod* method, 375561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void* throw_pc, 376561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes const DexFile& dex_file, 377561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ClassLinker* class_linker); 378561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 379561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static void Startup(); 380561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static void FinishStartup(); 381561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static void Shutdown(); 382561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 383561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // JNI methods 384561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes JNIEnvExt* GetJniEnv() const { 385561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return jni_env_; 386561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 387561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 388561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Convert a jobject into a Object* 389561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes Object* DecodeJObject(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 390561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 391561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Implements java.lang.Thread.interrupted. 392561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool Interrupted(); 393561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Implements java.lang.Thread.isInterrupted. 394561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool IsInterrupted(); 395561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void Interrupt(); 396561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void Notify(); 397561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 398561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ClassLoader* GetClassLoaderOverride() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 399561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return class_loader_override_; 400561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 401561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 402561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void SetClassLoaderOverride(ClassLoader* class_loader_override) { 403561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes class_loader_override_ = class_loader_override; 404561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 405561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 406561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Create the internal representation of a stack trace, that is more time 407561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // and space efficient to compute than the StackTraceElement[] 408561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes jobject CreateInternalStackTrace(const ScopedObjectAccessUnchecked& soa) const 409561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 410561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 411561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Convert an internal stack trace representation (returned by CreateInternalStackTrace) to a 412561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // StackTraceElement[]. If output_array is NULL, a new array is created, otherwise as many 413561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // frames as will fit are written into the given array. If stack_depth is non-NULL, it's updated 414561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // with the number of valid frames in the returned array. 415561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static jobjectArray InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal, 416561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes jobjectArray output_array = NULL, int* stack_depth = NULL); 417561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 418561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void VisitRoots(Heap::RootVisitor* visitor, void* arg) 419561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 420561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 421561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void VerifyRoots(Heap::VerifyRootVisitor* visitor, void* arg) 422561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 423561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 424561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#if VERIFY_OBJECT_ENABLED 425561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void VerifyStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 426561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#else 427561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void VerifyStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){} 428561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes#endif 429561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 430561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // 431561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Offsets of various members of native Thread class, used by compiled code. 432561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // 433561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 434561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset SelfOffset() { 435561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, self_)); 436561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 437561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 438561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset ExceptionOffset() { 439561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_)); 440561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 441561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 442561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset ThinLockIdOffset() { 443561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_)); 444561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 445561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 446561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset CardTableOffset() { 447561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_)); 448561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 449561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 450561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset ThreadFlagsOffset() { 451561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, state_and_flags_)); 452561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 453561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 454561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Size of stack less any space reserved for stack overflow 455561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes size_t GetStackSize() const { 456561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return stack_size_ - (stack_end_ - stack_begin_); 457561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 458561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 459561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes byte* GetStackEnd() const { 460561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return stack_end_; 461561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 462561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 463561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Set the stack end to that to be used during a stack overflow 464561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void SetStackEndForStackOverflow() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 465561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 466561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Set the stack end to that to be used during regular execution 467561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void ResetDefaultStackEnd() { 468561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room 469561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // to throw a StackOverflowError. 470561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes stack_end_ = stack_begin_ + kStackOverflowReservedBytes; 471561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 472561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 473561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool IsHandlingStackOverflow() const { 474561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return stack_end_ == stack_begin_; 475561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 476561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 477561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset StackEndOffset() { 478561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, stack_end_)); 479561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 480561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 481561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset JniEnvOffset() { 482561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_)); 483561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 484561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 485561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset TopOfManagedStackOffset() { 486561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) + 487561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ManagedStack::TopQuickFrameOffset()); 488561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 489561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 490561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset TopOfManagedStackPcOffset() { 491561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) + 492561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ManagedStack::TopQuickFramePcOffset()); 493561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 494561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 495561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes const ManagedStack* GetManagedStack() const { 496561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return &managed_stack_; 497561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 498561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 499561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Linked list recording fragments of managed stack. 500561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void PushManagedStackFragment(ManagedStack* fragment) { 501561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes managed_stack_.PushManagedStackFragment(fragment); 502561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 503561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void PopManagedStackFragment(const ManagedStack& fragment) { 504561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes managed_stack_.PopManagedStackFragment(fragment); 505561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 506561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 507561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ShadowFrame* PushShadowFrame(ShadowFrame* new_top_frame) { 508561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return managed_stack_.PushShadowFrame(new_top_frame); 509561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 510561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 511561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ShadowFrame* PopShadowFrame() { 512561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return managed_stack_.PopShadowFrame(); 513561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 514561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 515561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset TopShadowFrameOffset() { 516561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, managed_stack_) + 517561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes ManagedStack::TopShadowFrameOffset()); 518fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes } 519561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 520561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Number of references allocated in ShadowFrames on this thread 521561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes size_t NumShadowFrameReferences() const { 522561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return managed_stack_.NumShadowFrameReferences(); 523561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 524561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 525561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Number of references in SIRTs on this thread 526561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes size_t NumSirtReferences(); 527561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 528561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Number of references allocated in SIRTs & shadow frames on this thread 529561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes size_t NumStackReferences() { 530fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes return NumSirtReferences() + NumShadowFrameReferences(); 531561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes }; 532561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 533561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes // Is the given obj in this thread's stack indirect reference table? 534561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes bool SirtContains(jobject obj); 535561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 536561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void SirtVisitRoots(Heap::RootVisitor* visitor, void* arg); 537561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 538561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void PushSirt(StackIndirectReferenceTable* sirt) { 539561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes sirt->SetLink(top_sirt_); 540561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes top_sirt_ = sirt; 541561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 542561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 543561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes StackIndirectReferenceTable* PopSirt() { 544561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes StackIndirectReferenceTable* sirt = top_sirt_; 545561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes DCHECK(sirt != NULL); 546561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes top_sirt_ = top_sirt_->GetLink(); 547561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return sirt; 548561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 549561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 550561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes static ThreadOffset TopSirtOffset() { 551561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_)); 552561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 553561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 554561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes DebugInvokeReq* GetInvokeReq() { 555561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return debug_invoke_req_; 556561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 557561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 558561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes void SetDebuggerUpdatesEnabled(bool enabled); 559561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes 560561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes const std::vector<InstrumentationStackFrame>* GetInstrumentationStack() const { 561561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes return instrumentation_stack_; 562561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes } 563 564 bool IsInstrumentationStackEmpty() const { 565 return instrumentation_stack_->empty(); 566 } 567 568 void PushInstrumentationStackFrame(const InstrumentationStackFrame& frame) { 569 instrumentation_stack_->push_back(frame); 570 } 571 572 InstrumentationStackFrame PopInstrumentationStackFrame() { 573 InstrumentationStackFrame frame = instrumentation_stack_->back(); 574 instrumentation_stack_->pop_back(); 575 return frame; 576 } 577 578 BaseMutex* GetHeldMutex(LockLevel level) const { 579 return held_mutexes_[level]; 580 } 581 582 void SetHeldMutex(LockLevel level, BaseMutex* mutex) { 583 held_mutexes_[level] = mutex; 584 } 585 586 void RunCheckpointFunction() { 587 CHECK(checkpoint_function_ != NULL); 588 checkpoint_function_->Run(this); 589 } 590 591 bool ReadFlag(ThreadFlag flag) const { 592 return (state_and_flags_.as_struct.flags & flag) != 0; 593 } 594 595 void AtomicSetFlag(ThreadFlag flag); 596 597 void AtomicClearFlag(ThreadFlag flag); 598 599 private: 600 // We have no control over the size of 'bool', but want our boolean fields 601 // to be 4-byte quantities. 602 typedef uint32_t bool32_t; 603 604 explicit Thread(bool daemon); 605 ~Thread() LOCKS_EXCLUDED(Locks::mutator_lock_, 606 Locks::thread_suspend_count_lock_); 607 void Destroy(); 608 friend class ThreadList; // For ~Thread and Destroy. 609 610 void CreatePeer(const char* name, bool as_daemon, jobject thread_group); 611 friend class Runtime; // For CreatePeer. 612 613 // Avoid use, callers should use SetState. Used only by SignalCatcher::HandleSigQuit and ~Thread. 614 ThreadState SetStateUnsafe(ThreadState new_state) { 615 ThreadState old_state = GetState(); 616 state_and_flags_.as_struct.state = new_state; 617 return old_state; 618 } 619 friend class SignalCatcher; // For SetStateUnsafe. 620 621 void DumpState(std::ostream& os) const; 622 void DumpStack(std::ostream& os) const 623 LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_) 624 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 625 626 // Out-of-line conveniences for debugging in gdb. 627 static Thread* CurrentFromGdb(); // Like Thread::Current. 628 // Like Thread::Dump(std::cerr). 629 void DumpFromGdb() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 630 631 static void* CreateCallback(void* arg); 632 633 void HandleUncaughtExceptions(); 634 void RemoveFromThreadGroup(); 635 636 void Init(ThreadList*, JavaVMExt*) EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_); 637 void InitCardTable(); 638 void InitCpu(); 639 void InitFunctionPointers(); 640 void InitTid(); 641 void InitPthreadKeySelf(); 642 void InitStackHwm(); 643 644 void NotifyLocked(Thread* self) EXCLUSIVE_LOCKS_REQUIRED(wait_mutex_); 645 646 static void ThreadExitCallback(void* arg); 647 648 // TLS key used to retrieve the Thread*. 649 static pthread_key_t pthread_key_self_; 650 651 // Used to notify threads that they should attempt to resume, they will suspend again if 652 // their suspend count is > 0. 653 static ConditionVariable* resume_cond_ GUARDED_BY(Locks::thread_suspend_count_lock_); 654 655 // --- Frequently accessed fields first for short offsets --- 656 657 // 32 bits of atomically changed state and flags. Keeping as 32 bits allows and atomic CAS to 658 // change from being Suspended to Runnable without a suspend request occurring. 659 union StateAndFlags { 660 struct PACKED(4) { 661 // Bitfield of flag values. Must be changed atomically so that flag values aren't lost. See 662 // ThreadFlags for bit field meanings. 663 volatile uint16_t flags; 664 // Holds the ThreadState. May be changed non-atomically between Suspended (ie not Runnable) 665 // transitions. Changing to Runnable requires that the suspend_request be part of the atomic 666 // operation. If a thread is suspended and a suspend_request is present, a thread may not 667 // change to Runnable as a GC or other operation is in progress. 668 volatile uint16_t state; 669 } as_struct; 670 volatile int32_t as_int; 671 }; 672 union StateAndFlags state_and_flags_; 673 COMPILE_ASSERT(sizeof(union StateAndFlags) == sizeof(int32_t), 674 sizeof_state_and_flags_and_int32_are_different); 675 676 // A non-zero value is used to tell the current thread to enter a safe point 677 // at the next poll. 678 int suspend_count_ GUARDED_BY(Locks::thread_suspend_count_lock_); 679 680 // The biased card table, see CardTable for details 681 byte* card_table_; 682 683 // The pending exception or NULL. 684 Throwable* exception_; 685 686 // The end of this thread's stack. This is the lowest safely-addressable address on the stack. 687 // We leave extra space so there's room for the code that throws StackOverflowError. 688 byte* stack_end_; 689 690 // The top of the managed stack often manipulated directly by compiler generated code. 691 ManagedStack managed_stack_; 692 693 // Every thread may have an associated JNI environment 694 JNIEnvExt* jni_env_; 695 696 // Initialized to "this". On certain architectures (such as x86) reading 697 // off of Thread::Current is easy but getting the address of Thread::Current 698 // is hard. This field can be read off of Thread::Current to give the address. 699 Thread* self_; 700 701 // Our managed peer (an instance of java.lang.Thread). 702 jobject peer_; 703 704 // The "lowest addressable byte" of the stack 705 byte* stack_begin_; 706 707 // Size of the stack 708 size_t stack_size_; 709 710 // Thin lock thread id. This is a small integer used by the thin lock implementation. 711 // This is not to be confused with the native thread's tid, nor is it the value returned 712 // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One 713 // important difference between this id and the ids visible to managed code is that these 714 // ones get reused (to ensure that they fit in the number of bits available). 715 uint32_t thin_lock_id_; 716 717 // System thread id. 718 pid_t tid_; 719 720 // Guards the 'interrupted_' and 'wait_monitor_' members. 721 mutable Mutex* wait_mutex_ DEFAULT_MUTEX_ACQUIRED_AFTER; 722 ConditionVariable* wait_cond_ GUARDED_BY(wait_mutex_); 723 // Pointer to the monitor lock we're currently waiting on (or NULL). 724 Monitor* wait_monitor_ GUARDED_BY(wait_mutex_); 725 // Thread "interrupted" status; stays raised until queried or thrown. 726 bool32_t interrupted_ GUARDED_BY(wait_mutex_); 727 // The next thread in the wait set this thread is part of. 728 Thread* wait_next_; 729 // If we're blocked in MonitorEnter, this is the object we're trying to lock. 730 Object* monitor_enter_object_; 731 732 friend class Monitor; 733 734 // Top of linked list of stack indirect reference tables or NULL for none 735 StackIndirectReferenceTable* top_sirt_; 736 737 Runtime* runtime_; 738 739 RuntimeStats stats_; 740 741 // Needed to get the right ClassLoader in JNI_OnLoad, but also 742 // useful for testing. 743 ClassLoader* class_loader_override_; 744 745 // Thread local, lazily allocated, long jump context. Used to deliver exceptions. 746 Context* long_jump_context_; 747 748 // A boolean telling us whether we're recursively throwing OOME. 749 bool32_t throwing_OutOfMemoryError_; 750 751 // How much of 'suspend_count_' is by request of the debugger, used to set things right 752 // when the debugger detaches. Must be <= suspend_count_. 753 int debug_suspend_count_ GUARDED_BY(Locks::thread_suspend_count_lock_); 754 755 // JDWP invoke-during-breakpoint support. 756 DebugInvokeReq* debug_invoke_req_; 757 758 // Additional stack used by method instrumentation to store method and return pc values. 759 // Stored as a pointer since std::vector is not PACKED. 760 std::vector<InstrumentationStackFrame>* instrumentation_stack_; 761 762 // A cached copy of the java.lang.Thread's name. 763 std::string* name_; 764 765 // Is the thread a daemon? 766 const bool32_t daemon_; 767 768 // A cached pthread_t for the pthread underlying this Thread*. 769 pthread_t pthread_self_; 770 771 // Support for Mutex lock hierarchy bug detection. 772 BaseMutex* held_mutexes_[kMaxMutexLevel + 1]; 773 774 // A positive value implies we're in a region where thread suspension isn't expected. 775 uint32_t no_thread_suspension_; 776 777 // Cause for last suspension. 778 const char* last_no_thread_suspension_cause_; 779 780 // Pending checkpoint functions. 781 Closure* checkpoint_function_; 782 783 public: 784 // Runtime support function pointers 785 // TODO: move this near the top, since changing its offset requires all oats to be recompiled! 786 EntryPoints entrypoints_; 787 788 private: 789 // How many times has our pthread key's destructor been called? 790 uint32_t thread_exit_check_count_; 791 792 friend class ScopedThreadStateChange; 793 794 DISALLOW_COPY_AND_ASSIGN(Thread); 795}; 796 797std::ostream& operator<<(std::ostream& os, const Thread& thread); 798std::ostream& operator<<(std::ostream& os, const ThreadState& state); 799 800} // namespace art 801 802#endif // ART_SRC_THREAD_H_ 803