| 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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 } | 218 } |
| 219 } | 219 } |
| 220 | 220 |
| 221 | 221 |
| 222 uword PageSpace::TryAllocate(intptr_t size, | 222 uword PageSpace::TryAllocate(intptr_t size, |
| 223 HeapPage::PageType type, | 223 HeapPage::PageType type, |
| 224 GrowthPolicy growth_policy) { | 224 GrowthPolicy growth_policy) { |
| 225 ASSERT(size >= kObjectAlignment); | 225 ASSERT(size >= kObjectAlignment); |
| 226 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 226 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 227 uword result = 0; | 227 uword result = 0; |
| 228 SpaceUsage after_allocation = usage_; | 228 intptr_t after_capacity_in_words = usage_.capacity_in_words; |
| 229 after_allocation.used_in_words += size >> kWordSizeLog2; | |
| 230 if (size < kAllocatablePageSize) { | 229 if (size < kAllocatablePageSize) { |
| 231 const bool is_protected = (type == HeapPage::kExecutable) | 230 const bool is_protected = (type == HeapPage::kExecutable) |
| 232 && FLAG_write_protect_code; | 231 && FLAG_write_protect_code; |
| 233 result = freelist_[type].TryAllocate(size, is_protected); | 232 result = freelist_[type].TryAllocate(size, is_protected); |
| 234 if (result == 0) { | 233 if (result == 0) { |
| 235 // Can we grow by one page? | 234 // Can we grow by one page? |
| 236 after_allocation.capacity_in_words += kPageSizeInWords; | 235 after_capacity_in_words += kPageSizeInWords; |
| 237 if ((!page_space_controller_.NeedsGarbageCollection(after_allocation) || | 236 const bool needs_gc = page_space_controller_.NeedsGarbageCollection( |
| 238 growth_policy == kForceGrowth) && | 237 after_capacity_in_words); |
| 238 if ((!needs_gc || growth_policy == kForceGrowth) && |
| 239 CanIncreaseCapacityInWords(kPageSizeInWords)) { | 239 CanIncreaseCapacityInWords(kPageSizeInWords)) { |
| 240 HeapPage* page = AllocatePage(type); | 240 HeapPage* page = AllocatePage(type); |
| 241 ASSERT(page != NULL); | 241 ASSERT(page != NULL); |
| 242 // Start of the newly allocated page is the allocated object. | 242 // Start of the newly allocated page is the allocated object. |
| 243 result = page->object_start(); | 243 result = page->object_start(); |
| 244 // Enqueue the remainder in the free list. | 244 // Enqueue the remainder in the free list. |
| 245 uword free_start = result + size; | 245 uword free_start = result + size; |
| 246 intptr_t free_size = page->object_end() - free_start; | 246 intptr_t free_size = page->object_end() - free_start; |
| 247 if (free_size > 0) { | 247 if (free_size > 0) { |
| 248 freelist_[type].Free(free_start, free_size); | 248 freelist_[type].Free(free_start, free_size); |
| 249 } | 249 } |
| 250 } | 250 } |
| 251 } | 251 } |
| 252 } else { | 252 } else { |
| 253 // Large page allocation. | 253 // Large page allocation. |
| 254 intptr_t page_size_in_words = LargePageSizeInWordsFor(size); | 254 intptr_t page_size_in_words = LargePageSizeInWordsFor(size); |
| 255 if ((page_size_in_words << kWordSizeLog2) < size) { | 255 if ((page_size_in_words << kWordSizeLog2) < size) { |
| 256 // On overflow we fail to allocate. | 256 // On overflow we fail to allocate. |
| 257 return 0; | 257 return 0; |
| 258 } | 258 } |
| 259 after_allocation.capacity_in_words += page_size_in_words; | 259 after_capacity_in_words += page_size_in_words; |
| 260 if ((!page_space_controller_.NeedsGarbageCollection(after_allocation) || | 260 const bool needs_gc = page_space_controller_.NeedsGarbageCollection( |
| 261 growth_policy == kForceGrowth) && | 261 after_capacity_in_words); |
| 262 if ((!needs_gc || growth_policy == kForceGrowth) && |
| 262 CanIncreaseCapacityInWords(page_size_in_words)) { | 263 CanIncreaseCapacityInWords(page_size_in_words)) { |
| 263 HeapPage* page = AllocateLargePage(size, type); | 264 HeapPage* page = AllocateLargePage(size, type); |
| 264 if (page != NULL) { | 265 if (page != NULL) { |
| 265 result = page->object_start(); | 266 result = page->object_start(); |
| 266 } | 267 } |
| 267 } | 268 } |
| 268 } | 269 } |
| 269 if (result != 0) { | 270 if (result != 0) { |
| 270 usage_ = after_allocation; | 271 usage_.used_in_words += (size >> kWordSizeLog2); |
| 272 usage_.capacity_in_words = after_capacity_in_words; |
| 271 if (FLAG_compiler_stats && (type == HeapPage::kExecutable)) { | 273 if (FLAG_compiler_stats && (type == HeapPage::kExecutable)) { |
| 272 CompilerStats::code_allocated += size; | 274 CompilerStats::code_allocated += size; |
| 273 } | 275 } |
| 274 } | 276 } |
| 275 ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset); | 277 ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset); |
| 276 return result; | 278 return result; |
| 277 } | 279 } |
| 278 | 280 |
| 279 | 281 |
| 280 void PageSpace::AllocateExternal(intptr_t size) { | 282 void PageSpace::AllocateExternal(intptr_t size) { |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 desired_utilization_((100.0 - heap_growth_ratio) / 100.0), | 580 desired_utilization_((100.0 - heap_growth_ratio) / 100.0), |
| 579 heap_growth_max_(heap_growth_max), | 581 heap_growth_max_(heap_growth_max), |
| 580 garbage_collection_time_ratio_(garbage_collection_time_ratio), | 582 garbage_collection_time_ratio_(garbage_collection_time_ratio), |
| 581 last_code_collection_in_us_(OS::GetCurrentTimeMicros()) { | 583 last_code_collection_in_us_(OS::GetCurrentTimeMicros()) { |
| 582 } | 584 } |
| 583 | 585 |
| 584 | 586 |
| 585 PageSpaceController::~PageSpaceController() {} | 587 PageSpaceController::~PageSpaceController() {} |
| 586 | 588 |
| 587 | 589 |
| 588 bool PageSpaceController::NeedsGarbageCollection(SpaceUsage after) const { | 590 bool PageSpaceController::NeedsGarbageCollection( |
| 591 intptr_t after_capacity_in_words) const { |
| 589 if (!is_enabled_) { | 592 if (!is_enabled_) { |
| 590 return false; | 593 return false; |
| 591 } | 594 } |
| 592 if (heap_growth_ratio_ == 100) { | 595 if (heap_growth_ratio_ == 100) { |
| 593 return false; | 596 return false; |
| 594 } | 597 } |
| 595 intptr_t capacity_increase_in_words = | 598 intptr_t capacity_increase_in_words = |
| 596 after.capacity_in_words - last_usage_.capacity_in_words; | 599 after_capacity_in_words - last_usage_.capacity_in_words; |
| 597 ASSERT(capacity_increase_in_words >= 0); | 600 ASSERT(capacity_increase_in_words >= 0); |
| 598 capacity_increase_in_words = | 601 capacity_increase_in_words = |
| 599 Utils::RoundUp(capacity_increase_in_words, PageSpace::kPageSizeInWords); | 602 Utils::RoundUp(capacity_increase_in_words, PageSpace::kPageSizeInWords); |
| 600 intptr_t capacity_increase_in_pages = | 603 intptr_t capacity_increase_in_pages = |
| 601 capacity_increase_in_words / PageSpace::kPageSizeInWords; | 604 capacity_increase_in_words / PageSpace::kPageSizeInWords; |
| 602 double multiplier = 1.0; | 605 double multiplier = 1.0; |
| 603 // To avoid waste, the first GC should be triggered before too long. After | 606 // To avoid waste, the first GC should be triggered before too long. After |
| 604 // kInitialTimeoutSeconds, gradually lower the capacity limit. | 607 // kInitialTimeoutSeconds, gradually lower the capacity limit. |
| 605 static const double kInitialTimeoutSeconds = 1.00; | 608 static const double kInitialTimeoutSeconds = 1.00; |
| 606 if (history_.IsEmpty()) { | 609 if (history_.IsEmpty()) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 return 0; | 684 return 0; |
| 682 } else { | 685 } else { |
| 683 ASSERT(total_time >= gc_time); | 686 ASSERT(total_time >= gc_time); |
| 684 int result= static_cast<int>((static_cast<double>(gc_time) / | 687 int result= static_cast<int>((static_cast<double>(gc_time) / |
| 685 static_cast<double>(total_time)) * 100); | 688 static_cast<double>(total_time)) * 100); |
| 686 return result; | 689 return result; |
| 687 } | 690 } |
| 688 } | 691 } |
| 689 | 692 |
| 690 } // namespace dart | 693 } // namespace dart |
| OLD | NEW |