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