Index: vm/snapshot.cc |
=================================================================== |
--- vm/snapshot.cc (revision 10306) |
+++ vm/snapshot.cc (working copy) |
@@ -11,6 +11,7 @@ |
#include "vm/heap.h" |
#include "vm/object.h" |
#include "vm/object_store.h" |
+#include "vm/symbols.h" |
namespace dart { |
@@ -131,33 +132,33 @@ |
} |
-RawObject* SnapshotReader::ReadObjectImpl(intptr_t value) { |
- ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); |
- SerializedHeaderType header_type = SerializedHeaderTag::decode(value); |
- intptr_t header_value = SerializedHeaderData::decode(value); |
- |
- if (header_type == kObjectId) { |
- return ReadIndexedObject(header_value); |
+RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { |
+ ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
+ if (IsVMIsolateObject(header_value)) { |
+ return ReadVMIsolateObject(header_value); |
+ } else { |
+ if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
+ return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
+ } |
+ ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
+ return ReadInlinedObject(SerializedHeaderData::decode(header_value)); |
} |
- ASSERT(header_type == kInlined); |
- return ReadInlinedObject(header_value); |
} |
RawObject* SnapshotReader::ReadObjectRef() { |
- int64_t value = Read<int64_t>(); |
- if ((value & kSmiTagMask) == 0) { |
- return Integer::New((value >> kSmiTagShift)); |
+ int64_t header_value = Read<int64_t>(); |
+ if ((header_value & kSmiTagMask) == 0) { |
+ return Integer::New((header_value >> kSmiTagShift)); |
} |
- ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); |
- SerializedHeaderType header_type = SerializedHeaderTag::decode(value); |
- intptr_t header_value = SerializedHeaderData::decode(value); |
- |
- if (header_type == kObjectId) { |
- return ReadIndexedObject(header_value); |
+ ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
+ if (IsVMIsolateObject(header_value)) { |
+ return ReadVMIsolateObject(header_value); |
+ } else if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
+ return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
} |
- ASSERT(header_type == kInlined); |
- intptr_t object_id = header_value; |
+ ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
+ intptr_t object_id = SerializedHeaderData::decode(header_value); |
ASSERT(GetBackRef(object_id) == NULL); |
// Read the class header information and lookup the class. |
@@ -468,16 +469,17 @@ |
RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { |
- SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header); |
- |
// If the header is an object Id, lookup singleton VM classes or classes |
// stored in the object store. |
- if (header_type == kObjectId) { |
+ if (IsVMIsolateObject(class_header)) { |
+ intptr_t class_id = GetVMIsolateObjectId(class_header); |
+ if (IsSingletonClassId(class_id)) { |
+ return Object::GetSingletonClass(class_id); // return singleton. |
+ } |
+ } else if (SerializedHeaderTag::decode(class_header) == kObjectId) { |
intptr_t header_value = SerializedHeaderData::decode(class_header); |
if (IsObjectStoreClassId(header_value)) { |
return object_store()->GetClass(header_value); |
- } else if (IsSingletonClassId(header_value)) { |
- return Object::GetSingletonClass(header_value); // return the singleton. |
} |
} |
return Class::null(); |
@@ -510,7 +512,8 @@ |
} |
-RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { |
+RawObject* SnapshotReader::ReadVMIsolateObject(intptr_t header_value) { |
+ intptr_t object_id = GetVMIsolateObjectId(header_value); |
if (object_id == Object::kNullObject) { |
// This is a singleton null object, return it. |
return Object::null(); |
@@ -520,7 +523,16 @@ |
} |
if (IsSingletonClassId(object_id)) { |
return Object::GetSingletonClass(object_id); // return singleton object. |
- } else if (IsObjectStoreClassId(object_id)) { |
+ } else { |
+ ASSERT(Symbols::IsVMSymbolId(object_id)); |
+ return Symbols::GetVMSymbol(object_id); // return VM symbol. |
+ } |
+ UNREACHABLE(); |
+} |
+ |
+ |
+RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { |
+ if (IsObjectStoreClassId(object_id)) { |
return object_store()->GetClass(object_id); |
} else if (object_id == ObjectStore::kTrueValue) { |
return object_store()->true_value(); |
@@ -620,6 +632,38 @@ |
} |
+void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
+ // Check if it is a singleton null object. |
+ if (rawobj == Object::null()) { |
+ WriteVMIsolateObject(Object::kNullObject); |
+ return; |
+ } |
+ |
+ // Check if it is a singleton sentinel object. |
+ if (rawobj == Object::sentinel()) { |
+ WriteVMIsolateObject(Object::kSentinelObject); |
+ return; |
+ } |
+ |
+ // Check if it is a singleton class object. |
+ RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); |
+ intptr_t index = Object::GetSingletonClassIndex(raw_class); |
+ if (index != Object::kInvalidIndex) { |
+ WriteVMIsolateObject(index); |
+ return; |
+ } |
+ |
+ // Check it is a predefined symbol. |
+ index = Symbols::LookupVMSymbol(rawobj); |
+ if (index != Object::kInvalidIndex) { |
+ WriteVMIsolateObject(index); |
+ return; |
+ } |
+ |
+ UNREACHABLE(); |
+} |
+ |
+ |
void SnapshotWriter::WriteObjectRef(RawObject* raw) { |
// First check if object can be written as a simple predefined type. |
if (CheckAndWritePredefinedObject(raw)) { |
@@ -646,7 +690,7 @@ |
intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
// Write out the serialization header value for this object. |
- WriteSerializationMarker(kInlined, object_id); |
+ WriteInlinedObjectHeader(object_id); |
// Indicate this is an instance object. |
WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); |
@@ -666,7 +710,7 @@ |
RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
// Write out the serialization header value for this object. |
- WriteSerializationMarker(kInlined, object_id); |
+ WriteInlinedObjectHeader(object_id); |
// Write out the class information. |
WriteIndexedObject(ObjectStore::kArrayClass); |
@@ -686,7 +730,7 @@ |
RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
// Write out the serialization header value for this object. |
- WriteSerializationMarker(kInlined, object_id); |
+ WriteInlinedObjectHeader(object_id); |
// Write out the class information. |
WriteIndexedObject(ObjectStore::kImmutableArrayClass); |
@@ -787,27 +831,23 @@ |
return true; |
} |
- // Check if it is a singleton null object which is shared by all isolates. |
- if (rawobj == Object::null()) { |
- WriteIndexedObject(Object::kNullObject); |
+ // Check if object has already been serialized, in that case just write |
+ // the object id out. |
+ uword tags = rawobj->ptr()->tags_; |
+ if (SerializedHeaderTag::decode(tags) == kObjectId) { |
+ intptr_t id = SerializedHeaderData::decode(tags); |
+ WriteIndexedObject(id); |
return true; |
} |
- // Check if it is a singleton sentinel object which is shared by all isolates. |
- if (rawobj == Object::sentinel()) { |
- WriteIndexedObject(Object::kSentinelObject); |
+ // 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->IsMarked()) { |
+ HandleVMIsolateObject(rawobj); |
return true; |
} |
- // Check if it is a singleton class object which is shared by |
- // all isolates. |
- RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); |
- intptr_t index = Object::GetSingletonClassIndex(raw_class); |
- if (index != Object::kInvalidIndex) { |
- WriteIndexedObject(index); |
- return true; |
- } |
- |
// Check if it is a singleton boolean true value. |
if (rawobj == object_store()->true_value()) { |
WriteIndexedObject(ObjectStore::kTrueValue); |
@@ -822,15 +862,15 @@ |
// Check if it is a code object in that case just write a Null object |
// as we do not want code objects in the snapshot. |
- if (RawObject::ClassIdTag::decode(GetObjectTags(rawobj)) == kCode) { |
- WriteIndexedObject(Object::kNullObject); |
+ if (rawobj->GetClassId() == kCode) { |
+ WriteVMIsolateObject(Object::kNullObject); |
return true; |
} |
// Check if classes are not being serialized and it is preinitialized type. |
if (kind_ != Snapshot::kFull) { |
RawType* raw_type = reinterpret_cast<RawType*>(rawobj); |
- index = object_store()->GetTypeIndex(raw_type); |
+ intptr_t index = object_store()->GetTypeIndex(raw_type); |
if (index != ObjectStore::kInvalidIndex) { |
WriteIndexedObject(index); |
return true; |
@@ -847,15 +887,6 @@ |
return; |
} |
- // Check if object has already been serialized, in that |
- // case just write the object id out. |
- uword tags = raw->ptr()->tags_; |
- if (SerializedHeaderTag::decode(tags) == kObjectId) { |
- intptr_t id = SerializedHeaderData::decode(tags); |
- WriteIndexedObject(id); |
- return; |
- } |
- |
// Object is being serialized, add it to the forward ref list and mark |
// it so that future references to this object in the snapshot will use |
// an object id, instead of trying to serialize it again. |
@@ -866,9 +897,6 @@ |
void SnapshotWriter::WriteInlinedObject(RawObject* raw) { |
- // Assert object is not a simple predefined type. |
- ASSERT(!CheckAndWritePredefinedObject(raw)); |
- |
// Now write the object out inline in the stream as follows: |
// - Object is seen for the first time (inlined as follows): |
// (object size in multiples of kObjectAlignment | 0x1) |
@@ -891,7 +919,7 @@ |
ASSERT(instance_size != 0); |
// Write out the serialization header value for this object. |
- WriteSerializationMarker(kInlined, object_id); |
+ WriteInlinedObjectHeader(object_id); |
// Indicate this is an instance object. |
WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); |
@@ -949,13 +977,16 @@ |
void SnapshotWriter::WriteClassId(RawClass* cls) { |
ASSERT(kind_ != Snapshot::kFull); |
int id = object_store()->GetClassIndex(cls); |
- if (IsSingletonClassId(id) || IsObjectStoreClassId(id)) { |
+ if (IsSingletonClassId(id)) { |
+ WriteVMIsolateObject(id); |
+ } else if (IsObjectStoreClassId(id)) { |
WriteIndexedObject(id); |
} else { |
// TODO(5411462): Should restrict this to only core-lib classes in this |
// case. |
// Write out the class and tags information. |
- WriteObjectHeader(Object::kClassClass, GetObjectTags(cls)); |
+ WriteVMIsolateObject(Object::kClassClass); |
+ WriteIntptrValue(GetObjectTags(cls)); |
// Write out the library url and class name. |
RawLibrary* library = cls->ptr()->library_; |
@@ -975,10 +1006,11 @@ |
intptr_t len = Smi::Value(length); |
// Write out the serialization header value for this object. |
- WriteSerializationMarker(kInlined, object_id); |
+ WriteInlinedObjectHeader(object_id); |
// Write out the class and tags information. |
- WriteObjectHeader(array_kind, tags); |
+ WriteIndexedObject(array_kind); |
+ WriteIntptrValue(tags); |
// Write out the length field. |
Write<RawObject*>(length); |