// 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 "platform/growable_array.h"
#include "platform/thread_sanitizer.h"
#include "vm/class_table.h"
#include "vm/dispatch_table.h"
#include "vm/exceptions.h"
#include "vm/ffi_callback_metadata.h"
#include "vm/field_table.h"
#include "vm/fixed_cache.h"
#include "vm/handles.h"
#include "vm/hash_map.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/port.h"
#include "vm/random.h"
#include "vm/roots.h"
#include "vm/service.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"

namespace dart {

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

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 group flags.
//
//     V(when, name, bit-name, Dart_IsolateFlags-name, command-line-flag-name)
//
#define BOOL_ISOLATE_GROUP_FLAG_LIST(V)                                        \
  V(PRECOMPILER, obfuscate, Obfuscate, obfuscate, false)                       \
  V(NONPRODUCT, asserts, EnableAsserts, enable_asserts, FLAG_enable_asserts)   \
  V(PRODUCT, use_field_guards, UseFieldGuards, use_field_guards,               \
    FLAG_use_field_guards)                                                     \
  V(PRODUCT, should_load_vmservice_library, ShouldLoadVmService,               \
    load_vmservice_library, false)                                             \
  V(PRODUCT, 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)                                                      \
  V(NONPRODUCT, coverage, Coverage, coverage, FLAG_coverage)                   \
  V(PRODUCT, dwarf_stack_traces, DwarfStackTraces, dwarf_stack_traces,         \
    FLAG_dwarf_stack_traces_mode)                                              \
  V(PRODUCT, code_comments, CodeComments, code_comments, FLAG_code_comments)

// List of Isolate flags with corresponding members of Dart_IsolateFlags and
// corresponding global command line flags.
#define BOOL_ISOLATE_FLAG_LIST(V)                                              \
  V(NONPRODUCT, is_system_isolate, IsSystemIsolate, is_system_isolate, false)  \
  V(NONPRODUCT, is_service_isolate, IsServiceIsolate, is_service_isolate,      \
    false)                                                                     \
  V(NONPRODUCT, is_kernel_isolate, IsKernelIsolate, is_kernel_isolate, 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_text,
                     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_text(snapshot_text),
        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_text;
  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);

  // 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(MutexLocker* ml, ThreadPool::Worker* worker);

 private:
  void NotifyIdle();

  IsolateGroup* isolate_group_ = nullptr;
};

enum RootSlice : intptr_t {
  kClassTable,
  kApiState,
  kObjectStore,
  kInitialFieldTable,
  kSentinelFieldTable,
  kSharedInitialFieldTable,
  kSharedFieldTable,
  kBackgroundCompiler,
  kDebugger,
  kReloadContext,
  kLoadedBlobs,
  kBecome,
  kObjectIdZones,

  kNumRootSlices,
};

inline const char* RootSliceToCString(intptr_t slice) {
  switch (slice) {
    case kClassTable:
      return "class table";
    case kApiState:
      return "api state";
    case kObjectStore:
      return "group object store";
    case kInitialFieldTable:
      return "initial field table";
    case kSentinelFieldTable:
      return "sentinel field table";
    case kSharedInitialFieldTable:
      return "shared initial field table";
    case kSharedFieldTable:
      return "shared field table";
    case kBackgroundCompiler:
      return "background compiler";
    case kDebugger:
      return "debugger";
    case kReloadContext:
      return "reload context";
    case kLoadedBlobs:
      return "loaded blobs";
    case kBecome:
      return "become";
    case kObjectIdZones:
      return "object id zones";
    default:
      return "?";
  }
}

// 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(Become* become);
#if defined(DEBUG)
  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(); }
  Roots* roots() const { return roots_.get(); }
  FfiCallbackMetadata* callback_metadata() const {
    return callback_metadata_.get();
  }

  BackgroundCompiler* background_compiler() const {
#if defined(DART_PRECOMPILED_RUNTIME)
    return nullptr;
#else
    return background_compiler_.get();
#endif
  }
#if !defined(DART_PRECOMPILED_RUNTIME)
  intptr_t optimization_counter_threshold() const {
    if (IsSystemIsolateGroup(this)) {
      return kDefaultOptimizationCounterThreshold;
    }
    return FLAG_optimization_counter_threshold;
  }
#endif

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

  IdleTimeHandler* idle_time_handler() { return &idle_time_handler_; }

  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();
  void IncrementIsolateGroupMutatorCount();
  void DecrementIsolateGroupMutatorCount();
  bool ContainsOnlyOneIsolate();
  void RegisterIsolateGroupMutator(Thread* mutator);
  void UnregisterIsolateGroupMutator(Thread* mutator);

  Dart_Port interrupt_port() { return interrupt_port_; }

  ThreadRegistry* thread_registry() const { return thread_registry_.get(); }
  SafepointHandler* safepoint_handler() { return safepoint_handler_.get(); }

  void CreateHeap(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;
  }

  ClassTableAllocator* class_table_allocator() {
    return &class_table_allocator_;
  }

  static intptr_t class_table_offset() {
    COMPILE_ASSERT(sizeof(IsolateGroup::class_table_) == kWordSize);
    return OFFSET_OF(IsolateGroup, 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_; }

  bool is_system_isolate_group() const { return is_system_isolate_group_; }
  bool is_bootstrapping() const { return bootstrapping_; }
  void set_bootstrapping(bool v) { bootstrapping_ = v; }

  // 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(DECLARE_GETTER)
#undef FLAG_FOR_NONPRODUCT
#undef FLAG_FOR_PRECOMPILER
#undef FLAG_FOR_PRODUCT
#undef DECLARE_GETTER

  bool should_load_vmservice() const {
    return isolate_group_flags_.Read<ShouldLoadVmServiceBit>();
  }
  void set_should_load_vmservice(bool value) {
    isolate_group_flags_.UpdateBool<ShouldLoadVmServiceBit>(value);
  }

  void set_asserts(bool value) {
    isolate_group_flags_.UpdateBool<EnableAssertsBit>(value);
  }
  void set_branch_coverage(bool value) {
    isolate_group_flags_.UpdateBool<BranchCoverageBit>(value);
  }
  void set_coverage(bool value) {
    isolate_group_flags_.UpdateBool<CoverageBit>(value);
  }
  void set_use_field_guards(bool value) {
    isolate_group_flags_.UpdateBool<UseFieldGuardsBit>(value);
  }
  void set_use_osr(bool value) {
    isolate_group_flags_.UpdateBool<UseOsrBit>(value);
  }
  void set_code_comments(bool value) {
    isolate_group_flags_.UpdateBool<CodeCommentsBit>(value);
  }
  void set_dwarf_stack_traces(bool value) {
    isolate_group_flags_.UpdateBool<DwarfStackTracesBit>(value);
  }

#if !defined(PRODUCT)
#if !defined(DART_PRECOMPILED_RUNTIME)
  bool HasAttemptedReload() const {
    return isolate_group_flags_.Read<HasAttemptedReloadBit>();
  }
  void SetHasAttemptedReload(bool value) {
    isolate_group_flags_.UpdateBool<HasAttemptedReloadBit>(value);
  }
  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)

  bool has_seen_oom() const {
    return isolate_group_flags_.Read<HasSeenOOMBit>();
  }
  void set_has_seen_oom(bool value) {
    isolate_group_flags_.UpdateBool<HasSeenOOMBit>(value);
  }

  // Class table for the program loaded into this isolate group.
  //
  // This table is modified by kernel loading.
  ClassTable* class_table() const { return class_table_; }

  // Class table used for heap walks by GC visitors. Usually it
  // is the same table as one in |class_table_|, except when in the
  // middle of the reload.
  //
  // See comment for |ClassTable| class for more details.
  ClassTable* heap_walk_class_table() const { return heap_walk_class_table_; }

  void CloneClassTableForReload();
  void RestoreOriginalClassTable();
  void DropOriginalClassTable();

  StoreBuffer* store_buffer() const { return store_buffer_.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) || defined(DART_DYNAMIC_MODULES)
  Mutex* initializer_functions_mutex() { return &initializer_functions_mutex_; }
#endif  // !defined(DART_PRECOMPILED_RUNTIME) || defined(DART_DYNAMIC_MODULES)

  SafepointRwLock* shared_field_initializer_rwlock() {
    return &shared_field_initializer_rwlock_;
  }

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

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

  void IncreaseMutatorCount(Thread* thread,
                            bool is_nested_reenter,
                            bool was_stolen);
  void DecreaseMutatorCount(bool is_nested_exit);
  NO_SANITIZE_THREAD
  intptr_t MutatorCount() const { 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;
  }

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

  MarkingStack* old_marking_stack() const { return old_marking_stack_; }
  MarkingStack* new_marking_stack() const { return new_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);

  void ForEachMutatorAtASafepoint(std::function<void(Thread* thread)> function);

  // Ensures mutators are stopped during execution of the provided function.
  //
  // If the current thread is the only mutator in the isolate group,
  // [callable] will be called directly. Otherwise [callable] will be
  // called inside a [SafepointOperationsScope].
  //
  // During the duration of this function, no new isolates can be added to the
  // isolate group.
  void RunWithStoppedMutatorsCallable(Callable* callable);

  template <typename T>
  void RunWithStoppedMutators(T function) {
    LambdaCallable<T> callable(function);
    RunWithStoppedMutatorsCallable(&callable);
  }

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

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

  Dart_Port id() const { return id_; }

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

  static void ForEach(std::function<void(IsolateGroup*)> action);
  static void RunWithIsolateGroup(Dart_Port 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 HasIsolateGroups();
  static bool HasApplicationIsolateGroups();
  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 VisitSharedPointers(ObjectPointerVisitor* visitor, intptr_t slice);
  void VisitStackPointers(ObjectPointerVisitor* visitor,
                          ValidationPolicy validate_frames);
  void VisitWeakPersistentHandles(HandleVisitor* visitor);

  // In precompilation we finalize all regular classes before compiling.
  bool all_classes_finalized() const {
    return isolate_group_flags_.Read<AllClassesFinalizedBit>();
  }
  void set_all_classes_finalized(bool value) {
    isolate_group_flags_.UpdateBool<AllClassesFinalizedBit>(value);
  }
  bool has_dynamically_extendable_classes() const {
    return isolate_group_flags_.Read<HasDynamicallyExtendableClassesBit>();
  }
  void set_has_dynamically_extendable_classes(bool value) {
    isolate_group_flags_.UpdateBool<HasDynamicallyExtendableClassesBit>(value);
  }

  bool remapping_cids() const {
    return isolate_group_flags_.Read<RemappingCidsBit>();
  }
  void set_remapping_cids(bool value) {
    isolate_group_flags_.UpdateBool<RemappingCidsBit>(value);
  }

  void RememberLiveTemporaries();
  void DeferredMarkLiveTemporaries();

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

  FieldTable* sentinel_field_table() const {
    return sentinel_field_table_.get();
  }
  std::shared_ptr<FieldTable> sentinel_field_table_shareable() {
    return sentinel_field_table_;
  }
  void set_sentinel_field_table(std::shared_ptr<FieldTable> field_table) {
    sentinel_field_table_ = field_table;
  }

  FieldTable* shared_initial_field_table() const {
    return shared_initial_field_table_.get();
  }
  std::shared_ptr<FieldTable> shared_initial_field_table_shareable() {
    return shared_initial_field_table_;
  }
  void set_shared_initial_field_table(std::shared_ptr<FieldTable> field_table) {
    shared_initial_field_table_ = field_table;
  }

  FieldTable* shared_field_table() const { return shared_field_table_.get(); }
  std::shared_ptr<FieldTable> shared_field_table_shareable() {
    return shared_field_table_;
  }
  void set_shared_field_table(Thread* T, FieldTable* shared_field_table) {
    shared_field_table_.reset(shared_field_table);
    T->shared_field_table_values_ = shared_field_table->table();
  }

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

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

  Isolate* EnterTemporaryIsolate();
  static void ExitTemporaryIsolate();

  Mutex* cache_mutex() { return &cache_mutex_; }
  void RunWithCachedCatchEntryMoves(
      const Code& code,
      intptr_t pc,
      std::function<void(const CatchEntryMoves&)> action);
  void ClearCatchEntryMovesCacheLocked();
  HandlerInfoCache* handler_info_cache() { return &handler_info_cache_; }

  void SetNativeAssetsCallbacks(NativeAssetsApi* native_assets_api) {
    native_assets_api_ = *native_assets_api;
  }
  NativeAssetsApi* native_assets_api() { return &native_assets_api_; }

  bool has_attempted_stepping() const {
    return has_attempted_stepping_.load(std::memory_order_relaxed);
  }
  void set_has_attempted_stepping(bool value) {
    has_attempted_stepping_.store(value, std::memory_order_relaxed);
  }

  SafepointRwLock* tag_table_lock() { return &tag_table_lock_; }

  intptr_t thread_locals_count() { return thread_locals_count_; }
  intptr_t increment_thread_locals_count() {
    return thread_locals_count_.fetch_add(1u, std::memory_order_relaxed);
  }

  FfiCallbackMetadata::Trampoline CreateIsolateGroupBoundFfiCallback(
      Zone* zone,
      const Function& trampoline,
      const Closure& target);
  void DeleteFfiCallback(FfiCallbackMetadata::Trampoline callback);

 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(EnableAsserts)                                                             \
  V(HasAttemptedReload)                                                        \
  V(HasSeenOOM)                                                                \
  V(RemappingCids)                                                             \
  V(ShouldLoadVmService)                                                       \
  V(Obfuscate)                                                                 \
  V(UseFieldGuards)                                                            \
  V(UseOsr)                                                                    \
  V(SnapshotIsDontNeedSafe)                                                    \
  V(BranchCoverage)                                                            \
  V(Coverage)                                                                  \
  V(HasDynamicallyExtendableClasses)                                           \
  V(DwarfStackTraces)                                                          \
  V(CodeComments)

  // 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)                                                 \
  using Name##Bit = BitField<uint32_t, bool, k##Name##Bit>;
  ISOLATE_GROUP_FLAG_BITS(DECLARE_BITFIELD)
#undef DECLARE_BITFIELD

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

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

  ClassTableAllocator class_table_allocator_;
  ClassTable* heap_walk_class_table_;

  const char** obfuscation_map_ = nullptr;

  void* embedder_data_ = nullptr;

  IdleTimeHandler idle_time_handler_;
  std::unique_ptr<MutatorThreadPool> thread_pool_;
  std::unique_ptr<SafepointRwLock> isolates_lock_;
  IntrusiveDList<Isolate> isolates_;
  RelaxedAtomic<Dart_Port> interrupt_port_ = ILLEGAL_PORT;
  intptr_t isolate_count_ = 0;
  IntrusiveDList<Thread> mutators_;
  intptr_t group_mutator_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_;
  bool bootstrapping_ = true;

#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* old_marking_stack_ = nullptr;
  MarkingStack* new_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_;

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

  Dart_Port 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;
  std::shared_ptr<FieldTable> initial_field_table_;
  std::shared_ptr<FieldTable> sentinel_field_table_;
  std::shared_ptr<FieldTable> shared_initial_field_table_;
  std::shared_ptr<FieldTable> shared_field_table_;
  AtomicBitFieldContainer<uint32_t> isolate_group_flags_;

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

  std::unique_ptr<FfiCallbackMetadata> callback_metadata_;

  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) || defined(DART_DYNAMIC_MODULES)
  Mutex initializer_functions_mutex_;
#endif  // !defined(DART_PRECOMPILED_RUNTIME) || defined(DART_DYNAMIC_MODULES)

  // Ensure exclusive execution of shared field initializers.
  SafepointRwLock shared_field_initializer_rwlock_;

  // 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;
  bool has_timeout_waiter_ = false;

  NOT_IN_PRODUCT(GroupDebugger* debugger_ = nullptr);

  NativeAssetsApi native_assets_api_;

  Mutex cache_mutex_;
  HandlerInfoCache handler_info_cache_;
  CatchEntryMovesCache catch_entry_moves_cache_;

  std::atomic<bool> has_attempted_stepping_;

  SafepointRwLock tag_table_lock_;

  std::atomic<intptr_t> thread_locals_count_ = 0;

  std::unique_ptr<Roots> roots_;

  FfiCallbackMetadata::MetadataEntry* ffi_callback_list_head_ = 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 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();
  }

  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);
    is_acquirable_ = false;
  }

  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 { return mutator_thread_; }
  NO_SANITIZE_THREAD
  Thread* mutator_thread_ignore_race() const { return mutator_thread_; }

  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;
  }
  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);
  static bool SendInternalLibMessage(Dart_Port main_port,
                                     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_);
  }

  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;

  bool is_runnable() const { return isolate_flags_.Read<IsRunnableBit>(); }
  void set_is_runnable(bool value) {
    isolate_flags_.UpdateBool<IsRunnableBit>(value);
#if !defined(PRODUCT)
    if (is_runnable()) {
      set_last_resume_timestamp();
    }
#endif
  }

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

  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 isolate_flags_.Read<ResumeRequestBit>(); }
  // Lets the embedder know that a service message resulted in a resume request.
  void SetResumeRequest() {
    isolate_flags_.UpdateBool<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 isolate_flags_.TryClear<ResumeRequestBit>();
  }
#endif

#if defined(DART_INCLUDE_PROFILER)
  // Returns the current SampleBlock used to track CPU profiling samples.
  SampleBlock* current_sample_block() const { return current_sample_block_; }
  void set_current_sample_block(SampleBlock* block) {
    current_sample_block_ = block;
  }
  SampleBlock* exchange_current_sample_block(SampleBlock* block) {
    return current_sample_block_.exchange(block, std::memory_order_acq_rel);
  }
  void ProcessFreeSampleBlocks(Thread* thread);

  // Returns the current SampleBlock used to track Dart allocation samples.
  SampleBlock* current_allocation_sample_block() const {
    return current_allocation_sample_block_;
  }
  void set_current_allocation_sample_block(SampleBlock* block) {
    current_allocation_sample_block_ = block;
  }
  SampleBlock* exchange_current_allocation_sample_block(SampleBlock* block) {
    return current_allocation_sample_block_.exchange(block,
                                                     std::memory_order_acq_rel);
  }

  bool TakeHasCompletedBlocks() {
    return has_completed_blocks_.exchange(0) != 0;
  }
  bool TrySetHasCompletedBlocks() {
    return has_completed_blocks_.exchange(1) == 0;
  }
#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 isolate_flags_.Read<ErrorsFatalBit>(); }
  void SetErrorsFatal(bool value) {
    isolate_flags_.UpdateBool<ErrorsFatalBit>(value);
  }

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

  bool TryAcquireOwnership();
  void ReleaseOwnership();
  bool is_permanently_pinned() { return is_permanently_pinned_; }
  void set_is_permanently_pinned() { is_permanently_pinned_ = true; }
  void clear_is_permanently_pinned_for_testing_only() {
    is_permanently_pinned_ = false;
  }
  bool is_acquirable() { return is_acquirable_; }
  void set_is_not_acquirable() { is_acquirable_ = false; }

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

#if !defined(PRODUCT)
  // This method first ensures that the default Service ID zone for this isolate
  // exists, by creating it if necessary, and then adds a new Service ID zone to
  // `serivce_id_zones_` and returns a reference to that new zone.
  RingServiceIdZone& AddServiceIdZone(
      ObjectIdRing::BackingBufferKind backing_buffer_kind,
      ObjectIdRing::IdPolicy id_assignment_policy,
      int32_t capacity);

  void DeleteServiceIdZone(int32_t id);

  // The default Service ID zone is created lazily; this method returns the
  // default Service ID zone, creating it if necessary.
  RingServiceIdZone& EnsureDefaultServiceIdZone();

  RingServiceIdZone* GetServiceIdZone(intptr_t zone_id) const;

  template <typename F>
  void ForEachServiceIdZone(F callback) const {
    if (service_id_zones_ == nullptr) return;
    auto it = service_id_zones_->GetIterator();
    while (auto* pair = it.Next()) {
      callback(pair->value);
    }
  }
#endif  // !defined(PRODUCT)

  FfiCallbackMetadata::Trampoline CreateAsyncFfiCallback(
      Zone* zone,
      const Function& send_function,
      Dart_Port send_port);
  FfiCallbackMetadata::Trampoline CreateIsolateLocalFfiCallback(
      Zone* zone,
      const Function& trampoline,
      const Closure& target,
      bool keep_isolate_alive);
  void DeleteFfiCallback(FfiCallbackMetadata::Trampoline callback);
  void UpdateNativeCallableKeepIsolateAliveCounter(intptr_t delta);
  bool HasOpenNativeCallables();

  bool HasLivePorts();
  ReceivePortPtr CreateReceivePort(const String& debug_name);
  void SetReceivePortKeepAliveState(const ReceivePort& receive_port,
                                    bool keep_isolate_alive);
  void CloseReceivePort(const ReceivePort& receive_port);

  // Visible for testing.
  FfiCallbackMetadata::MetadataEntry* ffi_callback_list_head() {
    return ffi_callback_list_head_;
  }

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

  void PrintPauseEventJSON(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 isolate_flags_.Read<ShouldPausePostServiceRequestBit>();
  }
  void set_should_pause_post_service_request(bool value) {
    isolate_flags_.UpdateBool<ShouldPausePostServiceRequestBit>(value);
  }
#endif  // !defined(PRODUCT)

  ErrorPtr PausePostRequest();

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

  // 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_registered() const {
    return isolate_flags_.Read<IsServiceRegisteredBit>();
  }
  void set_is_service_registered(bool value) {
    isolate_flags_.UpdateBool<IsServiceRegisteredBit>(value);
  }

  // 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(isolate_flags_.Read<bitname##Bit>(), flag_name);    \
  }
  BOOL_ISOLATE_FLAG_LIST(DECLARE_GETTER)
#undef FLAG_FOR_NONPRODUCT
#undef FLAG_FOR_PRECOMPILER
#undef FLAG_FOR_PRODUCT
#undef DECLARE_GETTER

  // Kills all non-system isolates.
  static void KillAllIsolates(LibMsgId msg_id);
  // Kills all system isolates, excluding the kernel service and VM service.
  static void KillAllSystemIsolates(LibMsgId msg_id);
  static void KillIfExists(Isolate* isolate, LibMsgId msg_id);

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

  void RememberLiveTemporaries();
  void DeferredMarkLiveTemporaries();

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

  bool SetOwnerThread(ThreadId expected_old_owner, ThreadId new_owner);

  // Must be invoked with a valid PortMap::Locker, or while this isolate is the
  // current isolate (in which case the locker may be null).
  ThreadId GetOwnerThread(PortMap::Locker* locker);

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

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

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

  Thread* scheduled_mutator_thread_ = nullptr;
  // Stores the saved [Thread] object of a mutator. Mutators may retain their
  // thread even when being descheduled (e.g. due to having an active stack).
  Thread* mutator_thread_ = nullptr;

  IsolateGroup* const isolate_group_;
  std::unique_ptr<IsolateObjectStore> isolate_object_store_;

#define ISOLATE_FLAG_BITS(V)                                                   \
  V(ErrorsFatal)                                                               \
  V(IsRunnable)                                                                \
  V(IsVMIsolate)                                                               \
  V(IsServiceIsolate)                                                          \
  V(IsKernelIsolate)                                                           \
  V(ResumeRequest)                                                             \
  V(HasAttemptedStepping)                                                      \
  V(ShouldPausePostServiceRequest)                                             \
  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)                                                 \
  using Name##Bit = BitField<uint32_t, bool, k##Name##Bit>;
  ISOLATE_FLAG_BITS(DECLARE_BITFIELD)
#undef DECLARE_BITFIELD

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

  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;

  // The map of Service ID zones is created lazily.
  MallocDirectChainedHashMap<IntKeyRawPointerValueTrait<RingServiceIdZone*>>*
      service_id_zones_;

  // Monotonically increasing counter used to assign unique IDs to non-default
  // Service ID zones.
  intptr_t next_service_id_zone_id_;

#define ISOLATE_METRIC_VARIABLE(type, variable, name, unit)                    \
  type metric_##variable##_;
  ISOLATE_METRIC_LIST(ISOLATE_METRIC_VARIABLE);
#undef ISOLATE_METRIC_VARIABLE
#endif  // !defined(PRODUCT)

#if defined(DART_INCLUDE_PROFILER)
  // SampleBlock containing CPU profiling samples.
  RelaxedAtomic<SampleBlock*> current_sample_block_ = nullptr;

  // SampleBlock containing Dart allocation profiling samples.
  RelaxedAtomic<SampleBlock*> current_allocation_sample_block_ = nullptr;

  RelaxedAtomic<uword> has_completed_blocks_ = {0};
#endif

  // 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;
  uint64_t pause_capability_ = 0;
  uint64_t terminate_capability_ = 0;
  void* init_callback_data_ = nullptr;
  Dart_EnvironmentCallback environment_callback_ = nullptr;
  Mutex mutex_;  // Protects compiler stats.
  IsolateMessageHandler* message_handler_ = nullptr;
  intptr_t defer_finalization_count_ = 0;
  FfiCallbackMetadata::MetadataEntry* ffi_callback_list_head_ = nullptr;
  intptr_t ffi_callback_keep_alive_counter_ = 0;
  RelaxedAtomic<ThreadId> owner_thread_ = OSThread::kInvalidThreadId;
  bool is_permanently_pinned_ = false;
  bool is_acquirable_ = true;

  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;

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

  intptr_t wake_pause_event_handler_count_;

  // The number of open [ReceivePort]s the isolate owns.
  intptr_t open_ports_ = 0;

  // The number of open [ReceivePort]s that keep the isolate alive.
  intptr_t open_ports_keepalive_ = 0;

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

#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_] and [pending_shutdowns_].
  static Monitor* isolate_creation_monitor_;
  static bool creation_enabled_;
  static intptr_t pending_shutdowns_;

  ArrayPtr loaded_prefixes_set_storage_;

  bool is_system_isolate_ = false;

#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()->top_exit_frame_info() == 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()->top_exit_frame_info() == 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);
    Thread::EnterIsolateGroupAsHelper(isolate_group_, Thread::kUnknownTask,
                                      /*bypass_safepoint=*/false);
  }

  ~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, Compiler) that should not
// operate on an individual isolate.
class NoActiveIsolateScope : public StackResource {
 public:
  explicit NoActiveIsolateScope(bool allow_no_thread = false)
      : NoActiveIsolateScope(Thread::Current(), allow_no_thread) {}
  explicit NoActiveIsolateScope(Thread* thread, bool allow_no_thread = false)
      : StackResource(thread), thread_(thread) {
    ASSERT(allow_no_thread || thread_ != nullptr);
    if (thread_ != nullptr) {
      outer_ = thread_->no_active_isolate_scope_;
      saved_isolate_ = thread_->isolate_;

      thread_->no_active_isolate_scope_ = this;
      thread_->isolate_ = nullptr;
    }
  }
  ~NoActiveIsolateScope() {
    ASSERT(thread_ == nullptr || thread_->isolate_ == nullptr);
    ASSERT(thread_ != nullptr || saved_isolate_ == nullptr);
    if (thread_ != nullptr) {
      thread_->isolate_ = saved_isolate_;
      thread_->no_active_isolate_scope_ = outer_;
    }
  }

 private:
  friend class ActiveIsolateScope;

  Thread* thread_ = nullptr;
  Isolate* saved_isolate_ = nullptr;
  NoActiveIsolateScope* outer_ = nullptr;
};

class ActiveIsolateScope : public StackResource {
 public:
  explicit ActiveIsolateScope(Thread* thread)
      : ActiveIsolateScope(thread,
                           thread->no_active_isolate_scope_->saved_isolate_) {}

  ActiveIsolateScope(Thread* thread, Isolate* isolate)
      : StackResource(thread), thread_(thread) {
    RELEASE_ASSERT(thread->isolate() == nullptr);
    thread_->isolate_ = isolate;
  }
  ~ActiveIsolateScope() {
    ASSERT(thread_->isolate_ != nullptr);
    thread_->isolate_ = nullptr;
  }

 private:
  Thread* thread_;
};

}  // namespace dart

#endif  // RUNTIME_VM_ISOLATE_H_
