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