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 |
758 stream->WriteWord(marked_tags); | 761 stream->WriteWord(marked_tags); |
759 start += sizeof(uword); | 762 start += sizeof(uword); |
760 for (uword* cursor = reinterpret_cast<uword*>(start); | 763 for (uword* cursor = reinterpret_cast<uword*>(start); |
761 cursor < reinterpret_cast<uword*>(end); cursor++) { | 764 cursor < reinterpret_cast<uword*>(end); cursor++) { |
762 stream->WriteWord(*cursor); | 765 stream->WriteWord(*cursor); |
763 } | 766 } |
764 } | 767 } |
765 } | 768 } |
766 | 769 |
767 | 770 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 { | 837 { |
835 NoSafepointScope no_safepoint; | 838 NoSafepointScope no_safepoint; |
836 | 839 |
837 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); | 840 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); |
838 uword entry = beginning + Instructions::HeaderSize(); | 841 uword entry = beginning + Instructions::HeaderSize(); |
839 | 842 |
840 // Write Instructions with the mark and VM heap bits set. | 843 // Write Instructions with the mark and VM heap bits set. |
841 uword marked_tags = insns.raw_ptr()->tags_; | 844 uword marked_tags = insns.raw_ptr()->tags_; |
842 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | 845 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
843 marked_tags = RawObject::MarkBit::update(true, marked_tags); | 846 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 |
844 | 852 |
845 WriteWordLiteralText(marked_tags); | 853 WriteWordLiteralText(marked_tags); |
846 beginning += sizeof(uword); | 854 beginning += sizeof(uword); |
847 | 855 |
848 WriteByteSequence(beginning, entry); | 856 WriteByteSequence(beginning, entry); |
849 } | 857 } |
850 | 858 |
851 // 2. Write a label at the entry point. | 859 // 2. Write a label at the entry point. |
852 // Linux's perf uses these labels. | 860 // Linux's perf uses these labels. |
853 owner = code.owner(); | 861 owner = code.owner(); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment()); | 1047 payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment()); |
1040 uword end = entry + payload_size; | 1048 uword end = entry + payload_size; |
1041 | 1049 |
1042 ASSERT(Utils::IsAligned(beginning, sizeof(uword))); | 1050 ASSERT(Utils::IsAligned(beginning, sizeof(uword))); |
1043 ASSERT(Utils::IsAligned(entry, sizeof(uword))); | 1051 ASSERT(Utils::IsAligned(entry, sizeof(uword))); |
1044 | 1052 |
1045 // Write Instructions with the mark and VM heap bits set. | 1053 // Write Instructions with the mark and VM heap bits set. |
1046 uword marked_tags = insns.raw_ptr()->tags_; | 1054 uword marked_tags = insns.raw_ptr()->tags_; |
1047 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | 1055 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
1048 marked_tags = RawObject::MarkBit::update(true, marked_tags); | 1056 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
| 1057 #if defined(HASH_IN_OBJECT_HEADER) |
| 1058 // Can't use GetObjectTagsAndHash because the update methods discard the |
| 1059 // high bits. |
| 1060 marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32; |
| 1061 #endif |
1049 | 1062 |
1050 instructions_blob_stream_.WriteWord(marked_tags); | 1063 instructions_blob_stream_.WriteWord(marked_tags); |
1051 beginning += sizeof(uword); | 1064 beginning += sizeof(uword); |
1052 | 1065 |
1053 for (uword* cursor = reinterpret_cast<uword*>(beginning); | 1066 for (uword* cursor = reinterpret_cast<uword*>(beginning); |
1054 cursor < reinterpret_cast<uword*>(end); cursor++) { | 1067 cursor < reinterpret_cast<uword*>(end); cursor++) { |
1055 instructions_blob_stream_.WriteWord(*cursor); | 1068 instructions_blob_stream_.WriteWord(*cursor); |
1056 } | 1069 } |
1057 } | 1070 } |
1058 } | 1071 } |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1343 ASSERT(forward_list_ != NULL); | 1356 ASSERT(forward_list_ != NULL); |
1344 } | 1357 } |
1345 | 1358 |
1346 | 1359 |
1347 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 1360 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
1348 WriteObjectImpl(rawobj, kAsInlinedObject); | 1361 WriteObjectImpl(rawobj, kAsInlinedObject); |
1349 WriteForwardedObjects(); | 1362 WriteForwardedObjects(); |
1350 } | 1363 } |
1351 | 1364 |
1352 | 1365 |
1353 uword SnapshotWriter::GetObjectTags(RawObject* raw) { | 1366 uint32_t SnapshotWriter::GetObjectTags(RawObject* raw) { |
1354 return raw->ptr()->tags_; | 1367 return raw->ptr()->tags_; |
1355 } | 1368 } |
1356 | 1369 |
1357 | 1370 |
| 1371 uword SnapshotWriter::GetObjectTagsAndHash(RawObject* raw) { |
| 1372 uword result = raw->ptr()->tags_; |
| 1373 #if defined(HASH_IN_OBJECT_HEADER) |
| 1374 result |= static_cast<uword>(raw->ptr()->hash_) << 32; |
| 1375 #endif |
| 1376 return result; |
| 1377 } |
| 1378 |
| 1379 |
1358 #define VM_OBJECT_CLASS_LIST(V) \ | 1380 #define VM_OBJECT_CLASS_LIST(V) \ |
1359 V(OneByteString) \ | 1381 V(OneByteString) \ |
1360 V(TwoByteString) \ | 1382 V(TwoByteString) \ |
1361 V(Mint) \ | 1383 V(Mint) \ |
1362 V(Bigint) \ | 1384 V(Bigint) \ |
1363 V(Double) \ | 1385 V(Double) \ |
1364 V(ImmutableArray) | 1386 V(ImmutableArray) |
1365 | 1387 |
1366 #define VM_OBJECT_WRITE(clazz) \ | 1388 #define VM_OBJECT_WRITE(clazz) \ |
1367 case clazz::kClassId: { \ | 1389 case clazz::kClassId: { \ |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 | 1593 |
1572 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { | 1594 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { |
1573 // First check if object can be written as a simple predefined type. | 1595 // First check if object can be written as a simple predefined type. |
1574 if (CheckAndWritePredefinedObject(raw)) { | 1596 if (CheckAndWritePredefinedObject(raw)) { |
1575 return; | 1597 return; |
1576 } | 1598 } |
1577 | 1599 |
1578 // When we know that we are dealing with leaf or shallow objects we write | 1600 // When we know that we are dealing with leaf or shallow objects we write |
1579 // these objects inline even when 'as_reference' is true. | 1601 // these objects inline even when 'as_reference' is true. |
1580 const bool write_as_reference = as_reference && !raw->IsCanonical(); | 1602 const bool write_as_reference = as_reference && !raw->IsCanonical(); |
1581 intptr_t tags = raw->ptr()->tags_; | 1603 uintptr_t tags = GetObjectTagsAndHash(raw); |
1582 | 1604 |
1583 // Add object to the forward ref list and mark it so that future references | 1605 // Add object to the forward ref list and mark it so that future references |
1584 // to this object in the snapshot will use this object id. Mark the | 1606 // to this object in the snapshot will use this object id. Mark the |
1585 // serialization state so that we do the right thing when we go through | 1607 // serialization state so that we do the right thing when we go through |
1586 // the forward list. | 1608 // the forward list. |
1587 intptr_t class_id = raw->GetClassId(); | 1609 intptr_t class_id = raw->GetClassId(); |
1588 intptr_t object_id; | 1610 intptr_t object_id; |
1589 if (write_as_reference && IsSplitClassId(class_id)) { | 1611 if (write_as_reference && IsSplitClassId(class_id)) { |
1590 object_id = forward_list_->AddObject(zone(), raw, kIsNotSerialized); | 1612 object_id = forward_list_->AddObject(zone(), raw, kIsNotSerialized); |
1591 } else { | 1613 } else { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1648 | 1670 |
1649 | 1671 |
1650 class WriteInlinedObjectVisitor : public ObjectVisitor { | 1672 class WriteInlinedObjectVisitor : public ObjectVisitor { |
1651 public: | 1673 public: |
1652 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) | 1674 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) |
1653 : writer_(writer) {} | 1675 : writer_(writer) {} |
1654 | 1676 |
1655 virtual void VisitObject(RawObject* obj) { | 1677 virtual void VisitObject(RawObject* obj) { |
1656 intptr_t object_id = writer_->forward_list_->FindObject(obj); | 1678 intptr_t object_id = writer_->forward_list_->FindObject(obj); |
1657 ASSERT(object_id != kInvalidIndex); | 1679 ASSERT(object_id != kInvalidIndex); |
1658 intptr_t tags = writer_->GetObjectTags(obj); | 1680 intptr_t tags = MessageWriter::GetObjectTagsAndHash(obj); |
1659 writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject); | 1681 writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject); |
1660 } | 1682 } |
1661 | 1683 |
1662 private: | 1684 private: |
1663 SnapshotWriter* writer_; | 1685 SnapshotWriter* writer_; |
1664 }; | 1686 }; |
1665 | 1687 |
1666 | 1688 |
1667 void SnapshotWriter::WriteForwardedObjects() { | 1689 void SnapshotWriter::WriteForwardedObjects() { |
1668 WriteInlinedObjectVisitor visitor(this); | 1690 WriteInlinedObjectVisitor visitor(this); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1813 thread()->zone(), | 1835 thread()->zone(), |
1814 "Illegal argument in isolate message : (object is a closure - %s)", | 1836 "Illegal argument in isolate message : (object is a closure - %s)", |
1815 errorFunc.ToCString()); | 1837 errorFunc.ToCString()); |
1816 SetWriteException(Exceptions::kArgument, chars); | 1838 SetWriteException(Exceptions::kArgument, chars); |
1817 return Function::null(); | 1839 return Function::null(); |
1818 } | 1840 } |
1819 | 1841 |
1820 | 1842 |
1821 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { | 1843 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { |
1822 RawObject* owner = func->ptr()->owner_; | 1844 RawObject* owner = func->ptr()->owner_; |
1823 uword tags = GetObjectTags(owner); | 1845 uint32_t tags = GetObjectTags(owner); |
1824 intptr_t class_id = RawObject::ClassIdTag::decode(tags); | 1846 intptr_t class_id = RawObject::ClassIdTag::decode(tags); |
1825 if (class_id == kClassCid) { | 1847 if (class_id == kClassCid) { |
1826 return reinterpret_cast<RawClass*>(owner); | 1848 return reinterpret_cast<RawClass*>(owner); |
1827 } | 1849 } |
1828 ASSERT(class_id == kPatchClassCid); | 1850 ASSERT(class_id == kPatchClassCid); |
1829 return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_; | 1851 return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_; |
1830 } | 1852 } |
1831 | 1853 |
1832 | 1854 |
1833 void SnapshotWriter::CheckForNativeFields(RawClass* cls) { | 1855 void SnapshotWriter::CheckForNativeFields(RawClass* cls) { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2044 *buffer_len_ = BytesWritten(); | 2066 *buffer_len_ = BytesWritten(); |
2045 } | 2067 } |
2046 } else { | 2068 } else { |
2047 FreeBuffer(); | 2069 FreeBuffer(); |
2048 ThrowException(exception_type(), exception_msg()); | 2070 ThrowException(exception_type(), exception_msg()); |
2049 } | 2071 } |
2050 } | 2072 } |
2051 | 2073 |
2052 | 2074 |
2053 } // namespace dart | 2075 } // namespace dart |
OLD | NEW |