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 |