Chromium Code Reviews| Index: runtime/vm/snapshot.cc |
| diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc |
| index aacef7f31f8719c2f8e596eb2d19941a74f39bc9..3b0b2fcbf18afedd6de19eff53eee2233d9c8038 100644 |
| --- a/runtime/vm/snapshot.cc |
| +++ b/runtime/vm/snapshot.cc |
| @@ -1562,8 +1562,8 @@ RawObject* SnapshotReader::ReadVMIsolateObject(intptr_t header_value) { |
| } |
| } |
| - ASSERT(Symbols::IsVMSymbolId(object_id)); |
| - return Symbols::GetVMSymbol(object_id); // return VM symbol. |
| + ASSERT(Symbols::IsPredefinedSymbolId(object_id)); |
| + return Symbols::GetPredefinedSymbol(object_id); // return VM symbol. |
| } |
| @@ -1818,7 +1818,7 @@ SnapshotWriter::SnapshotWriter(Thread* thread, |
| ForwardList* forward_list, |
| InstructionsWriter* instructions_writer, |
| bool can_send_any_object, |
| - bool vm_isolate_is_symbolic) |
| + bool writing_vm_isolate) |
| : BaseWriter(buffer, alloc, initial_size), |
| thread_(thread), |
| kind_(kind), |
| @@ -1830,7 +1830,7 @@ SnapshotWriter::SnapshotWriter(Thread* thread, |
| exception_msg_(NULL), |
| unmarked_objects_(false), |
| can_send_any_object_(can_send_any_object), |
| - vm_isolate_is_symbolic_(vm_isolate_is_symbolic) { |
| + writing_vm_isolate_(writing_vm_isolate) { |
| ASSERT(forward_list_ != NULL); |
| } |
| @@ -1922,9 +1922,14 @@ bool SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| } |
| } |
| + if (writing_vm_isolate_) { |
| + // Write the object instead of a reference. |
|
siva
2016/05/10 00:49:10
maybe make this comment a little more elaborate by
rmacnak
2016/05/10 01:45:01
Done.
|
| + return false; |
| + } |
| + |
| if (Snapshot::IsFull(kind())) { |
| // Check it is a predefined symbol in the VM isolate. |
| - id = Symbols::LookupVMSymbol(rawobj); |
| + id = Symbols::LookupPredefinedSymbol(rawobj); |
| if (id != kInvalidIndex) { |
| WriteVMIsolateObject(id); |
| return true; |
| @@ -1960,10 +1965,6 @@ bool SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| } |
| } |
| - if (!vm_isolate_is_symbolic()) { |
| - return false; |
| - } |
| - |
| const Object& obj = Object::Handle(rawobj); |
| FATAL1("Unexpected reference to object in VM isolate: %s\n", obj.ToCString()); |
| return false; |
| @@ -2011,8 +2012,7 @@ FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind, |
| uint8_t** vm_isolate_snapshot_buffer, |
| uint8_t** isolate_snapshot_buffer, |
| ReAlloc alloc, |
| - InstructionsWriter* instructions_writer, |
| - bool vm_isolate_is_symbolic) |
| + InstructionsWriter* instructions_writer) |
| : thread_(Thread::Current()), |
| kind_(kind), |
| vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer), |
| @@ -2023,8 +2023,8 @@ FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind, |
| forward_list_(NULL), |
| instructions_writer_(instructions_writer), |
| scripts_(Array::Handle(zone())), |
| - symbol_table_(Array::Handle(zone())), |
| - vm_isolate_is_symbolic_(vm_isolate_is_symbolic) { |
| + saved_symbol_table_(Array::Handle(zone())), |
| + new_vm_symbol_table_(Array::Handle(zone())) { |
| ASSERT(isolate_snapshot_buffer_ != NULL); |
| ASSERT(alloc_ != NULL); |
| ASSERT(isolate() != NULL); |
| @@ -2033,32 +2033,49 @@ FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind, |
| ASSERT(heap() != NULL); |
| ObjectStore* object_store = isolate()->object_store(); |
| ASSERT(object_store != NULL); |
| - // Ensure the class table is valid. |
| + |
| #if defined(DEBUG) |
| + // Ensure the class table is valid. |
| isolate()->ValidateClassTable(); |
| #endif |
| + // Can't have any mutation happening while we're serializing. |
| ASSERT(isolate()->background_compiler() == NULL); |
| - // Collect all the script objects and their accompanying token stream objects |
| - // into an array so that we can write it out as part of the VM isolate |
| - // snapshot. We first count the number of script objects, allocate an array |
| - // and then fill it up with the script objects. |
| - ScriptVisitor scripts_counter(thread()); |
| - heap()->IterateOldObjects(&scripts_counter); |
| - intptr_t count = scripts_counter.count(); |
| - scripts_ = Array::New(count, Heap::kOld); |
| - ScriptVisitor script_visitor(thread(), &scripts_); |
| - heap()->IterateOldObjects(&script_visitor); |
| - |
| + intptr_t first_object_id = -1; |
| if (vm_isolate_snapshot_buffer != NULL) { |
| - // Stash the symbol table away for writing and reading into the vm isolate, |
| - // and reset the symbol table for the regular isolate so that we do not |
| - // write these symbols into the snapshot of a regular dart isolate. |
| - symbol_table_ = object_store->symbol_table(); |
| + // Collect all the script objects and their accompanying token stream |
| + // objects into an array so that we can write it out as part of the VM |
| + // isolate snapshot. We first count the number of script objects, allocate |
| + // an array and then fill it up with the script objects. |
| + ScriptVisitor scripts_counter(thread()); |
| + heap()->IterateOldObjects(&scripts_counter); |
| + Dart::vm_isolate()->heap()->IterateOldObjects(&scripts_counter); |
| + intptr_t count = scripts_counter.count(); |
| + scripts_ = Array::New(count, Heap::kOld); |
| + ScriptVisitor script_visitor(thread(), &scripts_); |
| + heap()->IterateOldObjects(&script_visitor); |
| + Dart::vm_isolate()->heap()->IterateOldObjects(&script_visitor); |
| + ASSERT(script_visitor.count() == count); |
| + |
| + // Tuck away the current symbol table. |
| + saved_symbol_table_ = object_store->symbol_table(); |
| + |
| + // Create a unified symbol table that will be written as the vm isolate's |
| + // symbol table. |
| + new_vm_symbol_table_ = Symbols::UnifiedSymbolTable(); |
| + |
| + // Create an empty symbol table that will be written as the isolate's symbol |
| + // table. |
| Symbols::SetupSymbolTable(isolate()); |
| + |
| + first_object_id = kMaxPredefinedObjectIds; |
| + } else { |
| + intptr_t max_vm_isolate_object_id = |
| + Object::vm_isolate_snapshot_object_table().Length(); |
| + first_object_id = kMaxPredefinedObjectIds + max_vm_isolate_object_id; |
| } |
| - forward_list_ = new ForwardList(thread(), SnapshotWriter::FirstObjectId()); |
| + forward_list_ = new ForwardList(thread(), first_object_id); |
| ASSERT(forward_list_ != NULL); |
| } |
| @@ -2066,10 +2083,11 @@ FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind, |
| FullSnapshotWriter::~FullSnapshotWriter() { |
| delete forward_list_; |
| // We may run Dart code afterwards, restore the symbol table if needed. |
| - if (!symbol_table_.IsNull()) { |
| - isolate()->object_store()->set_symbol_table(symbol_table_); |
| - symbol_table_ = Array::null(); |
| + if (!saved_symbol_table_.IsNull()) { |
| + isolate()->object_store()->set_symbol_table(saved_symbol_table_); |
| + saved_symbol_table_ = Array::null(); |
| } |
| + new_vm_symbol_table_ = Array::null(); |
| scripts_ = Array::null(); |
| } |
| @@ -2084,7 +2102,7 @@ void FullSnapshotWriter::WriteVmIsolateSnapshot() { |
| forward_list_, |
| instructions_writer_, |
| true, /* can_send_any_object */ |
| - vm_isolate_is_symbolic_); |
| + true /* writing_vm_isolate */); |
| // Write full snapshot for the VM isolate. |
| // Setup for long jump in case there is an exception while writing |
| // the snapshot. |
| @@ -2100,10 +2118,10 @@ void FullSnapshotWriter::WriteVmIsolateSnapshot() { |
| * Now Write out the following |
| * - the symbol table |
| * - all the scripts and token streams for these scripts |
| - * |
| + * - the stub code (precompiled snapshots only) |
| **/ |
| // Write out the symbol table. |
| - writer.WriteObject(symbol_table_.raw()); |
| + writer.WriteObject(new_vm_symbol_table_.raw()); |
| // Write out all the script objects and the accompanying token streams |
| // for the bootstrap libraries so that they are in the VM isolate |
| @@ -2111,11 +2129,9 @@ void FullSnapshotWriter::WriteVmIsolateSnapshot() { |
| writer.WriteObject(scripts_.raw()); |
| if (Snapshot::IncludesCode(kind_)) { |
| - ASSERT(!vm_isolate_is_symbolic_); |
| StubCode::WriteTo(&writer); |
| } |
| - |
| writer.FillHeader(writer.kind()); |
| vm_isolate_snapshot_size_ = writer.BytesWritten(); |
| @@ -2134,7 +2150,7 @@ void FullSnapshotWriter::WriteIsolateFullSnapshot() { |
| forward_list_, |
| instructions_writer_, |
| true, /* can_send_any_object */ |
| - true /* vm_isolate_is_symbolic */); |
| + false /* writing_vm_isolate */); |
| ObjectStore* object_store = isolate()->object_store(); |
| ASSERT(object_store != NULL); |
| @@ -2194,6 +2210,7 @@ ForwardList::ForwardList(Thread* thread, intptr_t first_object_id) |
| first_object_id_(first_object_id), |
| nodes_(), |
| first_unprocessed_object_id_(first_object_id) { |
| + ASSERT(first_object_id > 0); |
| } |
| @@ -2212,7 +2229,6 @@ intptr_t ForwardList::AddObject(Zone* zone, |
| Node* node = new Node(&obj, state); |
| ASSERT(node != NULL); |
| nodes_.Add(node); |
| - ASSERT(SnapshotWriter::FirstObjectId() > 0); |
| ASSERT(object_id != 0); |
| heap()->SetObjectId(raw, object_id); |
| return object_id; |
| @@ -2221,7 +2237,6 @@ intptr_t ForwardList::AddObject(Zone* zone, |
| intptr_t ForwardList::FindObject(RawObject* raw) { |
| NoSafepointScope no_safepoint; |
| - ASSERT(SnapshotWriter::FirstObjectId() > 0); |
| intptr_t id = heap()->GetObjectId(raw); |
| ASSERT(id == 0 || NodeForObjectId(id)->obj()->raw() == raw); |
| return (id == 0) ? static_cast<intptr_t>(kInvalidIndex) : id; |
| @@ -2680,13 +2695,6 @@ void SnapshotWriter::WriteVersion() { |
| } |
| -intptr_t SnapshotWriter::FirstObjectId() { |
| - intptr_t max_vm_isolate_object_id = |
| - Object::vm_isolate_snapshot_object_table().Length(); |
| - return kMaxPredefinedObjectIds + max_vm_isolate_object_id; |
| -} |
| - |
| - |
| ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, |
| ReAlloc alloc) |
| : SnapshotWriter(Thread::Current(), |
| @@ -2697,7 +2705,7 @@ ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, |
| &forward_list_, |
| NULL, /* instructions_writer */ |
| true, /* can_send_any_object */ |
| - true /* vm_isolate_is_symbolic */), |
| + false /* writing_vm_isolate */), |
| forward_list_(thread(), kMaxPredefinedObjectIds) { |
| ASSERT(buffer != NULL); |
| ASSERT(alloc != NULL); |
| @@ -2753,7 +2761,7 @@ MessageWriter::MessageWriter(uint8_t** buffer, |
| &forward_list_, |
| NULL, /* instructions_writer */ |
| can_send_any_object, |
| - true /* vm_isolate_is_symbolic */), |
| + false /* writing_vm_isolate */), |
| forward_list_(thread(), kMaxPredefinedObjectIds) { |
| ASSERT(buffer != NULL); |
| ASSERT(alloc != NULL); |