// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_THREAD_H_
#define RUNTIME_VM_THREAD_H_

#if defined(SHOULD_NOT_INCLUDE_RUNTIME)
#error "Should not include runtime"
#endif

#include <setjmp.h>

#include "include/dart_api.h"
#include "platform/assert.h"
#include "platform/atomic.h"
#include "platform/safe_stack.h"
#include "vm/bitfield.h"
#include "vm/compiler/runtime_api.h"
#include "vm/constants.h"
#include "vm/globals.h"
#include "vm/handles.h"
#include "vm/heap/pointer_block.h"
#include "vm/heap/sampler.h"
#include "vm/os_thread.h"
#include "vm/pending_deopts.h"
#include "vm/random.h"
#include "vm/runtime_entry_list.h"
#include "vm/tags.h"
#include "vm/thread_stack_resource.h"
#include "vm/thread_state.h"

namespace dart {

class AbstractType;
class ApiLocalScope;
class Array;
class Bytecode;
class CompilerState;
class CompilerTimings;
class Class;
class Code;
class DeoptContext;
class Error;
class ExceptionHandlers;
class Field;
class FieldTable;
class Function;
class GrowableObjectArray;
class HandleScope;
class Heap;
class HierarchyInfo;
class Instance;
class Interpreter;
class Isolate;
class IsolateGroup;
class Library;
class LocalHandle;
class Object;
class OSThread;
class JSONObject;
class NoActiveIsolateScope;
class PcDescriptors;
class RuntimeEntry;
class Smi;
class StackResource;
class StackTrace;
class StreamInfo;
class String;
class TimelineStream;
class TypeArguments;
class TypeParameter;
class TypeUsageInfo;
class Zone;

namespace bytecode {
class BytecodeLoader;
}

namespace compiler {
namespace target {
class Thread;
}  // namespace target
}  // namespace compiler

#define REUSABLE_HANDLE_LIST(V)                                                \
  V(AbstractType)                                                              \
  V(Array)                                                                     \
  V(Class)                                                                     \
  V(Code)                                                                      \
  V(Bytecode)                                                                  \
  V(Error)                                                                     \
  V(ExceptionHandlers)                                                         \
  V(Field)                                                                     \
  V(Function)                                                                  \
  V(GrowableObjectArray)                                                       \
  V(Instance)                                                                  \
  V(Library)                                                                   \
  V(LoadingUnit)                                                               \
  V(Object)                                                                    \
  V(PcDescriptors)                                                             \
  V(Smi)                                                                       \
  V(String)                                                                    \
  V(TypeParameters)                                                            \
  V(TypeArguments)                                                             \
  V(TypeParameter)                                                             \
  V(WeakArray)

#define CACHED_VM_STUBS_LIST(V)                                                \
  V(CodePtr, fix_callers_target_code_, StubCode::FixCallersTarget().ptr(),     \
    nullptr)                                                                   \
  V(CodePtr, fix_allocation_stub_code_,                                        \
    StubCode::FixAllocationStubTarget().ptr(), nullptr)                        \
  V(CodePtr, invoke_dart_code_stub_, StubCode::InvokeDartCode().ptr(),         \
    nullptr)                                                                   \
  V(CodePtr, invoke_dart_code_from_bytecode_stub_,                             \
    StubCode::InvokeDartCodeFromBytecode().ptr(), nullptr)                     \
  V(CodePtr, call_to_runtime_stub_, StubCode::CallToRuntime().ptr(), nullptr)  \
  V(CodePtr, late_initialization_error_shared_without_fpu_regs_stub_,          \
    StubCode::LateInitializationErrorSharedWithoutFPURegs().ptr(), nullptr)    \
  V(CodePtr, late_initialization_error_shared_with_fpu_regs_stub_,             \
    StubCode::LateInitializationErrorSharedWithFPURegs().ptr(), nullptr)       \
  V(CodePtr, null_error_shared_without_fpu_regs_stub_,                         \
    StubCode::NullErrorSharedWithoutFPURegs().ptr(), nullptr)                  \
  V(CodePtr, null_error_shared_with_fpu_regs_stub_,                            \
    StubCode::NullErrorSharedWithFPURegs().ptr(), nullptr)                     \
  V(CodePtr, null_arg_error_shared_without_fpu_regs_stub_,                     \
    StubCode::NullArgErrorSharedWithoutFPURegs().ptr(), nullptr)               \
  V(CodePtr, null_arg_error_shared_with_fpu_regs_stub_,                        \
    StubCode::NullArgErrorSharedWithFPURegs().ptr(), nullptr)                  \
  V(CodePtr, null_cast_error_shared_without_fpu_regs_stub_,                    \
    StubCode::NullCastErrorSharedWithoutFPURegs().ptr(), nullptr)              \
  V(CodePtr, null_cast_error_shared_with_fpu_regs_stub_,                       \
    StubCode::NullCastErrorSharedWithFPURegs().ptr(), nullptr)                 \
  V(CodePtr, range_error_shared_without_fpu_regs_stub_,                        \
    StubCode::RangeErrorSharedWithoutFPURegs().ptr(), nullptr)                 \
  V(CodePtr, range_error_shared_with_fpu_regs_stub_,                           \
    StubCode::RangeErrorSharedWithFPURegs().ptr(), nullptr)                    \
  V(CodePtr, write_error_shared_without_fpu_regs_stub_,                        \
    StubCode::WriteErrorSharedWithoutFPURegs().ptr(), nullptr)                 \
  V(CodePtr, write_error_shared_with_fpu_regs_stub_,                           \
    StubCode::WriteErrorSharedWithFPURegs().ptr(), nullptr)                    \
  V(CodePtr, field_access_error_shared_without_fpu_regs_stub_,                 \
    StubCode::FieldAccessErrorSharedWithoutFPURegs().ptr(), nullptr)           \
  V(CodePtr, field_access_error_shared_with_fpu_regs_stub_,                    \
    StubCode::FieldAccessErrorSharedWithFPURegs().ptr(), nullptr)              \
  V(CodePtr, allocate_mint_with_fpu_regs_stub_,                                \
    StubCode::AllocateMintSharedWithFPURegs().ptr(), nullptr)                  \
  V(CodePtr, allocate_mint_without_fpu_regs_stub_,                             \
    StubCode::AllocateMintSharedWithoutFPURegs().ptr(), nullptr)               \
  V(CodePtr, allocate_object_stub_, StubCode::AllocateObject().ptr(), nullptr) \
  V(CodePtr, allocate_object_parameterized_stub_,                              \
    StubCode::AllocateObjectParameterized().ptr(), nullptr)                    \
  V(CodePtr, allocate_object_slow_stub_, StubCode::AllocateObjectSlow().ptr(), \
    nullptr)                                                                   \
  V(CodePtr, async_exception_handler_stub_,                                    \
    StubCode::AsyncExceptionHandler().ptr(), nullptr)                          \
  V(CodePtr, resume_stub_, StubCode::Resume().ptr(), nullptr)                  \
  V(CodePtr, return_async_stub_, StubCode::ReturnAsync().ptr(), nullptr)       \
  V(CodePtr, return_async_not_future_stub_,                                    \
    StubCode::ReturnAsyncNotFuture().ptr(), nullptr)                           \
  V(CodePtr, return_async_star_stub_, StubCode::ReturnAsyncStar().ptr(),       \
    nullptr)                                                                   \
  V(CodePtr, stack_overflow_shared_without_fpu_regs_stub_,                     \
    StubCode::StackOverflowSharedWithoutFPURegs().ptr(), nullptr)              \
  V(CodePtr, stack_overflow_shared_with_fpu_regs_stub_,                        \
    StubCode::StackOverflowSharedWithFPURegs().ptr(), nullptr)                 \
  V(CodePtr, switchable_call_miss_stub_, StubCode::SwitchableCallMiss().ptr(), \
    nullptr)                                                                   \
  V(CodePtr, throw_stub_, StubCode::Throw().ptr(), nullptr)                    \
  V(CodePtr, re_throw_stub_, StubCode::Throw().ptr(), nullptr)                 \
  V(CodePtr, optimize_stub_, StubCode::OptimizeFunction().ptr(), nullptr)      \
  V(CodePtr, deoptimize_stub_, StubCode::Deoptimize().ptr(), nullptr)          \
  V(CodePtr, lazy_deopt_from_return_stub_,                                     \
    StubCode::DeoptimizeLazyFromReturn().ptr(), nullptr)                       \
  V(CodePtr, lazy_deopt_from_throw_stub_,                                      \
    StubCode::DeoptimizeLazyFromThrow().ptr(), nullptr)                        \
  V(CodePtr, slow_type_test_stub_, StubCode::SlowTypeTest().ptr(), nullptr)    \
  V(CodePtr, lazy_specialize_type_test_stub_,                                  \
    StubCode::LazySpecializeTypeTest().ptr(), nullptr)                         \
  V(CodePtr, enter_safepoint_stub_, StubCode::EnterSafepoint().ptr(), nullptr) \
  V(CodePtr, exit_safepoint_stub_, StubCode::ExitSafepoint().ptr(), nullptr)   \
  V(CodePtr, call_native_through_safepoint_stub_,                              \
    StubCode::CallNativeThroughSafepoint().ptr(), nullptr)

#define CACHED_NON_VM_STUB_LIST(V)                                             \
  V(ObjectPtr, object_null_, Object::null(), nullptr)                          \
  V(BoolPtr, bool_true_, Object::bool_true().ptr(), nullptr)                   \
  V(BoolPtr, bool_false_, Object::bool_false().ptr(), nullptr)                 \
  V(ArrayPtr, empty_array_, Object::empty_array().ptr(), nullptr)              \
  V(TypeArgumentsPtr, empty_type_arguments_,                                   \
    Object::empty_type_arguments().ptr(), nullptr)                             \
  V(TypePtr, dynamic_type_, Type::dynamic_type().ptr(), nullptr)

// List of VM-global objects/addresses cached in each Thread object.
// Important: constant false must immediately follow constant true.
#define CACHED_VM_OBJECTS_LIST(V)                                              \
  CACHED_NON_VM_STUB_LIST(V)                                                   \
  CACHED_VM_STUBS_LIST(V)

#define CACHED_FUNCTION_ENTRY_POINTS_LIST(V)                                   \
  V(suspend_state_init_async)                                                  \
  V(suspend_state_await)                                                       \
  V(suspend_state_await_with_type_check)                                       \
  V(suspend_state_return_async)                                                \
  V(suspend_state_return_async_not_future)                                     \
  V(suspend_state_init_async_star)                                             \
  V(suspend_state_yield_async_star)                                            \
  V(suspend_state_return_async_star)                                           \
  V(suspend_state_init_sync_star)                                              \
  V(suspend_state_suspend_sync_star_at_start)                                  \
  V(suspend_state_handle_exception)

// This assertion marks places which assume that boolean false immediate
// follows bool true in the CACHED_VM_OBJECTS_LIST
#define ASSERT_BOOL_FALSE_FOLLOWS_BOOL_TRUE()                                  \
  ASSERT((Thread::bool_true_offset() + kWordSize) ==                           \
         Thread::bool_false_offset());

#define CACHED_VM_STUBS_ADDRESSES_LIST(V)                                      \
  V(uword, write_barrier_entry_point_, StubCode::WriteBarrier().EntryPoint(),  \
    0)                                                                         \
  V(uword, array_write_barrier_entry_point_,                                   \
    StubCode::ArrayWriteBarrier().EntryPoint(), 0)                             \
  V(uword, call_to_runtime_entry_point_,                                       \
    StubCode::CallToRuntime().EntryPoint(), 0)                                 \
  V(uword, allocate_mint_with_fpu_regs_entry_point_,                           \
    StubCode::AllocateMintSharedWithFPURegs().EntryPoint(), 0)                 \
  V(uword, allocate_mint_without_fpu_regs_entry_point_,                        \
    StubCode::AllocateMintSharedWithoutFPURegs().EntryPoint(), 0)              \
  V(uword, allocate_object_entry_point_,                                       \
    StubCode::AllocateObject().EntryPoint(), 0)                                \
  V(uword, allocate_object_parameterized_entry_point_,                         \
    StubCode::AllocateObjectParameterized().EntryPoint(), 0)                   \
  V(uword, allocate_object_slow_entry_point_,                                  \
    StubCode::AllocateObjectSlow().EntryPoint(), 0)                            \
  V(uword, stack_overflow_shared_without_fpu_regs_entry_point_,                \
    StubCode::StackOverflowSharedWithoutFPURegs().EntryPoint(), 0)             \
  V(uword, stack_overflow_shared_with_fpu_regs_entry_point_,                   \
    StubCode::StackOverflowSharedWithFPURegs().EntryPoint(), 0)                \
  V(uword, megamorphic_call_checked_entry_,                                    \
    StubCode::MegamorphicCall().EntryPoint(), 0)                               \
  V(uword, switchable_call_miss_entry_,                                        \
    StubCode::SwitchableCallMiss().EntryPoint(), 0)                            \
  V(uword, optimize_entry_, StubCode::OptimizeFunction().EntryPoint(), 0)      \
  V(uword, deoptimize_entry_, StubCode::Deoptimize().EntryPoint(), 0)          \
  V(uword, call_native_through_safepoint_entry_point_,                         \
    StubCode::CallNativeThroughSafepoint().EntryPoint(), 0)                    \
  V(uword, jump_to_frame_entry_point_, StubCode::JumpToFrame().EntryPoint(),   \
    0)                                                                         \
  V(uword, slow_type_test_entry_point_, StubCode::SlowTypeTest().EntryPoint(), \
    0)                                                                         \
  V(uword, resume_interpreter_adjusted_entry_point_,                           \
    StubCode::ResumeInterpreter().EntryPoint() +                               \
        SuspendStubABI::kResumePcDistance,                                     \
    0)

#define CACHED_ADDRESSES_LIST(V)                                               \
  CACHED_VM_STUBS_ADDRESSES_LIST(V)                                            \
  V(uword, bootstrap_native_wrapper_entry_point_,                              \
    NativeEntry::BootstrapNativeCallWrapperEntry(), 0)                         \
  V(uword, no_scope_native_wrapper_entry_point_,                               \
    NativeEntry::NoScopeNativeCallWrapperEntry(), 0)                           \
  V(uword, auto_scope_native_wrapper_entry_point_,                             \
    NativeEntry::AutoScopeNativeCallWrapperEntry(), 0)                         \
  V(uword, interpret_call_entry_point_, RuntimeEntry::InterpretCallEntry(), 0) \
  V(StringPtr*, predefined_symbols_address_, Symbols::PredefinedAddress(),     \
    nullptr)                                                                   \
  V(uword, double_nan_address_, reinterpret_cast<uword>(&double_nan_constant), \
    0)                                                                         \
  V(uword, double_negate_address_,                                             \
    reinterpret_cast<uword>(&double_negate_constant), 0)                       \
  V(uword, double_abs_address_, reinterpret_cast<uword>(&double_abs_constant), \
    0)                                                                         \
  V(uword, float_not_address_, reinterpret_cast<uword>(&float_not_constant),   \
    0)                                                                         \
  V(uword, float_negate_address_,                                              \
    reinterpret_cast<uword>(&float_negate_constant), 0)                        \
  V(uword, float_absolute_address_,                                            \
    reinterpret_cast<uword>(&float_absolute_constant), 0)                      \
  V(uword, float_zerow_address_,                                               \
    reinterpret_cast<uword>(&float_zerow_constant), 0)

#define CACHED_CONSTANTS_LIST(V)                                               \
  CACHED_VM_OBJECTS_LIST(V)                                                    \
  CACHED_ADDRESSES_LIST(V)

enum class ValidationPolicy {
  kValidateFrames = 0,
  kDontValidateFrames = 1,
};

enum class RuntimeCallDeoptAbility {
  // There was no leaf call or a leaf call that can cause deoptimization
  // after-call.
  kCanLazyDeopt,
  // There was a leaf call and the VM cannot cause deoptimize after-call.
  kCannotLazyDeopt,
};

// The safepoint level a thread is on or a safepoint operation is requested for
//
// The higher the number the stronger the guarantees:
//   * the time-to-safepoint latency increases with level
//   * the frequency of hitting possible safe points decreases with level
enum SafepointLevel {
  // Safe to GC
  kGC,
  // Safe to GC as well as Deopt.
  kGCAndDeopt,
  // Safe to GC, Deopt as well as Reload.
  kGCAndDeoptAndReload,
  // Number of levels.
  kNumLevels,

  // No safepoint.
  kNoSafepoint,
};

// Accessed from generated code.
struct TsanUtils {
  // Used to allow unwinding runtime C frames using longjmp() when throwing
  // exceptions. This allows triggering the normal TSAN shadow stack unwinding
  // implementation.
  // -> See https://dartbug.com/47472#issuecomment-948235479 for details.
#if defined(USING_THREAD_SANITIZER)
  void* setjmp_function = reinterpret_cast<void*>(&DART_SETJMP);
#else
  // MSVC (on Windows) is not happy with getting address of purely intrinsic.
  void* setjmp_function = nullptr;
#endif
  jmp_buf* setjmp_buffer = nullptr;
  uword exception_pc = 0;
  uword exception_sp = 0;
  uword exception_fp = 0;

  static intptr_t setjmp_function_offset() {
    return OFFSET_OF(TsanUtils, setjmp_function);
  }
  static intptr_t setjmp_buffer_offset() {
    return OFFSET_OF(TsanUtils, setjmp_buffer);
  }
  static intptr_t exception_pc_offset() {
    return OFFSET_OF(TsanUtils, exception_pc);
  }
  static intptr_t exception_sp_offset() {
    return OFFSET_OF(TsanUtils, exception_sp);
  }
  static intptr_t exception_fp_offset() {
    return OFFSET_OF(TsanUtils, exception_fp);
  }
};

class MutatorThreadVisitor {
 public:
  MutatorThreadVisitor() {}
  virtual ~MutatorThreadVisitor() {}

  virtual void VisitMutatorThread(Thread* isolate) = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(MutatorThreadVisitor);
};

// A VM thread; may be executing Dart code or performing helper tasks like
// garbage collection or compilation. The Thread structure associated with
// a thread is allocated by ThreadRegistry::GetFromFreelistLocked either
// before entering an isolate or entering an isolate group, and destroyed
// automatically when the underlying OS thread exits.
class Thread : public ThreadState {
 public:
  // The kind of task this thread is performing. Sampled by the profiler.
  enum TaskKind {
    kUnknownTask = 0,
    kMutatorTask,
    kCompilerTask,
    kMarkerTask,
    kSweeperTask,
    kCompactorTask,
    kScavengerTask,
    kSampleBlockTask,
    kIncrementalCompactorTask,
    kSpawnTask,
    kIsolateGroupSharedCallbackTask,
  };

  ~Thread();

  // The currently executing thread, or nullptr if not yet initialized.
  static Thread* Current() {
    return static_cast<Thread*>(OSThread::CurrentVMThread());
  }

  // Whether there's any active state on the [thread] that needs to be preserved
  // across `Thread::ExitIsolate()` and `Thread::EnterIsolate()`.
  bool HasActiveState();
  void AssertNonMutatorInvariants();
  void AssertDartMutatorInvariants();
  void AssertNonDartMutatorInvariants();
  void AssertEmptyStackInvariants();
  void AssertEmptyThreadInvariants();

  // Makes the current thread enter 'isolate'.
  static void EnterIsolate(Isolate* isolate);
  // Makes the current thread exit its isolate.
  static void ExitIsolate(bool isolate_shutdown = false);

  static void EnterIsolateGroupAsHelper(IsolateGroup* isolate_group,
                                        TaskKind kind,
                                        bool bypass_safepoint);
  static void ExitIsolateGroupAsHelper(bool bypass_safepoint);

  static void EnterIsolateGroupAsNonMutator(IsolateGroup* isolate_group,
                                            TaskKind kind);
  static void ExitIsolateGroupAsNonMutator();

  static void EnterIsolateGroupAsMutator(IsolateGroup* isolate_group,
                                         bool bypass_safepoint);
  static void ExitIsolateGroupAsMutator(bool bypass_safepoint);

  // Empties the store buffer block into the isolate.
  void ReleaseStoreBuffer();
  void AcquireMarkingStack();
  void ReleaseMarkingStack();

  void SetStackLimit(uword value);
  void ClearStackLimit();

  // Access to the current stack limit for generated code. Either the true OS
  // thread's stack limit minus some headroom, or a special value to trigger
  // interrupts.
  uword stack_limit_address() const {
    return reinterpret_cast<uword>(&stack_limit_);
  }
  static intptr_t stack_limit_offset() {
    return OFFSET_OF(Thread, stack_limit_);
  }

  // The true stack limit for this OS thread.
  static intptr_t saved_stack_limit_offset() {
    return OFFSET_OF(Thread, saved_stack_limit_);
  }
  uword saved_stack_limit() const { return saved_stack_limit_; }

#if defined(USING_SAFE_STACK)
  uword saved_safestack_limit() const { return saved_safestack_limit_; }
  void set_saved_safestack_limit(uword limit) {
    saved_safestack_limit_ = limit;
  }
#endif
  uword saved_shadow_call_stack() const { return saved_shadow_call_stack_; }
  static uword saved_shadow_call_stack_offset() {
    return OFFSET_OF(Thread, saved_shadow_call_stack_);
  }

  // Stack overflow flags
  enum {
    kOsrRequest = 0x1,  // Current stack overflow caused by OSR request.
  };

  uword write_barrier_mask() const { return write_barrier_mask_; }
  uword heap_base() const {
#if defined(DART_COMPRESSED_POINTERS)
    return heap_base_;
#else
    return 0;
#endif
  }

  static intptr_t write_barrier_mask_offset() {
    return OFFSET_OF(Thread, write_barrier_mask_);
  }
#if defined(DART_COMPRESSED_POINTERS)
  static intptr_t heap_base_offset() { return OFFSET_OF(Thread, heap_base_); }
#endif
  static intptr_t stack_overflow_flags_offset() {
    return OFFSET_OF(Thread, stack_overflow_flags_);
  }

  int32_t IncrementAndGetStackOverflowCount() {
    return ++stack_overflow_count_;
  }

  uint32_t IncrementAndGetRuntimeCallCount() { return ++runtime_call_count_; }

  static uword stack_overflow_shared_stub_entry_point_offset(bool fpu_regs) {
    return fpu_regs
               ? stack_overflow_shared_with_fpu_regs_entry_point_offset()
               : stack_overflow_shared_without_fpu_regs_entry_point_offset();
  }

  static intptr_t safepoint_state_offset() {
    return OFFSET_OF(Thread, safepoint_state_);
  }

  // Tag state is maintained on transitions.
  enum {
    // Always true in generated state.
    kDidNotExit = 0,
    // The VM exited the generated state through FFI.
    // This can be true in both native and VM state.
    kExitThroughFfi = 1,
    // The VM exited the generated state through a runtime call.
    // This can be true in both native and VM state.
    kExitThroughRuntimeCall = 2,
  };

  uword exit_through_ffi() { return exit_through_ffi_; }
  static intptr_t exit_through_ffi_offset() {
    return OFFSET_OF(Thread, exit_through_ffi_);
  }

  TaskKind task_kind() const {
    return task_kind_.load(std::memory_order_acquire);
  }
  void set_task_kind(TaskKind kind) {
    task_kind_.store(kind, std::memory_order_release);
  }

  // Retrieves and clears the stack overflow flags.  These are set by
  // the generated code before the slow path runtime routine for a
  // stack overflow is called.
  uword GetAndClearStackOverflowFlags();

  // Interrupt bits.
  enum {
    kVMInterrupt = 0x1,  // Internal VM checks: safepoints, store buffers, etc.
    kMessageInterrupt = 0x2,  // An interrupt to process an out of band message.

    kInterruptsMask = (kVMInterrupt | kMessageInterrupt),
  };

  void ScheduleInterrupts(uword interrupt_bits);
  ErrorPtr HandleInterrupts();
  ErrorPtr HandleInterrupts(uword interrupt_bits);
  uword GetAndClearInterrupts();
  bool HasScheduledInterrupts() const {
    return (stack_limit_.load() & kInterruptsMask) != 0;
  }

  // Monitor corresponding to this thread.
  Monitor* thread_lock() const { return &thread_lock_; }

  // The reusable api local scope for this thread.
  ApiLocalScope* api_reusable_scope() const { return api_reusable_scope_; }
  void set_api_reusable_scope(ApiLocalScope* value) {
    ASSERT(value == nullptr || api_reusable_scope_ == nullptr);
    api_reusable_scope_ = value;
  }

  // The api local scope for this thread, this where all local handles
  // are allocated.
  ApiLocalScope* api_top_scope() const { return api_top_scope_; }
  void set_api_top_scope(ApiLocalScope* value) { api_top_scope_ = value; }
  static intptr_t api_top_scope_offset() {
    return OFFSET_OF(Thread, api_top_scope_);
  }

  void EnterApiScope();
  void ExitApiScope();

  static intptr_t double_truncate_round_supported_offset() {
    return OFFSET_OF(Thread, double_truncate_round_supported_);
  }

  static intptr_t tsan_utils_offset() { return OFFSET_OF(Thread, tsan_utils_); }

#if defined(USING_THREAD_SANITIZER)
  uword exit_through_ffi() const { return exit_through_ffi_; }
  TsanUtils* tsan_utils() const { return tsan_utils_; }
#endif  // defined(USING_THREAD_SANITIZER)

  // The isolate that this thread is operating on, or nullptr if none.
  Isolate* isolate() const { return isolate_; }
  static intptr_t isolate_offset() { return OFFSET_OF(Thread, isolate_); }
  static intptr_t isolate_group_offset() {
    return OFFSET_OF(Thread, isolate_group_);
  }

  // The isolate group that this thread is operating on, or nullptr if none.
  IsolateGroup* isolate_group() const { return isolate_group_; }

  static intptr_t field_table_values_offset() {
    return OFFSET_OF(Thread, field_table_values_);
  }

  static intptr_t shared_field_table_values_offset() {
    return OFFSET_OF(Thread, shared_field_table_values_);
  }

  bool IsDartMutatorThread() const { return task_kind_ == kMutatorTask; }

  bool HasDartMutatorStack() const {
    // The thread with dart mutator task might be temporarily
    // occupied by a gc task.
    return IsDartMutatorThread()
           // mutator thread with isolate
           || scheduled_dart_mutator_isolate_ != nullptr
           // mutator thread without isolate
           || top_exit_frame_info_ != 0;
  }

  // Returns the dart mutator [Isolate] this thread belongs to or nullptr.
  //
  // `isolate()` in comparison can return
  //   - `nullptr` for dart mutators (e.g. if the mutator runs under
  //     [NoActiveIsolateScope])
  //   - an incorrect isolate (e.g. if [ActiveIsolateScope] is used to seemingly
  //     enter another isolate)
  Isolate* scheduled_dart_mutator_isolate() const {
    return scheduled_dart_mutator_isolate_;
  }

#if defined(DEBUG)
  bool IsInsideCompiler() const { return inside_compiler_; }
#endif

  // Offset of Dart TimelineStream object.
  static intptr_t dart_stream_offset() {
    return OFFSET_OF(Thread, dart_stream_);
  }

  // Offset of the Dart VM Service Extension StreamInfo object.
  static intptr_t service_extension_stream_offset() {
    return OFFSET_OF(Thread, service_extension_stream_);
  }

  // Is |this| executing Dart code?
  bool IsExecutingDartCode() const;

  // Has |this| exited Dart code?
  bool HasExitedDartCode() const;

  bool HasCompilerState() const { return compiler_state_ != nullptr; }

  CompilerState& compiler_state() {
    ASSERT(HasCompilerState());
    return *compiler_state_;
  }

  HierarchyInfo* hierarchy_info() const {
    ASSERT(isolate_group_ != nullptr);
    return hierarchy_info_;
  }

  void set_hierarchy_info(HierarchyInfo* value) {
    ASSERT(isolate_group_ != nullptr);
    ASSERT((hierarchy_info_ == nullptr && value != nullptr) ||
           (hierarchy_info_ != nullptr && value == nullptr));
    hierarchy_info_ = value;
  }

  TypeUsageInfo* type_usage_info() const {
    ASSERT(isolate_group_ != nullptr);
    return type_usage_info_;
  }

  void set_type_usage_info(TypeUsageInfo* value) {
    ASSERT(isolate_group_ != nullptr);
    ASSERT((type_usage_info_ == nullptr && value != nullptr) ||
           (type_usage_info_ != nullptr && value == nullptr));
    type_usage_info_ = value;
  }

  CompilerTimings* compiler_timings() const { return compiler_timings_; }

  void set_compiler_timings(CompilerTimings* stats) {
    compiler_timings_ = stats;
  }

  int32_t no_callback_scope_depth() const { return no_callback_scope_depth_; }
  void IncrementNoCallbackScopeDepth() {
    ASSERT(no_callback_scope_depth_ < INT_MAX);
    no_callback_scope_depth_ += 1;
  }
  void DecrementNoCallbackScopeDepth() {
    ASSERT(no_callback_scope_depth_ > 0);
    no_callback_scope_depth_ -= 1;
  }

  bool force_growth() const { return force_growth_scope_depth_ != 0; }
  void IncrementForceGrowthScopeDepth() {
    ASSERT(force_growth_scope_depth_ < INT_MAX);
    force_growth_scope_depth_ += 1;
  }
  void DecrementForceGrowthScopeDepth() {
    ASSERT(force_growth_scope_depth_ > 0);
    force_growth_scope_depth_ -= 1;
  }

  bool is_unwind_in_progress() const { return is_unwind_in_progress_; }

  void StartUnwindError() {
    is_unwind_in_progress_ = true;
    SetUnwindErrorInProgress(true);
  }

#if defined(DEBUG)
  void EnterCompiler() {
    ASSERT(!IsInsideCompiler());
    inside_compiler_ = true;
  }

  void LeaveCompiler() {
    ASSERT(IsInsideCompiler());
    inside_compiler_ = false;
  }
#endif

  void StoreBufferAddObject(ObjectPtr obj);
  void StoreBufferAddObjectGC(ObjectPtr obj);
#if defined(TESTING)
  bool StoreBufferContains(ObjectPtr obj) const {
    return store_buffer_block_->Contains(obj);
  }
#endif
  void StoreBufferBlockProcess(StoreBuffer::ThresholdPolicy policy);
  void StoreBufferReleaseGC();
  void StoreBufferAcquireGC();
  static intptr_t store_buffer_block_offset() {
    return OFFSET_OF(Thread, store_buffer_block_);
  }

  bool is_marking() const { return old_marking_stack_block_ != nullptr; }
  void MarkingStackAddObject(ObjectPtr obj);
  void OldMarkingStackAddObject(ObjectPtr obj);
  void NewMarkingStackAddObject(ObjectPtr obj);
  void DeferredMarkingStackAddObject(ObjectPtr obj);
  void OldMarkingStackBlockProcess();
  void NewMarkingStackBlockProcess();
  void DeferredMarkingStackBlockProcess();
  static intptr_t old_marking_stack_block_offset() {
    return OFFSET_OF(Thread, old_marking_stack_block_);
  }
  static intptr_t new_marking_stack_block_offset() {
    return OFFSET_OF(Thread, new_marking_stack_block_);
  }

  uword top_exit_frame_info() const { return top_exit_frame_info_; }
  void set_top_exit_frame_info(uword top_exit_frame_info) {
    top_exit_frame_info_ = top_exit_frame_info;
  }
  static intptr_t top_exit_frame_info_offset() {
    return OFFSET_OF(Thread, top_exit_frame_info_);
  }

  Heap* heap() const;

  // The TLAB memory boundaries.
  //
  // When the heap sampling profiler is enabled, we use the TLAB boundary to
  // trigger slow path allocations so we can take a sample. This means that
  // true_end() >= end(), where true_end() is the actual end address of the
  // TLAB and end() is the chosen sampling boundary for the thread.
  //
  // When the heap sampling profiler is disabled, true_end() == end().
  uword top() const { return top_.load(std::memory_order_relaxed); }
  uword end() const { return end_; }
  uword true_end() const { return true_end_; }
  void set_top(uword top) { top_.store(top, std::memory_order_relaxed); }
  void set_end(uword end) { end_ = end; }
  void set_true_end(uword true_end) { true_end_ = true_end; }
  static intptr_t top_offset() { return OFFSET_OF(Thread, top_); }
  static intptr_t end_offset() { return OFFSET_OF(Thread, end_); }

  int32_t no_safepoint_scope_depth() const {
#if defined(DEBUG)
    return no_safepoint_scope_depth_;
#else
    return 0;
#endif
  }

  void IncrementNoSafepointScopeDepth() {
#if defined(DEBUG)
    ASSERT(no_safepoint_scope_depth_ < INT_MAX);
    no_safepoint_scope_depth_ += 1;
#endif
  }

  void DecrementNoSafepointScopeDepth() {
#if defined(DEBUG)
    ASSERT(no_safepoint_scope_depth_ > 0);
    no_safepoint_scope_depth_ -= 1;
#endif
  }

  bool IsInNoReloadScope() const { return no_reload_scope_depth_ > 0; }

  bool IsInStoppedMutatorsScope() const {
    return stopped_mutators_scope_depth_ > 0;
  }

#define DEFINE_OFFSET_METHOD(type_name, member_name, expr, default_init_value) \
  static intptr_t member_name##offset() {                                      \
    return OFFSET_OF(Thread, member_name);                                     \
  }
  CACHED_CONSTANTS_LIST(DEFINE_OFFSET_METHOD)
#undef DEFINE_OFFSET_METHOD

  static intptr_t write_barrier_wrappers_thread_offset(Register reg) {
    ASSERT((kDartAvailableCpuRegs & (1 << reg)) != 0);
    intptr_t index = 0;
    for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
      if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
      if (i == reg) break;
      ++index;
    }
    return OFFSET_OF(Thread, write_barrier_wrappers_entry_points_) +
           index * sizeof(uword);
  }

  static intptr_t WriteBarrierWrappersOffsetForRegister(Register reg) {
    intptr_t index = 0;
    for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
      if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
      if (i == reg) {
        return index * kStoreBufferWrapperSize;
      }
      ++index;
    }
    UNREACHABLE();
    return 0;
  }

#define DEFINE_OFFSET_METHOD(name)                                             \
  static intptr_t name##_entry_point_offset() {                                \
    return OFFSET_OF(Thread, name##_entry_point_);                             \
  }
  RUNTIME_ENTRY_LIST(DEFINE_OFFSET_METHOD)
#undef DEFINE_OFFSET_METHOD

#define DEFINE_OFFSET_METHOD(returntype, name, ...)                            \
  static intptr_t name##_entry_point_offset() {                                \
    return OFFSET_OF(Thread, name##_entry_point_);                             \
  }
  LEAF_RUNTIME_ENTRY_LIST(DEFINE_OFFSET_METHOD)
#undef DEFINE_OFFSET_METHOD

  ObjectPoolPtr global_object_pool() const { return global_object_pool_; }
  void set_global_object_pool(ObjectPoolPtr raw_value) {
    global_object_pool_ = raw_value;
  }

  const uword* dispatch_table_array() const { return dispatch_table_array_; }
  void set_dispatch_table_array(const uword* array) {
    dispatch_table_array_ = array;
  }

  static bool CanLoadFromThread(const Object& object);
  static intptr_t OffsetFromThread(const Object& object);
  static bool ObjectAtOffset(intptr_t offset, Object* object);
  static intptr_t OffsetFromThread(const RuntimeEntry* runtime_entry);

#define DEFINE_OFFSET_METHOD(name)                                             \
  static intptr_t name##_entry_point_offset() {                                \
    return OFFSET_OF(Thread, name##_entry_point_);                             \
  }
  CACHED_FUNCTION_ENTRY_POINTS_LIST(DEFINE_OFFSET_METHOD)
#undef DEFINE_OFFSET_METHOD

#if defined(DEBUG)
  // For asserts only. Has false positives when running with a simulator or
  // SafeStack.
  bool TopErrorHandlerIsSetJump() const;
  bool TopErrorHandlerIsExitFrame() const;
#endif

  uword vm_tag() const { return vm_tag_; }
  void set_vm_tag(uword tag) { vm_tag_ = tag; }
  static intptr_t vm_tag_offset() { return OFFSET_OF(Thread, vm_tag_); }

  int64_t unboxed_int64_runtime_arg() const {
    return unboxed_runtime_arg_.int64_storage[0];
  }
  void set_unboxed_int64_runtime_arg(int64_t value) {
    unboxed_runtime_arg_.int64_storage[0] = value;
  }
  int64_t unboxed_int64_runtime_second_arg() const {
    return unboxed_runtime_arg_.int64_storage[1];
  }
  void set_unboxed_int64_runtime_second_arg(int64_t value) {
    unboxed_runtime_arg_.int64_storage[1] = value;
  }
  double unboxed_double_runtime_arg() const {
    return unboxed_runtime_arg_.double_storage[0];
  }
  void set_unboxed_double_runtime_arg(double value) {
    unboxed_runtime_arg_.double_storage[0] = value;
  }
  simd128_value_t unboxed_simd128_runtime_arg() const {
    return unboxed_runtime_arg_;
  }
  void set_unboxed_simd128_runtime_arg(simd128_value_t value) {
    unboxed_runtime_arg_ = value;
  }
  static intptr_t unboxed_runtime_arg_offset() {
    return OFFSET_OF(Thread, unboxed_runtime_arg_);
  }

  static intptr_t global_object_pool_offset() {
    return OFFSET_OF(Thread, global_object_pool_);
  }

  static intptr_t dispatch_table_array_offset() {
    return OFFSET_OF(Thread, dispatch_table_array_);
  }

  ObjectPtr active_exception() const { return active_exception_; }
  void set_active_exception(const Object& value);
  void set_active_exception(LocalHandle* value);
  static intptr_t active_exception_offset() {
    return OFFSET_OF(Thread, active_exception_);
  }

  ObjectPtr active_stacktrace() const { return active_stacktrace_; }
  void set_active_stacktrace(const Object& value);
  static intptr_t active_stacktrace_offset() {
    return OFFSET_OF(Thread, active_stacktrace_);
  }

  uword resume_pc() const { return resume_pc_; }
  void set_resume_pc(uword value) { resume_pc_ = value; }
  static uword resume_pc_offset() { return OFFSET_OF(Thread, resume_pc_); }

  ErrorPtr sticky_error() const;
  void set_sticky_error(const Error& value);
  void ClearStickyError();
  DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError();

#if defined(DEBUG)
#define REUSABLE_HANDLE_SCOPE_ACCESSORS(object)                                \
  void set_reusable_##object##_handle_scope_active(bool value) {               \
    reusable_##object##_handle_scope_active_ = value;                          \
  }                                                                            \
  bool reusable_##object##_handle_scope_active() const {                       \
    return reusable_##object##_handle_scope_active_;                           \
  }
  REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_ACCESSORS)
#undef REUSABLE_HANDLE_SCOPE_ACCESSORS

  bool IsAnyReusableHandleScopeActive() const {
#define IS_REUSABLE_HANDLE_SCOPE_ACTIVE(object)                                \
  if (reusable_##object##_handle_scope_active_) {                              \
    return true;                                                               \
  }
    REUSABLE_HANDLE_LIST(IS_REUSABLE_HANDLE_SCOPE_ACTIVE)
    return false;
#undef IS_REUSABLE_HANDLE_SCOPE_ACTIVE
  }
#endif  // defined(DEBUG)

  void ClearReusableHandles();

#define REUSABLE_HANDLE(object)                                                \
  object& object##Handle() const { return *object##_handle_; }
  REUSABLE_HANDLE_LIST(REUSABLE_HANDLE)
#undef REUSABLE_HANDLE

  static bool IsAtSafepoint(SafepointLevel level, uword state) {
    const uword mask = AtSafepointBits(level);
    return (state & mask) == mask;
  }

  // Whether the current thread is owning any safepoint level.
  bool IsAtSafepoint() const {
    // Owning a higher level safepoint implies owning the lower levels as well.
    return IsAtSafepoint(SafepointLevel::kGC);
  }
  bool IsAtSafepoint(SafepointLevel level) const {
    return IsAtSafepoint(level, safepoint_state_.load());
  }
  void SetAtSafepoint(bool value, SafepointLevel level) {
    ASSERT(thread_lock()->IsOwnedByCurrentThread());
    ASSERT(level <= current_safepoint_level());
    if (value) {
      safepoint_state_ |= AtSafepointBits(level);
    } else {
      safepoint_state_ &= ~AtSafepointBits(level);
    }
  }
  bool IsSafepointRequestedLocked(SafepointLevel level) const {
    ASSERT(thread_lock()->IsOwnedByCurrentThread());
    return IsSafepointRequested(level);
  }
  bool IsSafepointRequested() const {
    return IsSafepointRequested(current_safepoint_level());
  }
  bool IsSafepointRequested(SafepointLevel level) const {
    const uword state = safepoint_state_.load();
    for (intptr_t i = level; i >= 0; --i) {
      if (IsSafepointLevelRequested(state, static_cast<SafepointLevel>(i)))
        return true;
    }
    return false;
  }
  bool IsSafepointLevelRequestedLocked(SafepointLevel level) const {
    ASSERT(thread_lock()->IsOwnedByCurrentThread());
    if (level > current_safepoint_level()) return false;
    const uword state = safepoint_state_.load();
    return IsSafepointLevelRequested(state, level);
  }

  static bool IsSafepointLevelRequested(uword state, SafepointLevel level) {
    switch (level) {
      case SafepointLevel::kGC:
        return SafepointRequestedField::decode(state);
      case SafepointLevel::kGCAndDeopt:
        return DeoptSafepointRequestedField::decode(state);
      case SafepointLevel::kGCAndDeoptAndReload:
        return ReloadSafepointRequestedField::decode(state);
      default:
        UNREACHABLE();
    }
  }

  void BlockForSafepoint();

  uword SetSafepointRequested(SafepointLevel level, bool value) {
    ASSERT(thread_lock()->IsOwnedByCurrentThread());

    uword mask = 0;
    switch (level) {
      case SafepointLevel::kGC:
        mask = SafepointRequestedField::mask_in_place();
        break;
      case SafepointLevel::kGCAndDeopt:
        mask = DeoptSafepointRequestedField::mask_in_place();
        break;
      case SafepointLevel::kGCAndDeoptAndReload:
        mask = ReloadSafepointRequestedField::mask_in_place();
        break;
      default:
        UNREACHABLE();
    }

    if (value) {
      // acquire pulls from the release in TryEnterSafepoint.
      return safepoint_state_.fetch_or(mask, std::memory_order_acquire);
    } else {
      // release pushes to the acquire in TryExitSafepoint.
      return safepoint_state_.fetch_and(~mask, std::memory_order_release);
    }
  }
  static bool IsBlockedForSafepoint(uword state) {
    return BlockedForSafepointField::decode(state);
  }
  bool IsBlockedForSafepoint() const {
    return BlockedForSafepointField::decode(safepoint_state_);
  }
  // Normally execution state is only accessed for the current thread.
  NO_SANITIZE_THREAD
  bool IsBlockedForSafepointCrossThreadForTesting() const {
    return BlockedForSafepointField::decode(safepoint_state_);
  }
  void SetBlockedForSafepoint(bool value) {
    ASSERT(thread_lock()->IsOwnedByCurrentThread());
    const uword mask = BlockedForSafepointField::mask_in_place();
    if (value) {
      safepoint_state_.fetch_or(mask);
    } else {
      safepoint_state_.fetch_and(~mask);
    }
  }
  bool BypassSafepoints() const {
    return BypassSafepointsField::decode(safepoint_state_);
  }
  static uword SetBypassSafepoints(bool value, uword state) {
    return BypassSafepointsField::update(value, state);
  }
  bool UnwindErrorInProgress() const {
    return UnwindErrorInProgressField::decode(safepoint_state_);
  }
  void SetUnwindErrorInProgress(bool value) {
    const uword mask = UnwindErrorInProgressField::mask_in_place();
    if (value) {
      safepoint_state_.fetch_or(mask);
    } else {
      safepoint_state_.fetch_and(~mask);
    }
  }
  void SetNoReloadScope(bool value) {
    const uword mask = NoReloadScopeField::mask_in_place();
    if (value) {
      safepoint_state_.fetch_or(mask);
    } else {
      safepoint_state_.fetch_and(~mask);
    }
  }

  bool OwnsGCSafepoint() const;
  bool OwnsReloadSafepoint() const;
  bool OwnsDeoptSafepoint() const;
  bool OwnsSafepoint() const;
  bool CanAcquireSafepointLocks() const;

  uword safepoint_state() { return safepoint_state_; }

  enum ExecutionState {
    kThreadInVM = 0,
    kThreadInGenerated,
    kThreadInNative,
    kThreadInBlockedState
  };

  ExecutionState execution_state() const {
    return static_cast<ExecutionState>(execution_state_);
  }
  void set_execution_state(ExecutionState state) {
    execution_state_ = static_cast<uword>(state);
  }
  static intptr_t execution_state_offset() {
    return OFFSET_OF(Thread, execution_state_);
  }

  virtual bool MayAllocateHandles() {
    return (execution_state() == kThreadInVM) ||
           (execution_state() == kThreadInGenerated);
  }

  static uword native_safepoint_state_unacquired() {
    return AtSafepointField::encode(false) |
           AtDeoptSafepointField::encode(false) |
#if !defined(PRODUCT)
           AtReloadSafepointField::encode(false) |
#endif
           ActiveMutatorStealableField::encode(false) |
           NoReloadScopeField::encode(false);
  }
  static uword native_safepoint_state_acquired() {
    return AtSafepointField::encode(true) |
           AtDeoptSafepointField::encode(true) |
#if !defined(PRODUCT)
           AtReloadSafepointField::encode(true) |
#endif
           ActiveMutatorStealableField::encode(true) |
           NoReloadScopeField::encode(false);
  }

  bool TryStealActiveMutator() {
    uword old_state = safepoint_state_.load();
    if (!ActiveMutatorStealableField::decode(old_state)) return false;
    uword new_state = old_state;
    new_state = ActiveMutatorStealableField::update(false, new_state);
    new_state = ActiveMutatorStolenField::update(true, new_state);
    return safepoint_state_.compare_exchange_strong(old_state, new_state,
                                                    std::memory_order_relaxed);
  }

  bool TryEnterSafepointToNative() {
    uword old_state = native_safepoint_state_unacquired();
    uword new_state = native_safepoint_state_acquired();
    return safepoint_state_.compare_exchange_strong(old_state, new_state,
                                                    std::memory_order_release);
  }

  void EnterSafepointToNative() {
    ASSERT(no_safepoint_scope_depth() == 0);
    // First try a fast update of the thread state to indicate it is at a
    // safepoint.
    if (!TryEnterSafepointToNative()) {
      // Fast update failed which means we could potentially be in the middle
      // of a safepoint operation.
      EnterSafepointUsingLock();
      if (!NoReloadScopeField::decode(safepoint_state_)) {
        safepoint_state_.fetch_or(ActiveMutatorStealableField::encode(true));
      }
    }
  }

  bool TryEnterSafepoint() {
    uword old_state = 0;
    uword new_state = AtSafepointBits(current_safepoint_level());
    return safepoint_state_.compare_exchange_strong(old_state, new_state,
                                                    std::memory_order_release);
  }

  void EnterSafepoint() {
    ASSERT(no_safepoint_scope_depth() == 0);
    // First try a fast update of the thread state to indicate it is at a
    // safepoint.
    if (!TryEnterSafepoint()) {
      // Fast update failed which means we could potentially be in the middle
      // of a safepoint operation.
      EnterSafepointUsingLock();
    }
  }

  bool TryExitSafepoint() {
    uword old_state = AtSafepointBits(current_safepoint_level());
    uword new_state = 0;
    return safepoint_state_.compare_exchange_strong(old_state, new_state,
                                                    std::memory_order_acquire);
  }

  void ExitSafepoint() {
    ASSERT(!ActiveMutatorStealableField::decode(safepoint_state_));
    ASSERT(!ActiveMutatorStolenField::decode(safepoint_state_));

    // First try a fast update of the thread state to indicate it is not at a
    // safepoint anymore.
    if (!TryExitSafepoint()) {
      // Fast update failed which means we could potentially be in the middle
      // of a safepoint operation.
      ExitSafepointUsingLock();
    }

#ifndef PRODUCT
    // Exit frame must have remained valid for the whole duration of the
    // safepoint. Do some quick checks to validate that.
    if (FLAG_use_slow_path) {
      ValidateExitFrameState();
    }
#endif
  }

  bool TryExitSafepointFromNative() {
    uword old_state = native_safepoint_state_acquired();
    uword new_state = native_safepoint_state_unacquired();
    return safepoint_state_.compare_exchange_strong(old_state, new_state,
                                                    std::memory_order_acquire);
  }

  void ExitSafepointFromNative() {
    if (!TryExitSafepointFromNative()) {
      ExitSafepointUsingLock();
      uword old_state = safepoint_state_.fetch_and(
          ~(ActiveMutatorStealableField::encode(true) |
            ActiveMutatorStolenField::encode(true)));
      if (ActiveMutatorStolenField::decode(old_state)) {
        set_execution_state(Thread::kThreadInVM);
        allow_reload_scope_depth_++;
        HandleStolen();
        allow_reload_scope_depth_--;
      }
    }

    ASSERT(!ActiveMutatorStealableField::decode(safepoint_state_));
    ASSERT(!ActiveMutatorStolenField::decode(safepoint_state_));

#ifndef PRODUCT
    // Exit frame must have remained valid for the whole duration of the
    // safepoint. Do some quick checks to validate that.
    if (FLAG_use_slow_path) {
      ValidateExitFrameState();
    }
#endif
  }

  void HandleStolen();

#ifndef PRODUCT
  void ValidateExitFrameState();
#endif

  void CheckForSafepoint() {
    // If we are in a runtime call that doesn't support lazy deopt, we will only
    // respond to gc safepointing requests.
    ASSERT(no_safepoint_scope_depth() == 0);
    if (IsSafepointRequested()) {
      bool stolen = ActiveMutatorStolenField::decode(safepoint_state_.load());
      ASSERT(!stolen);

      BlockForSafepoint();
    }
  }

  Thread* next() const { return next_; }

  // Visit all object pointers.
  void VisitObjectPointers(ObjectPointerVisitor* visitor,
                           ValidationPolicy validate_frames);
  void RememberLiveTemporaries();
  void DeferredMarkLiveTemporaries();

  bool IsValidHandle(Dart_Handle object) const;
  bool IsValidLocalHandle(Dart_Handle object) const;
  intptr_t CountLocalHandles() const;
  int ZoneSizeInBytes() const;
  void UnwindScopes(uword stack_marker);

  void InitVMConstants();

  int64_t GetNextTaskId() { return next_task_id_++; }
  static intptr_t next_task_id_offset() {
    return OFFSET_OF(Thread, next_task_id_);
  }
  Random* random() { return &thread_random_; }
  static intptr_t random_offset() { return OFFSET_OF(Thread, thread_random_); }

#ifndef PRODUCT
  void PrintJSON(JSONStream* stream) const;
#endif

#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
  HeapProfileSampler& heap_sampler() { return heap_sampler_; }
#endif

  PendingDeopts& pending_deopts() { return pending_deopts_; }

  SafepointLevel current_safepoint_level() const {
    if (runtime_call_deopt_ability_ ==
        RuntimeCallDeoptAbility::kCannotLazyDeopt) {
      return SafepointLevel::kGC;
    }
#if defined(PRODUCT)
    return SafepointLevel::kGCAndDeopt;
#else
    if (no_reload_scope_depth_ > 0) {
      return SafepointLevel::kGCAndDeopt;
    }
    if (execution_state_ == kThreadInNative) {
      return SafepointLevel::kGCAndDeoptAndReload;
    }
    if (allow_reload_scope_depth_ <= 0) {
      return SafepointLevel::kGCAndDeopt;
    }
    return SafepointLevel::kGCAndDeoptAndReload;
#endif
  }

#if defined(DART_DYNAMIC_MODULES)
  Interpreter* interpreter() const { return interpreter_; }
  void set_interpreter(Interpreter* value) { interpreter_ = value; }

  bytecode::BytecodeLoader* bytecode_loader() const { return bytecode_loader_; }
  void set_bytecode_loader(bytecode::BytecodeLoader* value) {
    bytecode_loader_ = value;
  }
#endif

  void set_single_step(bool value) { single_step_ = value; }
  bool single_step() const { return single_step_; }
  static intptr_t single_step_offset() {
    return OFFSET_OF(Thread, single_step_);
  }

  bool IsDeoptimizing() const { return deopt_context_ != nullptr; }
  DeoptContext* deopt_context() const { return deopt_context_; }
  void set_deopt_context(DeoptContext* value) {
    ASSERT(value == nullptr || deopt_context_ == nullptr);
    deopt_context_ = value;
  }

 private:
  template <class T>
  T* AllocateReusableHandle();

  enum class RestoreWriteBarrierInvariantOp {
    kAddToRememberedSet,
    kAddToDeferredMarkingStack
  };
  friend class RestoreWriteBarrierInvariantVisitor;
  void RestoreWriteBarrierInvariant(RestoreWriteBarrierInvariantOp op);

  // Set the current compiler state and return the previous compiler state.
  CompilerState* SetCompilerState(CompilerState* state) {
    CompilerState* previous = compiler_state_;
    compiler_state_ = state;
    return previous;
  }

  // Accessed from generated code.
  // ** This block of fields must come first! **
  // For AOT cross-compilation, we rely on these members having the same offsets
  // in SIMARM(IA32) and ARM, and the same offsets in SIMARM64(X64) and ARM64.
  // We use only word-sized fields to avoid differences in struct packing on the
  // different architectures. See also CheckOffsets in dart.cc.
  volatile RelaxedAtomic<uword> stack_limit_ = 0;
  uword write_barrier_mask_;
#if defined(DART_COMPRESSED_POINTERS)
  uword heap_base_ = 0;
#endif
  std::atomic<uword> top_ = 0;
  uword end_ = 0;
  const uword* dispatch_table_array_ = nullptr;
  ObjectPtr* field_table_values_ = nullptr;
  ObjectPtr* shared_field_table_values_ = nullptr;

  // Offsets up to this point can all fit in a byte on X64. All of the above
  // fields are very abundantly accessed from code. Thus, keeping them first
  // is important for code size (although code size on X64 is not a priority).

// State that is cached in the TLS for fast access in generated code.
#define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value)      \
  type_name member_name;
  CACHED_CONSTANTS_LIST(DECLARE_MEMBERS)
#undef DECLARE_MEMBERS

#define DECLARE_MEMBERS(name) uword name##_entry_point_;
  RUNTIME_ENTRY_LIST(DECLARE_MEMBERS)
#undef DECLARE_MEMBERS

#define DECLARE_MEMBERS(returntype, name, ...) uword name##_entry_point_;
  LEAF_RUNTIME_ENTRY_LIST(DECLARE_MEMBERS)
#undef DECLARE_MEMBERS

  uword write_barrier_wrappers_entry_points_[kNumberOfDartAvailableCpuRegs];

#define DECLARE_MEMBERS(name) uword name##_entry_point_ = 0;
  CACHED_FUNCTION_ENTRY_POINTS_LIST(DECLARE_MEMBERS)
#undef DECLARE_MEMBERS

  Isolate* isolate_ = nullptr;
  IsolateGroup* isolate_group_ = nullptr;

  uword saved_stack_limit_ = OSThread::kInvalidStackLimit;
  // The mutator uses this to indicate it wants to OSR (by
  // setting [Thread::kOsrRequest]) before going to runtime which will see this
  // bit.
  uword stack_overflow_flags_ = 0;
  uword volatile top_exit_frame_info_ = 0;
  StoreBufferBlock* store_buffer_block_ = nullptr;
  MarkingStackBlock* old_marking_stack_block_ = nullptr;
  MarkingStackBlock* new_marking_stack_block_ = nullptr;
  MarkingStackBlock* deferred_marking_stack_block_ = nullptr;
  uword volatile vm_tag_ = 0;
  // Memory locations dedicated for passing unboxed int64 and double
  // values from generated code to runtime.
  // TODO(dartbug.com/33549): Clean this up when unboxed values
  // could be passed as arguments.
  ALIGN8 simd128_value_t unboxed_runtime_arg_;

  // JumpToExceptionHandler state:
  ObjectPtr active_exception_;
  ObjectPtr active_stacktrace_;

  ObjectPoolPtr global_object_pool_;
  uword resume_pc_;
  uword saved_shadow_call_stack_ = 0;

  /*
   * The execution state for a thread.
   *
   * Potential execution states a thread could be in:
   *   kThreadInGenerated - The thread is running jitted dart/stub code.
   *   kThreadInVM - The thread is running VM code.
   *   kThreadInNative - The thread is running native code.
   *   kThreadInBlockedState - The thread is blocked waiting for a resource.
   *
   * Warning: Execution state doesn't imply the safepoint state. It's possible
   * to be in [kThreadInNative] and still not be at-safepoint (e.g. due to a
   * pending Dart_TypedDataAcquire() that increases no-callback-scope)
   */
  uword execution_state_;

  /*
   * Stores
   *
   *   - whether the thread is at a safepoint (current thread sets these)
   *     [AtSafepointField]
   *     [AtDeoptSafepointField]
   *     [AtReloadSafepointField]
   *
   *   - whether the thread is requested to safepoint (other thread sets these)
   *     [SafepointRequestedField]
   *     [DeoptSafepointRequestedField]
   *     [ReloadSafepointRequestedField]
   *
   *   - whether the thread is blocked due to safepoint request and needs to
   *     be resumed after safepoint is done (current thread sets this)
   *     [BlockedForSafepointField]
   *
   *   - whether the thread should be ignored for safepointing purposes
   *     [BypassSafepointsField]
   *
   *   - whether the isolate running this thread has triggered an unwind error,
   *     which requires enforced exit on a transition from native back to
   *     generated.
   *     [UnwindErrorInProgressField]
   *
   *   - whether a NoReloadScope is active (current thread sets these), this
   *     causes transitions to native/FFI to take the slow path instead of
   *     entering a reload safepoint
   *     [NoReloadScopeField]
   */
  std::atomic<uword> safepoint_state_;
  uword exit_through_ffi_ = 0;
  ApiLocalScope* api_top_scope_;
  uint8_t double_truncate_round_supported_;
  ALIGN8 int64_t next_task_id_;
  ALIGN8 Random thread_random_;

  TsanUtils* tsan_utils_ = nullptr;

  bool single_step_ = false;

  // ---- End accessed from generated code. ----

  // The layout of Thread object up to this point should not depend
  // on DART_PRECOMPILED_RUNTIME, as it is accessed from generated code.
  // The code is generated without DART_PRECOMPILED_RUNTIME, but used with
  // DART_PRECOMPILED_RUNTIME.

  uword true_end_ = 0;
  std::atomic<TaskKind> task_kind_;
  TimelineStream* const dart_stream_;
  StreamInfo* const service_extension_stream_;
  mutable Monitor thread_lock_;
  ApiLocalScope* api_reusable_scope_;
  int32_t no_callback_scope_depth_;
  int32_t force_growth_scope_depth_ = 0;
  intptr_t no_reload_scope_depth_ = 0;
  intptr_t allow_reload_scope_depth_ = 0;
  intptr_t stopped_mutators_scope_depth_ = 0;
#if defined(DEBUG)
  int32_t no_safepoint_scope_depth_;
#endif
  VMHandles reusable_handles_;
  int32_t stack_overflow_count_;
  uint32_t runtime_call_count_ = 0;

  // Deoptimization of stack frames.
  RuntimeCallDeoptAbility runtime_call_deopt_ability_ =
      RuntimeCallDeoptAbility::kCanLazyDeopt;
  PendingDeopts pending_deopts_;

  // Compiler state:
  CompilerState* compiler_state_ = nullptr;
  HierarchyInfo* hierarchy_info_;
  TypeUsageInfo* type_usage_info_;
  NoActiveIsolateScope* no_active_isolate_scope_ = nullptr;

  CompilerTimings* compiler_timings_ = nullptr;

  ErrorPtr sticky_error_;

  ObjectPtr* field_table_values() const { return field_table_values_; }
  ObjectPtr* shared_field_table_values() const {
    return shared_field_table_values_;
  }

// Reusable handles support.
#define REUSABLE_HANDLE_FIELDS(object) object* object##_handle_;
  REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_FIELDS)
#undef REUSABLE_HANDLE_FIELDS

#if defined(DEBUG)
#define REUSABLE_HANDLE_SCOPE_VARIABLE(object)                                 \
  bool reusable_##object##_handle_scope_active_;
  REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_VARIABLE);
#undef REUSABLE_HANDLE_SCOPE_VARIABLE
#endif  // defined(DEBUG)

  using AtSafepointField = BitField<uword, bool>;
  using SafepointRequestedField =
      BitField<uword, bool, AtSafepointField::kNextBit>;
  using AtDeoptSafepointField =
      BitField<uword, bool, SafepointRequestedField::kNextBit>;
  using DeoptSafepointRequestedField =
      BitField<uword, bool, AtDeoptSafepointField::kNextBit>;
  using AtReloadSafepointField =
      BitField<uword, bool, DeoptSafepointRequestedField::kNextBit>;
  using ReloadSafepointRequestedField =
      BitField<uword, bool, AtReloadSafepointField::kNextBit>;
  using ActiveMutatorStealableField =
      BitField<uword, bool, ReloadSafepointRequestedField::kNextBit>;
  using ActiveMutatorStolenField =
      BitField<uword, bool, ActiveMutatorStealableField::kNextBit>;
  using BlockedForSafepointField =
      BitField<uword, bool, ActiveMutatorStolenField::kNextBit>;
  using BypassSafepointsField =
      BitField<uword, bool, BlockedForSafepointField::kNextBit>;
  using UnwindErrorInProgressField =
      BitField<uword, bool, BypassSafepointsField::kNextBit>;
  using NoReloadScopeField =
      BitField<uword, bool, UnwindErrorInProgressField::kNextBit>;

  static uword AtSafepointBits(SafepointLevel level) {
    switch (level) {
      case SafepointLevel::kGC:
        return AtSafepointField::encode(true);
      case SafepointLevel::kGCAndDeopt:
        return AtSafepointField::encode(true) |
               AtDeoptSafepointField::encode(true);
      case SafepointLevel::kGCAndDeoptAndReload:
        return AtSafepointField::encode(true) |
               AtDeoptSafepointField::encode(true) |
               AtReloadSafepointField::encode(true);
      default:
        UNREACHABLE();
    }
  }

#if defined(USING_SAFE_STACK)
  uword saved_safestack_limit_;
#endif

  Thread* next_;  // Used to chain the thread structures in an isolate.
  Isolate* scheduled_dart_mutator_isolate_ = nullptr;

  bool is_unwind_in_progress_ = false;

#if defined(DEBUG)
  bool inside_compiler_ = false;
#endif

#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
  HeapProfileSampler heap_sampler_;
#endif

#if defined(DART_DYNAMIC_MODULES)
  Interpreter* interpreter_ = nullptr;
  bytecode::BytecodeLoader* bytecode_loader_ = nullptr;
#endif

  DeoptContext* deopt_context_ = nullptr;

  explicit Thread(bool is_vm_isolate);

  void StoreBufferRelease(
      StoreBuffer::ThresholdPolicy policy = StoreBuffer::kCheckThreshold);
  void StoreBufferAcquire();

  void OldMarkingStackRelease();
  void OldMarkingStackAcquire();
  void NewMarkingStackRelease();
  void NewMarkingStackAcquire();
  void DeferredMarkingStackRelease();
  void DeferredMarkingStackAcquire();

  void AcquireMarkingStacks();
  void ReleaseMarkingStacks();
  void FlushMarkingStacks();

  void set_safepoint_state(uint32_t value) { safepoint_state_ = value; }
  void EnterSafepointUsingLock();
  void ExitSafepointUsingLock();

  void SetupStateLocked(TaskKind kind);
  void ResetStateLocked();

  void SetupMutatorState();
  void ResetMutatorState();

  void SetupDartMutatorState(Isolate* isolate);
  void SetupDartMutatorStateDependingOnSnapshot(IsolateGroup* group);
  void ResetDartMutatorState();

  static void SuspendDartMutatorThreadInternal(Thread* thread,
                                               VMTag::VMTagId tag);
  static void ResumeDartMutatorThreadInternal(Thread* thread);

  static void SuspendThreadInternal(Thread* thread, VMTag::VMTagId tag);
  static void ResumeThreadInternal(Thread* thread);

  // Adds a new active thread to thread registry while associating it
  // with the given isolate (group).
  //
  // All existing safepoint operations are waited for before adding the thread
  // to the thread registry.
  //
  // => Anyone who iterates the active threads will first have to get us to
  // safepoint (but can access `Thread::isolate()`).
  static Thread* AddActiveThread(IsolateGroup* group,
                                 Isolate* isolate,
                                 TaskKind task_kind,
                                 bool bypass_safepoint);

  // Releases an active thread from the thread registry.
  //
  // Thread needs to be at-safepoint.
  static void FreeActiveThread(Thread* thread,
                               Isolate* isolate,
                               bool bypass_safepoint);

  static void SetCurrent(Thread* current) { OSThread::SetCurrentTLS(current); }

#define REUSABLE_FRIEND_DECLARATION(name)                                      \
  friend class Reusable##name##HandleScope;
  REUSABLE_HANDLE_LIST(REUSABLE_FRIEND_DECLARATION)
#undef REUSABLE_FRIEND_DECLARATION

  friend class ApiZone;
  friend class ActiveIsolateScope;
  friend class Interpreter;
  friend class InterruptChecker;
  friend class Isolate;
  friend class IsolateGroup;
  friend class NoActiveIsolateScope;
  friend class NoReloadScope;
  friend class RawReloadParticipationScope;
  friend class Simulator;
  friend class StackZone;
  friend class StoppedMutatorsScope;
  friend class ThreadRegistry;
  friend class CompilerState;
  friend class compiler::target::Thread;
  friend class FieldTable;
  friend class RuntimeCallDeoptScope;
  friend class Dart;  // Calls SetupCachedEntryPoints after snapshot reading
  friend class
      TransitionGeneratedToVM;  // IsSafepointRequested/BlockForSafepoint
  friend class
      TransitionVMToGenerated;  // IsSafepointRequested/BlockForSafepoint
  friend class MonitorLocker;   // ExitSafepointUsingLock
  friend Isolate* CreateWithinExistingIsolateGroup(IsolateGroup*,
                                                   const char*,
                                                   char**);
  DISALLOW_COPY_AND_ASSIGN(Thread);
};

class RuntimeCallDeoptScope : public StackResource {
 public:
  RuntimeCallDeoptScope(Thread* thread, RuntimeCallDeoptAbility kind)
      : StackResource(thread) {
    // We cannot have nested calls into the VM without deopt support.
    ASSERT(thread->runtime_call_deopt_ability_ ==
           RuntimeCallDeoptAbility::kCanLazyDeopt);
    thread->runtime_call_deopt_ability_ = kind;
  }
  virtual ~RuntimeCallDeoptScope() {
    thread()->runtime_call_deopt_ability_ =
        RuntimeCallDeoptAbility::kCanLazyDeopt;
  }

 private:
  Thread* thread() {
    return reinterpret_cast<Thread*>(StackResource::thread());
  }
};

#if defined(DART_HOST_OS_WINDOWS)
// Clears the state of the current thread and frees the allocation.
void WindowsThreadCleanUp();
#endif

#if !defined(PRODUCT)
// Disable thread interrupts.
class DisableThreadInterruptsScope : public StackResource {
 public:
  explicit DisableThreadInterruptsScope(Thread* thread);
  ~DisableThreadInterruptsScope();
};
#else
class DisableThreadInterruptsScope : public StackResource {
 public:
  explicit DisableThreadInterruptsScope(Thread* thread)
      : StackResource(thread) {}
  ~DisableThreadInterruptsScope() {}
};
#endif  // !defined(PRODUCT)

// Within a NoSafepointScope, the thread must not reach any safepoint. Used
// around code that manipulates raw object pointers directly without handles.
#if defined(DEBUG)
class NoSafepointScope : public ThreadStackResource {
 public:
  explicit NoSafepointScope(Thread* thread = nullptr)
      : ThreadStackResource(thread != nullptr ? thread : Thread::Current()) {
    this->thread()->IncrementNoSafepointScopeDepth();
  }
  ~NoSafepointScope() { thread()->DecrementNoSafepointScopeDepth(); }

 private:
  DISALLOW_COPY_AND_ASSIGN(NoSafepointScope);
};
#else   // defined(DEBUG)
class NoSafepointScope : public ValueObject {
 public:
  explicit NoSafepointScope(Thread* thread = nullptr) {}

 private:
  DISALLOW_COPY_AND_ASSIGN(NoSafepointScope);
};
#endif  // defined(DEBUG)

// Disables initiating a reload operation as well as participating in another
// threads reload operation.
//
// Reload triggered by a mutator thread happens by sending all other mutator
// threads (that are running) OOB messages to check into a safepoint. The thread
// initiating the reload operation will block until all mutators are at a reload
// safepoint.
//
// When running under this scope, the processing of those OOB messages will
// ignore reload safepoint checkin requests. Yet we'll have to ensure that the
// dropped message is still acted upon.
//
// => To solve this we make the [~NoReloadScope] destructor resend a new reload
// OOB request to itself (the [~NoReloadScope] destructor is not necessarily at
// well-defined place where reload can happen - those places will explicitly
// opt-in via [ReloadParticipationScope]).
//
class NoReloadScope : public ThreadStackResource {
 public:
  explicit NoReloadScope(Thread* thread);
  ~NoReloadScope();

 private:
  DISALLOW_COPY_AND_ASSIGN(NoReloadScope);
};

// Allows triggering reload safepoint operations as well as participating in
// reload operations (at safepoint checks).
//
// By-default safepoint checkins will not participate in reload operations, as
// reload has to happen at very well-defined places. This scope is intended
// for those places where we explicitly want to allow safepoint checkins to
// participate in reload operations (triggered by other threads).
//
// If there is any [NoReloadScope] active we will still disable the safepoint
// checkins to participate in reload.
//
// We also require the thread inititating a reload operation to explicitly
// opt-in via this scope.
class RawReloadParticipationScope {
 public:
  explicit RawReloadParticipationScope(Thread* thread) : thread_(thread) {
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
    thread->allow_reload_scope_depth_++;
    ASSERT(thread->allow_reload_scope_depth_ >= 0);
#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
  }

  ~RawReloadParticipationScope() {
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
    thread_->allow_reload_scope_depth_ -= 1;
    ASSERT(thread_->allow_reload_scope_depth_ >= 0);
#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
  }

 private:
  Thread* thread_;

  DISALLOW_COPY_AND_ASSIGN(RawReloadParticipationScope);
};

using ReloadParticipationScope =
    AsThreadStackResource<RawReloadParticipationScope>;

class StoppedMutatorsScope : public ThreadStackResource {
 public:
  explicit StoppedMutatorsScope(Thread* thread) : ThreadStackResource(thread) {
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
    thread->stopped_mutators_scope_depth_++;
    ASSERT(thread->stopped_mutators_scope_depth_ >= 0);
#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
  }

  ~StoppedMutatorsScope() {
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
    thread()->stopped_mutators_scope_depth_ -= 1;
    ASSERT(thread()->stopped_mutators_scope_depth_ >= 0);
#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(StoppedMutatorsScope);
};

// Within a EnterCompilerScope, the thread must operate on cloned fields.
#if defined(DEBUG)
class EnterCompilerScope : public ThreadStackResource {
 public:
  explicit EnterCompilerScope(Thread* thread = nullptr)
      : ThreadStackResource(thread != nullptr ? thread : Thread::Current()) {
    previously_is_inside_compiler_ = this->thread()->IsInsideCompiler();
    if (!previously_is_inside_compiler_) {
      this->thread()->EnterCompiler();
    }
  }
  ~EnterCompilerScope() {
    if (!previously_is_inside_compiler_) {
      thread()->LeaveCompiler();
    }
  }

 private:
  bool previously_is_inside_compiler_;
  DISALLOW_COPY_AND_ASSIGN(EnterCompilerScope);
};
#else   // defined(DEBUG)
class EnterCompilerScope : public ValueObject {
 public:
  explicit EnterCompilerScope(Thread* thread = nullptr) {}

 private:
  DISALLOW_COPY_AND_ASSIGN(EnterCompilerScope);
};
#endif  // defined(DEBUG)

// Within a LeaveCompilerScope, the thread must operate on cloned fields.
#if defined(DEBUG)
class LeaveCompilerScope : public ThreadStackResource {
 public:
  explicit LeaveCompilerScope(Thread* thread = nullptr)
      : ThreadStackResource(thread != nullptr ? thread : Thread::Current()) {
    previously_is_inside_compiler_ = this->thread()->IsInsideCompiler();
    if (previously_is_inside_compiler_) {
      this->thread()->LeaveCompiler();
    }
  }
  ~LeaveCompilerScope() {
    if (previously_is_inside_compiler_) {
      thread()->EnterCompiler();
    }
  }

 private:
  bool previously_is_inside_compiler_;
  DISALLOW_COPY_AND_ASSIGN(LeaveCompilerScope);
};
#else   // defined(DEBUG)
class LeaveCompilerScope : public ValueObject {
 public:
  explicit LeaveCompilerScope(Thread* thread = nullptr) {}

 private:
  DISALLOW_COPY_AND_ASSIGN(LeaveCompilerScope);
};
#endif  // defined(DEBUG)

}  // namespace dart

#endif  // RUNTIME_VM_THREAD_H_
