| 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 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 enum { | 17 enum { |
| 18 kInstanceId = ObjectStore::kMaxId, | 18 kInstanceId = ObjectStore::kMaxId, |
| 19 kMaxPredefinedObjectIds, | 19 kMaxPredefinedObjectIds, |
| 20 }; | 20 }; |
| 21 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; | 21 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; |
| 22 static const int kNumInitialReferences = 4; | 22 static const int kNumInitialReferences = 4; |
| 23 | 23 |
| 24 | 24 |
| 25 static bool IsSingletonClassId(intptr_t index) { | 25 static bool IsSingletonClassId(intptr_t index) { |
| 26 // Check if this is a singleton object class which is shared by all isolates. | 26 // Check if this is a singleton class which is shared by all isolates. |
| 27 return (index >= Object::kClassClass && index < Object::kMaxId); | 27 return ((index >= kClass && index <= kUnwindError) || |
| 28 (index >= kNullClassId && index <= kVoidClassId)); |
| 28 } | 29 } |
| 29 | 30 |
| 30 | 31 |
| 31 static bool IsObjectStoreClassId(intptr_t index) { | 32 static bool IsObjectStoreClassId(intptr_t index) { |
| 32 // Check if this is a class which is stored in the object store. | 33 // Check if this is a class which is stored in the object store. |
| 33 return (index >= ObjectStore::kObjectClass && index < ObjectStore::kMaxId); | 34 return ((index == kObject) || (index >= kInstance && index <= kJSRegExp)); |
| 34 } | 35 } |
| 35 | 36 |
| 36 | 37 |
| 37 static bool IsObjectStoreTypeId(intptr_t index) { | 38 static bool IsObjectStoreTypeId(intptr_t index) { |
| 38 // Check if this is a type which is stored in the object store. | 39 // Check if this is a type which is stored in the object store. |
| 39 return (index >= ObjectStore::kObjectType && | 40 return (index >= ObjectStore::kObjectType && |
| 40 index <= ObjectStore::kListInterface); | 41 index <= ObjectStore::kByteArrayInterface); |
| 41 } | 42 } |
| 42 | 43 |
| 43 | 44 |
| 44 // TODO(5411462): Temporary setup of snapshot for testing purposes, | 45 // TODO(5411462): Temporary setup of snapshot for testing purposes, |
| 45 // the actual creation of a snapshot maybe done differently. | 46 // the actual creation of a snapshot maybe done differently. |
| 46 const Snapshot* Snapshot::SetupFromBuffer(const void* raw_memory) { | 47 const Snapshot* Snapshot::SetupFromBuffer(const void* raw_memory) { |
| 47 ASSERT(raw_memory != NULL); | 48 ASSERT(raw_memory != NULL); |
| 48 ASSERT(kHeaderSize == sizeof(Snapshot)); | 49 ASSERT(kHeaderSize == sizeof(Snapshot)); |
| 49 ASSERT(kLengthIndex == length_offset()); | 50 ASSERT(kLengthIndex == length_offset()); |
| 50 ASSERT((kSnapshotFlagIndex * sizeof(int32_t)) == kind_offset()); | 51 ASSERT((kSnapshotFlagIndex * sizeof(int32_t)) == kind_offset()); |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header); |
| 472 | 473 |
| 473 // If the header is an object Id, lookup singleton VM classes or classes | 474 // If the header is an object Id, lookup singleton VM classes or classes |
| 474 // stored in the object store. | 475 // stored in the object store. |
| 475 if (header_type == kObjectId) { | 476 if (header_type == kObjectId) { |
| 476 intptr_t header_value = SerializedHeaderData::decode(class_header); | 477 intptr_t header_value = SerializedHeaderData::decode(class_header); |
| 477 if (IsObjectStoreClassId(header_value)) { | 478 if (IsObjectStoreClassId(header_value) || |
| 478 return object_store()->GetClass(header_value); | 479 IsSingletonClassId(header_value)) { |
| 479 } else if (IsSingletonClassId(header_value)) { | 480 return class_table()->At(header_value); |
| 480 return Object::GetSingletonClass(header_value); // return the singleton. | |
| 481 } | 481 } |
| 482 } | 482 } |
| 483 return Class::null(); | 483 return Class::null(); |
| 484 } | 484 } |
| 485 | 485 |
| 486 | 486 |
| 487 RawObject* SnapshotReader::AllocateUninitialized(const Class& cls, | 487 RawObject* SnapshotReader::AllocateUninitialized(const Class& cls, |
| 488 intptr_t size) { | 488 intptr_t size) { |
| 489 ASSERT(isolate()->no_gc_scope_depth() != 0); | 489 ASSERT(isolate()->no_gc_scope_depth() != 0); |
| 490 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 490 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 511 | 511 |
| 512 | 512 |
| 513 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { | 513 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { |
| 514 if (object_id == Object::kNullObject) { | 514 if (object_id == Object::kNullObject) { |
| 515 // This is a singleton null object, return it. | 515 // This is a singleton null object, return it. |
| 516 return Object::null(); | 516 return Object::null(); |
| 517 } | 517 } |
| 518 if (object_id == Object::kSentinelObject) { | 518 if (object_id == Object::kSentinelObject) { |
| 519 return Object::sentinel(); | 519 return Object::sentinel(); |
| 520 } | 520 } |
| 521 if (IsSingletonClassId(object_id)) { | 521 if (IsSingletonClassId(object_id) || IsObjectStoreClassId(object_id)) { |
| 522 return Object::GetSingletonClass(object_id); // return singleton object. | 522 return class_table()->At(object_id); |
| 523 } else if (IsObjectStoreClassId(object_id)) { | |
| 524 return object_store()->GetClass(object_id); | |
| 525 } else if (object_id == ObjectStore::kTrueValue) { | 523 } else if (object_id == ObjectStore::kTrueValue) { |
| 526 return object_store()->true_value(); | 524 return object_store()->true_value(); |
| 527 } else if (object_id == ObjectStore::kFalseValue) { | 525 } else if (object_id == ObjectStore::kFalseValue) { |
| 528 return object_store()->false_value(); | 526 return object_store()->false_value(); |
| 529 } else if (kind_ != Snapshot::kFull) { | 527 } else if (kind_ != Snapshot::kFull) { |
| 530 if (IsObjectStoreTypeId(object_id)) { | 528 if (IsObjectStoreTypeId(object_id)) { |
| 531 return object_store()->GetType(object_id); // return type object. | 529 return object_store()->GetType(object_id); // return type object. |
| 532 } | 530 } |
| 533 } | 531 } |
| 534 | 532 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 // this object id. Mark it as not having been serialized yet so that we | 660 // 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. | 661 // will serialize the object when we go through the forward list. |
| 664 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 662 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
| 665 | 663 |
| 666 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | 664 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
| 667 | 665 |
| 668 // Write out the serialization header value for this object. | 666 // Write out the serialization header value for this object. |
| 669 WriteSerializationMarker(kInlined, object_id); | 667 WriteSerializationMarker(kInlined, object_id); |
| 670 | 668 |
| 671 // Write out the class information. | 669 // Write out the class information. |
| 672 WriteIndexedObject(ObjectStore::kArrayClass); | 670 WriteIndexedObject(kArray); |
| 673 | 671 |
| 674 // Write out the length field. | 672 // Write out the length field. |
| 675 Write<RawObject*>(rawarray->ptr()->length_); | 673 Write<RawObject*>(rawarray->ptr()->length_); |
| 676 | 674 |
| 677 return; | 675 return; |
| 678 } | 676 } |
| 679 if (obj_kind == ImmutableArray::kInstanceKind) { | 677 if (obj_kind == ImmutableArray::kInstanceKind) { |
| 680 // Object is being referenced, add it to the forward ref list and mark | 678 // 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 | 679 // 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 | 680 // 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. | 681 // will serialize the object when we go through the forward list. |
| 684 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 682 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
| 685 | 683 |
| 686 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | 684 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
| 687 | 685 |
| 688 // Write out the serialization header value for this object. | 686 // Write out the serialization header value for this object. |
| 689 WriteSerializationMarker(kInlined, object_id); | 687 WriteSerializationMarker(kInlined, object_id); |
| 690 | 688 |
| 691 // Write out the class information. | 689 // Write out the class information. |
| 692 WriteIndexedObject(ObjectStore::kImmutableArrayClass); | 690 WriteIndexedObject(kImmutableArray); |
| 693 | 691 |
| 694 // Write out the length field. | 692 // Write out the length field. |
| 695 Write<RawObject*>(rawarray->ptr()->length_); | 693 Write<RawObject*>(rawarray->ptr()->length_); |
| 696 | 694 |
| 697 return; | 695 return; |
| 698 } | 696 } |
| 699 // Object is being referenced, add it to the forward ref list and mark | 697 // Object is being referenced, add it to the forward ref list and mark |
| 700 // it so that future references to this object in the snapshot will use | 698 // it so that future references to this object in the snapshot will use |
| 701 // this object id. Mark it as not having been serialized yet so that we | 699 // this object id. Mark it as not having been serialized yet so that we |
| 702 // will serialize the object when we go through the forward list. | 700 // will serialize the object when we go through the forward list. |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 } | 792 } |
| 795 | 793 |
| 796 // Check if it is a singleton sentinel object which is shared by all isolates. | 794 // Check if it is a singleton sentinel object which is shared by all isolates. |
| 797 if (rawobj == Object::sentinel()) { | 795 if (rawobj == Object::sentinel()) { |
| 798 WriteIndexedObject(Object::kSentinelObject); | 796 WriteIndexedObject(Object::kSentinelObject); |
| 799 return true; | 797 return true; |
| 800 } | 798 } |
| 801 | 799 |
| 802 // Check if it is a singleton class object which is shared by | 800 // Check if it is a singleton class object which is shared by |
| 803 // all isolates. | 801 // all isolates. |
| 804 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); | 802 intptr_t index = Object::GetSingletonClassIndex(rawobj); |
| 805 intptr_t index = Object::GetSingletonClassIndex(raw_class); | |
| 806 if (index != Object::kInvalidIndex) { | 803 if (index != Object::kInvalidIndex) { |
| 807 WriteIndexedObject(index); | 804 WriteIndexedObject(index); |
| 808 return true; | 805 return true; |
| 809 } | 806 } |
| 810 | 807 |
| 811 // Check if it is a singleton boolean true value. | 808 // Check if it is a singleton boolean true value. |
| 812 if (rawobj == object_store()->true_value()) { | 809 if (rawobj == object_store()->true_value()) { |
| 813 WriteIndexedObject(ObjectStore::kTrueValue); | 810 WriteIndexedObject(ObjectStore::kTrueValue); |
| 814 return true; | 811 return true; |
| 815 } | 812 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 | 938 |
| 942 // Mark object as serialized. | 939 // Mark object as serialized. |
| 943 forward_list_[i]->set_state(kIsSerialized); | 940 forward_list_[i]->set_state(kIsSerialized); |
| 944 } | 941 } |
| 945 } | 942 } |
| 946 } | 943 } |
| 947 | 944 |
| 948 | 945 |
| 949 void SnapshotWriter::WriteClassId(RawClass* cls) { | 946 void SnapshotWriter::WriteClassId(RawClass* cls) { |
| 950 ASSERT(kind_ != Snapshot::kFull); | 947 ASSERT(kind_ != Snapshot::kFull); |
| 951 int id = object_store()->GetClassIndex(cls); | 948 int id = cls->ptr()->id_; |
| 952 if (IsSingletonClassId(id) || IsObjectStoreClassId(id)) { | 949 if (IsSingletonClassId(id) || IsObjectStoreClassId(id)) { |
| 953 WriteIndexedObject(id); | 950 WriteIndexedObject(id); |
| 954 } else { | 951 } else { |
| 955 // TODO(5411462): Should restrict this to only core-lib classes in this | 952 // TODO(5411462): Should restrict this to only core-lib classes in this |
| 956 // case. | 953 // case. |
| 957 // Write out the class and tags information. | 954 // Write out the class and tags information. |
| 958 WriteObjectHeader(Object::kClassClass, GetObjectTags(cls)); | 955 WriteObjectHeader(kClass, GetObjectTags(cls)); |
| 959 | 956 |
| 960 // Write out the library url and class name. | 957 // Write out the library url and class name. |
| 961 RawLibrary* library = cls->ptr()->library_; | 958 RawLibrary* library = cls->ptr()->library_; |
| 962 ASSERT(library != Library::null()); | 959 ASSERT(library != Library::null()); |
| 963 WriteObjectImpl(library->ptr()->url_); | 960 WriteObjectImpl(library->ptr()->url_); |
| 964 WriteObjectImpl(cls->ptr()->name_); | 961 WriteObjectImpl(cls->ptr()->name_); |
| 965 } | 962 } |
| 966 } | 963 } |
| 967 | 964 |
| 968 | 965 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 RawObject* raw_obj = *current; | 1006 RawObject* raw_obj = *current; |
| 1010 if (as_references_) { | 1007 if (as_references_) { |
| 1011 writer_->WriteObjectRef(raw_obj); | 1008 writer_->WriteObjectRef(raw_obj); |
| 1012 } else { | 1009 } else { |
| 1013 writer_->WriteObjectImpl(raw_obj); | 1010 writer_->WriteObjectImpl(raw_obj); |
| 1014 } | 1011 } |
| 1015 } | 1012 } |
| 1016 } | 1013 } |
| 1017 | 1014 |
| 1018 } // namespace dart | 1015 } // namespace dart |
| OLD | NEW |