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