// Copyright (c) 2016, 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_RELOAD_H_
#define RUNTIME_VM_ISOLATE_RELOAD_H_

#include "include/dart_tools_api.h"

#include "vm/globals.h"
#include "vm/growable_array.h"
#include "vm/hash_map.h"
#include "vm/log.h"
#include "vm/object.h"

DECLARE_FLAG(bool, trace_reload);
DECLARE_FLAG(bool, trace_reload_verbose);

// 'Trace Isolate Reload' TIR_Print
#if defined(_MSC_VER)
#define TIR_Print(format, ...)                                                 \
  if (FLAG_trace_reload) Log::Current()->Print(format, __VA_ARGS__)
#else
#define TIR_Print(format, ...)                                                 \
  if (FLAG_trace_reload) Log::Current()->Print(format, ##__VA_ARGS__)
#endif

// 'Verbose Trace Isolate Reload' VTIR_Print
#if defined(_MSC_VER)
#define VTIR_Print(format, ...)                                                \
  if (FLAG_trace_reload_verbose) Log::Current()->Print(format, __VA_ARGS__)
#else
#define VTIR_Print(format, ...)                                                \
  if (FLAG_trace_reload_verbose) Log::Current()->Print(format, ##__VA_ARGS__)
#endif

#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)

namespace dart {

class BitVector;
class GrowableObjectArray;
class Isolate;
class Library;
class ObjectPointerVisitor;
class ObjectStore;
class RawError;
class RawGrowableObjectArray;
class RawLibrary;
class RawObject;
class RawString;
class Script;
class UpdateClassesVisitor;

class InstanceMorpher : public ZoneAllocated {
 public:
  InstanceMorpher(Zone* zone, const Class& from, const Class& to);
  virtual ~InstanceMorpher() {}

  // Called on each instance that needs to be morphed.
  RawInstance* Morph(const Instance& instance) const;

  void RunNewFieldInitializers() const;

  // Adds an object to be morphed.
  void AddObject(RawObject* object) const;

  // Create the morphed objects based on the before() list.
  void CreateMorphedCopies() const;

  // Dump the state of the morpher.
  void Dump() const;

  // Append the morper info to JSON array.
  void AppendTo(JSONArray* array);

  // Returns the list of objects that need to be morphed.
  ZoneGrowableArray<const Instance*>* before() const { return before_; }
  // Returns the list of morphed objects (matches order in before()).
  ZoneGrowableArray<const Instance*>* after() const { return after_; }
  // Returns the list of new fields.
  ZoneGrowableArray<const Field*>* new_fields() const { return new_fields_; }

  // Returns the cid associated with the from_ and to_ class.
  intptr_t cid() const { return cid_; }

 private:
  const Class& from_;
  const Class& to_;
  ZoneGrowableArray<intptr_t> mapping_;
  ZoneGrowableArray<const Instance*>* before_;
  ZoneGrowableArray<const Instance*>* after_;
  ZoneGrowableArray<const Field*>* new_fields_;
  intptr_t cid_;

  void ComputeMapping();
  void DumpFormatFor(const Class& cls) const;
};

class ReasonForCancelling : public ZoneAllocated {
 public:
  explicit ReasonForCancelling(Zone* zone) {}
  virtual ~ReasonForCancelling() {}

  // Reports a reason for cancelling reload.
  void Report(IsolateReloadContext* context);

  // Conversion to a VM error object.
  // Default implementation calls ToString.
  virtual RawError* ToError();

  // Conversion to a string object.
  // Default implementation calls ToError.
  virtual RawString* ToString();

  // Append the reason to JSON array.
  virtual void AppendTo(JSONArray* array);

  // Concrete subclasses must override either ToError or ToString.
};

// Abstract class for also capturing the from_ and to_ class.
class ClassReasonForCancelling : public ReasonForCancelling {
 public:
  ClassReasonForCancelling(Zone* zone, const Class& from, const Class& to);
  void AppendTo(JSONArray* array);

 protected:
  const Class& from_;
  const Class& to_;
};

class IsolateReloadContext {
 public:
  explicit IsolateReloadContext(Isolate* isolate, JSONStream* js);
  ~IsolateReloadContext();

  // If kernel_buffer is provided, the VM takes ownership when Reload is called.
  void Reload(bool force_reload,
              const char* root_script_url = NULL,
              const char* packages_url = NULL,
              const uint8_t* kernel_buffer = NULL,
              intptr_t kernel_buffer_size = 0);

  // All zone allocated objects must be allocated from this zone.
  Zone* zone() const { return zone_; }

  bool reload_skipped() const { return reload_skipped_; }
  bool reload_aborted() const { return reload_aborted_; }
  RawError* error() const;
  int64_t reload_timestamp() const { return reload_timestamp_; }

  static Dart_FileModifiedCallback file_modified_callback() {
    return file_modified_callback_;
  }
  static void SetFileModifiedCallback(Dart_FileModifiedCallback callback) {
    file_modified_callback_ = callback;
  }

  static bool IsSameField(const Field& a, const Field& b);
  static bool IsSameLibrary(const Library& a_lib, const Library& b_lib);
  static bool IsSameClass(const Class& a, const Class& b);

 private:
  RawLibrary* saved_root_library() const;

  RawGrowableObjectArray* saved_libraries() const;

  RawClass* FindOriginalClass(const Class& cls);

  bool IsDirty(const Library& lib);

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

  void RegisterClass(const Class& new_cls);

  // Finds the library private key for |replacement_or_new| or return null
  // if |replacement_or_new| is new.
  RawString* FindLibraryPrivateKey(const Library& replacement_or_new);

  int64_t start_time_micros() const { return start_time_micros_; }

  // Tells whether there are reasons for cancelling the reload.
  bool HasReasonsForCancelling() const {
    return !reasons_to_cancel_reload_.is_empty();
  }

  // Record problem for this reload.
  void AddReasonForCancelling(ReasonForCancelling* reason);

  // Reports all reasons for cancelling reload.
  void ReportReasonsForCancelling();

  // Reports the details of a reload operation.
  void ReportOnJSON(JSONStream* stream);

  // Store morphing operation.
  void AddInstanceMorpher(InstanceMorpher* morpher);

  // Tells whether instance in the heap must be morphed.
  bool HasInstanceMorphers() const { return !instance_morphers_.is_empty(); }

  // NOTE: FinalizeLoading will be called *before* Reload() returns. This
  // function will not be called if the embedder does not call
  // Dart_FinalizeLoading.
  void FinalizeLoading();

  // NOTE: FinalizeFailedLoad will be called *before* Reload returns. This
  // function will not be called if the embedder calls Dart_FinalizeLoading.
  void FinalizeFailedLoad(const Error& error);

  // Called by both FinalizeLoading and FinalizeFailedLoad.
  void CommonFinalizeTail();

  // Report back through the observatory channels.
  void ReportError(const Error& error);
  void ReportSuccess();

  void set_saved_root_library(const Library& value);

  void set_saved_libraries(const GrowableObjectArray& value);

  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  Isolate* isolate() { return isolate_; }
  ObjectStore* object_store();

  void EnsuredUnoptimizedCodeForStack();
  void DeoptimizeDependentCode();

  void Checkpoint();

  void CheckpointClasses();

  bool ScriptModifiedSince(const Script& script, int64_t since);
  BitVector* FindModifiedLibraries(bool force_reload, bool root_lib_modified);
  void FindModifiedSources(Thread* thread,
                           bool force_reload,
                           Dart_SourceFile** modified_sources,
                           intptr_t* count,
                           const char* packages_url);

  void CheckpointLibraries();

  // Transforms the heap based on instance_morphers_. Return whether there was
  // any morphing.
  bool MorphInstances();

  void RunNewFieldInitializers();

  bool ValidateReload();

  void Rollback();

  void RollbackClasses();
  void RollbackLibraries();

#ifdef DEBUG
  void VerifyMaps();
#endif

  void Commit();

  void PostCommit();

  void ClearReplacedObjectBits();

  // atomic_install:
  void RunInvalidationVisitors();
  void ResetUnoptimizedICsOnStack();
  void ResetMegamorphicCaches();
  void InvalidateWorld();

  // The zone used for all reload related allocations.
  Zone* zone_;

  int64_t start_time_micros_;
  int64_t reload_timestamp_;
  Isolate* isolate_;
  bool reload_skipped_;
  bool reload_aborted_;
  bool reload_finalized_;
  JSONStream* js_;

  intptr_t saved_num_cids_;
  ClassAndSize* saved_class_table_;
  intptr_t num_saved_libs_;

  // Collect the necessary instance transformation for schema changes.
  ZoneGrowableArray<InstanceMorpher*> instance_morphers_;

  // Collects the reasons for cancelling the reload.
  ZoneGrowableArray<ReasonForCancelling*> reasons_to_cancel_reload_;

  // Required trait for the cid_mapper_;
  struct MorpherTrait {
    typedef InstanceMorpher* Value;
    typedef intptr_t Key;
    typedef InstanceMorpher* Pair;

    static Key KeyOf(Pair kv) { return kv->cid(); }
    static Value ValueOf(Pair kv) { return kv; }
    static intptr_t Hashcode(Key key) { return key; }
    static bool IsKeyEqual(Pair kv, Key key) { return kv->cid() == key; }
  };

  // Hash map from cid to InstanceMorpher.
  DirectChainedHashMap<MorpherTrait> cid_mapper_;

  struct LibraryInfo {
    bool dirty;
  };
  MallocGrowableArray<LibraryInfo> library_infos_;

  // A bit vector indicating which of the original libraries were modified.
  BitVector* modified_libs_;

  RawClass* OldClassOrNull(const Class& replacement_or_new);

  RawLibrary* OldLibraryOrNull(const Library& replacement_or_new);

  RawLibrary* OldLibraryOrNullBaseMoved(const Library& replacement_or_new);

  void BuildLibraryMapping();

  void AddClassMapping(const Class& replacement_or_new, const Class& original);

  void AddLibraryMapping(const Library& replacement_or_new,
                         const Library& original);

  void AddStaticFieldMapping(const Field& old_field, const Field& new_field);

  void AddBecomeMapping(const Object& old, const Object& neu);
  void AddEnumBecomeMapping(const Object& old, const Object& neu);

  void RebuildDirectSubclasses();

  RawClass* MappedClass(const Class& replacement_or_new);
  RawLibrary* MappedLibrary(const Library& replacement_or_new);

  RawObject** from() { return reinterpret_cast<RawObject**>(&script_url_); }
  RawString* script_url_;
  RawError* error_;
  RawArray* old_classes_set_storage_;
  RawArray* class_map_storage_;
  RawArray* old_libraries_set_storage_;
  RawArray* library_map_storage_;
  RawArray* become_map_storage_;
  RawGrowableObjectArray* become_enum_mappings_;
  RawLibrary* saved_root_library_;
  RawGrowableObjectArray* saved_libraries_;
  RawString* root_url_prefix_;
  RawString* old_root_url_prefix_;
  RawObject** to() {
    return reinterpret_cast<RawObject**>(&old_root_url_prefix_);
  }

  friend class Isolate;
  friend class Class;  // AddStaticFieldMapping, AddEnumBecomeMapping.
  friend class Library;
  friend class ObjectLocator;
  friend class MarkFunctionsForRecompilation;  // IsDirty.
  friend class ReasonForCancelling;

  static Dart_FileModifiedCallback file_modified_callback_;
};

}  // namespace dart

#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)

#endif  // RUNTIME_VM_ISOLATE_RELOAD_H_
