| 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 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 const Object& obj = *objects_[i].obj_; | 745 const Object& obj = *objects_[i].obj_; |
| 746 | 746 |
| 747 NoSafepointScope no_safepoint; | 747 NoSafepointScope no_safepoint; |
| 748 uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag; | 748 uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag; |
| 749 uword end = start + obj.raw()->Size(); | 749 uword end = start + obj.raw()->Size(); |
| 750 | 750 |
| 751 // Write object header with the mark and VM heap bits set. | 751 // Write object header with the mark and VM heap bits set. |
| 752 uword marked_tags = obj.raw()->ptr()->tags_; | 752 uword marked_tags = obj.raw()->ptr()->tags_; |
| 753 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | 753 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
| 754 marked_tags = RawObject::MarkBit::update(true, marked_tags); | 754 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
| 755 #if defined(HASH_IN_OBJECT_HEADER) |
| 756 marked_tags |= static_cast<uword>(obj.raw()->ptr()->hash_) << 32; |
| 757 #endif |
| 755 stream->WriteWord(marked_tags); | 758 stream->WriteWord(marked_tags); |
| 756 start += sizeof(uword); | 759 start += sizeof(uword); |
| 757 for (uword* cursor = reinterpret_cast<uword*>(start); | 760 for (uword* cursor = reinterpret_cast<uword*>(start); |
| 758 cursor < reinterpret_cast<uword*>(end); cursor++) { | 761 cursor < reinterpret_cast<uword*>(end); cursor++) { |
| 759 stream->WriteWord(*cursor); | 762 stream->WriteWord(*cursor); |
| 760 } | 763 } |
| 761 } | 764 } |
| 762 } | 765 } |
| 763 | 766 |
| 764 | 767 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 { | 834 { |
| 832 NoSafepointScope no_safepoint; | 835 NoSafepointScope no_safepoint; |
| 833 | 836 |
| 834 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); | 837 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); |
| 835 uword entry = beginning + Instructions::HeaderSize(); | 838 uword entry = beginning + Instructions::HeaderSize(); |
| 836 | 839 |
| 837 // Write Instructions with the mark and VM heap bits set. | 840 // Write Instructions with the mark and VM heap bits set. |
| 838 uword marked_tags = insns.raw_ptr()->tags_; | 841 uword marked_tags = insns.raw_ptr()->tags_; |
| 839 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | 842 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
| 840 marked_tags = RawObject::MarkBit::update(true, marked_tags); | 843 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
| 844 #if defined(HASH_IN_OBJECT_HEADER) |
| 845 // Can't use GetObjectTagsAndHash because the update methods discard the |
| 846 // high bits. |
| 847 marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32; |
| 848 #endif |
| 841 | 849 |
| 842 WriteWordLiteralText(marked_tags); | 850 WriteWordLiteralText(marked_tags); |
| 843 beginning += sizeof(uword); | 851 beginning += sizeof(uword); |
| 844 | 852 |
| 845 WriteByteSequence(beginning, entry); | 853 WriteByteSequence(beginning, entry); |
| 846 } | 854 } |
| 847 | 855 |
| 848 // 2. Write a label at the entry point. | 856 // 2. Write a label at the entry point. |
| 849 // Linux's perf uses these labels. | 857 // Linux's perf uses these labels. |
| 850 owner = code.owner(); | 858 owner = code.owner(); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment()); | 1044 payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment()); |
| 1037 uword end = entry + payload_size; | 1045 uword end = entry + payload_size; |
| 1038 | 1046 |
| 1039 ASSERT(Utils::IsAligned(beginning, sizeof(uword))); | 1047 ASSERT(Utils::IsAligned(beginning, sizeof(uword))); |
| 1040 ASSERT(Utils::IsAligned(entry, sizeof(uword))); | 1048 ASSERT(Utils::IsAligned(entry, sizeof(uword))); |
| 1041 | 1049 |
| 1042 // Write Instructions with the mark and VM heap bits set. | 1050 // Write Instructions with the mark and VM heap bits set. |
| 1043 uword marked_tags = insns.raw_ptr()->tags_; | 1051 uword marked_tags = insns.raw_ptr()->tags_; |
| 1044 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | 1052 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
| 1045 marked_tags = RawObject::MarkBit::update(true, marked_tags); | 1053 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
| 1054 #if defined(HASH_IN_OBJECT_HEADER) |
| 1055 // Can't use GetObjectTagsAndHash because the update methods discard the |
| 1056 // high bits. |
| 1057 marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32; |
| 1058 #endif |
| 1046 | 1059 |
| 1047 instructions_blob_stream_.WriteWord(marked_tags); | 1060 instructions_blob_stream_.WriteWord(marked_tags); |
| 1048 beginning += sizeof(uword); | 1061 beginning += sizeof(uword); |
| 1049 | 1062 |
| 1050 for (uword* cursor = reinterpret_cast<uword*>(beginning); | 1063 for (uword* cursor = reinterpret_cast<uword*>(beginning); |
| 1051 cursor < reinterpret_cast<uword*>(end); cursor++) { | 1064 cursor < reinterpret_cast<uword*>(end); cursor++) { |
| 1052 instructions_blob_stream_.WriteWord(*cursor); | 1065 instructions_blob_stream_.WriteWord(*cursor); |
| 1053 } | 1066 } |
| 1054 } | 1067 } |
| 1055 } | 1068 } |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1309 ASSERT(forward_list_ != NULL); | 1322 ASSERT(forward_list_ != NULL); |
| 1310 } | 1323 } |
| 1311 | 1324 |
| 1312 | 1325 |
| 1313 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 1326 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
| 1314 WriteObjectImpl(rawobj, kAsInlinedObject); | 1327 WriteObjectImpl(rawobj, kAsInlinedObject); |
| 1315 WriteForwardedObjects(); | 1328 WriteForwardedObjects(); |
| 1316 } | 1329 } |
| 1317 | 1330 |
| 1318 | 1331 |
| 1319 uword SnapshotWriter::GetObjectTags(RawObject* raw) { | 1332 uint32_t SnapshotWriter::GetObjectTags(RawObject* raw) { |
| 1320 return raw->ptr()->tags_; | 1333 return raw->ptr()->tags_; |
| 1321 } | 1334 } |
| 1322 | 1335 |
| 1323 | 1336 |
| 1337 uword SnapshotWriter::GetObjectTagsAndHash(RawObject* raw) { |
| 1338 uword result = raw->ptr()->tags_; |
| 1339 #if defined(HASH_IN_OBJECT_HEADER) |
| 1340 result |= static_cast<uword>(raw->ptr()->hash_) << 32; |
| 1341 #endif |
| 1342 return result; |
| 1343 } |
| 1344 |
| 1345 |
| 1324 #define VM_OBJECT_CLASS_LIST(V) \ | 1346 #define VM_OBJECT_CLASS_LIST(V) \ |
| 1325 V(OneByteString) \ | 1347 V(OneByteString) \ |
| 1326 V(TwoByteString) \ | 1348 V(TwoByteString) \ |
| 1327 V(Mint) \ | 1349 V(Mint) \ |
| 1328 V(Bigint) \ | 1350 V(Bigint) \ |
| 1329 V(Double) \ | 1351 V(Double) \ |
| 1330 V(ImmutableArray) | 1352 V(ImmutableArray) |
| 1331 | 1353 |
| 1332 #define VM_OBJECT_WRITE(clazz) \ | 1354 #define VM_OBJECT_WRITE(clazz) \ |
| 1333 case clazz::kClassId: { \ | 1355 case clazz::kClassId: { \ |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1537 | 1559 |
| 1538 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { | 1560 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { |
| 1539 // First check if object can be written as a simple predefined type. | 1561 // First check if object can be written as a simple predefined type. |
| 1540 if (CheckAndWritePredefinedObject(raw)) { | 1562 if (CheckAndWritePredefinedObject(raw)) { |
| 1541 return; | 1563 return; |
| 1542 } | 1564 } |
| 1543 | 1565 |
| 1544 // When we know that we are dealing with leaf or shallow objects we write | 1566 // When we know that we are dealing with leaf or shallow objects we write |
| 1545 // these objects inline even when 'as_reference' is true. | 1567 // these objects inline even when 'as_reference' is true. |
| 1546 const bool write_as_reference = as_reference && !raw->IsCanonical(); | 1568 const bool write_as_reference = as_reference && !raw->IsCanonical(); |
| 1547 intptr_t tags = raw->ptr()->tags_; | 1569 uintptr_t tags = GetObjectTagsAndHash(raw); |
| 1548 | 1570 |
| 1549 // Add object to the forward ref list and mark it so that future references | 1571 // Add object to the forward ref list and mark it so that future references |
| 1550 // to this object in the snapshot will use this object id. Mark the | 1572 // to this object in the snapshot will use this object id. Mark the |
| 1551 // serialization state so that we do the right thing when we go through | 1573 // serialization state so that we do the right thing when we go through |
| 1552 // the forward list. | 1574 // the forward list. |
| 1553 intptr_t class_id = raw->GetClassId(); | 1575 intptr_t class_id = raw->GetClassId(); |
| 1554 intptr_t object_id; | 1576 intptr_t object_id; |
| 1555 if (write_as_reference && IsSplitClassId(class_id)) { | 1577 if (write_as_reference && IsSplitClassId(class_id)) { |
| 1556 object_id = forward_list_->AddObject(zone(), raw, kIsNotSerialized); | 1578 object_id = forward_list_->AddObject(zone(), raw, kIsNotSerialized); |
| 1557 } else { | 1579 } else { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1614 | 1636 |
| 1615 | 1637 |
| 1616 class WriteInlinedObjectVisitor : public ObjectVisitor { | 1638 class WriteInlinedObjectVisitor : public ObjectVisitor { |
| 1617 public: | 1639 public: |
| 1618 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) | 1640 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) |
| 1619 : writer_(writer) {} | 1641 : writer_(writer) {} |
| 1620 | 1642 |
| 1621 virtual void VisitObject(RawObject* obj) { | 1643 virtual void VisitObject(RawObject* obj) { |
| 1622 intptr_t object_id = writer_->forward_list_->FindObject(obj); | 1644 intptr_t object_id = writer_->forward_list_->FindObject(obj); |
| 1623 ASSERT(object_id != kInvalidIndex); | 1645 ASSERT(object_id != kInvalidIndex); |
| 1624 intptr_t tags = writer_->GetObjectTags(obj); | 1646 intptr_t tags = MessageWriter::GetObjectTagsAndHash(obj); |
| 1625 writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject); | 1647 writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject); |
| 1626 } | 1648 } |
| 1627 | 1649 |
| 1628 private: | 1650 private: |
| 1629 SnapshotWriter* writer_; | 1651 SnapshotWriter* writer_; |
| 1630 }; | 1652 }; |
| 1631 | 1653 |
| 1632 | 1654 |
| 1633 void SnapshotWriter::WriteForwardedObjects() { | 1655 void SnapshotWriter::WriteForwardedObjects() { |
| 1634 WriteInlinedObjectVisitor visitor(this); | 1656 WriteInlinedObjectVisitor visitor(this); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1779 thread()->zone(), | 1801 thread()->zone(), |
| 1780 "Illegal argument in isolate message : (object is a closure - %s)", | 1802 "Illegal argument in isolate message : (object is a closure - %s)", |
| 1781 errorFunc.ToCString()); | 1803 errorFunc.ToCString()); |
| 1782 SetWriteException(Exceptions::kArgument, chars); | 1804 SetWriteException(Exceptions::kArgument, chars); |
| 1783 return Function::null(); | 1805 return Function::null(); |
| 1784 } | 1806 } |
| 1785 | 1807 |
| 1786 | 1808 |
| 1787 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { | 1809 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { |
| 1788 RawObject* owner = func->ptr()->owner_; | 1810 RawObject* owner = func->ptr()->owner_; |
| 1789 uword tags = GetObjectTags(owner); | 1811 uint32_t tags = GetObjectTags(owner); |
| 1790 intptr_t class_id = RawObject::ClassIdTag::decode(tags); | 1812 intptr_t class_id = RawObject::ClassIdTag::decode(tags); |
| 1791 if (class_id == kClassCid) { | 1813 if (class_id == kClassCid) { |
| 1792 return reinterpret_cast<RawClass*>(owner); | 1814 return reinterpret_cast<RawClass*>(owner); |
| 1793 } | 1815 } |
| 1794 ASSERT(class_id == kPatchClassCid); | 1816 ASSERT(class_id == kPatchClassCid); |
| 1795 return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_; | 1817 return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_; |
| 1796 } | 1818 } |
| 1797 | 1819 |
| 1798 | 1820 |
| 1799 void SnapshotWriter::CheckForNativeFields(RawClass* cls) { | 1821 void SnapshotWriter::CheckForNativeFields(RawClass* cls) { |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2010 *buffer_len_ = BytesWritten(); | 2032 *buffer_len_ = BytesWritten(); |
| 2011 } | 2033 } |
| 2012 } else { | 2034 } else { |
| 2013 FreeBuffer(); | 2035 FreeBuffer(); |
| 2014 ThrowException(exception_type(), exception_msg()); | 2036 ThrowException(exception_type(), exception_msg()); |
| 2015 } | 2037 } |
| 2016 } | 2038 } |
| 2017 | 2039 |
| 2018 | 2040 |
| 2019 } // namespace dart | 2041 } // namespace dart |
| OLD | NEW |