// Copyright (c) 2013, 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_ISOLATE_H_
#define RUNTIME_VM_ISOLATE_H_

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

#include <functional>
#include <memory>
#include <utility>

#include "include/dart_api.h"
#include "platform/assert.h"
#include "platform/atomic.h"
#include "vm/base_isolate.h"
#include "vm/class_table.h"
#include "vm/dispatch_table.h"
#include "vm/exceptions.h"
#include "vm/field_table.h"
#include "vm/fixed_cache.h"
#include "vm/growable_array.h"
#include "vm/handles.h"
#include "vm/heap/verifier.h"
#include "vm/intrusive_dlist.h"
#include "vm/megamorphic_cache_table.h"
#include "vm/metrics.h"
#include "vm/os_thread.h"
#include "vm/random.h"
#include "vm/tags.h"
#include "vm/thread.h"
#include "vm/thread_pool.h"
#include "vm/thread_stack_resource.h"
#include "vm/token_position.h"
#include "vm/virtual_memory.h"

#if !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/ffi_callback_trampolines.h"
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

namespace dart {

// Forward declarations.
class ApiState;
class BackgroundCompiler;
class Become;
class Capability;
class CodeIndexTable;
class Debugger;
class DeoptContext;
class ExternalTypedData;
class GroupDebugger;
class HandleScope;
class HandleVisitor;
class Heap;
class ICData;
class IsolateObjectStore;
class IsolateProfilerData;
class ProgramReloadContext;
class ReloadHandler;
class Log;
class Message;
class MessageHandler;
class MonitorLocker;
class Mutex;
class Object;
class ObjectIdRing;
class ObjectPointerVisitor;
class ObjectStore;
class PersistentHandle;
class RwLock;
class SafepointRwLock;
class SafepointHandler;
class SampleBuffer;
class SampleBlock;
class SampleBlockBuffer;
class SendPort;
class SerializedObjectBuffer;
class ServiceIdZone;
class Simulator;
class StackResource;
class StackZone;
class StoreBuffer;
class StubCode;
class ThreadRegistry;
class UserTag;
class WeakTable;

/*
 * Possible values of null safety flag
  0 - not specified
  1 - weak mode
  2 - strong mode)
*/
constexpr int kNullSafetyOptionUnspecified = 0;
constexpr int kNullSafetyOptionWeak = 1;
constexpr int kNullSafetyOptionStrong = 2;
extern int FLAG_sound_null_safety;

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

  virtual void VisitIsolate(Isolate* isolate) = 0;

 protected:
  // Returns true if |isolate| is the VM or service isolate.
  bool IsSystemIsolate(Isolate* isolate) const;

 private:
  DISALLOW_COPY_AND_ASSIGN(IsolateVisitor);
};

class Callable : public ValueObject {
 public:
  Callable() {}
  virtual ~Callable() {}

  virtual void Call() = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(Callable);
};

template <typename T>
class LambdaCallable : public Callable {
 public:
  explicit LambdaCallable(T& lambda) : lambda_(lambda) {}
  void Call() { lambda_(); }

 private:
  T& lambda_;
  DISALLOW_COPY_AND_ASSIGN(LambdaCallable);
};

// Fixed cache for exception handler lookup.
typedef FixedCache<intptr_t, ExceptionHandlerInfo, 16> HandlerInfoCache;
// Fixed cache for catch entry state lookup.
typedef FixedCache<intptr_t, CatchEntryMovesRefPtr, 16> CatchEntryMovesCache;

// List of Isolate flags with corresponding members of Dart_IsolateFlags and
// corresponding global command line flags.
#define BOOL_ISOLATE_FLAG_LIST(V) BOOL_ISOLATE_FLAG_LIST_DEFAULT_GETTER(V)

#define BOOL_ISOLATE_GROUP_FLAG_LIST(V)                                        \
  BOOL_ISOLATE_GROUP_FLAG_LIST_DEFAULT_GETTER(V)                               \
  BOOL_ISOLATE_GROUP_FLAG_LIST_CUSTOM_GETTER(V)

// List of Isolate flags with default getters.
//
//     V(when, name, bit-name, Dart_IsolateFlags-name, command-line-flag-name)
//
#define BOOL_ISOLATE_GROUP_FLAG_LIST_DEFAULT_GETTER(V)                         \
  V(PRECOMPILER, obfuscate, Obfuscate, obfuscate, false)                       \
  V(NONPRODUCT, asserts, EnableAsserts, enable_asserts, FLAG_enable_asserts)   \
  V(NONPRODUCT, use_field_guards, UseFieldGuards, use_field_guards,            \
    FLAG_use_field_guards)                                                     \
  V(PRODUCT, should_load_vmservice_library, ShouldLoadVmService,               \
    load_vmservice_library, false)                                             \
  V(NONPRODUCT, use_osr, UseOsr, use_osr, FLAG_use_osr)                        \
  V(NONPRODUCT, snapshot_is_dontneed_safe, SnapshotIsDontNeedSafe,             \
    snapshot_is_dontneed_safe, false)                                          \
  V(NONPRODUCT, branch_coverage, BranchCoverage, branch_coverage,              \
    FLAG_branch_coverage)

#define BOOL_ISOLATE_FLAG_LIST_DEFAULT_GETTER(V)                               \
  V(PRODUCT, copy_parent_code, CopyParentCode, copy_parent_code, false)        \
  V(PRODUCT, is_system_isolate, IsSystemIsolate, is_system_isolate, false)

// List of Isolate flags with custom getters named #name().
//
//     V(when, name, bit-name, Dart_IsolateFlags-name, default_value)
//
#define BOOL_ISOLATE_GROUP_FLAG_LIST_CUSTOM_GETTER(V)                          \
  V(PRODUCT, null_safety, NullSafety, null_safety, false)

// Represents the information used for spawning the first isolate within an
// isolate group. All isolates within a group will refer to this
// [IsolateGroupSource].
class IsolateGroupSource {
 public:
  IsolateGroupSource(const char* script_uri,
                     const char* name,
                     const uint8_t* snapshot_data,
                     const uint8_t* snapshot_instructions,
                     const uint8_t* kernel_buffer,
                     intptr_t kernel_buffer_size,
                     Dart_IsolateFlags flags)
      : script_uri(script_uri == nullptr ? nullptr : Utils::StrDup(script_uri)),
        name(Utils::StrDup(name)),
        snapshot_data(snapshot_data),
        snapshot_instructions(snapshot_instructions),
        kernel_buffer(kernel_buffer),
        kernel_buffer_size(kernel_buffer_size),
        flags(flags),
        script_kernel_buffer(nullptr),
        script_kernel_size(-1),
        loaded_blobs_(nullptr),
        num_blob_loads_(0) {}
  ~IsolateGroupSource() {
    free(script_uri);
    free(name);
  }

  void add_loaded_blob(Zone* zone_,
                       const ExternalTypedData& external_typed_data);

  // The arguments used for spawning in
  // `Dart_CreateIsolateGroupFromKernel` / `Dart_CreateIsolate`.
  char* script_uri;
  char* name;
  const uint8_t* snapshot_data;
  const uint8_t* snapshot_instructions;
  const uint8_t* kernel_buffer;
  const intptr_t kernel_buffer_size;
  Dart_IsolateFlags flags;

  // The kernel buffer used in `Dart_LoadScriptFromKernel`.
  const uint8_t* script_kernel_buffer;
  intptr_t script_kernel_size;

  // List of weak pointers to external typed data for loaded blobs.
  ArrayPtr loaded_blobs_;
  intptr_t num_blob_loads_;
};

// Tracks idle time and notifies heap when idle time expired.
class IdleTimeHandler : public ValueObject {
 public:
  IdleTimeHandler() {}

  // Initializes the idle time handler with the given [heap], to which
  // idle notifications will be sent.
  void InitializeWithHeap(Heap* heap);

  // Returns whether the caller should check for idle timeouts.
  bool ShouldCheckForIdle();

  // Declares that the idle time should be reset to now.
  void UpdateStartIdleTime();

  // Returns whether idle time expired and [NotifyIdle] should be called.
  bool ShouldNotifyIdle(int64_t* expiry);

  // Notifies the heap that now is a good time to do compactions and indicates
  // we have time for the GC until [deadline].
  void NotifyIdle(int64_t deadline);

  // Calls [NotifyIdle] with the default deadline.
  void NotifyIdleUsingDefaultDeadline();

 private:
  friend class DisableIdleTimerScope;

  Mutex mutex_;
  Heap* heap_ = nullptr;
  intptr_t disabled_counter_ = 0;
  int64_t idle_start_time_ = 0;
};

// Disables firing of the idle timer while this object is alive.
class DisableIdleTimerScope : public ValueObject {
 public:
  explicit DisableIdleTimerScope(IdleTimeHandler* handler);
  ~DisableIdleTimerScope();

 private:
  IdleTimeHandler* handler_;
};

class MutatorThreadPool : public ThreadPool {
 public:
  MutatorThreadPool(IsolateGroup* isolate_group, intptr_t max_pool_size)
      : ThreadPool(max_pool_size), isolate_group_(isolate_group) {}
  virtual ~MutatorThreadPool() {}

 protected:
  virtual void OnEnterIdleLocked(MonitorLocker* ml);

 private:
  void NotifyIdle();

  IsolateGroup* isolate_group_ = nullptr;
};

// Represents an isolate group and is shared among all isolates within a group.
class IsolateGroup : public IntrusiveDListEntry<IsolateGroup> {
 public:
  IsolateGroup(std::shared_ptr<IsolateGroupSource> source,
               void* embedder_data,
               ObjectStore* object_store,
               Dart_IsolateFlags api_flags);
  IsolateGroup(std::shared_ptr<IsolateGroupSource> source,
               void* embedder_data,
               Dart_IsolateFlags api_flags);
  ~IsolateGroup();

  void RehashConstants();
#if defined(DEBUG)
  void ValidateConstants();
  void ValidateClassTable();
#endif

  IsolateGroupSource* source() const { return source_.get(); }
  std::shared_ptr<IsolateGroupSource> shareable_source() const {
    return source_;
  }
  void* embedder_data() const { return embedder_data_; }

  bool initial_spawn_successful() { return initial_spawn_successful_; }
  void set_initial_spawn_successful() { initial_spawn_successful_ = true; }

  Heap* heap() const { return heap_.get(); }

  BackgroundCompiler* background_compiler() const {
#if defined(DART_PRECOMPILED_RUNTIME)
    return nullptr;
#else
    return background_compiler_.get();
#endif
  }

#if !defined(PRODUCT)
  GroupDebugger* debugger() const { return debugger_; }
#endif

  IdleTimeHandler* idle_time_handler() { return &idle_time_handler_; }

  // Returns true if this is the first isolate registered.
  void RegisterIsolate(Isolate* isolate);
  void UnregisterIsolate(Isolate* isolate);
  // Returns `true` if this was the last isolate and the caller is responsible
  // for deleting the isolate group.
  bool UnregisterIsolateDecrementCount(Isolate* isolate);

  bool ContainsOnlyOneIsolate();

  void RunWithLockedGroup(std::function<void()> fun);

  Monitor* threads_lock() const;
  ThreadRegistry* thread_registry() const { return thread_registry_.get(); }
  SafepointHandler* safepoint_handler() { return safepoint_handler_.get(); }
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
  ReloadHandler* reload_handler() { return reload_handler_.get(); }
#endif

  void CreateHeap(bool is_vm_isolate, bool is_service_or_kernel_isolate);
  void SetupImagePage(const uint8_t* snapshot_buffer, bool is_executable);
  void Shutdown();

#define ISOLATE_METRIC_ACCESSOR(type, variable, name, unit)                    \
  type* Get##variable##Metric() { return &metric_##variable##_; }
  ISOLATE_GROUP_METRIC_LIST(ISOLATE_METRIC_ACCESSOR);
#undef ISOLATE_METRIC_ACCESSOR

#if !defined(PRODUCT)
  void UpdateLastAllocationProfileAccumulatorResetTimestamp() {
    last_allocationprofile_accumulator_reset_timestamp_ =
        OS::GetCurrentTimeMillis();
  }

  int64_t last_allocationprofile_accumulator_reset_timestamp() const {
    return last_allocationprofile_accumulator_reset_timestamp_;
  }

  void UpdateLastAllocationProfileGCTimestamp() {
    last_allocationprofile_gc_timestamp_ = OS::GetCurrentTimeMillis();
  }

  int64_t last_allocationprofile_gc_timestamp() const {
    return last_allocationprofile_gc_timestamp_;
  }
#endif  // !defined(PRODUCT)

  DispatchTable* dispatch_table() const { return dispatch_table_.get(); }
  void set_dispatch_table(DispatchTable* table) {
    dispatch_table_.reset(table);
  }
  const uint8_t* dispatch_table_snapshot() const {
    return dispatch_table_snapshot_;
  }
  void set_dispatch_table_snapshot(const uint8_t* snapshot) {
    dispatch_table_snapshot_ = snapshot;
  }
  intptr_t dispatch_table_snapshot_size() const {
    return dispatch_table_snapshot_size_;
  }
  void set_dispatch_table_snapshot_size(intptr_t size) {
    dispatch_table_snapshot_size_ = size;
  }

  SharedClassTable* shared_class_table() const {
    return shared_class_table_.get();
  }

  static intptr_t shared_class_table_offset() {
    COMPILE_ASSERT(sizeof(IsolateGroup::shared_class_table_) == kWordSize);
    return OFFSET_OF(IsolateGroup, shared_class_table_);
  }

  ClassPtr* cached_class_table_table() {
    return cached_class_table_table_.load();
  }
  void set_cached_class_table_table(ClassPtr* cached_class_table_table) {
    cached_class_table_table_.store(cached_class_table_table);
  }
  static intptr_t cached_class_table_table_offset() {
    COMPILE_ASSERT(sizeof(IsolateGroup::cached_class_table_table_) ==
                   kWordSize);
    return OFFSET_OF(IsolateGroup, cached_class_table_table_);
  }

  void set_object_store(ObjectStore* object_store);
  static intptr_t object_store_offset() {
    COMPILE_ASSERT(sizeof(IsolateGroup::object_store_) == kWordSize);
    return OFFSET_OF(IsolateGroup, object_store_);
  }

  void set_obfuscation_map(const char** map) { obfuscation_map_ = map; }
  const char** obfuscation_map() const { return obfuscation_map_; }

  Random* random() { return &random_; }

  bool is_system_isolate_group() const { return is_system_isolate_group_; }

  // IsolateGroup-specific flag handling.
  static void FlagsInitialize(Dart_IsolateFlags* api_flags);
  void FlagsCopyTo(Dart_IsolateFlags* api_flags);
  void FlagsCopyFrom(const Dart_IsolateFlags& api_flags);

#if defined(DART_PRECOMPILER)
#define FLAG_FOR_PRECOMPILER(from_field, from_flag) (from_field)
#else
#define FLAG_FOR_PRECOMPILER(from_field, from_flag) (from_flag)
#endif

#if !defined(PRODUCT)
#define FLAG_FOR_NONPRODUCT(from_field, from_flag) (from_field)
#else
#define FLAG_FOR_NONPRODUCT(from_field, from_flag) (from_flag)
#endif

#define FLAG_FOR_PRODUCT(from_field, from_flag) (from_field)

#define DECLARE_GETTER(when, name, bitname, isolate_flag_name, flag_name)      \
  bool name() const {                                                          \
    return FLAG_FOR_##when(bitname##Bit::decode(isolate_group_flags_),         \
                           flag_name);                                         \
  }
  BOOL_ISOLATE_GROUP_FLAG_LIST_DEFAULT_GETTER(DECLARE_GETTER)
#undef FLAG_FOR_NONPRODUCT
#undef FLAG_FOR_PRECOMPILER
#undef FLAG_FOR_PRODUCT
#undef DECLARE_GETTER

  bool null_safety_not_set() const {
    return !NullSafetySetBit::decode(isolate_group_flags_);
  }

  bool null_safety() const {
    ASSERT(!null_safety_not_set());
    return NullSafetyBit::decode(isolate_group_flags_);
  }

  void set_null_safety(bool null_safety) {
    isolate_group_flags_ = NullSafetySetBit::update(true, isolate_group_flags_);
    isolate_group_flags_ =
        NullSafetyBit::update(null_safety, isolate_group_flags_);
  }

  bool use_strict_null_safety_checks() const {
    return null_safety() || FLAG_strict_null_safety_checks;
  }

  bool should_load_vmservice() const {
    return ShouldLoadVmServiceBit::decode(isolate_group_flags_);
  }
  void set_should_load_vmservice(bool value) {
    isolate_group_flags_ =
        ShouldLoadVmServiceBit::update(value, isolate_group_flags_);
  }

  void set_asserts(bool value) {
    isolate_group_flags_ =
        EnableAssertsBit::update(value, isolate_group_flags_);
  }

  void set_branch_coverage(bool value) {
    isolate_group_flags_ =
        BranchCoverageBit::update(value, isolate_group_flags_);
  }

#if !defined(PRODUCT)
#if !defined(DART_PRECOMPILED_RUNTIME)
  bool HasAttemptedReload() const {
    return HasAttemptedReloadBit::decode(isolate_group_flags_);
  }
  void SetHasAttemptedReload(bool value) {
    isolate_group_flags_ =
        HasAttemptedReloadBit::update(value, isolate_group_flags_);
  }
  void MaybeIncreaseReloadEveryNStackOverflowChecks();
  intptr_t reload_every_n_stack_overflow_checks() const {
    return reload_every_n_stack_overflow_checks_;
  }
#else
  bool HasAttemptedReload() const { return false; }
#endif  // !defined(DART_PRECOMPILED_RUNTIME)
#endif  // !defined(PRODUCT)

#if defined(PRODUCT)
  void set_use_osr(bool use_osr) { ASSERT(!use_osr); }
#else   // defined(PRODUCT)
  void set_use_osr(bool use_osr) {
    isolate_group_flags_ = UseOsrBit::update(use_osr, isolate_group_flags_);
  }
#endif  // defined(PRODUCT)

  StoreBuffer* store_buffer() const { return store_buffer_.get(); }
  ClassTable* class_table() const { return class_table_.get(); }
  ObjectStore* object_store() const { return object_store_.get(); }
  Mutex* symbols_mutex() { return &symbols_mutex_; }
  Mutex* type_canonicalization_mutex() { return &type_canonicalization_mutex_; }
  Mutex* type_arguments_canonicalization_mutex() {
    return &type_arguments_canonicalization_mutex_;
  }
  Mutex* subtype_test_cache_mutex() { return &subtype_test_cache_mutex_; }
  Mutex* megamorphic_table_mutex() { return &megamorphic_table_mutex_; }
  Mutex* type_feedback_mutex() { return &type_feedback_mutex_; }
  Mutex* patchable_call_mutex() { return &patchable_call_mutex_; }
  Mutex* constant_canonicalization_mutex() {
    return &constant_canonicalization_mutex_;
  }
  Mutex* kernel_data_lib_cache_mutex() { return &kernel_data_lib_cache_mutex_; }
  Mutex* kernel_data_class_cache_mutex() {
    return &kernel_data_class_cache_mutex_;
  }
  Mutex* kernel_constants_mutex() { return &kernel_constants_mutex_; }

#if defined(DART_PRECOMPILED_RUNTIME)
  Mutex* unlinked_call_map_mutex() { return &unlinked_call_map_mutex_; }
#endif

#if !defined(DART_PRECOMPILED_RUNTIME)
  Mutex* initializer_functions_mutex() { return &initializer_functions_mutex_; }
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

  SafepointRwLock* program_lock() { return program_lock_.get(); }

  static inline IsolateGroup* Current() {
    Thread* thread = Thread::Current();
    return thread == nullptr ? nullptr : thread->isolate_group();
  }

  Thread* ScheduleThreadLocked(MonitorLocker* ml,
                               Thread* existing_mutator_thread,
                               bool is_vm_isolate,
                               bool is_mutator,
                               bool bypass_safepoint = false);
  void UnscheduleThreadLocked(MonitorLocker* ml,
                              Thread* thread,
                              bool is_mutator,
                              bool bypass_safepoint = false);

  Thread* ScheduleThread(bool bypass_safepoint = false);
  void UnscheduleThread(Thread* thread,
                        bool is_mutator,
                        bool bypass_safepoint = false);

  void IncreaseMutatorCount(Isolate* mutator, bool is_nested_reenter);
  void DecreaseMutatorCount(Isolate* mutator, bool is_nested_exit);
  intptr_t MutatorCount() const {
    MonitorLocker ml(active_mutators_monitor_.get());
    return active_mutators_;
  }

  bool HasTagHandler() const { return library_tag_handler() != nullptr; }
  ObjectPtr CallTagHandler(Dart_LibraryTag tag,
                           const Object& arg1,
                           const Object& arg2);
  Dart_LibraryTagHandler library_tag_handler() const {
    return library_tag_handler_;
  }
  void set_library_tag_handler(Dart_LibraryTagHandler handler) {
    library_tag_handler_ = handler;
  }
  Dart_DeferredLoadHandler deferred_load_handler() const {
    return deferred_load_handler_;
  }
  void set_deferred_load_handler(Dart_DeferredLoadHandler handler) {
    deferred_load_handler_ = handler;
  }

  intptr_t GetClassSizeForHeapWalkAt(intptr_t cid);

  // Prepares all threads in an isolate for Garbage Collection.
  void ReleaseStoreBuffers();
  void EnableIncrementalBarrier(MarkingStack* marking_stack,
                                MarkingStack* deferred_marking_stack);
  void DisableIncrementalBarrier();

  MarkingStack* marking_stack() const { return marking_stack_; }
  MarkingStack* deferred_marking_stack() const {
    return deferred_marking_stack_;
  }

  // Runs the given [function] on every isolate in the isolate group.
  //
  // During the duration of this function, no new isolates can be added or
  // removed.
  //
  // If [at_safepoint] is `true`, then the entire isolate group must be in a
  // safepoint. There is therefore no reason to guard against other threads
  // adding/removing isolates, so no locks will be held.
  void ForEachIsolate(std::function<void(Isolate* isolate)> function,
                      bool at_safepoint = false);
  Isolate* FirstIsolate() const;
  Isolate* FirstIsolateLocked() const;

  // Ensures mutators are stopped during execution of the provided function.
  //
  // If the current thread is the only mutator in the isolate group,
  // [single_current_mutator] will be called. Otherwise [otherwise] will be
  // called inside a [SafepointOperationsScope] (or
  // [ForceGrowthSafepointOperationScope] if [use_force_growth_in_otherwise]
  // is set).
  //
  // During the duration of this function, no new isolates can be added to the
  // isolate group.
  void RunWithStoppedMutatorsCallable(
      Callable* single_current_mutator,
      Callable* otherwise,
      bool use_force_growth_in_otherwise = false);

  template <typename T, typename S>
  void RunWithStoppedMutators(T single_current_mutator,
                              S otherwise,
                              bool use_force_growth_in_otherwise = false) {
    LambdaCallable<T> single_callable(single_current_mutator);
    LambdaCallable<S> otherwise_callable(otherwise);
    RunWithStoppedMutatorsCallable(&single_callable, &otherwise_callable,
                                   use_force_growth_in_otherwise);
  }

  template <typename T>
  void RunWithStoppedMutators(T function, bool use_force_growth = false) {
    LambdaCallable<T> callable(function);
    RunWithStoppedMutatorsCallable(&callable, &callable, use_force_growth);
  }

#ifndef PRODUCT
  void PrintJSON(JSONStream* stream, bool ref = true);
  void PrintToJSONObject(JSONObject* jsobj, bool ref);

  // Creates an object with the total heap memory usage statistics for this
  // isolate group.
  void PrintMemoryUsageJSON(JSONStream* stream);
#endif

#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
  // By default the reload context is deleted. This parameter allows
  // the caller to delete is separately if it is still needed.
  bool ReloadSources(JSONStream* js,
                     bool force_reload,
                     const char* root_script_url = nullptr,
                     const char* packages_url = nullptr,
                     bool dont_delete_reload_context = false);

  // If provided, the VM takes ownership of kernel_buffer.
  bool ReloadKernel(JSONStream* js,
                    bool force_reload,
                    const uint8_t* kernel_buffer = nullptr,
                    intptr_t kernel_buffer_size = 0,
                    bool dont_delete_reload_context = false);

  void set_last_reload_timestamp(int64_t value) {
    last_reload_timestamp_ = value;
  }
  int64_t last_reload_timestamp() const { return last_reload_timestamp_; }

  IsolateGroupReloadContext* reload_context() {
    return group_reload_context_.get();
  }
  ProgramReloadContext* program_reload_context() {
    return program_reload_context_;
  }

  void DeleteReloadContext();
  bool CanReload();
#else
  bool CanReload() { return false; }
#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)

  // Prefers old classes when we are in the middle of a reload.
  ClassPtr GetClassForHeapWalkAt(intptr_t cid);

  bool IsReloading() const {
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
    return group_reload_context_ != nullptr;
#else
    return false;
#endif
  }

  Become* become() const { return become_; }
  void set_become(Become* become) { become_ = become; }

  uint64_t id() const { return id_; }

  static void Init();
  static void Cleanup();

  static void ForEach(std::function<void(IsolateGroup*)> action);
  static void RunWithIsolateGroup(uint64_t id,
                                  std::function<void(IsolateGroup*)> action,
                                  std::function<void()> not_found);

  // Manage list of existing isolate groups.
  static void RegisterIsolateGroup(IsolateGroup* isolate_group);
  static void UnregisterIsolateGroup(IsolateGroup* isolate_group);

  static bool HasApplicationIsolateGroups();
  static bool HasOnlyVMIsolateGroup();
  static bool IsSystemIsolateGroup(const IsolateGroup* group);

  int64_t UptimeMicros() const;

  ApiState* api_state() const { return api_state_.get(); }

  // Visit all object pointers. Caller must ensure concurrent sweeper is not
  // running, and the visitor must not allocate.
  void VisitObjectPointers(ObjectPointerVisitor* visitor,
                           ValidationPolicy validate_frames);
  void VisitSharedPointers(ObjectPointerVisitor* visitor);
  void VisitStackPointers(ObjectPointerVisitor* visitor,
                          ValidationPolicy validate_frames);
  void VisitObjectIdRingPointers(ObjectPointerVisitor* visitor);
  void VisitWeakPersistentHandles(HandleVisitor* visitor);

  bool compaction_in_progress() const {
    return CompactionInProgressBit::decode(isolate_group_flags_);
  }
  void set_compaction_in_progress(bool value) {
    isolate_group_flags_ =
        CompactionInProgressBit::update(value, isolate_group_flags_);
  }

  // In precompilation we finalize all regular classes before compiling.
  bool all_classes_finalized() const {
    return AllClassesFinalizedBit::decode(isolate_group_flags_);
  }
  void set_all_classes_finalized(bool value) {
    isolate_group_flags_ =
        AllClassesFinalizedBit::update(value, isolate_group_flags_);
  }

  bool remapping_cids() const {
    return RemappingCidsBit::decode(isolate_group_flags_);
  }
  void set_remapping_cids(bool value) {
    isolate_group_flags_ =
        RemappingCidsBit::update(value, isolate_group_flags_);
  }

  void RememberLiveTemporaries();
  void DeferredMarkLiveTemporaries();

  ArrayPtr saved_unlinked_calls() const { return saved_unlinked_calls_; }
  void set_saved_unlinked_calls(const Array& saved_unlinked_calls);

  FieldTable* initial_field_table() const { return initial_field_table_.get(); }
  std::shared_ptr<FieldTable> initial_field_table_shareable() {
    return initial_field_table_;
  }
  void set_initial_field_table(std::shared_ptr<FieldTable> field_table) {
    initial_field_table_ = field_table;
  }

  MutatorThreadPool* thread_pool() { return thread_pool_.get(); }

  void RegisterClass(const Class& cls);
  void RegisterStaticField(const Field& field, const Object& initial_value);
  void FreeStaticField(const Field& field);

 private:
  friend class Dart;  // For `object_store_ = ` in Dart::Init
  friend class Heap;
  friend class StackFrame;  // For `[isolates_].First()`.
  // For `object_store_shared_untag()`, `class_table_shared_untag()`
  friend class Isolate;

#define ISOLATE_GROUP_FLAG_BITS(V)                                             \
  V(AllClassesFinalized)                                                       \
  V(CompactionInProgress)                                                      \
  V(EnableAsserts)                                                             \
  V(HasAttemptedReload)                                                        \
  V(NullSafety)                                                                \
  V(RemappingCids)                                                             \
  V(ShouldLoadVmService)                                                       \
  V(NullSafetySet)                                                             \
  V(Obfuscate)                                                                 \
  V(UseFieldGuards)                                                            \
  V(UseOsr)                                                                    \
  V(SnapshotIsDontNeedSafe)                                                    \
  V(BranchCoverage)

  // Isolate group specific flags.
  enum FlagBits {
#define DECLARE_BIT(Name) k##Name##Bit,
    ISOLATE_GROUP_FLAG_BITS(DECLARE_BIT)
#undef DECLARE_BIT
  };

#define DECLARE_BITFIELD(Name)                                                 \
  class Name##Bit : public BitField<uint32_t, bool, k##Name##Bit, 1> {};
  ISOLATE_GROUP_FLAG_BITS(DECLARE_BITFIELD)
#undef DECLARE_BITFIELD

  void set_heap(std::unique_ptr<Heap> value);

  // Accessed from generated code.
  std::unique_ptr<SharedClassTable> shared_class_table_;
  std::unique_ptr<ClassTable> class_table_;
  AcqRelAtomic<ClassPtr*> cached_class_table_table_;
  std::unique_ptr<ObjectStore> object_store_;
  // End accessed from generated code.

  const char** obfuscation_map_ = nullptr;

  bool is_vm_isolate_heap_ = false;
  void* embedder_data_ = nullptr;

  IdleTimeHandler idle_time_handler_;
  std::unique_ptr<MutatorThreadPool> thread_pool_;
  std::unique_ptr<SafepointRwLock> isolates_lock_;
  IntrusiveDList<Isolate> isolates_;
  intptr_t isolate_count_ = 0;
  bool initial_spawn_successful_ = false;
  Dart_LibraryTagHandler library_tag_handler_ = nullptr;
  Dart_DeferredLoadHandler deferred_load_handler_ = nullptr;
  int64_t start_time_micros_;
  bool is_system_isolate_group_;
  Random random_;

#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
  int64_t last_reload_timestamp_;
  std::shared_ptr<IsolateGroupReloadContext> group_reload_context_;
  // Per-isolate-group copy of FLAG_reload_every.
  RelaxedAtomic<intptr_t> reload_every_n_stack_overflow_checks_;
  ProgramReloadContext* program_reload_context_ = nullptr;
#endif
  Become* become_ = nullptr;

#define ISOLATE_METRIC_VARIABLE(type, variable, name, unit)                    \
  type metric_##variable##_;
  ISOLATE_GROUP_METRIC_LIST(ISOLATE_METRIC_VARIABLE);
#undef ISOLATE_METRIC_VARIABLE

#if !defined(PRODUCT)
  // Timestamps of last operation via service.
  int64_t last_allocationprofile_accumulator_reset_timestamp_ = 0;
  int64_t last_allocationprofile_gc_timestamp_ = 0;

#endif  // !defined(PRODUCT)

  MarkingStack* marking_stack_ = nullptr;
  MarkingStack* deferred_marking_stack_ = nullptr;
  std::shared_ptr<IsolateGroupSource> source_;
  std::unique_ptr<ApiState> api_state_;
  std::unique_ptr<ThreadRegistry> thread_registry_;
  std::unique_ptr<SafepointHandler> safepoint_handler_;

  NOT_IN_PRODUCT(
      NOT_IN_PRECOMPILED(std::unique_ptr<ReloadHandler> reload_handler_));

  static RwLock* isolate_groups_rwlock_;
  static IntrusiveDList<IsolateGroup>* isolate_groups_;
  static Random* isolate_group_random_;

  uint64_t id_ = 0;

  std::unique_ptr<StoreBuffer> store_buffer_;
  std::unique_ptr<Heap> heap_;
  std::unique_ptr<DispatchTable> dispatch_table_;
  const uint8_t* dispatch_table_snapshot_ = nullptr;
  intptr_t dispatch_table_snapshot_size_ = 0;
  ArrayPtr saved_unlinked_calls_;
  std::shared_ptr<FieldTable> initial_field_table_;
  uint32_t isolate_group_flags_ = 0;

  NOT_IN_PRECOMPILED(std::unique_ptr<BackgroundCompiler> background_compiler_);

  Mutex symbols_mutex_;
  Mutex type_canonicalization_mutex_;
  Mutex type_arguments_canonicalization_mutex_;
  Mutex subtype_test_cache_mutex_;
  Mutex megamorphic_table_mutex_;
  Mutex type_feedback_mutex_;
  Mutex patchable_call_mutex_;
  Mutex constant_canonicalization_mutex_;
  Mutex kernel_data_lib_cache_mutex_;
  Mutex kernel_data_class_cache_mutex_;
  Mutex kernel_constants_mutex_;

#if defined(DART_PRECOMPILED_RUNTIME)
  Mutex unlinked_call_map_mutex_;
#endif

#if !defined(DART_PRECOMPILED_RUNTIME)
  Mutex initializer_functions_mutex_;
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

  // Protect access to boxed_field_list_.
  Mutex field_list_mutex_;
  // List of fields that became boxed and that trigger deoptimization.
  GrowableObjectArrayPtr boxed_field_list_;

  // Ensures synchronized access to classes functions, fields and other
  // program structure elements to accommodate concurrent modification done
  // by multiple isolates and background compiler.
  std::unique_ptr<SafepointRwLock> program_lock_;

  // Allow us to ensure the number of active mutators is limited by a maximum.
  std::unique_ptr<Monitor> active_mutators_monitor_;
  intptr_t active_mutators_ = 0;
  intptr_t waiting_mutators_ = 0;
  intptr_t max_active_mutators_ = 0;

  NOT_IN_PRODUCT(GroupDebugger* debugger_ = nullptr);
};

// When an isolate sends-and-exits this class represent things that it passed
// to the beneficiary.
class Bequest {
 public:
  Bequest(PersistentHandle* handle, Dart_Port beneficiary)
      : handle_(handle), beneficiary_(beneficiary) {}
  ~Bequest();

  PersistentHandle* handle() { return handle_; }
  PersistentHandle* TakeHandle() {
    auto handle = handle_;
    handle_ = nullptr;
    return handle;
  }
  Dart_Port beneficiary() { return beneficiary_; }

 private:
  PersistentHandle* handle_;
  Dart_Port beneficiary_;
};

class Isolate : public BaseIsolate, public IntrusiveDListEntry<Isolate> {
 public:
  // Keep both these enums in sync with isolate_patch.dart.
  // The different Isolate API message types.
  enum LibMsgId {
    kPauseMsg = 1,
    kResumeMsg = 2,
    kPingMsg = 3,
    kKillMsg = 4,
    kAddExitMsg = 5,
    kDelExitMsg = 6,
    kAddErrorMsg = 7,
    kDelErrorMsg = 8,
    kErrorFatalMsg = 9,

    // Internal message ids.
    kInterruptMsg = 10,     // Break in the debugger.
    kInternalKillMsg = 11,  // Like kill, but does not run exit listeners, etc.
    kDrainServiceExtensionsMsg = 12,  // Invoke pending service extensions
    kCheckForReload = 13,  // Participate in other isolate group reload.
  };
  // The different Isolate API message priorities for ping and kill messages.
  enum LibMsgPriority {
    kImmediateAction = 0,
    kBeforeNextEventAction = 1,
    kAsEventAction = 2
  };

  ~Isolate();

  static inline Isolate* Current() {
    Thread* thread = Thread::Current();
    return thread == nullptr ? nullptr : thread->isolate();
  }

  bool IsScheduled() { return scheduled_mutator_thread() != nullptr; }
  Thread* scheduled_mutator_thread() const { return scheduled_mutator_thread_; }

  ThreadRegistry* thread_registry() const { return group()->thread_registry(); }

  SafepointHandler* safepoint_handler() const {
    return group()->safepoint_handler();
  }

  FieldTable* field_table() const { return field_table_; }
  void set_field_table(Thread* T, FieldTable* field_table) {
    delete field_table_;
    field_table_ = field_table;
    T->field_table_values_ = field_table->table();
  }

  IsolateObjectStore* isolate_object_store() const {
    return isolate_object_store_.get();
  }

  static intptr_t ic_miss_code_offset() {
    return OFFSET_OF(Isolate, ic_miss_code_);
  }

  Dart_MessageNotifyCallback message_notify_callback() const {
    return message_notify_callback_.load(std::memory_order_relaxed);
  }

  void set_message_notify_callback(Dart_MessageNotifyCallback value) {
    message_notify_callback_.store(value, std::memory_order_release);
  }

  void set_on_shutdown_callback(Dart_IsolateShutdownCallback value) {
    on_shutdown_callback_ = value;
  }
  Dart_IsolateShutdownCallback on_shutdown_callback() {
    return on_shutdown_callback_;
  }
  void set_on_cleanup_callback(Dart_IsolateCleanupCallback value) {
    on_cleanup_callback_ = value;
  }
  Dart_IsolateCleanupCallback on_cleanup_callback() {
    return on_cleanup_callback_;
  }

  void bequeath(std::unique_ptr<Bequest> bequest) {
    bequest_ = std::move(bequest);
  }

  IsolateGroupSource* source() const { return isolate_group_->source(); }
  IsolateGroup* group() const { return isolate_group_; }

  bool HasPendingMessages();

  Thread* mutator_thread() const;

  const char* name() const { return name_; }
  void set_name(const char* name);

  int64_t UptimeMicros() const;

  Dart_Port main_port() const { return main_port_; }
  void set_main_port(Dart_Port port) {
    ASSERT(main_port_ == 0);  // Only set main port once.
    main_port_ = port;
  }
  Dart_Port origin_id();
  void set_origin_id(Dart_Port id);
  void set_pause_capability(uint64_t value) { pause_capability_ = value; }
  uint64_t pause_capability() const { return pause_capability_; }
  void set_terminate_capability(uint64_t value) {
    terminate_capability_ = value;
  }
  uint64_t terminate_capability() const { return terminate_capability_; }

  void SendInternalLibMessage(LibMsgId msg_id, uint64_t capability);

  void set_init_callback_data(void* value) { init_callback_data_ = value; }
  void* init_callback_data() const { return init_callback_data_; }

  void set_finalizers(const GrowableObjectArray& value);
  static intptr_t finalizers_offset() {
    return OFFSET_OF(Isolate, finalizers_);
  }

#if !defined(DART_PRECOMPILED_RUNTIME)
  NativeCallbackTrampolines* native_callback_trampolines() {
    return &native_callback_trampolines_;
  }
#endif

  Dart_EnvironmentCallback environment_callback() const {
    return environment_callback_;
  }
  void set_environment_callback(Dart_EnvironmentCallback value) {
    environment_callback_ = value;
  }

  bool HasDeferredLoadHandler() const {
    return group()->deferred_load_handler() != nullptr;
  }
  ObjectPtr CallDeferredLoadHandler(intptr_t id);

  void ScheduleInterrupts(uword interrupt_bits);

  const char* MakeRunnable();
  void MakeRunnableLocked();
  void Run();

  MessageHandler* message_handler() const { return message_handler_; }
  void set_message_handler(MessageHandler* value) { message_handler_ = value; }

  bool is_runnable() const { return LoadIsolateFlagsBit<IsRunnableBit>(); }
  void set_is_runnable(bool value) {
    UpdateIsolateFlagsBit<IsRunnableBit>(value);
#if !defined(PRODUCT)
    if (is_runnable()) {
      set_last_resume_timestamp();
    }
#endif
  }

  Mutex* mutex() { return &mutex_; }

#if !defined(PRODUCT)
  Debugger* debugger() const { return debugger_; }

  // NOTE: this lock should only be acquired within the profiler signal handler.
  Mutex* current_sample_block_lock() const {
    return const_cast<Mutex*>(&current_sample_block_lock_);
  }

  // Returns the current SampleBlock used to track CPU profiling samples.
  //
  // NOTE: current_sample_block_lock() should be held when accessing this
  // block.
  SampleBlock* current_sample_block() const { return current_sample_block_; }
  void set_current_sample_block(SampleBlock* current);

  void FreeSampleBlock(SampleBlock* block);
  void ProcessFreeSampleBlocks(Thread* thread);
  bool should_process_blocks() const {
    return free_block_list_.load(std::memory_order_relaxed) != nullptr;
  }
  std::atomic<SampleBlock*> free_block_list_ = nullptr;

  // Returns the current SampleBlock used to track Dart allocation samples.
  //
  // Allocations should only occur on the mutator thread for an isolate, so we
  // don't need to worry about grabbing a lock while accessing this block.
  SampleBlock* current_allocation_sample_block() const {
    return current_allocation_sample_block_;
  }
  void set_current_allocation_sample_block(SampleBlock* current);

  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(Isolate, single_step_);
  }

  void set_has_resumption_breakpoints(bool value) {
    has_resumption_breakpoints_ = value;
  }
  bool has_resumption_breakpoints() const {
    return has_resumption_breakpoints_;
  }
  static intptr_t has_resumption_breakpoints_offset() {
    return OFFSET_OF(Isolate, has_resumption_breakpoints_);
  }

  bool ResumeRequest() const { return LoadIsolateFlagsBit<ResumeRequestBit>(); }
  // Lets the embedder know that a service message resulted in a resume request.
  void SetResumeRequest() {
    UpdateIsolateFlagsBit<ResumeRequestBit>(true);
    set_last_resume_timestamp();
  }

  void set_last_resume_timestamp() {
    last_resume_timestamp_ = OS::GetCurrentTimeMillis();
  }

  int64_t last_resume_timestamp() const { return last_resume_timestamp_; }

  // Returns whether the vm service has requested that the debugger
  // resume execution.
  bool GetAndClearResumeRequest() {
    return UpdateIsolateFlagsBit<ResumeRequestBit>(false);
  }
#endif

  // Verify that the sender has the capability to pause or terminate the
  // isolate.
  bool VerifyPauseCapability(const Object& capability) const;
  bool VerifyTerminateCapability(const Object& capability) const;

  // Returns true if the capability was added or removed from this isolate's
  // list of pause events.
  bool AddResumeCapability(const Capability& capability);
  bool RemoveResumeCapability(const Capability& capability);

  void AddExitListener(const SendPort& listener, const Instance& response);
  void RemoveExitListener(const SendPort& listener);
  void NotifyExitListeners();

  void AddErrorListener(const SendPort& listener);
  void RemoveErrorListener(const SendPort& listener);
  bool NotifyErrorListeners(const char* msg, const char* stacktrace);

  bool ErrorsFatal() const { return LoadIsolateFlagsBit<ErrorsFatalBit>(); }
  void SetErrorsFatal(bool value) {
    UpdateIsolateFlagsBit<ErrorsFatalBit>(value);
  }

  Random* random() { return &random_; }

  Simulator* simulator() const { return simulator_; }
  void set_simulator(Simulator* value) { simulator_ = value; }

  void IncrementSpawnCount();
  void DecrementSpawnCount();
  void WaitForOutstandingSpawns();

  static void SetCreateGroupCallback(Dart_IsolateGroupCreateCallback cb) {
    create_group_callback_ = cb;
  }
  static Dart_IsolateGroupCreateCallback CreateGroupCallback() {
    return create_group_callback_;
  }

  static void SetInitializeCallback_(Dart_InitializeIsolateCallback cb) {
    initialize_callback_ = cb;
  }
  static Dart_InitializeIsolateCallback InitializeCallback() {
    return initialize_callback_;
  }

  static void SetShutdownCallback(Dart_IsolateShutdownCallback cb) {
    shutdown_callback_ = cb;
  }
  static Dart_IsolateShutdownCallback ShutdownCallback() {
    return shutdown_callback_;
  }

  static void SetCleanupCallback(Dart_IsolateCleanupCallback cb) {
    cleanup_callback_ = cb;
  }
  static Dart_IsolateCleanupCallback CleanupCallback() {
    return cleanup_callback_;
  }

  static void SetGroupCleanupCallback(Dart_IsolateGroupCleanupCallback cb) {
    cleanup_group_callback_ = cb;
  }
  static Dart_IsolateGroupCleanupCallback GroupCleanupCallback() {
    return cleanup_group_callback_;
  }
  static void SetRegisterKernelBlobCallback(
      Dart_RegisterKernelBlobCallback cb) {
    register_kernel_blob_callback_ = cb;
  }
  static Dart_RegisterKernelBlobCallback RegisterKernelBlobCallback() {
    return register_kernel_blob_callback_;
  }
  static void SetUnregisterKernelBlobCallback(
      Dart_UnregisterKernelBlobCallback cb) {
    unregister_kernel_blob_callback_ = cb;
  }
  static Dart_UnregisterKernelBlobCallback UnregisterKernelBlobCallback() {
    return unregister_kernel_blob_callback_;
  }

#if !defined(PRODUCT)
  ObjectIdRing* object_id_ring() const { return object_id_ring_; }
  ObjectIdRing* EnsureObjectIdRing();
#endif  // !defined(PRODUCT)

  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;
  }

  intptr_t BlockClassFinalization() {
    ASSERT(defer_finalization_count_ >= 0);
    return defer_finalization_count_++;
  }

  intptr_t UnblockClassFinalization() {
    ASSERT(defer_finalization_count_ > 0);
    return defer_finalization_count_--;
  }

  bool AllowClassFinalization() {
    ASSERT(defer_finalization_count_ >= 0);
    return defer_finalization_count_ == 0;
  }

#ifndef PRODUCT
  void PrintJSON(JSONStream* stream, bool ref = true);

  // Creates an object with the total heap memory usage statistics for this
  // isolate.
  void PrintMemoryUsageJSON(JSONStream* stream);
#endif

#if !defined(PRODUCT)
  VMTagCounters* vm_tag_counters() { return &vm_tag_counters_; }
#endif  // !defined(PRODUCT)

  bool IsPaused() const;

#if !defined(PRODUCT)
  bool should_pause_post_service_request() const {
    return LoadIsolateFlagsBit<ShouldPausePostServiceRequestBit>();
  }
  void set_should_pause_post_service_request(bool value) {
    UpdateIsolateFlagsBit<ShouldPausePostServiceRequestBit>(value);
  }
#endif  // !defined(PRODUCT)

  ErrorPtr PausePostRequest();

  uword user_tag() const { return user_tag_; }
  static intptr_t user_tag_offset() { return OFFSET_OF(Isolate, user_tag_); }
  static intptr_t current_tag_offset() {
    return OFFSET_OF(Isolate, current_tag_);
  }
  static intptr_t default_tag_offset() {
    return OFFSET_OF(Isolate, default_tag_);
  }

#if !defined(PRODUCT)
#define ISOLATE_METRIC_ACCESSOR(type, variable, name, unit)                    \
  type* Get##variable##Metric() { return &metric_##variable##_; }
  ISOLATE_METRIC_LIST(ISOLATE_METRIC_ACCESSOR);
#undef ISOLATE_METRIC_ACCESSOR
#endif  // !defined(PRODUCT)

  static intptr_t IsolateListLength();

  GrowableObjectArrayPtr tag_table() const { return tag_table_; }
  void set_tag_table(const GrowableObjectArray& value);

  UserTagPtr current_tag() const { return current_tag_; }
  void set_current_tag(const UserTag& tag);

  UserTagPtr default_tag() const { return default_tag_; }
  void set_default_tag(const UserTag& tag);

  void set_ic_miss_code(const Code& code);

  // Also sends a paused at exit event over the service protocol.
  void SetStickyError(ErrorPtr sticky_error);

  ErrorPtr sticky_error() const { return sticky_error_; }
  DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError();

#ifndef PRODUCT
  ErrorPtr InvokePendingServiceExtensionCalls();
  void AppendServiceExtensionCall(const Instance& closure,
                                  const String& method_name,
                                  const Array& parameter_keys,
                                  const Array& parameter_values,
                                  const Instance& reply_port,
                                  const Instance& id);
  void RegisterServiceExtensionHandler(const String& name,
                                       const Instance& closure);
  InstancePtr LookupServiceExtensionHandler(const String& name);
#endif

  static void VisitIsolates(IsolateVisitor* visitor);

#if !defined(PRODUCT)
  // Handle service messages until we are told to resume execution.
  void PauseEventHandler();
#endif

  bool is_service_isolate() const {
    return LoadIsolateFlagsBit<IsServiceIsolateBit>();
  }
  void set_is_service_isolate(bool value) {
    UpdateIsolateFlagsBit<IsServiceIsolateBit>(value);
  }

  bool is_kernel_isolate() const {
    return LoadIsolateFlagsBit<IsKernelIsolateBit>();
  }
  void set_is_kernel_isolate(bool value) {
    UpdateIsolateFlagsBit<IsKernelIsolateBit>(value);
  }

  bool is_service_registered() const {
    return LoadIsolateFlagsBit<IsServiceRegisteredBit>();
  }
  void set_is_service_registered(bool value) {
    UpdateIsolateFlagsBit<IsServiceRegisteredBit>(value);
  }

  const DispatchTable* dispatch_table() const {
    return group()->dispatch_table();
  }

  // Isolate-specific flag handling.
  static void FlagsInitialize(Dart_IsolateFlags* api_flags);
  void FlagsCopyTo(Dart_IsolateFlags* api_flags) const;
  void FlagsCopyFrom(const Dart_IsolateFlags& api_flags);

#if defined(DART_PRECOMPILER)
#define FLAG_FOR_PRECOMPILER(from_field, from_flag) (from_field)
#else
#define FLAG_FOR_PRECOMPILER(from_field, from_flag) (from_flag)
#endif

#if !defined(PRODUCT)
#define FLAG_FOR_NONPRODUCT(from_field, from_flag) (from_field)
#else
#define FLAG_FOR_NONPRODUCT(from_field, from_flag) (from_flag)
#endif

#define FLAG_FOR_PRODUCT(from_field, from_flag) (from_field)

#define DECLARE_GETTER(when, name, bitname, isolate_flag_name, flag_name)      \
  bool name() const {                                                          \
    return FLAG_FOR_##when(LoadIsolateFlagsBit<bitname##Bit>(), flag_name);    \
  }
  BOOL_ISOLATE_FLAG_LIST_DEFAULT_GETTER(DECLARE_GETTER)
#undef FLAG_FOR_NONPRODUCT
#undef FLAG_FOR_PRECOMPILER
#undef FLAG_FOR_PRODUCT
#undef DECLARE_GETTER

  bool has_attempted_stepping() const {
    return LoadIsolateFlagsBit<HasAttemptedSteppingBit>();
  }
  void set_has_attempted_stepping(bool value) {
    UpdateIsolateFlagsBit<HasAttemptedSteppingBit>(value);
  }

  static void KillAllIsolates(LibMsgId msg_id);
  static void KillIfExists(Isolate* isolate, LibMsgId msg_id);

  // Lookup an isolate by its main port. Returns nullptr if no matching isolate
  // is found.
  static Isolate* LookupIsolateByPort(Dart_Port port);

  // Lookup an isolate by its main port and return a copy of its name. Returns
  // nullptr if not matching isolate is found.
  static std::unique_ptr<char[]> LookupIsolateNameByPort(Dart_Port port);

  static void DisableIsolateCreation();
  static void EnableIsolateCreation();
  static bool IsolateCreationEnabled();
  static bool IsSystemIsolate(const Isolate* isolate) {
    return IsolateGroup::IsSystemIsolateGroup(isolate->group());
  }
  static bool IsVMInternalIsolate(const Isolate* isolate);

  HandlerInfoCache* handler_info_cache() { return &handler_info_cache_; }

  CatchEntryMovesCache* catch_entry_moves_cache() {
    return &catch_entry_moves_cache_;
  }

  // The weak table used in the snapshot writer for the purpose of fast message
  // sending.
  WeakTable* forward_table_new() { return forward_table_new_.get(); }
  void set_forward_table_new(WeakTable* table);

  WeakTable* forward_table_old() { return forward_table_old_.get(); }
  void set_forward_table_old(WeakTable* table);

  void RememberLiveTemporaries();
  void DeferredMarkLiveTemporaries();

  std::unique_ptr<VirtualMemory> TakeRegexpBacktrackStack() {
    return std::move(regexp_backtracking_stack_cache_);
  }

  void CacheRegexpBacktrackStack(std::unique_ptr<VirtualMemory> stack) {
    regexp_backtracking_stack_cache_ = std::move(stack);
  }

  void init_loaded_prefixes_set_storage();
  bool IsPrefixLoaded(const LibraryPrefix& prefix) const;
  void SetPrefixIsLoaded(const LibraryPrefix& prefix);

  MallocGrowableArray<ObjectPtr>* pointers_to_verify_at_exit() {
    return &pointers_to_verify_at_exit_;
  }

 private:
  friend class Dart;                  // Init, InitOnce, Shutdown.
  friend class IsolateKillerVisitor;  // Kill().
  friend Isolate* CreateWithinExistingIsolateGroup(IsolateGroup* g,
                                                   const char* n,
                                                   char** e);

  Isolate(IsolateGroup* group, const Dart_IsolateFlags& api_flags);

  static void InitVM();
  static Isolate* InitIsolate(const char* name_prefix,
                              IsolateGroup* isolate_group,
                              const Dart_IsolateFlags& api_flags,
                              bool is_vm_isolate = false);

  // The isolate_creation_monitor_ should be held when calling Kill().
  void KillLocked(LibMsgId msg_id);

  void Shutdown();
  void RunAndCleanupFinalizersOnShutdown();
  void LowLevelShutdown();

  // Unregister the [isolate] from the thread, remove it from the isolate group,
  // invoke the cleanup function (if any), delete the isolate and possibly
  // delete the isolate group (if it's the last isolate in the group).
  static void LowLevelCleanup(Isolate* isolate);

  void BuildName(const char* name_prefix);

  void ProfileIdle();

  // Visit all object pointers. Caller must ensure concurrent sweeper is not
  // running, and the visitor must not allocate.
  void VisitObjectPointers(ObjectPointerVisitor* visitor,
                           ValidationPolicy validate_frames);
  void VisitStackPointers(ObjectPointerVisitor* visitor,
                          ValidationPolicy validate_frames);

  void set_user_tag(uword tag) { user_tag_ = tag; }

  void set_is_system_isolate(bool is_system_isolate) {
    is_system_isolate_ = is_system_isolate;
  }

#if !defined(PRODUCT)
  GrowableObjectArrayPtr GetAndClearPendingServiceExtensionCalls();
  GrowableObjectArrayPtr pending_service_extension_calls() const {
    return pending_service_extension_calls_;
  }
  void set_pending_service_extension_calls(const GrowableObjectArray& value);
  GrowableObjectArrayPtr registered_service_extension_handlers() const {
    return registered_service_extension_handlers_;
  }
  void set_registered_service_extension_handlers(
      const GrowableObjectArray& value);
#endif  // !defined(PRODUCT)

  Thread* ScheduleThread(bool is_mutator,
                         bool is_nested_reenter,
                         bool bypass_safepoint);
  void UnscheduleThread(Thread* thread,
                        bool is_mutator,
                        bool is_nested_exit,
                        bool bypass_safepoint);

  // DEPRECATED: Use Thread's methods instead. During migration, these default
  // to using the mutator thread (which must also be the current thread).
  Zone* current_zone() const {
    ASSERT(Thread::Current() == mutator_thread());
    return mutator_thread()->zone();
  }

  // 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.
  uword user_tag_ = 0;
  UserTagPtr current_tag_;
  UserTagPtr default_tag_;
  CodePtr ic_miss_code_;
  FieldTable* field_table_ = nullptr;
  // Used to clear out `UntaggedFinalizerBase::isolate_` pointers on isolate
  // shutdown to prevent usage of dangling pointers.
  GrowableObjectArrayPtr finalizers_;
  bool single_step_ = false;
  bool has_resumption_breakpoints_ = false;
  bool is_system_isolate_ = false;
  // End accessed from generated code.

  IsolateGroup* isolate_group_;
  IdleTimeHandler idle_time_handler_;
  std::unique_ptr<IsolateObjectStore> isolate_object_store_;

#if !defined(DART_PRECOMPILED_RUNTIME)
  NativeCallbackTrampolines native_callback_trampolines_;
#endif

#define ISOLATE_FLAG_BITS(V)                                                   \
  V(ErrorsFatal)                                                               \
  V(IsRunnable)                                                                \
  V(IsServiceIsolate)                                                          \
  V(IsKernelIsolate)                                                           \
  V(ResumeRequest)                                                             \
  V(HasAttemptedStepping)                                                      \
  V(ShouldPausePostServiceRequest)                                             \
  V(CopyParentCode)                                                            \
  V(IsSystemIsolate)                                                           \
  V(IsServiceRegistered)

  // Isolate specific flags.
  enum FlagBits {
#define DECLARE_BIT(Name) k##Name##Bit,
    ISOLATE_FLAG_BITS(DECLARE_BIT)
#undef DECLARE_BIT
  };

#define DECLARE_BITFIELD(Name)                                                 \
  class Name##Bit : public BitField<uint32_t, bool, k##Name##Bit, 1> {};
  ISOLATE_FLAG_BITS(DECLARE_BITFIELD)
#undef DECLARE_BITFIELD

  template <class T>
  bool UpdateIsolateFlagsBit(bool value) {
    return T::decode(value ? isolate_flags_.fetch_or(T::encode(true),
                                                     std::memory_order_relaxed)
                           : isolate_flags_.fetch_and(
                                 ~T::encode(true), std::memory_order_relaxed));
  }
  template <class T>
  bool LoadIsolateFlagsBit() const {
    return T::decode(isolate_flags_.load(std::memory_order_relaxed));
  }
  std::atomic<uint32_t> isolate_flags_;

// Fields that aren't needed in a product build go here with boolean flags at
// the top.
#if !defined(PRODUCT)
  Debugger* debugger_ = nullptr;

  // SampleBlock containing CPU profiling samples.
  //
  // Can be accessed by multiple threads, so current_sample_block_lock_ should
  // be acquired before accessing.
  SampleBlock* current_sample_block_ = nullptr;
  Mutex current_sample_block_lock_;

  // SampleBlock containing Dart allocation profiling samples.
  //
  // Allocations should only occur on the mutator thread for an isolate, so we
  // shouldn't need to worry about grabbing a lock for the allocation sample
  // block.
  SampleBlock* current_allocation_sample_block_ = nullptr;

  int64_t last_resume_timestamp_;

  VMTagCounters vm_tag_counters_;

  // We use 6 list entries for each pending service extension calls.
  enum {kPendingHandlerIndex = 0, kPendingMethodNameIndex, kPendingKeysIndex,
        kPendingValuesIndex,      kPendingReplyPortIndex,  kPendingIdIndex,
        kPendingEntrySize};
  GrowableObjectArrayPtr pending_service_extension_calls_;

  // We use 2 list entries for each registered extension handler.
  enum {kRegisteredNameIndex = 0, kRegisteredHandlerIndex,
        kRegisteredEntrySize};
  GrowableObjectArrayPtr registered_service_extension_handlers_;

  // Used to wake the isolate when it is in the pause event loop.
  Monitor* pause_loop_monitor_ = nullptr;

#define ISOLATE_METRIC_VARIABLE(type, variable, name, unit)                    \
  type metric_##variable##_;
  ISOLATE_METRIC_LIST(ISOLATE_METRIC_VARIABLE);
#undef ISOLATE_METRIC_VARIABLE

  // Ring buffer of objects assigned an id.
  ObjectIdRing* object_id_ring_ = nullptr;
#endif  // !defined(PRODUCT)

  // All other fields go here.
  int64_t start_time_micros_;
  std::atomic<Dart_MessageNotifyCallback> message_notify_callback_;
  Dart_IsolateShutdownCallback on_shutdown_callback_ = nullptr;
  Dart_IsolateCleanupCallback on_cleanup_callback_ = nullptr;
  char* name_ = nullptr;
  Dart_Port main_port_ = 0;
  // Isolates created by Isolate.spawn have the same origin id.
  Dart_Port origin_id_ = 0;
  Mutex origin_id_mutex_;
  uint64_t pause_capability_ = 0;
  uint64_t terminate_capability_ = 0;
  void* init_callback_data_ = nullptr;
  Dart_EnvironmentCallback environment_callback_ = nullptr;
  Random random_;
  Simulator* simulator_ = nullptr;
  Mutex mutex_;  // Protects compiler stats.
  MessageHandler* message_handler_ = nullptr;
  intptr_t defer_finalization_count_ = 0;
  DeoptContext* deopt_context_ = nullptr;

  GrowableObjectArrayPtr tag_table_;

  ErrorPtr sticky_error_;

  std::unique_ptr<Bequest> bequest_;
  Dart_Port beneficiary_ = 0;

  // This guards spawn_count_. An isolate cannot complete shutdown and be
  // destroyed while there are child isolates in the midst of a spawn.
  Monitor spawn_count_monitor_;
  intptr_t spawn_count_ = 0;

  HandlerInfoCache handler_info_cache_;
  CatchEntryMovesCache catch_entry_moves_cache_;

  DispatchTable* dispatch_table_ = nullptr;

  // Used during message sending of messages between isolates.
  std::unique_ptr<WeakTable> forward_table_new_;
  std::unique_ptr<WeakTable> forward_table_old_;

  // Signals whether the isolate can receive messages (e.g. KillAllIsolates can
  // send a kill message).
  // This is protected by [isolate_creation_monitor_].
  bool accepts_messages_ = false;

  std::unique_ptr<VirtualMemory> regexp_backtracking_stack_cache_ = nullptr;

  static Dart_IsolateGroupCreateCallback create_group_callback_;
  static Dart_InitializeIsolateCallback initialize_callback_;
  static Dart_IsolateShutdownCallback shutdown_callback_;
  static Dart_IsolateCleanupCallback cleanup_callback_;
  static Dart_IsolateGroupCleanupCallback cleanup_group_callback_;
  static Dart_RegisterKernelBlobCallback register_kernel_blob_callback_;
  static Dart_UnregisterKernelBlobCallback unregister_kernel_blob_callback_;

#if !defined(PRODUCT)
  static void WakePauseEventHandler(Dart_Isolate isolate);
#endif

  // Manage list of existing isolates.
  static bool TryMarkIsolateReady(Isolate* isolate);
  static void UnMarkIsolateReady(Isolate* isolate);
  static void MaybeNotifyVMShutdown();
  bool AcceptsMessagesLocked() {
    ASSERT(isolate_creation_monitor_->IsOwnedByCurrentThread());
    return accepts_messages_;
  }

  // This monitor protects [creation_enabled_].
  static Monitor* isolate_creation_monitor_;
  static bool creation_enabled_;

  ArrayPtr loaded_prefixes_set_storage_;

  MallocGrowableArray<ObjectPtr> pointers_to_verify_at_exit_;

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

  friend class Become;       // VisitObjectPointers
  friend class GCCompactor;  // VisitObjectPointers
  friend class GCMarker;     // VisitObjectPointers
  friend class SafepointHandler;
  friend class ObjectGraph;         // VisitObjectPointers
  friend class HeapSnapshotWriter;  // VisitObjectPointers
  friend class Scavenger;           // VisitObjectPointers
  friend class HeapIterationScope;  // VisitObjectPointers
  friend class ServiceIsolate;
  friend class Thread;
  friend class Timeline;
  friend class IsolateGroup;  // reload_context_

  DISALLOW_COPY_AND_ASSIGN(Isolate);
};

// When we need to execute code in an isolate, we use the
// StartIsolateScope.
class StartIsolateScope {
 public:
  explicit StartIsolateScope(Isolate* new_isolate)
      : new_isolate_(new_isolate), saved_isolate_(Isolate::Current()) {
    if (new_isolate_ == nullptr) {
      ASSERT(Isolate::Current() == nullptr);
      // Do nothing.
      return;
    }
    if (saved_isolate_ != new_isolate_) {
      ASSERT(Isolate::Current() == nullptr);
      Thread::EnterIsolate(new_isolate_);
      // Ensure this is not a nested 'isolate enter' with prior state.
      ASSERT(Thread::Current()->saved_stack_limit() == 0);
    }
  }

  ~StartIsolateScope() {
    if (new_isolate_ == nullptr) {
      ASSERT(Isolate::Current() == nullptr);
      // Do nothing.
      return;
    }
    if (saved_isolate_ != new_isolate_) {
      ASSERT(saved_isolate_ == nullptr);
      // ASSERT that we have bottomed out of all Dart invocations.
      ASSERT(Thread::Current()->saved_stack_limit() == 0);
      Thread::ExitIsolate();
    }
  }

 private:
  Isolate* new_isolate_;
  Isolate* saved_isolate_;

  DISALLOW_COPY_AND_ASSIGN(StartIsolateScope);
};

class EnterIsolateGroupScope {
 public:
  explicit EnterIsolateGroupScope(IsolateGroup* isolate_group)
      : isolate_group_(isolate_group) {
    ASSERT(IsolateGroup::Current() == nullptr);
    const bool result = Thread::EnterIsolateGroupAsHelper(
        isolate_group_, Thread::kUnknownTask, /*bypass_safepoint=*/false);
    ASSERT(result);
  }

  ~EnterIsolateGroupScope() {
    Thread::ExitIsolateGroupAsHelper(/*bypass_safepoint=*/false);
  }

 private:
  IsolateGroup* isolate_group_;

  DISALLOW_COPY_AND_ASSIGN(EnterIsolateGroupScope);
};

// Ensure that isolate is not available for the duration of this scope.
//
// This can be used in code (e.g. GC, Kernel Loader) that should not operate on
// an individual isolate.
class NoActiveIsolateScope : public StackResource {
 public:
  NoActiveIsolateScope() : NoActiveIsolateScope(Thread::Current()) {}
  explicit NoActiveIsolateScope(Thread* thread)
      : StackResource(thread), thread_(thread) {
    saved_isolate_ = thread_->isolate_;
    thread_->isolate_ = nullptr;
  }
  ~NoActiveIsolateScope() {
    ASSERT(thread_->isolate_ == nullptr);
    thread_->isolate_ = saved_isolate_;
  }

 private:
  Thread* thread_;
  Isolate* saved_isolate_;
};

}  // namespace dart

#endif  // RUNTIME_VM_ISOLATE_H_
