Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/snapshot.h" | 5 #include "vm/snapshot.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/dart.h" | 10 #include "vm/dart.h" |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 // Setup for long jump in case there is an exception while reading. | 206 // Setup for long jump in case there is an exception while reading. |
| 207 LongJumpScope jump; | 207 LongJumpScope jump; |
| 208 if (setjmp(*jump.Set()) == 0) { | 208 if (setjmp(*jump.Set()) == 0) { |
| 209 PassiveObject& obj = PassiveObject::Handle(isolate(), ReadObjectImpl()); | 209 PassiveObject& obj = PassiveObject::Handle(isolate(), ReadObjectImpl()); |
| 210 for (intptr_t i = 0; i < backward_references_->length(); i++) { | 210 for (intptr_t i = 0; i < backward_references_->length(); i++) { |
| 211 if (!(*backward_references_)[i].is_deserialized()) { | 211 if (!(*backward_references_)[i].is_deserialized()) { |
| 212 ReadObjectImpl(); | 212 ReadObjectImpl(); |
| 213 (*backward_references_)[i].set_state(kIsDeserialized); | 213 (*backward_references_)[i].set_state(kIsDeserialized); |
| 214 } | 214 } |
| 215 } | 215 } |
| 216 ProcessDeferredCanonicalizations(); | |
| 216 return obj.raw(); | 217 return obj.raw(); |
| 217 } else { | 218 } else { |
| 218 // An error occurred while reading, return the error object. | 219 // An error occurred while reading, return the error object. |
| 219 const Error& err = Error::Handle(isolate()->object_store()->sticky_error()); | 220 const Error& err = Error::Handle(isolate()->object_store()->sticky_error()); |
| 220 isolate()->object_store()->clear_sticky_error(); | 221 isolate()->object_store()->clear_sticky_error(); |
| 221 return err.raw(); | 222 return err.raw(); |
| 222 } | 223 } |
| 223 } | 224 } |
| 224 | 225 |
| 225 | 226 |
| 226 RawClass* SnapshotReader::ReadClassId(intptr_t object_id) { | 227 RawClass* SnapshotReader::ReadClassId(intptr_t object_id) { |
| 227 ASSERT(kind_ != Snapshot::kFull); | 228 ASSERT(kind_ != Snapshot::kFull); |
| 228 // Read the class header information and lookup the class. | 229 // Read the class header information and lookup the class. |
| 229 intptr_t class_header = Read<int32_t>(); | 230 intptr_t class_header = Read<int32_t>(); |
| 230 ASSERT((class_header & kSmiTagMask) != kSmiTag); | 231 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 231 ASSERT(!IsVMIsolateObject(class_header) || | 232 ASSERT(!IsVMIsolateObject(class_header) || |
| 232 !IsSingletonClassId(GetVMIsolateObjectId(class_header))); | 233 !IsSingletonClassId(GetVMIsolateObjectId(class_header))); |
| 233 ASSERT((SerializedHeaderTag::decode(class_header) != kObjectId) || | 234 ASSERT((SerializedHeaderTag::decode(class_header) != kObjectId) || |
| 234 !IsObjectStoreClassId(SerializedHeaderData::decode(class_header))); | 235 !IsObjectStoreClassId(SerializedHeaderData::decode(class_header))); |
| 235 Class& cls = Class::ZoneHandle(zone(), Class::null()); | 236 Class& cls = Class::ZoneHandle(zone(), Class::null()); |
| 236 AddBackRef(object_id, &cls, kIsDeserialized); | 237 AddBackRef(object_id, &cls, kIsDeserialized); |
| 237 // Read the library/class information and lookup the class. | 238 // Read the library/class information and lookup the class. |
| 238 str_ ^= ReadObjectImpl(class_header); | 239 str_ ^= ReadObjectImpl(class_header, kInvalidPatchIndex, 0); |
| 239 library_ = Library::LookupLibrary(str_); | 240 library_ = Library::LookupLibrary(str_); |
| 240 if (library_.IsNull() || !library_.Loaded()) { | 241 if (library_.IsNull() || !library_.Loaded()) { |
| 241 SetReadException("Invalid object found in message."); | 242 SetReadException("Invalid object found in message."); |
| 242 } | 243 } |
| 243 str_ ^= ReadObjectImpl(); | 244 str_ ^= ReadObjectImpl(); |
| 244 cls = library_.LookupClass(str_); | 245 cls = library_.LookupClass(str_); |
| 245 if (cls.IsNull()) { | 246 if (cls.IsNull()) { |
| 246 SetReadException("Invalid object found in message."); | 247 SetReadException("Invalid object found in message."); |
| 247 } | 248 } |
| 248 cls.EnsureIsFinalized(isolate()); | 249 cls.EnsureIsFinalized(isolate()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 } | 286 } |
| 286 func = func.ImplicitClosureFunction(); | 287 func = func.ImplicitClosureFunction(); |
| 287 ASSERT(!func.IsNull()); | 288 ASSERT(!func.IsNull()); |
| 288 | 289 |
| 289 // Return the associated implicit static closure. | 290 // Return the associated implicit static closure. |
| 290 obj = func.ImplicitStaticClosure(); | 291 obj = func.ImplicitStaticClosure(); |
| 291 return obj.raw(); | 292 return obj.raw(); |
| 292 } | 293 } |
| 293 | 294 |
| 294 | 295 |
| 295 RawObject* SnapshotReader::ReadObjectImpl() { | 296 RawObject* SnapshotReader::ReadObjectImpl(intptr_t patch_object_id, |
| 297 intptr_t patch_offset) { | |
| 296 int64_t value = Read<int64_t>(); | 298 int64_t value = Read<int64_t>(); |
| 297 if ((value & kSmiTagMask) == kSmiTag) { | 299 if ((value & kSmiTagMask) == kSmiTag) { |
| 298 return NewInteger(value); | 300 return NewInteger(value); |
| 299 } | 301 } |
| 300 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | 302 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); |
| 301 return ReadObjectImpl(static_cast<intptr_t>(value)); | 303 return ReadObjectImpl(static_cast<intptr_t>(value), |
| 304 patch_object_id, | |
| 305 patch_offset); | |
| 302 } | 306 } |
| 303 | 307 |
| 304 | 308 |
| 305 intptr_t SnapshotReader::NextAvailableObjectId() const { | 309 intptr_t SnapshotReader::NextAvailableObjectId() const { |
| 306 return backward_references_->length() + | 310 return backward_references_->length() + |
| 307 kMaxPredefinedObjectIds + max_vm_isolate_object_id_; | 311 kMaxPredefinedObjectIds + max_vm_isolate_object_id_; |
| 308 } | 312 } |
| 309 | 313 |
| 310 | 314 |
| 311 void SnapshotReader::SetReadException(const char* msg) { | 315 void SnapshotReader::SetReadException(const char* msg) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 324 isolate, UnhandledException::New(Instance::Cast(result), stacktrace)); | 328 isolate, UnhandledException::New(Instance::Cast(result), stacktrace)); |
| 325 isolate->long_jump_base()->Jump(1, error); | 329 isolate->long_jump_base()->Jump(1, error); |
| 326 } | 330 } |
| 327 | 331 |
| 328 | 332 |
| 329 RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const { | 333 RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const { |
| 330 return Object::vm_isolate_snapshot_object_table().At(index); | 334 return Object::vm_isolate_snapshot_object_table().At(index); |
| 331 } | 335 } |
| 332 | 336 |
| 333 | 337 |
| 334 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { | 338 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value, |
| 339 intptr_t patch_object_id, | |
| 340 intptr_t patch_offset) { | |
| 335 if (IsVMIsolateObject(header_value)) { | 341 if (IsVMIsolateObject(header_value)) { |
| 336 return ReadVMIsolateObject(header_value); | 342 return ReadVMIsolateObject(header_value); |
| 337 } else { | 343 } else { |
| 338 if (SerializedHeaderTag::decode(header_value) == kObjectId) { | 344 if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
| 339 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); | 345 return ReadIndexedObject(SerializedHeaderData::decode(header_value), |
| 346 patch_object_id, | |
| 347 patch_offset); | |
| 340 } | 348 } |
| 341 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); | 349 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
| 342 intptr_t object_id = SerializedHeaderData::decode(header_value); | 350 intptr_t object_id = SerializedHeaderData::decode(header_value); |
| 343 if (object_id == kOmittedObjectId) { | 351 if (object_id == kOmittedObjectId) { |
| 344 object_id = NextAvailableObjectId(); | 352 object_id = NextAvailableObjectId(); |
| 345 } | 353 } |
| 346 return ReadInlinedObject(object_id); | 354 return ReadInlinedObject(object_id, patch_object_id, patch_offset); |
| 347 } | 355 } |
| 348 } | 356 } |
| 349 | 357 |
| 350 | 358 |
| 351 RawObject* SnapshotReader::ReadObjectRef() { | 359 RawObject* SnapshotReader::ReadObjectRef(intptr_t patch_object_id, |
| 360 intptr_t patch_offset) { | |
| 352 int64_t header_value = Read<int64_t>(); | 361 int64_t header_value = Read<int64_t>(); |
| 353 if ((header_value & kSmiTagMask) == kSmiTag) { | 362 if ((header_value & kSmiTagMask) == kSmiTag) { |
| 354 return NewInteger(header_value); | 363 return NewInteger(header_value); |
| 355 } | 364 } |
| 356 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); | 365 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
| 357 intptr_t value = static_cast<intptr_t>(header_value); | 366 intptr_t value = static_cast<intptr_t>(header_value); |
| 358 if (IsVMIsolateObject(value)) { | 367 if (IsVMIsolateObject(value)) { |
| 359 return ReadVMIsolateObject(value); | 368 return ReadVMIsolateObject(value); |
| 360 } else if (SerializedHeaderTag::decode(value) == kObjectId) { | 369 } else if (SerializedHeaderTag::decode(value) == kObjectId) { |
| 361 return ReadIndexedObject(SerializedHeaderData::decode(value)); | 370 return ReadIndexedObject(SerializedHeaderData::decode(value), |
| 371 patch_object_id, | |
| 372 patch_offset); | |
| 362 } | 373 } |
| 363 ASSERT(SerializedHeaderTag::decode(value) == kInlined); | 374 ASSERT(SerializedHeaderTag::decode(value) == kInlined); |
| 364 intptr_t object_id = SerializedHeaderData::decode(value); | 375 intptr_t object_id = SerializedHeaderData::decode(value); |
| 365 if (object_id == kOmittedObjectId) { | 376 if (object_id == kOmittedObjectId) { |
| 366 object_id = NextAvailableObjectId(); | 377 object_id = NextAvailableObjectId(); |
| 367 } | 378 } |
| 368 ASSERT(GetBackRef(object_id) == NULL); | 379 ASSERT(GetBackRef(object_id) == NULL); |
| 369 | 380 |
| 370 // Read the class header information and lookup the class. | 381 // Read the class header information and lookup the class. |
| 371 intptr_t class_header = Read<int32_t>(); | 382 intptr_t class_header = Read<int32_t>(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 449 tags = RawObject::ClassIdTag::update(class_id, tags); | 460 tags = RawObject::ClassIdTag::update(class_id, tags); |
| 450 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); | 461 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); |
| 451 break; | 462 break; |
| 452 } | 463 } |
| 453 #undef SNAPSHOT_READ | 464 #undef SNAPSHOT_READ |
| 454 default: UNREACHABLE(); break; | 465 default: UNREACHABLE(); break; |
| 455 } | 466 } |
| 456 if (kind_ == Snapshot::kFull) { | 467 if (kind_ == Snapshot::kFull) { |
| 457 pobj_.SetCreatedFromSnapshot(); | 468 pobj_.SetCreatedFromSnapshot(); |
| 458 } | 469 } |
| 470 AddPatchRecord(object_id, patch_object_id, patch_offset); | |
| 459 return pobj_.raw(); | 471 return pobj_.raw(); |
| 460 } | 472 } |
| 461 | 473 |
| 462 | 474 |
| 463 void SnapshotReader::AddBackRef(intptr_t id, | 475 void SnapshotReader::AddBackRef(intptr_t id, |
| 464 Object* obj, | 476 Object* obj, |
| 465 DeserializeState state) { | 477 DeserializeState state, |
| 478 bool defer_canonicalization) { | |
| 466 intptr_t index = (id - kMaxPredefinedObjectIds); | 479 intptr_t index = (id - kMaxPredefinedObjectIds); |
| 467 ASSERT(index >= max_vm_isolate_object_id_); | 480 ASSERT(index >= max_vm_isolate_object_id_); |
| 468 index -= max_vm_isolate_object_id_; | 481 index -= max_vm_isolate_object_id_; |
| 469 ASSERT(index == backward_references_->length()); | 482 ASSERT(index == backward_references_->length()); |
| 470 BackRefNode node(obj, state); | 483 BackRefNode node(obj, state, defer_canonicalization); |
| 471 backward_references_->Add(node); | 484 backward_references_->Add(node); |
| 472 } | 485 } |
| 473 | 486 |
| 474 | 487 |
| 475 Object* SnapshotReader::GetBackRef(intptr_t id) { | 488 Object* SnapshotReader::GetBackRef(intptr_t id) { |
| 476 ASSERT(id >= kMaxPredefinedObjectIds); | 489 ASSERT(id >= kMaxPredefinedObjectIds); |
| 477 intptr_t index = (id - kMaxPredefinedObjectIds); | 490 intptr_t index = (id - kMaxPredefinedObjectIds); |
| 478 ASSERT(index >= max_vm_isolate_object_id_); | 491 ASSERT(index >= max_vm_isolate_object_id_); |
| 479 index -= max_vm_isolate_object_id_; | 492 index -= max_vm_isolate_object_id_; |
| 480 if (index < backward_references_->length()) { | 493 if (index < backward_references_->length()) { |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 985 return isolate()->class_table()->At(class_id); // get singleton class. | 998 return isolate()->class_table()->At(class_id); // get singleton class. |
| 986 } else { | 999 } else { |
| 987 ASSERT(Symbols::IsVMSymbolId(object_id)); | 1000 ASSERT(Symbols::IsVMSymbolId(object_id)); |
| 988 return Symbols::GetVMSymbol(object_id); // return VM symbol. | 1001 return Symbols::GetVMSymbol(object_id); // return VM symbol. |
| 989 } | 1002 } |
| 990 UNREACHABLE(); | 1003 UNREACHABLE(); |
| 991 return Object::null(); | 1004 return Object::null(); |
| 992 } | 1005 } |
| 993 | 1006 |
| 994 | 1007 |
| 995 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { | 1008 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id, |
| 1009 intptr_t patch_object_id, | |
| 1010 intptr_t patch_offset) { | |
| 996 intptr_t class_id = ClassIdFromObjectId(object_id); | 1011 intptr_t class_id = ClassIdFromObjectId(object_id); |
| 997 if (IsObjectStoreClassId(class_id)) { | 1012 if (IsObjectStoreClassId(class_id)) { |
| 998 return isolate()->class_table()->At(class_id); // get singleton class. | 1013 return isolate()->class_table()->At(class_id); // get singleton class. |
| 999 } | 1014 } |
| 1000 if (kind_ != Snapshot::kFull) { | 1015 if (kind_ != Snapshot::kFull) { |
| 1001 if (IsObjectStoreTypeId(object_id)) { | 1016 if (IsObjectStoreTypeId(object_id)) { |
| 1002 return GetType(object_store(), object_id); // return type obj. | 1017 return GetType(object_store(), object_id); // return type obj. |
| 1003 } | 1018 } |
| 1004 } | 1019 } |
| 1005 ASSERT(object_id >= kMaxPredefinedObjectIds); | 1020 ASSERT(object_id >= kMaxPredefinedObjectIds); |
| 1006 intptr_t index = (object_id - kMaxPredefinedObjectIds); | 1021 intptr_t index = (object_id - kMaxPredefinedObjectIds); |
| 1007 if (index < max_vm_isolate_object_id_) { | 1022 if (index < max_vm_isolate_object_id_) { |
| 1008 return VmIsolateSnapshotObject(index); | 1023 return VmIsolateSnapshotObject(index); |
| 1009 } | 1024 } |
| 1025 AddPatchRecord(object_id, patch_object_id, patch_offset); | |
| 1010 return GetBackRef(object_id)->raw(); | 1026 return GetBackRef(object_id)->raw(); |
| 1011 } | 1027 } |
| 1012 | 1028 |
| 1013 | 1029 |
| 1014 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) { | 1030 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id, |
| 1031 intptr_t patch_object_id, | |
| 1032 intptr_t patch_offset) { | |
| 1015 // Read the class header information and lookup the class. | 1033 // Read the class header information and lookup the class. |
| 1016 intptr_t class_header = Read<int32_t>(); | 1034 intptr_t class_header = Read<int32_t>(); |
| 1017 intptr_t tags = ReadTags(); | 1035 intptr_t tags = ReadTags(); |
| 1018 intptr_t header_id = SerializedHeaderData::decode(class_header); | 1036 intptr_t header_id = SerializedHeaderData::decode(class_header); |
| 1037 bool is_canonical = RawObject::IsCanonical(tags); | |
| 1019 if (header_id == kInstanceObjectId) { | 1038 if (header_id == kInstanceObjectId) { |
| 1020 // Object is regular dart instance. | 1039 // Object is regular dart instance. |
| 1021 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id)); | 1040 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id)); |
| 1022 intptr_t instance_size = 0; | 1041 intptr_t instance_size = 0; |
| 1023 if (result == NULL) { | 1042 if (result == NULL) { |
| 1024 result = &(Instance::ZoneHandle(zone(), Instance::null())); | 1043 result = &(Instance::ZoneHandle(zone(), Instance::null())); |
| 1025 AddBackRef(object_id, result, kIsDeserialized); | 1044 AddBackRef(object_id, result, kIsDeserialized); |
| 1026 cls_ ^= ReadObjectImpl(); | 1045 cls_ ^= ReadObjectImpl(); |
| 1027 ASSERT(!cls_.IsNull()); | 1046 ASSERT(!cls_.IsNull()); |
| 1028 instance_size = cls_.instance_size(); | 1047 instance_size = cls_.instance_size(); |
| 1029 ASSERT(instance_size > 0); | 1048 ASSERT(instance_size > 0); |
| 1030 // Allocate the instance and read in all the fields for the object. | 1049 // Allocate the instance and read in all the fields for the object. |
| 1031 if (kind_ == Snapshot::kFull) { | 1050 if (kind_ == Snapshot::kFull) { |
| 1032 *result ^= AllocateUninitialized(cls_.id(), instance_size); | 1051 *result ^= AllocateUninitialized(cls_.id(), instance_size); |
| 1033 } else { | 1052 } else { |
| 1034 *result ^= Object::Allocate(cls_.id(), | 1053 *result ^= Object::Allocate(cls_.id(), |
| 1035 instance_size, | 1054 instance_size, |
| 1036 HEAP_SPACE(kind_)); | 1055 HEAP_SPACE(kind_)); |
| 1037 } | 1056 } |
| 1038 } else { | 1057 } else { |
| 1039 cls_ ^= ReadObjectImpl(); | 1058 cls_ ^= ReadObjectImpl(); |
| 1040 ASSERT(!cls_.IsNull()); | 1059 ASSERT(!cls_.IsNull()); |
| 1041 instance_size = cls_.instance_size(); | 1060 instance_size = cls_.instance_size(); |
| 1042 } | 1061 } |
| 1043 intptr_t next_field_offset = cls_.next_field_offset(); | 1062 intptr_t next_field_offset = cls_.next_field_offset(); |
| 1044 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); | 1063 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); |
| 1045 ASSERT(next_field_offset > 0); | 1064 ASSERT(next_field_offset > 0); |
| 1046 // Instance::NextFieldOffset() returns the offset of the first field in | 1065 // Instance::NextFieldOffset() returns the offset of the first field in |
| 1047 // a Dart object. | 1066 // a Dart object. |
| 1048 bool is_canonical = RawObject::IsCanonical(tags); | |
| 1049 intptr_t offset = Instance::NextFieldOffset(); | 1067 intptr_t offset = Instance::NextFieldOffset(); |
| 1050 intptr_t result_cid = result->GetClassId(); | 1068 intptr_t result_cid = result->GetClassId(); |
| 1051 while (offset < next_field_offset) { | 1069 while (offset < next_field_offset) { |
| 1052 pobj_ = is_canonical ? ReadObjectImpl() : ReadObjectRef(); | 1070 pobj_ = is_canonical ? ReadObjectImpl() : ReadObjectRef(); |
| 1053 result->SetFieldAtOffset(offset, pobj_); | 1071 result->SetFieldAtOffset(offset, pobj_); |
| 1054 if ((offset != type_argument_field_offset) && | 1072 if ((offset != type_argument_field_offset) && |
| 1055 (kind_ == Snapshot::kMessage)) { | 1073 (kind_ == Snapshot::kMessage)) { |
| 1056 // TODO(fschneider): Consider hoisting these lookups out of the loop. | 1074 // TODO(fschneider): Consider hoisting these lookups out of the loop. |
| 1057 // This would involve creating a handle, since cls_ can't be reused | 1075 // This would involve creating a handle, since cls_ can't be reused |
| 1058 // across the call to ReadObjectRef. | 1076 // across the call to ReadObjectRef. |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1069 offset += kWordSize; | 1087 offset += kWordSize; |
| 1070 } | 1088 } |
| 1071 if (kind_ == Snapshot::kFull) { | 1089 if (kind_ == Snapshot::kFull) { |
| 1072 // We create an uninitialized object in the case of full snapshots, so | 1090 // We create an uninitialized object in the case of full snapshots, so |
| 1073 // we need to initialize any remaining padding area with the Null object. | 1091 // we need to initialize any remaining padding area with the Null object. |
| 1074 while (offset < instance_size) { | 1092 while (offset < instance_size) { |
| 1075 result->SetFieldAtOffset(offset, Object::null_object()); | 1093 result->SetFieldAtOffset(offset, Object::null_object()); |
| 1076 offset += kWordSize; | 1094 offset += kWordSize; |
| 1077 } | 1095 } |
| 1078 result->SetCreatedFromSnapshot(); | 1096 result->SetCreatedFromSnapshot(); |
| 1079 } else if (RawObject::IsCanonical(tags)) { | 1097 } else if (is_canonical) { |
| 1080 *result = result->CheckAndCanonicalize(NULL); | 1098 *result = result->CheckAndCanonicalize(NULL); |
| 1081 ASSERT(!result->IsNull()); | 1099 ASSERT(!result->IsNull()); |
| 1082 } | 1100 } |
| 1083 return result->raw(); | 1101 return result->raw(); |
| 1084 } else if (header_id == kStaticImplicitClosureObjectId) { | 1102 } else if (header_id == kStaticImplicitClosureObjectId) { |
| 1085 // We do not use the tags as the implicit static closure | 1103 // We do not use the tags as the implicit static closure |
| 1086 // is going to be created in this isolate or the canonical | 1104 // is going to be created in this isolate or the canonical |
| 1087 // version already created in the isolate will be used. | 1105 // version already created in the isolate will be used. |
| 1088 return ReadStaticImplicitClosure(object_id, class_header); | 1106 return ReadStaticImplicitClosure(object_id, class_header); |
| 1089 } | 1107 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1113 tags = RawObject::ClassIdTag::update(class_id, tags); | 1131 tags = RawObject::ClassIdTag::update(class_id, tags); |
| 1114 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); | 1132 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); |
| 1115 break; | 1133 break; |
| 1116 } | 1134 } |
| 1117 #undef SNAPSHOT_READ | 1135 #undef SNAPSHOT_READ |
| 1118 default: UNREACHABLE(); break; | 1136 default: UNREACHABLE(); break; |
| 1119 } | 1137 } |
| 1120 if (kind_ == Snapshot::kFull) { | 1138 if (kind_ == Snapshot::kFull) { |
| 1121 pobj_.SetCreatedFromSnapshot(); | 1139 pobj_.SetCreatedFromSnapshot(); |
| 1122 } | 1140 } |
| 1141 AddPatchRecord(object_id, patch_object_id, patch_offset); | |
| 1123 return pobj_.raw(); | 1142 return pobj_.raw(); |
| 1124 } | 1143 } |
| 1125 | 1144 |
| 1126 | 1145 |
| 1127 void SnapshotReader::ArrayReadFrom(const Array& result, | 1146 void SnapshotReader::AddPatchRecord(intptr_t object_id, |
| 1147 intptr_t patch_object_id, | |
| 1148 intptr_t patch_offset) { | |
| 1149 if (patch_object_id != kInvalidPatchIndex && kind() != Snapshot::kFull) { | |
| 1150 ASSERT(object_id >= kMaxPredefinedObjectIds); | |
| 1151 intptr_t index = (object_id - kMaxPredefinedObjectIds); | |
| 1152 ASSERT(index >= max_vm_isolate_object_id_); | |
| 1153 index -= max_vm_isolate_object_id_; | |
| 1154 ASSERT(index < backward_references_->length()); | |
| 1155 BackRefNode& ref = (*backward_references_)[index]; | |
| 1156 if (ref.defer_canonicalization()) { | |
|
rmacnak
2015/07/28 22:43:22
Redundant with check in AddPatchRecord.
siva
2015/07/30 02:03:48
Removed check.
| |
| 1157 ref.AddPatchRecord(patch_object_id, patch_offset); | |
| 1158 } | |
| 1159 } | |
| 1160 } | |
| 1161 | |
| 1162 | |
| 1163 void SnapshotReader::ProcessDeferredCanonicalizations() { | |
| 1164 AbstractType& typeobj = AbstractType::Handle(); | |
| 1165 TypeArguments& typeargs = TypeArguments::Handle(); | |
| 1166 Object& newobj = Object::Handle(); | |
| 1167 for (intptr_t i = 0; i < backward_references_->length(); i++) { | |
| 1168 BackRefNode& backref = (*backward_references_)[i]; | |
| 1169 if (backref.defer_canonicalization()) { | |
| 1170 Object* objref = backref.reference(); | |
| 1171 // Object should either be an abstract type or a type argument. | |
| 1172 if (objref->IsAbstractType()) { | |
| 1173 typeobj ^= objref->raw(); | |
| 1174 typeobj.ClearCanonical(); | |
| 1175 newobj = typeobj.Canonicalize(); | |
| 1176 } else { | |
| 1177 ASSERT(objref->IsTypeArguments()); | |
| 1178 typeargs ^= objref->raw(); | |
| 1179 typeargs.ClearCanonical(); | |
| 1180 newobj = typeargs.Canonicalize(); | |
| 1181 } | |
| 1182 if (newobj.raw() == objref->raw()) { | |
| 1183 // Restore Canonical bit. | |
| 1184 objref->SetCanonical(); | |
| 1185 } else { | |
| 1186 ZoneGrowableArray<intptr_t>* patches = backref.patch_records(); | |
| 1187 ASSERT(newobj.IsCanonical()); | |
| 1188 ASSERT(patches != NULL); | |
| 1189 for (intptr_t j = 0; j < patches->length(); j+=2) { | |
| 1190 NoSafepointScope no_safepoint; | |
| 1191 intptr_t patch_object_id = (*patches)[j]; | |
| 1192 intptr_t patch_offset = (*patches)[j + 1]; | |
| 1193 Object* target = GetBackRef(patch_object_id); | |
| 1194 RawObject** rawptr = | |
| 1195 reinterpret_cast<RawObject**>(target->raw()->ptr()); | |
| 1196 target->StorePointer((rawptr + patch_offset), newobj.raw()); | |
| 1197 } | |
| 1198 } | |
| 1199 } | |
| 1200 } | |
| 1201 } | |
| 1202 | |
| 1203 | |
| 1204 void SnapshotReader::ArrayReadFrom(intptr_t object_id, | |
| 1205 const Array& result, | |
| 1128 intptr_t len, | 1206 intptr_t len, |
| 1129 intptr_t tags) { | 1207 intptr_t tags) { |
| 1130 // Set the object tags. | 1208 // Set the object tags. |
| 1131 result.set_tags(tags); | 1209 result.set_tags(tags); |
| 1132 | 1210 |
| 1133 // Setup the object fields. | 1211 // Setup the object fields. |
| 1134 *TypeArgumentsHandle() ^= ReadObjectImpl(); | 1212 intptr_t typeargs_offset = |
| 1213 reinterpret_cast<RawObject**>(&result.raw()->ptr()->type_arguments_) - | |
| 1214 reinterpret_cast<RawObject**>(result.raw()->ptr()); | |
| 1215 *TypeArgumentsHandle() ^= ReadObjectImpl(object_id, typeargs_offset); | |
| 1135 result.SetTypeArguments(*TypeArgumentsHandle()); | 1216 result.SetTypeArguments(*TypeArgumentsHandle()); |
| 1136 | 1217 |
| 1137 bool is_canonical = RawObject::IsCanonical(tags); | 1218 bool is_canonical = RawObject::IsCanonical(tags); |
| 1138 | 1219 |
| 1220 intptr_t offset = result.raw_ptr()->data() - | |
| 1221 reinterpret_cast<RawObject**>(result.raw()->ptr()); | |
| 1139 for (intptr_t i = 0; i < len; i++) { | 1222 for (intptr_t i = 0; i < len; i++) { |
| 1140 *PassiveObjectHandle() = is_canonical ? ReadObjectImpl() : ReadObjectRef(); | 1223 *PassiveObjectHandle() = is_canonical ? |
| 1224 ReadObjectImpl(object_id, i) : ReadObjectRef(object_id, (i + offset)); | |
| 1141 result.SetAt(i, *PassiveObjectHandle()); | 1225 result.SetAt(i, *PassiveObjectHandle()); |
| 1142 } | 1226 } |
| 1143 } | 1227 } |
| 1144 | 1228 |
| 1145 | 1229 |
| 1146 VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer, | 1230 VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer, |
| 1147 intptr_t size, | 1231 intptr_t size, |
| 1148 Zone* zone) | 1232 Zone* zone) |
| 1149 : SnapshotReader(buffer, | 1233 : SnapshotReader(buffer, |
| 1150 size, | 1234 size, |
| (...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2348 NoSafepointScope no_safepoint; | 2432 NoSafepointScope no_safepoint; |
| 2349 WriteObject(obj.raw()); | 2433 WriteObject(obj.raw()); |
| 2350 UnmarkAll(); | 2434 UnmarkAll(); |
| 2351 } else { | 2435 } else { |
| 2352 ThrowException(exception_type(), exception_msg()); | 2436 ThrowException(exception_type(), exception_msg()); |
| 2353 } | 2437 } |
| 2354 } | 2438 } |
| 2355 | 2439 |
| 2356 | 2440 |
| 2357 } // namespace dart | 2441 } // namespace dart |
| OLD | NEW |