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

Unified Diff: runtime/vm/snapshot.cc

Issue 1309563006: Emit assembly instead of a blob for the instructions snapshot, and provide labels for the entry poi… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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
Index: runtime/vm/snapshot.cc
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 5ab4697f865893740f448bc779d107658ed8a8ff..07770097f36a53ae40d049ca1ccebd40832a163f 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -1138,18 +1138,104 @@ RawStacktrace* SnapshotReader::NewStacktrace() {
int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions) {
- // Instructions are allocated with the code alignment and we don't write
- // anything else in the text section.
- ASSERT(Utils::IsAligned(stream_.bytes_written(),
- OS::PreferredCodeAlignment()));
-
- intptr_t offset = stream_.bytes_written();
- stream_.WriteBytes(reinterpret_cast<uint8_t*>(instructions) - kHeapObjectTag,
- instructions->Size());
+ intptr_t offset = next_offset_;
+ next_offset_ += instructions->Size();
+ instructions_.Add(InstructionsData(instructions));
return offset;
}
+static void EnsureIdentifier(char* label) {
+ for (char c = *label; c != '\0'; c = *++label) {
+ if (c >= 'a' && c <= 'z') continue;
+ if (c >= 'A' && c <= 'Z') continue;
+ if (c >= '0' && c <= '9') continue;
siva 2015/09/04 20:34:04 why not : if (((c >= 'a') && (c <= 'z')) || (
rmacnak 2015/09/04 22:11:56 Done.
+ *label = '_';
+ }
+}
+
+
+void InstructionsWriter::WriteAssembly() {
+ Zone* Z = Thread::Current()->zone();
+
+ // Handlify collected raw pointers as the building the names below
siva 2015/09/04 20:34:04 as building the names
rmacnak 2015/09/04 22:11:57 Done.
+ // will allocate on the Dart heap.
+ for (intptr_t i = 0; i < instructions_.length(); i++) {
+ InstructionsData& data = instructions_[i];
+ data.insns_ = &Instructions::Handle(Z, data.raw_insns_);
+ ASSERT(data.raw_code_ != NULL);
+ data.code_ = &Code::Handle(Z, data.raw_code_);
+ }
+
+ stream_.Print(".text\n");
+ stream_.Print(".globl _kInstructionsSnapshot\n");
+ stream_.Print(".balign %" Pd ", 0\n", OS::PreferredCodeAlignment());
+ stream_.Print("_kInstructionsSnapshot:\n");
+
+ Object& owner = Object::Handle(Z);
+ String& str = String::Handle(Z);
+
+ for (intptr_t i = 0; i < instructions_.length(); i++) {
+ const Instructions& insns = *instructions_[i].insns_;
+ const Code& code = *instructions_[i].code_;
siva 2015/09/04 20:34:04 Why do you have that additional loop on top to cre
rmacnak 2015/09/04 22:11:57 As discussed offline, GC can happen in the middle
+
+ ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0);
+
+ {
+ // 1. Write from the header to the entry point.
+ NoSafepointScope no_safepoint;
+ uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag;
+ uword entry = beginning + Instructions::HeaderSize();
+
+ ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t)));
+ ASSERT(Utils::IsAligned(entry, sizeof(uint64_t)));
+
+ for (uint64_t* cursor = reinterpret_cast<uint64_t*>(beginning);
+ cursor < reinterpret_cast<uint64_t*>(entry);
+ cursor++) {
+ stream_.Print(".quad 0x%0.16" Px64 "\n", *cursor);
+ }
+ }
+
+ // 2. Write a label at the entry point.
+ owner = code.owner();
+ if (owner.IsNull()) {
+ const char* name = StubCode::NameOfStub(insns.EntryPoint());
+ 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);
+ } else if (owner.IsFunction()) {
+ const char* name = Function::Cast(owner).ToQualifiedCString();
+ EnsureIdentifier(const_cast<char*>(name));
+ stream_.Print("Precompiled_%s_%" Pd ":\n", name, i);
+ } else {
+ UNREACHABLE();
+ }
+
+ {
+ // 3. 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 end = beginning + insns.raw()->Size();
+
+ ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t)));
+ ASSERT(Utils::IsAligned(entry, sizeof(uint64_t)));
+ ASSERT(Utils::IsAligned(end, sizeof(uint64_t)));
siva 2015/09/04 20:34:04 are these assertions valid for all architectures i
rmacnak 2015/09/04 22:11:56 The minimum OS::PreferredCodeAlignment() is 16.
+
+ for (uint64_t* cursor = reinterpret_cast<uint64_t*>(entry);
+ cursor < reinterpret_cast<uint64_t*>(end);
+ cursor++) {
+ stream_.Print(".quad 0x%0.16" Px64 "\n", *cursor);
+ }
+ }
+ }
+}
+
+
RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset,
uword expected_tags) {
ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment()));
@@ -1944,6 +2030,7 @@ void FullSnapshotWriter::WriteFullSnapshot() {
}
WriteIsolateFullSnapshot();
+ instructions_writer_->WriteAssembly();
instructions_snapshot_size_ = instructions_writer_->BytesWritten();
} else {
if (vm_isolate_snapshot_buffer() != NULL) {

Powered by Google App Engine
This is Rietveld 408576698