Index: runtime/vm/snapshot.cc |
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc |
index 5ceb31ddaccbbdf4966c92ae3dc4c28240c57142..13e4478c03a55aeda192bd779a4b9eb3a48b8520 100644 |
--- a/runtime/vm/snapshot.cc |
+++ b/runtime/vm/snapshot.cc |
@@ -682,6 +682,7 @@ int32_t ImageWriter::GetDataOffsetFor(RawObject* raw_object) { |
void ImageWriter::Write(WriteStream* clustered_stream, bool vm) { |
Thread* thread = Thread::Current(); |
Zone* zone = thread->zone(); |
+ Heap* heap = thread->isolate()->heap(); |
NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), |
"WriteInstructions")); |
@@ -692,6 +693,11 @@ void ImageWriter::Write(WriteStream* clustered_stream, bool vm) { |
data.insns_ = &Instructions::Handle(zone, data.raw_insns_); |
ASSERT(data.raw_code_ != NULL); |
data.code_ = &Code::Handle(zone, data.raw_code_); |
+ |
+ // Update object id table with offsets that will refer to the VM snapshot, |
+ // causing a subsequently written isolate snapshot to share instructions |
+ // with the VM snapshot. |
+ heap->SetObjectId(data.insns_->raw(), -data.offset_); |
} |
for (intptr_t i = 0; i < objects_.length(); i++) { |
ObjectData& data = objects_[i]; |
@@ -1018,11 +1024,29 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) { |
} |
} |
+ImageReader::ImageReader(const uint8_t* instructions_buffer, |
+ const uint8_t* data_buffer) |
+ : instructions_buffer_(instructions_buffer), data_buffer_(data_buffer) { |
+ ASSERT(instructions_buffer != NULL); |
+ ASSERT(data_buffer != NULL); |
+ ASSERT(Utils::IsAligned(reinterpret_cast<uword>(instructions_buffer), |
+ OS::PreferredCodeAlignment())); |
+ vm_instructions_buffer_ = Dart::vm_snapshot_instructions(); |
+} |
+ |
RawInstructions* ImageReader::GetInstructionsAt(int32_t offset) { |
ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); |
- RawInstructions* result = reinterpret_cast<RawInstructions*>( |
- reinterpret_cast<uword>(instructions_buffer_) + offset + kHeapObjectTag); |
+ RawInstructions* result; |
+ if (offset < 0) { |
+ result = reinterpret_cast<RawInstructions*>( |
+ reinterpret_cast<uword>(vm_instructions_buffer_) - offset + |
+ kHeapObjectTag); |
+ } else { |
+ result = reinterpret_cast<RawInstructions*>( |
+ reinterpret_cast<uword>(instructions_buffer_) + offset + |
+ kHeapObjectTag); |
+ } |
ASSERT(result->IsInstructions()); |
ASSERT(result->IsMarked()); |