| Index: runtime/vm/snapshot.cc
|
| diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
|
| index de11ff71d8e61109e1206df95016f2bc8440411e..cb9dfde5778a5b8fd62413cb0c0d9ad33d04f408 100644
|
| --- a/runtime/vm/snapshot.cc
|
| +++ b/runtime/vm/snapshot.cc
|
| @@ -709,21 +709,7 @@ int32_t InstructionsWriter::GetObjectOffsetFor(RawObject* raw_object) {
|
| }
|
|
|
|
|
| -static void EnsureIdentifier(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 = '_';
|
| - }
|
| -}
|
| -
|
| -
|
| -void AssemblyInstructionsWriter::Write(uint8_t* vmisolate_buffer,
|
| - intptr_t vmisolate_length,
|
| - uint8_t* isolate_buffer,
|
| - intptr_t isolate_length) {
|
| +void InstructionsWriter::Write(WriteStream* clustered_stream, bool vm) {
|
| Thread* thread = Thread::Current();
|
| Zone* zone = thread->zone();
|
| NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
|
| @@ -742,12 +728,68 @@ void AssemblyInstructionsWriter::Write(uint8_t* vmisolate_buffer,
|
| data.obj_ = &Object::Handle(zone, data.raw_obj_);
|
| }
|
|
|
| + // Append the direct-mapped RO data objects after the clustered snapshot.
|
| + WriteROData(clustered_stream);
|
| +
|
| + WriteText(clustered_stream, vm);
|
| +}
|
| +
|
| +
|
| +void InstructionsWriter::WriteROData(WriteStream* stream) {
|
| + stream->Align(OS::kMaxPreferredCodeAlignment);
|
| +
|
| + // Heap page starts here.
|
| +
|
| + stream->WriteWord(next_object_offset_); // Data length.
|
| + COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment);
|
| + stream->Align(OS::kMaxPreferredCodeAlignment);
|
| +
|
| + // Heap page objects start here.
|
| +
|
| + for (intptr_t i = 0; i < objects_.length(); i++) {
|
| + const Object& obj = *objects_[i].obj_;
|
| +
|
| + NoSafepointScope no_safepoint;
|
| + uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag;
|
| + uword end = start + obj.raw()->Size();
|
| +
|
| + // Write object header with the mark and VM heap bits set.
|
| + uword marked_tags = obj.raw()->ptr()->tags_;
|
| + marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags);
|
| + marked_tags = RawObject::MarkBit::update(true, marked_tags);
|
| + stream->WriteWord(marked_tags);
|
| + start += sizeof(uword);
|
| + for (uword* cursor = reinterpret_cast<uword*>(start);
|
| + cursor < reinterpret_cast<uword*>(end); cursor++) {
|
| + stream->WriteWord(*cursor);
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +static void EnsureIdentifier(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 = '_';
|
| + }
|
| +}
|
| +
|
| +
|
| +void AssemblyInstructionsWriter::WriteText(WriteStream* clustered_stream,
|
| + bool vm) {
|
| + Zone* zone = Thread::Current()->zone();
|
| +
|
| + const char* instructions_symbol =
|
| + vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions";
|
| assembly_stream_.Print(".text\n");
|
| - assembly_stream_.Print(".globl _kInstructionsSnapshot\n");
|
| + assembly_stream_.Print(".globl %s\n", instructions_symbol);
|
| // Start snapshot at page boundary.
|
| ASSERT(VirtualMemory::PageSize() >= OS::kMaxPreferredCodeAlignment);
|
| assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
|
| - assembly_stream_.Print("_kInstructionsSnapshot:\n");
|
| + assembly_stream_.Print("%s:\n", instructions_symbol);
|
|
|
| // This head also provides the gap to make the instructions snapshot
|
| // look like a HeapPage.
|
| @@ -829,6 +871,8 @@ void AssemblyInstructionsWriter::Write(uint8_t* vmisolate_buffer,
|
| }
|
| }
|
| }
|
| +
|
| +
|
| #if defined(TARGET_OS_LINUX)
|
| assembly_stream_.Print(".section .rodata\n");
|
| #elif defined(TARGET_OS_MACOS)
|
| @@ -837,76 +881,24 @@ void AssemblyInstructionsWriter::Write(uint8_t* vmisolate_buffer,
|
| // Unsupported platform.
|
| UNREACHABLE();
|
| #endif
|
| - assembly_stream_.Print(".globl _kDataSnapshot\n");
|
| - // Start snapshot at page boundary.
|
| - assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
|
| - assembly_stream_.Print("_kDataSnapshot:\n");
|
| - WriteWordLiteralData(next_object_offset_); // Data length.
|
| - COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment);
|
| +
|
| + const char* data_symbol =
|
| + vm ? "_kDartVmSnapshotData" : "_kDartIsolateSnapshotData";
|
| + assembly_stream_.Print(".globl %s\n", data_symbol);
|
| assembly_stream_.Print(".balign %" Pd ", 0\n",
|
| OS::kMaxPreferredCodeAlignment);
|
| -
|
| - for (intptr_t i = 0; i < objects_.length(); i++) {
|
| - const Object& obj = *objects_[i].obj_;
|
| - assembly_stream_.Print("Precompiled_Obj_%d:\n", i);
|
| -
|
| - NoSafepointScope no_safepoint;
|
| - uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag;
|
| - uword end = start + obj.raw()->Size();
|
| -
|
| - // Write object header with the mark and VM heap bits set.
|
| - uword marked_tags = obj.raw()->ptr()->tags_;
|
| - marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags);
|
| - marked_tags = RawObject::MarkBit::update(true, marked_tags);
|
| - WriteWordLiteralData(marked_tags);
|
| - start += sizeof(uword);
|
| - for (uword* cursor = reinterpret_cast<uword*>(start);
|
| - cursor < reinterpret_cast<uword*>(end); cursor++) {
|
| - WriteWordLiteralData(*cursor);
|
| - }
|
| - }
|
| -
|
| -
|
| - assembly_stream_.Print(".globl _kVmIsolateSnapshot\n");
|
| - assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
|
| - assembly_stream_.Print("_kVmIsolateSnapshot:\n");
|
| - for (intptr_t i = 0; i < vmisolate_length; i++) {
|
| - assembly_stream_.Print(".byte %" Pd "\n", vmisolate_buffer[i]);
|
| - }
|
| -
|
| - assembly_stream_.Print(".globl _kIsolateSnapshot\n");
|
| - assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
|
| - assembly_stream_.Print("_kIsolateSnapshot:\n");
|
| - for (intptr_t i = 0; i < isolate_length; i++) {
|
| - assembly_stream_.Print(".byte %" Pd "\n", isolate_buffer[i]);
|
| + assembly_stream_.Print("%s:\n", data_symbol);
|
| + uint8_t* buffer = clustered_stream->buffer();
|
| + intptr_t length = clustered_stream->bytes_written();
|
| + for (intptr_t i = 0; i < length; i++) {
|
| + assembly_stream_.Print(".byte %" Pd "\n", buffer[i]);
|
| }
|
| }
|
|
|
|
|
| -void BlobInstructionsWriter::Write(uint8_t* vmisolate_buffer,
|
| - intptr_t vmisolate_len,
|
| - uint8_t* isolate_buffer,
|
| - intptr_t isolate_length) {
|
| - Thread* thread = Thread::Current();
|
| - Zone* zone = thread->zone();
|
| - NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
|
| - "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];
|
| - data.insns_ = &Instructions::Handle(zone, data.raw_insns_);
|
| - ASSERT(data.raw_code_ != NULL);
|
| - data.code_ = &Code::Handle(zone, data.raw_code_);
|
| - }
|
| - for (intptr_t i = 0; i < objects_.length(); i++) {
|
| - ObjectData& data = objects_[i];
|
| - data.obj_ = &Object::Handle(zone, data.raw_obj_);
|
| - }
|
| -
|
| - // This head also provides the gap to make the instructions snapshot
|
| - // look like a HeapPage.
|
| +void BlobInstructionsWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
| + // This header provides the gap to make the instructions snapshot look like a
|
| + // HeapPage.
|
| intptr_t instructions_length = next_offset_;
|
| instructions_blob_stream_.WriteWord(instructions_length);
|
| intptr_t header_words = InstructionsSnapshot::kHeaderSize / sizeof(uword);
|
| @@ -960,38 +952,18 @@ void BlobInstructionsWriter::Write(uint8_t* vmisolate_buffer,
|
| }
|
| }
|
| }
|
| -
|
| - rodata_blob_stream_.WriteWord(next_object_offset_); // Data length.
|
| - COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment);
|
| - while (!Utils::IsAligned(rodata_blob_stream_.bytes_written(),
|
| - OS::kMaxPreferredCodeAlignment)) {
|
| - rodata_blob_stream_.WriteWord(0);
|
| - }
|
| -
|
| - for (intptr_t i = 0; i < objects_.length(); i++) {
|
| - const Object& obj = *objects_[i].obj_;
|
| -
|
| - NoSafepointScope no_safepoint;
|
| - uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag;
|
| - uword end = start + obj.raw()->Size();
|
| -
|
| - // Write object header with the mark and VM heap bits set.
|
| - uword marked_tags = obj.raw()->ptr()->tags_;
|
| - marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags);
|
| - marked_tags = RawObject::MarkBit::update(true, marked_tags);
|
| - rodata_blob_stream_.WriteWord(marked_tags);
|
| - start += sizeof(uword);
|
| - for (uword* cursor = reinterpret_cast<uword*>(start);
|
| - cursor < reinterpret_cast<uword*>(end); cursor++) {
|
| - rodata_blob_stream_.WriteWord(*cursor);
|
| - }
|
| - }
|
| }
|
|
|
|
|
| -uword InstructionsReader::GetInstructionsAt(int32_t offset) {
|
| +RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset) {
|
| ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment()));
|
| - return reinterpret_cast<uword>(instructions_buffer_) + offset;
|
| +
|
| + RawInstructions* result = reinterpret_cast<RawInstructions*>(
|
| + reinterpret_cast<uword>(instructions_buffer_) + offset + kHeapObjectTag);
|
| + ASSERT(result->IsInstructions());
|
| + ASSERT(result->IsMarked());
|
| +
|
| + return result;
|
| }
|
|
|
|
|
|
|