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 return Symbols::GetVMSymbol(object_id); // return VM symbol. |
| 528 } |
| 529 UNREACHABLE(); |
| 530 } |
| 531 |
| 532 |
| 533 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { |
| 534 if (IsObjectStoreClassId(object_id)) { |
524 return object_store()->GetClass(object_id); | 535 return object_store()->GetClass(object_id); |
525 } else if (object_id == ObjectStore::kTrueValue) { | 536 } else if (object_id == ObjectStore::kTrueValue) { |
526 return object_store()->true_value(); | 537 return object_store()->true_value(); |
527 } else if (object_id == ObjectStore::kFalseValue) { | 538 } else if (object_id == ObjectStore::kFalseValue) { |
528 return object_store()->false_value(); | 539 return object_store()->false_value(); |
529 } else if (kind_ != Snapshot::kFull) { | 540 } else if (kind_ != Snapshot::kFull) { |
530 if (IsObjectStoreTypeId(object_id)) { | 541 if (IsObjectStoreTypeId(object_id)) { |
531 return object_store()->GetType(object_id); // return type object. | 542 return object_store()->GetType(object_id); // return type object. |
532 } | 543 } |
533 } | 544 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 } | 624 } |
614 } | 625 } |
615 | 626 |
616 | 627 |
617 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 628 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
618 WriteObjectImpl(rawobj); | 629 WriteObjectImpl(rawobj); |
619 WriteForwardedObjects(); | 630 WriteForwardedObjects(); |
620 } | 631 } |
621 | 632 |
622 | 633 |
| 634 void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| 635 // Check if it is a singleton null object. |
| 636 if (rawobj == Object::null()) { |
| 637 WriteVMIsolateObject(Object::kNullObject); |
| 638 return; |
| 639 } |
| 640 |
| 641 // Check if it is a singleton sentinel object. |
| 642 if (rawobj == Object::sentinel()) { |
| 643 WriteVMIsolateObject(Object::kSentinelObject); |
| 644 return; |
| 645 } |
| 646 |
| 647 // Check if it is a singleton class object. |
| 648 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); |
| 649 intptr_t index = Object::GetSingletonClassIndex(raw_class); |
| 650 if (index != Object::kInvalidIndex) { |
| 651 WriteVMIsolateObject(index); |
| 652 return; |
| 653 } |
| 654 |
| 655 // Check it is a predefined symbol. |
| 656 index = Symbols::LookupVMSymbol(rawobj); |
| 657 if (index != Object::kInvalidIndex) { |
| 658 WriteVMIsolateObject(index); |
| 659 return; |
| 660 } |
| 661 |
| 662 UNREACHABLE(); |
| 663 } |
| 664 |
| 665 |
623 void SnapshotWriter::WriteObjectRef(RawObject* raw) { | 666 void SnapshotWriter::WriteObjectRef(RawObject* raw) { |
624 // First check if object can be written as a simple predefined type. | 667 // First check if object can be written as a simple predefined type. |
625 if (CheckAndWritePredefinedObject(raw)) { | 668 if (CheckAndWritePredefinedObject(raw)) { |
626 return; | 669 return; |
627 } | 670 } |
628 // Check if object has already been serialized, in that | 671 // Check if object has already been serialized, in that |
629 // case just write the object id out. | 672 // case just write the object id out. |
630 uword tags = raw->ptr()->tags_; | 673 uword tags = raw->ptr()->tags_; |
631 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 674 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
632 intptr_t id = SerializedHeaderData::decode(tags); | 675 intptr_t id = SerializedHeaderData::decode(tags); |
633 WriteIndexedObject(id); | 676 WriteIndexedObject(id); |
634 return; | 677 return; |
635 } | 678 } |
636 | 679 |
637 NoGCScope no_gc; | 680 NoGCScope no_gc; |
638 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); | 681 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); |
639 | 682 |
640 ObjectKind obj_kind = cls->ptr()->instance_kind_; | 683 ObjectKind obj_kind = cls->ptr()->instance_kind_; |
641 if (obj_kind == Instance::kInstanceKind) { | 684 if (obj_kind == Instance::kInstanceKind) { |
642 // Object is being referenced, add it to the forward ref list and mark | 685 // 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 | 686 // 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 | 687 // 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. | 688 // will serialize the object when we go through the forward list. |
646 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 689 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
647 | 690 |
648 // Write out the serialization header value for this object. | 691 // Write out the serialization header value for this object. |
649 WriteSerializationMarker(kInlined, object_id); | 692 WriteInlinedObjectHeader(object_id); |
650 | 693 |
651 // Indicate this is an instance object. | 694 // Indicate this is an instance object. |
652 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); | 695 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); |
653 | 696 |
654 // Write out the class information for this object. | 697 // Write out the class information for this object. |
655 WriteObjectImpl(cls); | 698 WriteObjectImpl(cls); |
656 | 699 |
657 return; | 700 return; |
658 } | 701 } |
659 if (obj_kind == Array::kInstanceKind) { | 702 if (obj_kind == Array::kInstanceKind) { |
660 // Object is being referenced, add it to the forward ref list and mark | 703 // 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 | 704 // 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 | 705 // 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. | 706 // will serialize the object when we go through the forward list. |
664 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 707 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
665 | 708 |
666 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | 709 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
667 | 710 |
668 // Write out the serialization header value for this object. | 711 // Write out the serialization header value for this object. |
669 WriteSerializationMarker(kInlined, object_id); | 712 WriteInlinedObjectHeader(object_id); |
670 | 713 |
671 // Write out the class information. | 714 // Write out the class information. |
672 WriteIndexedObject(ObjectStore::kArrayClass); | 715 WriteIndexedObject(ObjectStore::kArrayClass); |
673 | 716 |
674 // Write out the length field. | 717 // Write out the length field. |
675 Write<RawObject*>(rawarray->ptr()->length_); | 718 Write<RawObject*>(rawarray->ptr()->length_); |
676 | 719 |
677 return; | 720 return; |
678 } | 721 } |
679 if (obj_kind == ImmutableArray::kInstanceKind) { | 722 if (obj_kind == ImmutableArray::kInstanceKind) { |
680 // Object is being referenced, add it to the forward ref list and mark | 723 // 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 | 724 // 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 | 725 // 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. | 726 // will serialize the object when we go through the forward list. |
684 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 727 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
685 | 728 |
686 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | 729 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
687 | 730 |
688 // Write out the serialization header value for this object. | 731 // Write out the serialization header value for this object. |
689 WriteSerializationMarker(kInlined, object_id); | 732 WriteInlinedObjectHeader(object_id); |
690 | 733 |
691 // Write out the class information. | 734 // Write out the class information. |
692 WriteIndexedObject(ObjectStore::kImmutableArrayClass); | 735 WriteIndexedObject(ObjectStore::kImmutableArrayClass); |
693 | 736 |
694 // Write out the length field. | 737 // Write out the length field. |
695 Write<RawObject*>(rawarray->ptr()->length_); | 738 Write<RawObject*>(rawarray->ptr()->length_); |
696 | 739 |
697 return; | 740 return; |
698 } | 741 } |
699 // Object is being referenced, add it to the forward ref list and mark | 742 // 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) | 823 // - Object that has already been written: (negative id in stream | 0x3) |
781 | 824 |
782 NoGCScope no_gc; | 825 NoGCScope no_gc; |
783 | 826 |
784 // First check if it is a Smi (i.e not a heap object). | 827 // First check if it is a Smi (i.e not a heap object). |
785 if (!rawobj->IsHeapObject()) { | 828 if (!rawobj->IsHeapObject()) { |
786 Write<int64_t>(reinterpret_cast<intptr_t>(rawobj)); | 829 Write<int64_t>(reinterpret_cast<intptr_t>(rawobj)); |
787 return true; | 830 return true; |
788 } | 831 } |
789 | 832 |
790 // Check if it is a singleton null object which is shared by all isolates. | 833 // Check if object has already been serialized, in that case just write |
791 if (rawobj == Object::null()) { | 834 // the object id out. |
792 WriteIndexedObject(Object::kNullObject); | 835 uword tags = rawobj->ptr()->tags_; |
| 836 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
| 837 intptr_t id = SerializedHeaderData::decode(tags); |
| 838 WriteIndexedObject(id); |
793 return true; | 839 return true; |
794 } | 840 } |
795 | 841 |
796 // Check if it is a singleton sentinel object which is shared by all isolates. | 842 // Now check if it is an object from the VM isolate (NOTE: premarked objects |
797 if (rawobj == Object::sentinel()) { | 843 // are considered to be objects in the VM isolate). These objects are shared |
798 WriteIndexedObject(Object::kSentinelObject); | 844 // by all isolates. |
799 return true; | 845 if (rawobj->IsMarked()) { |
800 } | 846 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; | 847 return true; |
809 } | 848 } |
810 | 849 |
811 // Check if it is a singleton boolean true value. | 850 // Check if it is a singleton boolean true value. |
812 if (rawobj == object_store()->true_value()) { | 851 if (rawobj == object_store()->true_value()) { |
813 WriteIndexedObject(ObjectStore::kTrueValue); | 852 WriteIndexedObject(ObjectStore::kTrueValue); |
814 return true; | 853 return true; |
815 } | 854 } |
816 | 855 |
817 // Check if it is a singleton boolean false value. | 856 // Check if it is a singleton boolean false value. |
818 if (rawobj == object_store()->false_value()) { | 857 if (rawobj == object_store()->false_value()) { |
819 WriteIndexedObject(ObjectStore::kFalseValue); | 858 WriteIndexedObject(ObjectStore::kFalseValue); |
820 return true; | 859 return true; |
821 } | 860 } |
822 | 861 |
823 // Check if it is a code object in that case just write a Null object | 862 // 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. | 863 // as we do not want code objects in the snapshot. |
825 if (RawObject::ClassIdTag::decode(GetObjectTags(rawobj)) == kCode) { | 864 if (rawobj->GetClassId() == kCode) { |
826 WriteIndexedObject(Object::kNullObject); | 865 WriteVMIsolateObject(Object::kNullObject); |
827 return true; | 866 return true; |
828 } | 867 } |
829 | 868 |
830 // Check if classes are not being serialized and it is preinitialized type. | 869 // Check if classes are not being serialized and it is preinitialized type. |
831 if (kind_ != Snapshot::kFull) { | 870 if (kind_ != Snapshot::kFull) { |
832 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); | 871 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); |
833 index = object_store()->GetTypeIndex(raw_type); | 872 intptr_t index = object_store()->GetTypeIndex(raw_type); |
834 if (index != ObjectStore::kInvalidIndex) { | 873 if (index != ObjectStore::kInvalidIndex) { |
835 WriteIndexedObject(index); | 874 WriteIndexedObject(index); |
836 return true; | 875 return true; |
837 } | 876 } |
838 } | 877 } |
839 | 878 |
840 return false; | 879 return false; |
841 } | 880 } |
842 | 881 |
843 | 882 |
844 void SnapshotWriter::WriteObjectImpl(RawObject* raw) { | 883 void SnapshotWriter::WriteObjectImpl(RawObject* raw) { |
845 // First check if object can be written as a simple predefined type. | 884 // First check if object can be written as a simple predefined type. |
846 if (CheckAndWritePredefinedObject(raw)) { | 885 if (CheckAndWritePredefinedObject(raw)) { |
847 return; | 886 return; |
848 } | 887 } |
849 | 888 |
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 | 889 // 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 | 890 // it so that future references to this object in the snapshot will use |
861 // an object id, instead of trying to serialize it again. | 891 // an object id, instead of trying to serialize it again. |
862 MarkObject(raw, kIsSerialized); | 892 MarkObject(raw, kIsSerialized); |
863 | 893 |
864 WriteInlinedObject(raw); | 894 WriteInlinedObject(raw); |
865 } | 895 } |
866 | 896 |
867 | 897 |
868 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { | 898 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: | 899 // Now write the object out inline in the stream as follows: |
873 // - Object is seen for the first time (inlined as follows): | 900 // - Object is seen for the first time (inlined as follows): |
874 // (object size in multiples of kObjectAlignment | 0x1) | 901 // (object size in multiples of kObjectAlignment | 0x1) |
875 // serialized fields of the object | 902 // serialized fields of the object |
876 // ...... | 903 // ...... |
877 NoGCScope no_gc; | 904 NoGCScope no_gc; |
878 uword tags = raw->ptr()->tags_; | 905 uword tags = raw->ptr()->tags_; |
879 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | 906 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
880 intptr_t object_id = SerializedHeaderData::decode(tags); | 907 intptr_t object_id = SerializedHeaderData::decode(tags); |
881 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); | 908 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); |
882 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); | 909 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); |
883 ObjectKind kind = cls->ptr()->instance_kind_; | 910 ObjectKind kind = cls->ptr()->instance_kind_; |
884 | 911 |
885 if (kind == Instance::kInstanceKind) { | 912 if (kind == Instance::kInstanceKind) { |
886 // Object is regular dart instance. | 913 // Object is regular dart instance. |
887 // TODO(5411462): figure out what we need to do if an object with native | 914 // 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). | 915 // fields is serialized (throw exception or serialize a null object). |
889 ASSERT(cls->ptr()->num_native_fields_ == 0); | 916 ASSERT(cls->ptr()->num_native_fields_ == 0); |
890 intptr_t instance_size = cls->ptr()->instance_size_; | 917 intptr_t instance_size = cls->ptr()->instance_size_; |
891 ASSERT(instance_size != 0); | 918 ASSERT(instance_size != 0); |
892 | 919 |
893 // Write out the serialization header value for this object. | 920 // Write out the serialization header value for this object. |
894 WriteSerializationMarker(kInlined, object_id); | 921 WriteInlinedObjectHeader(object_id); |
895 | 922 |
896 // Indicate this is an instance object. | 923 // Indicate this is an instance object. |
897 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); | 924 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); |
898 | 925 |
899 // Write out the tags. | 926 // Write out the tags. |
900 WriteIntptrValue(tags); | 927 WriteIntptrValue(tags); |
901 | 928 |
902 // Write out the class information for this object. | 929 // Write out the class information for this object. |
903 WriteObjectImpl(cls); | 930 WriteObjectImpl(cls); |
904 | 931 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 // Mark object as serialized. | 969 // Mark object as serialized. |
943 forward_list_[i]->set_state(kIsSerialized); | 970 forward_list_[i]->set_state(kIsSerialized); |
944 } | 971 } |
945 } | 972 } |
946 } | 973 } |
947 | 974 |
948 | 975 |
949 void SnapshotWriter::WriteClassId(RawClass* cls) { | 976 void SnapshotWriter::WriteClassId(RawClass* cls) { |
950 ASSERT(kind_ != Snapshot::kFull); | 977 ASSERT(kind_ != Snapshot::kFull); |
951 int id = object_store()->GetClassIndex(cls); | 978 int id = object_store()->GetClassIndex(cls); |
952 if (IsSingletonClassId(id) || IsObjectStoreClassId(id)) { | 979 if (IsSingletonClassId(id)) { |
| 980 WriteVMIsolateObject(id); |
| 981 } else if (IsObjectStoreClassId(id)) { |
953 WriteIndexedObject(id); | 982 WriteIndexedObject(id); |
954 } else { | 983 } else { |
955 // TODO(5411462): Should restrict this to only core-lib classes in this | 984 // TODO(5411462): Should restrict this to only core-lib classes in this |
956 // case. | 985 // case. |
957 // Write out the class and tags information. | 986 // Write out the class and tags information. |
958 WriteObjectHeader(Object::kClassClass, GetObjectTags(cls)); | 987 WriteVMIsolateObject(Object::kClassClass); |
| 988 WriteIntptrValue(GetObjectTags(cls)); |
959 | 989 |
960 // Write out the library url and class name. | 990 // Write out the library url and class name. |
961 RawLibrary* library = cls->ptr()->library_; | 991 RawLibrary* library = cls->ptr()->library_; |
962 ASSERT(library != Library::null()); | 992 ASSERT(library != Library::null()); |
963 WriteObjectImpl(library->ptr()->url_); | 993 WriteObjectImpl(library->ptr()->url_); |
964 WriteObjectImpl(cls->ptr()->name_); | 994 WriteObjectImpl(cls->ptr()->name_); |
965 } | 995 } |
966 } | 996 } |
967 | 997 |
968 | 998 |
969 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, | 999 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, |
970 intptr_t array_kind, | 1000 intptr_t array_kind, |
971 intptr_t tags, | 1001 intptr_t tags, |
972 RawSmi* length, | 1002 RawSmi* length, |
973 RawAbstractTypeArguments* type_arguments, | 1003 RawAbstractTypeArguments* type_arguments, |
974 RawObject* data[]) { | 1004 RawObject* data[]) { |
975 intptr_t len = Smi::Value(length); | 1005 intptr_t len = Smi::Value(length); |
976 | 1006 |
977 // Write out the serialization header value for this object. | 1007 // Write out the serialization header value for this object. |
978 WriteSerializationMarker(kInlined, object_id); | 1008 WriteInlinedObjectHeader(object_id); |
979 | 1009 |
980 // Write out the class and tags information. | 1010 // Write out the class and tags information. |
981 WriteObjectHeader(array_kind, tags); | 1011 WriteIndexedObject(array_kind); |
| 1012 WriteIntptrValue(tags); |
982 | 1013 |
983 // Write out the length field. | 1014 // Write out the length field. |
984 Write<RawObject*>(length); | 1015 Write<RawObject*>(length); |
985 | 1016 |
986 // Write out the type arguments. | 1017 // Write out the type arguments. |
987 WriteObjectImpl(type_arguments); | 1018 WriteObjectImpl(type_arguments); |
988 | 1019 |
989 // Write out the individual object ids. | 1020 // Write out the individual object ids. |
990 for (intptr_t i = 0; i < len; i++) { | 1021 for (intptr_t i = 0; i < len; i++) { |
991 WriteObjectRef(data[i]); | 1022 WriteObjectRef(data[i]); |
(...skipping 17 matching lines...) Expand all Loading... |
1009 RawObject* raw_obj = *current; | 1040 RawObject* raw_obj = *current; |
1010 if (as_references_) { | 1041 if (as_references_) { |
1011 writer_->WriteObjectRef(raw_obj); | 1042 writer_->WriteObjectRef(raw_obj); |
1012 } else { | 1043 } else { |
1013 writer_->WriteObjectImpl(raw_obj); | 1044 writer_->WriteObjectImpl(raw_obj); |
1014 } | 1045 } |
1015 } | 1046 } |
1016 } | 1047 } |
1017 | 1048 |
1018 } // namespace dart | 1049 } // namespace dart |
OLD | NEW |