| Index: vm/raw_object_snapshot.cc
|
| ===================================================================
|
| --- vm/raw_object_snapshot.cc (revision 2601)
|
| +++ vm/raw_object_snapshot.cc (working copy)
|
| @@ -29,7 +29,8 @@
|
| ASSERT(reader != NULL);
|
|
|
| Class& cls = Class::ZoneHandle();
|
| - if (kind == Snapshot::kFull) {
|
| + if ((kind == Snapshot::kFull) ||
|
| + (kind == Snapshot::kScript && !RawObject::IsCreatedFromSnapshot(tags))) {
|
| // Read in the base information.
|
| ObjectKind kind = reader->Read<ObjectKind>();
|
|
|
| @@ -71,12 +72,12 @@
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| - SnapshotWriterVisitor visitor(writer);
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
|
|
| - if (kind == Snapshot::kFull) {
|
| + if ((kind == Snapshot::kFull) ||
|
| + (kind == Snapshot::kScript && !IsCreatedFromSnapshot())) {
|
| // Write out the class and tags information.
|
| writer->WriteObjectHeader(Object::kClassClass, ptr()->tags_);
|
|
|
| @@ -92,6 +93,7 @@
|
| writer->Write<bool>(ptr()->is_interface_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to());
|
| } else {
|
| writer->WriteClassId(this);
|
| @@ -132,7 +134,6 @@
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| - SnapshotWriterVisitor visitor(writer);
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -144,6 +145,7 @@
|
| writer->Write<intptr_t>(ptr()->token_index_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to());
|
| }
|
|
|
| @@ -188,6 +190,11 @@
|
| for (intptr_t i = 0; i <= num_flds; i++) {
|
| *(parameterized_type.raw()->from() + i) = reader->ReadObject();
|
| }
|
| +
|
| + // If object needs to be a canonical object, Canonicalize it.
|
| + if ((kind != Snapshot::kFull) && parameterized_type.IsCanonical()) {
|
| + parameterized_type ^= parameterized_type.Canonicalize();
|
| + }
|
| return parameterized_type.raw();
|
| }
|
|
|
| @@ -196,7 +203,6 @@
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| - SnapshotWriterVisitor visitor(writer);
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -208,6 +214,7 @@
|
| writer->Write<int8_t>(ptr()->type_state_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to());
|
| }
|
|
|
| @@ -247,7 +254,6 @@
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| - SnapshotWriterVisitor visitor(writer);
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -260,6 +266,7 @@
|
| writer->Write<int8_t>(ptr()->type_state_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to());
|
| }
|
|
|
| @@ -296,7 +303,6 @@
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| ASSERT(kind == Snapshot::kMessage);
|
| - SnapshotWriterVisitor visitor(writer);
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -305,6 +311,7 @@
|
| writer->WriteObjectHeader(Object::kInstantiatedTypeClass, ptr()->tags_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to());
|
| }
|
|
|
| @@ -347,9 +354,15 @@
|
| type_arguments.SetTypeAt(i, type);
|
| }
|
|
|
| - // Set the object tags.
|
| + // Set the object tags (This is done after setting the object fields
|
| + // because 'SetTypeAt' has an assertion to check if the object is not
|
| + // already canonical).
|
| type_arguments.set_tags(tags);
|
|
|
| + // If object needs to be a canonical object, Canonicalize it.
|
| + if ((kind != Snapshot::kFull) && type_arguments.IsCanonical()) {
|
| + type_arguments ^= type_arguments.Canonicalize();
|
| + }
|
| return type_arguments.raw();
|
| }
|
|
|
| @@ -409,7 +422,6 @@
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| ASSERT(kind == Snapshot::kMessage);
|
| - SnapshotWriterVisitor visitor(writer);
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -419,6 +431,7 @@
|
| ptr()->tags_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to());
|
| }
|
|
|
| @@ -428,6 +441,7 @@
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| ASSERT(reader != NULL);
|
| + ASSERT(kind != Snapshot::kMessage && !RawObject::IsCreatedFromSnapshot(tags));
|
|
|
| // Allocate function object.
|
| Function& func = Function::ZoneHandle(Function::New());
|
| @@ -463,7 +477,7 @@
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| - SnapshotWriterVisitor visitor(writer);
|
| + ASSERT(kind != Snapshot::kMessage && !IsCreatedFromSnapshot());
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -483,6 +497,7 @@
|
| writer->Write<bool>(ptr()->is_optimizable_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to());
|
| }
|
|
|
| @@ -492,6 +507,7 @@
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| ASSERT(reader != NULL);
|
| + ASSERT(kind != Snapshot::kMessage && !RawObject::IsCreatedFromSnapshot(tags));
|
|
|
| // Allocate field object.
|
| Field& field = Field::ZoneHandle(Field::New());
|
| @@ -522,7 +538,7 @@
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| - SnapshotWriterVisitor visitor(writer);
|
| + ASSERT(kind != Snapshot::kMessage && !IsCreatedFromSnapshot());
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -530,12 +546,14 @@
|
| // Write out the class and tags information.
|
| writer->WriteObjectHeader(Object::kFieldClass, ptr()->tags_);
|
|
|
| + // Write out all the non object fields.
|
| writer->Write<intptr_t>(ptr()->token_index_);
|
| writer->Write<bool>(ptr()->is_static_);
|
| writer->Write<bool>(ptr()->is_final_);
|
| writer->Write<bool>(ptr()->has_initializer_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to());
|
| }
|
|
|
| @@ -545,6 +563,7 @@
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| ASSERT(reader != NULL);
|
| + ASSERT(kind != Snapshot::kMessage && !RawObject::IsCreatedFromSnapshot(tags));
|
|
|
| // Read the length so that we can determine number of tokens to read.
|
| RawSmi* smi_len = GetSmi(reader->Read<intptr_t>());
|
| @@ -573,6 +592,7 @@
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| + ASSERT(kind != Snapshot::kMessage && !IsCreatedFromSnapshot());
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -596,6 +616,7 @@
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| ASSERT(reader != NULL);
|
| + ASSERT(kind != Snapshot::kMessage && !RawObject::IsCreatedFromSnapshot(tags));
|
|
|
| // Allocate script object.
|
| Script& script = Script::ZoneHandle(Script::New());
|
| @@ -621,7 +642,7 @@
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| ASSERT(tokens_ != TokenStream::null());
|
| - SnapshotWriterVisitor visitor(writer);
|
| + ASSERT(kind != Snapshot::kMessage && !IsCreatedFromSnapshot());
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -630,6 +651,7 @@
|
| writer->WriteObjectHeader(Object::kScriptClass, ptr()->tags_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to());
|
| }
|
|
|
| @@ -639,33 +661,44 @@
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| ASSERT(reader != NULL);
|
| + ASSERT(kind != Snapshot::kMessage);
|
|
|
| - // Allocate library object.
|
| - Library& library = Library::ZoneHandle(Library::New());
|
| + Library& library = Library::ZoneHandle();
|
| reader->AddBackwardReference(object_id, &library);
|
|
|
| - // Set the object tags.
|
| - library.set_tags(tags);
|
| + if (RawObject::IsCreatedFromSnapshot(tags)) {
|
| + ASSERT(kind != Snapshot::kFull);
|
| + // Lookup the object as it should already exist in the heap.
|
| + String& library_url = String::Handle();
|
| + library_url ^= reader->ReadObject();
|
| + library = Library::LookupLibrary(library_url);
|
| + } else {
|
| + // Allocate library object.
|
| + library = Library::New();
|
|
|
| - // Set all non object fields.
|
| - library.raw_ptr()->num_imports_ = reader->Read<intptr_t>();
|
| - library.raw_ptr()->num_imported_into_ = reader->Read<intptr_t>();
|
| - library.raw_ptr()->num_anonymous_ = reader->Read<intptr_t>();
|
| - library.raw_ptr()->corelib_imported_ = reader->Read<bool>();
|
| - library.raw_ptr()->load_state_ = reader->Read<int8_t>();
|
| - // The native resolver is not serialized.
|
| - Dart_NativeEntryResolver resolver = reader->Read<Dart_NativeEntryResolver>();
|
| - ASSERT(resolver == NULL);
|
| - library.set_native_entry_resolver(resolver);
|
| + // Set the object tags.
|
| + library.set_tags(tags);
|
|
|
| - // Set all the object fields.
|
| - // TODO(5411462): Need to assert No GC can happen here, even though
|
| - // allocations may happen.
|
| - intptr_t num_flds = (library.raw()->to() - library.raw()->from());
|
| - for (intptr_t i = 0; i <= num_flds; i++) {
|
| - *(library.raw()->from() + i) = reader->ReadObject();
|
| + // Set all non object fields.
|
| + library.raw_ptr()->num_imports_ = reader->Read<intptr_t>();
|
| + library.raw_ptr()->num_imported_into_ = reader->Read<intptr_t>();
|
| + library.raw_ptr()->num_anonymous_ = reader->Read<intptr_t>();
|
| + library.raw_ptr()->corelib_imported_ = reader->Read<bool>();
|
| + library.raw_ptr()->load_state_ = reader->Read<int8_t>();
|
| + // The native resolver is not serialized.
|
| + Dart_NativeEntryResolver resolver =
|
| + reader->Read<Dart_NativeEntryResolver>();
|
| + ASSERT(resolver == NULL);
|
| + library.set_native_entry_resolver(resolver);
|
| +
|
| + // Set all the object fields.
|
| + // TODO(5411462): Need to assert No GC can happen here, even though
|
| + // allocations may happen.
|
| + intptr_t num_flds = (library.raw()->to() - library.raw()->from());
|
| + for (intptr_t i = 0; i <= num_flds; i++) {
|
| + *(library.raw()->from() + i) = reader->ReadObject();
|
| + }
|
| }
|
| -
|
| return library.raw();
|
| }
|
|
|
| @@ -674,7 +707,7 @@
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| - SnapshotWriterVisitor visitor(writer);
|
| + ASSERT(kind != Snapshot::kMessage);
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -682,17 +715,25 @@
|
| // Write out the class and tags information.
|
| writer->WriteObjectHeader(Object::kLibraryClass, ptr()->tags_);
|
|
|
| - writer->Write<intptr_t>(ptr()->num_imports_);
|
| - writer->Write<intptr_t>(ptr()->num_imported_into_);
|
| - writer->Write<intptr_t>(ptr()->num_anonymous_);
|
| - writer->Write<bool>(ptr()->corelib_imported_);
|
| - writer->Write<int8_t>(ptr()->load_state_);
|
| - // We do not serialize the native resolver over, this needs to be explicitly
|
| - // set after deserialization.
|
| - writer->Write<Dart_NativeEntryResolver>(NULL);
|
| + if (IsCreatedFromSnapshot()) {
|
| + ASSERT(kind != Snapshot::kFull);
|
| + // Write out library URL so that it can be looked up when reading.
|
| + writer->WriteObject(ptr()->url_);
|
| + } else {
|
| + // Write out all non object fields.
|
| + writer->Write<intptr_t>(ptr()->num_imports_);
|
| + writer->Write<intptr_t>(ptr()->num_imported_into_);
|
| + writer->Write<intptr_t>(ptr()->num_anonymous_);
|
| + writer->Write<bool>(ptr()->corelib_imported_);
|
| + writer->Write<int8_t>(ptr()->load_state_);
|
| + // We do not serialize the native resolver over, this needs to be explicitly
|
| + // set after deserialization.
|
| + writer->Write<Dart_NativeEntryResolver>(NULL);
|
|
|
| - // Write out all the object pointer fields.
|
| - visitor.VisitPointers(from(), to());
|
| + // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| + visitor.VisitPointers(from(), to());
|
| + }
|
| }
|
|
|
|
|
| @@ -701,6 +742,7 @@
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| ASSERT(reader != NULL);
|
| + ASSERT(kind != Snapshot::kMessage && !RawObject::IsCreatedFromSnapshot(tags));
|
|
|
| // Allocate library prefix object.
|
| LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(LibraryPrefix::New());
|
| @@ -725,7 +767,7 @@
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| - SnapshotWriterVisitor visitor(writer);
|
| + ASSERT(kind != Snapshot::kMessage && !IsCreatedFromSnapshot());
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -734,6 +776,7 @@
|
| writer->WriteObjectHeader(Object::kLibraryPrefixClass, ptr()->tags_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to());
|
| }
|
|
|
| @@ -743,6 +786,7 @@
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| ASSERT(reader != NULL);
|
| + ASSERT(kind != Snapshot::kMessage);
|
|
|
| // Create Code object.
|
| Code& code = Code::ZoneHandle(Code::New(0));
|
| @@ -757,6 +801,7 @@
|
| // Currently we do not serialize any code and hence we write
|
| // out a null object for it.
|
| ASSERT(writer != NULL);
|
| + ASSERT(kind != Snapshot::kMessage);
|
|
|
| writer->WriteIndexedObject(Object::kNullObject);
|
| }
|
| @@ -845,7 +890,6 @@
|
| intptr_t object_id,
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| - SnapshotWriterVisitor visitor(writer);
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -859,6 +903,7 @@
|
| // Can't serialize the isolate pointer, we set it implicitly on read.
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to(ptr()->num_variables_));
|
| }
|
|
|
| @@ -895,7 +940,6 @@
|
| Snapshot::Kind kind) {
|
| ASSERT(writer != NULL);
|
| ASSERT(kind == Snapshot::kMessage);
|
| - SnapshotWriterVisitor visitor(writer);
|
|
|
| // Write out the serialization header value for this object.
|
| writer->WriteSerializationMarker(kInlined, object_id);
|
| @@ -907,6 +951,7 @@
|
| writer->Write<intptr_t>(ptr()->num_variables_);
|
|
|
| // Write out all the object pointer fields.
|
| + SnapshotWriterVisitor visitor(writer);
|
| visitor.VisitPointers(from(), to(ptr()->num_variables_));
|
| }
|
|
|
| @@ -968,9 +1013,14 @@
|
| // Read the 64 bit value for the object.
|
| int64_t value = reader->Read<int64_t>();
|
|
|
| - // Create a Mint object.
|
| - Mint& mint = Mint::ZoneHandle(
|
| - Mint::New(value, (kind == Snapshot::kFull) ? Heap::kOld : Heap::kNew));
|
| + // Create a Mint object or get canonical one if it is a canonical constant.
|
| + Mint& mint = Mint::ZoneHandle();
|
| + if ((kind != Snapshot::kFull) && RawObject::IsCanonical(tags)) {
|
| + mint = Mint::NewCanonical(value);
|
| + } else {
|
| + mint = Mint::New(value,
|
| + (kind == Snapshot::kFull) ? Heap::kOld : Heap::kNew);
|
| + }
|
| reader->AddBackwardReference(object_id, &mint);
|
|
|
| // Set the object tags.
|
| @@ -1001,6 +1051,7 @@
|
| intptr_t tags,
|
| Snapshot::Kind kind) {
|
| ASSERT(reader != NULL);
|
| +
|
| // Read in the HexCString representation of the bigint.
|
| intptr_t len = reader->Read<intptr_t>();
|
| char* str = reinterpret_cast<char*>(ZoneAllocator(len + 1));
|
| @@ -1008,8 +1059,14 @@
|
| for (intptr_t i = 0; i < len; i++) {
|
| str[i] = reader->Read<uint8_t>();
|
| }
|
| +
|
| // Create a Bigint object from HexCString.
|
| Bigint& obj = Bigint::ZoneHandle(BigintOperations::FromHexCString(str));
|
| +
|
| + // If it is a canonical constant make it one.
|
| + if ((kind != Snapshot::kFull) && RawObject::IsCanonical(tags)) {
|
| + obj ^= obj.Canonicalize();
|
| + }
|
| reader->AddBackwardReference(object_id, &obj);
|
|
|
| // Set the object tags.
|
| @@ -1048,9 +1105,15 @@
|
| ASSERT(reader != NULL);
|
| // Read the double value for the object.
|
| double value = reader->Read<double>();
|
| - // Create a double object.
|
| - Double& dbl = Double::ZoneHandle(
|
| - Double::New(value, (kind == Snapshot::kFull) ? Heap::kOld : Heap::kNew));
|
| +
|
| + // Create a Double object or get canonical one if it is a canonical constant.
|
| + Double& dbl = Double::ZoneHandle();
|
| + if ((kind != Snapshot::kFull) && RawObject::IsCanonical(tags)) {
|
| + dbl = Double::NewCanonical(value);
|
| + } else {
|
| + dbl = Double::New(value,
|
| + (kind == Snapshot::kFull) ? Heap::kOld : Heap::kNew);
|
| + }
|
| reader->AddBackwardReference(object_id, &dbl);
|
|
|
| // Set the object tags.
|
| @@ -1103,20 +1166,25 @@
|
| intptr_t len = Smi::Value(smi_len);
|
| RawSmi* smi_hash = GetSmi(reader->Read<intptr_t>());
|
|
|
| - // Set up the string object.
|
| - HandleType& str_obj = HandleType::ZoneHandle(HandleType::New(
|
| - len, (kind == Snapshot::kFull) ? Heap::kOld : Heap::kNew));
|
| - for (intptr_t i = 0; i < len; i++) {
|
| - *str_obj.CharAddr(i) = reader->Read<CharacterType>();
|
| + HandleType& str_obj = HandleType::ZoneHandle();
|
| + if (kind != Snapshot::kFull && RawObject::IsCanonical(tags)) {
|
| + CharacterType* ptr = reinterpret_cast<CharacterType*>(ZoneAllocator(len));
|
| + for (intptr_t i = 0; i < len; i++) {
|
| + ptr[i] = reader->Read<CharacterType>();
|
| + }
|
| + str_obj ^= String::NewSymbol(ptr, len);
|
| + } else {
|
| + // Set up the string object.
|
| + str_obj = HandleType::New(
|
| + len, (kind == Snapshot::kFull) ? Heap::kOld : Heap::kNew);
|
| + for (intptr_t i = 0; i < len; i++) {
|
| + *str_obj.CharAddr(i) = reader->Read<CharacterType>();
|
| + }
|
| + str_obj.set_tags(tags);
|
| + str_obj.SetHash(Smi::Value(smi_hash));
|
| }
|
| reader->AddBackwardReference(object_id, &str_obj);
|
|
|
| - // Set the object tags.
|
| - str_obj.set_tags(tags);
|
| -
|
| - // Set up the hash value.
|
| - str_obj.SetHash(Smi::Value(smi_hash));
|
| -
|
| return str_obj.raw();
|
| }
|
|
|
|
|