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

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

Issue 1405823003: Refactor ReadObjectImpl to use the as_reference field and eliminate ReadObjectRef and ReadInlinedOb… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: self-code-review-comments Created 5 years, 2 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
« no previous file with comments | « runtime/vm/snapshot.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 patch_offset); 391 patch_offset);
392 } 392 }
393 393
394 394
395 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value, 395 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value,
396 bool as_reference, 396 bool as_reference,
397 intptr_t patch_object_id, 397 intptr_t patch_object_id,
398 intptr_t patch_offset) { 398 intptr_t patch_offset) {
399 if (IsVMIsolateObject(header_value)) { 399 if (IsVMIsolateObject(header_value)) {
400 return ReadVMIsolateObject(header_value); 400 return ReadVMIsolateObject(header_value);
401 } else { 401 }
402 if (SerializedHeaderTag::decode(header_value) == kObjectId) { 402 if (SerializedHeaderTag::decode(header_value) == kObjectId) {
403 return ReadIndexedObject(SerializedHeaderData::decode(header_value), 403 return ReadIndexedObject(SerializedHeaderData::decode(header_value),
404 patch_object_id,
405 patch_offset);
406 }
407 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined);
408 intptr_t object_id = SerializedHeaderData::decode(header_value);
409 if (object_id == kOmittedObjectId) {
410 object_id = NextAvailableObjectId();
411 }
412
413 // Read the class header information.
414 intptr_t class_header = Read<int32_t>();
415 intptr_t tags = ReadTags();
416 if (as_reference && !RawObject::IsCanonical(tags)) {
417 return ReadObjectRef(object_id,
418 class_header,
419 tags,
420 patch_object_id,
421 patch_offset);
422 }
423 return ReadInlinedObject(object_id,
424 class_header,
425 tags,
426 patch_object_id, 404 patch_object_id,
427 patch_offset); 405 patch_offset);
428 } 406 }
429 } 407 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined);
408 intptr_t object_id = SerializedHeaderData::decode(header_value);
409 if (object_id == kOmittedObjectId) {
410 object_id = NextAvailableObjectId();
411 }
430 412
431 413 // Read the class header information.
432 RawObject* SnapshotReader::ReadObjectRef(intptr_t object_id, 414 intptr_t class_header = Read<int32_t>();
433 intptr_t class_header, 415 intptr_t tags = ReadTags();
434 intptr_t tags, 416 bool read_as_reference = as_reference && !RawObject::IsCanonical(tags);
435 intptr_t patch_object_id,
436 intptr_t patch_offset) {
437 // Since we are only reading an object reference, If it is an instance kind
438 // then we only need to figure out the class of the object and allocate an
439 // instance of it. The individual fields will be read later.
440 intptr_t header_id = SerializedHeaderData::decode(class_header); 417 intptr_t header_id = SerializedHeaderData::decode(class_header);
441 if (header_id == kInstanceObjectId) { 418 if (header_id == kInstanceObjectId) {
442 Instance& result = Instance::ZoneHandle(zone(), Instance::null()); 419 return ReadInstance(object_id, tags, read_as_reference);
443 AddBackRef(object_id, &result, kIsNotDeserialized);
444
445 cls_ ^= ReadObjectImpl(kAsInlinedObject); // Read class information.
446 ASSERT(!cls_.IsNull());
447 intptr_t instance_size = cls_.instance_size();
448 ASSERT(instance_size > 0);
449 if (kind_ == Snapshot::kFull) {
450 result ^= AllocateUninitialized(cls_.id(), instance_size);
451 } else {
452 result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_));
453 }
454 return result.raw();
455 } else if (header_id == kStaticImplicitClosureObjectId) { 420 } else if (header_id == kStaticImplicitClosureObjectId) {
456 // We skip the tags that have been written as the implicit static 421 // We skip the tags that have been written as the implicit static
457 // closure is going to be created in this isolate or the canonical 422 // closure is going to be created in this isolate or the canonical
458 // version already created in the isolate will be used. 423 // version already created in the isolate will be used.
459 return ReadStaticImplicitClosure(object_id, class_header); 424 return ReadStaticImplicitClosure(object_id, class_header);
460 } 425 }
461 ASSERT((class_header & kSmiTagMask) != kSmiTag); 426 ASSERT((class_header & kSmiTagMask) != kSmiTag);
462 427
463 // Similarly Array and ImmutableArray objects are also similarly only
464 // allocated here, the individual array elements are read later.
465 intptr_t class_id = LookupInternalClass(class_header); 428 intptr_t class_id = LookupInternalClass(class_header);
466 if (class_id == kArrayCid) {
467 // Read the length and allocate an object based on the len.
468 intptr_t len = ReadSmiValue();
469 Array& array = Array::ZoneHandle(
470 zone(),
471 ((kind_ == Snapshot::kFull) ?
472 NewArray(len) : Array::New(len, HEAP_SPACE(kind_))));
473 AddBackRef(object_id, &array, kIsNotDeserialized);
474
475 return array.raw();
476 }
477 if (class_id == kImmutableArrayCid) {
478 // Read the length and allocate an object based on the len.
479 intptr_t len = ReadSmiValue();
480 Array& array = Array::ZoneHandle(
481 zone(),
482 (kind_ == Snapshot::kFull) ?
483 NewImmutableArray(len) : ImmutableArray::New(len, HEAP_SPACE(kind_)));
484 AddBackRef(object_id, &array, kIsNotDeserialized);
485
486 return array.raw();
487 }
488 if (class_id == kObjectPoolCid) {
489 ASSERT(kind_ == Snapshot::kFull);
490 // Read the length and allocate an object based on the len.
491 intptr_t len = Read<intptr_t>();
492 ObjectPool& pool = ObjectPool::ZoneHandle(zone(),
493 NewObjectPool(len));
494 AddBackRef(object_id, &pool, kIsNotDeserialized);
495
496 return pool.raw();
497 }
498
499 // For all other internal VM classes we read the object inline.
500 switch (class_id) { 429 switch (class_id) {
501 #define SNAPSHOT_READ(clazz) \ 430 #define SNAPSHOT_READ(clazz) \
502 case clazz::kClassId: { \ 431 case clazz::kClassId: { \
503 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, true); \ 432 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, read_as_reference);\
504 break; \ 433 break; \
505 } 434 }
506 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) 435 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
507 #undef SNAPSHOT_READ 436 #undef SNAPSHOT_READ
508 #define SNAPSHOT_READ(clazz) \ 437 #define SNAPSHOT_READ(clazz) \
509 case kTypedData##clazz##Cid: \ 438 case kTypedData##clazz##Cid: \
510 439
511 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { 440 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
512 tags = RawObject::ClassIdTag::update(class_id, tags); 441 tags = RawObject::ClassIdTag::update(class_id, tags);
513 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_, true); 442 pobj_ = TypedData::ReadFrom(
443 this, object_id, tags, kind_, read_as_reference);
514 break; 444 break;
515 } 445 }
516 #undef SNAPSHOT_READ 446 #undef SNAPSHOT_READ
517 #define SNAPSHOT_READ(clazz) \ 447 #define SNAPSHOT_READ(clazz) \
518 case kExternalTypedData##clazz##Cid: \ 448 case kExternalTypedData##clazz##Cid: \
519 449
520 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { 450 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
521 tags = RawObject::ClassIdTag::update(class_id, tags); 451 tags = RawObject::ClassIdTag::update(class_id, tags);
522 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_, true); 452 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_, true);
523 break; 453 break;
524 } 454 }
525 #undef SNAPSHOT_READ 455 #undef SNAPSHOT_READ
526 default: UNREACHABLE(); break; 456 default: UNREACHABLE(); break;
527 } 457 }
458 if (!read_as_reference) {
459 AddPatchRecord(object_id, patch_object_id, patch_offset);
460 }
528 return pobj_.raw(); 461 return pobj_.raw();
529 } 462 }
530 463
531 464
532 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id, 465 RawObject* SnapshotReader::ReadInstance(intptr_t object_id,
533 intptr_t class_header, 466 intptr_t tags,
534 intptr_t tags, 467 bool as_reference) {
535 intptr_t patch_object_id, 468 // Object is regular dart instance.
536 intptr_t patch_offset) { 469 intptr_t instance_size = 0;
537 // Lookup the class based on the class header information. 470 Instance* result = NULL;
538 intptr_t header_id = SerializedHeaderData::decode(class_header); 471 DeserializeState state;
539 if (header_id == kInstanceObjectId) { 472 if (!as_reference) {
540 // Object is regular dart instance. 473 result = reinterpret_cast<Instance*>(GetBackRef(object_id));
541 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id)); 474 state = kIsDeserialized;
542 intptr_t instance_size = 0; 475 } else {
543 if (result == NULL) { 476 state = kIsNotDeserialized;
544 result = &(Instance::ZoneHandle(zone(), Instance::null())); 477 }
545 AddBackRef(object_id, result, kIsDeserialized); 478 if (result == NULL) {
546 cls_ ^= ReadObjectImpl(kAsInlinedObject); 479 result = &(Instance::ZoneHandle(zone(), Instance::null()));
547 ASSERT(!cls_.IsNull()); 480 AddBackRef(object_id, result, state);
548 instance_size = cls_.instance_size(); 481 cls_ ^= ReadObjectImpl(kAsInlinedObject);
549 ASSERT(instance_size > 0); 482 ASSERT(!cls_.IsNull());
550 // Allocate the instance and read in all the fields for the object. 483 instance_size = cls_.instance_size();
551 if (kind_ == Snapshot::kFull) { 484 ASSERT(instance_size > 0);
552 *result ^= AllocateUninitialized(cls_.id(), instance_size); 485 // Allocate the instance and read in all the fields for the object.
553 } else { 486 if (kind_ == Snapshot::kFull) {
554 *result ^= Object::Allocate(cls_.id(), 487 *result ^= AllocateUninitialized(cls_.id(), instance_size);
555 instance_size,
556 HEAP_SPACE(kind_));
557 }
558 } else { 488 } else {
559 cls_ ^= ReadObjectImpl(kAsInlinedObject); 489 *result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_));
560 ASSERT(!cls_.IsNull());
561 instance_size = cls_.instance_size();
562 } 490 }
491 } else {
492 cls_ ^= ReadObjectImpl(kAsInlinedObject);
493 ASSERT(!cls_.IsNull());
494 instance_size = cls_.instance_size();
495 }
496 if (!as_reference) {
497 // Read all the individual fields for inlined objects.
563 intptr_t next_field_offset = Class::IsSignatureClass(cls_.raw()) 498 intptr_t next_field_offset = Class::IsSignatureClass(cls_.raw())
564 ? Closure::InstanceSize() : cls_.next_field_offset(); 499 ? Closure::InstanceSize() : cls_.next_field_offset();
565 500
566 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); 501 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset();
567 ASSERT(next_field_offset > 0); 502 ASSERT(next_field_offset > 0);
568 // Instance::NextFieldOffset() returns the offset of the first field in 503 // Instance::NextFieldOffset() returns the offset of the first field in
569 // a Dart object. 504 // a Dart object.
570 bool as_reference = RawObject::IsCanonical(tags) ? false : true; 505 bool read_as_reference = RawObject::IsCanonical(tags) ? false : true;
571 intptr_t offset = Instance::NextFieldOffset(); 506 intptr_t offset = Instance::NextFieldOffset();
572 intptr_t result_cid = result->GetClassId(); 507 intptr_t result_cid = result->GetClassId();
573 while (offset < next_field_offset) { 508 while (offset < next_field_offset) {
574 pobj_ = ReadObjectImpl(as_reference); 509 pobj_ = ReadObjectImpl(read_as_reference);
575 result->SetFieldAtOffset(offset, pobj_); 510 result->SetFieldAtOffset(offset, pobj_);
576 if ((offset != type_argument_field_offset) && 511 if ((offset != type_argument_field_offset) &&
577 (kind_ == Snapshot::kMessage)) { 512 (kind_ == Snapshot::kMessage)) {
578 // TODO(fschneider): Consider hoisting these lookups out of the loop. 513 // TODO(fschneider): Consider hoisting these lookups out of the loop.
579 // This would involve creating a handle, since cls_ can't be reused 514 // This would involve creating a handle, since cls_ can't be reused
580 // across the call to ReadObjectImpl. 515 // across the call to ReadObjectImpl.
581 cls_ = isolate()->class_table()->At(result_cid); 516 cls_ = isolate()->class_table()->At(result_cid);
582 array_ = cls_.OffsetToFieldMap(); 517 array_ = cls_.OffsetToFieldMap();
583 field_ ^= array_.At(offset >> kWordSizeLog2); 518 field_ ^= array_.At(offset >> kWordSizeLog2);
584 ASSERT(!field_.IsNull()); 519 ASSERT(!field_.IsNull());
(...skipping 14 matching lines...) Expand all
599 } 534 }
600 } 535 }
601 if (RawObject::IsCanonical(tags)) { 536 if (RawObject::IsCanonical(tags)) {
602 if (kind_ == Snapshot::kFull) { 537 if (kind_ == Snapshot::kFull) {
603 result->SetCanonical(); 538 result->SetCanonical();
604 } else { 539 } else {
605 *result = result->CheckAndCanonicalize(NULL); 540 *result = result->CheckAndCanonicalize(NULL);
606 ASSERT(!result->IsNull()); 541 ASSERT(!result->IsNull());
607 } 542 }
608 } 543 }
609 return result->raw();
610 } else if (header_id == kStaticImplicitClosureObjectId) {
611 // We do not use the tags as the implicit static closure
612 // is going to be created in this isolate or the canonical
613 // version already created in the isolate will be used.
614 return ReadStaticImplicitClosure(object_id, class_header);
615 } 544 }
616 ASSERT((class_header & kSmiTagMask) != kSmiTag); 545 return result->raw();
617 intptr_t class_id = LookupInternalClass(class_header);
618 switch (class_id) {
619 #define SNAPSHOT_READ(clazz) \
620 case clazz::kClassId: { \
621 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, false); \
622 break; \
623 }
624 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
625 #undef SNAPSHOT_READ
626 #define SNAPSHOT_READ(clazz) \
627 case kTypedData##clazz##Cid: \
628
629 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
630 tags = RawObject::ClassIdTag::update(class_id, tags);
631 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_, false);
632 break;
633 }
634 #undef SNAPSHOT_READ
635 #define SNAPSHOT_READ(clazz) \
636 case kExternalTypedData##clazz##Cid: \
637
638 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
639 tags = RawObject::ClassIdTag::update(class_id, tags);
640 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_, false);
641 break;
642 }
643 #undef SNAPSHOT_READ
644 default: UNREACHABLE(); break;
645 }
646 AddPatchRecord(object_id, patch_object_id, patch_offset);
647 return pobj_.raw();
648 } 546 }
649 547
650 548
651 void SnapshotReader::AddBackRef(intptr_t id, 549 void SnapshotReader::AddBackRef(intptr_t id,
652 Object* obj, 550 Object* obj,
653 DeserializeState state, 551 DeserializeState state,
654 bool defer_canonicalization) { 552 bool defer_canonicalization) {
655 intptr_t index = (id - kMaxPredefinedObjectIds); 553 intptr_t index = (id - kMaxPredefinedObjectIds);
656 ASSERT(index >= max_vm_isolate_object_id_); 554 ASSERT(index >= max_vm_isolate_object_id_);
657 index -= max_vm_isolate_object_id_; 555 index -= max_vm_isolate_object_id_;
(...skipping 1997 matching lines...) Expand 10 before | Expand all | Expand 10 after
2655 if (setjmp(*jump.Set()) == 0) { 2553 if (setjmp(*jump.Set()) == 0) {
2656 NoSafepointScope no_safepoint; 2554 NoSafepointScope no_safepoint;
2657 WriteObject(obj.raw()); 2555 WriteObject(obj.raw());
2658 } else { 2556 } else {
2659 ThrowException(exception_type(), exception_msg()); 2557 ThrowException(exception_type(), exception_msg());
2660 } 2558 }
2661 } 2559 }
2662 2560
2663 2561
2664 } // namespace dart 2562 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/snapshot.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698