| 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 |