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/dart.h" | 10 #include "vm/dart.h" |
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 const Object& obj = *objects_[i].obj_; | 748 const Object& obj = *objects_[i].obj_; |
749 | 749 |
750 NoSafepointScope no_safepoint; | 750 NoSafepointScope no_safepoint; |
751 uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag; | 751 uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag; |
752 uword end = start + obj.raw()->Size(); | 752 uword end = start + obj.raw()->Size(); |
753 | 753 |
754 // Write object header with the mark and VM heap bits set. | 754 // Write object header with the mark and VM heap bits set. |
755 uword marked_tags = obj.raw()->ptr()->tags_; | 755 uword marked_tags = obj.raw()->ptr()->tags_; |
756 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | 756 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
757 marked_tags = RawObject::MarkBit::update(true, marked_tags); | 757 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
758 #if defined(HASH_IN_OBJECT_HEADER) | |
759 marked_tags |= static_cast<uword>(obj.raw()->ptr()->hash_) << 32; | |
760 #endif | |
761 stream->WriteWord(marked_tags); | 758 stream->WriteWord(marked_tags); |
762 start += sizeof(uword); | 759 start += sizeof(uword); |
763 for (uword* cursor = reinterpret_cast<uword*>(start); | 760 for (uword* cursor = reinterpret_cast<uword*>(start); |
764 cursor < reinterpret_cast<uword*>(end); cursor++) { | 761 cursor < reinterpret_cast<uword*>(end); cursor++) { |
765 stream->WriteWord(*cursor); | 762 stream->WriteWord(*cursor); |
766 } | 763 } |
767 } | 764 } |
768 } | 765 } |
769 | 766 |
770 | 767 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 { | 834 { |
838 NoSafepointScope no_safepoint; | 835 NoSafepointScope no_safepoint; |
839 | 836 |
840 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); | 837 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); |
841 uword entry = beginning + Instructions::HeaderSize(); | 838 uword entry = beginning + Instructions::HeaderSize(); |
842 | 839 |
843 // Write Instructions with the mark and VM heap bits set. | 840 // Write Instructions with the mark and VM heap bits set. |
844 uword marked_tags = insns.raw_ptr()->tags_; | 841 uword marked_tags = insns.raw_ptr()->tags_; |
845 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | 842 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
846 marked_tags = RawObject::MarkBit::update(true, marked_tags); | 843 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
847 #if defined(HASH_IN_OBJECT_HEADER) | |
848 // Can't use GetObjectTagsAndHash because the update methods discard the | |
849 // high bits. | |
850 marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32; | |
851 #endif | |
852 | 844 |
853 WriteWordLiteralText(marked_tags); | 845 WriteWordLiteralText(marked_tags); |
854 beginning += sizeof(uword); | 846 beginning += sizeof(uword); |
855 | 847 |
856 WriteByteSequence(beginning, entry); | 848 WriteByteSequence(beginning, entry); |
857 } | 849 } |
858 | 850 |
859 // 2. Write a label at the entry point. | 851 // 2. Write a label at the entry point. |
860 // Linux's perf uses these labels. | 852 // Linux's perf uses these labels. |
861 owner = code.owner(); | 853 owner = code.owner(); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment()); | 1024 payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment()); |
1033 uword end = entry + payload_size; | 1025 uword end = entry + payload_size; |
1034 | 1026 |
1035 ASSERT(Utils::IsAligned(beginning, sizeof(uword))); | 1027 ASSERT(Utils::IsAligned(beginning, sizeof(uword))); |
1036 ASSERT(Utils::IsAligned(entry, sizeof(uword))); | 1028 ASSERT(Utils::IsAligned(entry, sizeof(uword))); |
1037 | 1029 |
1038 // Write Instructions with the mark and VM heap bits set. | 1030 // Write Instructions with the mark and VM heap bits set. |
1039 uword marked_tags = insns.raw_ptr()->tags_; | 1031 uword marked_tags = insns.raw_ptr()->tags_; |
1040 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | 1032 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
1041 marked_tags = RawObject::MarkBit::update(true, marked_tags); | 1033 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
1042 #if defined(HASH_IN_OBJECT_HEADER) | |
1043 // Can't use GetObjectTagsAndHash because the update methods discard the | |
1044 // high bits. | |
1045 marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32; | |
1046 #endif | |
1047 | 1034 |
1048 instructions_blob_stream_.WriteWord(marked_tags); | 1035 instructions_blob_stream_.WriteWord(marked_tags); |
1049 beginning += sizeof(uword); | 1036 beginning += sizeof(uword); |
1050 | 1037 |
1051 for (uword* cursor = reinterpret_cast<uword*>(beginning); | 1038 for (uword* cursor = reinterpret_cast<uword*>(beginning); |
1052 cursor < reinterpret_cast<uword*>(end); cursor++) { | 1039 cursor < reinterpret_cast<uword*>(end); cursor++) { |
1053 instructions_blob_stream_.WriteWord(*cursor); | 1040 instructions_blob_stream_.WriteWord(*cursor); |
1054 } | 1041 } |
1055 } | 1042 } |
1056 } | 1043 } |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1341 ASSERT(forward_list_ != NULL); | 1328 ASSERT(forward_list_ != NULL); |
1342 } | 1329 } |
1343 | 1330 |
1344 | 1331 |
1345 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 1332 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
1346 WriteObjectImpl(rawobj, kAsInlinedObject); | 1333 WriteObjectImpl(rawobj, kAsInlinedObject); |
1347 WriteForwardedObjects(); | 1334 WriteForwardedObjects(); |
1348 } | 1335 } |
1349 | 1336 |
1350 | 1337 |
1351 uint32_t SnapshotWriter::GetObjectTags(RawObject* raw) { | 1338 uword SnapshotWriter::GetObjectTags(RawObject* raw) { |
1352 return raw->ptr()->tags_; | 1339 return raw->ptr()->tags_; |
1353 } | 1340 } |
1354 | 1341 |
1355 | 1342 |
1356 uword SnapshotWriter::GetObjectTagsAndHash(RawObject* raw) { | |
1357 uword result = raw->ptr()->tags_; | |
1358 #if defined(HASH_IN_OBJECT_HEADER) | |
1359 result |= static_cast<uword>(raw->ptr()->hash_) << 32; | |
1360 #endif | |
1361 return result; | |
1362 } | |
1363 | |
1364 | |
1365 #define VM_OBJECT_CLASS_LIST(V) \ | 1343 #define VM_OBJECT_CLASS_LIST(V) \ |
1366 V(OneByteString) \ | 1344 V(OneByteString) \ |
1367 V(TwoByteString) \ | 1345 V(TwoByteString) \ |
1368 V(Mint) \ | 1346 V(Mint) \ |
1369 V(Bigint) \ | 1347 V(Bigint) \ |
1370 V(Double) \ | 1348 V(Double) \ |
1371 V(ImmutableArray) | 1349 V(ImmutableArray) |
1372 | 1350 |
1373 #define VM_OBJECT_WRITE(clazz) \ | 1351 #define VM_OBJECT_WRITE(clazz) \ |
1374 case clazz::kClassId: { \ | 1352 case clazz::kClassId: { \ |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1578 | 1556 |
1579 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { | 1557 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { |
1580 // First check if object can be written as a simple predefined type. | 1558 // First check if object can be written as a simple predefined type. |
1581 if (CheckAndWritePredefinedObject(raw)) { | 1559 if (CheckAndWritePredefinedObject(raw)) { |
1582 return; | 1560 return; |
1583 } | 1561 } |
1584 | 1562 |
1585 // When we know that we are dealing with leaf or shallow objects we write | 1563 // When we know that we are dealing with leaf or shallow objects we write |
1586 // these objects inline even when 'as_reference' is true. | 1564 // these objects inline even when 'as_reference' is true. |
1587 const bool write_as_reference = as_reference && !raw->IsCanonical(); | 1565 const bool write_as_reference = as_reference && !raw->IsCanonical(); |
1588 uintptr_t tags = GetObjectTagsAndHash(raw); | 1566 intptr_t tags = raw->ptr()->tags_; |
1589 | 1567 |
1590 // Add object to the forward ref list and mark it so that future references | 1568 // Add object to the forward ref list and mark it so that future references |
1591 // to this object in the snapshot will use this object id. Mark the | 1569 // to this object in the snapshot will use this object id. Mark the |
1592 // serialization state so that we do the right thing when we go through | 1570 // serialization state so that we do the right thing when we go through |
1593 // the forward list. | 1571 // the forward list. |
1594 intptr_t class_id = raw->GetClassId(); | 1572 intptr_t class_id = raw->GetClassId(); |
1595 intptr_t object_id; | 1573 intptr_t object_id; |
1596 if (write_as_reference && IsSplitClassId(class_id)) { | 1574 if (write_as_reference && IsSplitClassId(class_id)) { |
1597 object_id = forward_list_->AddObject(zone(), raw, kIsNotSerialized); | 1575 object_id = forward_list_->AddObject(zone(), raw, kIsNotSerialized); |
1598 } else { | 1576 } else { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1655 | 1633 |
1656 | 1634 |
1657 class WriteInlinedObjectVisitor : public ObjectVisitor { | 1635 class WriteInlinedObjectVisitor : public ObjectVisitor { |
1658 public: | 1636 public: |
1659 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) | 1637 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) |
1660 : writer_(writer) {} | 1638 : writer_(writer) {} |
1661 | 1639 |
1662 virtual void VisitObject(RawObject* obj) { | 1640 virtual void VisitObject(RawObject* obj) { |
1663 intptr_t object_id = writer_->forward_list_->FindObject(obj); | 1641 intptr_t object_id = writer_->forward_list_->FindObject(obj); |
1664 ASSERT(object_id != kInvalidIndex); | 1642 ASSERT(object_id != kInvalidIndex); |
1665 intptr_t tags = MessageWriter::GetObjectTagsAndHash(obj); | 1643 intptr_t tags = writer_->GetObjectTags(obj); |
1666 writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject); | 1644 writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject); |
1667 } | 1645 } |
1668 | 1646 |
1669 private: | 1647 private: |
1670 SnapshotWriter* writer_; | 1648 SnapshotWriter* writer_; |
1671 }; | 1649 }; |
1672 | 1650 |
1673 | 1651 |
1674 void SnapshotWriter::WriteForwardedObjects() { | 1652 void SnapshotWriter::WriteForwardedObjects() { |
1675 WriteInlinedObjectVisitor visitor(this); | 1653 WriteInlinedObjectVisitor visitor(this); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1820 thread()->zone(), | 1798 thread()->zone(), |
1821 "Illegal argument in isolate message : (object is a closure - %s)", | 1799 "Illegal argument in isolate message : (object is a closure - %s)", |
1822 errorFunc.ToCString()); | 1800 errorFunc.ToCString()); |
1823 SetWriteException(Exceptions::kArgument, chars); | 1801 SetWriteException(Exceptions::kArgument, chars); |
1824 return Function::null(); | 1802 return Function::null(); |
1825 } | 1803 } |
1826 | 1804 |
1827 | 1805 |
1828 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { | 1806 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { |
1829 RawObject* owner = func->ptr()->owner_; | 1807 RawObject* owner = func->ptr()->owner_; |
1830 uint32_t tags = GetObjectTags(owner); | 1808 uword tags = GetObjectTags(owner); |
1831 intptr_t class_id = RawObject::ClassIdTag::decode(tags); | 1809 intptr_t class_id = RawObject::ClassIdTag::decode(tags); |
1832 if (class_id == kClassCid) { | 1810 if (class_id == kClassCid) { |
1833 return reinterpret_cast<RawClass*>(owner); | 1811 return reinterpret_cast<RawClass*>(owner); |
1834 } | 1812 } |
1835 ASSERT(class_id == kPatchClassCid); | 1813 ASSERT(class_id == kPatchClassCid); |
1836 return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_; | 1814 return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_; |
1837 } | 1815 } |
1838 | 1816 |
1839 | 1817 |
1840 void SnapshotWriter::CheckForNativeFields(RawClass* cls) { | 1818 void SnapshotWriter::CheckForNativeFields(RawClass* cls) { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2051 *buffer_len_ = BytesWritten(); | 2029 *buffer_len_ = BytesWritten(); |
2052 } | 2030 } |
2053 } else { | 2031 } else { |
2054 FreeBuffer(); | 2032 FreeBuffer(); |
2055 ThrowException(exception_type(), exception_msg()); | 2033 ThrowException(exception_type(), exception_msg()); |
2056 } | 2034 } |
2057 } | 2035 } |
2058 | 2036 |
2059 | 2037 |
2060 } // namespace dart | 2038 } // namespace dart |
OLD | NEW |