Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(753)

Unified Diff: runtime/vm/snapshot.cc

Issue 1915853004: Option to output precompiled instructions as a blob for use with mmap instead of assembly for use i… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/snapshot.h ('k') | runtime/vm/snapshot_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/snapshot.cc
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 936acbd5364ae84662b610be2f9eda945e8f28fd..472979820c3a6a476c9da091ea1c137a7939b19c 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -1196,7 +1196,7 @@ static void EnsureIdentifier(char* label) {
}
-void InstructionsWriter::WriteAssembly() {
+void AssemblyInstructionsWriter::Write() {
Zone* zone = Thread::Current()->zone();
// Handlify collected raw pointers as building the names below
@@ -1212,12 +1212,12 @@ void InstructionsWriter::WriteAssembly() {
data.obj_ = &Object::Handle(zone, data.raw_obj_);
}
- stream_.Print(".text\n");
- stream_.Print(".globl _kInstructionsSnapshot\n");
+ assembly_stream_.Print(".text\n");
+ assembly_stream_.Print(".globl _kInstructionsSnapshot\n");
// Start snapshot at page boundary.
ASSERT(VirtualMemory::PageSize() >= OS::kMaxPreferredCodeAlignment);
- stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
- stream_.Print("_kInstructionsSnapshot:\n");
+ assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
+ assembly_stream_.Print("_kInstructionsSnapshot:\n");
// This head also provides the gap to make the instructions snapshot
// look like a HeapPage.
@@ -1241,16 +1241,17 @@ void InstructionsWriter::WriteAssembly() {
owner = code.owner();
if (owner.IsNull()) {
const char* name = StubCode::NameOfStub(insns.EntryPoint());
- stream_.Print("Precompiled_Stub_%s:\n", name);
+ assembly_stream_.Print("Precompiled_Stub_%s:\n", name);
} else if (owner.IsClass()) {
str = Class::Cast(owner).Name();
const char* name = str.ToCString();
EnsureIdentifier(const_cast<char*>(name));
- stream_.Print("Precompiled_AllocationStub_%s_%" Pd ":\n", name, i);
+ assembly_stream_.Print("Precompiled_AllocationStub_%s_%" Pd ":\n",
+ name, i);
} else if (owner.IsFunction()) {
const char* name = Function::Cast(owner).ToQualifiedCString();
EnsureIdentifier(const_cast<char*>(name));
- stream_.Print("Precompiled_%s_%" Pd ":\n", name, i);
+ assembly_stream_.Print("Precompiled_%s_%" Pd ":\n", name, i);
} else {
UNREACHABLE();
}
@@ -1276,24 +1277,25 @@ void InstructionsWriter::WriteAssembly() {
}
}
#if defined(TARGET_OS_LINUX)
- stream_.Print(".section .rodata\n");
+ assembly_stream_.Print(".section .rodata\n");
#elif defined(TARGET_OS_MACOS)
- stream_.Print(".const\n");
+ assembly_stream_.Print(".const\n");
#else
// Unsupported platform.
UNREACHABLE();
#endif
- stream_.Print(".globl _kDataSnapshot\n");
+ assembly_stream_.Print(".globl _kDataSnapshot\n");
// Start snapshot at page boundary.
- stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
- stream_.Print("_kDataSnapshot:\n");
+ assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
+ assembly_stream_.Print("_kDataSnapshot:\n");
WriteWordLiteral(next_object_offset_); // Data length.
COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment);
- stream_.Print(".balign %" Pd ", 0\n", OS::kMaxPreferredCodeAlignment);
+ assembly_stream_.Print(".balign %" Pd ", 0\n",
+ OS::kMaxPreferredCodeAlignment);
for (intptr_t i = 0; i < objects_.length(); i++) {
const Object& obj = *objects_[i].obj_;
- stream_.Print("Precompiled_Obj_%d:\n", i);
+ assembly_stream_.Print("Precompiled_Obj_%d:\n", i);
NoSafepointScope no_safepoint;
uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag;
@@ -1314,6 +1316,84 @@ void InstructionsWriter::WriteAssembly() {
}
+void BlobInstructionsWriter::Write() {
+ Zone* zone = Thread::Current()->zone();
+
+ // 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.
+ intptr_t instructions_length = next_offset_;
+ instructions_blob_stream_.WriteWord(instructions_length);
+ intptr_t header_words = InstructionsSnapshot::kHeaderSize / sizeof(uword);
+ for (intptr_t i = 1; i < header_words; i++) {
+ instructions_blob_stream_.WriteWord(0);
+ }
+
+ for (intptr_t i = 0; i < instructions_.length(); i++) {
+ const Instructions& insns = *instructions_[i].insns_;
+
+ {
+ // 2. Write from the entry point to the end.
+ NoSafepointScope no_safepoint;
+ uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag;
+ uword entry = beginning + Instructions::HeaderSize();
+ uword payload_size = insns.size();
+ payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment());
+ uword end = entry + payload_size;
+
+ ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t)));
+ ASSERT(Utils::IsAligned(entry, sizeof(uint64_t)));
+ ASSERT(Utils::IsAligned(end, sizeof(uint64_t)));
+
+ for (uword* cursor = reinterpret_cast<uword*>(entry);
+ cursor < reinterpret_cast<uword*>(end);
+ cursor++) {
+ instructions_blob_stream_.WriteWord(*cursor);
+ }
+ }
+ }
+
+ 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) {
ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment()));
return reinterpret_cast<uword>(instructions_buffer_) + offset;
@@ -1883,20 +1963,18 @@ class ScriptVisitor : public ObjectVisitor {
FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer,
uint8_t** isolate_snapshot_buffer,
- uint8_t** instructions_snapshot_buffer,
ReAlloc alloc,
+ InstructionsWriter* instructions_writer,
bool snapshot_code,
bool vm_isolate_is_symbolic)
: thread_(Thread::Current()),
vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer),
isolate_snapshot_buffer_(isolate_snapshot_buffer),
- instructions_snapshot_buffer_(instructions_snapshot_buffer),
alloc_(alloc),
vm_isolate_snapshot_size_(0),
isolate_snapshot_size_(0),
- instructions_snapshot_size_(0),
forward_list_(NULL),
- instructions_writer_(NULL),
+ instructions_writer_(instructions_writer),
scripts_(Array::Handle(zone())),
symbol_table_(Array::Handle(zone())),
snapshot_code_(snapshot_code),
@@ -1935,12 +2013,6 @@ FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer,
forward_list_ = new ForwardList(thread(), SnapshotWriter::FirstObjectId());
ASSERT(forward_list_ != NULL);
-
- if (instructions_snapshot_buffer != NULL) {
- instructions_writer_ = new InstructionsWriter(instructions_snapshot_buffer,
- alloc,
- kInitialSize);
- }
}
@@ -2059,8 +2131,7 @@ void FullSnapshotWriter::WriteFullSnapshot() {
}
WriteIsolateFullSnapshot();
if (snapshot_code_) {
- instructions_writer_->WriteAssembly();
- instructions_snapshot_size_ = instructions_writer_->BytesWritten();
+ instructions_writer_->Write();
OS::Print("VMIsolate(CodeSize): %" Pd "\n", VmIsolateSnapshotSize());
OS::Print("Isolate(CodeSize): %" Pd "\n", IsolateSnapshotSize());
@@ -2077,12 +2148,12 @@ void FullSnapshotWriter::WriteFullSnapshot() {
PrecompiledSnapshotWriter::PrecompiledSnapshotWriter(
uint8_t** vm_isolate_snapshot_buffer,
uint8_t** isolate_snapshot_buffer,
- uint8_t** instructions_snapshot_buffer,
- ReAlloc alloc)
+ ReAlloc alloc,
+ InstructionsWriter* instructions_writer)
: FullSnapshotWriter(vm_isolate_snapshot_buffer,
isolate_snapshot_buffer,
- instructions_snapshot_buffer,
alloc,
+ instructions_writer,
true, /* snapshot_code */
false /* vm_isolate_is_symbolic */) {
}
« no previous file with comments | « runtime/vm/snapshot.h ('k') | runtime/vm/snapshot_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698