Chromium Code Reviews| 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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 701 | 701 |
| 702 int32_t InstructionsWriter::GetObjectOffsetFor(RawObject* raw_object) { | 702 int32_t InstructionsWriter::GetObjectOffsetFor(RawObject* raw_object) { |
| 703 intptr_t heap_size = raw_object->Size(); | 703 intptr_t heap_size = raw_object->Size(); |
| 704 intptr_t offset = next_object_offset_; | 704 intptr_t offset = next_object_offset_; |
| 705 next_object_offset_ += heap_size; | 705 next_object_offset_ += heap_size; |
| 706 objects_.Add(ObjectData(raw_object)); | 706 objects_.Add(ObjectData(raw_object)); |
| 707 return offset; | 707 return offset; |
| 708 } | 708 } |
| 709 | 709 |
| 710 | 710 |
| 711 void InstructionsWriter::HandlifyObjects() { | |
| 712 Zone* zone = Thread::Current()->zone(); | |
| 713 for (intptr_t i = 0; i < instructions_.length(); i++) { | |
| 714 InstructionsData& data = instructions_[i]; | |
| 715 data.insns_ = &Instructions::Handle(zone, data.raw_insns_); | |
| 716 ASSERT(data.raw_code_ != NULL); | |
| 717 data.code_ = &Code::Handle(zone, data.raw_code_); | |
| 718 } | |
| 719 for (intptr_t i = 0; i < objects_.length(); i++) { | |
| 720 ObjectData& data = objects_[i]; | |
| 721 data.obj_ = &Object::Handle(zone, data.raw_obj_); | |
| 722 } | |
| 723 } | |
| 724 | |
| 725 | |
| 726 void InstructionsWriter::WriteROData(WriteStream* stream) { | |
| 727 stream->Align(OS::kMaxPreferredCodeAlignment); | |
| 728 | |
| 729 // Heap page starts here. | |
| 730 | |
| 731 stream->WriteWord(next_object_offset_); // Data length. | |
| 732 COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment); | |
| 733 stream->Align(OS::kMaxPreferredCodeAlignment); | |
| 734 | |
| 735 // Heap page objects start here. | |
| 736 | |
| 737 for (intptr_t i = 0; i < objects_.length(); i++) { | |
| 738 const Object& obj = *objects_[i].obj_; | |
| 739 | |
| 740 NoSafepointScope no_safepoint; | |
| 741 uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag; | |
| 742 uword end = start + obj.raw()->Size(); | |
| 743 | |
| 744 // Write object header with the mark and VM heap bits set. | |
| 745 uword marked_tags = obj.raw()->ptr()->tags_; | |
| 746 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | |
| 747 marked_tags = RawObject::MarkBit::update(true, marked_tags); | |
| 748 stream->WriteWord(marked_tags); | |
| 749 start += sizeof(uword); | |
| 750 for (uword* cursor = reinterpret_cast<uword*>(start); | |
| 751 cursor < reinterpret_cast<uword*>(end); cursor++) { | |
| 752 stream->WriteWord(*cursor); | |
| 753 } | |
| 754 } | |
| 755 } | |
| 756 | |
| 757 | |
| 711 static void EnsureIdentifier(char* label) { | 758 static void EnsureIdentifier(char* label) { |
| 712 for (char c = *label; c != '\0'; c = *++label) { | 759 for (char c = *label; c != '\0'; c = *++label) { |
| 713 if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || | 760 if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || |
| 714 ((c >= '0') && (c <= '9'))) { | 761 ((c >= '0') && (c <= '9'))) { |
| 715 continue; | 762 continue; |
| 716 } | 763 } |
| 717 *label = '_'; | 764 *label = '_'; |
| 718 } | 765 } |
| 719 } | 766 } |
| 720 | 767 |
| 721 | 768 |
| 722 void AssemblyInstructionsWriter::Write(uint8_t* vmisolate_buffer, | 769 void AssemblyInstructionsWriter::Write(WriteStream* clustered_stream, bool vm) { |
| 723 intptr_t vmisolate_length, | |
| 724 uint8_t* isolate_buffer, | |
| 725 intptr_t isolate_length) { | |
| 726 Thread* thread = Thread::Current(); | 770 Thread* thread = Thread::Current(); |
| 727 Zone* zone = thread->zone(); | 771 Zone* zone = thread->zone(); |
| 728 NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), | 772 NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), |
| 729 "WriteInstructions")); | 773 "WriteInstructions")); |
| 730 | 774 |
| 731 // Handlify collected raw pointers as building the names below | 775 // Handlify collected raw pointers as building the names below |
| 732 // will allocate on the Dart heap. | 776 // will allocate on the Dart heap. |
| 733 for (intptr_t i = 0; i < instructions_.length(); i++) { | 777 HandlifyObjects(); |
| 734 InstructionsData& data = instructions_[i]; | |
| 735 data.insns_ = &Instructions::Handle(zone, data.raw_insns_); | |
| 736 ASSERT(data.raw_code_ != NULL); | |
| 737 data.code_ = &Code::Handle(zone, data.raw_code_); | |
| 738 } | |
| 739 for (intptr_t i = 0; i < objects_.length(); i++) { | |
| 740 ObjectData& data = objects_[i]; | |
| 741 data.obj_ = &Object::Handle(zone, data.raw_obj_); | |
| 742 } | |
| 743 | 778 |
| 779 // Append the direct-mapped RO data objects after the clustered snapshot. | |
| 780 WriteROData(clustered_stream); | |
|
siva
2017/01/20 22:53:54
These two calls (HandlifyObjects and WriteROData)
rmacnak
2017/01/21 00:50:43
Commoned this sequence in one InstructionsWriter::
| |
| 781 | |
| 782 const char* instructions_symbol = | |
| 783 vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions"; | |
| 744 assembly_stream_.Print(".text\n"); | 784 assembly_stream_.Print(".text\n"); |
| 745 assembly_stream_.Print(".globl _kInstructionsSnapshot\n"); | 785 assembly_stream_.Print(".globl %s\n", instructions_symbol); |
| 746 // Start snapshot at page boundary. | 786 // Start snapshot at page boundary. |
| 747 ASSERT(VirtualMemory::PageSize() >= OS::kMaxPreferredCodeAlignment); | 787 ASSERT(VirtualMemory::PageSize() >= OS::kMaxPreferredCodeAlignment); |
| 748 assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); | 788 assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); |
| 749 assembly_stream_.Print("_kInstructionsSnapshot:\n"); | 789 assembly_stream_.Print("%s:\n", instructions_symbol); |
| 750 | 790 |
| 751 // This head also provides the gap to make the instructions snapshot | 791 // This head also provides the gap to make the instructions snapshot |
| 752 // look like a HeapPage. | 792 // look like a HeapPage. |
| 753 intptr_t instructions_length = next_offset_; | 793 intptr_t instructions_length = next_offset_; |
| 754 WriteWordLiteralText(instructions_length); | 794 WriteWordLiteralText(instructions_length); |
| 755 intptr_t header_words = InstructionsSnapshot::kHeaderSize / sizeof(uword); | 795 intptr_t header_words = InstructionsSnapshot::kHeaderSize / sizeof(uword); |
| 756 for (intptr_t i = 1; i < header_words; i++) { | 796 for (intptr_t i = 1; i < header_words; i++) { |
| 757 WriteWordLiteralText(0); | 797 WriteWordLiteralText(0); |
| 758 } | 798 } |
| 759 | 799 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 821 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); | 861 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 822 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); | 862 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 823 ASSERT(Utils::IsAligned(end, sizeof(uint64_t))); | 863 ASSERT(Utils::IsAligned(end, sizeof(uint64_t))); |
| 824 | 864 |
| 825 for (uword* cursor = reinterpret_cast<uword*>(entry); | 865 for (uword* cursor = reinterpret_cast<uword*>(entry); |
| 826 cursor < reinterpret_cast<uword*>(end); cursor++) { | 866 cursor < reinterpret_cast<uword*>(end); cursor++) { |
| 827 WriteWordLiteralText(*cursor); | 867 WriteWordLiteralText(*cursor); |
| 828 } | 868 } |
| 829 } | 869 } |
| 830 } | 870 } |
| 871 | |
| 872 | |
| 831 #if defined(TARGET_OS_LINUX) | 873 #if defined(TARGET_OS_LINUX) |
| 832 assembly_stream_.Print(".section .rodata\n"); | 874 assembly_stream_.Print(".section .rodata\n"); |
| 833 #elif defined(TARGET_OS_MACOS) | 875 #elif defined(TARGET_OS_MACOS) |
| 834 assembly_stream_.Print(".const\n"); | 876 assembly_stream_.Print(".const\n"); |
| 835 #else | 877 #else |
| 836 // Unsupported platform. | 878 // Unsupported platform. |
| 837 UNREACHABLE(); | 879 UNREACHABLE(); |
| 838 #endif | 880 #endif |
| 839 assembly_stream_.Print(".globl _kDataSnapshot\n"); | 881 |
| 840 // Start snapshot at page boundary. | 882 const char* data_symbol = |
| 841 assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); | 883 vm ? "_kDartVmSnapshotData" : "_kDartIsolateSnapshotData"; |
| 842 assembly_stream_.Print("_kDataSnapshot:\n"); | 884 assembly_stream_.Print(".globl %s\n", data_symbol); |
| 843 WriteWordLiteralData(next_object_offset_); // Data length. | |
| 844 COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment); | |
| 845 assembly_stream_.Print(".balign %" Pd ", 0\n", | 885 assembly_stream_.Print(".balign %" Pd ", 0\n", |
| 846 OS::kMaxPreferredCodeAlignment); | 886 OS::kMaxPreferredCodeAlignment); |
| 847 | 887 assembly_stream_.Print("%s:\n", data_symbol); |
| 848 for (intptr_t i = 0; i < objects_.length(); i++) { | 888 uint8_t* buffer = clustered_stream->buffer(); |
| 849 const Object& obj = *objects_[i].obj_; | 889 intptr_t length = clustered_stream->bytes_written(); |
| 850 assembly_stream_.Print("Precompiled_Obj_%d:\n", i); | 890 for (intptr_t i = 0; i < length; i++) { |
| 851 | 891 assembly_stream_.Print(".byte %" Pd "\n", buffer[i]); |
| 852 NoSafepointScope no_safepoint; | |
| 853 uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag; | |
| 854 uword end = start + obj.raw()->Size(); | |
| 855 | |
| 856 // Write object header with the mark and VM heap bits set. | |
| 857 uword marked_tags = obj.raw()->ptr()->tags_; | |
| 858 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | |
| 859 marked_tags = RawObject::MarkBit::update(true, marked_tags); | |
| 860 WriteWordLiteralData(marked_tags); | |
| 861 start += sizeof(uword); | |
| 862 for (uword* cursor = reinterpret_cast<uword*>(start); | |
| 863 cursor < reinterpret_cast<uword*>(end); cursor++) { | |
| 864 WriteWordLiteralData(*cursor); | |
| 865 } | |
| 866 } | |
| 867 | |
| 868 | |
| 869 assembly_stream_.Print(".globl _kVmIsolateSnapshot\n"); | |
| 870 assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); | |
| 871 assembly_stream_.Print("_kVmIsolateSnapshot:\n"); | |
| 872 for (intptr_t i = 0; i < vmisolate_length; i++) { | |
| 873 assembly_stream_.Print(".byte %" Pd "\n", vmisolate_buffer[i]); | |
| 874 } | |
| 875 | |
| 876 assembly_stream_.Print(".globl _kIsolateSnapshot\n"); | |
| 877 assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); | |
| 878 assembly_stream_.Print("_kIsolateSnapshot:\n"); | |
| 879 for (intptr_t i = 0; i < isolate_length; i++) { | |
| 880 assembly_stream_.Print(".byte %" Pd "\n", isolate_buffer[i]); | |
| 881 } | 892 } |
| 882 } | 893 } |
| 883 | 894 |
| 884 | 895 |
| 885 void BlobInstructionsWriter::Write(uint8_t* vmisolate_buffer, | 896 void BlobInstructionsWriter::Write(WriteStream* clustered_stream, bool vm) { |
| 886 intptr_t vmisolate_len, | 897 NOT_IN_PRODUCT(TimelineDurationScope tds( |
| 887 uint8_t* isolate_buffer, | 898 Thread::Current(), Timeline::GetIsolateStream(), "WriteInstructions")); |
| 888 intptr_t isolate_length) { | |
| 889 Thread* thread = Thread::Current(); | |
| 890 Zone* zone = thread->zone(); | |
| 891 NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), | |
| 892 "WriteInstructions")); | |
| 893 | 899 |
| 894 // Handlify collected raw pointers as building the names below | 900 // Handlify collected raw pointers as building the names below |
| 895 // will allocate on the Dart heap. | 901 // will allocate on the Dart heap. |
| 896 for (intptr_t i = 0; i < instructions_.length(); i++) { | 902 HandlifyObjects(); |
| 897 InstructionsData& data = instructions_[i]; | 903 |
| 898 data.insns_ = &Instructions::Handle(zone, data.raw_insns_); | 904 // Append the direct-mapped RO data objects after the clustered snapshot. |
| 899 ASSERT(data.raw_code_ != NULL); | 905 WriteROData(clustered_stream); |
|
siva
2017/01/20 22:53:54
Ditto comment.
| |
| 900 data.code_ = &Code::Handle(zone, data.raw_code_); | |
| 901 } | |
| 902 for (intptr_t i = 0; i < objects_.length(); i++) { | |
| 903 ObjectData& data = objects_[i]; | |
| 904 data.obj_ = &Object::Handle(zone, data.raw_obj_); | |
| 905 } | |
| 906 | 906 |
| 907 // This head also provides the gap to make the instructions snapshot | 907 // This head also provides the gap to make the instructions snapshot |
| 908 // look like a HeapPage. | 908 // look like a HeapPage. |
| 909 intptr_t instructions_length = next_offset_; | 909 intptr_t instructions_length = next_offset_; |
| 910 instructions_blob_stream_.WriteWord(instructions_length); | 910 instructions_blob_stream_.WriteWord(instructions_length); |
| 911 intptr_t header_words = InstructionsSnapshot::kHeaderSize / sizeof(uword); | 911 intptr_t header_words = InstructionsSnapshot::kHeaderSize / sizeof(uword); |
| 912 for (intptr_t i = 1; i < header_words; i++) { | 912 for (intptr_t i = 1; i < header_words; i++) { |
| 913 instructions_blob_stream_.WriteWord(0); | 913 instructions_blob_stream_.WriteWord(0); |
| 914 } | 914 } |
| 915 | 915 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 952 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); | 952 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 953 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); | 953 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 954 ASSERT(Utils::IsAligned(end, sizeof(uint64_t))); | 954 ASSERT(Utils::IsAligned(end, sizeof(uint64_t))); |
| 955 | 955 |
| 956 for (uword* cursor = reinterpret_cast<uword*>(entry); | 956 for (uword* cursor = reinterpret_cast<uword*>(entry); |
| 957 cursor < reinterpret_cast<uword*>(end); cursor++) { | 957 cursor < reinterpret_cast<uword*>(end); cursor++) { |
| 958 instructions_blob_stream_.WriteWord(*cursor); | 958 instructions_blob_stream_.WriteWord(*cursor); |
| 959 } | 959 } |
| 960 } | 960 } |
| 961 } | 961 } |
| 962 | |
| 963 rodata_blob_stream_.WriteWord(next_object_offset_); // Data length. | |
| 964 COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment); | |
| 965 while (!Utils::IsAligned(rodata_blob_stream_.bytes_written(), | |
| 966 OS::kMaxPreferredCodeAlignment)) { | |
| 967 rodata_blob_stream_.WriteWord(0); | |
| 968 } | |
| 969 | |
| 970 for (intptr_t i = 0; i < objects_.length(); i++) { | |
| 971 const Object& obj = *objects_[i].obj_; | |
| 972 | |
| 973 NoSafepointScope no_safepoint; | |
| 974 uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag; | |
| 975 uword end = start + obj.raw()->Size(); | |
| 976 | |
| 977 // Write object header with the mark and VM heap bits set. | |
| 978 uword marked_tags = obj.raw()->ptr()->tags_; | |
| 979 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | |
| 980 marked_tags = RawObject::MarkBit::update(true, marked_tags); | |
| 981 rodata_blob_stream_.WriteWord(marked_tags); | |
| 982 start += sizeof(uword); | |
| 983 for (uword* cursor = reinterpret_cast<uword*>(start); | |
| 984 cursor < reinterpret_cast<uword*>(end); cursor++) { | |
| 985 rodata_blob_stream_.WriteWord(*cursor); | |
| 986 } | |
| 987 } | |
| 988 } | 962 } |
| 989 | 963 |
| 990 | 964 |
| 991 uword InstructionsReader::GetInstructionsAt(int32_t offset) { | 965 RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset) { |
| 992 ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); | 966 ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); |
| 993 return reinterpret_cast<uword>(instructions_buffer_) + offset; | 967 |
| 968 RawInstructions* result = reinterpret_cast<RawInstructions*>( | |
| 969 reinterpret_cast<uword>(instructions_buffer_) + offset + kHeapObjectTag); | |
| 970 ASSERT(result->IsInstructions()); | |
| 971 ASSERT(result->IsMarked()); | |
| 972 | |
| 973 return result; | |
| 994 } | 974 } |
| 995 | 975 |
| 996 | 976 |
| 997 RawObject* InstructionsReader::GetObjectAt(int32_t offset) { | 977 RawObject* InstructionsReader::GetObjectAt(int32_t offset) { |
| 998 ASSERT(Utils::IsAligned(offset, kWordSize)); | 978 ASSERT(Utils::IsAligned(offset, kWordSize)); |
| 999 | 979 |
| 1000 RawObject* result = reinterpret_cast<RawObject*>( | 980 RawObject* result = reinterpret_cast<RawObject*>( |
| 1001 reinterpret_cast<uword>(data_buffer_) + offset + kHeapObjectTag); | 981 reinterpret_cast<uword>(data_buffer_) + offset + kHeapObjectTag); |
| 1002 ASSERT(result->IsMarked()); | 982 ASSERT(result->IsMarked()); |
| 1003 | 983 |
| (...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1961 NoSafepointScope no_safepoint; | 1941 NoSafepointScope no_safepoint; |
| 1962 WriteObject(obj.raw()); | 1942 WriteObject(obj.raw()); |
| 1963 } else { | 1943 } else { |
| 1964 FreeBuffer(); | 1944 FreeBuffer(); |
| 1965 ThrowException(exception_type(), exception_msg()); | 1945 ThrowException(exception_type(), exception_msg()); |
| 1966 } | 1946 } |
| 1967 } | 1947 } |
| 1968 | 1948 |
| 1969 | 1949 |
| 1970 } // namespace dart | 1950 } // namespace dart |
| OLD | NEW |