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/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/compiler_stats.h" | 8 #include "vm/compiler_stats.h" |
9 #include "vm/gc_marker.h" | 9 #include "vm/gc_marker.h" |
10 #include "vm/gc_sweeper.h" | 10 #include "vm/gc_sweeper.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 memory->Commit(is_executable); | 36 memory->Commit(is_executable); |
37 | 37 |
38 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); | 38 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); |
39 result->memory_ = memory; | 39 result->memory_ = memory; |
40 result->next_ = NULL; | 40 result->next_ = NULL; |
41 result->executable_ = is_executable; | 41 result->executable_ = is_executable; |
42 return result; | 42 return result; |
43 } | 43 } |
44 | 44 |
45 | 45 |
46 HeapPage* HeapPage::Allocate(intptr_t size, PageType type) { | 46 HeapPage* HeapPage::Allocate(intptr_t size_in_words, PageType type) { |
47 VirtualMemory* memory = VirtualMemory::Reserve(size); | 47 VirtualMemory* memory = |
| 48 VirtualMemory::Reserve(size_in_words << kWordSizeLog2); |
48 return Initialize(memory, type); | 49 return Initialize(memory, type); |
49 } | 50 } |
50 | 51 |
51 | 52 |
52 void HeapPage::Deallocate() { | 53 void HeapPage::Deallocate() { |
53 // The memory for this object will become unavailable after the delete below. | 54 // The memory for this object will become unavailable after the delete below. |
54 delete memory_; | 55 delete memory_; |
55 } | 56 } |
56 | 57 |
57 | 58 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 FLAG_heap_growth_time_ratio) { | 128 FLAG_heap_growth_time_ratio) { |
128 } | 129 } |
129 | 130 |
130 | 131 |
131 PageSpace::~PageSpace() { | 132 PageSpace::~PageSpace() { |
132 FreePages(pages_); | 133 FreePages(pages_); |
133 FreePages(large_pages_); | 134 FreePages(large_pages_); |
134 } | 135 } |
135 | 136 |
136 | 137 |
137 intptr_t PageSpace::LargePageSizeFor(intptr_t size) { | 138 intptr_t PageSpace::LargePageSizeInWordsFor(intptr_t size) { |
138 intptr_t page_size = Utils::RoundUp(size + HeapPage::ObjectStartOffset(), | 139 intptr_t page_size = Utils::RoundUp(size + HeapPage::ObjectStartOffset(), |
139 VirtualMemory::PageSize()); | 140 VirtualMemory::PageSize()); |
140 return page_size; | 141 return page_size >> kWordSizeLog2; |
141 } | 142 } |
142 | 143 |
143 | 144 |
144 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) { | 145 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) { |
145 HeapPage* page = HeapPage::Allocate(kPageSize, type); | 146 HeapPage* page = HeapPage::Allocate(kPageSizeInWords, type); |
146 if (pages_ == NULL) { | 147 if (pages_ == NULL) { |
147 pages_ = page; | 148 pages_ = page; |
148 } else { | 149 } else { |
149 pages_tail_->set_next(page); | 150 pages_tail_->set_next(page); |
150 } | 151 } |
151 pages_tail_ = page; | 152 pages_tail_ = page; |
152 capacity_in_words_ += (kPageSize >> kWordSizeLog2); | 153 capacity_in_words_ += kPageSizeInWords; |
153 page->set_object_end(page->memory_->end()); | 154 page->set_object_end(page->memory_->end()); |
154 return page; | 155 return page; |
155 } | 156 } |
156 | 157 |
157 | 158 |
158 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) { | 159 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) { |
159 intptr_t page_size = LargePageSizeFor(size); | 160 intptr_t page_size_in_words = LargePageSizeInWordsFor(size); |
160 HeapPage* page = HeapPage::Allocate(page_size, type); | 161 HeapPage* page = HeapPage::Allocate(page_size_in_words, type); |
161 page->set_next(large_pages_); | 162 page->set_next(large_pages_); |
162 large_pages_ = page; | 163 large_pages_ = page; |
163 capacity_in_words_ += (page_size >> kWordSizeLog2); | 164 capacity_in_words_ += page_size_in_words; |
164 // Only one object in this page. | 165 // Only one object in this page. |
165 page->set_object_end(page->object_start() + size); | 166 page->set_object_end(page->object_start() + size); |
166 return page; | 167 return page; |
167 } | 168 } |
168 | 169 |
169 | 170 |
170 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) { | 171 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) { |
171 capacity_in_words_ -= (page->memory_->size() >> kWordSizeLog2); | 172 capacity_in_words_ -= (page->memory_->size() >> kWordSizeLog2); |
172 // Remove the page from the list. | 173 // Remove the page from the list. |
173 if (previous_page != NULL) { | 174 if (previous_page != NULL) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 HeapPage::PageType type, | 210 HeapPage::PageType type, |
210 GrowthPolicy growth_policy) { | 211 GrowthPolicy growth_policy) { |
211 ASSERT(size >= kObjectAlignment); | 212 ASSERT(size >= kObjectAlignment); |
212 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 213 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
213 uword result = 0; | 214 uword result = 0; |
214 if (size < kAllocatablePageSize) { | 215 if (size < kAllocatablePageSize) { |
215 result = freelist_[type].TryAllocate(size); | 216 result = freelist_[type].TryAllocate(size); |
216 if ((result == 0) && | 217 if ((result == 0) && |
217 (page_space_controller_.CanGrowPageSpace(size) || | 218 (page_space_controller_.CanGrowPageSpace(size) || |
218 growth_policy == kForceGrowth) && | 219 growth_policy == kForceGrowth) && |
219 CanIncreaseCapacityInWords(kPageSize >> kWordSizeLog2)) { | 220 CanIncreaseCapacityInWords(kPageSizeInWords)) { |
220 HeapPage* page = AllocatePage(type); | 221 HeapPage* page = AllocatePage(type); |
221 ASSERT(page != NULL); | 222 ASSERT(page != NULL); |
222 // Start of the newly allocated page is the allocated object. | 223 // Start of the newly allocated page is the allocated object. |
223 result = page->object_start(); | 224 result = page->object_start(); |
224 // Enqueue the remainder in the free list. | 225 // Enqueue the remainder in the free list. |
225 uword free_start = result + size; | 226 uword free_start = result + size; |
226 intptr_t free_size = page->object_end() - free_start; | 227 intptr_t free_size = page->object_end() - free_start; |
227 if (free_size > 0) { | 228 if (free_size > 0) { |
228 freelist_[type].Free(free_start, free_size); | 229 freelist_[type].Free(free_start, free_size); |
229 } | 230 } |
230 } | 231 } |
231 } else { | 232 } else { |
232 // Large page allocation. | 233 // Large page allocation. |
233 intptr_t page_size = LargePageSizeFor(size); | 234 intptr_t page_size_in_words = LargePageSizeInWordsFor(size); |
234 if (page_size < size) { | 235 if ((page_size_in_words << kWordSizeLog2) < size) { |
235 // On overflow we fail to allocate. | 236 // On overflow we fail to allocate. |
236 return 0; | 237 return 0; |
237 } | 238 } |
238 if ((page_space_controller_.CanGrowPageSpace(size) || | 239 if ((page_space_controller_.CanGrowPageSpace(size) || |
239 growth_policy == kForceGrowth) && | 240 growth_policy == kForceGrowth) && |
240 CanIncreaseCapacityInWords(page_size >> kWordSizeLog2)) { | 241 CanIncreaseCapacityInWords(page_size_in_words)) { |
241 HeapPage* page = AllocateLargePage(size, type); | 242 HeapPage* page = AllocateLargePage(size, type); |
242 if (page != NULL) { | 243 if (page != NULL) { |
243 result = page->object_start(); | 244 result = page->object_start(); |
244 } | 245 } |
245 } | 246 } |
246 } | 247 } |
247 if (result != 0) { | 248 if (result != 0) { |
248 used_in_words_ += (size >> kWordSizeLog2); | 249 used_in_words_ += (size >> kWordSizeLog2); |
249 if (FLAG_compiler_stats && (type == HeapPage::kExecutable)) { | 250 if (FLAG_compiler_stats && (type == HeapPage::kExecutable)) { |
250 CompilerStats::code_allocated += size; | 251 CompilerStats::code_allocated += size; |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 heap_growth_rate_(heap_growth_rate), | 562 heap_growth_rate_(heap_growth_rate), |
562 garbage_collection_time_ratio_(garbage_collection_time_ratio), | 563 garbage_collection_time_ratio_(garbage_collection_time_ratio), |
563 last_code_collection_in_us_(OS::GetCurrentTimeMicros()) { | 564 last_code_collection_in_us_(OS::GetCurrentTimeMicros()) { |
564 } | 565 } |
565 | 566 |
566 | 567 |
567 PageSpaceController::~PageSpaceController() {} | 568 PageSpaceController::~PageSpaceController() {} |
568 | 569 |
569 | 570 |
570 bool PageSpaceController::CanGrowPageSpace(intptr_t size_in_bytes) { | 571 bool PageSpaceController::CanGrowPageSpace(intptr_t size_in_bytes) { |
571 size_in_bytes = Utils::RoundUp(size_in_bytes, PageSpace::kPageSize); | 572 intptr_t size_in_words = size_in_bytes >> kWordSizeLog2; |
572 intptr_t size_in_pages = size_in_bytes / PageSpace::kPageSize; | 573 size_in_words = Utils::RoundUp(size_in_words, PageSpace::kPageSizeInWords); |
| 574 intptr_t size_in_pages = size_in_words / PageSpace::kPageSizeInWords; |
573 if (!is_enabled_) { | 575 if (!is_enabled_) { |
574 return true; | 576 return true; |
575 } | 577 } |
576 if (heap_growth_ratio_ == 100) { | 578 if (heap_growth_ratio_ == 100) { |
577 return true; | 579 return true; |
578 } | 580 } |
579 if (grow_heap_ <= 0) { | 581 if (grow_heap_ <= 0) { |
580 return false; | 582 return false; |
581 } | 583 } |
582 grow_heap_ -= size_in_pages; | 584 grow_heap_ -= size_in_pages; |
(...skipping 20 matching lines...) Expand all Loading... |
603 (garbage_collection_time_fraction <= garbage_collection_time_ratio_); | 605 (garbage_collection_time_fraction <= garbage_collection_time_ratio_); |
604 | 606 |
605 Heap* heap = Isolate::Current()->heap(); | 607 Heap* heap = Isolate::Current()->heap(); |
606 if (enough_free_space && enough_free_time) { | 608 if (enough_free_space && enough_free_time) { |
607 grow_heap_ = 0; | 609 grow_heap_ = 0; |
608 } else { | 610 } else { |
609 intptr_t growth_target = static_cast<intptr_t>( | 611 intptr_t growth_target = static_cast<intptr_t>( |
610 used_after_in_words / desired_utilization_); | 612 used_after_in_words / desired_utilization_); |
611 intptr_t growth_in_words = Utils::RoundUp( | 613 intptr_t growth_in_words = Utils::RoundUp( |
612 growth_target - used_after_in_words, | 614 growth_target - used_after_in_words, |
613 PageSpace::kPageSize >> kWordSizeLog2); | 615 PageSpace::kPageSizeInWords); |
614 int growth_in_pages = | 616 int growth_in_pages = |
615 growth_in_words / (PageSpace::kPageSize >> kWordSizeLog2); | 617 growth_in_words / PageSpace::kPageSizeInWords; |
616 grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_); | 618 grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_); |
617 heap->RecordData(PageSpace::kPageGrowth, growth_in_pages); | 619 heap->RecordData(PageSpace::kPageGrowth, growth_in_pages); |
618 } | 620 } |
619 heap->RecordData(PageSpace::kGarbageRatio, collected_garbage_ratio); | 621 heap->RecordData(PageSpace::kGarbageRatio, collected_garbage_ratio); |
620 heap->RecordData(PageSpace::kGCTimeFraction, | 622 heap->RecordData(PageSpace::kGCTimeFraction, |
621 garbage_collection_time_fraction); | 623 garbage_collection_time_fraction); |
622 heap->RecordData(PageSpace::kAllowedGrowth, grow_heap_); | 624 heap->RecordData(PageSpace::kAllowedGrowth, grow_heap_); |
623 } | 625 } |
624 | 626 |
625 | 627 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 return 0; | 662 return 0; |
661 } else { | 663 } else { |
662 ASSERT(total_time >= gc_time); | 664 ASSERT(total_time >= gc_time); |
663 int result= static_cast<int>((static_cast<double>(gc_time) / | 665 int result= static_cast<int>((static_cast<double>(gc_time) / |
664 static_cast<double>(total_time)) * 100); | 666 static_cast<double>(total_time)) * 100); |
665 return result; | 667 return result; |
666 } | 668 } |
667 } | 669 } |
668 | 670 |
669 } // namespace dart | 671 } // namespace dart |
OLD | NEW |