| 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/bootstrap.h" | 8 #include "vm/bootstrap.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/exceptions.h" | 10 #include "vm/exceptions.h" |
| (...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 } else { | 944 } else { |
| 945 cls_ ^= ReadObjectImpl(); | 945 cls_ ^= ReadObjectImpl(); |
| 946 ASSERT(!cls_.IsNull()); | 946 ASSERT(!cls_.IsNull()); |
| 947 instance_size = cls_.instance_size(); | 947 instance_size = cls_.instance_size(); |
| 948 } | 948 } |
| 949 intptr_t next_field_offset = cls_.next_field_offset(); | 949 intptr_t next_field_offset = cls_.next_field_offset(); |
| 950 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); | 950 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); |
| 951 ASSERT(next_field_offset > 0); | 951 ASSERT(next_field_offset > 0); |
| 952 // Instance::NextFieldOffset() returns the offset of the first field in | 952 // Instance::NextFieldOffset() returns the offset of the first field in |
| 953 // a Dart object. | 953 // a Dart object. |
| 954 bool is_canonical = RawObject::IsCanonical(tags); |
| 954 intptr_t offset = Instance::NextFieldOffset(); | 955 intptr_t offset = Instance::NextFieldOffset(); |
| 955 intptr_t result_cid = result->GetClassId(); | 956 intptr_t result_cid = result->GetClassId(); |
| 956 while (offset < next_field_offset) { | 957 while (offset < next_field_offset) { |
| 957 pobj_ = ReadObjectRef(); | 958 pobj_ = is_canonical ? ReadObjectImpl() : ReadObjectRef(); |
| 958 result->SetFieldAtOffset(offset, pobj_); | 959 result->SetFieldAtOffset(offset, pobj_); |
| 959 if ((offset != type_argument_field_offset) && | 960 if ((offset != type_argument_field_offset) && |
| 960 (kind_ == Snapshot::kMessage)) { | 961 (kind_ == Snapshot::kMessage)) { |
| 961 // TODO(fschneider): Consider hoisting these lookups out of the loop. | 962 // TODO(fschneider): Consider hoisting these lookups out of the loop. |
| 962 // This would involve creating a handle, since cls_ can't be reused | 963 // This would involve creating a handle, since cls_ can't be reused |
| 963 // across the call to ReadObjectRef. | 964 // across the call to ReadObjectRef. |
| 964 cls_ = isolate()->class_table()->At(result_cid); | 965 cls_ = isolate()->class_table()->At(result_cid); |
| 965 array_ = cls_.OffsetToFieldMap(); | 966 array_ = cls_.OffsetToFieldMap(); |
| 966 field_ ^= array_.At(offset >> kWordSizeLog2); | 967 field_ ^= array_.At(offset >> kWordSizeLog2); |
| 967 ASSERT(!field_.IsNull()); | 968 ASSERT(!field_.IsNull()); |
| 968 ASSERT(field_.Offset() == offset); | 969 ASSERT(field_.Offset() == offset); |
| 969 obj_ = pobj_.raw(); | 970 obj_ = pobj_.raw(); |
| 970 field_.RecordStore(obj_); | 971 field_.RecordStore(obj_); |
| 971 } | 972 } |
| 972 // TODO(fschneider): Verify the guarded cid and length for other kinds of | 973 // TODO(fschneider): Verify the guarded cid and length for other kinds of |
| 973 // snapshot (kFull, kScript) with asserts. | 974 // snapshot (kFull, kScript) with asserts. |
| 974 offset += kWordSize; | 975 offset += kWordSize; |
| 975 } | 976 } |
| 976 if (kind_ == Snapshot::kFull) { | 977 if (kind_ == Snapshot::kFull) { |
| 977 // We create an uninitialized object in the case of full snapshots, so | 978 // We create an uninitialized object in the case of full snapshots, so |
| 978 // we need to initialize any remaining padding area with the Null object. | 979 // we need to initialize any remaining padding area with the Null object. |
| 979 while (offset < instance_size) { | 980 while (offset < instance_size) { |
| 980 result->SetFieldAtOffset(offset, Object::null_object()); | 981 result->SetFieldAtOffset(offset, Object::null_object()); |
| 981 offset += kWordSize; | 982 offset += kWordSize; |
| 982 } | 983 } |
| 983 result->SetCreatedFromSnapshot(); | 984 result->SetCreatedFromSnapshot(); |
| 984 } else if (false && RawObject::IsCanonical(tags)) { | 985 } else if (RawObject::IsCanonical(tags)) { |
| 985 *result = result->CheckAndCanonicalize(NULL); | 986 *result = result->CheckAndCanonicalize(NULL); |
| 986 ASSERT(!result->IsNull()); | 987 ASSERT(!result->IsNull()); |
| 987 } | 988 } |
| 988 return result->raw(); | 989 return result->raw(); |
| 989 } | 990 } |
| 990 ASSERT((class_header & kSmiTagMask) != kSmiTag); | 991 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 991 intptr_t class_id = LookupInternalClass(class_header); | 992 intptr_t class_id = LookupInternalClass(class_header); |
| 992 switch (class_id) { | 993 switch (class_id) { |
| 993 #define SNAPSHOT_READ(clazz) \ | 994 #define SNAPSHOT_READ(clazz) \ |
| 994 case clazz::kClassId: { \ | 995 case clazz::kClassId: { \ |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 void SnapshotReader::ArrayReadFrom(const Array& result, | 1028 void SnapshotReader::ArrayReadFrom(const Array& result, |
| 1028 intptr_t len, | 1029 intptr_t len, |
| 1029 intptr_t tags) { | 1030 intptr_t tags) { |
| 1030 // Set the object tags. | 1031 // Set the object tags. |
| 1031 result.set_tags(tags); | 1032 result.set_tags(tags); |
| 1032 | 1033 |
| 1033 // Setup the object fields. | 1034 // Setup the object fields. |
| 1034 *TypeArgumentsHandle() ^= ReadObjectImpl(); | 1035 *TypeArgumentsHandle() ^= ReadObjectImpl(); |
| 1035 result.SetTypeArguments(*TypeArgumentsHandle()); | 1036 result.SetTypeArguments(*TypeArgumentsHandle()); |
| 1036 | 1037 |
| 1038 bool is_canonical = RawObject::IsCanonical(tags); |
| 1039 |
| 1037 for (intptr_t i = 0; i < len; i++) { | 1040 for (intptr_t i = 0; i < len; i++) { |
| 1038 *PassiveObjectHandle() = ReadObjectRef(); | 1041 *PassiveObjectHandle() = is_canonical ? ReadObjectImpl() : ReadObjectRef(); |
| 1039 result.SetAt(i, *PassiveObjectHandle()); | 1042 result.SetAt(i, *PassiveObjectHandle()); |
| 1040 } | 1043 } |
| 1041 } | 1044 } |
| 1042 | 1045 |
| 1043 | 1046 |
| 1044 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, | 1047 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, |
| 1045 uint8_t** buffer, | 1048 uint8_t** buffer, |
| 1046 ReAlloc alloc, | 1049 ReAlloc alloc, |
| 1047 intptr_t initial_size) | 1050 intptr_t initial_size) |
| 1048 : BaseWriter(buffer, alloc, initial_size), | 1051 : BaseWriter(buffer, alloc, initial_size), |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1586 WriteIndexedObject(array_kind); | 1589 WriteIndexedObject(array_kind); |
| 1587 WriteTags(tags); | 1590 WriteTags(tags); |
| 1588 | 1591 |
| 1589 // Write out the length field. | 1592 // Write out the length field. |
| 1590 Write<RawObject*>(length); | 1593 Write<RawObject*>(length); |
| 1591 | 1594 |
| 1592 // Write out the type arguments. | 1595 // Write out the type arguments. |
| 1593 WriteObjectImpl(type_arguments); | 1596 WriteObjectImpl(type_arguments); |
| 1594 | 1597 |
| 1595 // Write out the individual object ids. | 1598 // Write out the individual object ids. |
| 1599 bool is_canonical = RawObject::IsCanonical(tags); |
| 1596 for (intptr_t i = 0; i < len; i++) { | 1600 for (intptr_t i = 0; i < len; i++) { |
| 1597 WriteObjectRef(data[i]); | 1601 if (is_canonical) { |
| 1602 WriteObjectImpl(data[i]); |
| 1603 } else { |
| 1604 WriteObjectRef(data[i]); |
| 1605 } |
| 1598 } | 1606 } |
| 1599 } | 1607 } |
| 1600 | 1608 |
| 1601 | 1609 |
| 1602 void SnapshotWriter::CheckIfSerializable(RawClass* cls) { | 1610 void SnapshotWriter::CheckIfSerializable(RawClass* cls) { |
| 1603 if (Class::IsSignatureClass(cls)) { | 1611 if (Class::IsSignatureClass(cls)) { |
| 1604 // We do not allow closure objects in an isolate message. | 1612 // We do not allow closure objects in an isolate message. |
| 1605 SetWriteException(Exceptions::kArgument, | 1613 SetWriteException(Exceptions::kArgument, |
| 1606 "Illegal argument in isolate message" | 1614 "Illegal argument in isolate message" |
| 1607 " : (object is a closure)"); | 1615 " : (object is a closure)"); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1645 | 1653 |
| 1646 // Write out the tags. | 1654 // Write out the tags. |
| 1647 WriteTags(tags); | 1655 WriteTags(tags); |
| 1648 | 1656 |
| 1649 // Write out the class information for this object. | 1657 // Write out the class information for this object. |
| 1650 WriteObjectImpl(cls); | 1658 WriteObjectImpl(cls); |
| 1651 | 1659 |
| 1652 // Write out all the fields for the object. | 1660 // Write out all the fields for the object. |
| 1653 // Instance::NextFieldOffset() returns the offset of the first field in | 1661 // Instance::NextFieldOffset() returns the offset of the first field in |
| 1654 // a Dart object. | 1662 // a Dart object. |
| 1663 bool is_canonical = RawObject::IsCanonical(tags); |
| 1655 intptr_t offset = Instance::NextFieldOffset(); | 1664 intptr_t offset = Instance::NextFieldOffset(); |
| 1656 while (offset < next_field_offset) { | 1665 while (offset < next_field_offset) { |
| 1657 WriteObjectRef(*reinterpret_cast<RawObject**>( | 1666 RawObject* raw_obj = *reinterpret_cast<RawObject**>( |
| 1658 reinterpret_cast<uword>(raw->ptr()) + offset)); | 1667 reinterpret_cast<uword>(raw->ptr()) + offset); |
| 1668 if (is_canonical) { |
| 1669 WriteObjectImpl(raw_obj); |
| 1670 } else { |
| 1671 WriteObjectRef(raw_obj); |
| 1672 } |
| 1659 offset += kWordSize; | 1673 offset += kWordSize; |
| 1660 } | 1674 } |
| 1661 return; | 1675 return; |
| 1662 } | 1676 } |
| 1663 | 1677 |
| 1664 | 1678 |
| 1665 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { | 1679 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { |
| 1666 // First check if object is a closure or has native fields. | 1680 // First check if object is a closure or has native fields. |
| 1667 CheckIfSerializable(cls); | 1681 CheckIfSerializable(cls); |
| 1668 | 1682 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1761 NoGCScope no_gc; | 1775 NoGCScope no_gc; |
| 1762 WriteObject(obj.raw()); | 1776 WriteObject(obj.raw()); |
| 1763 UnmarkAll(); | 1777 UnmarkAll(); |
| 1764 } else { | 1778 } else { |
| 1765 ThrowException(exception_type(), exception_msg()); | 1779 ThrowException(exception_type(), exception_msg()); |
| 1766 } | 1780 } |
| 1767 } | 1781 } |
| 1768 | 1782 |
| 1769 | 1783 |
| 1770 } // namespace dart | 1784 } // namespace dart |
| OLD | NEW |