Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: runtime/vm/snapshot.cc

Issue 1255003004: Implement patch records to patch canonical objects. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: merged-to-tot Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698