Index: runtime/vm/snapshot.cc |
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc |
index a57296f25d3d99d43f16abcf771f865ee65bad33..5d05c15380933550c7f508e514da057ad8434ebe 100644 |
--- a/runtime/vm/snapshot.cc |
+++ b/runtime/vm/snapshot.cc |
@@ -174,11 +174,13 @@ SnapshotReader::SnapshotReader( |
const uint8_t* buffer, |
intptr_t size, |
const uint8_t* instructions_buffer, |
+ const uint8_t* data_buffer, |
Snapshot::Kind kind, |
ZoneGrowableArray<BackRefNode>* backward_refs, |
Thread* thread) |
: BaseReader(buffer, size), |
instructions_buffer_(instructions_buffer), |
+ data_buffer_(data_buffer), |
kind_(kind), |
snapshot_code_(instructions_buffer != NULL), |
thread_(thread), |
@@ -208,7 +210,8 @@ SnapshotReader::SnapshotReader( |
backward_references_(backward_refs), |
instructions_reader_(NULL) { |
if (instructions_buffer != NULL) { |
- instructions_reader_ = new InstructionsReader(instructions_buffer); |
+ instructions_reader_ = |
+ new InstructionsReader(instructions_buffer, data_buffer); |
} |
} |
@@ -1107,6 +1110,15 @@ int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions) { |
} |
+int32_t InstructionsWriter::GetObjectOffsetFor(RawObject* raw_object) { |
+ intptr_t heap_size = raw_object->Size(); |
+ intptr_t offset = next_object_offset_; |
+ next_object_offset_ += heap_size; |
+ objects_.Add(ObjectData(raw_object)); |
+ return offset; |
+} |
+ |
+ |
static void EnsureIdentifier(char* label) { |
for (char c = *label; c != '\0'; c = *++label) { |
if (((c >= 'a') && (c <= 'z')) || |
@@ -1130,6 +1142,10 @@ void InstructionsWriter::WriteAssembly() { |
ASSERT(data.raw_code_ != NULL); |
data.code_ = &Code::Handle(Z, data.raw_code_); |
} |
+ for (intptr_t i = 0; i < objects_.length(); i++) { |
+ ObjectData& data = objects_[i]; |
+ data.obj_ = &Object::Handle(Z, data.raw_obj_); |
+ } |
stream_.Print(".text\n"); |
stream_.Print(".globl _kInstructionsSnapshot\n"); |
@@ -1215,6 +1231,39 @@ void InstructionsWriter::WriteAssembly() { |
} |
} |
} |
+#if defined(TARGET_OS_LINUX) |
+ stream_.Print(".section .rodata\n"); |
+#elif defined(TARGET_OS_MACOS) |
+ stream_.Print(".section __DATA,__const\n"); |
+#else |
+#error Unsupported platform |
+#endif |
+ stream_.Print(".globl _kDataSnapshot\n"); |
+ stream_.Print(".balign %" Pd ", 0\n", kObjectAlignment); |
+ stream_.Print("_kDataSnapshot:\n"); |
+ WriteWordLiteral(next_object_offset_); // Data length. |
+ WriteWordLiteral(0); // Zero padding for object alignment. |
+ |
+ for (intptr_t i = 0; i < objects_.length(); i++) { |
+ const Object& obj = *objects_[i].obj_; |
+ 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); |
+ WriteWordLiteral(marked_tags); |
+ start += sizeof(uword); |
+ for (uword* cursor = reinterpret_cast<uword*>(start); |
+ cursor < reinterpret_cast<uword*>(end); |
+ cursor++) { |
+ WriteWordLiteral(*cursor); |
+ } |
+ } |
} |
@@ -1224,15 +1273,30 @@ RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset, |
RawInstructions* result = |
reinterpret_cast<RawInstructions*>( |
- reinterpret_cast<uword>(buffer_) + offset + kHeapObjectTag); |
+ reinterpret_cast<uword>(instructions_buffer_) + |
+ offset + kHeapObjectTag); |
+#ifdef DEBUG |
uword actual_tags = result->ptr()->tags_; |
if (actual_tags != expected_tags) { |
FATAL2("Instructions tag mismatch: expected %" Pd ", saw %" Pd, |
expected_tags, |
actual_tags); |
} |
+#endif |
+ |
+ ASSERT(result->IsMarked()); |
+ |
+ return result; |
+} |
+ |
+ |
+RawObject* InstructionsReader::GetObjectAt(int32_t offset) { |
+ ASSERT(Utils::IsAligned(offset, kWordSize)); |
+ RawObject* result = |
+ reinterpret_cast<RawObject*>( |
+ reinterpret_cast<uword>(data_buffer_) + offset + kHeapObjectTag); |
ASSERT(result->IsMarked()); |
return result; |
@@ -1459,10 +1523,12 @@ VmIsolateSnapshotReader::VmIsolateSnapshotReader( |
const uint8_t* buffer, |
intptr_t size, |
const uint8_t* instructions_buffer, |
+ const uint8_t* data_buffer, |
Thread* thread) |
: SnapshotReader(buffer, |
size, |
instructions_buffer, |
+ data_buffer, |
Snapshot::kFull, |
new ZoneGrowableArray<BackRefNode>( |
kNumVmIsolateSnapshotReferences), |
@@ -1480,6 +1546,7 @@ VmIsolateSnapshotReader::~VmIsolateSnapshotReader() { |
} |
ResetBackwardReferenceTable(); |
Dart::set_instructions_snapshot_buffer(instructions_buffer_); |
+ Dart::set_data_snapshot_buffer(data_buffer_); |
} |
@@ -1531,10 +1598,12 @@ RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { |
IsolateSnapshotReader::IsolateSnapshotReader(const uint8_t* buffer, |
intptr_t size, |
const uint8_t* instructions_buffer, |
+ const uint8_t* data_buffer, |
Thread* thread) |
: SnapshotReader(buffer, |
size, |
instructions_buffer, |
+ data_buffer, |
Snapshot::kFull, |
new ZoneGrowableArray<BackRefNode>( |
kNumInitialReferencesInFullSnapshot), |
@@ -1554,6 +1623,7 @@ ScriptSnapshotReader::ScriptSnapshotReader(const uint8_t* buffer, |
: SnapshotReader(buffer, |
size, |
NULL, /* instructions_buffer */ |
+ NULL, /* data_buffer */ |
Snapshot::kScript, |
new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), |
thread) { |
@@ -1571,6 +1641,7 @@ MessageSnapshotReader::MessageSnapshotReader(const uint8_t* buffer, |
: SnapshotReader(buffer, |
size, |
NULL, /* instructions_buffer */ |
+ NULL, /* data_buffer */ |
Snapshot::kMessage, |
new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), |
thread) { |