| 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 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 RawObject* SnapshotReader::NewInteger(int64_t value) { | 672 RawObject* SnapshotReader::NewInteger(int64_t value) { |
| 673 ASSERT((value & kSmiTagMask) == kSmiTag); | 673 ASSERT((value & kSmiTagMask) == kSmiTag); |
| 674 value = value >> kSmiTagShift; | 674 value = value >> kSmiTagShift; |
| 675 if (Smi::IsValid(value)) { | 675 if (Smi::IsValid(value)) { |
| 676 return Smi::New(static_cast<intptr_t>(value)); | 676 return Smi::New(static_cast<intptr_t>(value)); |
| 677 } | 677 } |
| 678 return Mint::NewCanonical(value); | 678 return Mint::NewCanonical(value); |
| 679 } | 679 } |
| 680 | 680 |
| 681 | 681 |
| 682 int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions, | 682 int32_t ImageWriter::GetOffsetFor(RawInstructions* instructions, |
| 683 RawCode* code) { | 683 RawCode* code) { |
| 684 #if defined(PRODUCT) | 684 #if defined(PRODUCT) |
| 685 // Instructions are only dedup in product mode because it obfuscates profiler | 685 // Instructions are only dedup in product mode because it obfuscates profiler |
| 686 // results. | 686 // results. |
| 687 for (intptr_t i = 0; i < instructions_.length(); i++) { | 687 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 688 if (instructions_[i].raw_insns_ == instructions) { | 688 if (instructions_[i].raw_insns_ == instructions) { |
| 689 return instructions_[i].offset_; | 689 return instructions_[i].offset_; |
| 690 } | 690 } |
| 691 } | 691 } |
| 692 #endif | 692 #endif |
| 693 | 693 |
| 694 intptr_t heap_size = instructions->Size(); | 694 intptr_t heap_size = instructions->Size(); |
| 695 intptr_t offset = next_offset_; | 695 intptr_t offset = next_offset_; |
| 696 next_offset_ += heap_size; | 696 next_offset_ += heap_size; |
| 697 instructions_.Add(InstructionsData(instructions, code, offset)); | 697 instructions_.Add(InstructionsData(instructions, code, offset)); |
| 698 | 698 |
| 699 return offset; | 699 return offset; |
| 700 } | 700 } |
| 701 | 701 |
| 702 | 702 |
| 703 int32_t InstructionsWriter::GetObjectOffsetFor(RawObject* raw_object) { | 703 int32_t ImageWriter::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 void InstructionsWriter::Write(WriteStream* clustered_stream, bool vm) { | 712 void ImageWriter::Write(WriteStream* clustered_stream, bool vm) { |
| 713 Thread* thread = Thread::Current(); | 713 Thread* thread = Thread::Current(); |
| 714 Zone* zone = thread->zone(); | 714 Zone* zone = thread->zone(); |
| 715 NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), | 715 NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), |
| 716 "WriteInstructions")); | 716 "WriteInstructions")); |
| 717 | 717 |
| 718 // Handlify collected raw pointers as building the names below | 718 // Handlify collected raw pointers as building the names below |
| 719 // will allocate on the Dart heap. | 719 // will allocate on the Dart heap. |
| 720 for (intptr_t i = 0; i < instructions_.length(); i++) { | 720 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 721 InstructionsData& data = instructions_[i]; | 721 InstructionsData& data = instructions_[i]; |
| 722 data.insns_ = &Instructions::Handle(zone, data.raw_insns_); | 722 data.insns_ = &Instructions::Handle(zone, data.raw_insns_); |
| 723 ASSERT(data.raw_code_ != NULL); | 723 ASSERT(data.raw_code_ != NULL); |
| 724 data.code_ = &Code::Handle(zone, data.raw_code_); | 724 data.code_ = &Code::Handle(zone, data.raw_code_); |
| 725 } | 725 } |
| 726 for (intptr_t i = 0; i < objects_.length(); i++) { | 726 for (intptr_t i = 0; i < objects_.length(); i++) { |
| 727 ObjectData& data = objects_[i]; | 727 ObjectData& data = objects_[i]; |
| 728 data.obj_ = &Object::Handle(zone, data.raw_obj_); | 728 data.obj_ = &Object::Handle(zone, data.raw_obj_); |
| 729 } | 729 } |
| 730 | 730 |
| 731 // Append the direct-mapped RO data objects after the clustered snapshot. | 731 // Append the direct-mapped RO data objects after the clustered snapshot. |
| 732 WriteROData(clustered_stream); | 732 WriteROData(clustered_stream); |
| 733 | 733 |
| 734 WriteText(clustered_stream, vm); | 734 WriteText(clustered_stream, vm); |
| 735 } | 735 } |
| 736 | 736 |
| 737 | 737 |
| 738 void InstructionsWriter::WriteROData(WriteStream* stream) { | 738 void ImageWriter::WriteROData(WriteStream* stream) { |
| 739 stream->Align(OS::kMaxPreferredCodeAlignment); | 739 stream->Align(OS::kMaxPreferredCodeAlignment); |
| 740 | 740 |
| 741 // Heap page starts here. | 741 // Heap page starts here. |
| 742 | 742 |
| 743 stream->WriteWord(next_object_offset_); // Data length. | 743 stream->WriteWord(next_object_offset_); // Data length. |
| 744 COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment); | 744 COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment); |
| 745 stream->Align(OS::kMaxPreferredCodeAlignment); | 745 stream->Align(OS::kMaxPreferredCodeAlignment); |
| 746 | 746 |
| 747 // Heap page objects start here. | 747 // Heap page objects start here. |
| 748 | 748 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 771 for (char c = *label; c != '\0'; c = *++label) { | 771 for (char c = *label; c != '\0'; c = *++label) { |
| 772 if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || | 772 if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || |
| 773 ((c >= '0') && (c <= '9'))) { | 773 ((c >= '0') && (c <= '9'))) { |
| 774 continue; | 774 continue; |
| 775 } | 775 } |
| 776 *label = '_'; | 776 *label = '_'; |
| 777 } | 777 } |
| 778 } | 778 } |
| 779 | 779 |
| 780 | 780 |
| 781 void AssemblyInstructionsWriter::WriteText(WriteStream* clustered_stream, | 781 void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) { |
| 782 bool vm) { | |
| 783 Zone* zone = Thread::Current()->zone(); | 782 Zone* zone = Thread::Current()->zone(); |
| 784 | 783 |
| 785 const char* instructions_symbol = | 784 const char* instructions_symbol = |
| 786 vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions"; | 785 vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions"; |
| 787 assembly_stream_.Print(".text\n"); | 786 assembly_stream_.Print(".text\n"); |
| 788 assembly_stream_.Print(".globl %s\n", instructions_symbol); | 787 assembly_stream_.Print(".globl %s\n", instructions_symbol); |
| 789 // Start snapshot at page boundary. | 788 // Start snapshot at page boundary. |
| 790 ASSERT(VirtualMemory::PageSize() >= OS::kMaxPreferredCodeAlignment); | 789 ASSERT(VirtualMemory::PageSize() >= OS::kMaxPreferredCodeAlignment); |
| 791 assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); | 790 assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize()); |
| 792 assembly_stream_.Print("%s:\n", instructions_symbol); | 791 assembly_stream_.Print("%s:\n", instructions_symbol); |
| 793 | 792 |
| 794 // This head also provides the gap to make the instructions snapshot | 793 // This head also provides the gap to make the instructions snapshot |
| 795 // look like a HeapPage. | 794 // look like a HeapPage. |
| 796 intptr_t instructions_length = next_offset_; | 795 intptr_t instructions_length = next_offset_; |
| 797 WriteWordLiteralText(instructions_length); | 796 WriteWordLiteralText(instructions_length); |
| 798 intptr_t header_words = InstructionsSnapshot::kHeaderSize / sizeof(uword); | 797 intptr_t header_words = Image::kHeaderSize / sizeof(uword); |
| 799 for (intptr_t i = 1; i < header_words; i++) { | 798 for (intptr_t i = 1; i < header_words; i++) { |
| 800 WriteWordLiteralText(0); | 799 WriteWordLiteralText(0); |
| 801 } | 800 } |
| 802 | 801 |
| 803 Object& owner = Object::Handle(zone); | 802 Object& owner = Object::Handle(zone); |
| 804 String& str = String::Handle(zone); | 803 String& str = String::Handle(zone); |
| 805 | 804 |
| 806 for (intptr_t i = 0; i < instructions_.length(); i++) { | 805 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 807 const Instructions& insns = *instructions_[i].insns_; | 806 const Instructions& insns = *instructions_[i].insns_; |
| 808 const Code& code = *instructions_[i].code_; | 807 const Code& code = *instructions_[i].code_; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 OS::kMaxPreferredCodeAlignment); | 888 OS::kMaxPreferredCodeAlignment); |
| 890 assembly_stream_.Print("%s:\n", data_symbol); | 889 assembly_stream_.Print("%s:\n", data_symbol); |
| 891 uint8_t* buffer = clustered_stream->buffer(); | 890 uint8_t* buffer = clustered_stream->buffer(); |
| 892 intptr_t length = clustered_stream->bytes_written(); | 891 intptr_t length = clustered_stream->bytes_written(); |
| 893 for (intptr_t i = 0; i < length; i++) { | 892 for (intptr_t i = 0; i < length; i++) { |
| 894 assembly_stream_.Print(".byte %" Pd "\n", buffer[i]); | 893 assembly_stream_.Print(".byte %" Pd "\n", buffer[i]); |
| 895 } | 894 } |
| 896 } | 895 } |
| 897 | 896 |
| 898 | 897 |
| 899 void BlobInstructionsWriter::WriteText(WriteStream* clustered_stream, bool vm) { | 898 void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) { |
| 900 // This header provides the gap to make the instructions snapshot look like a | 899 // This header provides the gap to make the instructions snapshot look like a |
| 901 // HeapPage. | 900 // HeapPage. |
| 902 intptr_t instructions_length = next_offset_; | 901 intptr_t instructions_length = next_offset_; |
| 903 instructions_blob_stream_.WriteWord(instructions_length); | 902 instructions_blob_stream_.WriteWord(instructions_length); |
| 904 intptr_t header_words = InstructionsSnapshot::kHeaderSize / sizeof(uword); | 903 intptr_t header_words = Image::kHeaderSize / sizeof(uword); |
| 905 for (intptr_t i = 1; i < header_words; i++) { | 904 for (intptr_t i = 1; i < header_words; i++) { |
| 906 instructions_blob_stream_.WriteWord(0); | 905 instructions_blob_stream_.WriteWord(0); |
| 907 } | 906 } |
| 908 | 907 |
| 909 for (intptr_t i = 0; i < instructions_.length(); i++) { | 908 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 910 const Instructions& insns = *instructions_[i].insns_; | 909 const Instructions& insns = *instructions_[i].insns_; |
| 911 | 910 |
| 912 // 1. Write from the header to the entry point. | 911 // 1. Write from the header to the entry point. |
| 913 { | 912 { |
| 914 NoSafepointScope no_safepoint; | 913 NoSafepointScope no_safepoint; |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1939 *buffer_len_ = BytesWritten(); | 1938 *buffer_len_ = BytesWritten(); |
| 1940 } | 1939 } |
| 1941 } else { | 1940 } else { |
| 1942 FreeBuffer(); | 1941 FreeBuffer(); |
| 1943 ThrowException(exception_type(), exception_msg()); | 1942 ThrowException(exception_type(), exception_msg()); |
| 1944 } | 1943 } |
| 1945 } | 1944 } |
| 1946 | 1945 |
| 1947 | 1946 |
| 1948 } // namespace dart | 1947 } // namespace dart |
| OLD | NEW |