// 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 VM_ISOLATE_H_
#define VM_ISOLATE_H_

#include "include/dart_api.h"
#include "platform/assert.h"
#include "platform/thread.h"
#include "vm/base_isolate.h"
#include "vm/class_table.h"
#include "vm/gc_callbacks.h"
#include "vm/megamorphic_cache_table.h"
#include "vm/store_buffer.h"
#include "vm/timer.h"

namespace dart {

// Forward declarations.
class ApiState;
class CodeIndexTable;
class Debugger;
class Function;
class HandleScope;
class HandleVisitor;
class Heap;
class ICData;
class Instance;
class LongJump;
class MessageHandler;
class Mutex;
class ObjectPointerVisitor;
class ObjectStore;
class RawInstance;
class RawArray;
class RawContext;
class RawDouble;
class RawMint;
class RawObject;
class RawInteger;
class RawError;
class Simulator;
class StackResource;
class StackZone;
class StubCode;
class RawFloat32x4;
class RawUint32x4;


// Used by the deoptimization infrastructure to defer allocation of unboxed
// objects until frame is fully rewritten and GC is safe.
// Describes a stack slot that should be populated with a reference to the
// materialized object.
class DeferredSlot {
 public:
  DeferredSlot(RawInstance** slot, DeferredSlot* next)
      : slot_(slot), next_(next) { }
  virtual ~DeferredSlot() { }

  RawInstance** slot() const { return slot_; }
  DeferredSlot* next() const { return next_; }

  virtual void Materialize() = 0;

 private:
  RawInstance** const slot_;
  DeferredSlot* const next_;

  DISALLOW_COPY_AND_ASSIGN(DeferredSlot);
};


class DeferredDouble : public DeferredSlot {
 public:
  DeferredDouble(double value, RawInstance** slot, DeferredSlot* next)
      : DeferredSlot(slot, next), value_(value) { }

  virtual void Materialize();

  double value() const { return value_; }

 private:
  const double value_;

  DISALLOW_COPY_AND_ASSIGN(DeferredDouble);
};


class DeferredMint : public DeferredSlot {
 public:
  DeferredMint(int64_t value, RawInstance** slot, DeferredSlot* next)
      : DeferredSlot(slot, next), value_(value) { }

  virtual void Materialize();

  int64_t value() const { return value_; }

 private:
  const int64_t value_;

  DISALLOW_COPY_AND_ASSIGN(DeferredMint);
};


class DeferredFloat32x4 : public DeferredSlot {
 public:
  DeferredFloat32x4(simd128_value_t value, RawInstance** slot,
                    DeferredSlot* next)
      : DeferredSlot(slot, next), value_(value) { }

  virtual void Materialize();

  simd128_value_t value() const { return value_; }

 private:
  const simd128_value_t value_;

  DISALLOW_COPY_AND_ASSIGN(DeferredFloat32x4);
};


class DeferredUint32x4 : public DeferredSlot {
 public:
  DeferredUint32x4(simd128_value_t value, RawInstance** slot,
                   DeferredSlot* next)
      : DeferredSlot(slot, next), value_(value) { }

  virtual void Materialize();

  simd128_value_t value() const { return value_; }

 private:
  const simd128_value_t value_;

  DISALLOW_COPY_AND_ASSIGN(DeferredUint32x4);
};


// Describes a slot that contains a reference to an object that had its
// allocation removed by AllocationSinking pass.
// Object itself is described and materialized by DeferredObject.
class DeferredObjectRef : public DeferredSlot {
 public:
  DeferredObjectRef(intptr_t index, RawInstance** slot, DeferredSlot* next)
      : DeferredSlot(slot, next), index_(index) { }

  virtual void Materialize();

  intptr_t index() const { return index_; }

 private:
  const intptr_t index_;

  DISALLOW_COPY_AND_ASSIGN(DeferredObjectRef);
};


// Describes an object which allocation was removed by AllocationSinking pass.
// Arguments for materialization are stored as a part of expression stack
// for the bottommost deoptimized frame so that GC could discover them.
// They will be removed from the stack at the very end of deoptimization.
class DeferredObject {
 public:
  DeferredObject(intptr_t field_count, intptr_t* args)
      : field_count_(field_count),
        args_(reinterpret_cast<RawObject**>(args)),
        object_(NULL) { }

  intptr_t ArgumentCount() const {
    return kFieldsStartIndex + kFieldEntrySize * field_count_;
  }

  RawInstance* object();

 private:
  enum {
    kClassIndex = 0,
    kFieldsStartIndex = kClassIndex + 1
  };

  enum {
    kFieldIndex = 0,
    kValueIndex,
    kFieldEntrySize,
  };

  // Materializes the object. Returns amount of values that were consumed
  // and should be removed from the expression stack at the very end of
  // deoptimization.
  void Materialize();

  RawObject* GetClass() const {
    return args_[kClassIndex];
  }

  RawObject* GetField(intptr_t index) const {
    return args_[kFieldsStartIndex + kFieldEntrySize * index + kFieldIndex];
  }

  RawObject* GetValue(intptr_t index) const {
    return args_[kFieldsStartIndex + kFieldEntrySize * index + kValueIndex];
  }

  // Amount of fields that have to be initialized.
  const intptr_t field_count_;

  // Pointer to the first materialization argument on the stack.
  // The first argument is Class of the instance to materialize followed by
  // Field, value pairs.
  RawObject** args_;

  // Object materialized from this description.
  const Instance* object_;

  DISALLOW_COPY_AND_ASSIGN(DeferredObject);
};


class Isolate : public BaseIsolate {
 public:
  ~Isolate();

  static inline Isolate* Current() {
    return reinterpret_cast<Isolate*>(Thread::GetThreadLocal(isolate_key));
  }

  static void SetCurrent(Isolate* isolate);

  static void InitOnce();
  static Isolate* Init(const char* name_prefix);
  void Shutdown();

  // Visit all object pointers.
  void VisitObjectPointers(ObjectPointerVisitor* visitor,
                           bool visit_prologue_weak_persistent_handles,
                           bool validate_frames);

  // Visits weak object pointers.
  void VisitWeakPersistentHandles(HandleVisitor* visit,
                                  bool visit_prologue_weak_persistent_handles);

  StoreBuffer* store_buffer() { return &store_buffer_; }
  static intptr_t store_buffer_offset() {
    return OFFSET_OF(Isolate, store_buffer_);
  }

  ClassTable* class_table() { return &class_table_; }
  static intptr_t class_table_offset() {
    return OFFSET_OF(Isolate, class_table_);
  }

  MegamorphicCacheTable* megamorphic_cache_table() {
    return &megamorphic_cache_table_;
  }

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

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

  int64_t start_time() const { return start_time_; }

  Dart_Port main_port() { return main_port_; }
  void set_main_port(Dart_Port port) {
    ASSERT(main_port_ == 0);  // Only set main port once.
    main_port_ = port;
  }

  Heap* heap() const { return heap_; }
  void set_heap(Heap* value) { heap_ = value; }
  static intptr_t heap_offset() { return OFFSET_OF(Isolate, heap_); }

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

  RawContext* top_context() const { return top_context_; }
  void set_top_context(RawContext* value) { top_context_ = value; }
  static intptr_t top_context_offset() {
    return OFFSET_OF(Isolate, top_context_);
  }

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

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

  StubCode* stub_code() const { return stub_code_; }
  void set_stub_code(StubCode* value) { stub_code_ = value; }

  LongJump* long_jump_base() const { return long_jump_base_; }
  void set_long_jump_base(LongJump* value) { long_jump_base_ = value; }

  TimerList& timer_list() { return timer_list_; }

  static intptr_t current_zone_offset() {
    return OFFSET_OF(Isolate, current_zone_);
  }

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

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

  void SetStackLimit(uword value);
  void SetStackLimitFromCurrentTOS(uword isolate_stack_top);

  uword stack_limit_address() const {
    return reinterpret_cast<uword>(&stack_limit_);
  }

  // The current stack limit.  This may be overwritten with a special
  // value to trigger interrupts.
  uword stack_limit() const { return stack_limit_; }

  // The true stack limit for this isolate.
  uword saved_stack_limit() const { return saved_stack_limit_; }

  static uword GetSpecifiedStackSize();

  static const intptr_t kStackSizeBuffer = (4 * KB * kWordSize);

  enum {
    kApiInterrupt = 0x1,      // An interrupt from Dart_InterruptIsolate.
    kMessageInterrupt = 0x2,  // An interrupt to process an out of band message.
    kStoreBufferInterrupt = 0x4,  // An interrupt to process the store buffer.
    kVmStatusInterrupt = 0x8,     // An interrupt to process a status request.

    kInterruptsMask =
        kApiInterrupt |
        kMessageInterrupt |
        kStoreBufferInterrupt |
        kVmStatusInterrupt,
  };

  enum IsolateRunState {
    kIsolateWaiting = 0,      // The isolate is waiting for code to execute.
    kIsolateRunning,          // The isolate is executing code.
  };

  void ScheduleInterrupts(uword interrupt_bits);
  uword GetAndClearInterrupts();

  bool MakeRunnable();
  void Run();

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

  bool is_runnable() const { return is_runnable_; }
  void set_is_runnable(bool value) { is_runnable_ = value; }

  IsolateRunState running_state() const { return running_state_; }
  void set_running_state(IsolateRunState value) { running_state_ = value; }

  uword spawn_data() const { return spawn_data_; }
  void set_spawn_data(uword value) { spawn_data_ = value; }

  static const intptr_t kNoDeoptId = -1;
  static const intptr_t kDeoptIdStep = 2;
  static const intptr_t kDeoptIdBeforeOffset = 0;
  static const intptr_t kDeoptIdAfterOffset = 1;
  intptr_t deopt_id() const { return deopt_id_; }
  void set_deopt_id(int value) {
    ASSERT(value >= 0);
    deopt_id_ = value;
  }
  intptr_t GetNextDeoptId() {
    ASSERT(deopt_id_ != kNoDeoptId);
    const intptr_t id = deopt_id_;
    deopt_id_ += kDeoptIdStep;
    return id;
  }

  static intptr_t ToDeoptAfter(intptr_t deopt_id) {
    ASSERT(IsDeoptBefore(deopt_id));
    return deopt_id + kDeoptIdAfterOffset;
  }

  static bool IsDeoptBefore(intptr_t deopt_id) {
    return (deopt_id % kDeoptIdStep) == kDeoptIdBeforeOffset;
  }

  static bool IsDeoptAfter(intptr_t deopt_id) {
    return (deopt_id % kDeoptIdStep) == kDeoptIdAfterOffset;
  }

  Mutex* mutex() const { return mutex_; }

  Debugger* debugger() const { return debugger_; }

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

  GcPrologueCallbacks& gc_prologue_callbacks() {
    return gc_prologue_callbacks_;
  }

  GcEpilogueCallbacks& gc_epilogue_callbacks() {
    return gc_epilogue_callbacks_;
  }

  static void SetCreateCallback(Dart_IsolateCreateCallback cb) {
    create_callback_ = cb;
  }
  static Dart_IsolateCreateCallback CreateCallback() {
    return create_callback_;
  }

  static void SetInterruptCallback(Dart_IsolateInterruptCallback cb) {
    interrupt_callback_ = cb;
  }
  static Dart_IsolateInterruptCallback InterruptCallback() {
    return interrupt_callback_;
  }

  static void SetVmStatsCallback(Dart_IsolateInterruptCallback cb) {
    vmstats_callback_ = cb;
  }
  static Dart_IsolateInterruptCallback VmStatsCallback() {
    return vmstats_callback_;
  }

  static void SetUnhandledExceptionCallback(
      Dart_IsolateUnhandledExceptionCallback cb) {
    unhandled_exception_callback_ = cb;
  }
  static Dart_IsolateUnhandledExceptionCallback UnhandledExceptionCallback() {
    return unhandled_exception_callback_;
  }

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

  static void SetFileCallbacks(Dart_FileOpenCallback file_open,
                               Dart_FileReadCallback file_read,
                               Dart_FileWriteCallback file_write,
                               Dart_FileCloseCallback file_close) {
    file_open_callback_ = file_open;
    file_read_callback_ = file_read;
    file_write_callback_ = file_write;
    file_close_callback_ = file_close;
  }

  static Dart_FileOpenCallback file_open_callback() {
    return file_open_callback_;
  }
  static Dart_FileReadCallback file_read_callback() {
    return file_read_callback_;
  }
  static Dart_FileWriteCallback file_write_callback() {
    return file_write_callback_;
  }
  static Dart_FileCloseCallback file_close_callback() {
    return file_close_callback_;
  }

  intptr_t* deopt_cpu_registers_copy() const {
    return deopt_cpu_registers_copy_;
  }
  void set_deopt_cpu_registers_copy(intptr_t* value) {
    ASSERT((value == NULL) || (deopt_cpu_registers_copy_ == NULL));
    deopt_cpu_registers_copy_ = value;
  }
  fpu_register_t* deopt_fpu_registers_copy() const {
    return deopt_fpu_registers_copy_;
  }
  void set_deopt_fpu_registers_copy(fpu_register_t* value) {
    ASSERT((value == NULL) || (deopt_fpu_registers_copy_ == NULL));
    deopt_fpu_registers_copy_ = value;
  }
  intptr_t* deopt_frame_copy() const { return deopt_frame_copy_; }
  void SetDeoptFrameCopy(intptr_t* value, intptr_t size) {
    ASSERT((value == NULL) || (size > 0));
    ASSERT((value == NULL) || (deopt_frame_copy_ == NULL));
    deopt_frame_copy_ = value;
    deopt_frame_copy_size_ = size;
  }
  intptr_t deopt_frame_copy_size() const { return deopt_frame_copy_size_; }

  void PrepareForDeferredMaterialization(intptr_t count) {
    if (count > 0) {
      deferred_objects_ = new DeferredObject*[count];
      deferred_objects_count_ = count;
    }
  }

  void DeleteDeferredObjects() {
    for (intptr_t i = 0; i < deferred_objects_count_; i++) {
      delete deferred_objects_[i];
    }
    delete[] deferred_objects_;
    deferred_objects_ = NULL;
    deferred_objects_count_ = 0;
  }

  DeferredObject* GetDeferredObject(intptr_t idx) const {
    return deferred_objects_[idx];
  }

  void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) {
    deferred_objects_[idx] = object;
  }

  intptr_t DeferredObjectsCount() const {
    return deferred_objects_count_;
  }

  void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) {
    deferred_object_refs_ = new DeferredObjectRef(
        idx,
        reinterpret_cast<RawInstance**>(slot),
        deferred_object_refs_);
  }

  void DeferDoubleMaterialization(double value, RawDouble** slot) {
    deferred_boxes_ = new DeferredDouble(
        value,
        reinterpret_cast<RawInstance**>(slot),
        deferred_boxes_);
  }

  void DeferMintMaterialization(int64_t value, RawMint** slot) {
    deferred_boxes_ = new DeferredMint(
        value,
        reinterpret_cast<RawInstance**>(slot),
        deferred_boxes_);
  }

  void DeferFloat32x4Materialization(simd128_value_t value,
                                     RawFloat32x4** slot) {
    deferred_boxes_ = new DeferredFloat32x4(
        value,
        reinterpret_cast<RawInstance**>(slot),
        deferred_boxes_);
  }

  void DeferUint32x4Materialization(simd128_value_t value,
                                    RawUint32x4** slot) {
    deferred_boxes_ = new DeferredUint32x4(
        value,
        reinterpret_cast<RawInstance**>(slot),
        deferred_boxes_);
  }

  // Populate all deferred slots that contain boxes for double, mint, simd
  // values.
  void MaterializeDeferredBoxes();

  // Populate all slots containing references to objects which allocations
  // were eliminated by AllocationSinking pass.
  void MaterializeDeferredObjects();

  static char* GetStatus(const char* request);

 private:
  Isolate();

  void BuildName(const char* name_prefix);
  void PrintInvokedFunctions();

  static bool FetchStacktrace();
  static bool FetchStackFrameDetails();
  char* GetStatusDetails();
  char* GetStatusStacktrace();
  char* GetStatusStackFrame(intptr_t index);
  char* DoStacktraceInterrupt(Dart_IsolateInterruptCallback cb);

  static ThreadLocalKey isolate_key;
  StoreBuffer store_buffer_;
  ClassTable class_table_;
  MegamorphicCacheTable megamorphic_cache_table_;
  Dart_MessageNotifyCallback message_notify_callback_;
  char* name_;
  int64_t start_time_;
  Dart_Port main_port_;
  Heap* heap_;
  ObjectStore* object_store_;
  RawContext* top_context_;
  uword top_exit_frame_info_;
  void* init_callback_data_;
  Dart_LibraryTagHandler library_tag_handler_;
  ApiState* api_state_;
  StubCode* stub_code_;
  Debugger* debugger_;
  Simulator* simulator_;
  LongJump* long_jump_base_;
  TimerList timer_list_;
  intptr_t deopt_id_;
  Mutex* mutex_;  // protects stack_limit_ and saved_stack_limit_.
  uword stack_limit_;
  uword saved_stack_limit_;
  MessageHandler* message_handler_;
  uword spawn_data_;
  bool is_runnable_;
  IsolateRunState running_state_;
  GcPrologueCallbacks gc_prologue_callbacks_;
  GcEpilogueCallbacks gc_epilogue_callbacks_;

  // Deoptimization support.
  intptr_t* deopt_cpu_registers_copy_;
  fpu_register_t* deopt_fpu_registers_copy_;
  intptr_t* deopt_frame_copy_;
  intptr_t deopt_frame_copy_size_;
  DeferredSlot* deferred_boxes_;
  DeferredSlot* deferred_object_refs_;

  intptr_t deferred_objects_count_;
  DeferredObject** deferred_objects_;

  // Status support.
  char* stacktrace_;
  intptr_t stack_frame_index_;

  static Dart_IsolateCreateCallback create_callback_;
  static Dart_IsolateInterruptCallback interrupt_callback_;
  static Dart_IsolateUnhandledExceptionCallback unhandled_exception_callback_;
  static Dart_IsolateShutdownCallback shutdown_callback_;
  static Dart_FileOpenCallback file_open_callback_;
  static Dart_FileReadCallback file_read_callback_;
  static Dart_FileWriteCallback file_write_callback_;
  static Dart_FileCloseCallback file_close_callback_;
  static Dart_IsolateInterruptCallback vmstats_callback_;

  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()) {
    ASSERT(new_isolate_ != NULL);
    if (saved_isolate_ != new_isolate_) {
      ASSERT(Isolate::Current() == NULL);
      Isolate::SetCurrent(new_isolate_);
      new_isolate_->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(this));
    }
  }

  ~StartIsolateScope() {
    if (saved_isolate_ != new_isolate_) {
      new_isolate_->SetStackLimit(~static_cast<uword>(0));
      Isolate::SetCurrent(saved_isolate_);
    }
  }

 private:
  Isolate* new_isolate_;
  Isolate* saved_isolate_;

  DISALLOW_COPY_AND_ASSIGN(StartIsolateScope);
};

// When we need to temporarily become another isolate, we use the
// SwitchIsolateScope.  It is not permitted to run dart code while in
// a SwitchIsolateScope.
class SwitchIsolateScope {
 public:
  explicit SwitchIsolateScope(Isolate* new_isolate)
      : new_isolate_(new_isolate),
        saved_isolate_(Isolate::Current()),
        saved_stack_limit_(saved_isolate_
                           ? saved_isolate_->saved_stack_limit() : 0) {
    if (saved_isolate_ != new_isolate_) {
      Isolate::SetCurrent(new_isolate_);
      if (new_isolate_ != NULL) {
        // Don't allow dart code to execute.
        new_isolate_->SetStackLimit(~static_cast<uword>(0));
      }
    }
  }

  ~SwitchIsolateScope() {
    if (saved_isolate_ != new_isolate_) {
      Isolate::SetCurrent(saved_isolate_);
      if (saved_isolate_ != NULL) {
        saved_isolate_->SetStackLimit(saved_stack_limit_);
      }
    }
  }

 private:
  Isolate* new_isolate_;
  Isolate* saved_isolate_;
  uword saved_stack_limit_;

  DISALLOW_COPY_AND_ASSIGN(SwitchIsolateScope);
};


class IsolateSpawnState {
 public:
  IsolateSpawnState(const Function& func, const Function& callback_func);
  explicit IsolateSpawnState(const char* script_url);
  ~IsolateSpawnState();

  Isolate* isolate() const { return isolate_; }
  void set_isolate(Isolate* value) { isolate_ = value; }
  char* script_url() const { return script_url_; }
  char* library_url() const { return library_url_; }
  char* function_name() const { return function_name_; }
  char* exception_callback_name() const { return exception_callback_name_; }

  RawObject* ResolveFunction();
  void Cleanup();

 private:
  Isolate* isolate_;
  char* script_url_;
  char* library_url_;
  char* function_name_;
  char* exception_callback_name_;
};


class IsolateRunStateManager : public StackResource {
 public:
  explicit IsolateRunStateManager()
      : StackResource(Isolate::Current()),
        saved_state_(Isolate::kIsolateWaiting) {
    saved_state_ = reinterpret_cast<Isolate*>(isolate())->running_state();
  }

  virtual ~IsolateRunStateManager() {
    reinterpret_cast<Isolate*>(isolate())->set_running_state(saved_state_);
  }

  void SetRunState(Isolate::IsolateRunState run_state) {
    reinterpret_cast<Isolate*>(isolate())->set_running_state(run_state);
  }

 private:
  Isolate::IsolateRunState saved_state_;

  DISALLOW_COPY_AND_ASSIGN(IsolateRunStateManager);
};

}  // namespace dart

#endif  // VM_ISOLATE_H_
