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