| 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 |