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/pages.h" | 5 #include "vm/pages.h" |
6 | 6 |
7 #include "platform/address_sanitizer.h" | 7 #include "platform/address_sanitizer.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/compiler_stats.h" | 9 #include "vm/compiler_stats.h" |
10 #include "vm/gc_marker.h" | 10 #include "vm/gc_marker.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 HeapPage* result = Initialize(memory, type); | 86 HeapPage* result = Initialize(memory, type); |
87 if (result == NULL) { | 87 if (result == NULL) { |
88 delete memory; // Release reservation to OS. | 88 delete memory; // Release reservation to OS. |
89 return NULL; | 89 return NULL; |
90 } | 90 } |
91 return result; | 91 return result; |
92 } | 92 } |
93 | 93 |
94 | 94 |
95 void HeapPage::Deallocate() { | 95 void HeapPage::Deallocate() { |
96 bool is_embedder_allocated = embedder_allocated(); | 96 bool image_page = is_image_page(); |
97 | 97 |
98 if (!is_embedder_allocated) { | 98 if (!image_page) { |
99 LSAN_UNREGISTER_ROOT_REGION(this, sizeof(*this)); | 99 LSAN_UNREGISTER_ROOT_REGION(this, sizeof(*this)); |
100 } | 100 } |
101 | 101 |
102 // For a regular heap pages, the memory for this object will become | 102 // For a regular heap pages, the memory for this object will become |
103 // unavailable after the delete below. | 103 // unavailable after the delete below. |
104 delete memory_; | 104 delete memory_; |
105 | 105 |
106 // For a heap page from a snapshot, the HeapPage object lives in the malloc | 106 // For a heap page from a snapshot, the HeapPage object lives in the malloc |
107 // heap rather than the page itself. | 107 // heap rather than the page itself. |
108 if (is_embedder_allocated) { | 108 if (image_page) { |
109 free(this); | 109 free(this); |
110 } | 110 } |
111 } | 111 } |
112 | 112 |
113 | 113 |
114 void HeapPage::VisitObjects(ObjectVisitor* visitor) const { | 114 void HeapPage::VisitObjects(ObjectVisitor* visitor) const { |
115 NoSafepointScope no_safepoint; | 115 NoSafepointScope no_safepoint; |
116 uword obj_addr = object_start(); | 116 uword obj_addr = object_start(); |
117 uword end_addr = object_end(); | 117 uword end_addr = object_end(); |
118 while (obj_addr < end_addr) { | 118 while (obj_addr < end_addr) { |
(...skipping 30 matching lines...) Expand all Loading... |
149 } | 149 } |
150 obj_addr = next_obj_addr; | 150 obj_addr = next_obj_addr; |
151 } | 151 } |
152 ASSERT(obj_addr == end_addr); | 152 ASSERT(obj_addr == end_addr); |
153 } | 153 } |
154 return Object::null(); | 154 return Object::null(); |
155 } | 155 } |
156 | 156 |
157 | 157 |
158 void HeapPage::WriteProtect(bool read_only) { | 158 void HeapPage::WriteProtect(bool read_only) { |
159 ASSERT(!embedder_allocated()); | 159 ASSERT(!is_image_page()); |
160 | 160 |
161 VirtualMemory::Protection prot; | 161 VirtualMemory::Protection prot; |
162 if (read_only) { | 162 if (read_only) { |
163 if (type_ == kExecutable) { | 163 if (type_ == kExecutable) { |
164 prot = VirtualMemory::kReadExecute; | 164 prot = VirtualMemory::kReadExecute; |
165 } else { | 165 } else { |
166 prot = VirtualMemory::kReadOnly; | 166 prot = VirtualMemory::kReadOnly; |
167 } | 167 } |
168 } else { | 168 } else { |
169 prot = VirtualMemory::kReadWrite; | 169 prot = VirtualMemory::kReadWrite; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 } | 244 } |
245 pages_tail_ = page; | 245 pages_tail_ = page; |
246 } else { | 246 } else { |
247 // Should not allocate executable pages when running from a precompiled | 247 // Should not allocate executable pages when running from a precompiled |
248 // snapshot. | 248 // snapshot. |
249 ASSERT(Dart::vm_snapshot_kind() != Snapshot::kAppAOT); | 249 ASSERT(Dart::vm_snapshot_kind() != Snapshot::kAppAOT); |
250 | 250 |
251 if (exec_pages_ == NULL) { | 251 if (exec_pages_ == NULL) { |
252 exec_pages_ = page; | 252 exec_pages_ = page; |
253 } else { | 253 } else { |
254 if (FLAG_write_protect_code && !exec_pages_tail_->embedder_allocated()) { | 254 if (FLAG_write_protect_code && !exec_pages_tail_->is_image_page()) { |
255 exec_pages_tail_->WriteProtect(false); | 255 exec_pages_tail_->WriteProtect(false); |
256 } | 256 } |
257 exec_pages_tail_->set_next(page); | 257 exec_pages_tail_->set_next(page); |
258 if (FLAG_write_protect_code && !exec_pages_tail_->embedder_allocated()) { | 258 if (FLAG_write_protect_code && !exec_pages_tail_->is_image_page()) { |
259 exec_pages_tail_->WriteProtect(true); | 259 exec_pages_tail_->WriteProtect(true); |
260 } | 260 } |
261 } | 261 } |
262 exec_pages_tail_ = page; | 262 exec_pages_tail_ = page; |
263 } | 263 } |
264 IncreaseCapacityInWordsLocked(kPageSizeInWords); | 264 IncreaseCapacityInWordsLocked(kPageSizeInWords); |
265 page->set_object_end(page->memory_->end()); | 265 page->set_object_end(page->memory_->end()); |
266 return page; | 266 return page; |
267 } | 267 } |
268 | 268 |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 } | 636 } |
637 | 637 |
638 | 638 |
639 void PageSpace::VisitObjects(ObjectVisitor* visitor) const { | 639 void PageSpace::VisitObjects(ObjectVisitor* visitor) const { |
640 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { | 640 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
641 it.page()->VisitObjects(visitor); | 641 it.page()->VisitObjects(visitor); |
642 } | 642 } |
643 } | 643 } |
644 | 644 |
645 | 645 |
646 void PageSpace::VisitObjectsNoExternalPages(ObjectVisitor* visitor) const { | 646 void PageSpace::VisitObjectsNoImagePages(ObjectVisitor* visitor) const { |
647 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { | 647 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
648 if (!it.page()->embedder_allocated()) { | 648 if (!it.page()->is_image_page()) { |
649 it.page()->VisitObjects(visitor); | 649 it.page()->VisitObjects(visitor); |
650 } | 650 } |
651 } | 651 } |
652 } | 652 } |
653 | 653 |
654 | 654 |
655 void PageSpace::VisitObjectsExternalPages(ObjectVisitor* visitor) const { | 655 void PageSpace::VisitObjectsImagePages(ObjectVisitor* visitor) const { |
656 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { | 656 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
657 if (it.page()->embedder_allocated()) { | 657 if (it.page()->is_image_page()) { |
658 it.page()->VisitObjects(visitor); | 658 it.page()->VisitObjects(visitor); |
659 } | 659 } |
660 } | 660 } |
661 } | 661 } |
662 | 662 |
663 | 663 |
664 void PageSpace::VisitObjectPointers(ObjectPointerVisitor* visitor) const { | 664 void PageSpace::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
665 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { | 665 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
666 it.page()->VisitObjectPointers(visitor); | 666 it.page()->VisitObjectPointers(visitor); |
667 } | 667 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 return Object::null(); | 701 return Object::null(); |
702 } | 702 } |
703 | 703 |
704 | 704 |
705 void PageSpace::WriteProtect(bool read_only) { | 705 void PageSpace::WriteProtect(bool read_only) { |
706 if (read_only) { | 706 if (read_only) { |
707 // Avoid MakeIterable trying to write to the heap. | 707 // Avoid MakeIterable trying to write to the heap. |
708 AbandonBumpAllocation(); | 708 AbandonBumpAllocation(); |
709 } | 709 } |
710 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { | 710 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
711 if (!it.page()->embedder_allocated()) { | 711 if (!it.page()->is_image_page()) { |
712 it.page()->WriteProtect(read_only); | 712 it.page()->WriteProtect(read_only); |
713 } | 713 } |
714 } | 714 } |
715 } | 715 } |
716 | 716 |
717 | 717 |
718 #ifndef PRODUCT | 718 #ifndef PRODUCT |
719 void PageSpace::PrintToJSONObject(JSONObject* object) const { | 719 void PageSpace::PrintToJSONObject(JSONObject* object) const { |
720 if (!FLAG_support_service) { | 720 if (!FLAG_support_service) { |
721 return; | 721 return; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 | 821 |
822 | 822 |
823 void PageSpace::WriteProtectCode(bool read_only) { | 823 void PageSpace::WriteProtectCode(bool read_only) { |
824 if (FLAG_write_protect_code) { | 824 if (FLAG_write_protect_code) { |
825 MutexLocker ml(pages_lock_); | 825 MutexLocker ml(pages_lock_); |
826 NoSafepointScope no_safepoint; | 826 NoSafepointScope no_safepoint; |
827 // No need to go through all of the data pages first. | 827 // No need to go through all of the data pages first. |
828 HeapPage* page = exec_pages_; | 828 HeapPage* page = exec_pages_; |
829 while (page != NULL) { | 829 while (page != NULL) { |
830 ASSERT(page->type() == HeapPage::kExecutable); | 830 ASSERT(page->type() == HeapPage::kExecutable); |
831 if (!page->embedder_allocated()) { | 831 if (!page->is_image_page()) { |
832 page->WriteProtect(read_only); | 832 page->WriteProtect(read_only); |
833 } | 833 } |
834 page = page->next(); | 834 page = page->next(); |
835 } | 835 } |
836 page = large_pages_; | 836 page = large_pages_; |
837 while (page != NULL) { | 837 while (page != NULL) { |
838 if (page->type() == HeapPage::kExecutable && | 838 if (page->type() == HeapPage::kExecutable && !page->is_image_page()) { |
839 !page->embedder_allocated()) { | |
840 page->WriteProtect(read_only); | 839 page->WriteProtect(read_only); |
841 } | 840 } |
842 page = page->next(); | 841 page = page->next(); |
843 } | 842 } |
844 } | 843 } |
845 } | 844 } |
846 | 845 |
847 | 846 |
848 void PageSpace::MarkSweep(bool invoke_api_callbacks) { | 847 void PageSpace::MarkSweep(bool invoke_api_callbacks) { |
849 Thread* thread = Thread::Current(); | 848 Thread* thread = Thread::Current(); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 AtomicOperations::IncrementBy(&(usage_.used_in_words), | 1090 AtomicOperations::IncrementBy(&(usage_.used_in_words), |
1092 (size >> kWordSizeLog2)); | 1091 (size >> kWordSizeLog2)); |
1093 return result; | 1092 return result; |
1094 } | 1093 } |
1095 result = TryAllocateDataBumpLocked(size, growth_policy); | 1094 result = TryAllocateDataBumpLocked(size, growth_policy); |
1096 if (result != 0) return result; | 1095 if (result != 0) return result; |
1097 return TryAllocateDataLocked(size, growth_policy); | 1096 return TryAllocateDataLocked(size, growth_policy); |
1098 } | 1097 } |
1099 | 1098 |
1100 | 1099 |
1101 void PageSpace::SetupExternalPage(void* pointer, | 1100 void PageSpace::SetupImagePage(void* pointer, uword size, bool is_executable) { |
1102 uword size, | |
1103 bool is_executable) { | |
1104 // Setup a HeapPage so precompiled Instructions can be traversed. | 1101 // Setup a HeapPage so precompiled Instructions can be traversed. |
1105 // Instructions are contiguous at [pointer, pointer + size). HeapPage | 1102 // Instructions are contiguous at [pointer, pointer + size). HeapPage |
1106 // expects to find objects at [memory->start() + ObjectStartOffset, | 1103 // expects to find objects at [memory->start() + ObjectStartOffset, |
1107 // memory->end()). | 1104 // memory->end()). |
1108 uword offset = HeapPage::ObjectStartOffset(); | 1105 uword offset = HeapPage::ObjectStartOffset(); |
1109 pointer = reinterpret_cast<void*>(reinterpret_cast<uword>(pointer) - offset); | 1106 pointer = reinterpret_cast<void*>(reinterpret_cast<uword>(pointer) - offset); |
1110 size += offset; | 1107 size += offset; |
1111 | 1108 |
1112 VirtualMemory* memory = VirtualMemory::ForExternalPage(pointer, size); | 1109 VirtualMemory* memory = VirtualMemory::ForImagePage(pointer, size); |
1113 ASSERT(memory != NULL); | 1110 ASSERT(memory != NULL); |
1114 HeapPage* page = reinterpret_cast<HeapPage*>(malloc(sizeof(HeapPage))); | 1111 HeapPage* page = reinterpret_cast<HeapPage*>(malloc(sizeof(HeapPage))); |
1115 page->memory_ = memory; | 1112 page->memory_ = memory; |
1116 page->next_ = NULL; | 1113 page->next_ = NULL; |
1117 page->object_end_ = memory->end(); | 1114 page->object_end_ = memory->end(); |
1118 | 1115 |
1119 MutexLocker ml(pages_lock_); | 1116 MutexLocker ml(pages_lock_); |
1120 HeapPage **first, **tail; | 1117 HeapPage **first, **tail; |
1121 if (is_executable) { | 1118 if (is_executable) { |
1122 ASSERT(Utils::IsAligned(pointer, OS::PreferredCodeAlignment())); | 1119 ASSERT(Utils::IsAligned(pointer, OS::PreferredCodeAlignment())); |
1123 page->type_ = HeapPage::kExecutable; | 1120 page->type_ = HeapPage::kExecutable; |
1124 first = &exec_pages_; | 1121 first = &exec_pages_; |
1125 tail = &exec_pages_tail_; | 1122 tail = &exec_pages_tail_; |
1126 } else { | 1123 } else { |
1127 page->type_ = HeapPage::kData; | 1124 page->type_ = HeapPage::kData; |
1128 first = &pages_; | 1125 first = &pages_; |
1129 tail = &pages_tail_; | 1126 tail = &pages_tail_; |
1130 } | 1127 } |
1131 if (*first == NULL) { | 1128 if (*first == NULL) { |
1132 *first = page; | 1129 *first = page; |
1133 } else { | 1130 } else { |
1134 if (is_executable && FLAG_write_protect_code && | 1131 if (is_executable && FLAG_write_protect_code && !(*tail)->is_image_page()) { |
1135 !(*tail)->embedder_allocated()) { | |
1136 (*tail)->WriteProtect(false); | 1132 (*tail)->WriteProtect(false); |
1137 } | 1133 } |
1138 (*tail)->set_next(page); | 1134 (*tail)->set_next(page); |
1139 if (is_executable && FLAG_write_protect_code && | 1135 if (is_executable && FLAG_write_protect_code && !(*tail)->is_image_page()) { |
1140 !(*tail)->embedder_allocated()) { | |
1141 (*tail)->WriteProtect(true); | 1136 (*tail)->WriteProtect(true); |
1142 } | 1137 } |
1143 } | 1138 } |
1144 (*tail) = page; | 1139 (*tail) = page; |
1145 } | 1140 } |
1146 | 1141 |
1147 | 1142 |
1148 PageSpaceController::PageSpaceController(Heap* heap, | 1143 PageSpaceController::PageSpaceController(Heap* heap, |
1149 int heap_growth_ratio, | 1144 int heap_growth_ratio, |
1150 int heap_growth_max, | 1145 int heap_growth_max, |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 return 0; | 1295 return 0; |
1301 } else { | 1296 } else { |
1302 ASSERT(total_time >= gc_time); | 1297 ASSERT(total_time >= gc_time); |
1303 int result = static_cast<int>( | 1298 int result = static_cast<int>( |
1304 (static_cast<double>(gc_time) / static_cast<double>(total_time)) * 100); | 1299 (static_cast<double>(gc_time) / static_cast<double>(total_time)) * 100); |
1305 return result; | 1300 return result; |
1306 } | 1301 } |
1307 } | 1302 } |
1308 | 1303 |
1309 } // namespace dart | 1304 } // namespace dart |
OLD | NEW |