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

#include "vm/image_snapshot.h"

#include "include/dart_api.h"
#include "platform/assert.h"
#include "vm/class_id.h"
#include "vm/compiler/runtime_api.h"
#include "vm/dwarf.h"
#include "vm/elf.h"
#include "vm/hash.h"
#include "vm/hash_map.h"
#include "vm/heap/heap.h"
#include "vm/instructions.h"
#include "vm/json_writer.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/program_visitor.h"
#include "vm/stub_code.h"
#include "vm/timeline.h"
#include "vm/type_testing_stubs.h"

#if !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/compiler/backend/code_statistics.h"
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

namespace dart {

#if defined(DART_PRECOMPILER)
DEFINE_FLAG(bool,
            print_instruction_stats,
            false,
            "Print instruction statistics");

DEFINE_FLAG(charp,
            print_instructions_sizes_to,
            NULL,
            "Print sizes of all instruction objects to the given file");
#endif

intptr_t ObjectOffsetTrait::Hashcode(Key key) {
  ObjectPtr obj = key;
  ASSERT(!obj->IsSmi());

  uword body = ObjectLayout::ToAddr(obj) + sizeof(ObjectLayout);
  uword end = ObjectLayout::ToAddr(obj) + obj->ptr()->HeapSize();

  uint32_t hash = obj->GetClassId();
  // Don't include the header. Objects in the image are pre-marked, but objects
  // in the current isolate are not.
  for (uword cursor = body; cursor < end; cursor += sizeof(uint32_t)) {
    hash = CombineHashes(hash, *reinterpret_cast<uint32_t*>(cursor));
  }

  return FinalizeHash(hash, 30);
}

bool ObjectOffsetTrait::IsKeyEqual(Pair pair, Key key) {
  ObjectPtr a = pair.object;
  ObjectPtr b = key;
  ASSERT(!a->IsSmi());
  ASSERT(!b->IsSmi());

  if (a->GetClassId() != b->GetClassId()) {
    return false;
  }

  intptr_t heap_size = a->ptr()->HeapSize();
  if (b->ptr()->HeapSize() != heap_size) {
    return false;
  }

  // Don't include the header. Objects in the image are pre-marked, but objects
  // in the current isolate are not.
  uword body_a = ObjectLayout::ToAddr(a) + sizeof(ObjectLayout);
  uword body_b = ObjectLayout::ToAddr(b) + sizeof(ObjectLayout);
  uword body_size = heap_size - sizeof(ObjectLayout);
  return 0 == memcmp(reinterpret_cast<const void*>(body_a),
                     reinterpret_cast<const void*>(body_b), body_size);
}

#if !defined(DART_PRECOMPILED_RUNTIME)
ImageWriter::ImageWriter(Thread* t)
    : heap_(t->heap()),
      next_data_offset_(0),
      next_text_offset_(0),
      objects_(),
      instructions_(),
      instructions_section_type_(
          TagObjectTypeAsReadOnly(t->zone(), "InstructionsSection")),
      instructions_type_(TagObjectTypeAsReadOnly(t->zone(), "Instructions")),
      trampoline_type_(TagObjectTypeAsReadOnly(t->zone(), "Trampoline")) {
  ResetOffsets();
}

void ImageWriter::PrepareForSerialization(
    GrowableArray<ImageWriterCommand>* commands) {
  if (commands != nullptr) {
    const intptr_t initial_offset = next_text_offset_;
    for (auto& inst : *commands) {
      ASSERT((initial_offset + inst.expected_offset) == next_text_offset_);
      switch (inst.op) {
        case ImageWriterCommand::InsertInstructionOfCode: {
          CodePtr code = inst.insert_instruction_of_code.code;
          InstructionsPtr instructions = Code::InstructionsOf(code);
          const intptr_t offset = next_text_offset_;
          instructions_.Add(InstructionsData(instructions, code, offset));
          next_text_offset_ += SizeInSnapshot(instructions);
          ASSERT(heap_->GetObjectId(instructions) == 0);
          heap_->SetObjectId(instructions, offset);
          break;
        }
        case ImageWriterCommand::InsertBytesOfTrampoline: {
          auto trampoline_bytes = inst.insert_trampoline_bytes.buffer;
          auto trampoline_length = inst.insert_trampoline_bytes.buffer_length;
          const intptr_t offset = next_text_offset_;
          instructions_.Add(
              InstructionsData(trampoline_bytes, trampoline_length, offset));
          next_text_offset_ += trampoline_length;
          break;
        }
        default:
          UNREACHABLE();
      }
    }
  }
}

int32_t ImageWriter::GetTextOffsetFor(InstructionsPtr instructions,
                                      CodePtr code) {
  intptr_t offset = heap_->GetObjectId(instructions);
  if (offset != 0) {
    return offset;
  }

  offset = next_text_offset_;
  heap_->SetObjectId(instructions, offset);
  next_text_offset_ += SizeInSnapshot(instructions);
  instructions_.Add(InstructionsData(instructions, code, offset));

  ASSERT(offset != 0);
  return offset;
}

static intptr_t InstructionsSizeInSnapshot(InstructionsPtr raw) {
  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
    // Currently, we align bare instruction payloads on 4 byte boundaries.
    //
    // If we later decide to align on larger boundaries to put entries at the
    // start of cache lines, make sure to account for entry points that are
    // _not_ at the start of the payload.
    return Utils::RoundUp(Instructions::Size(raw),
                          ImageWriter::kBareInstructionsAlignment);
  }
#if defined(IS_SIMARM_X64)
  return Utils::RoundUp(
      compiler::target::Instructions::HeaderSize() + Instructions::Size(raw),
      compiler::target::ObjectAlignment::kObjectAlignment);
#else
  return raw->ptr()->HeapSize();
#endif
}

#if defined(IS_SIMARM_X64)
static intptr_t CompressedStackMapsSizeInSnapshot(intptr_t payload_size) {
  const intptr_t unrounded_size_in_bytes =
      compiler::target::CompressedStackMaps::HeaderSize() + payload_size;
  return Utils::RoundUp(unrounded_size_in_bytes,
                        compiler::target::ObjectAlignment::kObjectAlignment);
}

static intptr_t StringPayloadSize(intptr_t len, bool isOneByteString) {
  return len * (isOneByteString ? OneByteString::kBytesPerElement
                                : TwoByteString::kBytesPerElement);
}

static intptr_t StringSizeInSnapshot(intptr_t len, bool isOneByteString) {
  const intptr_t unrounded_size_in_bytes =
      (String::kSizeofRawString / 2) + StringPayloadSize(len, isOneByteString);
  return Utils::RoundUp(unrounded_size_in_bytes,
                        compiler::target::ObjectAlignment::kObjectAlignment);
}

static intptr_t CodeSourceMapSizeInSnapshot(intptr_t len) {
  const intptr_t unrounded_size_in_bytes =
      2 * compiler::target::kWordSize + len;
  return Utils::RoundUp(unrounded_size_in_bytes,
                        compiler::target::ObjectAlignment::kObjectAlignment);
}

static intptr_t PcDescriptorsSizeInSnapshot(intptr_t len) {
  const intptr_t unrounded_size_in_bytes =
      2 * compiler::target::kWordSize + len;
  return Utils::RoundUp(unrounded_size_in_bytes,
                        compiler::target::ObjectAlignment::kObjectAlignment);
}

intptr_t ImageWriter::SizeInSnapshot(ObjectPtr raw_object) {
  const classid_t cid = raw_object->GetClassId();

  switch (cid) {
    case kCompressedStackMapsCid: {
      CompressedStackMapsPtr raw_maps =
          static_cast<CompressedStackMapsPtr>(raw_object);
      auto const payload_size = CompressedStackMaps::PayloadSizeOf(raw_maps);
      return CompressedStackMapsSizeInSnapshot(payload_size);
    }
    case kOneByteStringCid:
    case kTwoByteStringCid: {
      StringPtr raw_str = static_cast<StringPtr>(raw_object);
      return StringSizeInSnapshot(Smi::Value(raw_str->ptr()->length_),
                                  cid == kOneByteStringCid);
    }
    case kCodeSourceMapCid: {
      CodeSourceMapPtr raw_map = static_cast<CodeSourceMapPtr>(raw_object);
      return CodeSourceMapSizeInSnapshot(raw_map->ptr()->length_);
    }
    case kPcDescriptorsCid: {
      PcDescriptorsPtr raw_desc = static_cast<PcDescriptorsPtr>(raw_object);
      return PcDescriptorsSizeInSnapshot(raw_desc->ptr()->length_);
    }
    case kInstructionsCid: {
      InstructionsPtr raw_insns = static_cast<InstructionsPtr>(raw_object);
      return InstructionsSizeInSnapshot(raw_insns);
    }
    default: {
      const Class& clazz = Class::Handle(Object::Handle(raw_object).clazz());
      FATAL1("Unsupported class %s in rodata section.\n", clazz.ToCString());
      return 0;
    }
  }
}
#else   // defined(IS_SIMARM_X64)
intptr_t ImageWriter::SizeInSnapshot(ObjectPtr raw) {
  switch (raw->GetClassId()) {
    case kInstructionsCid:
      return InstructionsSizeInSnapshot(static_cast<InstructionsPtr>(raw));
    default:
      return raw->ptr()->HeapSize();
  }
}
#endif  // defined(IS_SIMARM_X64)

uint32_t ImageWriter::GetDataOffsetFor(ObjectPtr raw_object) {
  intptr_t snap_size = SizeInSnapshot(raw_object);
  intptr_t offset = next_data_offset_;
  next_data_offset_ += snap_size;
  objects_.Add(ObjectData(raw_object));
  return offset;
}

intptr_t ImageWriter::GetTextObjectCount() const {
  return instructions_.length();
}

void ImageWriter::GetTrampolineInfo(intptr_t* count, intptr_t* size) const {
  ASSERT(count != nullptr && size != nullptr);
  *count = 0;
  *size = 0;
  for (auto const data : instructions_) {
    if (data.trampoline_length != 0) {
      *count += 1;
      *size += data.trampoline_length;
    }
  }
}

// Returns nullptr if there is no profile writer.
const char* ImageWriter::ObjectTypeForProfile(const Object& object) const {
  if (profile_writer_ == nullptr) return nullptr;
  ASSERT(IsROSpace());
  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();
  auto const name_str = name.ToCString();
  return TagObjectTypeAsReadOnly(thread->zone(), name_str);
}

const char* ImageWriter::TagObjectTypeAsReadOnly(Zone* zone, const char* type) {
  ASSERT(zone != nullptr && type != nullptr);
  return OS::SCreate(zone, "(RO) %s", type);
}

#if defined(DART_PRECOMPILER)
void ImageWriter::DumpInstructionStats() {
  std::unique_ptr<CombinedCodeStatistics> instruction_stats(
      new CombinedCodeStatistics());
  for (intptr_t i = 0; i < instructions_.length(); i++) {
    auto& data = instructions_[i];
    CodeStatistics* stats = data.insns_->stats();
    if (stats != nullptr) {
      stats->AppendTo(instruction_stats.get());
    }
  }
  instruction_stats->DumpStatistics();
}

void ImageWriter::DumpInstructionsSizes() {
  auto thread = Thread::Current();
  auto zone = thread->zone();

  auto& cls = Class::Handle(zone);
  auto& lib = Library::Handle(zone);
  auto& owner = Object::Handle(zone);
  auto& url = String::Handle(zone);
  auto& name = String::Handle(zone);
  intptr_t trampolines_total_size = 0;

  JSONWriter js;
  js.OpenArray();
  for (intptr_t i = 0; i < instructions_.length(); i++) {
    auto& data = instructions_[i];
    const bool is_trampoline = data.code_ == nullptr;
    if (is_trampoline) {
      trampolines_total_size += data.trampoline_length;
      continue;
    }
    owner = WeakSerializationReference::Unwrap(data.code_->owner());
    js.OpenObject();
    if (owner.IsFunction()) {
      cls = Function::Cast(owner).Owner();
      name = cls.ScrubbedName();
      lib = cls.library();
      url = lib.url();
      js.PrintPropertyStr("l", url);
      js.PrintPropertyStr("c", name);
    } else if (owner.IsClass()) {
      cls ^= owner.raw();
      name = cls.ScrubbedName();
      lib = cls.library();
      url = lib.url();
      js.PrintPropertyStr("l", url);
      js.PrintPropertyStr("c", name);
    }
    js.PrintProperty("n",
                     data.code_->QualifiedName(
                         NameFormattingParams::DisambiguatedWithoutClassName(
                             Object::kInternalName)));
    js.PrintProperty("s", SizeInSnapshot(data.insns_->raw()));
    js.CloseObject();
  }
  if (trampolines_total_size != 0) {
    js.OpenObject();
    js.PrintProperty("n", "[Stub] Trampoline");
    js.PrintProperty("s", trampolines_total_size);
    js.CloseObject();
  }
  js.CloseArray();

  auto file_open = Dart::file_open_callback();
  auto file_write = Dart::file_write_callback();
  auto file_close = Dart::file_close_callback();
  if ((file_open == nullptr) || (file_write == nullptr) ||
      (file_close == nullptr)) {
    return;
  }

  auto file = file_open(FLAG_print_instructions_sizes_to, /*write=*/true);
  if (file == nullptr) {
    OS::PrintErr("Failed to open file %s\n", FLAG_print_instructions_sizes_to);
    return;
  }

  char* output = nullptr;
  intptr_t output_length = 0;
  js.Steal(&output, &output_length);
  file_write(output, output_length, file);
  free(output);
  file_close(file);
}

void ImageWriter::DumpStatistics() {
  if (FLAG_print_instruction_stats) {
    DumpInstructionStats();
  }

  if (FLAG_print_instructions_sizes_to != nullptr) {
    DumpInstructionsSizes();
  }
}
#endif

void ImageWriter::Write(WriteStream* clustered_stream, bool vm) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  Heap* heap = thread->isolate()->heap();
  TIMELINE_DURATION(thread, Isolate, "WriteInstructions");

  // Handlify collected raw pointers as building the names below
  // will allocate on the Dart heap.
  for (intptr_t i = 0; i < instructions_.length(); i++) {
    InstructionsData& data = instructions_[i];
    const bool is_trampoline = data.trampoline_bytes != nullptr;
    if (is_trampoline) continue;

    data.insns_ = &Instructions::Handle(zone, data.raw_insns_);
    ASSERT(data.raw_code_ != nullptr);
    data.code_ = &Code::Handle(zone, data.raw_code_);

    // Reset object id as an isolate snapshot after a VM snapshot will not use
    // the VM snapshot's text image.
    heap->SetObjectId(data.insns_->raw(), 0);
  }
  for (intptr_t i = 0; i < objects_.length(); i++) {
    ObjectData& data = objects_[i];
    data.obj_ = &Object::Handle(zone, data.raw_obj_);
  }

  // Append the direct-mapped RO data objects after the clustered snapshot.
  // We need to do this before WriteText because WriteText currently adds the
  // finalized contents of the clustered_stream as data sections.
  offset_space_ = vm ? V8SnapshotProfileWriter::kVmData
                     : V8SnapshotProfileWriter::kIsolateData;
  WriteROData(clustered_stream);

  offset_space_ = vm ? V8SnapshotProfileWriter::kVmText
                     : V8SnapshotProfileWriter::kIsolateText;
  // Needs to happen after WriteROData, because all image writers currently
  // add the clustered data information to their output in WriteText().
  WriteText(clustered_stream, vm);
}

void ImageWriter::WriteROData(WriteStream* stream) {
#if defined(DART_PRECOMPILER)
  const intptr_t start_position = stream->Position();
#endif
  stream->Align(kMaxObjectAlignment);

  // Heap page starts here.

  intptr_t section_start = stream->Position();

  stream->WriteWord(next_data_offset_);  // Data length.
  // Zero values for other image header fields.
  stream->Align(kMaxObjectAlignment);
  ASSERT(stream->Position() - section_start == Image::kHeaderSize);
#if defined(DART_PRECOMPILER)
  if (profile_writer_ != nullptr) {
    const intptr_t end_position = stream->Position();
    profile_writer_->AttributeBytesTo(
        V8SnapshotProfileWriter::ArtificialRootId(),
        end_position - start_position);
  }
#endif

  // Heap page objects start here.

  for (intptr_t i = 0; i < objects_.length(); i++) {
    const Object& obj = *objects_[i].obj_;
    AutoTraceImage(obj, section_start, stream);

    NoSafepointScope no_safepoint;
    uword start = static_cast<uword>(obj.raw()) - kHeapObjectTag;

    // Write object header with the mark and read-only bits set.
    uword marked_tags = obj.raw()->ptr()->tags_;
    marked_tags = ObjectLayout::OldBit::update(true, marked_tags);
    marked_tags = ObjectLayout::OldAndNotMarkedBit::update(false, marked_tags);
    marked_tags =
        ObjectLayout::OldAndNotRememberedBit::update(true, marked_tags);
    marked_tags = ObjectLayout::NewBit::update(false, marked_tags);
#if defined(HASH_IN_OBJECT_HEADER)
    marked_tags |= static_cast<uword>(obj.raw()->ptr()->hash_) << 32;
#endif

#if defined(IS_SIMARM_X64)
    if (obj.IsCompressedStackMaps()) {
      const CompressedStackMaps& map = CompressedStackMaps::Cast(obj);
      auto const object_start = stream->Position();

      const intptr_t payload_size = map.payload_size();
      const intptr_t size_in_bytes =
          CompressedStackMapsSizeInSnapshot(payload_size);
      marked_tags = UpdateObjectSizeForTarget(size_in_bytes, marked_tags);

      stream->WriteTargetWord(marked_tags);
      stream->WriteFixed<uint32_t>(map.raw()->ptr()->flags_and_size_);
      ASSERT_EQUAL(stream->Position() - object_start,
                   compiler::target::CompressedStackMaps::HeaderSize());
      stream->WriteBytes(map.raw()->ptr()->data(), payload_size);
      stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
    } else if (obj.IsString()) {
      const String& str = String::Cast(obj);
      RELEASE_ASSERT(String::GetCachedHash(str.raw()) != 0);
      RELEASE_ASSERT(str.IsOneByteString() || str.IsTwoByteString());
      const intptr_t size_in_bytes =
          StringSizeInSnapshot(str.Length(), str.IsOneByteString());
      marked_tags = UpdateObjectSizeForTarget(size_in_bytes, marked_tags);

      stream->WriteTargetWord(marked_tags);
      stream->WriteTargetWord(static_cast<uword>(str.raw()->ptr()->length_));
      stream->WriteTargetWord(static_cast<uword>(str.raw()->ptr()->hash_));
      stream->WriteBytes(
          reinterpret_cast<const void*>(start + String::kSizeofRawString),
          StringPayloadSize(str.Length(), str.IsOneByteString()));
      stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
    } else if (obj.IsCodeSourceMap()) {
      const CodeSourceMap& map = CodeSourceMap::Cast(obj);
      const intptr_t size_in_bytes = CodeSourceMapSizeInSnapshot(map.Length());
      marked_tags = UpdateObjectSizeForTarget(size_in_bytes, marked_tags);

      stream->WriteTargetWord(marked_tags);
      stream->WriteTargetWord(map.Length());
      stream->WriteBytes(map.Data(), map.Length());
      stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
    } else if (obj.IsPcDescriptors()) {
      const PcDescriptors& desc = PcDescriptors::Cast(obj);

      const intptr_t size_in_bytes = PcDescriptorsSizeInSnapshot(desc.Length());
      marked_tags = UpdateObjectSizeForTarget(size_in_bytes, marked_tags);

      stream->WriteTargetWord(marked_tags);
      stream->WriteTargetWord(desc.Length());
      stream->WriteBytes(desc.raw()->ptr()->data(), desc.Length());
      stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
    } else {
      const Class& clazz = Class::Handle(obj.clazz());
      FATAL1("Unsupported class %s in rodata section.\n", clazz.ToCString());
    }
#else   // defined(IS_SIMARM_X64)
    const uword end = start + obj.raw()->ptr()->HeapSize();

    stream->WriteWord(marked_tags);
    start += sizeof(uword);
    for (uword* cursor = reinterpret_cast<uword*>(start);
         cursor < reinterpret_cast<uword*>(end); cursor++) {
      stream->WriteWord(*cursor);
    }
#endif  // defined(IS_SIMARM_X64)
  }
}

#if defined(DART_PRECOMPILER)
class DwarfAssemblyStream : public DwarfWriteStream {
 public:
  explicit DwarfAssemblyStream(StreamingWriteStream* stream)
      : stream_(ASSERT_NOTNULL(stream)) {}

  void sleb128(intptr_t value) { Print(".sleb128 %" Pd "\n", value); }
  void uleb128(uintptr_t value) { Print(".uleb128 %" Pd "\n", value); }
  void u1(uint8_t value) { Print(".byte %u\n", value); }
  void u2(uint16_t value) { Print(".2byte %u\n", value); }
  void u4(uint32_t value) { Print(".4byte %" Pu32 "\n", value); }
  void u8(uint64_t value) { Print(".8byte %" Pu64 "\n", value); }
  void string(const char* cstr) {     // NOLINT
    Print(".string \"%s\"\n", cstr);  // NOLINT
  }
  // Uses labels, so doesn't output to start or return a useful fixup position.
  intptr_t ReserveSize(const char* prefix, intptr_t* start) {
    // Assignment to temp works around buggy Mac assembler.
    Print("L%s_size = .L%s_end - .L%s_start\n", prefix, prefix, prefix);
    Print(".4byte L%s_size\n", prefix);
    Print(".L%s_start:\n", prefix);
    return -1;
  }
  // Just need to label the end so the assembler can calculate the size, so
  // start and the fixup position is unused.
  void SetSize(intptr_t fixup, const char* prefix, intptr_t start) {
    Print(".L%s_end:\n", prefix);
  }
  void OffsetFromSymbol(const char* symbol, intptr_t offset) {
    if (offset == 0) {
      PrintNamedAddress(symbol);
    } else {
      PrintNamedAddressWithOffset(symbol, offset);
    }
  }
  void DistanceBetweenSymbolOffsets(const char* symbol1,
                                    intptr_t offset1,
                                    const char* symbol2,
                                    intptr_t offset2) {
    Print(".uleb128 %s - %s + %" Pd "\n", symbol1, symbol2, offset1 - offset2);
  }

  // No-op, we'll be using labels.
  void InitializeAbstractOrigins(intptr_t size) {}
  void RegisterAbstractOrigin(intptr_t index) {
    // Label for DW_AT_abstract_origin references
    Print(".Lfunc%" Pd ":\n", index);
  }
  void AbstractOrigin(intptr_t index) {
    // Assignment to temp works around buggy Mac assembler.
    Print("Ltemp%" Pd " = .Lfunc%" Pd " - %s\n", temp_, index, kDebugInfoLabel);
    Print(".4byte Ltemp%" Pd "\n", temp_);
    temp_++;
  }

  // Methods for writing the assembly prologues for various DWARF sections.
  void AbbreviationsPrologue() {
#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
    Print(".section __DWARF,__debug_abbrev,regular,debug\n");
#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
    defined(TARGET_OS_FUCHSIA)
    Print(".section .debug_abbrev,\"\"\n");
#else
    UNIMPLEMENTED();
#endif
  }
  void DebugInfoPrologue() {
#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
    Print(".section __DWARF,__debug_info,regular,debug\n");
#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
    defined(TARGET_OS_FUCHSIA)
    Print(".section .debug_info,\"\"\n");
#else
    UNIMPLEMENTED();
#endif
    // Used to calculate abstract origin values.
    Print("%s:\n", kDebugInfoLabel);
  }
  void LineNumberProgramPrologue() {
#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
    Print(".section __DWARF,__debug_line,regular,debug\n");
#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
    defined(TARGET_OS_FUCHSIA)
    Print(".section .debug_line,\"\"\n");
#else
    UNIMPLEMENTED();
#endif
  }

 private:
  static constexpr const char* kDebugInfoLabel = ".Ldebug_info";

  void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) {
    va_list args;
    va_start(args, format);
    stream_->VPrint(format, args);
    va_end(args);
  }

#if defined(TARGET_ARCH_IS_32_BIT)
#define FORM_ADDR ".4byte"
#elif defined(TARGET_ARCH_IS_64_BIT)
#define FORM_ADDR ".8byte"
#endif

  void PrintNamedAddress(const char* name) { Print(FORM_ADDR " %s\n", name); }
  void PrintNamedAddressWithOffset(const char* name, intptr_t offset) {
    Print(FORM_ADDR " %s + %" Pd "\n", name, offset);
  }

#undef FORM_ADDR

  StreamingWriteStream* const stream_;
  intptr_t temp_ = 0;

  DISALLOW_COPY_AND_ASSIGN(DwarfAssemblyStream);
};
#endif

static inline Dwarf* AddDwarfIfUnstripped(Zone* zone, bool strip, Elf* elf) {
#if defined(DART_PRECOMPILER)
  if (!strip) {
    if (elf != nullptr) {
      // Reuse the existing DWARF object.
      ASSERT(elf->dwarf() != nullptr);
      return elf->dwarf();
    }
    return new (zone) Dwarf(zone);
  }
#endif
  return nullptr;
}

AssemblyImageWriter::AssemblyImageWriter(Thread* thread,
                                         Dart_StreamingWriteCallback callback,
                                         void* callback_data,
                                         bool strip,
                                         Elf* debug_elf)
    : ImageWriter(thread),
      assembly_stream_(512 * KB, callback, callback_data),
      assembly_dwarf_(AddDwarfIfUnstripped(thread->zone(), strip, debug_elf)),
      debug_elf_(debug_elf) {}

void AssemblyImageWriter::Finalize() {
#if defined(DART_PRECOMPILER)
  if (assembly_dwarf_ != nullptr) {
    DwarfAssemblyStream dwarf_stream(&assembly_stream_);
    dwarf_stream.AbbreviationsPrologue();
    assembly_dwarf_->WriteAbbreviations(&dwarf_stream);
    dwarf_stream.DebugInfoPrologue();
    assembly_dwarf_->WriteDebugInfo(&dwarf_stream);
    dwarf_stream.LineNumberProgramPrologue();
    assembly_dwarf_->WriteLineNumberProgram(&dwarf_stream);
  }
  if (debug_elf_ != nullptr) {
    debug_elf_->Finalize();
  }
#endif
}

#if !defined(DART_PRECOMPILED_RUNTIME)
static void EnsureAssemblerIdentifier(char* label) {
  for (char c = *label; c != '\0'; c = *++label) {
    if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) ||
        ((c >= '0') && (c <= '9'))) {
      continue;
    }
    *label = '_';
  }
}
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

const char* SnapshotTextObjectNamer::SnapshotNameFor(intptr_t code_index,
                                                     const Code& code) {
  ASSERT(!code.IsNull());
  const char* prefix = FLAG_precompiled_mode ? "Precompiled_" : "";
  owner_ = code.owner();
  if (owner_.IsNull()) {
    insns_ = code.instructions();
    const char* name = StubCode::NameOfStub(insns_.EntryPoint());
    ASSERT(name != nullptr);
    return OS::SCreate(zone_, "%sStub_%s", prefix, name);
  }
  // The weak reference to the Code's owner should never have been removed via
  // an intermediate serialization, since WSRs are only introduced during
  // precompilation.
  owner_ = WeakSerializationReference::Unwrap(owner_);
  ASSERT(!owner_.IsNull());
  if (owner_.IsClass()) {
    string_ = Class::Cast(owner_).Name();
    const char* name = string_.ToCString();
    EnsureAssemblerIdentifier(const_cast<char*>(name));
    return OS::SCreate(zone_, "%sAllocationStub_%s_%" Pd, prefix, name,
                       code_index);
  } else if (owner_.IsAbstractType()) {
    const char* name = namer_.StubNameForType(AbstractType::Cast(owner_));
    return OS::SCreate(zone_, "%s%s_%" Pd, prefix, name, code_index);
  } else if (owner_.IsFunction()) {
    const char* name = Function::Cast(owner_).ToQualifiedCString();
    EnsureAssemblerIdentifier(const_cast<char*>(name));
    return OS::SCreate(zone_, "%s%s_%" Pd, prefix, name, code_index);
  } else {
    UNREACHABLE();
  }
}

const char* SnapshotTextObjectNamer::SnapshotNameFor(
    intptr_t index,
    const ImageWriter::InstructionsData& data) {
  if (data.trampoline_bytes != nullptr) {
    return OS::SCreate(zone_, "Trampoline_%" Pd "", index);
  }
  return SnapshotNameFor(index, *data.code_);
}

void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
#if defined(DART_PRECOMPILED_RUNTIME)
  UNREACHABLE();
#else
  Zone* zone = Thread::Current()->zone();

  const bool bare_instruction_payloads =
      FLAG_precompiled_mode && FLAG_use_bare_instructions;

#if defined(DART_PRECOMPILER)
  const char* bss_symbol =
      vm ? "_kDartVmSnapshotBss" : "_kDartIsolateSnapshotBss";
  intptr_t debug_segment_base = 0;
  if (debug_elf_ != nullptr) {
    debug_segment_base = debug_elf_->NextMemoryOffset();
  }
#endif

  const char* instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
                                       : kIsolateSnapshotInstructionsAsmSymbol;
  assembly_stream_.Print(".text\n");
  assembly_stream_.Print(".globl %s\n", instructions_symbol);

  // Start snapshot at page boundary.
  ASSERT(VirtualMemory::PageSize() >= kMaxObjectAlignment);
  ASSERT(VirtualMemory::PageSize() >= Image::kBssAlignment);
  Align(VirtualMemory::PageSize());
  assembly_stream_.Print("%s:\n", instructions_symbol);

  intptr_t text_offset = 0;
#if defined(DART_PRECOMPILER)
  // Parent used for later profile objects. Starts off as the Image. When
  // writing bare instructions payloads, this is later updated with the
  // InstructionsSection object which contains all the bare payloads.
  V8SnapshotProfileWriter::ObjectId parent_id(offset_space_, text_offset);
#endif

  // This head also provides the gap to make the instructions snapshot
  // look like a OldPage.
  const intptr_t image_size = Utils::RoundUp(
      next_text_offset_, compiler::target::ObjectAlignment::kObjectAlignment);
  text_offset += WriteWordLiteralText(image_size);

#if defined(DART_PRECOMPILER)
  assembly_stream_.Print("%s %s - %s\n", kLiteralPrefix, bss_symbol,
                         instructions_symbol);
  text_offset += compiler::target::kWordSize;
#else
  text_offset += WriteWordLiteralText(0);  // No relocations.
#endif

  text_offset += Align(kMaxObjectAlignment, text_offset);
  ASSERT_EQUAL(text_offset, Image::kHeaderSize);
#if defined(DART_PRECOMPILER)
  if (profile_writer_ != nullptr) {
    profile_writer_->SetObjectTypeAndName(parent_id, "Image",
                                          instructions_symbol);
    // Assign post-instruction padding to the Image, unless we're writing bare
    // instruction payloads, in which case we'll assign it to the
    // InstructionsSection object.
    const intptr_t padding =
        bare_instruction_payloads ? 0 : image_size - next_text_offset_;
    profile_writer_->AttributeBytesTo(parent_id, Image::kHeaderSize + padding);
    profile_writer_->AddRoot(parent_id);
  }
#endif

  if (bare_instruction_payloads) {
#if defined(DART_PRECOMPILER)
    if (profile_writer_ != nullptr) {
      const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
      profile_writer_->SetObjectTypeAndName(id, instructions_section_type_,
                                            instructions_symbol);
      const intptr_t padding = image_size - next_text_offset_;
      profile_writer_->AttributeBytesTo(
          id, compiler::target::InstructionsSection::HeaderSize() + padding);
      const intptr_t element_offset = id.second - parent_id.second;
      profile_writer_->AttributeReferenceTo(
          parent_id,
          {id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
      // Later objects will have the InstructionsSection as a parent.
      parent_id = id;
    }
#endif
    const intptr_t section_size = image_size - text_offset;
    // Add the RawInstructionsSection header.
    const compiler::target::uword marked_tags =
        ObjectLayout::OldBit::encode(true) |
        ObjectLayout::OldAndNotMarkedBit::encode(false) |
        ObjectLayout::OldAndNotRememberedBit::encode(true) |
        ObjectLayout::NewBit::encode(false) |
        ObjectLayout::SizeTag::encode(AdjustObjectSizeForTarget(section_size)) |
        ObjectLayout::ClassIdTag::encode(kInstructionsSectionCid);
    text_offset += WriteWordLiteralText(marked_tags);
    // Calculated using next_text_offset_, which doesn't include post-payload
    // padding to object alignment.
    const intptr_t instructions_length =
        next_text_offset_ - (text_offset + compiler::target::kWordSize);
    text_offset += WriteWordLiteralText(instructions_length);
  }

  FrameUnwindPrologue();

  PcDescriptors& descriptors = PcDescriptors::Handle(zone);
  SnapshotTextObjectNamer namer(zone);

  ASSERT(offset_space_ != V8SnapshotProfileWriter::kSnapshot);
  for (intptr_t i = 0; i < instructions_.length(); i++) {
    auto& data = instructions_[i];
    const bool is_trampoline = data.trampoline_bytes != nullptr;
    ASSERT_EQUAL(data.text_offset_, text_offset);

    intptr_t dwarf_index = i;
#if defined(DART_PRECOMPILER)
    if (!is_trampoline && assembly_dwarf_ != nullptr) {
      dwarf_index =
          assembly_dwarf_->AddCode(*data.code_, SegmentRelativeOffset(vm));
    }
#endif

    const auto object_name = namer.SnapshotNameFor(dwarf_index, data);

#if defined(DART_PRECOMPILER)
    if (profile_writer_ != nullptr) {
      const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
      auto const type = is_trampoline ? trampoline_type_ : instructions_type_;
      const intptr_t size = is_trampoline ? data.trampoline_length
                                          : SizeInSnapshot(data.insns_->raw());
      profile_writer_->SetObjectTypeAndName(id, type, object_name);
      profile_writer_->AttributeBytesTo(id, size);
      const intptr_t element_offset = id.second - parent_id.second;
      profile_writer_->AttributeReferenceTo(
          parent_id,
          {id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
    }
#endif

    if (is_trampoline) {
      const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
      const auto end = start + data.trampoline_length;
      text_offset += WriteByteSequence(start, end);
      delete[] data.trampoline_bytes;
      data.trampoline_bytes = nullptr;
      continue;
    }

    const intptr_t instr_start = text_offset;

    const auto& code = *data.code_;
    const auto& insns = *data.insns_;
    descriptors = code.pc_descriptors();

    const uword payload_start = insns.PayloadStart();

    // 1. Write from the object start to the payload start. This includes the
    // object header and the fixed fields.  Not written for AOT snapshots using
    // bare instructions.
    if (!bare_instruction_payloads) {
      NoSafepointScope no_safepoint;

      // Write Instructions with the mark and read-only bits set.
      uword marked_tags = insns.raw_ptr()->tags_;
      marked_tags = ObjectLayout::OldBit::update(true, marked_tags);
      marked_tags =
          ObjectLayout::OldAndNotMarkedBit::update(false, marked_tags);
      marked_tags =
          ObjectLayout::OldAndNotRememberedBit::update(true, marked_tags);
      marked_tags = ObjectLayout::NewBit::update(false, marked_tags);
#if defined(HASH_IN_OBJECT_HEADER)
      // Can't use GetObjectTagsAndHash because the update methods discard the
      // high bits.
      marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32;
#endif

#if defined(IS_SIMARM_X64)
      const intptr_t size_in_bytes = InstructionsSizeInSnapshot(insns.raw());
      marked_tags = UpdateObjectSizeForTarget(size_in_bytes, marked_tags);
      WriteWordLiteralText(marked_tags);
      text_offset += sizeof(compiler::target::uword);
      WriteWordLiteralText(insns.raw_ptr()->size_and_flags_);
      text_offset += sizeof(compiler::target::uword);
#else   // defined(IS_SIMARM_X64)
      uword object_start = reinterpret_cast<uword>(insns.raw_ptr());
      WriteWordLiteralText(marked_tags);
      object_start += sizeof(uword);
      text_offset += sizeof(uword);
      text_offset += WriteByteSequence(object_start, payload_start);
#endif  // defined(IS_SIMARM_X64)

      ASSERT((text_offset - instr_start) ==
             compiler::target::Instructions::HeaderSize());
    }

#if defined(DART_PRECOMPILER)
    if (debug_elf_ != nullptr) {
      debug_elf_->dwarf()->AddCode(code, {vm, text_offset});
    }
#endif
    // 2. Write a label at the entry point.
    // Linux's perf uses these labels.
    assembly_stream_.Print("%s:\n", object_name);

    {
      // 3. Write from the payload start to payload end. For AOT snapshots
      // with bare instructions, this is the only part serialized.
      NoSafepointScope no_safepoint;
      assert(kBareInstructionsAlignment <=
             compiler::target::ObjectAlignment::kObjectAlignment);
      const auto payload_align = bare_instruction_payloads
                                     ? kBareInstructionsAlignment
                                     : sizeof(compiler::target::uword);
      const uword payload_size = Utils::RoundUp(insns.Size(), payload_align);
      const uword payload_end = payload_start + payload_size;

      ASSERT(Utils::IsAligned(text_offset, payload_align));

#if defined(DART_PRECOMPILER)
      PcDescriptors::Iterator iterator(descriptors,
                                       PcDescriptorsLayout::kBSSRelocation);
      uword next_reloc_offset = iterator.MoveNext() ? iterator.PcOffset() : -1;

      // We only generate BSS relocations that are word-sized and at
      // word-aligned offsets in the payload.
      auto const possible_relocations_end =
          Utils::RoundDown(payload_end, sizeof(compiler::target::uword));
      for (uword cursor = payload_start; cursor < possible_relocations_end;
           cursor += sizeof(compiler::target::uword)) {
        compiler::target::uword data =
            *reinterpret_cast<compiler::target::uword*>(cursor);
        if ((cursor - payload_start) == next_reloc_offset) {
          assembly_stream_.Print("%s %s - (.) + %" Pd "\n", kLiteralPrefix,
                                 bss_symbol, /*addend=*/data);
          text_offset += compiler::target::kWordSize;
          next_reloc_offset = iterator.MoveNext() ? iterator.PcOffset() : -1;
        } else {
          text_offset += WriteWordLiteralText(data);
        }
      }
      assert(next_reloc_offset != (possible_relocations_end - payload_start));
      text_offset += WriteByteSequence(possible_relocations_end, payload_end);
#else
      text_offset += WriteByteSequence(payload_start, payload_end);
#endif

      // 4. Write from the payload end to object end. Note we can't simply copy
      // from the object because the host object may have less alignment filler
      // than the target object in the cross-word case. Not written for AOT
      // snapshots using bare instructions.
      if (!bare_instruction_payloads) {
        uword unaligned_size =
            compiler::target::Instructions::HeaderSize() + payload_size;
        uword alignment_size =
            Utils::RoundUp(
                unaligned_size,
                compiler::target::ObjectAlignment::kObjectAlignment) -
            unaligned_size;
        while (alignment_size > 0) {
          text_offset += WriteWordLiteralText(kBreakInstructionFiller);
          alignment_size -= sizeof(compiler::target::uword);
        }

        ASSERT(kWordSize != compiler::target::kWordSize ||
               (text_offset - instr_start) == insns.raw()->ptr()->HeapSize());
      }
    }

    ASSERT((text_offset - instr_start) == SizeInSnapshot(insns.raw()));
  }

  // Should be a no-op unless writing bare instruction payloads, in which case
  // we need to add post-payload padding to the object alignment. The alignment
  // needs to match the one we used for image_size above.
  text_offset +=
      Align(compiler::target::ObjectAlignment::kObjectAlignment, text_offset);

  ASSERT_EQUAL(text_offset, image_size);

  FrameUnwindEpilogue();

#if defined(DART_PRECOMPILER)
  if (debug_elf_ != nullptr) {
    // We need to generate a text segment of the appropriate size in the ELF
    // for two reasons:
    //
    // * We need unique virtual addresses for each text section in the DWARF
    //   file and that the virtual addresses for payloads within those sections
    //   do not overlap.
    //
    // * Our tools for converting DWARF stack traces back to "normal" Dart
    //   stack traces calculate an offset into the appropriate instructions
    //   section, and then add that offset to the virtual address of the
    //   corresponding segment to get the virtual address for the frame.
    //
    // Since we don't want to add the actual contents of the segment in the
    // separate debugging information, we pass nullptr for the bytes, which
    // creates an appropriate NOBITS section instead of PROGBITS.
    auto const debug_segment_base2 = debug_elf_->AddText(
        instructions_symbol, /*bytes=*/nullptr, text_offset);
    // Double-check that no other ELF sections were added in the middle of
    // writing the text section.
    ASSERT(debug_segment_base2 == debug_segment_base);
  }

  assembly_stream_.Print(".bss\n");
  // Align the BSS contents as expected by the Image class.
  Align(Image::kBssAlignment);
  assembly_stream_.Print("%s:\n", bss_symbol);

  auto const entry_count = vm ? BSS::kVmEntryCount : BSS::kIsolateEntryCount;
  for (intptr_t i = 0; i < entry_count; i++) {
    WriteWordLiteralText(0);
  }
#endif

#if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                  \
    defined(TARGET_OS_FUCHSIA)
  assembly_stream_.Print(".section .rodata\n");
#elif defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
  assembly_stream_.Print(".const\n");
#else
  UNIMPLEMENTED();
#endif

  const char* data_symbol =
      vm ? kVmSnapshotDataAsmSymbol : kIsolateSnapshotDataAsmSymbol;
  assembly_stream_.Print(".globl %s\n", data_symbol);
  Align(kMaxObjectAlignment);
  assembly_stream_.Print("%s:\n", data_symbol);
  const uword buffer = reinterpret_cast<uword>(clustered_stream->buffer());
  const intptr_t length = clustered_stream->bytes_written();
  WriteByteSequence(buffer, buffer + length);
#if defined(DART_PRECOMPILER)
  if (debug_elf_ != nullptr) {
    // Add a NoBits section for the ROData as well.
    debug_elf_->AddROData(data_symbol, clustered_stream->buffer(), length);
  }
#endif  // defined(DART_PRECOMPILER)
#endif  // !defined(DART_PRECOMPILED_RUNTIME)
}

void AssemblyImageWriter::FrameUnwindPrologue() {
  // Creates DWARF's .debug_frame
  // CFI = Call frame information
  // CFA = Canonical frame address
  assembly_stream_.Print(".cfi_startproc\n");

#if defined(TARGET_ARCH_X64)
  assembly_stream_.Print(".cfi_def_cfa rbp, 0\n");  // CFA is fp+0
  assembly_stream_.Print(".cfi_offset rbp, 0\n");   // saved fp is *(CFA+0)
  assembly_stream_.Print(".cfi_offset rip, 8\n");   // saved pc is *(CFA+8)
  // saved sp is CFA+16
  // Should be ".cfi_value_offset rsp, 16", but requires gcc newer than late
  // 2016 and not supported by Android's libunwind.
  // DW_CFA_expression          0x10
  // uleb128 register (rsp)        7   (DWARF register number)
  // uleb128 size of operation     2
  // DW_OP_plus_uconst          0x23
  // uleb128 addend               16
  assembly_stream_.Print(".cfi_escape 0x10, 31, 2, 0x23, 16\n");

#elif defined(TARGET_ARCH_ARM64)
  COMPILE_ASSERT(FP == R29);
  COMPILE_ASSERT(LR == R30);
  assembly_stream_.Print(".cfi_def_cfa x29, 0\n");  // CFA is fp+0
  assembly_stream_.Print(".cfi_offset x29, 0\n");   // saved fp is *(CFA+0)
  assembly_stream_.Print(".cfi_offset x30, 8\n");   // saved pc is *(CFA+8)
  // saved sp is CFA+16
  // Should be ".cfi_value_offset sp, 16", but requires gcc newer than late
  // 2016 and not supported by Android's libunwind.
  // DW_CFA_expression          0x10
  // uleb128 register (x31)       31
  // uleb128 size of operation     2
  // DW_OP_plus_uconst          0x23
  // uleb128 addend               16
  assembly_stream_.Print(".cfi_escape 0x10, 31, 2, 0x23, 16\n");

#elif defined(TARGET_ARCH_ARM)
#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
  COMPILE_ASSERT(FP == R7);
  assembly_stream_.Print(".cfi_def_cfa r7, 0\n");  // CFA is fp+j0
  assembly_stream_.Print(".cfi_offset r7, 0\n");   // saved fp is *(CFA+0)
#else
  COMPILE_ASSERT(FP == R11);
  assembly_stream_.Print(".cfi_def_cfa r11, 0\n");  // CFA is fp+0
  assembly_stream_.Print(".cfi_offset r11, 0\n");   // saved fp is *(CFA+0)
#endif
  assembly_stream_.Print(".cfi_offset lr, 4\n");   // saved pc is *(CFA+4)
  // saved sp is CFA+8
  // Should be ".cfi_value_offset sp, 8", but requires gcc newer than late
  // 2016 and not supported by Android's libunwind.
  // DW_CFA_expression          0x10
  // uleb128 register (sp)        13
  // uleb128 size of operation     2
  // DW_OP_plus_uconst          0x23
  // uleb128 addend                8
  assembly_stream_.Print(".cfi_escape 0x10, 13, 2, 0x23, 8\n");

// libunwind on ARM may use .ARM.exidx instead of .debug_frame
#if !defined(TARGET_OS_MACOS) && !defined(TARGET_OS_MACOS_IOS)
  COMPILE_ASSERT(FP == R11);
  assembly_stream_.Print(".fnstart\n");
  assembly_stream_.Print(".save {r11, lr}\n");
  assembly_stream_.Print(".setfp r11, sp, #0\n");
#endif

#endif
}

void AssemblyImageWriter::FrameUnwindEpilogue() {
#if defined(TARGET_ARCH_ARM)
#if !defined(TARGET_OS_MACOS) && !defined(TARGET_OS_MACOS_IOS)
  assembly_stream_.Print(".fnend\n");
#endif
#endif
  assembly_stream_.Print(".cfi_endproc\n");
}

intptr_t AssemblyImageWriter::WriteByteSequence(uword start, uword end) {
  assert(end >= start);
  auto const end_of_words =
      Utils::RoundDown(end, sizeof(compiler::target::uword));
  for (auto cursor = reinterpret_cast<compiler::target::uword*>(start);
       cursor < reinterpret_cast<compiler::target::uword*>(end_of_words);
       cursor++) {
    WriteWordLiteralText(*cursor);
  }
  if (end != end_of_words) {
    auto start_of_rest = reinterpret_cast<const uint8_t*>(end_of_words);
    assembly_stream_.Print(".byte ");
    for (auto cursor = start_of_rest;
         cursor < reinterpret_cast<const uint8_t*>(end); cursor++) {
      if (cursor != start_of_rest) assembly_stream_.Print(", ");
      assembly_stream_.Print("0x%0.2" Px "", *cursor);
    }
    assembly_stream_.Print("\n");
  }
  return end - start;
}

intptr_t AssemblyImageWriter::Align(intptr_t alignment, uword position) {
  const uword next_position = Utils::RoundUp(position, alignment);
  assembly_stream_.Print(".balign %" Pd ", 0\n", alignment);
  return next_position - position;
}

BlobImageWriter::BlobImageWriter(Thread* thread,
                                 uint8_t** instructions_blob_buffer,
                                 ReAlloc alloc,
                                 intptr_t initial_size,
                                 Elf* debug_elf,
                                 Elf* elf)
    : ImageWriter(thread),
      instructions_blob_stream_(instructions_blob_buffer, alloc, initial_size),
      elf_(elf),
      debug_elf_(debug_elf) {
#if defined(DART_PRECOMPILER)
  ASSERT(debug_elf_ == nullptr || debug_elf_->dwarf() != nullptr);
#else
  RELEASE_ASSERT(elf_ == nullptr);
#endif
}

intptr_t BlobImageWriter::WriteByteSequence(uword start, uword end) {
  const uword size = end - start;
  instructions_blob_stream_.WriteBytes(reinterpret_cast<const void*>(start),
                                       size);
  return size;
}

void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
  const bool bare_instruction_payloads =
      FLAG_precompiled_mode && FLAG_use_bare_instructions;
  auto const zone = Thread::Current()->zone();

#if defined(DART_PRECOMPILER)
  auto const instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
                                      : kIsolateSnapshotInstructionsAsmSymbol;
  intptr_t segment_base = 0;
  if (elf_ != nullptr) {
    segment_base = elf_->NextMemoryOffset();
  }
  intptr_t debug_segment_base = 0;
  if (debug_elf_ != nullptr) {
    debug_segment_base = debug_elf_->NextMemoryOffset();
    // If we're also generating an ELF snapshot, we want the virtual addresses
    // in it and the separately saved DWARF information to match.
    ASSERT(elf_ == nullptr || segment_base == debug_segment_base);
  }
#endif

  intptr_t text_offset = 0;
#if defined(DART_PRECOMPILER)
  // Parent used for later profile objects. Starts off as the Image. When
  // writing bare instructions payloads, this is later updated with the
  // InstructionsSection object which contains all the bare payloads.
  V8SnapshotProfileWriter::ObjectId parent_id(offset_space_, text_offset);
#endif

  // This header provides the gap to make the instructions snapshot look like a
  // OldPage.
  const intptr_t image_size = Utils::RoundUp(
      next_text_offset_, compiler::target::ObjectAlignment::kObjectAlignment);
  instructions_blob_stream_.WriteTargetWord(image_size);
#if defined(DART_PRECOMPILER)
  // Store the offset of the BSS section from the instructions section here.
  // If not compiling to ELF (and thus no BSS segment), write 0.
  const word bss_offset =
      elf_ != nullptr ? elf_->BssStart(vm) - segment_base : 0;
  ASSERT_EQUAL(Utils::RoundDown(bss_offset, Image::kBssAlignment), bss_offset);
  // Set the lowest bit if we are compiling to ELF.
  const word compiled_to_elf = elf_ != nullptr ? 0x1 : 0x0;
  instructions_blob_stream_.WriteTargetWord(bss_offset | compiled_to_elf);
#else
  instructions_blob_stream_.WriteTargetWord(0);  // No relocations.
#endif
  instructions_blob_stream_.Align(kMaxObjectAlignment);
  ASSERT_EQUAL(instructions_blob_stream_.Position(), Image::kHeaderSize);
  text_offset += Image::kHeaderSize;
#if defined(DART_PRECOMPILER)
  if (profile_writer_ != nullptr) {
    profile_writer_->SetObjectTypeAndName(parent_id, "Image",
                                          instructions_symbol);
    // Assign post-instruction padding to the Image, unless we're writing bare
    // instruction payloads, in which case we'll assign it to the
    // InstructionsSection object.
    const intptr_t padding =
        bare_instruction_payloads ? 0 : image_size - next_text_offset_;
    profile_writer_->AttributeBytesTo(parent_id, Image::kHeaderSize + padding);
    profile_writer_->AddRoot(parent_id);
  }
#endif

  if (bare_instruction_payloads) {
#if defined(DART_PRECOMPILER)
    if (profile_writer_ != nullptr) {
      const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
      profile_writer_->SetObjectTypeAndName(id, instructions_section_type_,
                                            instructions_symbol);
      const intptr_t padding = image_size - next_text_offset_;
      profile_writer_->AttributeBytesTo(
          id, compiler::target::InstructionsSection::HeaderSize() + padding);
      const intptr_t element_offset = id.second - parent_id.second;
      profile_writer_->AttributeReferenceTo(
          parent_id,
          {id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
      // Later objects will have the InstructionsSection as a parent.
      parent_id = id;
    }
#endif
    const intptr_t section_size = image_size - Image::kHeaderSize;
    // Add the RawInstructionsSection header.
    const compiler::target::uword marked_tags =
        ObjectLayout::OldBit::encode(true) |
        ObjectLayout::OldAndNotMarkedBit::encode(false) |
        ObjectLayout::OldAndNotRememberedBit::encode(true) |
        ObjectLayout::NewBit::encode(false) |
        ObjectLayout::SizeTag::encode(AdjustObjectSizeForTarget(section_size)) |
        ObjectLayout::ClassIdTag::encode(kInstructionsSectionCid);
    instructions_blob_stream_.WriteTargetWord(marked_tags);
    // Uses next_text_offset_ to avoid any post-payload padding.
    const intptr_t instructions_length =
        next_text_offset_ - Image::kHeaderSize -
        compiler::target::InstructionsSection::HeaderSize();
    instructions_blob_stream_.WriteTargetWord(instructions_length);
    ASSERT_EQUAL(instructions_blob_stream_.Position() - text_offset,
                 compiler::target::InstructionsSection::HeaderSize());
    text_offset += compiler::target::InstructionsSection::HeaderSize();
  }

  ASSERT_EQUAL(text_offset, instructions_blob_stream_.Position());

#if defined(DART_PRECOMPILER)
  auto& descriptors = PcDescriptors::Handle(zone);
#endif
  SnapshotTextObjectNamer namer(zone);

  NoSafepointScope no_safepoint;
  for (intptr_t i = 0; i < instructions_.length(); i++) {
    auto& data = instructions_[i];
    const bool is_trampoline = data.trampoline_bytes != nullptr;
    ASSERT(data.text_offset_ == text_offset);

#if defined(DART_PRECOMPILER)
    const auto object_name = namer.SnapshotNameFor(i, data);
    if (profile_writer_ != nullptr) {
      const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
      auto const type = is_trampoline ? trampoline_type_ : instructions_type_;
      const intptr_t size = is_trampoline ? data.trampoline_length
                                          : SizeInSnapshot(data.insns_->raw());
      profile_writer_->SetObjectTypeAndName(id, type, object_name);
      profile_writer_->AttributeBytesTo(id, size);
      // If the object is wrapped in an InstructionSection, then add an
      // element reference.
      const intptr_t element_offset = id.second - parent_id.second;
      profile_writer_->AttributeReferenceTo(
          parent_id,
          {id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
    }
#endif

    if (is_trampoline) {
      const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
      const auto end = start + data.trampoline_length;
      text_offset += WriteByteSequence(start, end);
      delete[] data.trampoline_bytes;
      data.trampoline_bytes = nullptr;
      continue;
    }

    const intptr_t instr_start = text_offset;

    const auto& insns = *data.insns_;
    const uword payload_start = insns.PayloadStart();

    ASSERT(Utils::IsAligned(payload_start, sizeof(compiler::target::uword)));

    // Write Instructions with the mark and read-only bits set.
    uword marked_tags = insns.raw_ptr()->tags_;
    marked_tags = ObjectLayout::OldBit::update(true, marked_tags);
    marked_tags = ObjectLayout::OldAndNotMarkedBit::update(false, marked_tags);
    marked_tags =
        ObjectLayout::OldAndNotRememberedBit::update(true, marked_tags);
    marked_tags = ObjectLayout::NewBit::update(false, marked_tags);
#if defined(HASH_IN_OBJECT_HEADER)
    // Can't use GetObjectTagsAndHash because the update methods discard the
    // high bits.
    marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32;
#endif

#if defined(IS_SIMARM_X64)
    const intptr_t start_offset = instructions_blob_stream_.bytes_written();

    if (!bare_instruction_payloads) {
      const intptr_t size_in_bytes = InstructionsSizeInSnapshot(insns.raw());
      marked_tags = UpdateObjectSizeForTarget(size_in_bytes, marked_tags);
      instructions_blob_stream_.WriteTargetWord(marked_tags);
      instructions_blob_stream_.WriteFixed<uint32_t>(
          insns.raw_ptr()->size_and_flags_);
    } else {
      ASSERT(Utils::IsAligned(instructions_blob_stream_.Position(),
                              kBareInstructionsAlignment));
    }
    const intptr_t payload_offset = instructions_blob_stream_.Position();
    instructions_blob_stream_.WriteBytes(
        reinterpret_cast<const void*>(insns.PayloadStart()), insns.Size());
    const intptr_t alignment =
        bare_instruction_payloads
            ? kBareInstructionsAlignment
            : compiler::target::ObjectAlignment::kObjectAlignment;
    instructions_blob_stream_.Align(alignment);
    const intptr_t end_offset = instructions_blob_stream_.bytes_written();
    text_offset += (end_offset - start_offset);
#else   // defined(IS_SIMARM_X64)
    // Only payload is output in AOT snapshots.
    const uword header_size =
        bare_instruction_payloads
            ? 0
            : compiler::target::Instructions::HeaderSize();
    const uword payload_size = SizeInSnapshot(insns.raw()) - header_size;
    const uword object_end = payload_start + payload_size;
    if (!bare_instruction_payloads) {
      uword object_start = reinterpret_cast<uword>(insns.raw_ptr());
      instructions_blob_stream_.WriteWord(marked_tags);
      text_offset += sizeof(uword);
      object_start += sizeof(uword);
      text_offset += WriteByteSequence(object_start, payload_start);
    } else {
      ASSERT(Utils::IsAligned(instructions_blob_stream_.Position(),
                              kBareInstructionsAlignment));
    }
    const intptr_t payload_offset = instructions_blob_stream_.Position();
    text_offset += WriteByteSequence(payload_start, object_end);
#endif

#if defined(DART_PRECOMPILER)
    const auto& code = *data.code_;
    if (elf_ != nullptr && elf_->dwarf() != nullptr) {
      elf_->dwarf()->AddCode(code, {vm, payload_offset});
    }
    if (debug_elf_ != nullptr) {
      debug_elf_->dwarf()->AddCode(code, {vm, payload_offset});
    }

    // Don't patch the relocation if we're not generating ELF. The regular blobs
    // format does not yet support these relocations. Use
    // Code::VerifyBSSRelocations to check whether the relocations are patched
    // or not after loading.
    if (elf_ != nullptr) {
      const intptr_t current_stream_position =
          instructions_blob_stream_.Position();

      descriptors = code.pc_descriptors();

      PcDescriptors::Iterator iterator(
          descriptors, /*kind_mask=*/PcDescriptorsLayout::kBSSRelocation);

      while (iterator.MoveNext()) {
        const intptr_t reloc_offset = iterator.PcOffset();

        // The instruction stream at the relocation position holds an offset
        // into BSS corresponding to the symbol being resolved. This addend is
        // factored into the relocation.
        const auto addend = *reinterpret_cast<compiler::target::word*>(
            insns.PayloadStart() + reloc_offset);

        // Overwrite the relocation position in the instruction stream with the
        // offset of the BSS segment from the relocation position plus the
        // addend in the relocation.
        auto const reloc_pos = payload_offset + reloc_offset;
        instructions_blob_stream_.SetPosition(reloc_pos);

        const compiler::target::word offset = bss_offset - reloc_pos + addend;
        instructions_blob_stream_.WriteTargetWord(offset);
      }

      // Restore stream position after the relocation was patched.
      instructions_blob_stream_.SetPosition(current_stream_position);
    }
#else
    USE(payload_offset);
#endif

    ASSERT((text_offset - instr_start) ==
           ImageWriter::SizeInSnapshot(insns.raw()));
  }

  // Should be a no-op unless writing bare instruction payloads, in which case
  // we need to add post-payload padding to the object alignment. The alignment
  // should match the alignment used in image_size above.
  instructions_blob_stream_.Align(
      compiler::target::ObjectAlignment::kObjectAlignment);
  text_offset = Utils::RoundUp(
      text_offset, compiler::target::ObjectAlignment::kObjectAlignment);

  ASSERT_EQUAL(text_offset, instructions_blob_stream_.bytes_written());
  ASSERT_EQUAL(text_offset, image_size);

#ifdef DART_PRECOMPILER
  auto const data_symbol =
      vm ? kVmSnapshotDataAsmSymbol : kIsolateSnapshotDataAsmSymbol;
  if (elf_ != nullptr) {
    auto const segment_base2 =
        elf_->AddText(instructions_symbol, instructions_blob_stream_.buffer(),
                      instructions_blob_stream_.bytes_written());
    ASSERT_EQUAL(segment_base2, segment_base);
    // Write the .rodata section here like the AssemblyImageWriter.
    elf_->AddROData(data_symbol, clustered_stream->buffer(),
                    clustered_stream->bytes_written());
  }
  if (debug_elf_ != nullptr) {
    // To keep memory addresses consistent, we create elf::SHT_NOBITS sections
    // in the debugging information. We still pass along the buffers because
    // we'll need the buffer bytes at generation time to calculate the build ID
    // so it'll match the one in the snapshot.
    auto const debug_segment_base2 = debug_elf_->AddText(
        instructions_symbol, instructions_blob_stream_.buffer(),
        instructions_blob_stream_.bytes_written());
    ASSERT_EQUAL(debug_segment_base2, debug_segment_base);
    debug_elf_->AddROData(data_symbol, clustered_stream->buffer(),
                          clustered_stream->bytes_written());
  }
#endif
}
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

ImageReader::ImageReader(const uint8_t* data_image,
                         const uint8_t* instructions_image)
    : data_image_(data_image), instructions_image_(instructions_image) {
  ASSERT(data_image != NULL);
  ASSERT(instructions_image != NULL);
}

ApiErrorPtr ImageReader::VerifyAlignment() const {
  if (!Utils::IsAligned(data_image_, kObjectAlignment) ||
      !Utils::IsAligned(instructions_image_, kMaxObjectAlignment)) {
    return ApiError::New(
        String::Handle(String::New("Snapshot is misaligned", Heap::kOld)),
        Heap::kOld);
  }
  return ApiError::null();
}

#if defined(DART_PRECOMPILED_RUNTIME)
uword ImageReader::GetBareInstructionsAt(uint32_t offset) const {
  ASSERT(Utils::IsAligned(offset, ImageWriter::kBareInstructionsAlignment));
  return reinterpret_cast<uword>(instructions_image_) + offset;
}

uword ImageReader::GetBareInstructionsEnd() const {
  Image image(instructions_image_);
  return reinterpret_cast<uword>(image.object_start()) + image.object_size();
}
#endif

InstructionsPtr ImageReader::GetInstructionsAt(uint32_t offset) const {
  ASSERT(Utils::IsAligned(offset, kObjectAlignment));

  ObjectPtr result = ObjectLayout::FromAddr(
      reinterpret_cast<uword>(instructions_image_) + offset);
  ASSERT(result->IsInstructions());
  ASSERT(result->ptr()->IsMarked());

  return Instructions::RawCast(result);
}

ObjectPtr ImageReader::GetObjectAt(uint32_t offset) const {
  ASSERT(Utils::IsAligned(offset, kObjectAlignment));

  ObjectPtr result =
      ObjectLayout::FromAddr(reinterpret_cast<uword>(data_image_) + offset);
  ASSERT(result->ptr()->IsMarked());

  return result;
}

}  // namespace dart
