| 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" |
| 11 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
| 12 #include "vm/dwarf.h" | |
| 13 #include "vm/exceptions.h" | 12 #include "vm/exceptions.h" |
| 14 #include "vm/heap.h" | 13 #include "vm/heap.h" |
| 15 #include "vm/lockers.h" | 14 #include "vm/lockers.h" |
| 16 #include "vm/longjump.h" | 15 #include "vm/longjump.h" |
| 17 #include "vm/object.h" | 16 #include "vm/object.h" |
| 18 #include "vm/object_store.h" | 17 #include "vm/object_store.h" |
| 19 #include "vm/snapshot_ids.h" | 18 #include "vm/snapshot_ids.h" |
| 20 #include "vm/stub_code.h" | 19 #include "vm/stub_code.h" |
| 21 #include "vm/symbols.h" | 20 #include "vm/symbols.h" |
| 22 #include "vm/timeline.h" | 21 #include "vm/timeline.h" |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 stream->WriteWord(marked_tags); | 765 stream->WriteWord(marked_tags); |
| 767 start += sizeof(uword); | 766 start += sizeof(uword); |
| 768 for (uword* cursor = reinterpret_cast<uword*>(start); | 767 for (uword* cursor = reinterpret_cast<uword*>(start); |
| 769 cursor < reinterpret_cast<uword*>(end); cursor++) { | 768 cursor < reinterpret_cast<uword*>(end); cursor++) { |
| 770 stream->WriteWord(*cursor); | 769 stream->WriteWord(*cursor); |
| 771 } | 770 } |
| 772 } | 771 } |
| 773 } | 772 } |
| 774 | 773 |
| 775 | 774 |
| 776 AssemblyImageWriter::AssemblyImageWriter(uint8_t** assembly_buffer, | |
| 777 ReAlloc alloc, | |
| 778 intptr_t initial_size) | |
| 779 : ImageWriter(), | |
| 780 assembly_stream_(assembly_buffer, alloc, initial_size), | |
| 781 text_size_(0), | |
| 782 dwarf_(NULL) { | |
| 783 #if defined(DART_PRECOMPILER) | |
| 784 Zone* zone = Thread::Current()->zone(); | |
| 785 dwarf_ = new (zone) Dwarf(zone, &assembly_stream_); | |
| 786 #endif | |
| 787 } | |
| 788 | |
| 789 | |
| 790 void AssemblyImageWriter::Finalize() { | |
| 791 #ifdef DART_PRECOMPILER | |
| 792 dwarf_->Write(); | |
| 793 #endif | |
| 794 } | |
| 795 | |
| 796 | |
| 797 static void EnsureIdentifier(char* label) { | 775 static void EnsureIdentifier(char* label) { |
| 798 for (char c = *label; c != '\0'; c = *++label) { | 776 for (char c = *label; c != '\0'; c = *++label) { |
| 799 if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || | 777 if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || |
| 800 ((c >= '0') && (c <= '9'))) { | 778 ((c >= '0') && (c <= '9'))) { |
| 801 continue; | 779 continue; |
| 802 } | 780 } |
| 803 *label = '_'; | 781 *label = '_'; |
| 804 } | 782 } |
| 805 } | 783 } |
| 806 | 784 |
| 807 | 785 |
| 808 void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) { | 786 void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) { |
| 809 Zone* zone = Thread::Current()->zone(); | 787 Zone* zone = Thread::Current()->zone(); |
| 810 | 788 |
| 811 const char* instructions_symbol = | 789 const char* instructions_symbol = |
| 812 vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions"; | 790 vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions"; |
| 813 assembly_stream_.Print(".text\n"); | 791 assembly_stream_.Print(".text\n"); |
| 814 assembly_stream_.Print(".globl %s\n", instructions_symbol); | 792 assembly_stream_.Print(".globl %s\n", instructions_symbol); |
| 815 | |
| 816 // Start snapshot at page boundary. | 793 // Start snapshot at page boundary. |
| 817 ASSERT(VirtualMemory::PageSize() >= OS::kMaxPreferredCodeAlignment); | 794 ASSERT(VirtualMemory::PageSize() >= OS::kMaxPreferredCodeAlignment); |
| 818 assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); | 795 assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); |
| 819 assembly_stream_.Print("%s:\n", instructions_symbol); | 796 assembly_stream_.Print("%s:\n", instructions_symbol); |
| 820 | 797 |
| 821 // This head also provides the gap to make the instructions snapshot | 798 // This head also provides the gap to make the instructions snapshot |
| 822 // look like a HeapPage. | 799 // look like a HeapPage. |
| 823 intptr_t instructions_length = next_offset_; | 800 intptr_t instructions_length = next_offset_; |
| 824 WriteWordLiteralText(instructions_length); | 801 WriteWordLiteralText(instructions_length); |
| 825 intptr_t header_words = Image::kHeaderSize / sizeof(uword); | 802 intptr_t header_words = Image::kHeaderSize / sizeof(uword); |
| 826 for (intptr_t i = 1; i < header_words; i++) { | 803 for (intptr_t i = 1; i < header_words; i++) { |
| 827 WriteWordLiteralText(0); | 804 WriteWordLiteralText(0); |
| 828 } | 805 } |
| 829 | 806 |
| 830 FrameUnwindPrologue(); | |
| 831 | |
| 832 Object& owner = Object::Handle(zone); | 807 Object& owner = Object::Handle(zone); |
| 833 String& str = String::Handle(zone); | 808 String& str = String::Handle(zone); |
| 834 | 809 |
| 835 for (intptr_t i = 0; i < instructions_.length(); i++) { | 810 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 836 const Instructions& insns = *instructions_[i].insns_; | 811 const Instructions& insns = *instructions_[i].insns_; |
| 837 const Code& code = *instructions_[i].code_; | 812 const Code& code = *instructions_[i].code_; |
| 838 | 813 |
| 839 ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0); | 814 ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0); |
| 840 | 815 |
| 841 // 1. Write from the header to the entry point. | 816 // 1. Write from the header to the entry point. |
| 842 { | 817 { |
| 843 NoSafepointScope no_safepoint; | 818 NoSafepointScope no_safepoint; |
| 844 | 819 |
| 845 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); | 820 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); |
| 846 uword entry = beginning + Instructions::HeaderSize(); | 821 uword entry = beginning + Instructions::HeaderSize(); |
| 847 | 822 |
| 823 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 824 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 825 |
| 848 // Write Instructions with the mark and VM heap bits set. | 826 // Write Instructions with the mark and VM heap bits set. |
| 849 uword marked_tags = insns.raw_ptr()->tags_; | 827 uword marked_tags = insns.raw_ptr()->tags_; |
| 850 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | 828 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
| 851 marked_tags = RawObject::MarkBit::update(true, marked_tags); | 829 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
| 852 | 830 |
| 853 WriteWordLiteralText(marked_tags); | 831 WriteWordLiteralText(marked_tags); |
| 854 beginning += sizeof(uword); | 832 beginning += sizeof(uword); |
| 855 | 833 |
| 856 WriteByteSequence(beginning, entry); | 834 for (uword* cursor = reinterpret_cast<uword*>(beginning); |
| 835 cursor < reinterpret_cast<uword*>(entry); cursor++) { |
| 836 WriteWordLiteralText(*cursor); |
| 837 } |
| 857 } | 838 } |
| 858 | 839 |
| 859 // 2. Write a label at the entry point. | 840 // 2. Write a label at the entry point. |
| 860 // Linux's perf uses these labels. | |
| 861 owner = code.owner(); | 841 owner = code.owner(); |
| 862 if (owner.IsNull()) { | 842 if (owner.IsNull()) { |
| 863 const char* name = StubCode::NameOfStub(insns.UncheckedEntryPoint()); | 843 const char* name = StubCode::NameOfStub(insns.UncheckedEntryPoint()); |
| 864 assembly_stream_.Print("Precompiled_Stub_%s:\n", name); | 844 assembly_stream_.Print("Precompiled_Stub_%s:\n", name); |
| 865 } else if (owner.IsClass()) { | 845 } else if (owner.IsClass()) { |
| 866 str = Class::Cast(owner).Name(); | 846 str = Class::Cast(owner).Name(); |
| 867 const char* name = str.ToCString(); | 847 const char* name = str.ToCString(); |
| 868 EnsureIdentifier(const_cast<char*>(name)); | 848 EnsureIdentifier(const_cast<char*>(name)); |
| 869 assembly_stream_.Print("Precompiled_AllocationStub_%s_%" Pd ":\n", name, | 849 assembly_stream_.Print("Precompiled_AllocationStub_%s_%" Pd ":\n", name, |
| 870 i); | 850 i); |
| 871 } else if (owner.IsFunction()) { | 851 } else if (owner.IsFunction()) { |
| 872 const char* name = Function::Cast(owner).ToQualifiedCString(); | 852 const char* name = Function::Cast(owner).ToQualifiedCString(); |
| 873 EnsureIdentifier(const_cast<char*>(name)); | 853 EnsureIdentifier(const_cast<char*>(name)); |
| 874 assembly_stream_.Print("Precompiled_%s_%" Pd ":\n", name, i); | 854 assembly_stream_.Print("Precompiled_%s_%" Pd ":\n", name, i); |
| 875 } else { | 855 } else { |
| 876 UNREACHABLE(); | 856 UNREACHABLE(); |
| 877 } | 857 } |
| 878 | 858 |
| 879 #ifdef DART_PRECOMPILER | |
| 880 // Create a label for use by DWARF. | |
| 881 intptr_t dwarf_index = dwarf_->AddCode(code); | |
| 882 assembly_stream_.Print(".Lcode%" Pd ":\n", dwarf_index); | |
| 883 #endif | |
| 884 | |
| 885 { | 859 { |
| 886 // 3. Write from the entry point to the end. | 860 // 3. Write from the entry point to the end. |
| 887 NoSafepointScope no_safepoint; | 861 NoSafepointScope no_safepoint; |
| 888 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; | 862 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; |
| 889 uword entry = beginning + Instructions::HeaderSize(); | 863 uword entry = beginning + Instructions::HeaderSize(); |
| 890 uword payload_size = insns.Size(); | 864 uword payload_size = insns.Size(); |
| 891 payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment()); | 865 payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment()); |
| 892 uword end = entry + payload_size; | 866 uword end = entry + payload_size; |
| 893 | 867 |
| 894 ASSERT(Utils::IsAligned(beginning, sizeof(uword))); | 868 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 895 ASSERT(Utils::IsAligned(entry, sizeof(uword))); | 869 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 896 ASSERT(Utils::IsAligned(end, sizeof(uword))); | 870 ASSERT(Utils::IsAligned(end, sizeof(uint64_t))); |
| 897 | 871 |
| 898 WriteByteSequence(entry, end); | 872 for (uword* cursor = reinterpret_cast<uword*>(entry); |
| 873 cursor < reinterpret_cast<uword*>(end); cursor++) { |
| 874 WriteWordLiteralText(*cursor); |
| 875 } |
| 899 } | 876 } |
| 900 } | 877 } |
| 901 | 878 |
| 902 FrameUnwindEpilogue(); | |
| 903 | 879 |
| 904 #if defined(HOST_OS_LINUX) | 880 #if defined(HOST_OS_LINUX) |
| 905 assembly_stream_.Print(".section .rodata\n"); | 881 assembly_stream_.Print(".section .rodata\n"); |
| 906 #elif defined(HOST_OS_MACOS) | 882 #elif defined(HOST_OS_MACOS) |
| 907 assembly_stream_.Print(".const\n"); | 883 assembly_stream_.Print(".const\n"); |
| 908 #else | 884 #else |
| 909 // Unsupported platform. | 885 // Unsupported platform. |
| 910 UNREACHABLE(); | 886 UNREACHABLE(); |
| 911 #endif | 887 #endif |
| 912 | 888 |
| 913 const char* data_symbol = | 889 const char* data_symbol = |
| 914 vm ? "_kDartVmSnapshotData" : "_kDartIsolateSnapshotData"; | 890 vm ? "_kDartVmSnapshotData" : "_kDartIsolateSnapshotData"; |
| 915 assembly_stream_.Print(".globl %s\n", data_symbol); | 891 assembly_stream_.Print(".globl %s\n", data_symbol); |
| 916 assembly_stream_.Print(".balign %" Pd ", 0\n", | 892 assembly_stream_.Print(".balign %" Pd ", 0\n", |
| 917 OS::kMaxPreferredCodeAlignment); | 893 OS::kMaxPreferredCodeAlignment); |
| 918 assembly_stream_.Print("%s:\n", data_symbol); | 894 assembly_stream_.Print("%s:\n", data_symbol); |
| 919 uword buffer = reinterpret_cast<uword>(clustered_stream->buffer()); | 895 uint8_t* buffer = clustered_stream->buffer(); |
| 920 intptr_t length = clustered_stream->bytes_written(); | 896 intptr_t length = clustered_stream->bytes_written(); |
| 921 WriteByteSequence(buffer, buffer + length); | 897 for (intptr_t i = 0; i < length; i++) { |
| 922 } | 898 assembly_stream_.Print(".byte %" Pd "\n", buffer[i]); |
| 923 | |
| 924 | |
| 925 void AssemblyImageWriter::FrameUnwindPrologue() { | |
| 926 // Creates DWARF's .debug_frame | |
| 927 // CFI = Call frame information | |
| 928 // CFA = Canonical frame address | |
| 929 assembly_stream_.Print(".cfi_startproc\n"); | |
| 930 | |
| 931 #if defined(TARGET_ARCH_X64) | |
| 932 assembly_stream_.Print(".cfi_def_cfa rbp, 0\n"); // CFA is fp+0 | |
| 933 assembly_stream_.Print(".cfi_offset rbp, 0\n"); // saved fp is *(CFA+0) | |
| 934 assembly_stream_.Print(".cfi_offset rip, 8\n"); // saved pc is *(CFA+8) | |
| 935 // saved sp is CFA+16 | |
| 936 // Should be ".cfi_value_offset rsp, 16", but requires gcc newer than late | |
| 937 // 2016 and not supported by Android's libunwind. | |
| 938 // DW_CFA_expression 0x10 | |
| 939 // uleb128 register (rsp) 7 (DWARF register number) | |
| 940 // uleb128 size of operation 2 | |
| 941 // DW_OP_plus_uconst 0x23 | |
| 942 // uleb128 addend 16 | |
| 943 assembly_stream_.Print(".cfi_escape 0x10, 31, 2, 0x23, 16\n"); | |
| 944 | |
| 945 #elif defined(TARGET_ARCH_ARM64) | |
| 946 COMPILE_ASSERT(FP == R29); | |
| 947 COMPILE_ASSERT(LR == R30); | |
| 948 assembly_stream_.Print(".cfi_def_cfa x29, 0\n"); // CFA is fp+0 | |
| 949 assembly_stream_.Print(".cfi_offset x29, 0\n"); // saved fp is *(CFA+0) | |
| 950 assembly_stream_.Print(".cfi_offset x30, 8\n"); // saved pc is *(CFA+8) | |
| 951 // saved sp is CFA+16 | |
| 952 // Should be ".cfi_value_offset sp, 16", but requires gcc newer than late | |
| 953 // 2016 and not supported by Android's libunwind. | |
| 954 // DW_CFA_expression 0x10 | |
| 955 // uleb128 register (x31) 31 | |
| 956 // uleb128 size of operation 2 | |
| 957 // DW_OP_plus_uconst 0x23 | |
| 958 // uleb128 addend 16 | |
| 959 assembly_stream_.Print(".cfi_escape 0x10, 31, 2, 0x23, 16\n"); | |
| 960 | |
| 961 #elif defined(TARGET_ARCH_ARM) | |
| 962 #if defined(TARGET_ABI_EABI) | |
| 963 COMPILE_ASSERT(FP == R11); | |
| 964 assembly_stream_.Print(".cfi_def_cfa r11, 0\n"); // CFA is fp+0 | |
| 965 assembly_stream_.Print(".cfi_offset r11, 0\n"); // saved fp is *(CFA+0) | |
| 966 #elif defined(TARGET_ABI_IOS) | |
| 967 COMPILE_ASSERT(FP == R7); | |
| 968 assembly_stream_.Print(".cfi_def_cfa r7, 0\n"); // CFA is fp+0 | |
| 969 assembly_stream_.Print(".cfi_offset r7, 0\n"); // saved fp is *(CFA+0) | |
| 970 #endif | |
| 971 assembly_stream_.Print(".cfi_offset lr, 4\n"); // saved pc is *(CFA+4) | |
| 972 // saved sp is CFA+8 | |
| 973 // Should be ".cfi_value_offset sp, 8", but requires gcc newer than late | |
| 974 // 2016 and not supported by Android's libunwind. | |
| 975 // DW_CFA_expression 0x10 | |
| 976 // uleb128 register (sp) 13 | |
| 977 // uleb128 size of operation 2 | |
| 978 // DW_OP_plus_uconst 0x23 | |
| 979 // uleb128 addend 8 | |
| 980 assembly_stream_.Print(".cfi_escape 0x10, 13, 2, 0x23, 8\n"); | |
| 981 | |
| 982 // libunwind on ARM may use .ARM.exidx instead of .debug_frame | |
| 983 #if defined(TARGET_ABI_EABI) | |
| 984 COMPILE_ASSERT(FP == R11); | |
| 985 assembly_stream_.Print(".fnstart\n"); | |
| 986 assembly_stream_.Print(".save {r11, lr}\n"); | |
| 987 assembly_stream_.Print(".setfp r11, sp, #0\n"); | |
| 988 #elif defined(TARGET_ABI_IOS) | |
| 989 COMPILE_ASSERT(FP == R7); | |
| 990 assembly_stream_.Print(".fnstart\n"); | |
| 991 assembly_stream_.Print(".save {r7, lr}\n"); | |
| 992 assembly_stream_.Print(".setfp r7, sp, #0\n"); | |
| 993 #endif | |
| 994 | |
| 995 #elif defined(TARGET_ARCH_MIPS) | |
| 996 COMPILE_ASSERT(FP == R30); | |
| 997 COMPILE_ASSERT(RA == R31); | |
| 998 assembly_stream_.Print(".cfi_def_cfa r30, 0\n"); // CFA is fp+0 | |
| 999 assembly_stream_.Print(".cfi_offset r30, 0\n"); // saved fp is *(CFA+0) | |
| 1000 assembly_stream_.Print(".cfi_offset r31, 4\n"); // saved pc is *(CFA+4) | |
| 1001 // saved sp is CFA+16 | |
| 1002 // Should be ".cfi_value_offset sp, 8", but requires gcc newer than late | |
| 1003 // 2016 and not supported by Android's libunwind. | |
| 1004 // DW_CFA_expression 0x10 | |
| 1005 // uleb128 register (sp) 29 | |
| 1006 // uleb128 size of operation 2 | |
| 1007 // DW_OP_plus_uconst 0x23 | |
| 1008 // uleb128 addend 8 | |
| 1009 assembly_stream_.Print(".cfi_escape 0x10, 29, 2, 0x23, 8\n"); | |
| 1010 #endif | |
| 1011 } | |
| 1012 | |
| 1013 | |
| 1014 void AssemblyImageWriter::FrameUnwindEpilogue() { | |
| 1015 #if defined(TARGET_ARCH_ARM) | |
| 1016 assembly_stream_.Print(".fnend\n"); | |
| 1017 #endif | |
| 1018 assembly_stream_.Print(".cfi_endproc\n"); | |
| 1019 } | |
| 1020 | |
| 1021 | |
| 1022 void AssemblyImageWriter::WriteByteSequence(uword start, uword end) { | |
| 1023 for (uword* cursor = reinterpret_cast<uword*>(start); | |
| 1024 cursor < reinterpret_cast<uword*>(end); cursor++) { | |
| 1025 WriteWordLiteralText(*cursor); | |
| 1026 } | 899 } |
| 1027 } | 900 } |
| 1028 | 901 |
| 1029 | 902 |
| 1030 void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) { | 903 void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) { |
| 1031 // This header provides the gap to make the instructions snapshot look like a | 904 // This header provides the gap to make the instructions snapshot look like a |
| 1032 // HeapPage. | 905 // HeapPage. |
| 1033 intptr_t instructions_length = next_offset_; | 906 intptr_t instructions_length = next_offset_; |
| 1034 instructions_blob_stream_.WriteWord(instructions_length); | 907 instructions_blob_stream_.WriteWord(instructions_length); |
| 1035 intptr_t header_words = Image::kHeaderSize / sizeof(uword); | 908 intptr_t header_words = Image::kHeaderSize / sizeof(uword); |
| 1036 for (intptr_t i = 1; i < header_words; i++) { | 909 for (intptr_t i = 1; i < header_words; i++) { |
| 1037 instructions_blob_stream_.WriteWord(0); | 910 instructions_blob_stream_.WriteWord(0); |
| 1038 } | 911 } |
| 1039 | 912 |
| 1040 NoSafepointScope no_safepoint; | |
| 1041 for (intptr_t i = 0; i < instructions_.length(); i++) { | 913 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 1042 const Instructions& insns = *instructions_[i].insns_; | 914 const Instructions& insns = *instructions_[i].insns_; |
| 1043 | 915 |
| 1044 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); | 916 // 1. Write from the header to the entry point. |
| 1045 uword entry = beginning + Instructions::HeaderSize(); | 917 { |
| 1046 uword payload_size = insns.Size(); | 918 NoSafepointScope no_safepoint; |
| 1047 payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment()); | |
| 1048 uword end = entry + payload_size; | |
| 1049 | 919 |
| 1050 ASSERT(Utils::IsAligned(beginning, sizeof(uword))); | 920 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); |
| 1051 ASSERT(Utils::IsAligned(entry, sizeof(uword))); | 921 uword entry = beginning + Instructions::HeaderSize(); |
| 1052 | 922 |
| 1053 // Write Instructions with the mark and VM heap bits set. | 923 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 1054 uword marked_tags = insns.raw_ptr()->tags_; | 924 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 1055 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); | |
| 1056 marked_tags = RawObject::MarkBit::update(true, marked_tags); | |
| 1057 | 925 |
| 1058 instructions_blob_stream_.WriteWord(marked_tags); | 926 // Write Instructions with the mark and VM heap bits set. |
| 1059 beginning += sizeof(uword); | 927 uword marked_tags = insns.raw_ptr()->tags_; |
| 928 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
| 929 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
| 1060 | 930 |
| 1061 for (uword* cursor = reinterpret_cast<uword*>(beginning); | 931 instructions_blob_stream_.WriteWord(marked_tags); |
| 1062 cursor < reinterpret_cast<uword*>(end); cursor++) { | 932 beginning += sizeof(uword); |
| 1063 instructions_blob_stream_.WriteWord(*cursor); | 933 |
| 934 for (uword* cursor = reinterpret_cast<uword*>(beginning); |
| 935 cursor < reinterpret_cast<uword*>(entry); cursor++) { |
| 936 instructions_blob_stream_.WriteWord(*cursor); |
| 937 } |
| 938 } |
| 939 |
| 940 // 2. Write from the entry point to the end. |
| 941 { |
| 942 NoSafepointScope no_safepoint; |
| 943 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; |
| 944 uword entry = beginning + Instructions::HeaderSize(); |
| 945 uword payload_size = insns.Size(); |
| 946 payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment()); |
| 947 uword end = entry + payload_size; |
| 948 |
| 949 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 950 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 951 ASSERT(Utils::IsAligned(end, sizeof(uint64_t))); |
| 952 |
| 953 for (uword* cursor = reinterpret_cast<uword*>(entry); |
| 954 cursor < reinterpret_cast<uword*>(end); cursor++) { |
| 955 instructions_blob_stream_.WriteWord(*cursor); |
| 956 } |
| 1064 } | 957 } |
| 1065 } | 958 } |
| 1066 } | 959 } |
| 1067 | 960 |
| 1068 | 961 |
| 1069 RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset) { | 962 RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset) { |
| 1070 ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); | 963 ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); |
| 1071 | 964 |
| 1072 RawInstructions* result = reinterpret_cast<RawInstructions*>( | 965 RawInstructions* result = reinterpret_cast<RawInstructions*>( |
| 1073 reinterpret_cast<uword>(instructions_buffer_) + offset + kHeapObjectTag); | 966 reinterpret_cast<uword>(instructions_buffer_) + offset + kHeapObjectTag); |
| (...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2052 *buffer_len_ = BytesWritten(); | 1945 *buffer_len_ = BytesWritten(); |
| 2053 } | 1946 } |
| 2054 } else { | 1947 } else { |
| 2055 FreeBuffer(); | 1948 FreeBuffer(); |
| 2056 ThrowException(exception_type(), exception_msg()); | 1949 ThrowException(exception_type(), exception_msg()); |
| 2057 } | 1950 } |
| 2058 } | 1951 } |
| 2059 | 1952 |
| 2060 | 1953 |
| 2061 } // namespace dart | 1954 } // namespace dart |
| OLD | NEW |