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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 } | 117 } |
118 | 118 |
119 | 119 |
120 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity_in_words) | 120 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity_in_words) |
121 : freelist_(), | 121 : freelist_(), |
122 heap_(heap), | 122 heap_(heap), |
123 pages_(NULL), | 123 pages_(NULL), |
124 pages_tail_(NULL), | 124 pages_tail_(NULL), |
125 large_pages_(NULL), | 125 large_pages_(NULL), |
126 max_capacity_in_words_(max_capacity_in_words), | 126 max_capacity_in_words_(max_capacity_in_words), |
| 127 capacity_in_words_(0), |
| 128 used_in_words_(0), |
| 129 external_in_words_(0), |
127 sweeping_(false), | 130 sweeping_(false), |
128 page_space_controller_(FLAG_heap_growth_space_ratio, | 131 page_space_controller_(FLAG_heap_growth_space_ratio, |
129 FLAG_heap_growth_rate, | 132 FLAG_heap_growth_rate, |
130 FLAG_heap_growth_time_ratio), | 133 FLAG_heap_growth_time_ratio), |
131 gc_time_micros_(0), | 134 gc_time_micros_(0), |
132 collections_(0) { | 135 collections_(0) { |
133 } | 136 } |
134 | 137 |
135 | 138 |
136 PageSpace::~PageSpace() { | 139 PageSpace::~PageSpace() { |
(...skipping 18 matching lines...) Expand all Loading... |
155 && FLAG_write_protect_code; | 158 && FLAG_write_protect_code; |
156 if (is_protected) { | 159 if (is_protected) { |
157 pages_tail_->WriteProtect(false); | 160 pages_tail_->WriteProtect(false); |
158 } | 161 } |
159 pages_tail_->set_next(page); | 162 pages_tail_->set_next(page); |
160 if (is_protected) { | 163 if (is_protected) { |
161 pages_tail_->WriteProtect(true); | 164 pages_tail_->WriteProtect(true); |
162 } | 165 } |
163 } | 166 } |
164 pages_tail_ = page; | 167 pages_tail_ = page; |
165 usage_.capacity_in_words += kPageSizeInWords; | 168 capacity_in_words_ += kPageSizeInWords; |
166 page->set_object_end(page->memory_->end()); | 169 page->set_object_end(page->memory_->end()); |
167 return page; | 170 return page; |
168 } | 171 } |
169 | 172 |
170 | 173 |
171 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) { | 174 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) { |
172 intptr_t page_size_in_words = LargePageSizeInWordsFor(size); | 175 intptr_t page_size_in_words = LargePageSizeInWordsFor(size); |
173 HeapPage* page = HeapPage::Allocate(page_size_in_words, type); | 176 HeapPage* page = HeapPage::Allocate(page_size_in_words, type); |
174 page->set_next(large_pages_); | 177 page->set_next(large_pages_); |
175 large_pages_ = page; | 178 large_pages_ = page; |
176 usage_.capacity_in_words += page_size_in_words; | 179 capacity_in_words_ += page_size_in_words; |
177 // Only one object in this page. | 180 // Only one object in this page. |
178 page->set_object_end(page->object_start() + size); | 181 page->set_object_end(page->object_start() + size); |
179 return page; | 182 return page; |
180 } | 183 } |
181 | 184 |
182 | 185 |
183 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) { | 186 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) { |
184 usage_.capacity_in_words -= (page->memory_->size() >> kWordSizeLog2); | 187 capacity_in_words_ -= (page->memory_->size() >> kWordSizeLog2); |
185 // Remove the page from the list. | 188 // Remove the page from the list. |
186 if (previous_page != NULL) { | 189 if (previous_page != NULL) { |
187 previous_page->set_next(page->next()); | 190 previous_page->set_next(page->next()); |
188 } else { | 191 } else { |
189 pages_ = page->next(); | 192 pages_ = page->next(); |
190 } | 193 } |
191 if (page == pages_tail_) { | 194 if (page == pages_tail_) { |
192 pages_tail_ = previous_page; | 195 pages_tail_ = previous_page; |
193 } | 196 } |
194 // TODO(iposva): Consider adding to a pool of empty pages. | 197 // TODO(iposva): Consider adding to a pool of empty pages. |
195 page->Deallocate(); | 198 page->Deallocate(); |
196 } | 199 } |
197 | 200 |
198 | 201 |
199 void PageSpace::FreeLargePage(HeapPage* page, HeapPage* previous_page) { | 202 void PageSpace::FreeLargePage(HeapPage* page, HeapPage* previous_page) { |
200 usage_.capacity_in_words -= (page->memory_->size() >> kWordSizeLog2); | 203 capacity_in_words_ -= (page->memory_->size() >> kWordSizeLog2); |
201 // Remove the page from the list. | 204 // Remove the page from the list. |
202 if (previous_page != NULL) { | 205 if (previous_page != NULL) { |
203 previous_page->set_next(page->next()); | 206 previous_page->set_next(page->next()); |
204 } else { | 207 } else { |
205 large_pages_ = page->next(); | 208 large_pages_ = page->next(); |
206 } | 209 } |
207 page->Deallocate(); | 210 page->Deallocate(); |
208 } | 211 } |
209 | 212 |
210 | 213 |
211 void PageSpace::FreePages(HeapPage* pages) { | 214 void PageSpace::FreePages(HeapPage* pages) { |
212 HeapPage* page = pages; | 215 HeapPage* page = pages; |
213 while (page != NULL) { | 216 while (page != NULL) { |
214 HeapPage* next = page->next(); | 217 HeapPage* next = page->next(); |
215 page->Deallocate(); | 218 page->Deallocate(); |
216 page = next; | 219 page = next; |
217 } | 220 } |
218 } | 221 } |
219 | 222 |
220 | 223 |
221 uword PageSpace::TryAllocate(intptr_t size, | 224 uword PageSpace::TryAllocate(intptr_t size, |
222 HeapPage::PageType type, | 225 HeapPage::PageType type, |
223 GrowthPolicy growth_policy) { | 226 GrowthPolicy growth_policy) { |
224 ASSERT(size >= kObjectAlignment); | 227 ASSERT(size >= kObjectAlignment); |
225 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 228 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
226 uword result = 0; | 229 uword result = 0; |
227 SpaceUsage after_allocation = usage_; | |
228 after_allocation.used_in_words += size >> kWordSizeLog2; | |
229 if (size < kAllocatablePageSize) { | 230 if (size < kAllocatablePageSize) { |
230 const bool is_protected = (type == HeapPage::kExecutable) | 231 const bool is_protected = (type == HeapPage::kExecutable) |
231 && FLAG_write_protect_code; | 232 && FLAG_write_protect_code; |
232 result = freelist_[type].TryAllocate(size, is_protected); | 233 result = freelist_[type].TryAllocate(size, is_protected); |
233 if (result == 0) { | 234 if ((result == 0) && |
234 // Can we grow by one page? | 235 (page_space_controller_.CanGrowPageSpace(size) || |
235 after_allocation.capacity_in_words += kPageSizeInWords; | 236 growth_policy == kForceGrowth) && |
236 if ((!page_space_controller_.NeedsGarbageCollection(after_allocation) || | 237 CanIncreaseCapacityInWords(kPageSizeInWords)) { |
237 growth_policy == kForceGrowth) && | 238 HeapPage* page = AllocatePage(type); |
238 CanIncreaseCapacityInWords(kPageSizeInWords)) { | 239 ASSERT(page != NULL); |
239 HeapPage* page = AllocatePage(type); | 240 // Start of the newly allocated page is the allocated object. |
240 ASSERT(page != NULL); | 241 result = page->object_start(); |
241 // Start of the newly allocated page is the allocated object. | 242 // Enqueue the remainder in the free list. |
242 result = page->object_start(); | 243 uword free_start = result + size; |
243 // Enqueue the remainder in the free list. | 244 intptr_t free_size = page->object_end() - free_start; |
244 uword free_start = result + size; | 245 if (free_size > 0) { |
245 intptr_t free_size = page->object_end() - free_start; | 246 freelist_[type].Free(free_start, free_size); |
246 if (free_size > 0) { | |
247 freelist_[type].Free(free_start, free_size); | |
248 } | |
249 } | 247 } |
250 } | 248 } |
251 } else { | 249 } else { |
252 // Large page allocation. | 250 // Large page allocation. |
253 intptr_t page_size_in_words = LargePageSizeInWordsFor(size); | 251 intptr_t page_size_in_words = LargePageSizeInWordsFor(size); |
254 if ((page_size_in_words << kWordSizeLog2) < size) { | 252 if ((page_size_in_words << kWordSizeLog2) < size) { |
255 // On overflow we fail to allocate. | 253 // On overflow we fail to allocate. |
256 return 0; | 254 return 0; |
257 } | 255 } |
258 after_allocation.capacity_in_words += page_size_in_words; | 256 if ((page_space_controller_.CanGrowPageSpace(size) || |
259 if ((!page_space_controller_.NeedsGarbageCollection(after_allocation) || | |
260 growth_policy == kForceGrowth) && | 257 growth_policy == kForceGrowth) && |
261 CanIncreaseCapacityInWords(page_size_in_words)) { | 258 CanIncreaseCapacityInWords(page_size_in_words)) { |
262 HeapPage* page = AllocateLargePage(size, type); | 259 HeapPage* page = AllocateLargePage(size, type); |
263 if (page != NULL) { | 260 if (page != NULL) { |
264 result = page->object_start(); | 261 result = page->object_start(); |
265 } | 262 } |
266 } | 263 } |
267 } | 264 } |
268 if (result != 0) { | 265 if (result != 0) { |
269 usage_ = after_allocation; | 266 used_in_words_ += (size >> kWordSizeLog2); |
270 if (FLAG_compiler_stats && (type == HeapPage::kExecutable)) { | 267 if (FLAG_compiler_stats && (type == HeapPage::kExecutable)) { |
271 CompilerStats::code_allocated += size; | 268 CompilerStats::code_allocated += size; |
272 } | 269 } |
273 } | 270 } |
274 ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset); | 271 ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset); |
275 return result; | 272 return result; |
276 } | 273 } |
277 | 274 |
278 | 275 |
279 void PageSpace::AllocateExternal(intptr_t size) { | 276 void PageSpace::AllocateExternal(intptr_t size) { |
280 intptr_t size_in_words = size >> kWordSizeLog2; | 277 intptr_t size_in_words = size >> kWordSizeLog2; |
281 usage_.external_in_words += size_in_words; | 278 external_in_words_ += size_in_words; |
282 // TODO(koda): Control growth. | |
283 } | 279 } |
284 | 280 |
285 | 281 |
286 void PageSpace::FreeExternal(intptr_t size) { | 282 void PageSpace::FreeExternal(intptr_t size) { |
287 intptr_t size_in_words = size >> kWordSizeLog2; | 283 intptr_t size_in_words = size >> kWordSizeLog2; |
288 usage_.external_in_words -= size_in_words; | 284 external_in_words_ -= size_in_words; |
289 } | 285 } |
290 | 286 |
291 | 287 |
292 bool PageSpace::Contains(uword addr) const { | 288 bool PageSpace::Contains(uword addr) const { |
293 HeapPage* page = pages_; | 289 HeapPage* page = pages_; |
294 while (page != NULL) { | 290 while (page != NULL) { |
295 if (page->Contains(addr)) { | 291 if (page->Contains(addr)) { |
296 return true; | 292 return true; |
297 } | 293 } |
298 page = page->next(); | 294 page = page->next(); |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 current_page = large_pages_; | 523 current_page = large_pages_; |
528 while (current_page != NULL) { | 524 while (current_page != NULL) { |
529 if (current_page->type() == HeapPage::kExecutable) { | 525 if (current_page->type() == HeapPage::kExecutable) { |
530 current_page->WriteProtect(false); | 526 current_page->WriteProtect(false); |
531 } | 527 } |
532 current_page = current_page->next(); | 528 current_page = current_page->next(); |
533 } | 529 } |
534 } | 530 } |
535 | 531 |
536 // Save old value before GCMarker visits the weak persistent handles. | 532 // Save old value before GCMarker visits the weak persistent handles. |
537 SpaceUsage usage_before = usage_; | 533 intptr_t external_before_in_words = external_in_words_; |
538 usage_.used_in_words = 0; | |
539 | 534 |
540 // Mark all reachable old-gen objects. | 535 // Mark all reachable old-gen objects. |
541 bool collect_code = FLAG_collect_code && ShouldCollectCode(); | 536 bool collect_code = FLAG_collect_code && ShouldCollectCode(); |
542 GCMarker marker(heap_); | 537 GCMarker marker(heap_); |
543 marker.MarkObjects(isolate, this, invoke_api_callbacks, collect_code); | 538 marker.MarkObjects(isolate, this, invoke_api_callbacks, collect_code); |
544 | 539 |
545 int64_t mid1 = OS::GetCurrentTimeMicros(); | 540 int64_t mid1 = OS::GetCurrentTimeMicros(); |
546 | 541 |
547 // Reset the bump allocation page to unused. | 542 // Reset the bump allocation page to unused. |
548 // Reset the freelists and setup sweeping. | 543 // Reset the freelists and setup sweeping. |
549 freelist_[HeapPage::kData].Reset(); | 544 freelist_[HeapPage::kData].Reset(); |
550 freelist_[HeapPage::kExecutable].Reset(); | 545 freelist_[HeapPage::kExecutable].Reset(); |
551 | 546 |
552 int64_t mid2 = OS::GetCurrentTimeMicros(); | 547 int64_t mid2 = OS::GetCurrentTimeMicros(); |
553 | 548 |
554 GCSweeper sweeper(heap_); | 549 GCSweeper sweeper(heap_); |
| 550 intptr_t used_in_words = 0; |
555 | 551 |
556 HeapPage* prev_page = NULL; | 552 HeapPage* prev_page = NULL; |
557 HeapPage* page = pages_; | 553 HeapPage* page = pages_; |
558 while (page != NULL) { | 554 while (page != NULL) { |
559 HeapPage* next_page = page->next(); | 555 HeapPage* next_page = page->next(); |
560 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]); | 556 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]); |
561 if (page_in_use == 0) { | 557 if (page_in_use == 0) { |
562 FreePage(page, prev_page); | 558 FreePage(page, prev_page); |
563 } else { | 559 } else { |
564 usage_.used_in_words += (page_in_use >> kWordSizeLog2); | 560 used_in_words += (page_in_use >> kWordSizeLog2); |
565 prev_page = page; | 561 prev_page = page; |
566 } | 562 } |
567 // Advance to the next page. | 563 // Advance to the next page. |
568 page = next_page; | 564 page = next_page; |
569 } | 565 } |
570 | 566 |
571 int64_t mid3 = OS::GetCurrentTimeMicros(); | 567 int64_t mid3 = OS::GetCurrentTimeMicros(); |
572 | 568 |
573 prev_page = NULL; | 569 prev_page = NULL; |
574 page = large_pages_; | 570 page = large_pages_; |
575 while (page != NULL) { | 571 while (page != NULL) { |
576 intptr_t page_in_use = sweeper.SweepLargePage(page); | 572 intptr_t page_in_use = sweeper.SweepLargePage(page); |
577 HeapPage* next_page = page->next(); | 573 HeapPage* next_page = page->next(); |
578 if (page_in_use == 0) { | 574 if (page_in_use == 0) { |
579 FreeLargePage(page, prev_page); | 575 FreeLargePage(page, prev_page); |
580 } else { | 576 } else { |
581 usage_.used_in_words += (page_in_use >> kWordSizeLog2); | 577 used_in_words += (page_in_use >> kWordSizeLog2); |
582 prev_page = page; | 578 prev_page = page; |
583 } | 579 } |
584 // Advance to the next page. | 580 // Advance to the next page. |
585 page = next_page; | 581 page = next_page; |
586 } | 582 } |
587 | 583 |
588 if (FLAG_write_protect_code) { | 584 if (FLAG_write_protect_code) { |
589 // Make code pages read-only. | 585 // Make code pages read-only. |
590 HeapPage* current_page = pages_; | 586 HeapPage* current_page = pages_; |
591 while (current_page != NULL) { | 587 while (current_page != NULL) { |
592 if (current_page->type() == HeapPage::kExecutable) { | 588 if (current_page->type() == HeapPage::kExecutable) { |
593 current_page->WriteProtect(true); | 589 current_page->WriteProtect(true); |
594 } | 590 } |
595 current_page = current_page->next(); | 591 current_page = current_page->next(); |
596 } | 592 } |
597 current_page = large_pages_; | 593 current_page = large_pages_; |
598 while (current_page != NULL) { | 594 while (current_page != NULL) { |
599 if (current_page->type() == HeapPage::kExecutable) { | 595 if (current_page->type() == HeapPage::kExecutable) { |
600 current_page->WriteProtect(true); | 596 current_page->WriteProtect(true); |
601 } | 597 } |
602 current_page = current_page->next(); | 598 current_page = current_page->next(); |
603 } | 599 } |
604 } | 600 } |
605 | 601 |
| 602 // Record data and print if requested. |
| 603 intptr_t used_before_in_words = used_in_words_; |
| 604 used_in_words_ = used_in_words; |
| 605 |
606 int64_t end = OS::GetCurrentTimeMicros(); | 606 int64_t end = OS::GetCurrentTimeMicros(); |
607 | 607 |
608 // Record signals for growth control. Include size of external allocations. | 608 // Record signals for growth control. Include size of external allocations. |
609 page_space_controller_.EvaluateGarbageCollection(usage_before, usage_, | 609 page_space_controller_.EvaluateGarbageCollection( |
610 start, end); | 610 used_before_in_words + external_before_in_words, |
| 611 used_in_words + external_in_words_, |
| 612 start, end); |
611 | 613 |
612 heap_->RecordTime(kMarkObjects, mid1 - start); | 614 heap_->RecordTime(kMarkObjects, mid1 - start); |
613 heap_->RecordTime(kResetFreeLists, mid2 - mid1); | 615 heap_->RecordTime(kResetFreeLists, mid2 - mid1); |
614 heap_->RecordTime(kSweepPages, mid3 - mid2); | 616 heap_->RecordTime(kSweepPages, mid3 - mid2); |
615 heap_->RecordTime(kSweepLargePages, end - mid3); | 617 heap_->RecordTime(kSweepLargePages, end - mid3); |
616 | 618 |
617 if (FLAG_print_free_list_after_gc) { | 619 if (FLAG_print_free_list_after_gc) { |
618 OS::Print("Data Freelist (after GC):\n"); | 620 OS::Print("Data Freelist (after GC):\n"); |
619 freelist_[HeapPage::kData].Print(); | 621 freelist_[HeapPage::kData].Print(); |
620 OS::Print("Executable Freelist (after GC):\n"); | 622 OS::Print("Executable Freelist (after GC):\n"); |
(...skipping 21 matching lines...) Expand all Loading... |
642 desired_utilization_((100.0 - heap_growth_ratio) / 100.0), | 644 desired_utilization_((100.0 - heap_growth_ratio) / 100.0), |
643 heap_growth_rate_(heap_growth_rate), | 645 heap_growth_rate_(heap_growth_rate), |
644 garbage_collection_time_ratio_(garbage_collection_time_ratio), | 646 garbage_collection_time_ratio_(garbage_collection_time_ratio), |
645 last_code_collection_in_us_(OS::GetCurrentTimeMicros()) { | 647 last_code_collection_in_us_(OS::GetCurrentTimeMicros()) { |
646 } | 648 } |
647 | 649 |
648 | 650 |
649 PageSpaceController::~PageSpaceController() {} | 651 PageSpaceController::~PageSpaceController() {} |
650 | 652 |
651 | 653 |
652 bool PageSpaceController::NeedsGarbageCollection(SpaceUsage after) const { | 654 bool PageSpaceController::CanGrowPageSpace(intptr_t size_in_bytes) { |
| 655 intptr_t size_in_words = size_in_bytes >> kWordSizeLog2; |
| 656 size_in_words = Utils::RoundUp(size_in_words, PageSpace::kPageSizeInWords); |
| 657 intptr_t size_in_pages = size_in_words / PageSpace::kPageSizeInWords; |
653 if (!is_enabled_) { | 658 if (!is_enabled_) { |
| 659 return true; |
| 660 } |
| 661 if (heap_growth_ratio_ == 100) { |
| 662 return true; |
| 663 } |
| 664 if (grow_heap_ <= 0) { |
654 return false; | 665 return false; |
655 } | 666 } |
656 if (heap_growth_ratio_ == 100) { | 667 grow_heap_ -= size_in_pages; |
657 return false; | 668 return true; |
658 } | |
659 intptr_t capacity_increase_in_words = | |
660 after.capacity_in_words - last_usage_.capacity_in_words; | |
661 ASSERT(capacity_increase_in_words >= 0); | |
662 intptr_t capacity_increase_in_pages = | |
663 Utils::RoundUp(capacity_increase_in_words, PageSpace::kPageSizeInWords); | |
664 return capacity_increase_in_pages >= grow_heap_; | |
665 } | 669 } |
666 | 670 |
667 | 671 |
668 void PageSpaceController::EvaluateGarbageCollection( | 672 void PageSpaceController::EvaluateGarbageCollection( |
669 SpaceUsage before, SpaceUsage after, int64_t start, int64_t end) { | 673 intptr_t used_before_in_words, intptr_t used_after_in_words, |
| 674 int64_t start, int64_t end) { |
670 // TODO(iposva): Reevaluate the growth policies. | 675 // TODO(iposva): Reevaluate the growth policies. |
671 intptr_t before_total_in_words = | 676 ASSERT(used_before_in_words >= used_after_in_words); |
672 before.used_in_words + before.external_in_words; | |
673 intptr_t after_total_in_words = | |
674 after.used_in_words + after.external_in_words; | |
675 ASSERT(before_total_in_words >= after_total_in_words); | |
676 ASSERT(end >= start); | 677 ASSERT(end >= start); |
677 history_.AddGarbageCollectionTime(start, end); | 678 history_.AddGarbageCollectionTime(start, end); |
678 int collected_garbage_ratio = static_cast<int>( | 679 int collected_garbage_ratio = static_cast<int>( |
679 (static_cast<double>(before_total_in_words - after_total_in_words) / | 680 (static_cast<double>(used_before_in_words - used_after_in_words) / |
680 static_cast<double>(before_total_in_words)) | 681 static_cast<double>(used_before_in_words)) |
681 * 100.0); | 682 * 100.0); |
682 bool enough_free_space = | 683 bool enough_free_space = |
683 (collected_garbage_ratio >= heap_growth_ratio_); | 684 (collected_garbage_ratio >= heap_growth_ratio_); |
684 int garbage_collection_time_fraction = | 685 int garbage_collection_time_fraction = |
685 history_.GarbageCollectionTimeFraction(); | 686 history_.GarbageCollectionTimeFraction(); |
686 bool enough_free_time = | 687 bool enough_free_time = |
687 (garbage_collection_time_fraction <= garbage_collection_time_ratio_); | 688 (garbage_collection_time_fraction <= garbage_collection_time_ratio_); |
688 | 689 |
689 Heap* heap = Isolate::Current()->heap(); | 690 Heap* heap = Isolate::Current()->heap(); |
690 if (enough_free_space && enough_free_time) { | 691 if (enough_free_space && enough_free_time) { |
691 grow_heap_ = 0; | 692 grow_heap_ = 0; |
692 } else { | 693 } else { |
693 intptr_t growth_target = static_cast<intptr_t>( | 694 intptr_t growth_target = static_cast<intptr_t>( |
694 after_total_in_words / desired_utilization_); | 695 used_after_in_words / desired_utilization_); |
695 intptr_t growth_in_words = Utils::RoundUp( | 696 intptr_t growth_in_words = Utils::RoundUp( |
696 growth_target - after_total_in_words, | 697 growth_target - used_after_in_words, |
697 PageSpace::kPageSizeInWords); | 698 PageSpace::kPageSizeInWords); |
698 int growth_in_pages = | 699 int growth_in_pages = |
699 growth_in_words / PageSpace::kPageSizeInWords; | 700 growth_in_words / PageSpace::kPageSizeInWords; |
700 grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_); | 701 grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_); |
701 heap->RecordData(PageSpace::kPageGrowth, growth_in_pages); | 702 heap->RecordData(PageSpace::kPageGrowth, growth_in_pages); |
702 } | 703 } |
703 heap->RecordData(PageSpace::kGarbageRatio, collected_garbage_ratio); | 704 heap->RecordData(PageSpace::kGarbageRatio, collected_garbage_ratio); |
704 heap->RecordData(PageSpace::kGCTimeFraction, | 705 heap->RecordData(PageSpace::kGCTimeFraction, |
705 garbage_collection_time_fraction); | 706 garbage_collection_time_fraction); |
706 heap->RecordData(PageSpace::kAllowedGrowth, grow_heap_); | 707 heap->RecordData(PageSpace::kAllowedGrowth, grow_heap_); |
707 last_usage_ = after; | |
708 } | 708 } |
709 | 709 |
710 | 710 |
711 PageSpaceGarbageCollectionHistory::PageSpaceGarbageCollectionHistory() | 711 PageSpaceGarbageCollectionHistory::PageSpaceGarbageCollectionHistory() |
712 : index_(0) { | 712 : index_(0) { |
713 for (intptr_t i = 0; i < kHistoryLength; i++) { | 713 for (intptr_t i = 0; i < kHistoryLength; i++) { |
714 start_[i] = 0; | 714 start_[i] = 0; |
715 end_[i] = 0; | 715 end_[i] = 0; |
716 } | 716 } |
717 } | 717 } |
(...skipping 27 matching lines...) Expand all Loading... |
745 return 0; | 745 return 0; |
746 } else { | 746 } else { |
747 ASSERT(total_time >= gc_time); | 747 ASSERT(total_time >= gc_time); |
748 int result= static_cast<int>((static_cast<double>(gc_time) / | 748 int result= static_cast<int>((static_cast<double>(gc_time) / |
749 static_cast<double>(total_time)) * 100); | 749 static_cast<double>(total_time)) * 100); |
750 return result; | 750 return result; |
751 } | 751 } |
752 } | 752 } |
753 | 753 |
754 } // namespace dart | 754 } // namespace dart |
OLD | NEW |