| 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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 (kind == Snapshot::kFull) ? | 199 (kind == Snapshot::kFull) ? |
| 200 Object::vm_isolate_snapshot_object_table().Length() : 0), | 200 Object::vm_isolate_snapshot_object_table().Length() : 0), |
| 201 backward_references_(backward_refs) { | 201 backward_references_(backward_refs) { |
| 202 } | 202 } |
| 203 | 203 |
| 204 | 204 |
| 205 RawObject* SnapshotReader::ReadObject() { | 205 RawObject* SnapshotReader::ReadObject() { |
| 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 = |
| 210 PassiveObject::Handle(isolate(), ReadObjectImpl(kAsInlinedObject)); |
| 210 for (intptr_t i = 0; i < backward_references_->length(); i++) { | 211 for (intptr_t i = 0; i < backward_references_->length(); i++) { |
| 211 if (!(*backward_references_)[i].is_deserialized()) { | 212 if (!(*backward_references_)[i].is_deserialized()) { |
| 212 ReadObjectImpl(); | 213 ReadObjectImpl(kAsInlinedObject); |
| 213 (*backward_references_)[i].set_state(kIsDeserialized); | 214 (*backward_references_)[i].set_state(kIsDeserialized); |
| 214 } | 215 } |
| 215 } | 216 } |
| 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, kAsInlinedObject); |
| 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(kAsInlinedObject); |
| 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()); |
| 249 return cls.raw(); | 250 return cls.raw(); |
| 250 } | 251 } |
| 251 | 252 |
| 252 | 253 |
| 253 RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id, | 254 RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id, |
| 254 intptr_t class_header) { | 255 intptr_t class_header) { |
| 255 ASSERT(kind_ == Snapshot::kMessage); | 256 ASSERT(kind_ == Snapshot::kMessage); |
| 256 | 257 |
| 257 // First create a function object and associate it with the specified | 258 // First create a function object and associate it with the specified |
| 258 // 'object_id'. | 259 // 'object_id'. |
| 259 Function& func = Function::Handle(isolate(), Function::null()); | 260 Function& func = Function::Handle(isolate(), Function::null()); |
| 260 Instance& obj = Instance::ZoneHandle(zone(), Instance::null()); | 261 Instance& obj = Instance::ZoneHandle(zone(), Instance::null()); |
| 261 AddBackRef(object_id, &obj, kIsDeserialized); | 262 AddBackRef(object_id, &obj, kIsDeserialized); |
| 262 | 263 |
| 263 // Read the library/class/function information and lookup the function. | 264 // Read the library/class/function information and lookup the function. |
| 264 str_ ^= ReadObjectImpl(); | 265 str_ ^= ReadObjectImpl(kAsInlinedObject); |
| 265 library_ = Library::LookupLibrary(str_); | 266 library_ = Library::LookupLibrary(str_); |
| 266 if (library_.IsNull() || !library_.Loaded()) { | 267 if (library_.IsNull() || !library_.Loaded()) { |
| 267 SetReadException("Invalid Library object found in message."); | 268 SetReadException("Invalid Library object found in message."); |
| 268 } | 269 } |
| 269 str_ ^= ReadObjectImpl(); | 270 str_ ^= ReadObjectImpl(kAsInlinedObject); |
| 270 if (str_.Equals(Symbols::TopLevel())) { | 271 if (str_.Equals(Symbols::TopLevel())) { |
| 271 str_ ^= ReadObjectImpl(); | 272 str_ ^= ReadObjectImpl(kAsInlinedObject); |
| 272 func = library_.LookupFunctionAllowPrivate(str_); | 273 func = library_.LookupFunctionAllowPrivate(str_); |
| 273 } else { | 274 } else { |
| 274 cls_ = library_.LookupClassAllowPrivate(str_); | 275 cls_ = library_.LookupClassAllowPrivate(str_); |
| 275 if (cls_.IsNull()) { | 276 if (cls_.IsNull()) { |
| 276 OS::Print("Name of class not found %s\n", str_.ToCString()); | 277 OS::Print("Name of class not found %s\n", str_.ToCString()); |
| 277 SetReadException("Invalid Class object found in message."); | 278 SetReadException("Invalid Class object found in message."); |
| 278 } | 279 } |
| 279 cls_.EnsureIsFinalized(isolate()); | 280 cls_.EnsureIsFinalized(isolate()); |
| 280 str_ ^= ReadObjectImpl(); | 281 str_ ^= ReadObjectImpl(kAsInlinedObject); |
| 281 func = cls_.LookupFunctionAllowPrivate(str_); | 282 func = cls_.LookupFunctionAllowPrivate(str_); |
| 282 } | 283 } |
| 283 if (func.IsNull()) { | 284 if (func.IsNull()) { |
| 284 SetReadException("Invalid function object found in message."); | 285 SetReadException("Invalid function object found in message."); |
| 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 int64_t value = Read<int64_t>(); | |
| 297 if ((value & kSmiTagMask) == kSmiTag) { | |
| 298 return NewInteger(value); | |
| 299 } | |
| 300 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | |
| 301 return ReadObjectImpl(static_cast<intptr_t>(value)); | |
| 302 } | |
| 303 | |
| 304 | |
| 305 intptr_t SnapshotReader::NextAvailableObjectId() const { | 296 intptr_t SnapshotReader::NextAvailableObjectId() const { |
| 306 return backward_references_->length() + | 297 return backward_references_->length() + |
| 307 kMaxPredefinedObjectIds + max_vm_isolate_object_id_; | 298 kMaxPredefinedObjectIds + max_vm_isolate_object_id_; |
| 308 } | 299 } |
| 309 | 300 |
| 310 | 301 |
| 311 void SnapshotReader::SetReadException(const char* msg) { | 302 void SnapshotReader::SetReadException(const char* msg) { |
| 312 Isolate* isolate = Isolate::Current(); | 303 Isolate* isolate = Isolate::Current(); |
| 313 const String& error_str = String::Handle(isolate, String::New(msg)); | 304 const String& error_str = String::Handle(isolate, String::New(msg)); |
| 314 const Array& args = Array::Handle(isolate, Array::New(1)); | 305 const Array& args = Array::Handle(isolate, Array::New(1)); |
| 315 args.SetAt(0, error_str); | 306 args.SetAt(0, error_str); |
| 316 Object& result = Object::Handle(isolate); | 307 Object& result = Object::Handle(isolate); |
| 317 const Library& library = Library::Handle(isolate, Library::CoreLibrary()); | 308 const Library& library = Library::Handle(isolate, Library::CoreLibrary()); |
| 318 result = DartLibraryCalls::InstanceCreate(library, | 309 result = DartLibraryCalls::InstanceCreate(library, |
| 319 Symbols::ArgumentError(), | 310 Symbols::ArgumentError(), |
| 320 Symbols::Dot(), | 311 Symbols::Dot(), |
| 321 args); | 312 args); |
| 322 const Stacktrace& stacktrace = Stacktrace::Handle(isolate); | 313 const Stacktrace& stacktrace = Stacktrace::Handle(isolate); |
| 323 const UnhandledException& error = UnhandledException::Handle( | 314 const UnhandledException& error = UnhandledException::Handle( |
| 324 isolate, UnhandledException::New(Instance::Cast(result), stacktrace)); | 315 isolate, UnhandledException::New(Instance::Cast(result), stacktrace)); |
| 325 isolate->long_jump_base()->Jump(1, error); | 316 isolate->long_jump_base()->Jump(1, error); |
| 326 } | 317 } |
| 327 | 318 |
| 328 | 319 |
| 329 RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const { | 320 RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const { |
| 330 return Object::vm_isolate_snapshot_object_table().At(index); | 321 return Object::vm_isolate_snapshot_object_table().At(index); |
| 331 } | 322 } |
| 332 | 323 |
| 333 | 324 |
| 334 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { | 325 RawObject* SnapshotReader::ReadObjectImpl(bool as_reference) { |
| 326 int64_t header_value = Read<int64_t>(); |
| 327 if ((header_value & kSmiTagMask) == kSmiTag) { |
| 328 return NewInteger(header_value); |
| 329 } |
| 330 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
| 331 return ReadObjectImpl(static_cast<intptr_t>(header_value), as_reference); |
| 332 } |
| 333 |
| 334 |
| 335 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value, |
| 336 bool as_reference) { |
| 335 if (IsVMIsolateObject(header_value)) { | 337 if (IsVMIsolateObject(header_value)) { |
| 336 return ReadVMIsolateObject(header_value); | 338 return ReadVMIsolateObject(header_value); |
| 337 } else { | 339 } else { |
| 338 if (SerializedHeaderTag::decode(header_value) == kObjectId) { | 340 if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
| 339 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); | 341 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
| 340 } | 342 } |
| 341 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); | 343 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
| 342 intptr_t object_id = SerializedHeaderData::decode(header_value); | 344 intptr_t object_id = SerializedHeaderData::decode(header_value); |
| 343 if (object_id == kOmittedObjectId) { | 345 if (object_id == kOmittedObjectId) { |
| 344 object_id = NextAvailableObjectId(); | 346 object_id = NextAvailableObjectId(); |
| 345 } | 347 } |
| 346 return ReadInlinedObject(object_id); | 348 |
| 349 // Read the class header information. |
| 350 intptr_t class_header = Read<int32_t>(); |
| 351 intptr_t tags = ReadTags(); |
| 352 if (as_reference && !RawObject::IsCanonical(tags)) { |
| 353 return ReadObjectRef(object_id, class_header, tags); |
| 354 } else { |
| 355 return ReadInlinedObject(object_id, class_header, tags); |
| 356 } |
| 347 } | 357 } |
| 348 } | 358 } |
| 349 | 359 |
| 350 | 360 |
| 351 RawObject* SnapshotReader::ReadObjectRef() { | 361 RawObject* SnapshotReader::ReadObjectRef(intptr_t object_id, |
| 352 int64_t header_value = Read<int64_t>(); | 362 intptr_t class_header, |
| 353 if ((header_value & kSmiTagMask) == kSmiTag) { | 363 intptr_t tags) { |
| 354 return NewInteger(header_value); | |
| 355 } | |
| 356 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); | |
| 357 intptr_t value = static_cast<intptr_t>(header_value); | |
| 358 if (IsVMIsolateObject(value)) { | |
| 359 return ReadVMIsolateObject(value); | |
| 360 } else if (SerializedHeaderTag::decode(value) == kObjectId) { | |
| 361 return ReadIndexedObject(SerializedHeaderData::decode(value)); | |
| 362 } | |
| 363 ASSERT(SerializedHeaderTag::decode(value) == kInlined); | |
| 364 intptr_t object_id = SerializedHeaderData::decode(value); | |
| 365 if (object_id == kOmittedObjectId) { | |
| 366 object_id = NextAvailableObjectId(); | |
| 367 } | |
| 368 ASSERT(GetBackRef(object_id) == NULL); | |
| 369 | |
| 370 // Read the class header information and lookup the class. | |
| 371 intptr_t class_header = Read<int32_t>(); | |
| 372 | |
| 373 // Since we are only reading an object reference, If it is an instance kind | 364 // Since we are only reading an object reference, If it is an instance kind |
| 374 // then we only need to figure out the class of the object and allocate an | 365 // then we only need to figure out the class of the object and allocate an |
| 375 // instance of it. The individual fields will be read later. | 366 // instance of it. The individual fields will be read later. |
| 376 intptr_t header_id = SerializedHeaderData::decode(class_header); | 367 intptr_t header_id = SerializedHeaderData::decode(class_header); |
| 377 if (header_id == kInstanceObjectId) { | 368 if (header_id == kInstanceObjectId) { |
| 378 Instance& result = Instance::ZoneHandle(zone(), Instance::null()); | 369 Instance& result = Instance::ZoneHandle(zone(), Instance::null()); |
| 379 AddBackRef(object_id, &result, kIsNotDeserialized); | 370 AddBackRef(object_id, &result, kIsNotDeserialized); |
| 380 | 371 |
| 381 cls_ ^= ReadObjectImpl(); // Read class information. | 372 cls_ ^= ReadObjectImpl(kAsInlinedObject); // Read class information. |
| 382 ASSERT(!cls_.IsNull()); | 373 ASSERT(!cls_.IsNull()); |
| 383 intptr_t instance_size = cls_.instance_size(); | 374 intptr_t instance_size = cls_.instance_size(); |
| 384 ASSERT(instance_size > 0); | 375 ASSERT(instance_size > 0); |
| 385 if (kind_ == Snapshot::kFull) { | 376 if (kind_ == Snapshot::kFull) { |
| 386 result ^= AllocateUninitialized(cls_.id(), instance_size); | 377 result ^= AllocateUninitialized(cls_.id(), instance_size); |
| 387 } else { | 378 } else { |
| 388 result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_)); | 379 result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_)); |
| 389 } | 380 } |
| 390 return result.raw(); | 381 return result.raw(); |
| 391 } else if (header_id == kStaticImplicitClosureObjectId) { | 382 } else if (header_id == kStaticImplicitClosureObjectId) { |
| 392 // We skip the tags that have been written as the implicit static | 383 // We skip the tags that have been written as the implicit static |
| 393 // closure is going to be created in this isolate or the canonical | 384 // closure is going to be created in this isolate or the canonical |
| 394 // version already created in the isolate will be used. | 385 // version already created in the isolate will be used. |
| 395 ReadTags(); | |
| 396 return ReadStaticImplicitClosure(object_id, class_header); | 386 return ReadStaticImplicitClosure(object_id, class_header); |
| 397 } | 387 } |
| 398 ASSERT((class_header & kSmiTagMask) != kSmiTag); | 388 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 399 | 389 |
| 400 // Similarly Array and ImmutableArray objects are also similarly only | 390 // Similarly Array and ImmutableArray objects are also similarly only |
| 401 // allocated here, the individual array elements are read later. | 391 // allocated here, the individual array elements are read later. |
| 402 intptr_t class_id = LookupInternalClass(class_header); | 392 intptr_t class_id = LookupInternalClass(class_header); |
| 403 if (class_id == kArrayCid) { | 393 if (class_id == kArrayCid) { |
| 404 // Read the length and allocate an object based on the len. | 394 // Read the length and allocate an object based on the len. |
| 405 intptr_t len = ReadSmiValue(); | 395 intptr_t len = ReadSmiValue(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 417 Array& array = Array::ZoneHandle( | 407 Array& array = Array::ZoneHandle( |
| 418 zone(), | 408 zone(), |
| 419 (kind_ == Snapshot::kFull) ? | 409 (kind_ == Snapshot::kFull) ? |
| 420 NewImmutableArray(len) : ImmutableArray::New(len, HEAP_SPACE(kind_))); | 410 NewImmutableArray(len) : ImmutableArray::New(len, HEAP_SPACE(kind_))); |
| 421 AddBackRef(object_id, &array, kIsNotDeserialized); | 411 AddBackRef(object_id, &array, kIsNotDeserialized); |
| 422 | 412 |
| 423 return array.raw(); | 413 return array.raw(); |
| 424 } | 414 } |
| 425 | 415 |
| 426 // For all other internal VM classes we read the object inline. | 416 // For all other internal VM classes we read the object inline. |
| 427 intptr_t tags = ReadTags(); | |
| 428 switch (class_id) { | 417 switch (class_id) { |
| 429 #define SNAPSHOT_READ(clazz) \ | 418 #define SNAPSHOT_READ(clazz) \ |
| 430 case clazz::kClassId: { \ | 419 case clazz::kClassId: { \ |
| 420 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ |
| 421 break; \ |
| 422 } |
| 423 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
| 424 #undef SNAPSHOT_READ |
| 425 #define SNAPSHOT_READ(clazz) \ |
| 426 case kTypedData##clazz##Cid: \ |
| 427 |
| 428 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
| 429 tags = RawObject::ClassIdTag::update(class_id, tags); |
| 430 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_); |
| 431 break; |
| 432 } |
| 433 #undef SNAPSHOT_READ |
| 434 #define SNAPSHOT_READ(clazz) \ |
| 435 case kExternalTypedData##clazz##Cid: \ |
| 436 |
| 437 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
| 438 tags = RawObject::ClassIdTag::update(class_id, tags); |
| 439 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); |
| 440 break; |
| 441 } |
| 442 #undef SNAPSHOT_READ |
| 443 default: UNREACHABLE(); break; |
| 444 } |
| 445 if (kind_ == Snapshot::kFull) { |
| 446 pobj_.SetCreatedFromSnapshot(); |
| 447 } |
| 448 return pobj_.raw(); |
| 449 } |
| 450 |
| 451 |
| 452 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id, |
| 453 intptr_t class_header, |
| 454 intptr_t tags) { |
| 455 // Lookup the class based on the class header information. |
| 456 intptr_t header_id = SerializedHeaderData::decode(class_header); |
| 457 if (header_id == kInstanceObjectId) { |
| 458 // Object is regular dart instance. |
| 459 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id)); |
| 460 intptr_t instance_size = 0; |
| 461 if (result == NULL) { |
| 462 result = &(Instance::ZoneHandle(zone(), Instance::null())); |
| 463 AddBackRef(object_id, result, kIsDeserialized); |
| 464 cls_ ^= ReadObjectImpl(kAsInlinedObject); |
| 465 ASSERT(!cls_.IsNull()); |
| 466 instance_size = cls_.instance_size(); |
| 467 ASSERT(instance_size > 0); |
| 468 // Allocate the instance and read in all the fields for the object. |
| 469 if (kind_ == Snapshot::kFull) { |
| 470 *result ^= AllocateUninitialized(cls_.id(), instance_size); |
| 471 } else { |
| 472 *result ^= Object::Allocate(cls_.id(), |
| 473 instance_size, |
| 474 HEAP_SPACE(kind_)); |
| 475 } |
| 476 } else { |
| 477 cls_ ^= ReadObjectImpl(kAsInlinedObject); |
| 478 ASSERT(!cls_.IsNull()); |
| 479 instance_size = cls_.instance_size(); |
| 480 } |
| 481 intptr_t next_field_offset = cls_.next_field_offset(); |
| 482 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); |
| 483 ASSERT(next_field_offset > 0); |
| 484 // Instance::NextFieldOffset() returns the offset of the first field in |
| 485 // a Dart object. |
| 486 bool as_reference = RawObject::IsCanonical(tags) ? false : true; |
| 487 intptr_t offset = Instance::NextFieldOffset(); |
| 488 intptr_t result_cid = result->GetClassId(); |
| 489 while (offset < next_field_offset) { |
| 490 pobj_ = ReadObjectImpl(as_reference); |
| 491 result->SetFieldAtOffset(offset, pobj_); |
| 492 if ((offset != type_argument_field_offset) && |
| 493 (kind_ == Snapshot::kMessage)) { |
| 494 // TODO(fschneider): Consider hoisting these lookups out of the loop. |
| 495 // This would involve creating a handle, since cls_ can't be reused |
| 496 // across the call to ReadObjectRef. |
| 497 cls_ = isolate()->class_table()->At(result_cid); |
| 498 array_ = cls_.OffsetToFieldMap(); |
| 499 field_ ^= array_.At(offset >> kWordSizeLog2); |
| 500 ASSERT(!field_.IsNull()); |
| 501 ASSERT(field_.Offset() == offset); |
| 502 obj_ = pobj_.raw(); |
| 503 field_.RecordStore(obj_); |
| 504 } |
| 505 // TODO(fschneider): Verify the guarded cid and length for other kinds of |
| 506 // snapshot (kFull, kScript) with asserts. |
| 507 offset += kWordSize; |
| 508 } |
| 509 if (kind_ == Snapshot::kFull) { |
| 510 // We create an uninitialized object in the case of full snapshots, so |
| 511 // we need to initialize any remaining padding area with the Null object. |
| 512 while (offset < instance_size) { |
| 513 result->SetFieldAtOffset(offset, Object::null_object()); |
| 514 offset += kWordSize; |
| 515 } |
| 516 result->SetCreatedFromSnapshot(); |
| 517 } else if (RawObject::IsCanonical(tags)) { |
| 518 *result = result->CheckAndCanonicalize(NULL); |
| 519 ASSERT(!result->IsNull()); |
| 520 } |
| 521 return result->raw(); |
| 522 } else if (header_id == kStaticImplicitClosureObjectId) { |
| 523 // We do not use the tags as the implicit static closure |
| 524 // is going to be created in this isolate or the canonical |
| 525 // version already created in the isolate will be used. |
| 526 return ReadStaticImplicitClosure(object_id, class_header); |
| 527 } |
| 528 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 529 intptr_t class_id = LookupInternalClass(class_header); |
| 530 switch (class_id) { |
| 531 #define SNAPSHOT_READ(clazz) \ |
| 532 case clazz::kClassId: { \ |
| 431 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ | 533 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ |
| 432 break; \ | 534 break; \ |
| 433 } | 535 } |
| 434 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) | 536 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
| 435 #undef SNAPSHOT_READ | 537 #undef SNAPSHOT_READ |
| 436 #define SNAPSHOT_READ(clazz) \ | 538 #define SNAPSHOT_READ(clazz) \ |
| 437 case kTypedData##clazz##Cid: \ | 539 case kTypedData##clazz##Cid: \ |
| 438 | 540 |
| 439 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { | 541 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
| 440 tags = RawObject::ClassIdTag::update(class_id, tags); | 542 tags = RawObject::ClassIdTag::update(class_id, tags); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 | 618 |
| 517 // TODO(asiva): Add a check here to ensure we have the right heap | 619 // TODO(asiva): Add a check here to ensure we have the right heap |
| 518 // size for the full snapshot being read. | 620 // size for the full snapshot being read. |
| 519 { | 621 { |
| 520 NoSafepointScope no_safepoint; | 622 NoSafepointScope no_safepoint; |
| 521 HeapLocker hl(isolate, old_space()); | 623 HeapLocker hl(isolate, old_space()); |
| 522 | 624 |
| 523 // Read in all the objects stored in the object store. | 625 // Read in all the objects stored in the object store. |
| 524 intptr_t num_flds = (object_store->to() - object_store->from()); | 626 intptr_t num_flds = (object_store->to() - object_store->from()); |
| 525 for (intptr_t i = 0; i <= num_flds; i++) { | 627 for (intptr_t i = 0; i <= num_flds; i++) { |
| 526 *(object_store->from() + i) = ReadObjectImpl(); | 628 *(object_store->from() + i) = ReadObjectImpl(kAsInlinedObject); |
| 527 } | 629 } |
| 528 for (intptr_t i = 0; i < backward_references_->length(); i++) { | 630 for (intptr_t i = 0; i < backward_references_->length(); i++) { |
| 529 if (!(*backward_references_)[i].is_deserialized()) { | 631 if (!(*backward_references_)[i].is_deserialized()) { |
| 530 ReadObjectImpl(); | 632 ReadObjectImpl(kAsInlinedObject); |
| 531 (*backward_references_)[i].set_state(kIsDeserialized); | 633 (*backward_references_)[i].set_state(kIsDeserialized); |
| 532 } | 634 } |
| 533 } | 635 } |
| 534 | 636 |
| 535 // Validate the class table. | 637 // Validate the class table. |
| 536 #if defined(DEBUG) | 638 #if defined(DEBUG) |
| 537 isolate->ValidateClassTable(); | 639 isolate->ValidateClassTable(); |
| 538 #endif | 640 #endif |
| 539 | 641 |
| 540 // Setup native resolver for bootstrap impl. | 642 // Setup native resolver for bootstrap impl. |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 } | 1106 } |
| 1005 ASSERT(object_id >= kMaxPredefinedObjectIds); | 1107 ASSERT(object_id >= kMaxPredefinedObjectIds); |
| 1006 intptr_t index = (object_id - kMaxPredefinedObjectIds); | 1108 intptr_t index = (object_id - kMaxPredefinedObjectIds); |
| 1007 if (index < max_vm_isolate_object_id_) { | 1109 if (index < max_vm_isolate_object_id_) { |
| 1008 return VmIsolateSnapshotObject(index); | 1110 return VmIsolateSnapshotObject(index); |
| 1009 } | 1111 } |
| 1010 return GetBackRef(object_id)->raw(); | 1112 return GetBackRef(object_id)->raw(); |
| 1011 } | 1113 } |
| 1012 | 1114 |
| 1013 | 1115 |
| 1014 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) { | |
| 1015 // Read the class header information and lookup the class. | |
| 1016 intptr_t class_header = Read<int32_t>(); | |
| 1017 intptr_t tags = ReadTags(); | |
| 1018 intptr_t header_id = SerializedHeaderData::decode(class_header); | |
| 1019 if (header_id == kInstanceObjectId) { | |
| 1020 // Object is regular dart instance. | |
| 1021 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id)); | |
| 1022 intptr_t instance_size = 0; | |
| 1023 if (result == NULL) { | |
| 1024 result = &(Instance::ZoneHandle(zone(), Instance::null())); | |
| 1025 AddBackRef(object_id, result, kIsDeserialized); | |
| 1026 cls_ ^= ReadObjectImpl(); | |
| 1027 ASSERT(!cls_.IsNull()); | |
| 1028 instance_size = cls_.instance_size(); | |
| 1029 ASSERT(instance_size > 0); | |
| 1030 // Allocate the instance and read in all the fields for the object. | |
| 1031 if (kind_ == Snapshot::kFull) { | |
| 1032 *result ^= AllocateUninitialized(cls_.id(), instance_size); | |
| 1033 } else { | |
| 1034 *result ^= Object::Allocate(cls_.id(), | |
| 1035 instance_size, | |
| 1036 HEAP_SPACE(kind_)); | |
| 1037 } | |
| 1038 } else { | |
| 1039 cls_ ^= ReadObjectImpl(); | |
| 1040 ASSERT(!cls_.IsNull()); | |
| 1041 instance_size = cls_.instance_size(); | |
| 1042 } | |
| 1043 intptr_t next_field_offset = cls_.next_field_offset(); | |
| 1044 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); | |
| 1045 ASSERT(next_field_offset > 0); | |
| 1046 // Instance::NextFieldOffset() returns the offset of the first field in | |
| 1047 // a Dart object. | |
| 1048 bool is_canonical = RawObject::IsCanonical(tags); | |
| 1049 intptr_t offset = Instance::NextFieldOffset(); | |
| 1050 intptr_t result_cid = result->GetClassId(); | |
| 1051 while (offset < next_field_offset) { | |
| 1052 pobj_ = is_canonical ? ReadObjectImpl() : ReadObjectRef(); | |
| 1053 result->SetFieldAtOffset(offset, pobj_); | |
| 1054 if ((offset != type_argument_field_offset) && | |
| 1055 (kind_ == Snapshot::kMessage)) { | |
| 1056 // TODO(fschneider): Consider hoisting these lookups out of the loop. | |
| 1057 // This would involve creating a handle, since cls_ can't be reused | |
| 1058 // across the call to ReadObjectRef. | |
| 1059 cls_ = isolate()->class_table()->At(result_cid); | |
| 1060 array_ = cls_.OffsetToFieldMap(); | |
| 1061 field_ ^= array_.At(offset >> kWordSizeLog2); | |
| 1062 ASSERT(!field_.IsNull()); | |
| 1063 ASSERT(field_.Offset() == offset); | |
| 1064 obj_ = pobj_.raw(); | |
| 1065 field_.RecordStore(obj_); | |
| 1066 } | |
| 1067 // TODO(fschneider): Verify the guarded cid and length for other kinds of | |
| 1068 // snapshot (kFull, kScript) with asserts. | |
| 1069 offset += kWordSize; | |
| 1070 } | |
| 1071 if (kind_ == Snapshot::kFull) { | |
| 1072 // 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. | |
| 1074 while (offset < instance_size) { | |
| 1075 result->SetFieldAtOffset(offset, Object::null_object()); | |
| 1076 offset += kWordSize; | |
| 1077 } | |
| 1078 result->SetCreatedFromSnapshot(); | |
| 1079 } else if (RawObject::IsCanonical(tags)) { | |
| 1080 *result = result->CheckAndCanonicalize(NULL); | |
| 1081 ASSERT(!result->IsNull()); | |
| 1082 } | |
| 1083 return result->raw(); | |
| 1084 } else if (header_id == kStaticImplicitClosureObjectId) { | |
| 1085 // We do not use the tags as the implicit static closure | |
| 1086 // is going to be created in this isolate or the canonical | |
| 1087 // version already created in the isolate will be used. | |
| 1088 return ReadStaticImplicitClosure(object_id, class_header); | |
| 1089 } | |
| 1090 ASSERT((class_header & kSmiTagMask) != kSmiTag); | |
| 1091 intptr_t class_id = LookupInternalClass(class_header); | |
| 1092 switch (class_id) { | |
| 1093 #define SNAPSHOT_READ(clazz) \ | |
| 1094 case clazz::kClassId: { \ | |
| 1095 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ | |
| 1096 break; \ | |
| 1097 } | |
| 1098 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) | |
| 1099 #undef SNAPSHOT_READ | |
| 1100 #define SNAPSHOT_READ(clazz) \ | |
| 1101 case kTypedData##clazz##Cid: \ | |
| 1102 | |
| 1103 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { | |
| 1104 tags = RawObject::ClassIdTag::update(class_id, tags); | |
| 1105 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_); | |
| 1106 break; | |
| 1107 } | |
| 1108 #undef SNAPSHOT_READ | |
| 1109 #define SNAPSHOT_READ(clazz) \ | |
| 1110 case kExternalTypedData##clazz##Cid: \ | |
| 1111 | |
| 1112 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { | |
| 1113 tags = RawObject::ClassIdTag::update(class_id, tags); | |
| 1114 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); | |
| 1115 break; | |
| 1116 } | |
| 1117 #undef SNAPSHOT_READ | |
| 1118 default: UNREACHABLE(); break; | |
| 1119 } | |
| 1120 if (kind_ == Snapshot::kFull) { | |
| 1121 pobj_.SetCreatedFromSnapshot(); | |
| 1122 } | |
| 1123 return pobj_.raw(); | |
| 1124 } | |
| 1125 | |
| 1126 | |
| 1127 void SnapshotReader::ArrayReadFrom(const Array& result, | 1116 void SnapshotReader::ArrayReadFrom(const Array& result, |
| 1128 intptr_t len, | 1117 intptr_t len, |
| 1129 intptr_t tags) { | 1118 intptr_t tags) { |
| 1130 // Set the object tags. | 1119 // Set the object tags. |
| 1131 result.set_tags(tags); | 1120 result.set_tags(tags); |
| 1132 | 1121 |
| 1133 // Setup the object fields. | 1122 // Setup the object fields. |
| 1134 *TypeArgumentsHandle() ^= ReadObjectImpl(); | 1123 *TypeArgumentsHandle() ^= ReadObjectImpl(kAsInlinedObject); |
| 1135 result.SetTypeArguments(*TypeArgumentsHandle()); | 1124 result.SetTypeArguments(*TypeArgumentsHandle()); |
| 1136 | 1125 |
| 1137 bool is_canonical = RawObject::IsCanonical(tags); | 1126 bool as_reference = RawObject::IsCanonical(tags) ? false : true; |
| 1138 | 1127 |
| 1139 for (intptr_t i = 0; i < len; i++) { | 1128 for (intptr_t i = 0; i < len; i++) { |
| 1140 *PassiveObjectHandle() = is_canonical ? ReadObjectImpl() : ReadObjectRef(); | 1129 *PassiveObjectHandle() = ReadObjectImpl(as_reference); |
| 1141 result.SetAt(i, *PassiveObjectHandle()); | 1130 result.SetAt(i, *PassiveObjectHandle()); |
| 1142 } | 1131 } |
| 1143 } | 1132 } |
| 1144 | 1133 |
| 1145 | 1134 |
| 1146 VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer, | 1135 VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer, |
| 1147 intptr_t size, | 1136 intptr_t size, |
| 1148 Zone* zone) | 1137 Zone* zone) |
| 1149 : SnapshotReader(buffer, | 1138 : SnapshotReader(buffer, |
| 1150 size, | 1139 size, |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1277 forward_list_(forward_list), | 1266 forward_list_(forward_list), |
| 1278 exception_type_(Exceptions::kNone), | 1267 exception_type_(Exceptions::kNone), |
| 1279 exception_msg_(NULL), | 1268 exception_msg_(NULL), |
| 1280 unmarked_objects_(false), | 1269 unmarked_objects_(false), |
| 1281 can_send_any_object_(can_send_any_object) { | 1270 can_send_any_object_(can_send_any_object) { |
| 1282 ASSERT(forward_list_ != NULL); | 1271 ASSERT(forward_list_ != NULL); |
| 1283 } | 1272 } |
| 1284 | 1273 |
| 1285 | 1274 |
| 1286 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 1275 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
| 1287 WriteObjectImpl(rawobj); | 1276 WriteObjectImpl(rawobj, kAsInlinedObject); |
| 1288 WriteForwardedObjects(); | 1277 WriteForwardedObjects(); |
| 1289 } | 1278 } |
| 1290 | 1279 |
| 1291 #define VM_OBJECT_CLASS_LIST(V) \ | 1280 #define VM_OBJECT_CLASS_LIST(V) \ |
| 1292 V(OneByteString) \ | 1281 V(OneByteString) \ |
| 1293 V(Mint) \ | 1282 V(Mint) \ |
| 1294 V(Bigint) \ | 1283 V(Bigint) \ |
| 1295 V(Double) \ | 1284 V(Double) \ |
| 1296 | 1285 |
| 1297 #define VM_OBJECT_WRITE(clazz) \ | 1286 #define VM_OBJECT_WRITE(clazz) \ |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1400 break; | 1389 break; |
| 1401 } | 1390 } |
| 1402 } | 1391 } |
| 1403 } | 1392 } |
| 1404 UNREACHABLE(); | 1393 UNREACHABLE(); |
| 1405 } | 1394 } |
| 1406 | 1395 |
| 1407 #undef VM_OBJECT_WRITE | 1396 #undef VM_OBJECT_WRITE |
| 1408 | 1397 |
| 1409 | 1398 |
| 1410 void SnapshotWriter::WriteObjectRef(RawObject* raw) { | |
| 1411 // First check if object can be written as a simple predefined type. | |
| 1412 if (CheckAndWritePredefinedObject(raw)) { | |
| 1413 return; | |
| 1414 } | |
| 1415 | |
| 1416 NoSafepointScope no_safepoint; | |
| 1417 RawClass* cls = class_table_->At(raw->GetClassId()); | |
| 1418 intptr_t class_id = cls->ptr()->id_; | |
| 1419 ASSERT(class_id == raw->GetClassId()); | |
| 1420 if (class_id >= kNumPredefinedCids) { | |
| 1421 WriteInstanceRef(raw, cls); | |
| 1422 return; | |
| 1423 } | |
| 1424 if (class_id == kArrayCid) { | |
| 1425 // Object is being referenced, add it to the forward ref list and mark | |
| 1426 // it so that future references to this object in the snapshot will use | |
| 1427 // this object id. Mark it as not having been serialized yet so that we | |
| 1428 // will serialize the object when we go through the forward list. | |
| 1429 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); | |
| 1430 | |
| 1431 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | |
| 1432 | |
| 1433 // Write out the serialization header value for this object. | |
| 1434 WriteInlinedObjectHeader(kOmittedObjectId); | |
| 1435 | |
| 1436 // Write out the class information. | |
| 1437 WriteIndexedObject(kArrayCid); | |
| 1438 | |
| 1439 // Write out the length field. | |
| 1440 Write<RawObject*>(rawarray->ptr()->length_); | |
| 1441 | |
| 1442 return; | |
| 1443 } | |
| 1444 if (class_id == kImmutableArrayCid) { | |
| 1445 // Object is being referenced, add it to the forward ref list and mark | |
| 1446 // it so that future references to this object in the snapshot will use | |
| 1447 // this object id. Mark it as not having been serialized yet so that we | |
| 1448 // will serialize the object when we go through the forward list. | |
| 1449 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); | |
| 1450 | |
| 1451 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | |
| 1452 | |
| 1453 // Write out the serialization header value for this object. | |
| 1454 WriteInlinedObjectHeader(kOmittedObjectId); | |
| 1455 | |
| 1456 // Write out the class information. | |
| 1457 WriteIndexedObject(kImmutableArrayCid); | |
| 1458 | |
| 1459 // Write out the length field. | |
| 1460 Write<RawObject*>(rawarray->ptr()->length_); | |
| 1461 | |
| 1462 return; | |
| 1463 } | |
| 1464 if (RawObject::IsImplicitFieldClassId(class_id)) { | |
| 1465 WriteInstanceRef(raw, cls); | |
| 1466 return; | |
| 1467 } | |
| 1468 // Add object to the forward ref list and mark it so that future references | |
| 1469 // to this object in the snapshot will use this object id. Mark it as having | |
| 1470 // been serialized so that we do not serialize the object when we go through | |
| 1471 // the forward list. | |
| 1472 forward_list_->MarkAndAddObject(raw, kIsSerialized); | |
| 1473 switch (class_id) { | |
| 1474 #define SNAPSHOT_WRITE(clazz) \ | |
| 1475 case clazz::kClassId: { \ | |
| 1476 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ | |
| 1477 raw_obj->WriteTo(this, kOmittedObjectId, kind_); \ | |
| 1478 return; \ | |
| 1479 } \ | |
| 1480 | |
| 1481 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) | |
| 1482 #undef SNAPSHOT_WRITE | |
| 1483 #define SNAPSHOT_WRITE(clazz) \ | |
| 1484 case kTypedData##clazz##Cid: \ | |
| 1485 | |
| 1486 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { | |
| 1487 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); | |
| 1488 raw_obj->WriteTo(this, kOmittedObjectId, kind_); | |
| 1489 return; | |
| 1490 } | |
| 1491 #undef SNAPSHOT_WRITE | |
| 1492 #define SNAPSHOT_WRITE(clazz) \ | |
| 1493 case kExternalTypedData##clazz##Cid: \ | |
| 1494 | |
| 1495 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { | |
| 1496 RawExternalTypedData* raw_obj = | |
| 1497 reinterpret_cast<RawExternalTypedData*>(raw); | |
| 1498 raw_obj->WriteTo(this, kOmittedObjectId, kind_); | |
| 1499 return; | |
| 1500 } | |
| 1501 #undef SNAPSHOT_WRITE | |
| 1502 default: break; | |
| 1503 } | |
| 1504 UNREACHABLE(); | |
| 1505 } | |
| 1506 | |
| 1507 | |
| 1508 // An object visitor which will iterate over all the script objects in the heap | 1399 // An object visitor which will iterate over all the script objects in the heap |
| 1509 // and either count them or collect them into an array. This is used during | 1400 // and either count them or collect them into an array. This is used during |
| 1510 // full snapshot generation of the VM isolate to write out all script | 1401 // full snapshot generation of the VM isolate to write out all script |
| 1511 // objects and their accompanying token streams. | 1402 // objects and their accompanying token streams. |
| 1512 class ScriptVisitor : public ObjectVisitor { | 1403 class ScriptVisitor : public ObjectVisitor { |
| 1513 public: | 1404 public: |
| 1514 explicit ScriptVisitor(Isolate* isolate) : | 1405 explicit ScriptVisitor(Isolate* isolate) : |
| 1515 ObjectVisitor(isolate), | 1406 ObjectVisitor(isolate), |
| 1516 objHandle_(Object::Handle(isolate)), | 1407 objHandle_(Object::Handle(isolate)), |
| 1517 count_(0), | 1408 count_(0), |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1846 if (index != kInvalidIndex) { | 1737 if (index != kInvalidIndex) { |
| 1847 WriteIndexedObject(index); | 1738 WriteIndexedObject(index); |
| 1848 return true; | 1739 return true; |
| 1849 } | 1740 } |
| 1850 } | 1741 } |
| 1851 | 1742 |
| 1852 return false; | 1743 return false; |
| 1853 } | 1744 } |
| 1854 | 1745 |
| 1855 | 1746 |
| 1856 void SnapshotWriter::WriteObjectImpl(RawObject* raw) { | 1747 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { |
| 1857 // First check if object can be written as a simple predefined type. | 1748 // First check if object can be written as a simple predefined type. |
| 1858 if (CheckAndWritePredefinedObject(raw)) { | 1749 if (CheckAndWritePredefinedObject(raw)) { |
| 1859 return; | 1750 return; |
| 1860 } | 1751 } |
| 1861 | 1752 |
| 1862 // Object is being serialized, add it to the forward ref list and mark | 1753 if (as_reference && !raw->IsCanonical()) { |
| 1863 // it so that future references to this object in the snapshot will use | 1754 WriteObjectRef(raw); |
| 1864 // an object id, instead of trying to serialize it again. | 1755 } else { |
| 1865 forward_list_->MarkAndAddObject(raw, kIsSerialized); | 1756 // Object is being serialized, add it to the forward ref list and mark |
| 1757 // it so that future references to this object in the snapshot will use |
| 1758 // an object id, instead of trying to serialize it again. |
| 1759 forward_list_->MarkAndAddObject(raw, kIsSerialized); |
| 1866 | 1760 |
| 1867 WriteInlinedObject(raw); | 1761 WriteInlinedObject(raw); |
| 1762 } |
| 1868 } | 1763 } |
| 1869 | 1764 |
| 1870 | 1765 |
| 1766 void SnapshotWriter::WriteObjectRef(RawObject* raw) { |
| 1767 NoSafepointScope no_safepoint; |
| 1768 RawClass* cls = class_table_->At(raw->GetClassId()); |
| 1769 intptr_t class_id = cls->ptr()->id_; |
| 1770 ASSERT(class_id == raw->GetClassId()); |
| 1771 if (class_id >= kNumPredefinedCids || |
| 1772 RawObject::IsImplicitFieldClassId(class_id)) { |
| 1773 WriteInstanceRef(raw, cls); |
| 1774 return; |
| 1775 } |
| 1776 if (class_id == kArrayCid || class_id == kImmutableArrayCid) { |
| 1777 intptr_t tags = GetObjectTags(raw); |
| 1778 |
| 1779 // Object is being referenced, add it to the forward ref list and mark |
| 1780 // it so that future references to this object in the snapshot will use |
| 1781 // this object id. Mark it as not having been serialized yet so that we |
| 1782 // will serialize the object when we go through the forward list. |
| 1783 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); |
| 1784 |
| 1785 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
| 1786 |
| 1787 // Write out the serialization header value for this object. |
| 1788 WriteInlinedObjectHeader(kOmittedObjectId); |
| 1789 |
| 1790 // Write out the class information. |
| 1791 WriteIndexedObject(class_id); |
| 1792 WriteTags(tags); |
| 1793 |
| 1794 // Write out the length field. |
| 1795 Write<RawObject*>(rawarray->ptr()->length_); |
| 1796 |
| 1797 return; |
| 1798 } |
| 1799 // Add object to the forward ref list and mark it so that future references |
| 1800 // to this object in the snapshot will use this object id. Mark it as having |
| 1801 // been serialized so that we do not serialize the object when we go through |
| 1802 // the forward list. |
| 1803 forward_list_->MarkAndAddObject(raw, kIsSerialized); |
| 1804 switch (class_id) { |
| 1805 #define SNAPSHOT_WRITE(clazz) \ |
| 1806 case clazz::kClassId: { \ |
| 1807 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ |
| 1808 raw_obj->WriteTo(this, kOmittedObjectId, kind_); \ |
| 1809 return; \ |
| 1810 } \ |
| 1811 |
| 1812 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) |
| 1813 #undef SNAPSHOT_WRITE |
| 1814 #define SNAPSHOT_WRITE(clazz) \ |
| 1815 case kTypedData##clazz##Cid: \ |
| 1816 |
| 1817 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { |
| 1818 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); |
| 1819 raw_obj->WriteTo(this, kOmittedObjectId, kind_); |
| 1820 return; |
| 1821 } |
| 1822 #undef SNAPSHOT_WRITE |
| 1823 #define SNAPSHOT_WRITE(clazz) \ |
| 1824 case kExternalTypedData##clazz##Cid: \ |
| 1825 |
| 1826 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { |
| 1827 RawExternalTypedData* raw_obj = |
| 1828 reinterpret_cast<RawExternalTypedData*>(raw); |
| 1829 raw_obj->WriteTo(this, kOmittedObjectId, kind_); |
| 1830 return; |
| 1831 } |
| 1832 #undef SNAPSHOT_WRITE |
| 1833 default: break; |
| 1834 } |
| 1835 UNREACHABLE(); |
| 1836 } |
| 1837 |
| 1838 |
| 1871 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { | 1839 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { |
| 1872 // Now write the object out inline in the stream as follows: | 1840 // Now write the object out inline in the stream as follows: |
| 1873 // - Object is seen for the first time (inlined as follows): | 1841 // - Object is seen for the first time (inlined as follows): |
| 1874 // (object size in multiples of kObjectAlignment | 0x1) | 1842 // (object size in multiples of kObjectAlignment | 0x1) |
| 1875 // serialized fields of the object | 1843 // serialized fields of the object |
| 1876 // ...... | 1844 // ...... |
| 1877 NoSafepointScope no_safepoint; | 1845 NoSafepointScope no_safepoint; |
| 1878 uword tags = raw->ptr()->tags_; | 1846 uword tags = raw->ptr()->tags_; |
| 1879 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | 1847 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
| 1880 intptr_t object_id = SerializedHeaderData::decode(tags); | 1848 intptr_t object_id = SerializedHeaderData::decode(tags); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1987 ASSERT(!IsSingletonClassId(class_id) && !IsObjectStoreClassId(class_id)); | 1955 ASSERT(!IsSingletonClassId(class_id) && !IsObjectStoreClassId(class_id)); |
| 1988 // TODO(5411462): Should restrict this to only core-lib classes in this | 1956 // TODO(5411462): Should restrict this to only core-lib classes in this |
| 1989 // case. | 1957 // case. |
| 1990 // Write out the class and tags information. | 1958 // Write out the class and tags information. |
| 1991 WriteVMIsolateObject(kClassCid); | 1959 WriteVMIsolateObject(kClassCid); |
| 1992 WriteTags(GetObjectTags(cls)); | 1960 WriteTags(GetObjectTags(cls)); |
| 1993 | 1961 |
| 1994 // Write out the library url and class name. | 1962 // Write out the library url and class name. |
| 1995 RawLibrary* library = cls->ptr()->library_; | 1963 RawLibrary* library = cls->ptr()->library_; |
| 1996 ASSERT(library != Library::null()); | 1964 ASSERT(library != Library::null()); |
| 1997 WriteObjectImpl(library->ptr()->url_); | 1965 WriteObjectImpl(library->ptr()->url_, kAsInlinedObject); |
| 1998 WriteObjectImpl(cls->ptr()->name_); | 1966 WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject); |
| 1999 } | 1967 } |
| 2000 | 1968 |
| 2001 | 1969 |
| 2002 void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id, | 1970 void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id, |
| 2003 RawFunction* func, | 1971 RawFunction* func, |
| 2004 intptr_t tags) { | 1972 intptr_t tags) { |
| 2005 // Write out the serialization header value for this object. | 1973 // Write out the serialization header value for this object. |
| 2006 WriteInlinedObjectHeader(object_id); | 1974 WriteInlinedObjectHeader(object_id); |
| 2007 | 1975 |
| 2008 // Indicate this is a static implicit closure object. | 1976 // Indicate this is a static implicit closure object. |
| 2009 Write<int32_t>(SerializedHeaderData::encode(kStaticImplicitClosureObjectId)); | 1977 Write<int32_t>(SerializedHeaderData::encode(kStaticImplicitClosureObjectId)); |
| 2010 | 1978 |
| 2011 // Write out the tags. | 1979 // Write out the tags. |
| 2012 WriteTags(tags); | 1980 WriteTags(tags); |
| 2013 | 1981 |
| 2014 // Write out the library url, class name and signature function name. | 1982 // Write out the library url, class name and signature function name. |
| 2015 RawClass* cls = GetFunctionOwner(func); | 1983 RawClass* cls = GetFunctionOwner(func); |
| 2016 ASSERT(cls != Class::null()); | 1984 ASSERT(cls != Class::null()); |
| 2017 RawLibrary* library = cls->ptr()->library_; | 1985 RawLibrary* library = cls->ptr()->library_; |
| 2018 ASSERT(library != Library::null()); | 1986 ASSERT(library != Library::null()); |
| 2019 WriteObjectImpl(library->ptr()->url_); | 1987 WriteObjectImpl(library->ptr()->url_, kAsInlinedObject); |
| 2020 WriteObjectImpl(cls->ptr()->name_); | 1988 WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject); |
| 2021 WriteObjectImpl(func->ptr()->name_); | 1989 WriteObjectImpl(func->ptr()->name_, kAsInlinedObject); |
| 2022 } | 1990 } |
| 2023 | 1991 |
| 2024 | 1992 |
| 2025 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, | 1993 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, |
| 2026 intptr_t array_kind, | 1994 intptr_t array_kind, |
| 2027 intptr_t tags, | 1995 intptr_t tags, |
| 2028 RawSmi* length, | 1996 RawSmi* length, |
| 2029 RawTypeArguments* type_arguments, | 1997 RawTypeArguments* type_arguments, |
| 2030 RawObject* data[]) { | 1998 RawObject* data[]) { |
| 2031 intptr_t len = Smi::Value(length); | 1999 intptr_t len = Smi::Value(length); |
| 2032 | 2000 |
| 2033 // Write out the serialization header value for this object. | 2001 // Write out the serialization header value for this object. |
| 2034 WriteInlinedObjectHeader(object_id); | 2002 WriteInlinedObjectHeader(object_id); |
| 2035 | 2003 |
| 2036 // Write out the class and tags information. | 2004 // Write out the class and tags information. |
| 2037 WriteIndexedObject(array_kind); | 2005 WriteIndexedObject(array_kind); |
| 2038 WriteTags(tags); | 2006 WriteTags(tags); |
| 2039 | 2007 |
| 2040 // Write out the length field. | 2008 // Write out the length field. |
| 2041 Write<RawObject*>(length); | 2009 Write<RawObject*>(length); |
| 2042 | 2010 |
| 2043 // Write out the type arguments. | 2011 // Write out the type arguments. |
| 2044 WriteObjectImpl(type_arguments); | 2012 WriteObjectImpl(type_arguments, kAsInlinedObject); |
| 2045 | 2013 |
| 2046 // Write out the individual object ids. | 2014 // Write out the individual object ids. |
| 2047 bool is_canonical = RawObject::IsCanonical(tags); | 2015 bool as_reference = RawObject::IsCanonical(tags) ? false : true; |
| 2048 for (intptr_t i = 0; i < len; i++) { | 2016 for (intptr_t i = 0; i < len; i++) { |
| 2049 if (is_canonical) { | 2017 WriteObjectImpl(data[i], as_reference); |
| 2050 WriteObjectImpl(data[i]); | |
| 2051 } else { | |
| 2052 WriteObjectRef(data[i]); | |
| 2053 } | |
| 2054 } | 2018 } |
| 2055 } | 2019 } |
| 2056 | 2020 |
| 2057 | 2021 |
| 2058 RawFunction* SnapshotWriter::IsSerializableClosure(RawClass* cls, | 2022 RawFunction* SnapshotWriter::IsSerializableClosure(RawClass* cls, |
| 2059 RawObject* obj) { | 2023 RawObject* obj) { |
| 2060 if (Class::IsSignatureClass(cls)) { | 2024 if (Class::IsSignatureClass(cls)) { |
| 2061 // 'obj' is a closure as its class is a signature class, extract | 2025 // 'obj' is a closure as its class is a signature class, extract |
| 2062 // the function object to check if this closure can be sent in an | 2026 // the function object to check if this closure can be sent in an |
| 2063 // isolate message. | 2027 // isolate message. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2152 // Write out the serialization header value for this object. | 2116 // Write out the serialization header value for this object. |
| 2153 WriteInlinedObjectHeader(object_id); | 2117 WriteInlinedObjectHeader(object_id); |
| 2154 | 2118 |
| 2155 // Indicate this is an instance object. | 2119 // Indicate this is an instance object. |
| 2156 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); | 2120 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); |
| 2157 | 2121 |
| 2158 // Write out the tags. | 2122 // Write out the tags. |
| 2159 WriteTags(tags); | 2123 WriteTags(tags); |
| 2160 | 2124 |
| 2161 // Write out the class information for this object. | 2125 // Write out the class information for this object. |
| 2162 WriteObjectImpl(cls); | 2126 WriteObjectImpl(cls, kAsInlinedObject); |
| 2163 | 2127 |
| 2164 // Write out all the fields for the object. | 2128 // Write out all the fields for the object. |
| 2165 // Instance::NextFieldOffset() returns the offset of the first field in | 2129 // Instance::NextFieldOffset() returns the offset of the first field in |
| 2166 // a Dart object. | 2130 // a Dart object. |
| 2167 bool is_canonical = RawObject::IsCanonical(tags); | 2131 bool as_reference = RawObject::IsCanonical(tags) ? false : true; |
| 2168 intptr_t offset = Instance::NextFieldOffset(); | 2132 intptr_t offset = Instance::NextFieldOffset(); |
| 2169 while (offset < next_field_offset) { | 2133 while (offset < next_field_offset) { |
| 2170 RawObject* raw_obj = *reinterpret_cast<RawObject**>( | 2134 RawObject* raw_obj = *reinterpret_cast<RawObject**>( |
| 2171 reinterpret_cast<uword>(raw->ptr()) + offset); | 2135 reinterpret_cast<uword>(raw->ptr()) + offset); |
| 2172 if (is_canonical) { | 2136 WriteObjectImpl(raw_obj, as_reference); |
| 2173 WriteObjectImpl(raw_obj); | |
| 2174 } else { | |
| 2175 WriteObjectRef(raw_obj); | |
| 2176 } | |
| 2177 offset += kWordSize; | 2137 offset += kWordSize; |
| 2178 } | 2138 } |
| 2179 return; | 2139 return; |
| 2180 } | 2140 } |
| 2181 | 2141 |
| 2182 | 2142 |
| 2183 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { | 2143 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { |
| 2184 // Check if the instance has native fields and throw an exception if it does. | 2144 // Check if the instance has native fields and throw an exception if it does. |
| 2185 CheckForNativeFields(cls); | 2145 CheckForNativeFields(cls); |
| 2186 | 2146 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2198 intptr_t object_id = SerializedHeaderData::decode(tags); | 2158 intptr_t object_id = SerializedHeaderData::decode(tags); |
| 2199 tags = forward_list_->NodeForObjectId(object_id)->tags(); | 2159 tags = forward_list_->NodeForObjectId(object_id)->tags(); |
| 2200 WriteStaticImplicitClosure(object_id, func, tags); | 2160 WriteStaticImplicitClosure(object_id, func, tags); |
| 2201 return; | 2161 return; |
| 2202 } | 2162 } |
| 2203 | 2163 |
| 2204 // Object is being referenced, add it to the forward ref list and mark | 2164 // Object is being referenced, add it to the forward ref list and mark |
| 2205 // it so that future references to this object in the snapshot will use | 2165 // it so that future references to this object in the snapshot will use |
| 2206 // this object id. Mark it as not having been serialized yet so that we | 2166 // this object id. Mark it as not having been serialized yet so that we |
| 2207 // will serialize the object when we go through the forward list. | 2167 // will serialize the object when we go through the forward list. |
| 2168 intptr_t tags = raw->ptr()->tags_; |
| 2208 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); | 2169 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); |
| 2209 | 2170 |
| 2210 // Write out the serialization header value for this object. | 2171 // Write out the serialization header value for this object. |
| 2211 WriteInlinedObjectHeader(kOmittedObjectId); | 2172 WriteInlinedObjectHeader(kOmittedObjectId); |
| 2212 | 2173 |
| 2213 // Indicate this is an instance object. | 2174 // Indicate this is an instance object. |
| 2214 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); | 2175 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); |
| 2176 WriteTags(tags); |
| 2215 | 2177 |
| 2216 // Write out the class information for this object. | 2178 // Write out the class information for this object. |
| 2217 WriteObjectImpl(cls); | 2179 WriteObjectImpl(cls, kAsInlinedObject); |
| 2218 } | 2180 } |
| 2219 | 2181 |
| 2220 | 2182 |
| 2221 bool SnapshotWriter::AllowObjectsInDartLibrary(RawLibrary* library) { | 2183 bool SnapshotWriter::AllowObjectsInDartLibrary(RawLibrary* library) { |
| 2222 return library == object_store()->typed_data_library(); | 2184 return library == object_store()->typed_data_library(); |
| 2223 } | 2185 } |
| 2224 | 2186 |
| 2225 | 2187 |
| 2226 intptr_t SnapshotWriter::FindVmSnapshotObject(RawObject* rawobj) { | 2188 intptr_t SnapshotWriter::FindVmSnapshotObject(RawObject* rawobj) { |
| 2227 intptr_t length = Object::vm_isolate_snapshot_object_table().Length(); | 2189 intptr_t length = Object::vm_isolate_snapshot_object_table().Length(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2306 } | 2268 } |
| 2307 } else { | 2269 } else { |
| 2308 ThrowException(exception_type(), exception_msg()); | 2270 ThrowException(exception_type(), exception_msg()); |
| 2309 } | 2271 } |
| 2310 } | 2272 } |
| 2311 | 2273 |
| 2312 | 2274 |
| 2313 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 2275 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
| 2314 for (RawObject** current = first; current <= last; current++) { | 2276 for (RawObject** current = first; current <= last; current++) { |
| 2315 RawObject* raw_obj = *current; | 2277 RawObject* raw_obj = *current; |
| 2316 if (as_references_) { | 2278 writer_->WriteObjectImpl(raw_obj, as_references_); |
| 2317 writer_->WriteObjectRef(raw_obj); | |
| 2318 } else { | |
| 2319 writer_->WriteObjectImpl(raw_obj); | |
| 2320 } | |
| 2321 } | 2279 } |
| 2322 } | 2280 } |
| 2323 | 2281 |
| 2324 | 2282 |
| 2325 MessageWriter::MessageWriter(uint8_t** buffer, | 2283 MessageWriter::MessageWriter(uint8_t** buffer, |
| 2326 ReAlloc alloc, | 2284 ReAlloc alloc, |
| 2327 bool can_send_any_object) | 2285 bool can_send_any_object) |
| 2328 : SnapshotWriter(Snapshot::kMessage, | 2286 : SnapshotWriter(Snapshot::kMessage, |
| 2329 buffer, | 2287 buffer, |
| 2330 alloc, | 2288 alloc, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2348 NoSafepointScope no_safepoint; | 2306 NoSafepointScope no_safepoint; |
| 2349 WriteObject(obj.raw()); | 2307 WriteObject(obj.raw()); |
| 2350 UnmarkAll(); | 2308 UnmarkAll(); |
| 2351 } else { | 2309 } else { |
| 2352 ThrowException(exception_type(), exception_msg()); | 2310 ThrowException(exception_type(), exception_msg()); |
| 2353 } | 2311 } |
| 2354 } | 2312 } |
| 2355 | 2313 |
| 2356 | 2314 |
| 2357 } // namespace dart | 2315 } // namespace dart |
| OLD | NEW |