1693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers/*
2693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers * Copyright (C) 2011 The Android Open Source Project
3693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers *
4693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License");
5693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers * you may not use this file except in compliance with the License.
6693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers * You may obtain a copy of the License at
7693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers *
8693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers *      http://www.apache.org/licenses/LICENSE-2.0
9693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers *
10693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers * Unless required by applicable law or agreed to in writing, software
11693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS,
12693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers * See the License for the specific language governing permissions and
14693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers * limitations under the License.
15693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers */
16693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_THREAD_INL_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_THREAD_INL_H_
19693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
20693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers#include "thread.h"
21693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
2239b378ca3b4b6dc6da1651b84ee4289cd9bff0f8Andreas Gampe#include "base/aborting.h"
231eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers#include "base/casts.h"
24693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers#include "base/mutex-inl.h"
25d49012909625c3bf87bf51138fe79315ce1b1bdcAndreas Gampe#include "base/time_utils.h"
2668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "jni_env_ext.h"
27513061a792b22c417c938d31c19581390709561cAndreas Gampe#include "managed_stack-inl.h"
28c73cb64585f301c8bb3b03a0684f6baead99b7acAndreas Gampe#include "obj_ptr.h"
29b486a98aadc95d80548953410cf23edba62259faAndreas Gampe#include "thread-current-inl.h"
303cf225386e8129dcbe32b289279ecb87ec255318Mathieu Chartier#include "thread_pool.h"
31693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
32693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogersnamespace art {
33693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
341eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers// Quickly access the current thread from a JNIEnv.
351eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogersstatic inline Thread* ThreadForEnv(JNIEnv* env) {
361eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  JNIEnvExt* full_env(down_cast<JNIEnvExt*>(env));
3755256cb60e11d4fac71affb4b9760a2931a3598dIan Rogers  return full_env->GetSelf();
381eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers}
391eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers
407b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogersinline void Thread::AllowThreadSuspension() {
417b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  DCHECK_EQ(Thread::Current(), this);
427b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  if (UNLIKELY(TestAllFlags())) {
437b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers    CheckSuspend();
447b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  }
45a59d9b228b1eda3bf71a81b6201ec64e26086c23Mathieu Chartier  // Invalidate the current thread's object pointers (ObjPtr) to catch possible moving GC bugs due
46a59d9b228b1eda3bf71a81b6201ec64e26086c23Mathieu Chartier  // to missing handles.
473f7f03ce9a102a23961753753b5aa500226b0581Mathieu Chartier  PoisonObjectPointers();
487b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers}
497b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers
507b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogersinline void Thread::CheckSuspend() {
517b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  DCHECK_EQ(Thread::Current(), this);
527b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  for (;;) {
537b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers    if (ReadFlag(kCheckpointRequest)) {
547b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers      RunCheckpointFunction();
557b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers    } else if (ReadFlag(kSuspendRequest)) {
567b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers      FullSuspendCheck();
573049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    } else if (ReadFlag(kEmptyCheckpointRequest)) {
583049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi      RunEmptyCheckpoint();
593049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    } else {
603049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi      break;
613049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    }
623049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi  }
633049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi}
643049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi
65a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchiinline void Thread::CheckEmptyCheckpointFromWeakRefAccess(BaseMutex* cond_var_mutex) {
66a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi  Thread* self = Thread::Current();
67a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi  DCHECK_EQ(self, this);
68a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi  for (;;) {
69a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi    if (ReadFlag(kEmptyCheckpointRequest)) {
70a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi      RunEmptyCheckpoint();
71a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi      // Check we hold only an expected mutex when accessing weak ref.
72a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi      if (kIsDebugBuild) {
73a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi        for (int i = kLockLevelCount - 1; i >= 0; --i) {
74a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi          BaseMutex* held_mutex = self->GetHeldMutex(static_cast<LockLevel>(i));
75a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi          if (held_mutex != nullptr &&
76a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi              held_mutex != Locks::mutator_lock_ &&
77a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi              held_mutex != cond_var_mutex) {
788a433246d0f26f1f8519925ee6fc5cee8fbd0788Hiroshi Yamauchi            CHECK(Locks::IsExpectedOnWeakRefAccess(held_mutex))
79a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi                << "Holding unexpected mutex " << held_mutex->GetName()
80a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi                << " when accessing weak ref";
81a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi          }
82a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi        }
83a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi      }
84a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi    } else {
85a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi      break;
86a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi    }
87a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi  }
88a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi}
89a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchi
90a222404a5832ab16786931576d52825d08eed3caHiroshi Yamauchiinline void Thread::CheckEmptyCheckpointFromMutex() {
913049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi  DCHECK_EQ(Thread::Current(), this);
923049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi  for (;;) {
933049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    if (ReadFlag(kEmptyCheckpointRequest)) {
943049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi      RunEmptyCheckpoint();
957b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers    } else {
967b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers      break;
977b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers    }
987b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  }
997b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers}
1007b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers
101c0fa3ad44a84b7f658d16a717027bf95abc85db6Ian Rogersinline ThreadState Thread::SetState(ThreadState new_state) {
102eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  // Should only be used to change between suspended states.
103eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  // Cannot use this code to change into or from Runnable as changing to Runnable should
104eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  // fail if old_state_and_flags.suspend_request is true and changing from Runnable might
105eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  // miss passing an active suspend barrier.
106c0fa3ad44a84b7f658d16a717027bf95abc85db6Ian Rogers  DCHECK_NE(new_state, kRunnable);
107ef048f6f968abd59fa7fa89413a6eb85c959beafAndreas Gampe  if (kIsDebugBuild && this != Thread::Current()) {
108ef048f6f968abd59fa7fa89413a6eb85c959beafAndreas Gampe    std::string name;
109ef048f6f968abd59fa7fa89413a6eb85c959beafAndreas Gampe    GetThreadName(name);
110ef048f6f968abd59fa7fa89413a6eb85c959beafAndreas Gampe    LOG(FATAL) << "Thread \"" << name << "\"(" << this << " != Thread::Current()="
111ef048f6f968abd59fa7fa89413a6eb85c959beafAndreas Gampe               << Thread::Current() << ") changing state to " << new_state;
112ef048f6f968abd59fa7fa89413a6eb85c959beafAndreas Gampe  }
11359cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman  union StateAndFlags old_state_and_flags;
114dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  old_state_and_flags.as_int = tls32_.state_and_flags.as_int;
115eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  CHECK_NE(old_state_and_flags.as_struct.state, kRunnable);
116dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  tls32_.state_and_flags.as_struct.state = new_state;
117c0fa3ad44a84b7f658d16a717027bf95abc85db6Ian Rogers  return static_cast<ThreadState>(old_state_and_flags.as_struct.state);
118c0fa3ad44a84b7f658d16a717027bf95abc85db6Ian Rogers}
119c0fa3ad44a84b7f658d16a717027bf95abc85db6Ian Rogers
12010b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartierinline bool Thread::IsThreadSuspensionAllowable() const {
12110b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartier  if (tls32_.no_thread_suspension != 0) {
12210b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartier    return false;
12310b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartier  }
12410b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartier  for (int i = kLockLevelCount - 1; i >= 0; --i) {
12588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    if (i != kMutatorLock &&
12688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light        i != kUserCodeSuspensionLock &&
12788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light        GetHeldMutex(static_cast<LockLevel>(i)) != nullptr) {
12810b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartier      return false;
12910b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartier    }
13010b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartier  }
13188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // Thread autoanalysis isn't able to understand that the GetHeldMutex(...) or AssertHeld means we
13288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // have the mutex meaning we need to do this hack.
13388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  auto is_suspending_for_user_code = [this]() NO_THREAD_SAFETY_ANALYSIS {
13488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    return tls32_.user_code_suspend_count != 0;
13588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  };
13688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  if (GetHeldMutex(kUserCodeSuspensionLock) != nullptr && is_suspending_for_user_code()) {
13788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    return false;
13888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  }
13910b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartier  return true;
14010b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartier}
14110b218d32c0006aab747a53a9867d982cde9c938Mathieu Chartier
142693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogersinline void Thread::AssertThreadSuspensionIsAllowable(bool check_locks) const {
143f3d874c60ee3ada19ce26a5c4e532312b6f3a9e9Ian Rogers  if (kIsDebugBuild) {
144db978719dbcb73fc6acfd193561445c4462786b8Nicolas Geoffray    if (gAborting == 0) {
145db978719dbcb73fc6acfd193561445c4462786b8Nicolas Geoffray      CHECK_EQ(0u, tls32_.no_thread_suspension) << tlsPtr_.last_no_thread_suspension_cause;
146db978719dbcb73fc6acfd193561445c4462786b8Nicolas Geoffray    }
147f3d874c60ee3ada19ce26a5c4e532312b6f3a9e9Ian Rogers    if (check_locks) {
148f3d874c60ee3ada19ce26a5c4e532312b6f3a9e9Ian Rogers      bool bad_mutexes_held = false;
149f3d874c60ee3ada19ce26a5c4e532312b6f3a9e9Ian Rogers      for (int i = kLockLevelCount - 1; i >= 0; --i) {
15088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light        // We expect no locks except the mutator_lock_. User code suspension lock is OK as long as
15188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light        // we aren't going to be held suspended due to SuspendReason::kForUserCode.
15288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light        if (i != kMutatorLock && i != kUserCodeSuspensionLock) {
153f3d874c60ee3ada19ce26a5c4e532312b6f3a9e9Ian Rogers          BaseMutex* held_mutex = GetHeldMutex(static_cast<LockLevel>(i));
1542cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier          if (held_mutex != nullptr) {
155f3d874c60ee3ada19ce26a5c4e532312b6f3a9e9Ian Rogers            LOG(ERROR) << "holding \"" << held_mutex->GetName()
156f3d874c60ee3ada19ce26a5c4e532312b6f3a9e9Ian Rogers                      << "\" at point where thread suspension is expected";
157f3d874c60ee3ada19ce26a5c4e532312b6f3a9e9Ian Rogers            bad_mutexes_held = true;
158f3d874c60ee3ada19ce26a5c4e532312b6f3a9e9Ian Rogers          }
159693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers        }
160693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers      }
16188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      // Make sure that if we hold the user_code_suspension_lock_ we aren't suspending due to
16288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      // user_code_suspend_count which would prevent the thread from ever waking up.  Thread
16388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      // autoanalysis isn't able to understand that the GetHeldMutex(...) or AssertHeld means we
16488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      // have the mutex meaning we need to do this hack.
16588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      auto is_suspending_for_user_code = [this]() NO_THREAD_SAFETY_ANALYSIS {
16688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light        return tls32_.user_code_suspend_count != 0;
16788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      };
16888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      if (GetHeldMutex(kUserCodeSuspensionLock) != nullptr && is_suspending_for_user_code()) {
16988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light        LOG(ERROR) << "suspending due to user-code while holding \""
17088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light                   << Locks::user_code_suspension_lock_->GetName() << "\"! Thread would never "
17188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light                   << "wake up.";
17288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light        bad_mutexes_held = true;
17388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      }
174db978719dbcb73fc6acfd193561445c4462786b8Nicolas Geoffray      if (gAborting == 0) {
175db978719dbcb73fc6acfd193561445c4462786b8Nicolas Geoffray        CHECK(!bad_mutexes_held);
176db978719dbcb73fc6acfd193561445c4462786b8Nicolas Geoffray      }
177693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    }
178693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  }
179693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers}
180693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
1818ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartierinline void Thread::TransitionToSuspendedAndRunCheckpoints(ThreadState new_state) {
182693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  DCHECK_NE(new_state, kRunnable);
183693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  DCHECK_EQ(GetState(), kRunnable);
184693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  union StateAndFlags old_state_and_flags;
185693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  union StateAndFlags new_state_and_flags;
1860f5f6bbc3a0bb125875f28ad61584001989a7f10Dave Allison  while (true) {
187dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    old_state_and_flags.as_int = tls32_.state_and_flags.as_int;
188d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    if (UNLIKELY((old_state_and_flags.as_struct.flags & kCheckpointRequest) != 0)) {
189d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers      RunCheckpointFunction();
190d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers      continue;
191d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    }
1923049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    if (UNLIKELY((old_state_and_flags.as_struct.flags & kEmptyCheckpointRequest) != 0)) {
1933049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi      RunEmptyCheckpoint();
1943049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi      continue;
1953049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    }
1960f5f6bbc3a0bb125875f28ad61584001989a7f10Dave Allison    // Change the state but keep the current flags (kCheckpointRequest is clear).
1970f5f6bbc3a0bb125875f28ad61584001989a7f10Dave Allison    DCHECK_EQ((old_state_and_flags.as_struct.flags & kCheckpointRequest), 0);
1983049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    DCHECK_EQ((old_state_and_flags.as_struct.flags & kEmptyCheckpointRequest), 0);
1990f5f6bbc3a0bb125875f28ad61584001989a7f10Dave Allison    new_state_and_flags.as_struct.flags = old_state_and_flags.as_struct.flags;
200693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    new_state_and_flags.as_struct.state = new_state;
201b8e087e0dfd619df90cbb56534478a60bc859ebfIan Rogers
202eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li    // CAS the value with a memory ordering.
203b8e087e0dfd619df90cbb56534478a60bc859ebfIan Rogers    bool done =
2044557b3858a66aa20e42bce937e1f0620aad880a2Orion Hodson        tls32_.state_and_flags.as_atomic_int.CompareAndSetWeakRelease(old_state_and_flags.as_int,
205b8e087e0dfd619df90cbb56534478a60bc859ebfIan Rogers                                                                        new_state_and_flags.as_int);
206b8e087e0dfd619df90cbb56534478a60bc859ebfIan Rogers    if (LIKELY(done)) {
2070f5f6bbc3a0bb125875f28ad61584001989a7f10Dave Allison      break;
2080f5f6bbc3a0bb125875f28ad61584001989a7f10Dave Allison    }
2090f5f6bbc3a0bb125875f28ad61584001989a7f10Dave Allison  }
2108ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier}
211eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li
2128ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartierinline void Thread::PassActiveSuspendBarriers() {
213eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  while (true) {
214eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li    uint16_t current_flags = tls32_.state_and_flags.as_struct.flags;
2153049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    if (LIKELY((current_flags &
2163049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi                (kCheckpointRequest | kEmptyCheckpointRequest | kActiveSuspendBarrier)) == 0)) {
217eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      break;
218eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li    } else if ((current_flags & kActiveSuspendBarrier) != 0) {
219eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      PassActiveSuspendBarriers(this);
220eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li    } else {
221eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      // Impossible
2228ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier      LOG(FATAL) << "Fatal, thread transitioned into suspended without running the checkpoint";
223eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li    }
224eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  }
225693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers}
226693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
2278ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartierinline void Thread::TransitionFromRunnableToSuspended(ThreadState new_state) {
2288ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier  AssertThreadSuspensionIsAllowable();
2293398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  PoisonObjectPointersIfDebug();
2308ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier  DCHECK_EQ(this, Thread::Current());
2318ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier  // Change to non-runnable state, thereby appearing suspended to the system.
2328ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier  TransitionToSuspendedAndRunCheckpoints(new_state);
2338ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier  // Mark the release of the share of the mutator_lock_.
2348ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier  Locks::mutator_lock_->TransitionFromRunnableToSuspended(this);
2358ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier  // Once suspended - check the active suspend barrier flag
2368ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier  PassActiveSuspendBarriers();
2378ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier}
2388ac9c91cfa2408cf8d27bcf12785a60923aab775Mathieu Chartier
239693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogersinline ThreadState Thread::TransitionFromSuspendedToRunnable() {
24059cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman  union StateAndFlags old_state_and_flags;
241dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  old_state_and_flags.as_int = tls32_.state_and_flags.as_int;
242693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  int16_t old_state = old_state_and_flags.as_struct.state;
243693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  DCHECK_NE(static_cast<ThreadState>(old_state), kRunnable);
244693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  do {
245693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    Locks::mutator_lock_->AssertNotHeld(this);  // Otherwise we starve GC..
246dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    old_state_and_flags.as_int = tls32_.state_and_flags.as_int;
247693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    DCHECK_EQ(old_state_and_flags.as_struct.state, old_state);
248eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li    if (LIKELY(old_state_and_flags.as_struct.flags == 0)) {
249eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      // Optimize for the return from native code case - this is the fast path.
250eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      // Atomically change from suspended to runnable if no suspend request pending.
251eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      union StateAndFlags new_state_and_flags;
252eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      new_state_and_flags.as_int = old_state_and_flags.as_int;
253eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      new_state_and_flags.as_struct.state = kRunnable;
254eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      // CAS the value with a memory barrier.
2554557b3858a66aa20e42bce937e1f0620aad880a2Orion Hodson      if (LIKELY(tls32_.state_and_flags.as_atomic_int.CompareAndSetWeakAcquire(
256eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li                                                 old_state_and_flags.as_int,
257eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li                                                 new_state_and_flags.as_int))) {
258eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li        // Mark the acquisition of a share of the mutator_lock_.
259eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li        Locks::mutator_lock_->TransitionFromSuspendedToRunnable(this);
260eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li        break;
261eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      }
262eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li    } else if ((old_state_and_flags.as_struct.flags & kActiveSuspendBarrier) != 0) {
263eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      PassActiveSuspendBarriers(this);
2643049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    } else if ((old_state_and_flags.as_struct.flags &
2653049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi                (kCheckpointRequest | kEmptyCheckpointRequest)) != 0) {
266eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li      // Impossible
267dabdccc816309ff29b39d13696c58c8543450739Mathieu Chartier      LOG(FATAL) << "Transitioning to runnable with checkpoint flag, "
268dabdccc816309ff29b39d13696c58c8543450739Mathieu Chartier                 << " flags=" << old_state_and_flags.as_struct.flags
269dabdccc816309ff29b39d13696c58c8543450739Mathieu Chartier                 << " state=" << old_state_and_flags.as_struct.state;
270eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li    } else if ((old_state_and_flags.as_struct.flags & kSuspendRequest) != 0) {
271693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers      // Wait while our suspend count is non-zero.
2729f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray
2739f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray      // We pass null to the MutexLock as we may be in a situation where the
2749f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray      // runtime is shutting down. Guarding ourselves from that situation
2759f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray      // requires to take the shutdown lock, which is undesirable here.
2769f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray      Thread* thread_to_pass = nullptr;
2779f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray      if (kIsDebugBuild && !IsDaemon()) {
2789f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray        // We know we can make our debug locking checks on non-daemon threads,
2799f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray        // so re-enable them on debug builds.
2809f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray        thread_to_pass = this;
2819f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray      }
2829f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray      MutexLock mu(thread_to_pass, *Locks::thread_suspend_count_lock_);
283ee23582af60b36f982de2ad16f485a61f35ae817Hiroshi Yamauchi      ScopedTransitioningToRunnable scoped_transitioning_to_runnable(this);
284dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      old_state_and_flags.as_int = tls32_.state_and_flags.as_int;
285693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers      DCHECK_EQ(old_state_and_flags.as_struct.state, old_state);
286693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers      while ((old_state_and_flags.as_struct.flags & kSuspendRequest) != 0) {
287693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers        // Re-check when Thread::resume_cond_ is notified.
2889f5f8ac136d88de546f70f0ac2438610150ff401Nicolas Geoffray        Thread::resume_cond_->Wait(thread_to_pass);
289dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers        old_state_and_flags.as_int = tls32_.state_and_flags.as_int;
290693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers        DCHECK_EQ(old_state_and_flags.as_struct.state, old_state);
291693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers      }
292693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers      DCHECK_EQ(GetSuspendCount(), 0);
293693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    }
294719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers  } while (true);
295eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  // Run the flip function, if set.
296eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  Closure* flip_func = GetFlipFunction();
297eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  if (flip_func != nullptr) {
298eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li    flip_func->Run(this);
299eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  }
300eac4424b3420c280f97ff2f815b5dedd8dac9801Yu Li  return static_cast<ThreadState>(old_state);
301693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers}
302693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
303e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartierinline mirror::Object* Thread::AllocTlab(size_t bytes) {
304e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  DCHECK_GE(TlabSize(), bytes);
305dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  ++tlsPtr_.thread_local_objects;
306dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  mirror::Object* ret = reinterpret_cast<mirror::Object*>(tlsPtr_.thread_local_pos);
307dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  tlsPtr_.thread_local_pos += bytes;
308692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier  return ret;
309692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier}
310692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier
311f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchiinline bool Thread::PushOnThreadLocalAllocationStack(mirror::Object* obj) {
312dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  DCHECK_LE(tlsPtr_.thread_local_alloc_stack_top, tlsPtr_.thread_local_alloc_stack_end);
313dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  if (tlsPtr_.thread_local_alloc_stack_top < tlsPtr_.thread_local_alloc_stack_end) {
314f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi    // There's room.
31513735955f39b3b304c37d2b2840663c131262c18Ian Rogers    DCHECK_LE(reinterpret_cast<uint8_t*>(tlsPtr_.thread_local_alloc_stack_top) +
316cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier              sizeof(StackReference<mirror::Object>),
31713735955f39b3b304c37d2b2840663c131262c18Ian Rogers              reinterpret_cast<uint8_t*>(tlsPtr_.thread_local_alloc_stack_end));
318cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier    DCHECK(tlsPtr_.thread_local_alloc_stack_top->AsMirrorPtr() == nullptr);
319cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier    tlsPtr_.thread_local_alloc_stack_top->Assign(obj);
320dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers    ++tlsPtr_.thread_local_alloc_stack_top;
321f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi    return true;
322f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  }
323f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  return false;
324f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi}
325f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi
326cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartierinline void Thread::SetThreadLocalAllocationStack(StackReference<mirror::Object>* start,
327cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier                                                  StackReference<mirror::Object>* end) {
328f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  DCHECK(Thread::Current() == this) << "Should be called by self";
329f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  DCHECK(start != nullptr);
330f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  DCHECK(end != nullptr);
331cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier  DCHECK_ALIGNED(start, sizeof(StackReference<mirror::Object>));
332cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier  DCHECK_ALIGNED(end, sizeof(StackReference<mirror::Object>));
333f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  DCHECK_LT(start, end);
334dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  tlsPtr_.thread_local_alloc_stack_end = end;
335dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  tlsPtr_.thread_local_alloc_stack_top = start;
336f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi}
337f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi
338f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchiinline void Thread::RevokeThreadLocalAllocationStack() {
339f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  if (kIsDebugBuild) {
340f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi    // Note: self is not necessarily equal to this thread since thread may be suspended.
341f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi    Thread* self = Thread::Current();
342f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi    DCHECK(this == self || IsSuspended() || GetState() == kWaitingPerformingGc)
343f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi        << GetState() << " thread " << this << " self " << self;
344f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi  }
345dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  tlsPtr_.thread_local_alloc_stack_end = nullptr;
346dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  tlsPtr_.thread_local_alloc_stack_top = nullptr;
347f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi}
348f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi
349a59d9b228b1eda3bf71a81b6201ec64e26086c23Mathieu Chartierinline void Thread::PoisonObjectPointersIfDebug() {
350c73cb64585f301c8bb3b03a0684f6baead99b7acAndreas Gampe  if (kObjPtrPoisoning) {
351a59d9b228b1eda3bf71a81b6201ec64e26086c23Mathieu Chartier    Thread::Current()->PoisonObjectPointers();
352a59d9b228b1eda3bf71a81b6201ec64e26086c23Mathieu Chartier  }
353a59d9b228b1eda3bf71a81b6201ec64e26086c23Mathieu Chartier}
354a59d9b228b1eda3bf71a81b6201ec64e26086c23Mathieu Chartier
35502e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchiinline bool Thread::ModifySuspendCount(Thread* self,
35602e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi                                       int delta,
35702e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi                                       AtomicInteger* suspend_barrier,
35846f9340f2a055a8fdfebbfbb739c697c20d83e7cAlex Light                                       SuspendReason reason) {
35902e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi  if (delta > 0 && ((kUseReadBarrier && this != self) || suspend_barrier != nullptr)) {
36002e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi    // When delta > 0 (requesting a suspend), ModifySuspendCountInternal() may fail either if
36102e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi    // active_suspend_barriers is full or we are in the middle of a thread flip. Retry in a loop.
36202e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi    while (true) {
36346f9340f2a055a8fdfebbfbb739c697c20d83e7cAlex Light      if (LIKELY(ModifySuspendCountInternal(self, delta, suspend_barrier, reason))) {
36402e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        return true;
36502e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi      } else {
36602e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        // Failure means the list of active_suspend_barriers is full or we are in the middle of a
36702e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        // thread flip, we should release the thread_suspend_count_lock_ (to avoid deadlock) and
36802e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        // wait till the target thread has executed or Thread::PassActiveSuspendBarriers() or the
36902e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        // flip function. Note that we could not simply wait for the thread to change to a suspended
37002e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        // state, because it might need to run checkpoint function before the state change or
37102e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        // resumes from the resume_cond_, which also needs thread_suspend_count_lock_.
37202e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        //
37302e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        // The list of active_suspend_barriers is very unlikely to be full since more than
37402e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        // kMaxSuspendBarriers threads need to execute SuspendAllInternal() simultaneously, and
37502e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        // target thread stays in kRunnable in the mean time.
37602e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        Locks::thread_suspend_count_lock_->ExclusiveUnlock(self);
37702e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        NanoSleep(100000);
37802e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi        Locks::thread_suspend_count_lock_->ExclusiveLock(self);
37902e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi      }
38002e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi    }
38102e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi  } else {
38246f9340f2a055a8fdfebbfbb739c697c20d83e7cAlex Light    return ModifySuspendCountInternal(self, delta, suspend_barrier, reason);
38302e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi  }
38402e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi}
38502e7f1a46d8dbb277d045182cd1fa4b058d55162Hiroshi Yamauchi
386513061a792b22c417c938d31c19581390709561cAndreas Gampeinline ShadowFrame* Thread::PushShadowFrame(ShadowFrame* new_top_frame) {
387513061a792b22c417c938d31c19581390709561cAndreas Gampe  return tlsPtr_.managed_stack.PushShadowFrame(new_top_frame);
388513061a792b22c417c938d31c19581390709561cAndreas Gampe}
389513061a792b22c417c938d31c19581390709561cAndreas Gampe
390513061a792b22c417c938d31c19581390709561cAndreas Gampeinline ShadowFrame* Thread::PopShadowFrame() {
391513061a792b22c417c938d31c19581390709561cAndreas Gampe  return tlsPtr_.managed_stack.PopShadowFrame();
392513061a792b22c417c938d31c19581390709561cAndreas Gampe}
393513061a792b22c417c938d31c19581390709561cAndreas Gampe
394693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers}  // namespace art
395693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
396fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_THREAD_INL_H_
397