Chromium Code Reviews| Index: runtime/vm/snapshot.cc |
| diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc |
| index 8f3dc434b72789d712e5e52df88fee209c829657..a3b912bb7b63ba80a1f99a05bd2a3ee9041d59c2 100644 |
| --- a/runtime/vm/snapshot.cc |
| +++ b/runtime/vm/snapshot.cc |
| @@ -16,6 +16,7 @@ |
| #include "vm/object.h" |
| #include "vm/object_store.h" |
| #include "vm/snapshot_ids.h" |
| +#include "vm/stub_code.h" |
| #include "vm/symbols.h" |
| #include "vm/verified_memory.h" |
| #include "vm/version.h" |
| @@ -171,13 +172,15 @@ intptr_t BaseReader::ReadSmiValue() { |
| SnapshotReader::SnapshotReader( |
| const uint8_t* buffer, |
| intptr_t size, |
| + const uint8_t* instructions_buffer, |
| Snapshot::Kind kind, |
| ZoneGrowableArray<BackRefNode>* backward_refs, |
| Isolate* isolate, |
| Zone* zone) |
| : BaseReader(buffer, size), |
| + instructions_buffer_(instructions_buffer), |
| kind_(kind), |
| - snapshot_code_(false), |
| + snapshot_code_(instructions_buffer != NULL), |
| isolate_(isolate), |
| zone_(zone), |
| heap_(isolate->heap()), |
| @@ -195,11 +198,16 @@ SnapshotReader::SnapshotReader( |
| stream_(TokenStream::Handle(isolate)), |
| data_(ExternalTypedData::Handle(isolate)), |
| typed_data_(TypedData::Handle(isolate)), |
| + code_(Code::Handle(isolate)), |
| error_(UnhandledException::Handle(isolate)), |
| max_vm_isolate_object_id_( |
| (kind == Snapshot::kFull) ? |
| Object::vm_isolate_snapshot_object_table().Length() : 0), |
| - backward_references_(backward_refs) { |
| + backward_references_(backward_refs), |
| + instructions_reader_(NULL) { |
| + if (instructions_buffer != NULL) { |
| + instructions_reader_ = new InstructionsReader(instructions_buffer); |
| + } |
| } |
| @@ -505,7 +513,9 @@ RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id, |
| ASSERT(!cls_.IsNull()); |
| instance_size = cls_.instance_size(); |
| } |
| - intptr_t next_field_offset = cls_.next_field_offset(); |
| + intptr_t next_field_offset = Class::IsSignatureClass(cls_.raw()) |
| + ? Closure::InstanceSize() : cls_.next_field_offset(); |
| + |
| intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); |
| ASSERT(next_field_offset > 0); |
| // Instance::NextFieldOffset() returns the offset of the first field in |
| @@ -778,6 +788,71 @@ RawTypeArguments* SnapshotReader::NewTypeArguments(intptr_t len) { |
| } |
| +RawObjectPool* SnapshotReader::NewObjectPool(intptr_t len) { |
| + ASSERT(kind_ == Snapshot::kFull); |
| + ASSERT_NO_SAFEPOINT_SCOPE(); |
| + RawObjectPool* obj = reinterpret_cast<RawObjectPool*>( |
| + AllocateUninitialized(kObjectPoolCid, ObjectPool::InstanceSize(len))); |
| + obj->ptr()->length_ = len; |
| + return obj; |
| +} |
| + |
| + |
| +RawLocalVarDescriptors* SnapshotReader::NewLocalVarDescriptors( |
| + intptr_t num_entries) { |
| + ASSERT(kind_ == Snapshot::kFull); |
| + ASSERT_NO_SAFEPOINT_SCOPE(); |
| + RawLocalVarDescriptors* obj = reinterpret_cast<RawLocalVarDescriptors*>( |
| + AllocateUninitialized(kLocalVarDescriptorsCid, |
| + LocalVarDescriptors::InstanceSize(num_entries))); |
| + obj->ptr()->num_entries_ = num_entries; |
| + return obj; |
| +} |
| + |
| + |
| +RawExceptionHandlers* SnapshotReader::NewExceptionHandlers( |
| + intptr_t num_entries) { |
| + ASSERT(kind_ == Snapshot::kFull); |
| + ASSERT_NO_SAFEPOINT_SCOPE(); |
| + RawExceptionHandlers* obj = reinterpret_cast<RawExceptionHandlers*>( |
| + AllocateUninitialized(kExceptionHandlersCid, |
| + ExceptionHandlers::InstanceSize(num_entries))); |
| + obj->ptr()->num_entries_ = num_entries; |
| + return obj; |
| +} |
| + |
| + |
| +RawPcDescriptors* SnapshotReader::NewPcDescriptors(intptr_t len) { |
| + ASSERT(kind_ == Snapshot::kFull); |
| + ASSERT_NO_SAFEPOINT_SCOPE(); |
| + RawPcDescriptors* obj = reinterpret_cast<RawPcDescriptors*>( |
| + AllocateUninitialized(kPcDescriptorsCid, |
| + PcDescriptors::InstanceSize(len))); |
| + obj->ptr()->length_ = len; |
| + return obj; |
| +} |
| + |
| + |
| +RawStackmap* SnapshotReader::NewStackmap(intptr_t len) { |
| + ASSERT(kind_ == Snapshot::kFull); |
| + ASSERT_NO_SAFEPOINT_SCOPE(); |
| + RawStackmap* obj = reinterpret_cast<RawStackmap*>( |
| + AllocateUninitialized(kStackmapCid, Stackmap::InstanceSize(len))); |
| + obj->ptr()->length_ = len; |
| + return obj; |
| +} |
| + |
| + |
| +RawCode* SnapshotReader::NewCode(intptr_t pointer_offsets_length) { |
| + ASSERT(pointer_offsets_length == 0); |
| + ASSERT(kind_ == Snapshot::kFull); |
| + ASSERT_NO_SAFEPOINT_SCOPE(); |
| + RawCode* obj = reinterpret_cast<RawCode*>( |
| + AllocateUninitialized(kCodeCid, Code::InstanceSize(0))); |
| + return obj; |
| +} |
| + |
| + |
| RawTokenStream* SnapshotReader::NewTokenStream(intptr_t len) { |
| ASSERT(kind_ == Snapshot::kFull); |
| ASSERT_NO_SAFEPOINT_SCOPE(); |
| @@ -927,19 +1002,13 @@ RawFunction* SnapshotReader::NewFunction() { |
| } |
| -RawCode* SnapshotReader::NewCode(intptr_t pointer_offsets_length) { |
| - ASSERT(pointer_offsets_length == 0); |
| - ALLOC_NEW_OBJECT(Code); |
| -} |
| - |
| - |
| -RawObjectPool* SnapshotReader::NewObjectPool(intptr_t length) { |
| - ALLOC_NEW_OBJECT(ObjectPool); |
| +RawICData* SnapshotReader::NewICData() { |
| + ALLOC_NEW_OBJECT(ICData); |
| } |
| -RawICData* SnapshotReader::NewICData() { |
| - ALLOC_NEW_OBJECT(ICData); |
| +RawLinkedHashMap* SnapshotReader::NewLinkedHashMap() { |
| + ALLOC_NEW_OBJECT(LinkedHashMap); |
| } |
| @@ -1060,8 +1129,36 @@ RawStacktrace* SnapshotReader::NewStacktrace() { |
| } |
| -RawInstructions* SnapshotReader::GetInstructionsById(int32_t id) { |
| - // TODO(rmacnak): Read from shared library. |
| +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()); |
| + return offset; |
| +} |
| + |
| + |
| +RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset, |
| + uword expected_tags) { |
| + ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); |
| + |
| + RawInstructions* result = |
| + reinterpret_cast<RawInstructions*>( |
| + reinterpret_cast<uword>(buffer_) + offset + kHeapObjectTag); |
| + |
| + uword actual_tags = result->ptr()->tags_; |
| + if (actual_tags != expected_tags) { |
| + FATAL2("Instructions tag mismatch: expected %" Pd ", saw %" Pd, |
| + expected_tags, |
| + actual_tags); |
| + } |
| + |
| + // TODO(rmacnak): The above contains stale pointers to a Code and an |
| + // ObjectPool. Return the actual result after calling convention change. |
| return Instructions::null(); |
| } |
| @@ -1076,7 +1173,7 @@ intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) { |
| } |
| ASSERT(SerializedHeaderTag::decode(class_header) == kObjectId); |
| intptr_t class_id = SerializedHeaderData::decode(class_header); |
| - ASSERT(IsObjectStoreClassId(class_id)); |
| + ASSERT(IsObjectStoreClassId(class_id) || IsSingletonClassId(class_id)); |
| return class_id; |
| } |
| @@ -1265,16 +1362,19 @@ void SnapshotReader::ArrayReadFrom(intptr_t object_id, |
| } |
| -VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer, |
| - intptr_t size, |
| - Zone* zone) |
| - : SnapshotReader(buffer, |
| - size, |
| - Snapshot::kFull, |
| - new ZoneGrowableArray<BackRefNode>( |
| - kNumVmIsolateSnapshotReferences), |
| - Dart::vm_isolate(), |
| - zone) { |
| +VmIsolateSnapshotReader::VmIsolateSnapshotReader( |
| + const uint8_t* buffer, |
| + intptr_t size, |
| + const uint8_t* instructions_buffer, |
| + Zone* zone) |
| + : SnapshotReader(buffer, |
| + size, |
| + instructions_buffer, |
| + Snapshot::kFull, |
| + new ZoneGrowableArray<BackRefNode>( |
| + kNumVmIsolateSnapshotReferences), |
| + Dart::vm_isolate(), |
| + zone) { |
| } |
| @@ -1287,6 +1387,7 @@ VmIsolateSnapshotReader::~VmIsolateSnapshotReader() { |
| i, *(backrefs->At(i).reference())); |
| } |
| ResetBackwardReferenceTable(); |
| + Object::set_instructions_snapshot_buffer(instructions_buffer_); |
| } |
| @@ -1320,6 +1421,29 @@ RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { |
| // only memory. |
| *(ArrayHandle()) ^= ReadObject(); |
| + |
| + if (snapshot_code()) { |
| + for (intptr_t i = 0; |
| + i < ArgumentsDescriptor::kCachedDescriptorCount; |
| + i++) { |
| + *(ArrayHandle()) ^= ReadObject(); |
| + // TODO(rmacnak): |
| + // ArgumentsDescriptor::InitOnceFromSnapshot(i, *(ArrayHandle())); |
| + } |
| + |
| + ObjectPool::CheckedHandle(ReadObject()); // empty pool |
| + PcDescriptors::CheckedHandle(ReadObject()); // empty pc desc |
| + LocalVarDescriptors::CheckedHandle(ReadObject()); // empty var desc |
| + ExceptionHandlers::CheckedHandle(ReadObject()); // empty exc handlers |
| + |
| +#define READ_STUB(name) \ |
| + *(CodeHandle()) ^= ReadObject(); |
| + // TODO(rmacnak): |
| + // StubCode::name##_entry()->InitOnceFromSnapshot(CodeHandle()) |
| + VM_STUB_CODE_LIST(READ_STUB); |
| +#undef READ_STUB |
| + } |
| + |
| // Validate the class table. |
| #if defined(DEBUG) |
| isolate->ValidateClassTable(); |
| @@ -1332,10 +1456,12 @@ RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { |
| IsolateSnapshotReader::IsolateSnapshotReader(const uint8_t* buffer, |
| intptr_t size, |
| + const uint8_t* instructions_buffer, |
| Isolate* isolate, |
| Zone* zone) |
| : SnapshotReader(buffer, |
| size, |
| + instructions_buffer, |
| Snapshot::kFull, |
| new ZoneGrowableArray<BackRefNode>( |
| kNumInitialReferencesInFullSnapshot), |
| @@ -1355,6 +1481,7 @@ ScriptSnapshotReader::ScriptSnapshotReader(const uint8_t* buffer, |
| Zone* zone) |
| : SnapshotReader(buffer, |
| size, |
| + NULL, /* instructions_buffer */ |
| Snapshot::kScript, |
| new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), |
| isolate, |
| @@ -1373,6 +1500,7 @@ MessageSnapshotReader::MessageSnapshotReader(const uint8_t* buffer, |
| Zone* zone) |
| : SnapshotReader(buffer, |
| size, |
| + NULL, /* instructions_buffer */ |
| Snapshot::kMessage, |
| new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), |
| isolate, |
| @@ -1390,19 +1518,23 @@ SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, |
| ReAlloc alloc, |
| intptr_t initial_size, |
| ForwardList* forward_list, |
| + InstructionsWriter* instructions_writer, |
| bool can_send_any_object, |
| - bool snapshot_code) |
| + bool snapshot_code, |
| + bool vm_isolate_is_symbolic) |
| : BaseWriter(buffer, alloc, initial_size), |
| kind_(kind), |
| isolate_(Isolate::Current()), |
| object_store_(isolate_->object_store()), |
| class_table_(isolate_->class_table()), |
| forward_list_(forward_list), |
| + instructions_writer_(instructions_writer), |
| exception_type_(Exceptions::kNone), |
| exception_msg_(NULL), |
| unmarked_objects_(false), |
| can_send_any_object_(can_send_any_object), |
| - snapshot_code_(snapshot_code) { |
| + snapshot_code_(snapshot_code), |
| + vm_isolate_is_symbolic_(vm_isolate_is_symbolic) { |
| ASSERT(forward_list_ != NULL); |
| } |
| @@ -1423,62 +1555,62 @@ void SnapshotWriter::WriteObject(RawObject* rawobj) { |
| object_id = forward_list_->AddObject(rawobj, kIsSerialized); \ |
| Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj); \ |
| raw_obj->WriteTo(this, object_id, kind()); \ |
| - return; \ |
| + return true; \ |
| } \ |
| -void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| +bool SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| // Check if it is a singleton null object. |
| if (rawobj == Object::null()) { |
| WriteVMIsolateObject(kNullObject); |
| - return; |
| + return true; |
| } |
| // Check if it is a singleton sentinel object. |
| if (rawobj == Object::sentinel().raw()) { |
| WriteVMIsolateObject(kSentinelObject); |
| - return; |
| + return true; |
| } |
| // Check if it is a singleton sentinel object. |
| if (rawobj == Object::transition_sentinel().raw()) { |
| WriteVMIsolateObject(kTransitionSentinelObject); |
| - return; |
| + return true; |
| } |
| // Check if it is a singleton empty array object. |
| if (rawobj == Object::empty_array().raw()) { |
| WriteVMIsolateObject(kEmptyArrayObject); |
| - return; |
| + return true; |
| } |
| // Check if it is a singleton zero array object. |
| if (rawobj == Object::zero_array().raw()) { |
| WriteVMIsolateObject(kZeroArrayObject); |
| - return; |
| + return true; |
| } |
| // Check if it is a singleton dyanmic Type object. |
| if (rawobj == Object::dynamic_type()) { |
| WriteVMIsolateObject(kDynamicType); |
| - return; |
| + return true; |
| } |
| // Check if it is a singleton void Type object. |
| if (rawobj == Object::void_type()) { |
| WriteVMIsolateObject(kVoidType); |
| - return; |
| + return true; |
| } |
| // Check if it is a singleton boolean true object. |
| if (rawobj == Bool::True().raw()) { |
| WriteVMIsolateObject(kTrueValue); |
| - return; |
| + return true; |
| } |
| // Check if it is a singleton boolean false object. |
| if (rawobj == Bool::False().raw()) { |
| WriteVMIsolateObject(kFalseValue); |
| - return; |
| + return true; |
| } |
| // Check if it is a singleton class object which is shared by |
| @@ -1490,23 +1622,27 @@ void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| if (IsSingletonClassId(class_id)) { |
| intptr_t object_id = ObjectIdFromClassId(class_id); |
| WriteVMIsolateObject(object_id); |
| - return; |
| + return true; |
| } |
| } |
| + if (!vm_isolate_is_symbolic()) { |
| + return false; |
| + } |
|
siva
2015/09/01 20:58:49
Maybe move this down to the end as discussed offli
rmacnak
2015/09/01 23:43:48
Done.
|
| + |
| if (kind() == Snapshot::kFull) { |
| // Check it is a predefined symbol in the VM isolate. |
| id = Symbols::LookupVMSymbol(rawobj); |
| if (id != kInvalidIndex) { |
| WriteVMIsolateObject(id); |
| - return; |
| + return true; |
| } |
| // Check if it is an object from the vm isolate snapshot object table. |
| id = FindVmSnapshotObject(rawobj); |
| if (id != kInvalidIndex) { |
| WriteIndexedObject(id); |
| - return; |
| + return true; |
| } |
| } else { |
| // In the case of script snapshots or for messages we do not use |
| @@ -1515,7 +1651,7 @@ void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| intptr_t object_id = forward_list_->FindObject(rawobj); |
| if (object_id != -1) { |
| WriteIndexedObject(object_id); |
| - return; |
| + return true; |
| } else { |
| switch (id) { |
| VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE) |
| @@ -1523,7 +1659,7 @@ void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| object_id = forward_list_->AddObject(rawobj, kIsSerialized); |
| RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj); |
| raw_obj->WriteTo(this, object_id, kind()); |
| - return; |
| + return true; |
| } |
| default: |
| OS::Print("class id = %" Pd "\n", id); |
| @@ -1534,6 +1670,7 @@ void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| const Object& obj = Object::Handle(rawobj); |
| FATAL1("Unexpected reference to object in VM isolate: %s\n", obj.ToCString()); |
| + return false; |
| } |
| #undef VM_OBJECT_WRITE |
| @@ -1578,18 +1715,24 @@ class ScriptVisitor : public ObjectVisitor { |
| FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer, |
| uint8_t** isolate_snapshot_buffer, |
| + uint8_t** instructions_snapshot_buffer, |
| ReAlloc alloc, |
| - bool snapshot_code) |
| + bool snapshot_code, |
| + bool vm_isolate_is_symbolic) |
| : isolate_(Isolate::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), |
| scripts_(Array::Handle(isolate_)), |
| symbol_table_(Array::Handle(isolate_)), |
| - snapshot_code_(snapshot_code) { |
| + snapshot_code_(snapshot_code), |
| + vm_isolate_is_symbolic_(vm_isolate_is_symbolic) { |
| ASSERT(isolate_snapshot_buffer_ != NULL); |
| ASSERT(alloc_ != NULL); |
| ASSERT(isolate_ != NULL); |
| @@ -1623,6 +1766,12 @@ FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer, |
| forward_list_ = new ForwardList(SnapshotWriter::FirstObjectId()); |
| ASSERT(forward_list_ != NULL); |
| + |
| + if (instructions_snapshot_buffer != NULL) { |
| + instructions_writer_ = new InstructionsWriter(instructions_snapshot_buffer, |
| + alloc, |
| + kInitialSize); |
| + } |
| } |
| @@ -1640,8 +1789,10 @@ void FullSnapshotWriter::WriteVmIsolateSnapshot() { |
| alloc_, |
| kInitialSize, |
| forward_list_, |
| + instructions_writer_, |
| true, /* can_send_any_object */ |
| - snapshot_code_); |
| + snapshot_code_, |
| + vm_isolate_is_symbolic_); |
| // Write full snapshot for the VM isolate. |
| // Setup for long jump in case there is an exception while writing |
| // the snapshot. |
| @@ -1667,8 +1818,26 @@ void FullSnapshotWriter::WriteVmIsolateSnapshot() { |
| // read only memory. |
| writer.WriteObject(scripts_.raw()); |
| - // Write out all forwarded objects. |
| - writer.WriteForwardedObjects(); |
| + if (snapshot_code_) { |
| + ASSERT(!vm_isolate_is_symbolic_); |
| + |
| + for (intptr_t i = 0; |
| + i < ArgumentsDescriptor::kCachedDescriptorCount; |
| + i++) { |
| + writer.WriteObject(ArgumentsDescriptor::cached_args_descriptors_[i]); |
| + } |
| + |
| + writer.WriteObject(Object::empty_object_pool().raw()); |
| + writer.WriteObject(Object::empty_descriptors().raw()); |
| + writer.WriteObject(Object::empty_var_descriptors().raw()); |
| + writer.WriteObject(Object::empty_exception_handlers().raw()); |
| + |
| +#define WRITE_STUB(name) \ |
| + writer.WriteObject(StubCode::name##_entry()->code()); |
| + VM_STUB_CODE_LIST(WRITE_STUB); |
| +#undef WRITE_STUB |
| + } |
| + |
| writer.FillHeader(writer.kind()); |
| @@ -1685,8 +1854,10 @@ void FullSnapshotWriter::WriteIsolateFullSnapshot() { |
| alloc_, |
| kInitialSize, |
| forward_list_, |
| + instructions_writer_, |
| true, /* can_send_any_object */ |
| - snapshot_code_); |
| + snapshot_code_, |
| + true /* vm_isolate_is_symbolic */); |
| ObjectStore* object_store = isolate_->object_store(); |
| ASSERT(object_store != NULL); |
| @@ -1721,22 +1892,50 @@ void FullSnapshotWriter::WriteIsolateFullSnapshot() { |
| } |
| +class WritableVMIsolateScope : StackResource { |
| + public: |
| + explicit WritableVMIsolateScope(Thread* thread) : StackResource(thread) { |
| + Dart::vm_isolate()->heap()->WriteProtect(false); |
| + } |
| + |
| + ~WritableVMIsolateScope() { |
| + ASSERT(Dart::vm_isolate()->heap()->UsedInWords(Heap::kNew) == 0); |
| + Dart::vm_isolate()->heap()->WriteProtect(true); |
| + } |
| +}; |
| + |
| + |
| void FullSnapshotWriter::WriteFullSnapshot() { |
| - if (vm_isolate_snapshot_buffer() != NULL) { |
| - WriteVmIsolateSnapshot(); |
| + if (!vm_isolate_is_symbolic_) { |
| + // TODO(asiva): Don't mutate object headers during serialization. |
| + WritableVMIsolateScope scope(Thread::Current()); |
| + |
| + if (vm_isolate_snapshot_buffer() != NULL) { |
| + WriteVmIsolateSnapshot(); |
| + } |
| + WriteIsolateFullSnapshot(); |
| + |
| + instructions_snapshot_size_ = instructions_writer_->BytesWritten(); |
| + } else { |
| + if (vm_isolate_snapshot_buffer() != NULL) { |
| + WriteVmIsolateSnapshot(); |
| + } |
| + WriteIsolateFullSnapshot(); |
| } |
| - WriteIsolateFullSnapshot(); |
| } |
| PrecompiledSnapshotWriter::PrecompiledSnapshotWriter( |
| uint8_t** vm_isolate_snapshot_buffer, |
| uint8_t** isolate_snapshot_buffer, |
| + uint8_t** instructions_snapshot_buffer, |
| ReAlloc alloc) |
| : FullSnapshotWriter(vm_isolate_snapshot_buffer, |
| isolate_snapshot_buffer, |
| + instructions_snapshot_buffer, |
| alloc, |
| - true /* snapshot_code */) { |
| + true, /* snapshot_code */ |
| + false /* vm_isolate_is_symbolic */) { |
| } |
| @@ -1866,8 +2065,7 @@ bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) { |
| // Now check if it is an object from the VM isolate (NOTE: premarked objects |
| // are considered to be objects in the VM isolate). These objects are shared |
| // by all isolates. |
| - if (rawobj->IsVMHeapObject()) { |
| - HandleVMIsolateObject(rawobj); |
| + if (rawobj->IsVMHeapObject() && HandleVMIsolateObject(rawobj)) { |
| return true; |
| } |
| @@ -2059,7 +2257,10 @@ void SnapshotWriter::WriteInlinedObject(RawObject* raw) { |
| #undef SNAPSHOT_WRITE |
| default: break; |
| } |
| - UNREACHABLE(); |
| + |
| + |
| + const Object& obj = Object::Handle(raw); |
| + FATAL1("Unexpected inlined object: %s\n", obj.ToCString()); |
| } |
| @@ -2255,12 +2456,14 @@ void SnapshotWriter::WriteInstance(intptr_t object_id, |
| // Check if the instance has native fields and throw an exception if it does. |
| CheckForNativeFields(cls); |
| - // Check if object is a closure that is serializable, if the object is a |
| - // closure that is not serializable this will throw an exception. |
| - RawFunction* func = IsSerializableClosure(cls, raw); |
| - if (func != Function::null()) { |
| - WriteStaticImplicitClosure(object_id, func, tags); |
| - return; |
| + if (kind() == Snapshot::kMessage) { |
|
siva
2015/09/01 20:58:49
|| kind() == Snapshot::kScript)
rmacnak
2015/09/01 23:43:48
Done.
|
| + // Check if object is a closure that is serializable, if the object is a |
| + // closure that is not serializable this will throw an exception. |
| + RawFunction* func = IsSerializableClosure(cls, raw); |
| + if (func != Function::null()) { |
| + WriteStaticImplicitClosure(object_id, func, tags); |
| + return; |
| + } |
| } |
| // Object is regular dart instance. |
| @@ -2390,8 +2593,10 @@ ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, |
| alloc, |
| kInitialSize, |
| &forward_list_, |
| + NULL, /* instructions_writer */ |
| true, /* can_send_any_object */ |
| - false /* snapshot_code */), |
| + false, /* snapshot_code */ |
| + true /* vm_isolate_is_symbolic */), |
| forward_list_(kMaxPredefinedObjectIds) { |
| ASSERT(buffer != NULL); |
| ASSERT(alloc != NULL); |
| @@ -2445,8 +2650,10 @@ MessageWriter::MessageWriter(uint8_t** buffer, |
| alloc, |
| kInitialSize, |
| &forward_list_, |
| + NULL, /* instructions_writer */ |
| can_send_any_object, |
| - false /* snapshot_code */), |
| + false, /* snapshot_code */ |
| + true /* vm_isolate_is_symbolic */), |
| forward_list_(kMaxPredefinedObjectIds) { |
| ASSERT(buffer != NULL); |
| ASSERT(alloc != NULL); |