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

#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/exceptions.h"
#include "vm/fixed_cache.h"
#include "vm/growable_array.h"
#include "vm/handles.h"
#include "vm/heap/verifier.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/token_position.h"

namespace dart {

// Forward declarations.
class ApiState;
class BackgroundCompiler;
class Capability;
class CodeIndexTable;
class Debugger;
class DeoptContext;
class ExternalTypedData;
class HandleScope;
class HandleVisitor;
class Heap;
class ICData;
#if !defined(DART_PRECOMPILED_RUNTIME)
class Interpreter;
#endif
class IsolateProfilerData;
class IsolateReloadContext;
class IsolateSpawnState;
class Log;
class Message;
class MessageHandler;
class Mutex;
class Object;
class ObjectIdRing;
class ObjectPointerVisitor;
class ObjectStore;
class RawInstance;
class RawArray;
class RawContext;
class RawDouble;
class RawError;
class RawField;
class RawGrowableObjectArray;
class RawMint;
class RawObject;
class RawInteger;
class RawFloat32x4;
class RawInt32x4;
class RawUserTag;
class SafepointHandler;
class SampleBuffer;
class SendPort;
class SerializedObjectBuffer;
class ServiceIdZone;
class Simulator;
class StackResource;
class StackZone;
class StoreBuffer;
class StubCode;
class ThreadRegistry;
class UserTag;

class PendingLazyDeopt {
 public:
  PendingLazyDeopt(uword fp, uword pc) : fp_(fp), pc_(pc) {}
  uword fp() { return fp_; }
  uword pc() { return pc_; }
  void set_pc(uword pc) { pc_ = pc; }

 private:
  uword fp_;
  uword pc_;
};

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

  virtual void VisitIsolate(Isolate* isolate) = 0;

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

 private:
  DISALLOW_COPY_AND_ASSIGN(IsolateVisitor);
};

// Disallow OOB message handling within this scope.
class NoOOBMessageScope : public StackResource {
 public:
  explicit NoOOBMessageScope(Thread* thread);
  ~NoOOBMessageScope();

 private:
  DISALLOW_COPY_AND_ASSIGN(NoOOBMessageScope);
};

// Disallow isolate reload.
class NoReloadScope : public StackResource {
 public:
  NoReloadScope(Isolate* isolate, Thread* thread);
  ~NoReloadScope();

 private:
  Isolate* isolate_;
  DISALLOW_COPY_AND_ASSIGN(NoReloadScope);
};

// 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.
//
//       V(when, name, Dart_IsolateFlags-member-name, command-line-flag-name)
//
#define ISOLATE_FLAG_LIST(V)                                                   \
  V(NONPRODUCT, type_checks, EnableTypeChecks, enable_type_checks,             \
    FLAG_enable_type_checks)                                                   \
  V(NONPRODUCT, asserts, EnableAsserts, enable_asserts, FLAG_enable_asserts)   \
  V(NONPRODUCT, error_on_bad_type, ErrorOnBadType, enable_error_on_bad_type,   \
    FLAG_error_on_bad_type)                                                    \
  V(NONPRODUCT, use_field_guards, UseFieldGuards, use_field_guards,            \
    FLAG_use_field_guards)                                                     \
  V(NONPRODUCT, use_osr, UseOsr, use_osr, FLAG_use_osr)                        \
  V(PRECOMPILER, obfuscate, Obfuscate, obfuscate, false_by_default)            \
  V(PRODUCT, unsafe_trust_strong_mode_types, UnsafeTrustStrongModeTypes,       \
    unsafe_trust_strong_mode_types,                                            \
    FLAG_experimental_unsafe_mode_use_at_your_own_risk)

class Isolate : public BaseIsolate {
 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.
    kLowMemoryMsg = 12,     // Run compactor, etc.
  };
  // 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 == NULL ? NULL : thread->isolate();
  }

  // Register a newly introduced class.
  void RegisterClass(const Class& cls);
#if defined(DEBUG)
  void ValidateClassTable();
#endif

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

  // Visits weak object pointers.
  void VisitWeakPersistentHandles(HandleVisitor* visitor);

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

  StoreBuffer* store_buffer() const { return store_buffer_; }
  MarkingStack* marking_stack() const { return marking_stack_; }

  ThreadRegistry* thread_registry() const { return thread_registry_; }
  SafepointHandler* safepoint_handler() const { return safepoint_handler_; }
  ClassTable* class_table() { return &class_table_; }
  static intptr_t class_table_offset() {
    return OFFSET_OF(Isolate, class_table_);
  }

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

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

  Dart_MessageNotifyCallback message_notify_callback() const {
    return message_notify_callback_;
  }
  void set_message_notify_callback(Dart_MessageNotifyCallback value) {
    message_notify_callback_ = value;
  }

  Thread* mutator_thread() const;

  // Mutator thread is not scheduled if NULL or no heap is attached
  // to it. The latter only occurs when the mutator thread object
  // is unscheduled by the isolate (or never scheduled).
  bool IsMutatorThreadScheduled() { return scheduled_mutator_thread_ != NULL; }

  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() const { return origin_id_; }
  void set_origin_id(Dart_Port id) {
    ASSERT((id == main_port_ && origin_id_ == 0) || (origin_id_ == main_port_));
    origin_id_ = 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);

  Heap* heap() const { return heap_; }
  void set_heap(Heap* value) { heap_ = value; }

  ObjectStore* object_store() const { return object_store_; }
  void set_object_store(ObjectStore* value) { object_store_ = value; }
  static intptr_t object_store_offset() {
    return OFFSET_OF(Isolate, object_store_);
  }

  ApiState* api_state() const { return api_state_; }
  void set_api_state(ApiState* value) { api_state_ = value; }

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

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

  Dart_LibraryTagHandler library_tag_handler() const {
    return library_tag_handler_;
  }
  void set_library_tag_handler(Dart_LibraryTagHandler value) {
    library_tag_handler_ = value;
  }

  void SetupImagePage(const uint8_t* snapshot_buffer, bool is_executable);

  void ScheduleInterrupts(uword interrupt_bits);

  // Marks all libraries as loaded.
  void DoneLoading();
  void DoneFinalizing();

#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 = NULL,
                     const char* packages_url = NULL,
                     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 = NULL,
                    intptr_t kernel_buffer_size = 0,
                    bool dont_delete_reload_context = false);
#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)

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

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

  bool is_runnable() const { return IsRunnableBit::decode(isolate_flags_); }
  void set_is_runnable(bool value) {
    isolate_flags_ = IsRunnableBit::update(value, isolate_flags_);
#if !defined(PRODUCT)
    if (is_runnable()) {
      set_last_resume_timestamp();
    }
#endif
  }

  void NotifyIdle(int64_t deadline);

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

  IsolateSpawnState* spawn_state() const { return spawn_state_; }
  void set_spawn_state(IsolateSpawnState* value) { spawn_state_ = value; }

  Mutex* mutex() const { return mutex_; }
  Mutex* symbols_mutex() const { return symbols_mutex_; }
  Mutex* type_canonicalization_mutex() const {
    return type_canonicalization_mutex_;
  }
  Mutex* constant_canonicalization_mutex() const {
    return constant_canonicalization_mutex_;
  }
  Mutex* megamorphic_lookup_mutex() const { return megamorphic_lookup_mutex_; }

  Mutex* kernel_data_lib_cache_mutex() const {
    return kernel_data_lib_cache_mutex_;
  }
  Mutex* kernel_data_class_cache_mutex() const {
    return kernel_data_class_cache_mutex_;
  }

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

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

#if !defined(PRODUCT)
  bool ResumeRequest() const {
    return ResumeRequestBit::decode(isolate_flags_);
  }
  // Lets the embedder know that a service message resulted in a resume request.
  void SetResumeRequest() {
    isolate_flags_ = ResumeRequestBit::update(true, isolate_flags_);
    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() {
    bool resume_request = ResumeRequestBit::decode(isolate_flags_);
    isolate_flags_ = ResumeRequestBit::update(false, isolate_flags_);
    return resume_request;
  }
#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 String& msg, const String& stacktrace);

  bool ErrorsFatal() const { return ErrorsFatalBit::decode(isolate_flags_); }
  void SetErrorsFatal(bool val) {
    isolate_flags_ = ErrorsFatalBit::update(val, isolate_flags_);
  }

  Random* random() { return &random_; }

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

  Monitor* spawn_count_monitor() const { return spawn_count_monitor_; }
  intptr_t* spawn_count() { return &spawn_count_; }

  void IncrementSpawnCount();
  void WaitForOutstandingSpawns();

  static void SetCreateCallback(Dart_IsolateCreateCallback cb) {
    create_callback_ = cb;
  }
  static Dart_IsolateCreateCallback CreateCallback() {
    return create_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_;
  }

#if !defined(PRODUCT)
  void set_object_id_ring(ObjectIdRing* ring) { object_id_ring_ = ring; }
  ObjectIdRing* object_id_ring() { return object_id_ring_; }
#endif  // !defined(PRODUCT)

  void AddPendingDeopt(uword fp, uword pc);
  uword FindPendingDeopt(uword fp) const;
  void ClearPendingDeoptsAtOrBelow(uword fp) const;
  MallocGrowableArray<PendingLazyDeopt>* pending_deopts() const {
    return pending_deopts_;
  }
  bool IsDeoptimizing() const { return deopt_context_ != NULL; }
  DeoptContext* deopt_context() const { return deopt_context_; }
  void set_deopt_context(DeoptContext* value) {
    ASSERT(value == NULL || deopt_context_ == NULL);
    deopt_context_ = value;
  }

  BackgroundCompiler* background_compiler() const {
    return background_compiler_;
  }

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

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

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

#if !defined(DART_PRECOMPILED_RUNTIME)
  bool IsReloading() const { return reload_context_ != NULL; }

  IsolateReloadContext* reload_context() { return reload_context_; }

  void DeleteReloadContext();

  bool HasAttemptedReload() const {
    return HasAttemptedReloadBit::decode(isolate_flags_);
  }
  void SetHasAttemptedReload(bool value) {
    isolate_flags_ = HasAttemptedReloadBit::update(value, isolate_flags_);
  }

  bool CanReload() const;

  void set_last_reload_timestamp(int64_t value) {
    last_reload_timestamp_ = value;
  }
  int64_t last_reload_timestamp() const { return last_reload_timestamp_; }
#else
  bool IsReloading() const { return false; }
  bool HasAttemptedReload() const { return false; }
  bool CanReload() const { return false; }
#endif  // !defined(DART_PRECOMPILED_RUNTIME)
#endif  // !defined(PRODUCT)

  bool IsPaused() const;

#if !defined(PRODUCT)
  bool should_pause_post_service_request() const {
    return ShouldPausePostServiceRequestBit::decode(isolate_flags_);
  }
  void set_should_pause_post_service_request(bool value) {
    isolate_flags_ =
        ShouldPausePostServiceRequestBit::update(value, isolate_flags_);
  }
#endif  // !defined(PRODUCT)

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

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

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

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

  void set_ic_miss_code(const Code& code);

#if !defined(PRODUCT)
  Metric* metrics_list_head() { return metrics_list_head_; }
  void set_metrics_list_head(Metric* metric) { metrics_list_head_ = metric; }
#endif  // !defined(PRODUCT)

  RawGrowableObjectArray* deoptimized_code_array() const {
    return deoptimized_code_array_;
  }
  void set_deoptimized_code_array(const GrowableObjectArray& value);
  void TrackDeoptimizedCode(const Code& code);

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

  RawError* sticky_error() const { return sticky_error_; }
  void clear_sticky_error();

  void RetainKernelBlob(const ExternalTypedData& kernel_blob);

  bool compilation_allowed() const {
    return CompilationAllowedBit::decode(isolate_flags_);
  }
  void set_compilation_allowed(bool allowed) {
    isolate_flags_ = CompilationAllowedBit::update(allowed, isolate_flags_);
  }

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

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

  // True during top level parsing.
  bool IsTopLevelParsing() {
    const intptr_t value =
        AtomicOperations::LoadRelaxed(&top_level_parsing_count_);
    ASSERT(value >= 0);
    return value > 0;
  }
  void IncrTopLevelParsingCount() {
    AtomicOperations::IncrementBy(&top_level_parsing_count_, 1);
  }
  void DecrTopLevelParsingCount() {
    AtomicOperations::DecrementBy(&top_level_parsing_count_, 1);
  }

  static const intptr_t kInvalidGen = 0;

  void IncrLoadingInvalidationGen() {
    AtomicOperations::IncrementBy(&loading_invalidation_gen_, 1);
    if (loading_invalidation_gen_ == kInvalidGen) {
      AtomicOperations::IncrementBy(&loading_invalidation_gen_, 1);
    }
  }
  intptr_t loading_invalidation_gen() {
    return AtomicOperations::LoadRelaxed(&loading_invalidation_gen_);
  }

  // Used by background compiler which field became boxed and must trigger
  // deoptimization in the mutator thread.
  void AddDeoptimizingBoxedField(const Field& field);
  // Returns Field::null() if none available in the list.
  RawField* GetDeoptimizingBoxedField();

#ifndef PRODUCT
  RawObject* 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);
  RawInstance* 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

  void AddClosureFunction(const Function& function) const;
  RawFunction* LookupClosureFunction(const Function& parent,
                                     TokenPosition token_pos) const;
  intptr_t FindClosureIndex(const Function& needle) const;
  RawFunction* ClosureFunctionFromIndex(intptr_t idx) const;

  bool is_service_isolate() const {
    return IsServiceIsolateBit::decode(isolate_flags_);
  }
  void set_is_service_isolate(bool value) {
    isolate_flags_ = IsServiceIsolateBit::update(value, isolate_flags_);
  }

  bool is_kernel_isolate() const {
    return IsKernelIsolateBit::decode(isolate_flags_);
  }
  void set_is_kernel_isolate(bool value) {
    isolate_flags_ = IsKernelIsolateBit::update(value, isolate_flags_);
  }

  bool can_use_strong_mode_types() const {
    return FLAG_strong && FLAG_use_strong_mode_types &&
           !unsafe_trust_strong_mode_types();
  }

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

  Dart_QualifiedFunctionName* embedder_entry_points() const {
    return embedder_entry_points_;
  }

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

  // 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 {                                                          \
    const bool false_by_default = false;                                       \
    USE(false_by_default);                                                     \
    return FLAG_FOR_##when(bitname##Bit::decode(isolate_flags_), flag_name);   \
  }
  ISOLATE_FLAG_LIST(DECLARE_GETTER)
#undef FLAG_FOR_NONPRODUCT
#undef FLAG_FOR_PRECOMPILER
#undef FLAG_FOR_PRODUCT
#undef DECLARE_GETTER

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

  // Convenience flag tester indicating whether incoming function arguments
  // should be type checked.
  bool argument_type_checks() const {
    return should_emit_strong_mode_checks() || type_checks();
  }

  bool should_emit_strong_mode_checks() const {
    return FLAG_strong && !unsafe_trust_strong_mode_types();
  }

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

  static void DisableIsolateCreation();
  static void EnableIsolateCreation();
  static bool IsolateCreationEnabled();
  static bool IsVMInternalIsolate(const Isolate* isolate);

#if !defined(PRODUCT)
  intptr_t reload_every_n_stack_overflow_checks() const {
    return reload_every_n_stack_overflow_checks_;
  }
#endif  // !defined(PRODUCT)

  HandlerInfoCache* handler_info_cache() { return &handler_info_cache_; }

  CatchEntryMovesCache* catch_entry_moves_cache() {
    return &catch_entry_moves_cache_;
  }

  void MaybeIncreaseReloadEveryNStackOverflowChecks();

  static void NotifyLowMemory();

 private:
  friend class Dart;                  // Init, InitOnce, Shutdown.
  friend class IsolateKillerVisitor;  // Kill().

  explicit Isolate(const Dart_IsolateFlags& api_flags);

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

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

  void LowLevelShutdown();
  void Shutdown();

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

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

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

  // 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_;
  RawUserTag* current_tag_;
  RawUserTag* default_tag_;
  RawCode* ic_miss_code_;
  ObjectStore* object_store_;
  ClassTable class_table_;
  bool single_step_;
  // End accessed from generated code.

  StoreBuffer* store_buffer_;
  MarkingStack* marking_stack_;
  Heap* heap_;

#define ISOLATE_FLAG_BITS(V)                                                   \
  V(ErrorsFatal)                                                               \
  V(IsRunnable)                                                                \
  V(IsServiceIsolate)                                                          \
  V(IsKernelIsolate)                                                           \
  V(CompilationAllowed)                                                        \
  V(AllClassesFinalized)                                                       \
  V(RemappingCids)                                                             \
  V(ResumeRequest)                                                             \
  V(HasAttemptedReload)                                                        \
  V(ShouldPausePostServiceRequest)                                             \
  V(EnableTypeChecks)                                                          \
  V(EnableAsserts)                                                             \
  V(ErrorOnBadType)                                                            \
  V(ErrorOnBadOverride)                                                        \
  V(UseFieldGuards)                                                            \
  V(UseOsr)                                                                    \
  V(Obfuscate)                                                                 \
  V(CompactionInProgress)                                                      \
  V(ShouldLoadVmService)                                                       \
  V(UnsafeTrustStrongModeTypes)

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

  uint32_t isolate_flags_;

  // Background compilation.
  BackgroundCompiler* background_compiler_;

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

  // Timestamps of last operation via service.
  int64_t last_allocationprofile_accumulator_reset_timestamp_;
  int64_t last_allocationprofile_gc_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
  };
  RawGrowableObjectArray* pending_service_extension_calls_;

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

  Metric* metrics_list_head_;

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

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

  intptr_t no_reload_scope_depth_;  // we can only reload when this is 0.
  // Per-isolate copy of FLAG_reload_every.
  intptr_t reload_every_n_stack_overflow_checks_;
  IsolateReloadContext* reload_context_;
  int64_t last_reload_timestamp_;
  // Ring buffer of objects assigned an id.
  ObjectIdRing* object_id_ring_;
#endif  // !defined(PRODUCT)

  // All other fields go here.
  int64_t start_time_micros_;
  ThreadRegistry* thread_registry_;
  SafepointHandler* safepoint_handler_;
  Dart_MessageNotifyCallback message_notify_callback_;
  char* name_;
  Dart_Port main_port_;
  Dart_Port origin_id_;  // Isolates created by spawnFunc have some origin id.
  uint64_t pause_capability_;
  uint64_t terminate_capability_;
  void* init_callback_data_;
  Dart_EnvironmentCallback environment_callback_;
  Dart_LibraryTagHandler library_tag_handler_;
  ApiState* api_state_;
  Random random_;
  Simulator* simulator_;
  Mutex* mutex_;          // Protects compiler stats.
  Mutex* symbols_mutex_;  // Protects concurrent access to the symbol table.
  Mutex* type_canonicalization_mutex_;      // Protects type canonicalization.
  Mutex* constant_canonicalization_mutex_;  // Protects const canonicalization.
  Mutex* megamorphic_lookup_mutex_;  // Protects megamorphic table lookup.
  Mutex* kernel_data_lib_cache_mutex_;
  Mutex* kernel_data_class_cache_mutex_;
  MessageHandler* message_handler_;
  IsolateSpawnState* spawn_state_;
  intptr_t defer_finalization_count_;
  MallocGrowableArray<PendingLazyDeopt>* pending_deopts_;
  DeoptContext* deopt_context_;

  RawGrowableObjectArray* tag_table_;

  RawGrowableObjectArray* deoptimized_code_array_;

  RawError* sticky_error_;

  // Issue(dartbug.com/33973): We keep a reference to [ExternalTypedData]s with
  // finalizers to ensure we keep the hot-reloaded kernel blobs alive.
  //
  // -> We should get rid of this field once Issue 33973 is fixed.
  RawGrowableObjectArray* reloaded_kernel_blobs_;

  // Isolate list next pointer.
  Isolate* next_;

  // Invalidation generations; used to track events occurring in parallel
  // to background compilation. The counters may overflow, which is OK
  // since we check for equality to detect if an event occured.
  intptr_t loading_invalidation_gen_;
  intptr_t top_level_parsing_count_;

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

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

  HandlerInfoCache handler_info_cache_;
  CatchEntryMovesCache catch_entry_moves_cache_;

  Dart_QualifiedFunctionName* embedder_entry_points_;
  const char** obfuscation_map_;

  static Dart_IsolateCreateCallback create_callback_;
  static Dart_IsolateShutdownCallback shutdown_callback_;
  static Dart_IsolateCleanupCallback cleanup_callback_;

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

  // Manage list of existing isolates.
  static bool AddIsolateToList(Isolate* isolate);
  static void RemoveIsolateFromList(Isolate* isolate);

  // This monitor protects isolates_list_head_, and creation_enabled_.
  static Monitor* isolates_list_monitor_;
  static Isolate* isolates_list_head_;
  static bool creation_enabled_;

#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 Scavenger;    // VisitObjectPointers
  friend class HeapIterationScope;  // VisitObjectPointers
  friend class ServiceIsolate;
  friend class Thread;
  friend class Timeline;
  friend class NoReloadScope;  // reload_block

  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()) {
    // TODO(koda): Audit users; passing NULL goes against naming of this class.
    if (new_isolate_ == NULL) {
      ASSERT(Isolate::Current() == NULL);
      // Do nothing.
      return;
    }
    if (saved_isolate_ != new_isolate_) {
      ASSERT(Isolate::Current() == NULL);
      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_ == NULL) {
      ASSERT(Isolate::Current() == NULL);
      // Do nothing.
      return;
    }
    if (saved_isolate_ != new_isolate_) {
      ASSERT(saved_isolate_ == NULL);
      // 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 IsolateSpawnState {
 public:
  IsolateSpawnState(Dart_Port parent_port,
                    Dart_Port origin_id,
                    void* init_data,
                    const char* script_url,
                    const Function& func,
                    SerializedObjectBuffer* message_buffer,
                    Monitor* spawn_count_monitor,
                    intptr_t* spawn_count,
                    const char* package_root,
                    const char* package_config,
                    bool paused,
                    bool errorsAreFatal,
                    Dart_Port onExit,
                    Dart_Port onError);
  IsolateSpawnState(Dart_Port parent_port,
                    void* init_data,
                    const char* script_url,
                    const char* package_root,
                    const char* package_config,
                    SerializedObjectBuffer* args_buffer,
                    SerializedObjectBuffer* message_buffer,
                    Monitor* spawn_count_monitor,
                    intptr_t* spawn_count,
                    bool paused,
                    bool errorsAreFatal,
                    Dart_Port onExit,
                    Dart_Port onError);
  ~IsolateSpawnState();

  Isolate* isolate() const { return isolate_; }
  void set_isolate(Isolate* value) { isolate_ = value; }

  Dart_Port parent_port() const { return parent_port_; }
  Dart_Port origin_id() const { return origin_id_; }
  void* init_data() const { return init_data_; }
  Dart_Port on_exit_port() const { return on_exit_port_; }
  Dart_Port on_error_port() const { return on_error_port_; }
  const char* script_url() const { return script_url_; }
  const char* package_root() const { return package_root_; }
  const char* package_config() const { return package_config_; }
  const char* library_url() const { return library_url_; }
  const char* class_name() const { return class_name_; }
  const char* function_name() const { return function_name_; }
  bool is_spawn_uri() const { return library_url_ == NULL; }
  bool paused() const { return paused_; }
  bool errors_are_fatal() const { return errors_are_fatal_; }
  Dart_IsolateFlags* isolate_flags() { return &isolate_flags_; }

  RawObject* ResolveFunction();
  RawInstance* BuildArgs(Thread* thread);
  RawInstance* BuildMessage(Thread* thread);

  void DecrementSpawnCount();

 private:
  Isolate* isolate_;
  Dart_Port parent_port_;
  Dart_Port origin_id_;
  void* init_data_;
  Dart_Port on_exit_port_;
  Dart_Port on_error_port_;
  const char* script_url_;
  const char* package_root_;
  const char* package_config_;
  const char* library_url_;
  const char* class_name_;
  const char* function_name_;
  Message* serialized_args_;
  Message* serialized_message_;

  // This counter tracks the number of outstanding calls to spawn by the parent
  // isolate.
  Monitor* spawn_count_monitor_;
  intptr_t* spawn_count_;

  Dart_IsolateFlags isolate_flags_;
  bool paused_;
  bool errors_are_fatal_;
};

}  // namespace dart

#endif  // RUNTIME_VM_ISOLATE_H_
