// Copyright (c) 2017, 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_IMAGE_SNAPSHOT_H_
#define RUNTIME_VM_IMAGE_SNAPSHOT_H_

#include <utility>

#include "platform/assert.h"
#include "vm/allocation.h"
#include "vm/datastream.h"
#include "vm/globals.h"
#include "vm/growable_array.h"
#include "vm/hash_map.h"
#include "vm/object.h"
#include "vm/reusable_handles.h"
#include "vm/v8_snapshot_writer.h"

namespace dart {

// Forward declarations.
class Code;
class Dwarf;
class Instructions;
class Object;
class RawApiError;
class RawCode;
class RawInstructions;
class RawObject;

class Image : ValueObject {
 public:
  explicit Image(const void* raw_memory) : raw_memory_(raw_memory) {
    ASSERT(Utils::IsAligned(raw_memory, OS::kMaxPreferredCodeAlignment));
  }

  void* object_start() const {
    return reinterpret_cast<void*>(reinterpret_cast<uword>(raw_memory_) +
                                   kHeaderSize);
  }

  uword object_size() const {
    uword snapshot_size = *reinterpret_cast<const uword*>(raw_memory_);
    return snapshot_size - kHeaderSize;
  }

  static const intptr_t kHeaderSize = OS::kMaxPreferredCodeAlignment;

 private:
  const void* raw_memory_;  // The symbol kInstructionsSnapshot.

  DISALLOW_COPY_AND_ASSIGN(Image);
};

class ImageReader : public ZoneAllocated {
 public:
  ImageReader(const uint8_t* data_image,
              const uint8_t* instructions_image,
              const uint8_t* shared_data_image,
              const uint8_t* shared_instructions_image);

  RawApiError* VerifyAlignment() const;

  RawInstructions* GetInstructionsAt(int32_t offset) const;
  RawObject* GetObjectAt(uint32_t offset) const;
  RawObject* GetSharedObjectAt(uint32_t offset) const;

 private:
  const uint8_t* data_image_;
  const uint8_t* instructions_image_;
  const uint8_t* shared_data_image_;
  const uint8_t* shared_instructions_image_;

  DISALLOW_COPY_AND_ASSIGN(ImageReader);
};

struct ObjectOffsetPair {
 public:
  ObjectOffsetPair() : ObjectOffsetPair(NULL, 0) {}
  ObjectOffsetPair(RawObject* obj, int32_t off) : object(obj), offset(off) {}

  RawObject* object;
  int32_t offset;
};

class ObjectOffsetTrait {
 public:
  // Typedefs needed for the DirectChainedHashMap template.
  typedef RawObject* Key;
  typedef int32_t Value;
  typedef ObjectOffsetPair Pair;

  static Key KeyOf(Pair kv) { return kv.object; }
  static Value ValueOf(Pair kv) { return kv.offset; }
  static intptr_t Hashcode(Key key);
  static inline bool IsKeyEqual(Pair pair, Key key);
};

typedef DirectChainedHashMap<ObjectOffsetTrait> ObjectOffsetMap;

// A command which instructs the image writer to emit something into the ".text"
// segment.
//
// For now this just supports emitting the instructions of a [Code] object.
// In the future we might also want to add support for emitting trampolines.
struct ImageWriterCommand {
  enum Opcode {
    InsertInstructionOfCode,
  };

  ImageWriterCommand(intptr_t expected_offset,
                     ImageWriterCommand::Opcode opcode,
                     RawCode* code)
      : expected_offset(expected_offset),
        op(opcode),
        insert_instruction_of_code({code}) {}

  // The offset (relative to the very first [ImageWriterCommand]) we expect
  // this [ImageWriterCommand] to have.
  intptr_t expected_offset;

  Opcode op;
  union {
    struct {
      RawCode* code;
    } insert_instruction_of_code;
  };
};

class ImageWriter : public ValueObject {
 public:
  ImageWriter(Heap* heap,
              const void* shared_objects,
              const void* shared_instructions,
              const void* reused_instructions);
  virtual ~ImageWriter() {}

  static void SetupShared(ObjectOffsetMap* map, const void* shared_image);
  void ResetOffsets() {
    next_data_offset_ = Image::kHeaderSize;
    next_text_offset_ = Image::kHeaderSize;
    objects_.Clear();
    instructions_.Clear();
  }

  // Will start preparing the ".text" segment by interpreting the provided
  // [ImageWriterCommand]s.
  void PrepareForSerialization(GrowableArray<ImageWriterCommand>* commands);

  int32_t GetTextOffsetFor(RawInstructions* instructions, RawCode* code);
  bool GetSharedDataOffsetFor(RawObject* raw_object, uint32_t* offset);
  uint32_t GetDataOffsetFor(RawObject* raw_object);

  void Write(WriteStream* clustered_stream, bool vm);
  intptr_t data_size() const { return next_data_offset_; }
  intptr_t text_size() const { return next_text_offset_; }

  void DumpStatistics();

  void SetProfileWriter(V8SnapshotProfileWriter* profile_writer) {
    profile_writer_ = profile_writer;
  }

  void ClearProfileWriter() { profile_writer_ = nullptr; }

  void TraceInstructions(const Instructions& instructions);

 protected:
  void WriteROData(WriteStream* stream);
  virtual void WriteText(WriteStream* clustered_stream, bool vm) = 0;

  void DumpInstructionStats();
  void DumpInstructionsSizes();

  struct InstructionsData {
    InstructionsData(RawInstructions* insns,
                     RawCode* code,
                     intptr_t text_offset)
        : raw_insns_(insns), raw_code_(code), text_offset_(text_offset) {}

    union {
      RawInstructions* raw_insns_;
      const Instructions* insns_;
    };
    union {
      RawCode* raw_code_;
      const Code* code_;
    };
    intptr_t text_offset_;
  };

  struct ObjectData {
    explicit ObjectData(RawObject* raw_obj) : raw_obj_(raw_obj) {}

    union {
      RawObject* raw_obj_;
      const Object* obj_;
    };
  };

  Heap* heap_;  // Used for mapping RawInstructiosn to object ids.
  intptr_t next_data_offset_;
  intptr_t next_text_offset_;
  GrowableArray<ObjectData> objects_;
  GrowableArray<InstructionsData> instructions_;
  ObjectOffsetMap shared_objects_;
  ObjectOffsetMap shared_instructions_;
  ObjectOffsetMap reuse_instructions_;

  V8SnapshotProfileWriter::IdSpace offset_space_ =
      V8SnapshotProfileWriter::kSnapshot;
  V8SnapshotProfileWriter* profile_writer_ = nullptr;

  template <class T>
  friend class TraceImageObjectScope;

 private:
  DISALLOW_COPY_AND_ASSIGN(ImageWriter);
};

#define AutoTraceImage(object, section_offset, stream)                         \
  auto AutoTraceImagObjectScopeVar##__COUNTER__ =                              \
      TraceImageObjectScope<std::remove_pointer<decltype(stream)>::type>(      \
          this, section_offset, stream, object);

template <typename T>
class TraceImageObjectScope {
 public:
  TraceImageObjectScope(ImageWriter* writer,
                        intptr_t section_offset,
                        const T* stream,
                        const Object& object)
      : writer_(writer),
        stream_(stream),
        section_offset_(section_offset),
        start_offset_(stream_->Position() - section_offset) {
    if (writer_->profile_writer_ != nullptr) {
      Thread* thread = Thread::Current();
      REUSABLE_CLASS_HANDLESCOPE(thread);
      REUSABLE_STRING_HANDLESCOPE(thread);
      Class& klass = thread->ClassHandle();
      String& name = thread->StringHandle();
      klass = object.clazz();
      name = klass.UserVisibleName();
      ASSERT(writer_->offset_space_ != V8SnapshotProfileWriter::kSnapshot);
      writer_->profile_writer_->SetObjectTypeAndName(
          {writer_->offset_space_, start_offset_}, name.ToCString(), nullptr);
    }
  }

  ~TraceImageObjectScope() {
    if (writer_->profile_writer_ != nullptr) {
      ASSERT(writer_->offset_space_ != V8SnapshotProfileWriter::kSnapshot);
      writer_->profile_writer_->AttributeBytesTo(
          {writer_->offset_space_, start_offset_},
          stream_->Position() - section_offset_ - start_offset_);
    }
  }

 private:
  ImageWriter* writer_;
  const T* stream_;
  intptr_t section_offset_;
  intptr_t start_offset_;
};

class AssemblyImageWriter : public ImageWriter {
 public:
  AssemblyImageWriter(Thread* thread,
                      Dart_StreamingWriteCallback callback,
                      void* callback_data,
                      const void* shared_objects,
                      const void* shared_instructions);
  void Finalize();

  virtual void WriteText(WriteStream* clustered_stream, bool vm);

 private:
  void FrameUnwindPrologue();
  void FrameUnwindEpilogue();
  void WriteByteSequence(uword start, uword end);
  void WriteWordLiteralText(uword value) {
// Padding is helpful for comparing the .S with --disassemble.
#if defined(ARCH_IS_64_BIT)
    assembly_stream_.Print(".quad 0x%0.16" Px "\n", value);
#else
    assembly_stream_.Print(".long 0x%0.8" Px "\n", value);
#endif
  }

  StreamingWriteStream assembly_stream_;
  Dwarf* dwarf_;

  DISALLOW_COPY_AND_ASSIGN(AssemblyImageWriter);
};

class BlobImageWriter : public ImageWriter {
 public:
  BlobImageWriter(Thread* thread,
                  uint8_t** instructions_blob_buffer,
                  ReAlloc alloc,
                  intptr_t initial_size,
                  const void* shared_objects,
                  const void* shared_instructions,
                  const void* reused_instructions);

  virtual void WriteText(WriteStream* clustered_stream, bool vm);

  intptr_t InstructionsBlobSize() const {
    return instructions_blob_stream_.bytes_written();
  }

 private:
  WriteStream instructions_blob_stream_;

  DISALLOW_COPY_AND_ASSIGN(BlobImageWriter);
};

void DropCodeWithoutReusableInstructions(const void* reused_instructions);

}  // namespace dart

#endif  // RUNTIME_VM_IMAGE_SNAPSHOT_H_
