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 |