xref: /aosp_15_r20/art/runtime/thread-inl.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_THREAD_INL_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_THREAD_INL_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "arch/instruction_set.h"
21*795d594fSAndroid Build Coastguard Worker #include "base/aborting.h"
22*795d594fSAndroid Build Coastguard Worker #include "base/casts.h"
23*795d594fSAndroid Build Coastguard Worker #include "base/mutex-inl.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/time_utils.h"
25*795d594fSAndroid Build Coastguard Worker #include "indirect_reference_table.h"
26*795d594fSAndroid Build Coastguard Worker #include "jni/jni_env_ext.h"
27*795d594fSAndroid Build Coastguard Worker #include "managed_stack-inl.h"
28*795d594fSAndroid Build Coastguard Worker #include "obj_ptr-inl.h"
29*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
30*795d594fSAndroid Build Coastguard Worker #include "thread-current-inl.h"
31*795d594fSAndroid Build Coastguard Worker #include "thread.h"
32*795d594fSAndroid Build Coastguard Worker #include "thread_list.h"
33*795d594fSAndroid Build Coastguard Worker #include "thread_pool.h"
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker // Quickly access the current thread from a JNIEnv.
ForEnv(JNIEnv * env)38*795d594fSAndroid Build Coastguard Worker inline Thread* Thread::ForEnv(JNIEnv* env) {
39*795d594fSAndroid Build Coastguard Worker   JNIEnvExt* full_env(down_cast<JNIEnvExt*>(env));
40*795d594fSAndroid Build Coastguard Worker   return full_env->GetSelf();
41*795d594fSAndroid Build Coastguard Worker }
42*795d594fSAndroid Build Coastguard Worker 
GetStackOverflowProtectedSize()43*795d594fSAndroid Build Coastguard Worker inline size_t Thread::GetStackOverflowProtectedSize() {
44*795d594fSAndroid Build Coastguard Worker   // The kMemoryToolStackGuardSizeScale is expected to be 1 when ASan is not enabled.
45*795d594fSAndroid Build Coastguard Worker   // As the function is always inlined, in those cases each function call should turn
46*795d594fSAndroid Build Coastguard Worker   // into a simple reference to gPageSize.
47*795d594fSAndroid Build Coastguard Worker   return kMemoryToolStackGuardSizeScale * gPageSize;
48*795d594fSAndroid Build Coastguard Worker }
49*795d594fSAndroid Build Coastguard Worker 
DecodeJObject(jobject obj)50*795d594fSAndroid Build Coastguard Worker inline ObjPtr<mirror::Object> Thread::DecodeJObject(jobject obj) const {
51*795d594fSAndroid Build Coastguard Worker   if (obj == nullptr) {
52*795d594fSAndroid Build Coastguard Worker     return nullptr;
53*795d594fSAndroid Build Coastguard Worker   }
54*795d594fSAndroid Build Coastguard Worker   IndirectRef ref = reinterpret_cast<IndirectRef>(obj);
55*795d594fSAndroid Build Coastguard Worker   if (LIKELY(IndirectReferenceTable::IsJniTransitionOrLocalReference(ref))) {
56*795d594fSAndroid Build Coastguard Worker     // For JNI transitions, the `jclass` for a static method points to the
57*795d594fSAndroid Build Coastguard Worker     // `CompressedReference<>` in the `ArtMethod::declaring_class_` and other `jobject`
58*795d594fSAndroid Build Coastguard Worker     // arguments point to spilled stack references but a `StackReference<>` is just
59*795d594fSAndroid Build Coastguard Worker     // a subclass of `CompressedReference<>`. Local references also point to
60*795d594fSAndroid Build Coastguard Worker     // a `CompressedReference<>` encapsulated in a `GcRoot<>`.
61*795d594fSAndroid Build Coastguard Worker     if (kIsDebugBuild && IndirectReferenceTable::GetIndirectRefKind(ref) == kJniTransition) {
62*795d594fSAndroid Build Coastguard Worker       CHECK(IsJniTransitionReference(obj));
63*795d594fSAndroid Build Coastguard Worker     }
64*795d594fSAndroid Build Coastguard Worker     auto* cref = IndirectReferenceTable::ClearIndirectRefKind<
65*795d594fSAndroid Build Coastguard Worker         mirror::CompressedReference<mirror::Object>*>(ref);
66*795d594fSAndroid Build Coastguard Worker     ObjPtr<mirror::Object> result = cref->AsMirrorPtr();
67*795d594fSAndroid Build Coastguard Worker     if (kIsDebugBuild && IndirectReferenceTable::GetIndirectRefKind(ref) != kJniTransition) {
68*795d594fSAndroid Build Coastguard Worker       CHECK_EQ(result, tlsPtr_.jni_env->locals_.Get(ref));
69*795d594fSAndroid Build Coastguard Worker     }
70*795d594fSAndroid Build Coastguard Worker     return result;
71*795d594fSAndroid Build Coastguard Worker   } else {
72*795d594fSAndroid Build Coastguard Worker     return DecodeGlobalJObject(obj);
73*795d594fSAndroid Build Coastguard Worker   }
74*795d594fSAndroid Build Coastguard Worker }
75*795d594fSAndroid Build Coastguard Worker 
AllowThreadSuspension()76*795d594fSAndroid Build Coastguard Worker inline void Thread::AllowThreadSuspension() {
77*795d594fSAndroid Build Coastguard Worker   CheckSuspend();
78*795d594fSAndroid Build Coastguard Worker   // Invalidate the current thread's object pointers (ObjPtr) to catch possible moving GC bugs due
79*795d594fSAndroid Build Coastguard Worker   // to missing handles.
80*795d594fSAndroid Build Coastguard Worker   PoisonObjectPointers();
81*795d594fSAndroid Build Coastguard Worker }
82*795d594fSAndroid Build Coastguard Worker 
CheckSuspend(bool implicit)83*795d594fSAndroid Build Coastguard Worker inline void Thread::CheckSuspend(bool implicit) {
84*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(Thread::Current(), this);
85*795d594fSAndroid Build Coastguard Worker   while (true) {
86*795d594fSAndroid Build Coastguard Worker     StateAndFlags state_and_flags = GetStateAndFlags(std::memory_order_relaxed);
87*795d594fSAndroid Build Coastguard Worker     if (LIKELY(!state_and_flags.IsAnyOfFlagsSet(SuspendOrCheckpointRequestFlags()))) {
88*795d594fSAndroid Build Coastguard Worker       break;
89*795d594fSAndroid Build Coastguard Worker     } else if (state_and_flags.IsFlagSet(ThreadFlag::kCheckpointRequest)) {
90*795d594fSAndroid Build Coastguard Worker       RunCheckpointFunction();
91*795d594fSAndroid Build Coastguard Worker     } else if (state_and_flags.IsFlagSet(ThreadFlag::kSuspendRequest) &&
92*795d594fSAndroid Build Coastguard Worker                !state_and_flags.IsFlagSet(ThreadFlag::kSuspensionImmune)) {
93*795d594fSAndroid Build Coastguard Worker       FullSuspendCheck(implicit);
94*795d594fSAndroid Build Coastguard Worker       implicit = false;  // We do not need to `MadviseAwayAlternateSignalStack()` anymore.
95*795d594fSAndroid Build Coastguard Worker     } else if (state_and_flags.IsFlagSet(ThreadFlag::kEmptyCheckpointRequest)) {
96*795d594fSAndroid Build Coastguard Worker       RunEmptyCheckpoint();
97*795d594fSAndroid Build Coastguard Worker     } else {
98*795d594fSAndroid Build Coastguard Worker       DCHECK(state_and_flags.IsFlagSet(ThreadFlag::kSuspensionImmune));
99*795d594fSAndroid Build Coastguard Worker       break;
100*795d594fSAndroid Build Coastguard Worker     }
101*795d594fSAndroid Build Coastguard Worker   }
102*795d594fSAndroid Build Coastguard Worker   if (implicit) {
103*795d594fSAndroid Build Coastguard Worker     // For implicit suspend check we want to `madvise()` away
104*795d594fSAndroid Build Coastguard Worker     // the alternate signal stack to avoid wasting memory.
105*795d594fSAndroid Build Coastguard Worker     MadviseAwayAlternateSignalStack();
106*795d594fSAndroid Build Coastguard Worker   }
107*795d594fSAndroid Build Coastguard Worker }
108*795d594fSAndroid Build Coastguard Worker 
CheckEmptyCheckpointFromWeakRefAccess(BaseMutex * cond_var_mutex)109*795d594fSAndroid Build Coastguard Worker inline void Thread::CheckEmptyCheckpointFromWeakRefAccess(BaseMutex* cond_var_mutex) {
110*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
111*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(self, this);
112*795d594fSAndroid Build Coastguard Worker   for (;;) {
113*795d594fSAndroid Build Coastguard Worker     if (ReadFlag(ThreadFlag::kEmptyCheckpointRequest)) {
114*795d594fSAndroid Build Coastguard Worker       RunEmptyCheckpoint();
115*795d594fSAndroid Build Coastguard Worker       // Check we hold only an expected mutex when accessing weak ref.
116*795d594fSAndroid Build Coastguard Worker       if (kIsDebugBuild) {
117*795d594fSAndroid Build Coastguard Worker         for (int i = kLockLevelCount - 1; i >= 0; --i) {
118*795d594fSAndroid Build Coastguard Worker           BaseMutex* held_mutex = self->GetHeldMutex(static_cast<LockLevel>(i));
119*795d594fSAndroid Build Coastguard Worker           if (held_mutex != nullptr && held_mutex != GetMutatorLock() &&
120*795d594fSAndroid Build Coastguard Worker               held_mutex != cond_var_mutex &&
121*795d594fSAndroid Build Coastguard Worker               held_mutex != cp_placeholder_mutex_.load(std::memory_order_relaxed)) {
122*795d594fSAndroid Build Coastguard Worker             // placeholder_mutex may still be nullptr. That's OK.
123*795d594fSAndroid Build Coastguard Worker             CHECK(Locks::IsExpectedOnWeakRefAccess(held_mutex))
124*795d594fSAndroid Build Coastguard Worker                 << "Holding unexpected mutex " << held_mutex->GetName()
125*795d594fSAndroid Build Coastguard Worker                 << " when accessing weak ref";
126*795d594fSAndroid Build Coastguard Worker           }
127*795d594fSAndroid Build Coastguard Worker         }
128*795d594fSAndroid Build Coastguard Worker       }
129*795d594fSAndroid Build Coastguard Worker     } else {
130*795d594fSAndroid Build Coastguard Worker       break;
131*795d594fSAndroid Build Coastguard Worker     }
132*795d594fSAndroid Build Coastguard Worker   }
133*795d594fSAndroid Build Coastguard Worker }
134*795d594fSAndroid Build Coastguard Worker 
CheckEmptyCheckpointFromMutex()135*795d594fSAndroid Build Coastguard Worker inline void Thread::CheckEmptyCheckpointFromMutex() {
136*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(Thread::Current(), this);
137*795d594fSAndroid Build Coastguard Worker   for (;;) {
138*795d594fSAndroid Build Coastguard Worker     if (ReadFlag(ThreadFlag::kEmptyCheckpointRequest)) {
139*795d594fSAndroid Build Coastguard Worker       RunEmptyCheckpoint();
140*795d594fSAndroid Build Coastguard Worker     } else {
141*795d594fSAndroid Build Coastguard Worker       break;
142*795d594fSAndroid Build Coastguard Worker     }
143*795d594fSAndroid Build Coastguard Worker   }
144*795d594fSAndroid Build Coastguard Worker }
145*795d594fSAndroid Build Coastguard Worker 
SetState(ThreadState new_state)146*795d594fSAndroid Build Coastguard Worker inline ThreadState Thread::SetState(ThreadState new_state) {
147*795d594fSAndroid Build Coastguard Worker   // Should only be used to change between suspended states.
148*795d594fSAndroid Build Coastguard Worker   // Cannot use this code to change into or from Runnable as changing to Runnable should
149*795d594fSAndroid Build Coastguard Worker   // fail if the `ThreadFlag::kSuspendRequest` is set and changing from Runnable might
150*795d594fSAndroid Build Coastguard Worker   // miss passing an active suspend barrier.
151*795d594fSAndroid Build Coastguard Worker   DCHECK_NE(new_state, ThreadState::kRunnable);
152*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild && this != Thread::Current()) {
153*795d594fSAndroid Build Coastguard Worker     std::string name;
154*795d594fSAndroid Build Coastguard Worker     GetThreadName(name);
155*795d594fSAndroid Build Coastguard Worker     LOG(FATAL) << "Thread \"" << name << "\"(" << this << " != Thread::Current()="
156*795d594fSAndroid Build Coastguard Worker                << Thread::Current() << ") changing state to " << new_state;
157*795d594fSAndroid Build Coastguard Worker   }
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   while (true) {
160*795d594fSAndroid Build Coastguard Worker     StateAndFlags old_state_and_flags = GetStateAndFlags(std::memory_order_relaxed);
161*795d594fSAndroid Build Coastguard Worker     CHECK_NE(old_state_and_flags.GetState(), ThreadState::kRunnable)
162*795d594fSAndroid Build Coastguard Worker         << new_state << " " << *this << " " << *Thread::Current();
163*795d594fSAndroid Build Coastguard Worker     StateAndFlags new_state_and_flags = old_state_and_flags.WithState(new_state);
164*795d594fSAndroid Build Coastguard Worker     bool done =
165*795d594fSAndroid Build Coastguard Worker         tls32_.state_and_flags.CompareAndSetWeakRelaxed(old_state_and_flags.GetValue(),
166*795d594fSAndroid Build Coastguard Worker                                                         new_state_and_flags.GetValue());
167*795d594fSAndroid Build Coastguard Worker     if (done) {
168*795d594fSAndroid Build Coastguard Worker       return static_cast<ThreadState>(old_state_and_flags.GetState());
169*795d594fSAndroid Build Coastguard Worker     }
170*795d594fSAndroid Build Coastguard Worker   }
171*795d594fSAndroid Build Coastguard Worker }
172*795d594fSAndroid Build Coastguard Worker 
IsThreadSuspensionAllowable()173*795d594fSAndroid Build Coastguard Worker inline bool Thread::IsThreadSuspensionAllowable() const {
174*795d594fSAndroid Build Coastguard Worker   if (tls32_.no_thread_suspension != 0) {
175*795d594fSAndroid Build Coastguard Worker     return false;
176*795d594fSAndroid Build Coastguard Worker   }
177*795d594fSAndroid Build Coastguard Worker   for (int i = kLockLevelCount - 1; i >= 0; --i) {
178*795d594fSAndroid Build Coastguard Worker     if (i != kMutatorLock &&
179*795d594fSAndroid Build Coastguard Worker         i != kUserCodeSuspensionLock &&
180*795d594fSAndroid Build Coastguard Worker         GetHeldMutex(static_cast<LockLevel>(i)) != nullptr) {
181*795d594fSAndroid Build Coastguard Worker       return false;
182*795d594fSAndroid Build Coastguard Worker     }
183*795d594fSAndroid Build Coastguard Worker   }
184*795d594fSAndroid Build Coastguard Worker   // Thread autoanalysis isn't able to understand that the GetHeldMutex(...) or AssertHeld means we
185*795d594fSAndroid Build Coastguard Worker   // have the mutex meaning we need to do this hack.
186*795d594fSAndroid Build Coastguard Worker   auto is_suspending_for_user_code = [this]() NO_THREAD_SAFETY_ANALYSIS {
187*795d594fSAndroid Build Coastguard Worker     return tls32_.user_code_suspend_count != 0;
188*795d594fSAndroid Build Coastguard Worker   };
189*795d594fSAndroid Build Coastguard Worker   if (GetHeldMutex(kUserCodeSuspensionLock) != nullptr && is_suspending_for_user_code()) {
190*795d594fSAndroid Build Coastguard Worker     return false;
191*795d594fSAndroid Build Coastguard Worker   }
192*795d594fSAndroid Build Coastguard Worker   return true;
193*795d594fSAndroid Build Coastguard Worker }
194*795d594fSAndroid Build Coastguard Worker 
AssertThreadSuspensionIsAllowable(bool check_locks)195*795d594fSAndroid Build Coastguard Worker inline void Thread::AssertThreadSuspensionIsAllowable(bool check_locks) const {
196*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
197*795d594fSAndroid Build Coastguard Worker     if (gAborting == 0) {
198*795d594fSAndroid Build Coastguard Worker       CHECK_EQ(0u, tls32_.no_thread_suspension) << tlsPtr_.last_no_thread_suspension_cause;
199*795d594fSAndroid Build Coastguard Worker     }
200*795d594fSAndroid Build Coastguard Worker     if (check_locks) {
201*795d594fSAndroid Build Coastguard Worker       bool bad_mutexes_held = false;
202*795d594fSAndroid Build Coastguard Worker       for (int i = kLockLevelCount - 1; i >= 0; --i) {
203*795d594fSAndroid Build Coastguard Worker         // We expect no locks except the mutator lock. User code suspension lock is OK as long as
204*795d594fSAndroid Build Coastguard Worker         // we aren't going to be held suspended due to SuspendReason::kForUserCode.
205*795d594fSAndroid Build Coastguard Worker         if (i != kMutatorLock && i != kUserCodeSuspensionLock) {
206*795d594fSAndroid Build Coastguard Worker           BaseMutex* held_mutex = GetHeldMutex(static_cast<LockLevel>(i));
207*795d594fSAndroid Build Coastguard Worker           if (held_mutex != nullptr) {
208*795d594fSAndroid Build Coastguard Worker             LOG(ERROR) << "holding \"" << held_mutex->GetName()
209*795d594fSAndroid Build Coastguard Worker                       << "\" at point where thread suspension is expected";
210*795d594fSAndroid Build Coastguard Worker             bad_mutexes_held = true;
211*795d594fSAndroid Build Coastguard Worker           }
212*795d594fSAndroid Build Coastguard Worker         }
213*795d594fSAndroid Build Coastguard Worker       }
214*795d594fSAndroid Build Coastguard Worker       // Make sure that if we hold the user_code_suspension_lock_ we aren't suspending due to
215*795d594fSAndroid Build Coastguard Worker       // user_code_suspend_count which would prevent the thread from ever waking up.  Thread
216*795d594fSAndroid Build Coastguard Worker       // autoanalysis isn't able to understand that the GetHeldMutex(...) or AssertHeld means we
217*795d594fSAndroid Build Coastguard Worker       // have the mutex meaning we need to do this hack.
218*795d594fSAndroid Build Coastguard Worker       auto is_suspending_for_user_code = [this]() NO_THREAD_SAFETY_ANALYSIS {
219*795d594fSAndroid Build Coastguard Worker         return tls32_.user_code_suspend_count != 0;
220*795d594fSAndroid Build Coastguard Worker       };
221*795d594fSAndroid Build Coastguard Worker       if (GetHeldMutex(kUserCodeSuspensionLock) != nullptr && is_suspending_for_user_code()) {
222*795d594fSAndroid Build Coastguard Worker         LOG(ERROR) << "suspending due to user-code while holding \""
223*795d594fSAndroid Build Coastguard Worker                    << Locks::user_code_suspension_lock_->GetName() << "\"! Thread would never "
224*795d594fSAndroid Build Coastguard Worker                    << "wake up.";
225*795d594fSAndroid Build Coastguard Worker         bad_mutexes_held = true;
226*795d594fSAndroid Build Coastguard Worker       }
227*795d594fSAndroid Build Coastguard Worker       if (gAborting == 0) {
228*795d594fSAndroid Build Coastguard Worker         CHECK(!bad_mutexes_held);
229*795d594fSAndroid Build Coastguard Worker       }
230*795d594fSAndroid Build Coastguard Worker     }
231*795d594fSAndroid Build Coastguard Worker   }
232*795d594fSAndroid Build Coastguard Worker }
233*795d594fSAndroid Build Coastguard Worker 
TransitionToSuspendedAndRunCheckpoints(ThreadState new_state)234*795d594fSAndroid Build Coastguard Worker inline void Thread::TransitionToSuspendedAndRunCheckpoints(ThreadState new_state) {
235*795d594fSAndroid Build Coastguard Worker   DCHECK_NE(new_state, ThreadState::kRunnable);
236*795d594fSAndroid Build Coastguard Worker   while (true) {
237*795d594fSAndroid Build Coastguard Worker     StateAndFlags old_state_and_flags = GetStateAndFlags(std::memory_order_relaxed);
238*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(old_state_and_flags.GetState(), ThreadState::kRunnable);
239*795d594fSAndroid Build Coastguard Worker     if (UNLIKELY(old_state_and_flags.IsFlagSet(ThreadFlag::kCheckpointRequest))) {
240*795d594fSAndroid Build Coastguard Worker       IncrementStatsCounter(&checkpoint_count_);
241*795d594fSAndroid Build Coastguard Worker       RunCheckpointFunction();
242*795d594fSAndroid Build Coastguard Worker       continue;
243*795d594fSAndroid Build Coastguard Worker     }
244*795d594fSAndroid Build Coastguard Worker     if (UNLIKELY(old_state_and_flags.IsFlagSet(ThreadFlag::kEmptyCheckpointRequest))) {
245*795d594fSAndroid Build Coastguard Worker       RunEmptyCheckpoint();
246*795d594fSAndroid Build Coastguard Worker       continue;
247*795d594fSAndroid Build Coastguard Worker     }
248*795d594fSAndroid Build Coastguard Worker     // Change the state but keep the current flags (kCheckpointRequest is clear).
249*795d594fSAndroid Build Coastguard Worker     DCHECK(!old_state_and_flags.IsFlagSet(ThreadFlag::kCheckpointRequest));
250*795d594fSAndroid Build Coastguard Worker     DCHECK(!old_state_and_flags.IsFlagSet(ThreadFlag::kEmptyCheckpointRequest));
251*795d594fSAndroid Build Coastguard Worker     StateAndFlags new_state_and_flags = old_state_and_flags.WithState(new_state);
252*795d594fSAndroid Build Coastguard Worker 
253*795d594fSAndroid Build Coastguard Worker     // CAS the value, ensuring that prior memory operations are visible to any thread
254*795d594fSAndroid Build Coastguard Worker     // that observes that we are suspended.
255*795d594fSAndroid Build Coastguard Worker     bool done =
256*795d594fSAndroid Build Coastguard Worker         tls32_.state_and_flags.CompareAndSetWeakRelease(old_state_and_flags.GetValue(),
257*795d594fSAndroid Build Coastguard Worker                                                         new_state_and_flags.GetValue());
258*795d594fSAndroid Build Coastguard Worker     if (LIKELY(done)) {
259*795d594fSAndroid Build Coastguard Worker       IncrementStatsCounter(&suspended_count_);
260*795d594fSAndroid Build Coastguard Worker       break;
261*795d594fSAndroid Build Coastguard Worker     }
262*795d594fSAndroid Build Coastguard Worker   }
263*795d594fSAndroid Build Coastguard Worker }
264*795d594fSAndroid Build Coastguard Worker 
CheckActiveSuspendBarriers()265*795d594fSAndroid Build Coastguard Worker inline void Thread::CheckActiveSuspendBarriers() {
266*795d594fSAndroid Build Coastguard Worker   DCHECK_NE(GetState(), ThreadState::kRunnable);
267*795d594fSAndroid Build Coastguard Worker   while (true) {
268*795d594fSAndroid Build Coastguard Worker     StateAndFlags state_and_flags = GetStateAndFlags(std::memory_order_relaxed);
269*795d594fSAndroid Build Coastguard Worker     if (LIKELY(!state_and_flags.IsFlagSet(ThreadFlag::kCheckpointRequest) &&
270*795d594fSAndroid Build Coastguard Worker                !state_and_flags.IsFlagSet(ThreadFlag::kEmptyCheckpointRequest) &&
271*795d594fSAndroid Build Coastguard Worker                !state_and_flags.IsFlagSet(ThreadFlag::kActiveSuspendBarrier))) {
272*795d594fSAndroid Build Coastguard Worker       break;
273*795d594fSAndroid Build Coastguard Worker     } else if (state_and_flags.IsFlagSet(ThreadFlag::kActiveSuspendBarrier)) {
274*795d594fSAndroid Build Coastguard Worker       PassActiveSuspendBarriers();
275*795d594fSAndroid Build Coastguard Worker     } else {
276*795d594fSAndroid Build Coastguard Worker       // Impossible
277*795d594fSAndroid Build Coastguard Worker       LOG(FATAL) << "Fatal, thread transitioned into suspended without running the checkpoint";
278*795d594fSAndroid Build Coastguard Worker     }
279*795d594fSAndroid Build Coastguard Worker   }
280*795d594fSAndroid Build Coastguard Worker }
281*795d594fSAndroid Build Coastguard Worker 
CheckBarrierInactive(WrappedSuspend1Barrier * suspend1_barrier)282*795d594fSAndroid Build Coastguard Worker inline void Thread::CheckBarrierInactive(WrappedSuspend1Barrier* suspend1_barrier) {
283*795d594fSAndroid Build Coastguard Worker   for (WrappedSuspend1Barrier* w = tlsPtr_.active_suspend1_barriers; w != nullptr; w = w->next_) {
284*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(w->magic_, WrappedSuspend1Barrier::kMagic)
285*795d594fSAndroid Build Coastguard Worker         << "first = " << tlsPtr_.active_suspend1_barriers << " current = " << w
286*795d594fSAndroid Build Coastguard Worker         << " next = " << w->next_;
287*795d594fSAndroid Build Coastguard Worker     CHECK_NE(w, suspend1_barrier);
288*795d594fSAndroid Build Coastguard Worker   }
289*795d594fSAndroid Build Coastguard Worker }
290*795d594fSAndroid Build Coastguard Worker 
AddSuspend1Barrier(WrappedSuspend1Barrier * suspend1_barrier)291*795d594fSAndroid Build Coastguard Worker inline void Thread::AddSuspend1Barrier(WrappedSuspend1Barrier* suspend1_barrier) {
292*795d594fSAndroid Build Coastguard Worker   if (tlsPtr_.active_suspend1_barriers != nullptr) {
293*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(tlsPtr_.active_suspend1_barriers->magic_, WrappedSuspend1Barrier::kMagic)
294*795d594fSAndroid Build Coastguard Worker         << "first = " << tlsPtr_.active_suspend1_barriers;
295*795d594fSAndroid Build Coastguard Worker   }
296*795d594fSAndroid Build Coastguard Worker   CHECK_EQ(suspend1_barrier->magic_, WrappedSuspend1Barrier::kMagic);
297*795d594fSAndroid Build Coastguard Worker   suspend1_barrier->next_ = tlsPtr_.active_suspend1_barriers;
298*795d594fSAndroid Build Coastguard Worker   tlsPtr_.active_suspend1_barriers = suspend1_barrier;
299*795d594fSAndroid Build Coastguard Worker }
300*795d594fSAndroid Build Coastguard Worker 
RemoveFirstSuspend1Barrier(WrappedSuspend1Barrier * suspend1_barrier)301*795d594fSAndroid Build Coastguard Worker inline void Thread::RemoveFirstSuspend1Barrier(WrappedSuspend1Barrier* suspend1_barrier) {
302*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(tlsPtr_.active_suspend1_barriers, suspend1_barrier);
303*795d594fSAndroid Build Coastguard Worker   tlsPtr_.active_suspend1_barriers = tlsPtr_.active_suspend1_barriers->next_;
304*795d594fSAndroid Build Coastguard Worker }
305*795d594fSAndroid Build Coastguard Worker 
RemoveSuspend1Barrier(WrappedSuspend1Barrier * barrier)306*795d594fSAndroid Build Coastguard Worker inline void Thread::RemoveSuspend1Barrier(WrappedSuspend1Barrier* barrier) {
307*795d594fSAndroid Build Coastguard Worker   // 'barrier' should be in the list. If not, we will get a SIGSEGV with fault address of 4 or 8.
308*795d594fSAndroid Build Coastguard Worker   WrappedSuspend1Barrier** last = &tlsPtr_.active_suspend1_barriers;
309*795d594fSAndroid Build Coastguard Worker   while (*last != barrier) {
310*795d594fSAndroid Build Coastguard Worker     last = &((*last)->next_);
311*795d594fSAndroid Build Coastguard Worker   }
312*795d594fSAndroid Build Coastguard Worker   *last = (*last)->next_;
313*795d594fSAndroid Build Coastguard Worker }
314*795d594fSAndroid Build Coastguard Worker 
HasActiveSuspendBarrier()315*795d594fSAndroid Build Coastguard Worker inline bool Thread::HasActiveSuspendBarrier() {
316*795d594fSAndroid Build Coastguard Worker   return tlsPtr_.active_suspend1_barriers != nullptr ||
317*795d594fSAndroid Build Coastguard Worker          tlsPtr_.active_suspendall_barrier != nullptr;
318*795d594fSAndroid Build Coastguard Worker }
319*795d594fSAndroid Build Coastguard Worker 
TransitionFromRunnableToSuspended(ThreadState new_state)320*795d594fSAndroid Build Coastguard Worker inline void Thread::TransitionFromRunnableToSuspended(ThreadState new_state) {
321*795d594fSAndroid Build Coastguard Worker   // Note: JNI stubs inline a fast path of this method that transitions to suspended if
322*795d594fSAndroid Build Coastguard Worker   // there are no flags set and then clears the `held_mutexes[kMutatorLock]` (this comes
323*795d594fSAndroid Build Coastguard Worker   // from a specialized `BaseMutex::RegisterAsLockedImpl(., kMutatorLock)` inlined from
324*795d594fSAndroid Build Coastguard Worker   // the `GetMutatorLock()->TransitionFromRunnableToSuspended(this)` below).
325*795d594fSAndroid Build Coastguard Worker   // Therefore any code added here (other than debug build assertions) should be gated
326*795d594fSAndroid Build Coastguard Worker   // on some flag being set, so that the JNI stub can take the slow path to get here.
327*795d594fSAndroid Build Coastguard Worker   AssertThreadSuspensionIsAllowable();
328*795d594fSAndroid Build Coastguard Worker   PoisonObjectPointersIfDebug();
329*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(this, Thread::Current());
330*795d594fSAndroid Build Coastguard Worker   // Change to non-runnable state, thereby appearing suspended to the system.
331*795d594fSAndroid Build Coastguard Worker   TransitionToSuspendedAndRunCheckpoints(new_state);
332*795d594fSAndroid Build Coastguard Worker   // Mark the release of the share of the mutator lock.
333*795d594fSAndroid Build Coastguard Worker   GetMutatorLock()->TransitionFromRunnableToSuspended(this);
334*795d594fSAndroid Build Coastguard Worker   // Once suspended - check the active suspend barrier flag
335*795d594fSAndroid Build Coastguard Worker   CheckActiveSuspendBarriers();
336*795d594fSAndroid Build Coastguard Worker }
337*795d594fSAndroid Build Coastguard Worker 
TransitionFromSuspendedToRunnable(bool fail_on_suspend_req)338*795d594fSAndroid Build Coastguard Worker inline ThreadState Thread::TransitionFromSuspendedToRunnable(bool fail_on_suspend_req) {
339*795d594fSAndroid Build Coastguard Worker   // Note: JNI stubs inline a fast path of this method that transitions to Runnable if
340*795d594fSAndroid Build Coastguard Worker   // there are no flags set and then stores the mutator lock to `held_mutexes[kMutatorLock]`
341*795d594fSAndroid Build Coastguard Worker   // (this comes from a specialized `BaseMutex::RegisterAsUnlockedImpl(., kMutatorLock)`
342*795d594fSAndroid Build Coastguard Worker   // inlined from the `GetMutatorLock()->TransitionFromSuspendedToRunnable(this)` below).
343*795d594fSAndroid Build Coastguard Worker   // Therefore any code added here (other than debug build assertions) should be gated
344*795d594fSAndroid Build Coastguard Worker   // on some flag being set, so that the JNI stub can take the slow path to get here.
345*795d594fSAndroid Build Coastguard Worker   DCHECK(this == Current());
346*795d594fSAndroid Build Coastguard Worker   StateAndFlags old_state_and_flags = GetStateAndFlags(std::memory_order_relaxed);
347*795d594fSAndroid Build Coastguard Worker   ThreadState old_state = old_state_and_flags.GetState();
348*795d594fSAndroid Build Coastguard Worker   DCHECK_NE(old_state, ThreadState::kRunnable);
349*795d594fSAndroid Build Coastguard Worker   while (true) {
350*795d594fSAndroid Build Coastguard Worker     DCHECK(!old_state_and_flags.IsFlagSet(ThreadFlag::kSuspensionImmune));
351*795d594fSAndroid Build Coastguard Worker     GetMutatorLock()->AssertNotHeld(this);  // Otherwise we starve GC.
352*795d594fSAndroid Build Coastguard Worker     // Optimize for the return from native code case - this is the fast path.
353*795d594fSAndroid Build Coastguard Worker     // Atomically change from suspended to runnable if no suspend request pending.
354*795d594fSAndroid Build Coastguard Worker     constexpr uint32_t kCheckedFlags =
355*795d594fSAndroid Build Coastguard Worker         SuspendOrCheckpointRequestFlags() |
356*795d594fSAndroid Build Coastguard Worker         enum_cast<uint32_t>(ThreadFlag::kActiveSuspendBarrier) |
357*795d594fSAndroid Build Coastguard Worker         FlipFunctionFlags();
358*795d594fSAndroid Build Coastguard Worker     if (LIKELY(!old_state_and_flags.IsAnyOfFlagsSet(kCheckedFlags))) {
359*795d594fSAndroid Build Coastguard Worker       // CAS the value with a memory barrier.
360*795d594fSAndroid Build Coastguard Worker       StateAndFlags new_state_and_flags = old_state_and_flags.WithState(ThreadState::kRunnable);
361*795d594fSAndroid Build Coastguard Worker       if (LIKELY(tls32_.state_and_flags.CompareAndSetWeakAcquire(old_state_and_flags.GetValue(),
362*795d594fSAndroid Build Coastguard Worker                                                                  new_state_and_flags.GetValue()))) {
363*795d594fSAndroid Build Coastguard Worker         // Mark the acquisition of a share of the mutator lock.
364*795d594fSAndroid Build Coastguard Worker         GetMutatorLock()->TransitionFromSuspendedToRunnable(this);
365*795d594fSAndroid Build Coastguard Worker         break;
366*795d594fSAndroid Build Coastguard Worker       }
367*795d594fSAndroid Build Coastguard Worker     } else if (old_state_and_flags.IsFlagSet(ThreadFlag::kActiveSuspendBarrier)) {
368*795d594fSAndroid Build Coastguard Worker       PassActiveSuspendBarriers();
369*795d594fSAndroid Build Coastguard Worker     } else if (UNLIKELY(old_state_and_flags.IsFlagSet(ThreadFlag::kCheckpointRequest) ||
370*795d594fSAndroid Build Coastguard Worker                         old_state_and_flags.IsFlagSet(ThreadFlag::kEmptyCheckpointRequest))) {
371*795d594fSAndroid Build Coastguard Worker       // Checkpoint flags should not be set while in suspended state.
372*795d594fSAndroid Build Coastguard Worker       static_assert(static_cast<std::underlying_type_t<ThreadState>>(ThreadState::kRunnable) == 0u);
373*795d594fSAndroid Build Coastguard Worker       LOG(FATAL) << "Transitioning to Runnable with checkpoint flag,"
374*795d594fSAndroid Build Coastguard Worker                  // Note: Keeping unused flags. If they are set, it points to memory corruption.
375*795d594fSAndroid Build Coastguard Worker                  << " flags=" << old_state_and_flags.WithState(ThreadState::kRunnable).GetValue()
376*795d594fSAndroid Build Coastguard Worker                  << " state=" << old_state_and_flags.GetState();
377*795d594fSAndroid Build Coastguard Worker     } else if (old_state_and_flags.IsFlagSet(ThreadFlag::kSuspendRequest)) {
378*795d594fSAndroid Build Coastguard Worker       auto fake_mutator_locker = []() SHARED_LOCK_FUNCTION(Locks::mutator_lock_)
379*795d594fSAndroid Build Coastguard Worker                                      NO_THREAD_SAFETY_ANALYSIS {};
380*795d594fSAndroid Build Coastguard Worker       if (fail_on_suspend_req) {
381*795d594fSAndroid Build Coastguard Worker         // Should get here EXTREMELY rarely.
382*795d594fSAndroid Build Coastguard Worker         fake_mutator_locker();  // We lie to make thread-safety analysis mostly work. See thread.h.
383*795d594fSAndroid Build Coastguard Worker         return ThreadState::kInvalidState;
384*795d594fSAndroid Build Coastguard Worker       }
385*795d594fSAndroid Build Coastguard Worker       // Wait while our suspend count is non-zero.
386*795d594fSAndroid Build Coastguard Worker 
387*795d594fSAndroid Build Coastguard Worker       // We pass null to the MutexLock as we may be in a situation where the
388*795d594fSAndroid Build Coastguard Worker       // runtime is shutting down. Guarding ourselves from that situation
389*795d594fSAndroid Build Coastguard Worker       // requires to take the shutdown lock, which is undesirable here.
390*795d594fSAndroid Build Coastguard Worker       Thread* thread_to_pass = nullptr;
391*795d594fSAndroid Build Coastguard Worker       if (kIsDebugBuild && !IsDaemon()) {
392*795d594fSAndroid Build Coastguard Worker         // We know we can make our debug locking checks on non-daemon threads,
393*795d594fSAndroid Build Coastguard Worker         // so re-enable them on debug builds.
394*795d594fSAndroid Build Coastguard Worker         thread_to_pass = this;
395*795d594fSAndroid Build Coastguard Worker       }
396*795d594fSAndroid Build Coastguard Worker       MutexLock mu(thread_to_pass, *Locks::thread_suspend_count_lock_);
397*795d594fSAndroid Build Coastguard Worker       // Reload state and flags after locking the mutex.
398*795d594fSAndroid Build Coastguard Worker       old_state_and_flags = GetStateAndFlags(std::memory_order_relaxed);
399*795d594fSAndroid Build Coastguard Worker       DCHECK_EQ(old_state, old_state_and_flags.GetState());
400*795d594fSAndroid Build Coastguard Worker       while (old_state_and_flags.IsFlagSet(ThreadFlag::kSuspendRequest)) {
401*795d594fSAndroid Build Coastguard Worker         // Re-check when Thread::resume_cond_ is notified.
402*795d594fSAndroid Build Coastguard Worker         Thread::resume_cond_->Wait(thread_to_pass);
403*795d594fSAndroid Build Coastguard Worker         // Reload state and flags after waiting.
404*795d594fSAndroid Build Coastguard Worker         old_state_and_flags = GetStateAndFlags(std::memory_order_relaxed);
405*795d594fSAndroid Build Coastguard Worker         DCHECK_EQ(old_state, old_state_and_flags.GetState());
406*795d594fSAndroid Build Coastguard Worker       }
407*795d594fSAndroid Build Coastguard Worker       DCHECK_EQ(GetSuspendCount(), 0);
408*795d594fSAndroid Build Coastguard Worker     } else if (UNLIKELY(old_state_and_flags.IsFlagSet(ThreadFlag::kRunningFlipFunction))) {
409*795d594fSAndroid Build Coastguard Worker       DCHECK(!old_state_and_flags.IsFlagSet(ThreadFlag::kPendingFlipFunction));
410*795d594fSAndroid Build Coastguard Worker       // Do this before transitioning to runnable, both because we shouldn't wait in a runnable
411*795d594fSAndroid Build Coastguard Worker       // state, and so that the thread running the flip function can DCHECK we're not runnable.
412*795d594fSAndroid Build Coastguard Worker       WaitForFlipFunction(this);
413*795d594fSAndroid Build Coastguard Worker     } else if (old_state_and_flags.IsFlagSet(ThreadFlag::kPendingFlipFunction)) {
414*795d594fSAndroid Build Coastguard Worker       // Logically acquire mutator lock in shared mode.
415*795d594fSAndroid Build Coastguard Worker       DCHECK(!old_state_and_flags.IsFlagSet(ThreadFlag::kRunningFlipFunction));
416*795d594fSAndroid Build Coastguard Worker       if (EnsureFlipFunctionStarted(this, this, old_state_and_flags)) {
417*795d594fSAndroid Build Coastguard Worker         break;
418*795d594fSAndroid Build Coastguard Worker       }
419*795d594fSAndroid Build Coastguard Worker     }
420*795d594fSAndroid Build Coastguard Worker     // Reload state and flags.
421*795d594fSAndroid Build Coastguard Worker     old_state_and_flags = GetStateAndFlags(std::memory_order_relaxed);
422*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(old_state, old_state_and_flags.GetState());
423*795d594fSAndroid Build Coastguard Worker   }
424*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(this->GetState(), ThreadState::kRunnable);
425*795d594fSAndroid Build Coastguard Worker   return static_cast<ThreadState>(old_state);
426*795d594fSAndroid Build Coastguard Worker }
427*795d594fSAndroid Build Coastguard Worker 
AllocTlab(size_t bytes)428*795d594fSAndroid Build Coastguard Worker inline mirror::Object* Thread::AllocTlab(size_t bytes) {
429*795d594fSAndroid Build Coastguard Worker   DCHECK_GE(TlabSize(), bytes);
430*795d594fSAndroid Build Coastguard Worker   ++tlsPtr_.thread_local_objects;
431*795d594fSAndroid Build Coastguard Worker   mirror::Object* ret = reinterpret_cast<mirror::Object*>(tlsPtr_.thread_local_pos);
432*795d594fSAndroid Build Coastguard Worker   tlsPtr_.thread_local_pos += bytes;
433*795d594fSAndroid Build Coastguard Worker   return ret;
434*795d594fSAndroid Build Coastguard Worker }
435*795d594fSAndroid Build Coastguard Worker 
PushOnThreadLocalAllocationStack(mirror::Object * obj)436*795d594fSAndroid Build Coastguard Worker inline bool Thread::PushOnThreadLocalAllocationStack(mirror::Object* obj) {
437*795d594fSAndroid Build Coastguard Worker   DCHECK_LE(tlsPtr_.thread_local_alloc_stack_top, tlsPtr_.thread_local_alloc_stack_end);
438*795d594fSAndroid Build Coastguard Worker   if (tlsPtr_.thread_local_alloc_stack_top < tlsPtr_.thread_local_alloc_stack_end) {
439*795d594fSAndroid Build Coastguard Worker     // There's room.
440*795d594fSAndroid Build Coastguard Worker     DCHECK_LE(reinterpret_cast<uint8_t*>(tlsPtr_.thread_local_alloc_stack_top) +
441*795d594fSAndroid Build Coastguard Worker               sizeof(StackReference<mirror::Object>),
442*795d594fSAndroid Build Coastguard Worker               reinterpret_cast<uint8_t*>(tlsPtr_.thread_local_alloc_stack_end));
443*795d594fSAndroid Build Coastguard Worker     DCHECK(tlsPtr_.thread_local_alloc_stack_top->AsMirrorPtr() == nullptr);
444*795d594fSAndroid Build Coastguard Worker     tlsPtr_.thread_local_alloc_stack_top->Assign(obj);
445*795d594fSAndroid Build Coastguard Worker     ++tlsPtr_.thread_local_alloc_stack_top;
446*795d594fSAndroid Build Coastguard Worker     return true;
447*795d594fSAndroid Build Coastguard Worker   }
448*795d594fSAndroid Build Coastguard Worker   return false;
449*795d594fSAndroid Build Coastguard Worker }
450*795d594fSAndroid Build Coastguard Worker 
GetWeakRefAccessEnabled()451*795d594fSAndroid Build Coastguard Worker inline bool Thread::GetWeakRefAccessEnabled() const {
452*795d594fSAndroid Build Coastguard Worker   DCHECK(gUseReadBarrier);
453*795d594fSAndroid Build Coastguard Worker   DCHECK(this == Thread::Current());
454*795d594fSAndroid Build Coastguard Worker   WeakRefAccessState s = tls32_.weak_ref_access_enabled.load(std::memory_order_relaxed);
455*795d594fSAndroid Build Coastguard Worker   if (LIKELY(s == WeakRefAccessState::kVisiblyEnabled)) {
456*795d594fSAndroid Build Coastguard Worker     return true;
457*795d594fSAndroid Build Coastguard Worker   }
458*795d594fSAndroid Build Coastguard Worker   s = tls32_.weak_ref_access_enabled.load(std::memory_order_acquire);
459*795d594fSAndroid Build Coastguard Worker   if (s == WeakRefAccessState::kVisiblyEnabled) {
460*795d594fSAndroid Build Coastguard Worker     return true;
461*795d594fSAndroid Build Coastguard Worker   } else if (s == WeakRefAccessState::kDisabled) {
462*795d594fSAndroid Build Coastguard Worker     return false;
463*795d594fSAndroid Build Coastguard Worker   }
464*795d594fSAndroid Build Coastguard Worker   DCHECK(s == WeakRefAccessState::kEnabled)
465*795d594fSAndroid Build Coastguard Worker       << "state = " << static_cast<std::underlying_type_t<WeakRefAccessState>>(s);
466*795d594fSAndroid Build Coastguard Worker   // The state is only changed back to DISABLED during a checkpoint. Thus no other thread can
467*795d594fSAndroid Build Coastguard Worker   // change the value concurrently here. No other thread reads the value we store here, so there
468*795d594fSAndroid Build Coastguard Worker   // is no need for a release store.
469*795d594fSAndroid Build Coastguard Worker   tls32_.weak_ref_access_enabled.store(WeakRefAccessState::kVisiblyEnabled,
470*795d594fSAndroid Build Coastguard Worker                                        std::memory_order_relaxed);
471*795d594fSAndroid Build Coastguard Worker   return true;
472*795d594fSAndroid Build Coastguard Worker }
473*795d594fSAndroid Build Coastguard Worker 
SetThreadLocalAllocationStack(StackReference<mirror::Object> * start,StackReference<mirror::Object> * end)474*795d594fSAndroid Build Coastguard Worker inline void Thread::SetThreadLocalAllocationStack(StackReference<mirror::Object>* start,
475*795d594fSAndroid Build Coastguard Worker                                                   StackReference<mirror::Object>* end) {
476*795d594fSAndroid Build Coastguard Worker   DCHECK(Thread::Current() == this) << "Should be called by self";
477*795d594fSAndroid Build Coastguard Worker   DCHECK(start != nullptr);
478*795d594fSAndroid Build Coastguard Worker   DCHECK(end != nullptr);
479*795d594fSAndroid Build Coastguard Worker   DCHECK_ALIGNED(start, sizeof(StackReference<mirror::Object>));
480*795d594fSAndroid Build Coastguard Worker   DCHECK_ALIGNED(end, sizeof(StackReference<mirror::Object>));
481*795d594fSAndroid Build Coastguard Worker   DCHECK_LT(start, end);
482*795d594fSAndroid Build Coastguard Worker   tlsPtr_.thread_local_alloc_stack_end = end;
483*795d594fSAndroid Build Coastguard Worker   tlsPtr_.thread_local_alloc_stack_top = start;
484*795d594fSAndroid Build Coastguard Worker }
485*795d594fSAndroid Build Coastguard Worker 
RevokeThreadLocalAllocationStack()486*795d594fSAndroid Build Coastguard Worker inline void Thread::RevokeThreadLocalAllocationStack() {
487*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
488*795d594fSAndroid Build Coastguard Worker     // Note: self is not necessarily equal to this thread since thread may be suspended.
489*795d594fSAndroid Build Coastguard Worker     Thread* self = Thread::Current();
490*795d594fSAndroid Build Coastguard Worker     DCHECK(this == self || GetState() != ThreadState::kRunnable)
491*795d594fSAndroid Build Coastguard Worker         << GetState() << " thread " << this << " self " << self;
492*795d594fSAndroid Build Coastguard Worker   }
493*795d594fSAndroid Build Coastguard Worker   tlsPtr_.thread_local_alloc_stack_end = nullptr;
494*795d594fSAndroid Build Coastguard Worker   tlsPtr_.thread_local_alloc_stack_top = nullptr;
495*795d594fSAndroid Build Coastguard Worker }
496*795d594fSAndroid Build Coastguard Worker 
PoisonObjectPointersIfDebug()497*795d594fSAndroid Build Coastguard Worker inline void Thread::PoisonObjectPointersIfDebug() {
498*795d594fSAndroid Build Coastguard Worker   if (kObjPtrPoisoning) {
499*795d594fSAndroid Build Coastguard Worker     Thread::Current()->PoisonObjectPointers();
500*795d594fSAndroid Build Coastguard Worker   }
501*795d594fSAndroid Build Coastguard Worker }
502*795d594fSAndroid Build Coastguard Worker 
IncrementSuspendCount(Thread * self,AtomicInteger * suspendall_barrier,WrappedSuspend1Barrier * suspend1_barrier,SuspendReason reason)503*795d594fSAndroid Build Coastguard Worker inline void Thread::IncrementSuspendCount(Thread* self,
504*795d594fSAndroid Build Coastguard Worker                                           AtomicInteger* suspendall_barrier,
505*795d594fSAndroid Build Coastguard Worker                                           WrappedSuspend1Barrier* suspend1_barrier,
506*795d594fSAndroid Build Coastguard Worker                                           SuspendReason reason) {
507*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
508*795d594fSAndroid Build Coastguard Worker     Locks::thread_suspend_count_lock_->AssertHeld(self);
509*795d594fSAndroid Build Coastguard Worker     if (this != self) {
510*795d594fSAndroid Build Coastguard Worker       Locks::thread_list_lock_->AssertHeld(self);
511*795d594fSAndroid Build Coastguard Worker     }
512*795d594fSAndroid Build Coastguard Worker   }
513*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(reason == SuspendReason::kForUserCode)) {
514*795d594fSAndroid Build Coastguard Worker     Locks::user_code_suspension_lock_->AssertHeld(self);
515*795d594fSAndroid Build Coastguard Worker   }
516*795d594fSAndroid Build Coastguard Worker 
517*795d594fSAndroid Build Coastguard Worker   uint32_t flags = enum_cast<uint32_t>(ThreadFlag::kSuspendRequest);
518*795d594fSAndroid Build Coastguard Worker   if (suspendall_barrier != nullptr) {
519*795d594fSAndroid Build Coastguard Worker     DCHECK(suspend1_barrier == nullptr);
520*795d594fSAndroid Build Coastguard Worker     DCHECK(tlsPtr_.active_suspendall_barrier == nullptr);
521*795d594fSAndroid Build Coastguard Worker     tlsPtr_.active_suspendall_barrier = suspendall_barrier;
522*795d594fSAndroid Build Coastguard Worker     flags |= enum_cast<uint32_t>(ThreadFlag::kActiveSuspendBarrier);
523*795d594fSAndroid Build Coastguard Worker   } else if (suspend1_barrier != nullptr) {
524*795d594fSAndroid Build Coastguard Worker     AddSuspend1Barrier(suspend1_barrier);
525*795d594fSAndroid Build Coastguard Worker     flags |= enum_cast<uint32_t>(ThreadFlag::kActiveSuspendBarrier);
526*795d594fSAndroid Build Coastguard Worker   }
527*795d594fSAndroid Build Coastguard Worker 
528*795d594fSAndroid Build Coastguard Worker   ++tls32_.suspend_count;
529*795d594fSAndroid Build Coastguard Worker   if (reason == SuspendReason::kForUserCode) {
530*795d594fSAndroid Build Coastguard Worker     ++tls32_.user_code_suspend_count;
531*795d594fSAndroid Build Coastguard Worker   }
532*795d594fSAndroid Build Coastguard Worker 
533*795d594fSAndroid Build Coastguard Worker   // Two bits might be set simultaneously.
534*795d594fSAndroid Build Coastguard Worker   tls32_.state_and_flags.fetch_or(flags, std::memory_order_release);
535*795d594fSAndroid Build Coastguard Worker   TriggerSuspend();
536*795d594fSAndroid Build Coastguard Worker }
537*795d594fSAndroid Build Coastguard Worker 
IncrementSuspendCount(Thread * self)538*795d594fSAndroid Build Coastguard Worker inline void Thread::IncrementSuspendCount(Thread* self) {
539*795d594fSAndroid Build Coastguard Worker   IncrementSuspendCount(self, nullptr, nullptr, SuspendReason::kInternal);
540*795d594fSAndroid Build Coastguard Worker }
541*795d594fSAndroid Build Coastguard Worker 
DecrementSuspendCount(Thread * self,bool for_user_code)542*795d594fSAndroid Build Coastguard Worker inline void Thread::DecrementSuspendCount(Thread* self, bool for_user_code) {
543*795d594fSAndroid Build Coastguard Worker   DCHECK(ReadFlag(ThreadFlag::kSuspendRequest));
544*795d594fSAndroid Build Coastguard Worker   Locks::thread_suspend_count_lock_->AssertHeld(self);
545*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(tls32_.suspend_count <= 0)) {
546*795d594fSAndroid Build Coastguard Worker     UnsafeLogFatalForSuspendCount(self, this);
547*795d594fSAndroid Build Coastguard Worker     UNREACHABLE();
548*795d594fSAndroid Build Coastguard Worker   }
549*795d594fSAndroid Build Coastguard Worker   if (for_user_code) {
550*795d594fSAndroid Build Coastguard Worker     Locks::user_code_suspension_lock_->AssertHeld(self);
551*795d594fSAndroid Build Coastguard Worker     if (UNLIKELY(tls32_.user_code_suspend_count <= 0)) {
552*795d594fSAndroid Build Coastguard Worker       LOG(ERROR) << "user_code_suspend_count incorrect";
553*795d594fSAndroid Build Coastguard Worker       UnsafeLogFatalForSuspendCount(self, this);
554*795d594fSAndroid Build Coastguard Worker       UNREACHABLE();
555*795d594fSAndroid Build Coastguard Worker     }
556*795d594fSAndroid Build Coastguard Worker     --tls32_.user_code_suspend_count;
557*795d594fSAndroid Build Coastguard Worker   }
558*795d594fSAndroid Build Coastguard Worker 
559*795d594fSAndroid Build Coastguard Worker   --tls32_.suspend_count;
560*795d594fSAndroid Build Coastguard Worker 
561*795d594fSAndroid Build Coastguard Worker   if (tls32_.suspend_count == 0) {
562*795d594fSAndroid Build Coastguard Worker     AtomicClearFlag(ThreadFlag::kSuspendRequest, std::memory_order_release);
563*795d594fSAndroid Build Coastguard Worker   }
564*795d594fSAndroid Build Coastguard Worker }
565*795d594fSAndroid Build Coastguard Worker 
PushShadowFrame(ShadowFrame * new_top_frame)566*795d594fSAndroid Build Coastguard Worker inline ShadowFrame* Thread::PushShadowFrame(ShadowFrame* new_top_frame) {
567*795d594fSAndroid Build Coastguard Worker   new_top_frame->CheckConsistentVRegs();
568*795d594fSAndroid Build Coastguard Worker   return tlsPtr_.managed_stack.PushShadowFrame(new_top_frame);
569*795d594fSAndroid Build Coastguard Worker }
570*795d594fSAndroid Build Coastguard Worker 
PopShadowFrame()571*795d594fSAndroid Build Coastguard Worker inline ShadowFrame* Thread::PopShadowFrame() {
572*795d594fSAndroid Build Coastguard Worker   return tlsPtr_.managed_stack.PopShadowFrame();
573*795d594fSAndroid Build Coastguard Worker }
574*795d594fSAndroid Build Coastguard Worker 
575*795d594fSAndroid Build Coastguard Worker template <>
576*795d594fSAndroid Build Coastguard Worker inline uint8_t* Thread::GetStackEnd<StackType::kHardware>() const {
577*795d594fSAndroid Build Coastguard Worker   return tlsPtr_.stack_end;
578*795d594fSAndroid Build Coastguard Worker }
579*795d594fSAndroid Build Coastguard Worker template <>
580*795d594fSAndroid Build Coastguard Worker inline void Thread::SetStackEnd<StackType::kHardware>(uint8_t* new_stack_end) {
581*795d594fSAndroid Build Coastguard Worker   tlsPtr_.stack_end = new_stack_end;
582*795d594fSAndroid Build Coastguard Worker }
583*795d594fSAndroid Build Coastguard Worker template <>
584*795d594fSAndroid Build Coastguard Worker inline uint8_t* Thread::GetStackBegin<StackType::kHardware>() const {
585*795d594fSAndroid Build Coastguard Worker   return tlsPtr_.stack_begin;
586*795d594fSAndroid Build Coastguard Worker }
587*795d594fSAndroid Build Coastguard Worker template <>
588*795d594fSAndroid Build Coastguard Worker inline void Thread::SetStackBegin<StackType::kHardware>(uint8_t* new_stack_begin) {
589*795d594fSAndroid Build Coastguard Worker   tlsPtr_.stack_begin = new_stack_begin;
590*795d594fSAndroid Build Coastguard Worker }
591*795d594fSAndroid Build Coastguard Worker template <>
592*795d594fSAndroid Build Coastguard Worker inline size_t Thread::GetStackSize<StackType::kHardware>() const {
593*795d594fSAndroid Build Coastguard Worker   return tlsPtr_.stack_size;
594*795d594fSAndroid Build Coastguard Worker }
595*795d594fSAndroid Build Coastguard Worker template <>
596*795d594fSAndroid Build Coastguard Worker inline void Thread::SetStackSize<StackType::kHardware>(size_t new_stack_size) {
597*795d594fSAndroid Build Coastguard Worker   tlsPtr_.stack_size = new_stack_size;
598*795d594fSAndroid Build Coastguard Worker }
599*795d594fSAndroid Build Coastguard Worker 
GetStackEndForInterpreter(bool implicit_overflow_check)600*795d594fSAndroid Build Coastguard Worker inline uint8_t* Thread::GetStackEndForInterpreter(bool implicit_overflow_check) const {
601*795d594fSAndroid Build Coastguard Worker   uint8_t* end = GetStackEnd<kNativeStackType>() + (implicit_overflow_check
602*795d594fSAndroid Build Coastguard Worker       ? GetStackOverflowReservedBytes(kRuntimeQuickCodeISA)
603*795d594fSAndroid Build Coastguard Worker           : 0);
604*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
605*795d594fSAndroid Build Coastguard Worker     // In a debuggable build, but especially under ASAN, the access-checks interpreter has a
606*795d594fSAndroid Build Coastguard Worker     // potentially humongous stack size. We don't want to take too much of the stack regularly,
607*795d594fSAndroid Build Coastguard Worker     // so do not increase the regular reserved size (for compiled code etc) and only report the
608*795d594fSAndroid Build Coastguard Worker     // virtually smaller stack to the interpreter here.
609*795d594fSAndroid Build Coastguard Worker     end += GetStackOverflowReservedBytes(kRuntimeQuickCodeISA);
610*795d594fSAndroid Build Coastguard Worker   }
611*795d594fSAndroid Build Coastguard Worker   return end;
612*795d594fSAndroid Build Coastguard Worker }
613*795d594fSAndroid Build Coastguard Worker 
614*795d594fSAndroid Build Coastguard Worker template <StackType stack_type>
ResetDefaultStackEnd()615*795d594fSAndroid Build Coastguard Worker inline void Thread::ResetDefaultStackEnd() {
616*795d594fSAndroid Build Coastguard Worker   // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room
617*795d594fSAndroid Build Coastguard Worker   // to throw a StackOverflowError.
618*795d594fSAndroid Build Coastguard Worker   SetStackEnd<stack_type>(
619*795d594fSAndroid Build Coastguard Worker       GetStackBegin<stack_type>() + GetStackOverflowReservedBytes(kRuntimeQuickCodeISA));
620*795d594fSAndroid Build Coastguard Worker }
621*795d594fSAndroid Build Coastguard Worker 
622*795d594fSAndroid Build Coastguard Worker template <StackType stack_type>
SetStackEndForStackOverflow()623*795d594fSAndroid Build Coastguard Worker inline void Thread::SetStackEndForStackOverflow()
624*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
625*795d594fSAndroid Build Coastguard Worker   // During stack overflow we allow use of the full stack.
626*795d594fSAndroid Build Coastguard Worker   if (GetStackEnd<stack_type>() == GetStackBegin<stack_type>()) {
627*795d594fSAndroid Build Coastguard Worker     // However, we seem to have already extended to use the full stack.
628*795d594fSAndroid Build Coastguard Worker     LOG(ERROR) << "Need to increase kStackOverflowReservedBytes (currently "
629*795d594fSAndroid Build Coastguard Worker                << GetStackOverflowReservedBytes(kRuntimeQuickCodeISA) << ")?";
630*795d594fSAndroid Build Coastguard Worker     DumpStack(LOG_STREAM(ERROR));
631*795d594fSAndroid Build Coastguard Worker     LOG(FATAL) << "Recursive stack overflow.";
632*795d594fSAndroid Build Coastguard Worker   }
633*795d594fSAndroid Build Coastguard Worker 
634*795d594fSAndroid Build Coastguard Worker   SetStackEnd<stack_type>(GetStackBegin<stack_type>());
635*795d594fSAndroid Build Coastguard Worker }
636*795d594fSAndroid Build Coastguard Worker 
NotifyOnThreadExit(ThreadExitFlag * tef)637*795d594fSAndroid Build Coastguard Worker inline void Thread::NotifyOnThreadExit(ThreadExitFlag* tef) {
638*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(tef->exited_, false);
639*795d594fSAndroid Build Coastguard Worker   DCHECK(tlsPtr_.thread_exit_flags == nullptr || !tlsPtr_.thread_exit_flags->exited_);
640*795d594fSAndroid Build Coastguard Worker   tef->next_ = tlsPtr_.thread_exit_flags;
641*795d594fSAndroid Build Coastguard Worker   tlsPtr_.thread_exit_flags = tef;
642*795d594fSAndroid Build Coastguard Worker   if (tef->next_ != nullptr) {
643*795d594fSAndroid Build Coastguard Worker     DCHECK(!tef->next_->HasExited());
644*795d594fSAndroid Build Coastguard Worker     tef->next_->prev_ = tef;
645*795d594fSAndroid Build Coastguard Worker   }
646*795d594fSAndroid Build Coastguard Worker   tef->prev_ = nullptr;
647*795d594fSAndroid Build Coastguard Worker }
648*795d594fSAndroid Build Coastguard Worker 
UnregisterThreadExitFlag(ThreadExitFlag * tef)649*795d594fSAndroid Build Coastguard Worker inline void Thread::UnregisterThreadExitFlag(ThreadExitFlag* tef) {
650*795d594fSAndroid Build Coastguard Worker   if (tef->HasExited()) {
651*795d594fSAndroid Build Coastguard Worker     // List is no longer used; each client will deallocate its own ThreadExitFlag.
652*795d594fSAndroid Build Coastguard Worker     return;
653*795d594fSAndroid Build Coastguard Worker   }
654*795d594fSAndroid Build Coastguard Worker   DCHECK(IsRegistered(tef));
655*795d594fSAndroid Build Coastguard Worker   // Remove tef from the list.
656*795d594fSAndroid Build Coastguard Worker   if (tef->next_ != nullptr) {
657*795d594fSAndroid Build Coastguard Worker     tef->next_->prev_ = tef->prev_;
658*795d594fSAndroid Build Coastguard Worker   }
659*795d594fSAndroid Build Coastguard Worker   if (tef->prev_ == nullptr) {
660*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(tlsPtr_.thread_exit_flags, tef);
661*795d594fSAndroid Build Coastguard Worker     tlsPtr_.thread_exit_flags = tef->next_;
662*795d594fSAndroid Build Coastguard Worker   } else {
663*795d594fSAndroid Build Coastguard Worker     DCHECK_NE(tlsPtr_.thread_exit_flags, tef);
664*795d594fSAndroid Build Coastguard Worker     tef->prev_->next_ = tef->next_;
665*795d594fSAndroid Build Coastguard Worker   }
666*795d594fSAndroid Build Coastguard Worker   DCHECK(tlsPtr_.thread_exit_flags == nullptr || tlsPtr_.thread_exit_flags->prev_ == nullptr);
667*795d594fSAndroid Build Coastguard Worker }
668*795d594fSAndroid Build Coastguard Worker 
DCheckUnregisteredEverywhere(ThreadExitFlag * first,ThreadExitFlag * last)669*795d594fSAndroid Build Coastguard Worker inline void Thread::DCheckUnregisteredEverywhere(ThreadExitFlag* first, ThreadExitFlag* last) {
670*795d594fSAndroid Build Coastguard Worker   if (!kIsDebugBuild) {
671*795d594fSAndroid Build Coastguard Worker     return;
672*795d594fSAndroid Build Coastguard Worker   }
673*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
674*795d594fSAndroid Build Coastguard Worker   MutexLock mu(self, *Locks::thread_list_lock_);
675*795d594fSAndroid Build Coastguard Worker   Runtime::Current()->GetThreadList()->ForEach([&](Thread* t) REQUIRES(Locks::thread_list_lock_) {
676*795d594fSAndroid Build Coastguard Worker     for (ThreadExitFlag* tef = t->tlsPtr_.thread_exit_flags; tef != nullptr; tef = tef->next_) {
677*795d594fSAndroid Build Coastguard Worker       CHECK(tef < first || tef > last)
678*795d594fSAndroid Build Coastguard Worker           << "tef = " << std::hex << tef << " first = " << first << std::dec;
679*795d594fSAndroid Build Coastguard Worker     }
680*795d594fSAndroid Build Coastguard Worker     // Also perform a minimal consistency check on each list.
681*795d594fSAndroid Build Coastguard Worker     ThreadExitFlag* flags = t->tlsPtr_.thread_exit_flags;
682*795d594fSAndroid Build Coastguard Worker     CHECK(flags == nullptr || flags->prev_ == nullptr);
683*795d594fSAndroid Build Coastguard Worker   });
684*795d594fSAndroid Build Coastguard Worker }
685*795d594fSAndroid Build Coastguard Worker 
IsRegistered(ThreadExitFlag * query_tef)686*795d594fSAndroid Build Coastguard Worker inline bool Thread::IsRegistered(ThreadExitFlag* query_tef) {
687*795d594fSAndroid Build Coastguard Worker   for (ThreadExitFlag* tef = tlsPtr_.thread_exit_flags; tef != nullptr; tef = tef->next_) {
688*795d594fSAndroid Build Coastguard Worker     if (tef == query_tef) {
689*795d594fSAndroid Build Coastguard Worker       return true;
690*795d594fSAndroid Build Coastguard Worker     }
691*795d594fSAndroid Build Coastguard Worker   }
692*795d594fSAndroid Build Coastguard Worker   return false;
693*795d594fSAndroid Build Coastguard Worker }
694*795d594fSAndroid Build Coastguard Worker 
DisallowPreMonitorMutexes()695*795d594fSAndroid Build Coastguard Worker inline void Thread::DisallowPreMonitorMutexes() {
696*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
697*795d594fSAndroid Build Coastguard Worker     CHECK(this == Thread::Current());
698*795d594fSAndroid Build Coastguard Worker     CHECK(GetHeldMutex(kMonitorLock) == nullptr);
699*795d594fSAndroid Build Coastguard Worker     // Pretend we hold a kMonitorLock level mutex to detect disallowed mutex
700*795d594fSAndroid Build Coastguard Worker     // acquisitions by checkpoint Run() methods.  We don't normally register or thus check
701*795d594fSAndroid Build Coastguard Worker     // kMonitorLock level mutexes, but this is an exception.
702*795d594fSAndroid Build Coastguard Worker     Mutex* ph = cp_placeholder_mutex_.load(std::memory_order_acquire);
703*795d594fSAndroid Build Coastguard Worker     if (UNLIKELY(ph == nullptr)) {
704*795d594fSAndroid Build Coastguard Worker       Mutex* new_ph = new Mutex("checkpoint placeholder mutex", kMonitorLock);
705*795d594fSAndroid Build Coastguard Worker       if (LIKELY(cp_placeholder_mutex_.compare_exchange_strong(ph, new_ph))) {
706*795d594fSAndroid Build Coastguard Worker         ph = new_ph;
707*795d594fSAndroid Build Coastguard Worker       } else {
708*795d594fSAndroid Build Coastguard Worker         // ph now has the value set by another thread.
709*795d594fSAndroid Build Coastguard Worker         delete new_ph;
710*795d594fSAndroid Build Coastguard Worker       }
711*795d594fSAndroid Build Coastguard Worker     }
712*795d594fSAndroid Build Coastguard Worker     SetHeldMutex(kMonitorLock, ph);
713*795d594fSAndroid Build Coastguard Worker   }
714*795d594fSAndroid Build Coastguard Worker }
715*795d594fSAndroid Build Coastguard Worker 
716*795d594fSAndroid Build Coastguard Worker // Undo the effect of the previous call. Again only invoked by the thread itself.
AllowPreMonitorMutexes()717*795d594fSAndroid Build Coastguard Worker inline void Thread::AllowPreMonitorMutexes() {
718*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
719*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(GetHeldMutex(kMonitorLock), cp_placeholder_mutex_.load(std::memory_order_relaxed));
720*795d594fSAndroid Build Coastguard Worker     SetHeldMutex(kMonitorLock, nullptr);
721*795d594fSAndroid Build Coastguard Worker   }
722*795d594fSAndroid Build Coastguard Worker }
723*795d594fSAndroid Build Coastguard Worker 
724*795d594fSAndroid Build Coastguard Worker }  // namespace art
725*795d594fSAndroid Build Coastguard Worker 
726*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_THREAD_INL_H_
727