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/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
10 #include "vm/exceptions.h" | 10 #include "vm/exceptions.h" |
11 #include "vm/heap.h" | 11 #include "vm/heap.h" |
12 #include "vm/object.h" | 12 #include "vm/object.h" |
13 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
| 14 #include "vm/symbols.h" |
14 | 15 |
15 namespace dart { | 16 namespace dart { |
16 | 17 |
17 enum { | 18 enum { |
18 kInstanceId = ObjectStore::kMaxId, | 19 kInstanceId = ObjectStore::kMaxId, |
19 kMaxPredefinedObjectIds, | 20 kMaxPredefinedObjectIds, |
20 }; | 21 }; |
21 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; | 22 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; |
22 static const int kNumInitialReferences = 4; | 23 static const int kNumInitialReferences = 4; |
23 | 24 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 125 |
125 RawObject* SnapshotReader::ReadObjectImpl() { | 126 RawObject* SnapshotReader::ReadObjectImpl() { |
126 int64_t value = Read<int64_t>(); | 127 int64_t value = Read<int64_t>(); |
127 if ((value & kSmiTagMask) == 0) { | 128 if ((value & kSmiTagMask) == 0) { |
128 return Integer::New((value >> kSmiTagShift)); | 129 return Integer::New((value >> kSmiTagShift)); |
129 } | 130 } |
130 return ReadObjectImpl(value); | 131 return ReadObjectImpl(value); |
131 } | 132 } |
132 | 133 |
133 | 134 |
134 RawObject* SnapshotReader::ReadObjectImpl(intptr_t value) { | 135 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { |
135 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | 136 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
136 SerializedHeaderType header_type = SerializedHeaderTag::decode(value); | 137 if (IsVMIsolateObject(header_value)) { |
137 intptr_t header_value = SerializedHeaderData::decode(value); | 138 return ReadVMIsolateObject(header_value); |
138 | 139 } else { |
139 if (header_type == kObjectId) { | 140 if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
140 return ReadIndexedObject(header_value); | 141 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
| 142 } |
| 143 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
| 144 return ReadInlinedObject(SerializedHeaderData::decode(header_value)); |
141 } | 145 } |
142 ASSERT(header_type == kInlined); | |
143 return ReadInlinedObject(header_value); | |
144 } | 146 } |
145 | 147 |
146 | 148 |
147 RawObject* SnapshotReader::ReadObjectRef() { | 149 RawObject* SnapshotReader::ReadObjectRef() { |
148 int64_t value = Read<int64_t>(); | 150 int64_t header_value = Read<int64_t>(); |
149 if ((value & kSmiTagMask) == 0) { | 151 if ((header_value & kSmiTagMask) == 0) { |
150 return Integer::New((value >> kSmiTagShift)); | 152 return Integer::New((header_value >> kSmiTagShift)); |
151 } | 153 } |
152 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | 154 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
153 SerializedHeaderType header_type = SerializedHeaderTag::decode(value); | 155 if (IsVMIsolateObject(header_value)) { |
154 intptr_t header_value = SerializedHeaderData::decode(value); | 156 return ReadVMIsolateObject(header_value); |
155 | 157 } else if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
156 if (header_type == kObjectId) { | 158 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
157 return ReadIndexedObject(header_value); | |
158 } | 159 } |
159 ASSERT(header_type == kInlined); | 160 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
160 intptr_t object_id = header_value; | 161 intptr_t object_id = SerializedHeaderData::decode(header_value); |
161 ASSERT(GetBackRef(object_id) == NULL); | 162 ASSERT(GetBackRef(object_id) == NULL); |
162 | 163 |
163 // Read the class header information and lookup the class. | 164 // Read the class header information and lookup the class. |
164 intptr_t class_header = ReadIntptrValue(); | 165 intptr_t class_header = ReadIntptrValue(); |
165 | 166 |
166 // Since we are only reading an object reference, If it is an instance kind | 167 // Since we are only reading an object reference, If it is an instance kind |
167 // then we only need to figure out the class of the object and allocate an | 168 // then we only need to figure out the class of the object and allocate an |
168 // instance of it. The individual fields will be read later. | 169 // instance of it. The individual fields will be read later. |
169 if (SerializedHeaderData::decode(class_header) == kInstanceId) { | 170 if (SerializedHeaderData::decode(class_header) == kInstanceId) { |
170 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); | 171 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 } | 462 } |
462 | 463 |
463 | 464 |
464 RawGrowableObjectArray* SnapshotReader::NewGrowableObjectArray() { | 465 RawGrowableObjectArray* SnapshotReader::NewGrowableObjectArray() { |
465 ALLOC_NEW_OBJECT(GrowableObjectArray, | 466 ALLOC_NEW_OBJECT(GrowableObjectArray, |
466 object_store()->growable_object_array_class()); | 467 object_store()->growable_object_array_class()); |
467 } | 468 } |
468 | 469 |
469 | 470 |
470 RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { | 471 RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { |
471 SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header); | |
472 | |
473 // If the header is an object Id, lookup singleton VM classes or classes | 472 // If the header is an object Id, lookup singleton VM classes or classes |
474 // stored in the object store. | 473 // stored in the object store. |
475 if (header_type == kObjectId) { | 474 if (IsVMIsolateObject(class_header)) { |
| 475 intptr_t class_id = GetVMIsolateObjectId(class_header); |
| 476 if (IsSingletonClassId(class_id)) { |
| 477 return Object::GetSingletonClass(class_id); // return singleton. |
| 478 } |
| 479 } else if (SerializedHeaderTag::decode(class_header) == kObjectId) { |
476 intptr_t header_value = SerializedHeaderData::decode(class_header); | 480 intptr_t header_value = SerializedHeaderData::decode(class_header); |
477 if (IsObjectStoreClassId(header_value)) { | 481 if (IsObjectStoreClassId(header_value)) { |
478 return object_store()->GetClass(header_value); | 482 return object_store()->GetClass(header_value); |
479 } else if (IsSingletonClassId(header_value)) { | |
480 return Object::GetSingletonClass(header_value); // return the singleton. | |
481 } | 483 } |
482 } | 484 } |
483 return Class::null(); | 485 return Class::null(); |
484 } | 486 } |
485 | 487 |
486 | 488 |
487 RawObject* SnapshotReader::AllocateUninitialized(const Class& cls, | 489 RawObject* SnapshotReader::AllocateUninitialized(const Class& cls, |
488 intptr_t size) { | 490 intptr_t size) { |
489 ASSERT(isolate()->no_gc_scope_depth() != 0); | 491 ASSERT(isolate()->no_gc_scope_depth() != 0); |
490 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 492 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
(...skipping 12 matching lines...) Expand all Loading... |
503 uword tags = 0; | 505 uword tags = 0; |
504 intptr_t index = cls.id(); | 506 intptr_t index = cls.id(); |
505 ASSERT(index != kIllegalObjectKind); | 507 ASSERT(index != kIllegalObjectKind); |
506 tags = RawObject::ClassIdTag::update(index, tags); | 508 tags = RawObject::ClassIdTag::update(index, tags); |
507 tags = RawObject::SizeTag::update(size, tags); | 509 tags = RawObject::SizeTag::update(size, tags); |
508 raw_obj->ptr()->tags_ = tags; | 510 raw_obj->ptr()->tags_ = tags; |
509 return raw_obj; | 511 return raw_obj; |
510 } | 512 } |
511 | 513 |
512 | 514 |
513 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { | 515 RawObject* SnapshotReader::ReadVMIsolateObject(intptr_t header_value) { |
| 516 intptr_t object_id = GetVMIsolateObjectId(header_value); |
514 if (object_id == Object::kNullObject) { | 517 if (object_id == Object::kNullObject) { |
515 // This is a singleton null object, return it. | 518 // This is a singleton null object, return it. |
516 return Object::null(); | 519 return Object::null(); |
517 } | 520 } |
518 if (object_id == Object::kSentinelObject) { | 521 if (object_id == Object::kSentinelObject) { |
519 return Object::sentinel(); | 522 return Object::sentinel(); |
520 } | 523 } |
521 if (IsSingletonClassId(object_id)) { | 524 if (IsSingletonClassId(object_id)) { |
522 return Object::GetSingletonClass(object_id); // return singleton object. | 525 return Object::GetSingletonClass(object_id); // return singleton object. |
523 } else if (IsObjectStoreClassId(object_id)) { | 526 } else { |
| 527 ASSERT(Symbols::IsVMSymbolId(object_id)); |
| 528 return Symbols::GetVMSymbol(object_id); // return VM symbol. |
| 529 } |
| 530 UNREACHABLE(); |
| 531 } |
| 532 |
| 533 |
| 534 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { |
| 535 if (IsObjectStoreClassId(object_id)) { |
524 return object_store()->GetClass(object_id); | 536 return object_store()->GetClass(object_id); |
525 } else if (object_id == ObjectStore::kTrueValue) { | 537 } else if (object_id == ObjectStore::kTrueValue) { |
526 return object_store()->true_value(); | 538 return object_store()->true_value(); |
527 } else if (object_id == ObjectStore::kFalseValue) { | 539 } else if (object_id == ObjectStore::kFalseValue) { |
528 return object_store()->false_value(); | 540 return object_store()->false_value(); |
529 } else if (kind_ != Snapshot::kFull) { | 541 } else if (kind_ != Snapshot::kFull) { |
530 if (IsObjectStoreTypeId(object_id)) { | 542 if (IsObjectStoreTypeId(object_id)) { |
531 return object_store()->GetType(object_id); // return type object. | 543 return object_store()->GetType(object_id); // return type object. |
532 } | 544 } |
533 } | 545 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 } | 625 } |
614 } | 626 } |
615 | 627 |
616 | 628 |
617 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 629 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
618 WriteObjectImpl(rawobj); | 630 WriteObjectImpl(rawobj); |
619 WriteForwardedObjects(); | 631 WriteForwardedObjects(); |
620 } | 632 } |
621 | 633 |
622 | 634 |
| 635 void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| 636 // Check if it is a singleton null object. |
| 637 if (rawobj == Object::null()) { |
| 638 WriteVMIsolateObject(Object::kNullObject); |
| 639 return; |
| 640 } |
| 641 |
| 642 // Check if it is a singleton sentinel object. |
| 643 if (rawobj == Object::sentinel()) { |
| 644 WriteVMIsolateObject(Object::kSentinelObject); |
| 645 return; |
| 646 } |
| 647 |
| 648 // Check if it is a singleton class object. |
| 649 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); |
| 650 intptr_t index = Object::GetSingletonClassIndex(raw_class); |
| 651 if (index != Object::kInvalidIndex) { |
| 652 WriteVMIsolateObject(index); |
| 653 return; |
| 654 } |
| 655 |
| 656 // Check it is a predefined symbol. |
| 657 index = Symbols::LookupVMSymbol(rawobj); |
| 658 if (index != Object::kInvalidIndex) { |
| 659 WriteVMIsolateObject(index); |
| 660 return; |
| 661 } |
| 662 |
| 663 UNREACHABLE(); |
| 664 } |
| 665 |
| 666 |
623 void SnapshotWriter::WriteObjectRef(RawObject* raw) { | 667 void SnapshotWriter::WriteObjectRef(RawObject* raw) { |
624 // First check if object can be written as a simple predefined type. | 668 // First check if object can be written as a simple predefined type. |
625 if (CheckAndWritePredefinedObject(raw)) { | 669 if (CheckAndWritePredefinedObject(raw)) { |
626 return; | 670 return; |
627 } | 671 } |
628 // Check if object has already been serialized, in that | 672 // Check if object has already been serialized, in that |
629 // case just write the object id out. | 673 // case just write the object id out. |
630 uword tags = raw->ptr()->tags_; | 674 uword tags = raw->ptr()->tags_; |
631 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 675 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
632 intptr_t id = SerializedHeaderData::decode(tags); | 676 intptr_t id = SerializedHeaderData::decode(tags); |
633 WriteIndexedObject(id); | 677 WriteIndexedObject(id); |
634 return; | 678 return; |
635 } | 679 } |
636 | 680 |
637 NoGCScope no_gc; | 681 NoGCScope no_gc; |
638 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); | 682 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); |
639 | 683 |
640 ObjectKind obj_kind = cls->ptr()->instance_kind_; | 684 ObjectKind obj_kind = cls->ptr()->instance_kind_; |
641 if (obj_kind == Instance::kInstanceKind) { | 685 if (obj_kind == Instance::kInstanceKind) { |
642 // Object is being referenced, add it to the forward ref list and mark | 686 // Object is being referenced, add it to the forward ref list and mark |
643 // it so that future references to this object in the snapshot will use | 687 // it so that future references to this object in the snapshot will use |
644 // this object id. Mark it as not having been serialized yet so that we | 688 // this object id. Mark it as not having been serialized yet so that we |
645 // will serialize the object when we go through the forward list. | 689 // will serialize the object when we go through the forward list. |
646 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 690 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
647 | 691 |
648 // Write out the serialization header value for this object. | 692 // Write out the serialization header value for this object. |
649 WriteSerializationMarker(kInlined, object_id); | 693 WriteInlinedObjectHeader(object_id); |
650 | 694 |
651 // Indicate this is an instance object. | 695 // Indicate this is an instance object. |
652 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); | 696 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); |
653 | 697 |
654 // Write out the class information for this object. | 698 // Write out the class information for this object. |
655 WriteObjectImpl(cls); | 699 WriteObjectImpl(cls); |
656 | 700 |
657 return; | 701 return; |
658 } | 702 } |
659 if (obj_kind == Array::kInstanceKind) { | 703 if (obj_kind == Array::kInstanceKind) { |
660 // Object is being referenced, add it to the forward ref list and mark | 704 // Object is being referenced, add it to the forward ref list and mark |
661 // it so that future references to this object in the snapshot will use | 705 // it so that future references to this object in the snapshot will use |
662 // this object id. Mark it as not having been serialized yet so that we | 706 // this object id. Mark it as not having been serialized yet so that we |
663 // will serialize the object when we go through the forward list. | 707 // will serialize the object when we go through the forward list. |
664 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 708 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
665 | 709 |
666 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | 710 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
667 | 711 |
668 // Write out the serialization header value for this object. | 712 // Write out the serialization header value for this object. |
669 WriteSerializationMarker(kInlined, object_id); | 713 WriteInlinedObjectHeader(object_id); |
670 | 714 |
671 // Write out the class information. | 715 // Write out the class information. |
672 WriteIndexedObject(ObjectStore::kArrayClass); | 716 WriteIndexedObject(ObjectStore::kArrayClass); |
673 | 717 |
674 // Write out the length field. | 718 // Write out the length field. |
675 Write<RawObject*>(rawarray->ptr()->length_); | 719 Write<RawObject*>(rawarray->ptr()->length_); |
676 | 720 |
677 return; | 721 return; |
678 } | 722 } |
679 if (obj_kind == ImmutableArray::kInstanceKind) { | 723 if (obj_kind == ImmutableArray::kInstanceKind) { |
680 // Object is being referenced, add it to the forward ref list and mark | 724 // Object is being referenced, add it to the forward ref list and mark |
681 // it so that future references to this object in the snapshot will use | 725 // it so that future references to this object in the snapshot will use |
682 // this object id. Mark it as not having been serialized yet so that we | 726 // this object id. Mark it as not having been serialized yet so that we |
683 // will serialize the object when we go through the forward list. | 727 // will serialize the object when we go through the forward list. |
684 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 728 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
685 | 729 |
686 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | 730 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
687 | 731 |
688 // Write out the serialization header value for this object. | 732 // Write out the serialization header value for this object. |
689 WriteSerializationMarker(kInlined, object_id); | 733 WriteInlinedObjectHeader(object_id); |
690 | 734 |
691 // Write out the class information. | 735 // Write out the class information. |
692 WriteIndexedObject(ObjectStore::kImmutableArrayClass); | 736 WriteIndexedObject(ObjectStore::kImmutableArrayClass); |
693 | 737 |
694 // Write out the length field. | 738 // Write out the length field. |
695 Write<RawObject*>(rawarray->ptr()->length_); | 739 Write<RawObject*>(rawarray->ptr()->length_); |
696 | 740 |
697 return; | 741 return; |
698 } | 742 } |
699 // Object is being referenced, add it to the forward ref list and mark | 743 // Object is being referenced, add it to the forward ref list and mark |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 // - Object that has already been written: (negative id in stream | 0x3) | 824 // - Object that has already been written: (negative id in stream | 0x3) |
781 | 825 |
782 NoGCScope no_gc; | 826 NoGCScope no_gc; |
783 | 827 |
784 // First check if it is a Smi (i.e not a heap object). | 828 // First check if it is a Smi (i.e not a heap object). |
785 if (!rawobj->IsHeapObject()) { | 829 if (!rawobj->IsHeapObject()) { |
786 Write<int64_t>(reinterpret_cast<intptr_t>(rawobj)); | 830 Write<int64_t>(reinterpret_cast<intptr_t>(rawobj)); |
787 return true; | 831 return true; |
788 } | 832 } |
789 | 833 |
790 // Check if it is a singleton null object which is shared by all isolates. | 834 // Check if object has already been serialized, in that case just write |
791 if (rawobj == Object::null()) { | 835 // the object id out. |
792 WriteIndexedObject(Object::kNullObject); | 836 uword tags = rawobj->ptr()->tags_; |
| 837 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
| 838 intptr_t id = SerializedHeaderData::decode(tags); |
| 839 WriteIndexedObject(id); |
793 return true; | 840 return true; |
794 } | 841 } |
795 | 842 |
796 // Check if it is a singleton sentinel object which is shared by all isolates. | 843 // Now check if it is an object from the VM isolate (NOTE: premarked objects |
797 if (rawobj == Object::sentinel()) { | 844 // are considered to be objects in the VM isolate). These objects are shared |
798 WriteIndexedObject(Object::kSentinelObject); | 845 // by all isolates. |
799 return true; | 846 if (rawobj->IsMarked()) { |
800 } | 847 HandleVMIsolateObject(rawobj); |
801 | |
802 // Check if it is a singleton class object which is shared by | |
803 // all isolates. | |
804 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); | |
805 intptr_t index = Object::GetSingletonClassIndex(raw_class); | |
806 if (index != Object::kInvalidIndex) { | |
807 WriteIndexedObject(index); | |
808 return true; | 848 return true; |
809 } | 849 } |
810 | 850 |
811 // Check if it is a singleton boolean true value. | 851 // Check if it is a singleton boolean true value. |
812 if (rawobj == object_store()->true_value()) { | 852 if (rawobj == object_store()->true_value()) { |
813 WriteIndexedObject(ObjectStore::kTrueValue); | 853 WriteIndexedObject(ObjectStore::kTrueValue); |
814 return true; | 854 return true; |
815 } | 855 } |
816 | 856 |
817 // Check if it is a singleton boolean false value. | 857 // Check if it is a singleton boolean false value. |
818 if (rawobj == object_store()->false_value()) { | 858 if (rawobj == object_store()->false_value()) { |
819 WriteIndexedObject(ObjectStore::kFalseValue); | 859 WriteIndexedObject(ObjectStore::kFalseValue); |
820 return true; | 860 return true; |
821 } | 861 } |
822 | 862 |
823 // Check if it is a code object in that case just write a Null object | 863 // Check if it is a code object in that case just write a Null object |
824 // as we do not want code objects in the snapshot. | 864 // as we do not want code objects in the snapshot. |
825 if (RawObject::ClassIdTag::decode(GetObjectTags(rawobj)) == kCode) { | 865 if (rawobj->GetClassId() == kCode) { |
826 WriteIndexedObject(Object::kNullObject); | 866 WriteVMIsolateObject(Object::kNullObject); |
827 return true; | 867 return true; |
828 } | 868 } |
829 | 869 |
830 // Check if classes are not being serialized and it is preinitialized type. | 870 // Check if classes are not being serialized and it is preinitialized type. |
831 if (kind_ != Snapshot::kFull) { | 871 if (kind_ != Snapshot::kFull) { |
832 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); | 872 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); |
833 index = object_store()->GetTypeIndex(raw_type); | 873 intptr_t index = object_store()->GetTypeIndex(raw_type); |
834 if (index != ObjectStore::kInvalidIndex) { | 874 if (index != ObjectStore::kInvalidIndex) { |
835 WriteIndexedObject(index); | 875 WriteIndexedObject(index); |
836 return true; | 876 return true; |
837 } | 877 } |
838 } | 878 } |
839 | 879 |
840 return false; | 880 return false; |
841 } | 881 } |
842 | 882 |
843 | 883 |
844 void SnapshotWriter::WriteObjectImpl(RawObject* raw) { | 884 void SnapshotWriter::WriteObjectImpl(RawObject* raw) { |
845 // First check if object can be written as a simple predefined type. | 885 // First check if object can be written as a simple predefined type. |
846 if (CheckAndWritePredefinedObject(raw)) { | 886 if (CheckAndWritePredefinedObject(raw)) { |
847 return; | 887 return; |
848 } | 888 } |
849 | 889 |
850 // Check if object has already been serialized, in that | |
851 // case just write the object id out. | |
852 uword tags = raw->ptr()->tags_; | |
853 if (SerializedHeaderTag::decode(tags) == kObjectId) { | |
854 intptr_t id = SerializedHeaderData::decode(tags); | |
855 WriteIndexedObject(id); | |
856 return; | |
857 } | |
858 | |
859 // Object is being serialized, add it to the forward ref list and mark | 890 // Object is being serialized, add it to the forward ref list and mark |
860 // it so that future references to this object in the snapshot will use | 891 // it so that future references to this object in the snapshot will use |
861 // an object id, instead of trying to serialize it again. | 892 // an object id, instead of trying to serialize it again. |
862 MarkObject(raw, kIsSerialized); | 893 MarkObject(raw, kIsSerialized); |
863 | 894 |
864 WriteInlinedObject(raw); | 895 WriteInlinedObject(raw); |
865 } | 896 } |
866 | 897 |
867 | 898 |
868 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { | 899 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { |
869 // Assert object is not a simple predefined type. | |
870 ASSERT(!CheckAndWritePredefinedObject(raw)); | |
871 | |
872 // Now write the object out inline in the stream as follows: | 900 // Now write the object out inline in the stream as follows: |
873 // - Object is seen for the first time (inlined as follows): | 901 // - Object is seen for the first time (inlined as follows): |
874 // (object size in multiples of kObjectAlignment | 0x1) | 902 // (object size in multiples of kObjectAlignment | 0x1) |
875 // serialized fields of the object | 903 // serialized fields of the object |
876 // ...... | 904 // ...... |
877 NoGCScope no_gc; | 905 NoGCScope no_gc; |
878 uword tags = raw->ptr()->tags_; | 906 uword tags = raw->ptr()->tags_; |
879 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | 907 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
880 intptr_t object_id = SerializedHeaderData::decode(tags); | 908 intptr_t object_id = SerializedHeaderData::decode(tags); |
881 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); | 909 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); |
882 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); | 910 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); |
883 ObjectKind kind = cls->ptr()->instance_kind_; | 911 ObjectKind kind = cls->ptr()->instance_kind_; |
884 | 912 |
885 if (kind == Instance::kInstanceKind) { | 913 if (kind == Instance::kInstanceKind) { |
886 // Object is regular dart instance. | 914 // Object is regular dart instance. |
887 // TODO(5411462): figure out what we need to do if an object with native | 915 // TODO(5411462): figure out what we need to do if an object with native |
888 // fields is serialized (throw exception or serialize a null object). | 916 // fields is serialized (throw exception or serialize a null object). |
889 ASSERT(cls->ptr()->num_native_fields_ == 0); | 917 ASSERT(cls->ptr()->num_native_fields_ == 0); |
890 intptr_t instance_size = cls->ptr()->instance_size_; | 918 intptr_t instance_size = cls->ptr()->instance_size_; |
891 ASSERT(instance_size != 0); | 919 ASSERT(instance_size != 0); |
892 | 920 |
893 // Write out the serialization header value for this object. | 921 // Write out the serialization header value for this object. |
894 WriteSerializationMarker(kInlined, object_id); | 922 WriteInlinedObjectHeader(object_id); |
895 | 923 |
896 // Indicate this is an instance object. | 924 // Indicate this is an instance object. |
897 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); | 925 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); |
898 | 926 |
899 // Write out the tags. | 927 // Write out the tags. |
900 WriteIntptrValue(tags); | 928 WriteIntptrValue(tags); |
901 | 929 |
902 // Write out the class information for this object. | 930 // Write out the class information for this object. |
903 WriteObjectImpl(cls); | 931 WriteObjectImpl(cls); |
904 | 932 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 // Mark object as serialized. | 970 // Mark object as serialized. |
943 forward_list_[i]->set_state(kIsSerialized); | 971 forward_list_[i]->set_state(kIsSerialized); |
944 } | 972 } |
945 } | 973 } |
946 } | 974 } |
947 | 975 |
948 | 976 |
949 void SnapshotWriter::WriteClassId(RawClass* cls) { | 977 void SnapshotWriter::WriteClassId(RawClass* cls) { |
950 ASSERT(kind_ != Snapshot::kFull); | 978 ASSERT(kind_ != Snapshot::kFull); |
951 int id = object_store()->GetClassIndex(cls); | 979 int id = object_store()->GetClassIndex(cls); |
952 if (IsSingletonClassId(id) || IsObjectStoreClassId(id)) { | 980 if (IsSingletonClassId(id)) { |
| 981 WriteVMIsolateObject(id); |
| 982 } else if (IsObjectStoreClassId(id)) { |
953 WriteIndexedObject(id); | 983 WriteIndexedObject(id); |
954 } else { | 984 } else { |
955 // TODO(5411462): Should restrict this to only core-lib classes in this | 985 // TODO(5411462): Should restrict this to only core-lib classes in this |
956 // case. | 986 // case. |
957 // Write out the class and tags information. | 987 // Write out the class and tags information. |
958 WriteObjectHeader(Object::kClassClass, GetObjectTags(cls)); | 988 WriteVMIsolateObject(Object::kClassClass); |
| 989 WriteIntptrValue(GetObjectTags(cls)); |
959 | 990 |
960 // Write out the library url and class name. | 991 // Write out the library url and class name. |
961 RawLibrary* library = cls->ptr()->library_; | 992 RawLibrary* library = cls->ptr()->library_; |
962 ASSERT(library != Library::null()); | 993 ASSERT(library != Library::null()); |
963 WriteObjectImpl(library->ptr()->url_); | 994 WriteObjectImpl(library->ptr()->url_); |
964 WriteObjectImpl(cls->ptr()->name_); | 995 WriteObjectImpl(cls->ptr()->name_); |
965 } | 996 } |
966 } | 997 } |
967 | 998 |
968 | 999 |
969 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, | 1000 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, |
970 intptr_t array_kind, | 1001 intptr_t array_kind, |
971 intptr_t tags, | 1002 intptr_t tags, |
972 RawSmi* length, | 1003 RawSmi* length, |
973 RawAbstractTypeArguments* type_arguments, | 1004 RawAbstractTypeArguments* type_arguments, |
974 RawObject* data[]) { | 1005 RawObject* data[]) { |
975 intptr_t len = Smi::Value(length); | 1006 intptr_t len = Smi::Value(length); |
976 | 1007 |
977 // Write out the serialization header value for this object. | 1008 // Write out the serialization header value for this object. |
978 WriteSerializationMarker(kInlined, object_id); | 1009 WriteInlinedObjectHeader(object_id); |
979 | 1010 |
980 // Write out the class and tags information. | 1011 // Write out the class and tags information. |
981 WriteObjectHeader(array_kind, tags); | 1012 WriteIndexedObject(array_kind); |
| 1013 WriteIntptrValue(tags); |
982 | 1014 |
983 // Write out the length field. | 1015 // Write out the length field. |
984 Write<RawObject*>(length); | 1016 Write<RawObject*>(length); |
985 | 1017 |
986 // Write out the type arguments. | 1018 // Write out the type arguments. |
987 WriteObjectImpl(type_arguments); | 1019 WriteObjectImpl(type_arguments); |
988 | 1020 |
989 // Write out the individual object ids. | 1021 // Write out the individual object ids. |
990 for (intptr_t i = 0; i < len; i++) { | 1022 for (intptr_t i = 0; i < len; i++) { |
991 WriteObjectRef(data[i]); | 1023 WriteObjectRef(data[i]); |
(...skipping 17 matching lines...) Expand all Loading... |
1009 RawObject* raw_obj = *current; | 1041 RawObject* raw_obj = *current; |
1010 if (as_references_) { | 1042 if (as_references_) { |
1011 writer_->WriteObjectRef(raw_obj); | 1043 writer_->WriteObjectRef(raw_obj); |
1012 } else { | 1044 } else { |
1013 writer_->WriteObjectImpl(raw_obj); | 1045 writer_->WriteObjectImpl(raw_obj); |
1014 } | 1046 } |
1015 } | 1047 } |
1016 } | 1048 } |
1017 | 1049 |
1018 } // namespace dart | 1050 } // namespace dart |
OLD | NEW |