// 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/os_thread.h"
#include "vm/pending_deopts.h"
#include "vm/random.h"
#include "vm/runtime_entry_list.h"
#include "vm/thread_stack_resource.h"
#include "vm/thread_state.h"

namespace dart {

class AbstractType;
class ApiLocalScope;
class Array;
class CompilerState;
class CompilerTimings;
class Class;
class Code;
class Error;
class ExceptionHandlers;
class Field;
class FieldTable;
class Function;
class GrowableObjectArray;
class HandleScope;
class Heap;
class HierarchyInfo;
class Instance;
class Isolate;
class IsolateGroup;
class Library;
class Object;
class OSThread;
class JSONObject;
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 compiler {
namespace target {
class Thread;
}  // namespace target
}  // namespace compiler

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

#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, 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, 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, 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, assert_boolean_stub_, StubCode::AssertBoolean().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, exit_safepoint_ignore_unwind_in_progress_stub_,                   \
    StubCode::ExitSafepointIgnoreUnwindInProgress().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(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)

// 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)

#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(StringPtr*, predefined_symbols_address_, Symbols::PredefinedAddress(),     \
    NULL)                                                                      \
  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,
  // Number of levels.
  kNumLevels,
};

// 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*>(&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);
  }
};

// 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 EnsureInit before entering an isolate, and destroyed
// automatically when the underlying OS thread exits. NOTE: On Windows, CleanUp
// must currently be called manually (issue 23474).
class Thread : public ThreadState {
 public:
  // The kind of task this thread is performing. Sampled by the profiler.
  enum TaskKind {
    kUnknownTask = 0x0,
    kMutatorTask = 0x1,
    kCompilerTask = 0x2,
    kMarkerTask = 0x4,
    kSweeperTask = 0x8,
    kCompactorTask = 0x10,
    kScavengerTask = 0x20,
    kSampleBlockTask = 0x40,
  };
  // Converts a TaskKind to its corresponding C-String name.
  static const char* TaskKindToCString(TaskKind kind);

  ~Thread();

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

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

  // A VM thread other than the main mutator thread can enter an isolate as a
  // "helper" to gain limited concurrent access to the isolate. One example is
  // SweeperTask (which uses the class table, which is copy-on-write).
  // TODO(koda): Properly synchronize heap access to expand allowed operations.
  static bool EnterIsolateAsHelper(Isolate* isolate,
                                   TaskKind kind,
                                   bool bypass_safepoint = false);
  static void ExitIsolateAsHelper(bool bypass_safepoint = false);

  static bool EnterIsolateGroupAsHelper(IsolateGroup* isolate_group,
                                        TaskKind kind,
                                        bool bypass_safepoint);
  static void ExitIsolateGroupAsHelper(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
  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 { return heap_base_; }

  static intptr_t write_barrier_mask_offset() {
    return OFFSET_OF(Thread, write_barrier_mask_);
  }
  static intptr_t heap_base_offset() { return OFFSET_OF(Thread, heap_base_); }
  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_);
  }

  static intptr_t callback_code_offset() {
    return OFFSET_OF(Thread, ffi_callback_code_);
  }

  static intptr_t callback_stack_return_offset() {
    return OFFSET_OF(Thread, ffi_callback_stack_return_);
  }

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

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

  TaskKind task_kind() const { return task_kind_; }

  // 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();
  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 == NULL || api_reusable_scope_ == NULL);
    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_);
  }

  bool IsMutatorThread() const { return is_mutator_thread_; }

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

  bool CanCollectGarbage() const;

  // 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 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);
  static intptr_t store_buffer_block_offset() {
    return OFFSET_OF(Thread, store_buffer_block_);
  }

  bool is_marking() const { return marking_stack_block_ != NULL; }
  void MarkingStackAddObject(ObjectPtr obj);
  void DeferredMarkingStackAddObject(ObjectPtr obj);
  void MarkingStackBlockProcess();
  void DeferredMarkingStackBlockProcess();
  static intptr_t marking_stack_block_offset() {
    return OFFSET_OF(Thread, 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 of the isolate that this thread is operating on.
  Heap* heap() const { return heap_; }
  static intptr_t heap_offset() { return OFFSET_OF(Thread, heap_); }

  uword top() const { return top_; }
  uword end() const { return end_; }
  void set_top(uword top) { top_ = top; }
  void set_end(uword end) { end_ = 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

#if !defined(TARGET_ARCH_IA32)
  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;
  }
#endif

#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);

#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_int64_runtime_arg_;
  }
  void set_unboxed_int64_runtime_arg(int64_t value) {
    unboxed_int64_runtime_arg_ = value;
  }
  static intptr_t unboxed_int64_runtime_arg_offset() {
    return OFFSET_OF(Thread, unboxed_int64_runtime_arg_);
  }
  double unboxed_double_runtime_arg() const {
    return unboxed_double_runtime_arg_;
  }
  void set_unboxed_double_runtime_arg(double value) {
    unboxed_double_runtime_arg_ = value;
  }
  static intptr_t unboxed_double_runtime_arg_offset() {
    return OFFSET_OF(Thread, unboxed_double_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);
  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

  /*
   * Fields used to support safepointing a thread.
   *
   * - Bit 0 of the safepoint_state_ field is used to indicate if the thread is
   *   already at a safepoint,
   * - Bit 1 of the safepoint_state_ field is used to indicate if a safepoint
   *   is requested for this thread.
   * - Bit 2 of the safepoint_state_ field is used to indicate if the thread is
   *   already at a deopt safepoint,
   * - Bit 3 of the safepoint_state_ field is used to indicate if a deopt
   *   safepoint is requested for this thread.
   * - Bit 4 of the safepoint_state_ field is used to indicate that the thread
   *   is blocked at a (deopt)safepoint and has to be woken up once the
   *   (deopt)safepoint operation is complete.
   * - Bit 6 of the safepoint_state_ field is used to indicate that the isolate
   *   running on this thread has triggered unwind error, which requires
   *   enforced exit on a transition from native back to generated.
   *
   * The safepoint execution state (described above) for a thread is stored in
   * in the execution_state_ field.
   * 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.
   */
  static bool IsAtSafepoint(SafepointLevel level, uword state) {
    const uword mask = AtSafepointBits(level);
    return (state & mask) == mask;
  }
  bool IsAtSafepoint() const {
    return IsAtSafepoint(current_safepoint_level());
  }
  bool IsAtSafepoint(SafepointLevel level) const {
    return IsAtSafepoint(level, safepoint_state_.load());
  }
  void SetAtSafepoint(bool value) {
    ASSERT(thread_lock()->IsOwnedByCurrentThread());
    if (value) {
      safepoint_state_ |= AtSafepointBits(current_safepoint_level());
    } else {
      safepoint_state_ &= ~AtSafepointBits(current_safepoint_level());
    }
  }
  bool IsSafepointRequestedLocked() const {
    ASSERT(thread_lock()->IsOwnedByCurrentThread());
    return IsSafepointRequested();
  }
  bool IsSafepointRequested() const {
    const uword state = safepoint_state_.load();
    for (intptr_t level = current_safepoint_level(); level >= 0; --level) {
      if (IsSafepointLevelRequested(state, static_cast<SafepointLevel>(level)))
        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 (state & SafepointRequestedField::mask_in_place()) != 0;
      case SafepointLevel::kGCAndDeopt:
        return (state & DeoptSafepointRequestedField::mask_in_place()) != 0;
      default:
        UNREACHABLE();
    }
  }

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

    const uword mask = level == SafepointLevel::kGC
                           ? SafepointRequestedField::mask_in_place()
                           : DeoptSafepointRequestedField::mask_in_place();

    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_);
  }
  void SetBlockedForSafepoint(bool value) {
    ASSERT(thread_lock()->IsOwnedByCurrentThread());
    safepoint_state_ =
        BlockedForSafepointField::update(value, safepoint_state_);
  }
  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);
    }
  }

  uword safepoint_state() { return safepoint_state_; }

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

  ExecutionState execution_state() const {
    return static_cast<ExecutionState>(execution_state_);
  }
  // Normally execution state is only accessed for the current thread.
  NO_SANITIZE_THREAD
  ExecutionState execution_state_cross_thread_for_testing() 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 full_safepoint_state_unacquired() {
    return (0 << AtSafepointField::shift()) |
           (0 << AtDeoptSafepointField::shift());
  }
  static uword full_safepoint_state_acquired() {
    return (1 << AtSafepointField::shift()) |
           (1 << AtDeoptSafepointField::shift());
  }

  bool TryEnterSafepoint() {
    uword old_state = 0;
    uword new_state = AtSafepointField::encode(true);
    if (current_safepoint_level() == SafepointLevel::kGCAndDeopt) {
      new_state |= AtDeoptSafepointField::encode(true);
    }
    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 = AtSafepointField::encode(true);
    if (current_safepoint_level() == SafepointLevel::kGCAndDeopt) {
      old_state |= AtDeoptSafepointField::encode(true);
    }
    uword new_state = 0;
    return safepoint_state_.compare_exchange_strong(old_state, new_state,
                                                    std::memory_order_acquire);
  }

  void ExitSafepoint() {
    // 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();
    }
  }

  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()) {
      BlockForSafepoint();
    }
  }

  int32_t AllocateFfiCallbackId();

  // Store 'code' for the native callback identified by 'callback_id'.
  //
  // Expands the callback code array as necessary to accomodate the callback
  // ID.
  void SetFfiCallbackCode(int32_t callback_id, const Code& code);

  // Store 'stack_return' for the native callback identified by 'callback_id'.
  //
  // Expands the callback stack return array as necessary to accomodate the
  // callback ID.
  void SetFfiCallbackStackReturn(int32_t callback_id,
                                 intptr_t stack_return_delta);

  // Ensure that 'callback_id' refers to a valid callback in this isolate.
  //
  // If "entry != 0", additionally checks that entry is inside the instructions
  // of this callback.
  //
  // Aborts if any of these conditions fails.
  void VerifyCallbackIsolate(int32_t callback_id, uword entry);

  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();

  Random* random() { return &thread_random_; }
  static intptr_t random_offset() { return OFFSET_OF(Thread, thread_random_); }

  uint64_t* GetFfiMarshalledArguments(intptr_t size) {
    if (ffi_marshalled_arguments_size_ < size) {
      if (ffi_marshalled_arguments_size_ > 0) {
        free(ffi_marshalled_arguments_);
      }
      ffi_marshalled_arguments_ =
          reinterpret_cast<uint64_t*>(malloc(size * sizeof(uint64_t)));
    }
    return ffi_marshalled_arguments_;
  }

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

  PendingDeopts& pending_deopts() { return pending_deopts_; }

  SafepointLevel current_safepoint_level() const {
    return runtime_call_deopt_ability_ ==
                   RuntimeCallDeoptAbility::kCannotLazyDeopt
               ? SafepointLevel::kGC
               : SafepointLevel::kGCAndDeopt;
  }

 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_;
  uword write_barrier_mask_;
  uword heap_base_;
  Isolate* isolate_;
  const uword* dispatch_table_array_;
  uword top_ = 0;
  uword end_ = 0;
  // 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).
  uword saved_stack_limit_;
  uword stack_overflow_flags_;
  ObjectPtr* field_table_values_;
  Heap* heap_;
  uword volatile top_exit_frame_info_;
  StoreBufferBlock* store_buffer_block_;
  MarkingStackBlock* marking_stack_block_;
  MarkingStackBlock* deferred_marking_stack_block_;
  uword volatile vm_tag_;
  // 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 int64_t unboxed_int64_runtime_arg_;
  ALIGN8 double unboxed_double_runtime_arg_;

// 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

#if !defined(TARGET_ARCH_IA32)
  uword write_barrier_wrappers_entry_points_[kNumberOfDartAvailableCpuRegs];
#endif

  // JumpToExceptionHandler state:
  ObjectPtr active_exception_;
  ObjectPtr active_stacktrace_;

  ObjectPoolPtr global_object_pool_;
  uword resume_pc_;
  uword saved_shadow_call_stack_ = 0;
  uword execution_state_;
  std::atomic<uword> safepoint_state_;
  GrowableObjectArrayPtr ffi_callback_code_;
  TypedDataPtr ffi_callback_stack_return_;
  uword exit_through_ffi_ = 0;
  ApiLocalScope* api_top_scope_;
  uint8_t double_truncate_round_supported_;
  ALIGN8 Random thread_random_;

  TsanUtils* tsan_utils_ = nullptr;

  // ---- 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.

  TaskKind task_kind_;
  TimelineStream* dart_stream_;
  StreamInfo* service_extension_stream_;
  IsolateGroup* isolate_group_ = nullptr;
  mutable Monitor thread_lock_;
  ApiLocalScope* api_reusable_scope_;
  int32_t no_callback_scope_depth_;
  intptr_t no_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_;

  CompilerTimings* compiler_timings_ = nullptr;

  ErrorPtr sticky_error_;

  intptr_t ffi_marshalled_arguments_size_ = 0;
  uint64_t* ffi_marshalled_arguments_;

  ObjectPtr* field_table_values() const { return 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)

  class AtSafepointField : public BitField<uword, bool, 0, 1> {};
  class SafepointRequestedField
      : public BitField<uword, bool, AtSafepointField::kNextBit, 1> {};
  class AtDeoptSafepointField
      : public BitField<uword, bool, SafepointRequestedField::kNextBit, 1> {};
  class DeoptSafepointRequestedField
      : public BitField<uword, bool, AtDeoptSafepointField::kNextBit, 1> {};
  class BlockedForSafepointField
      : public BitField<uword,
                        bool,
                        DeoptSafepointRequestedField::kNextBit,
                        1> {};
  class BypassSafepointsField
      : public BitField<uword, bool, BlockedForSafepointField::kNextBit, 1> {};
  class UnwindErrorInProgressField
      : public BitField<uword, bool, BypassSafepointsField::kNextBit, 1> {};

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

#if defined(USING_SAFE_STACK)
  uword saved_safestack_limit_;
#endif

  Thread* next_;  // Used to chain the thread structures in an isolate.
  bool is_mutator_thread_ = false;

  bool is_unwind_in_progress_ = false;

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

  explicit Thread(bool is_vm_isolate);

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

  void MarkingStackRelease();
  void MarkingStackAcquire();
  void DeferredMarkingStackRelease();
  void DeferredMarkingStackAcquire();

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

  void FinishEntering(TaskKind kind);
  void PrepareLeaving();

  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 DisabledNoActiveIsolateScope;
  friend class InterruptChecker;
  friend class Isolate;
  friend class IsolateGroup;
  friend class NoActiveIsolateScope;
  friend class NoReloadScope;
  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
      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

// Disable thread interrupts.
class DisableThreadInterruptsScope : public StackResource {
 public:
  explicit DisableThreadInterruptsScope(Thread* thread);
  ~DisableThreadInterruptsScope();
};

// 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)

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

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

 private:
  DISALLOW_COPY_AND_ASSIGN(NoReloadScope);
};

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_
