Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Side by Side Diff: runtime/vm/pages.cc

Issue 70993002: - Convert heap sizes to words from bytes. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/pages.h ('k') | runtime/vm/pages_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 if (executable_) { 105 if (executable_) {
106 prot = VirtualMemory::kReadWriteExecute; 106 prot = VirtualMemory::kReadWriteExecute;
107 } else { 107 } else {
108 prot = VirtualMemory::kReadWrite; 108 prot = VirtualMemory::kReadWrite;
109 } 109 }
110 } 110 }
111 memory_->Protect(prot); 111 memory_->Protect(prot);
112 } 112 }
113 113
114 114
115 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity) 115 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity_in_words)
116 : freelist_(), 116 : freelist_(),
117 heap_(heap), 117 heap_(heap),
118 pages_(NULL), 118 pages_(NULL),
119 pages_tail_(NULL), 119 pages_tail_(NULL),
120 large_pages_(NULL), 120 large_pages_(NULL),
121 max_capacity_(max_capacity), 121 max_capacity_in_words_(max_capacity_in_words),
122 capacity_(0), 122 capacity_in_words_(0),
123 in_use_(0), 123 used_in_words_(0),
124 sweeping_(false), 124 sweeping_(false),
125 page_space_controller_(FLAG_heap_growth_space_ratio, 125 page_space_controller_(FLAG_heap_growth_space_ratio,
126 FLAG_heap_growth_rate, 126 FLAG_heap_growth_rate,
127 FLAG_heap_growth_time_ratio) { 127 FLAG_heap_growth_time_ratio) {
128 } 128 }
129 129
130 130
131 PageSpace::~PageSpace() { 131 PageSpace::~PageSpace() {
132 FreePages(pages_); 132 FreePages(pages_);
133 FreePages(large_pages_); 133 FreePages(large_pages_);
134 } 134 }
135 135
136 136
137 intptr_t PageSpace::LargePageSizeFor(intptr_t size) { 137 intptr_t PageSpace::LargePageSizeFor(intptr_t size) {
138 intptr_t page_size = Utils::RoundUp(size + HeapPage::ObjectStartOffset(), 138 intptr_t page_size = Utils::RoundUp(size + HeapPage::ObjectStartOffset(),
139 VirtualMemory::PageSize()); 139 VirtualMemory::PageSize());
140 return page_size; 140 return page_size;
141 } 141 }
142 142
143 143
144 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) { 144 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) {
145 HeapPage* page = HeapPage::Allocate(kPageSize, type); 145 HeapPage* page = HeapPage::Allocate(kPageSize, type);
146 if (pages_ == NULL) { 146 if (pages_ == NULL) {
147 pages_ = page; 147 pages_ = page;
148 } else { 148 } else {
149 pages_tail_->set_next(page); 149 pages_tail_->set_next(page);
150 } 150 }
151 pages_tail_ = page; 151 pages_tail_ = page;
152 capacity_ += kPageSize; 152 capacity_in_words_ += (kPageSize >> kWordSizeLog2);
siva 2013/11/15 22:06:22 Why not have kPageSizeInWords ?
153 page->set_object_end(page->memory_->end()); 153 page->set_object_end(page->memory_->end());
154 return page; 154 return page;
155 } 155 }
156 156
157 157
158 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) { 158 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) {
siva 2013/11/15 22:06:22 Why is this size not in words? It is confusing tha
Ivan Posva 2013/11/16 00:16:57 HeapPage has not been updated yet.
159 intptr_t page_size = LargePageSizeFor(size); 159 intptr_t page_size = LargePageSizeFor(size);
160 HeapPage* page = HeapPage::Allocate(page_size, type); 160 HeapPage* page = HeapPage::Allocate(page_size, type);
161 page->set_next(large_pages_); 161 page->set_next(large_pages_);
162 large_pages_ = page; 162 large_pages_ = page;
163 capacity_ += page_size; 163 capacity_in_words_ += (page_size >> kWordSizeLog2);
164 // Only one object in this page. 164 // Only one object in this page.
165 page->set_object_end(page->object_start() + size); 165 page->set_object_end(page->object_start() + size);
166 return page; 166 return page;
167 } 167 }
168 168
169 169
170 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) { 170 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) {
171 capacity_ -= page->memory_->size(); 171 capacity_in_words_ -= (page->memory_->size() >> kWordSizeLog2);
172 // Remove the page from the list. 172 // Remove the page from the list.
173 if (previous_page != NULL) { 173 if (previous_page != NULL) {
174 previous_page->set_next(page->next()); 174 previous_page->set_next(page->next());
175 } else { 175 } else {
176 pages_ = page->next(); 176 pages_ = page->next();
177 } 177 }
178 if (page == pages_tail_) { 178 if (page == pages_tail_) {
179 pages_tail_ = previous_page; 179 pages_tail_ = previous_page;
180 } 180 }
181 // TODO(iposva): Consider adding to a pool of empty pages. 181 // TODO(iposva): Consider adding to a pool of empty pages.
182 page->Deallocate(); 182 page->Deallocate();
183 } 183 }
184 184
185 185
186 void PageSpace::FreeLargePage(HeapPage* page, HeapPage* previous_page) { 186 void PageSpace::FreeLargePage(HeapPage* page, HeapPage* previous_page) {
187 capacity_ -= page->memory_->size(); 187 capacity_in_words_ -= (page->memory_->size() >> kWordSizeLog2);
188 // Remove the page from the list. 188 // Remove the page from the list.
189 if (previous_page != NULL) { 189 if (previous_page != NULL) {
190 previous_page->set_next(page->next()); 190 previous_page->set_next(page->next());
191 } else { 191 } else {
192 large_pages_ = page->next(); 192 large_pages_ = page->next();
193 } 193 }
194 page->Deallocate(); 194 page->Deallocate();
195 } 195 }
196 196
197 197
(...skipping 11 matching lines...) Expand all
209 HeapPage::PageType type, 209 HeapPage::PageType type,
210 GrowthPolicy growth_policy) { 210 GrowthPolicy growth_policy) {
211 ASSERT(size >= kObjectAlignment); 211 ASSERT(size >= kObjectAlignment);
212 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 212 ASSERT(Utils::IsAligned(size, kObjectAlignment));
213 uword result = 0; 213 uword result = 0;
214 if (size < kAllocatablePageSize) { 214 if (size < kAllocatablePageSize) {
215 result = freelist_[type].TryAllocate(size); 215 result = freelist_[type].TryAllocate(size);
216 if ((result == 0) && 216 if ((result == 0) &&
217 (page_space_controller_.CanGrowPageSpace(size) || 217 (page_space_controller_.CanGrowPageSpace(size) ||
218 growth_policy == kForceGrowth) && 218 growth_policy == kForceGrowth) &&
219 CanIncreaseCapacity(kPageSize)) { 219 CanIncreaseCapacityInWords(kPageSize >> kWordSizeLog2)) {
220 HeapPage* page = AllocatePage(type); 220 HeapPage* page = AllocatePage(type);
221 ASSERT(page != NULL); 221 ASSERT(page != NULL);
222 // Start of the newly allocated page is the allocated object. 222 // Start of the newly allocated page is the allocated object.
223 result = page->object_start(); 223 result = page->object_start();
224 // Enqueue the remainder in the free list. 224 // Enqueue the remainder in the free list.
225 uword free_start = result + size; 225 uword free_start = result + size;
226 intptr_t free_size = page->object_end() - free_start; 226 intptr_t free_size = page->object_end() - free_start;
227 if (free_size > 0) { 227 if (free_size > 0) {
228 freelist_[type].Free(free_start, free_size); 228 freelist_[type].Free(free_start, free_size);
229 } 229 }
230 } 230 }
231 } else { 231 } else {
232 // Large page allocation. 232 // Large page allocation.
233 intptr_t page_size = LargePageSizeFor(size); 233 intptr_t page_size = LargePageSizeFor(size);
234 if (page_size < size) { 234 if (page_size < size) {
235 // On overflow we fail to allocate. 235 // On overflow we fail to allocate.
236 return 0; 236 return 0;
237 } 237 }
238 if ((page_space_controller_.CanGrowPageSpace(size) || 238 if ((page_space_controller_.CanGrowPageSpace(size) ||
239 growth_policy == kForceGrowth) && 239 growth_policy == kForceGrowth) &&
240 CanIncreaseCapacity(page_size)) { 240 CanIncreaseCapacityInWords(page_size >> kWordSizeLog2)) {
241 HeapPage* page = AllocateLargePage(size, type); 241 HeapPage* page = AllocateLargePage(size, type);
242 if (page != NULL) { 242 if (page != NULL) {
243 result = page->object_start(); 243 result = page->object_start();
244 } 244 }
245 } 245 }
246 } 246 }
247 if (result != 0) { 247 if (result != 0) {
248 in_use_ += size; 248 used_in_words_ += (size >> kWordSizeLog2);
249 if (FLAG_compiler_stats && (type == HeapPage::kExecutable)) { 249 if (FLAG_compiler_stats && (type == HeapPage::kExecutable)) {
250 CompilerStats::code_allocated += size; 250 CompilerStats::code_allocated += size;
251 } 251 }
252 } 252 }
253 ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset); 253 ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset);
254 return result; 254 return result;
255 } 255 }
256 256
257 257
258 bool PageSpace::Contains(uword addr) const { 258 bool PageSpace::Contains(uword addr) const {
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 int64_t mid1 = OS::GetCurrentTimeMicros(); 475 int64_t mid1 = OS::GetCurrentTimeMicros();
476 476
477 // Reset the bump allocation page to unused. 477 // Reset the bump allocation page to unused.
478 // Reset the freelists and setup sweeping. 478 // Reset the freelists and setup sweeping.
479 freelist_[HeapPage::kData].Reset(); 479 freelist_[HeapPage::kData].Reset();
480 freelist_[HeapPage::kExecutable].Reset(); 480 freelist_[HeapPage::kExecutable].Reset();
481 481
482 int64_t mid2 = OS::GetCurrentTimeMicros(); 482 int64_t mid2 = OS::GetCurrentTimeMicros();
483 483
484 GCSweeper sweeper(heap_); 484 GCSweeper sweeper(heap_);
485 intptr_t in_use = 0; 485 intptr_t used_in_words = 0;
486 486
487 HeapPage* prev_page = NULL; 487 HeapPage* prev_page = NULL;
488 HeapPage* page = pages_; 488 HeapPage* page = pages_;
489 while (page != NULL) { 489 while (page != NULL) {
490 HeapPage* next_page = page->next(); 490 HeapPage* next_page = page->next();
491 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]); 491 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]);
492 if (page_in_use == 0) { 492 if (page_in_use == 0) {
493 FreePage(page, prev_page); 493 FreePage(page, prev_page);
494 } else { 494 } else {
495 in_use += page_in_use; 495 used_in_words += (page_in_use >> kWordSizeLog2);
496 prev_page = page; 496 prev_page = page;
497 } 497 }
498 // Advance to the next page. 498 // Advance to the next page.
499 page = next_page; 499 page = next_page;
500 } 500 }
501 501
502 int64_t mid3 = OS::GetCurrentTimeMicros(); 502 int64_t mid3 = OS::GetCurrentTimeMicros();
503 503
504 prev_page = NULL; 504 prev_page = NULL;
505 page = large_pages_; 505 page = large_pages_;
506 while (page != NULL) { 506 while (page != NULL) {
507 intptr_t page_in_use = sweeper.SweepLargePage(page); 507 intptr_t page_in_use = sweeper.SweepLargePage(page);
508 HeapPage* next_page = page->next(); 508 HeapPage* next_page = page->next();
509 if (page_in_use == 0) { 509 if (page_in_use == 0) {
510 FreeLargePage(page, prev_page); 510 FreeLargePage(page, prev_page);
511 } else { 511 } else {
512 in_use += page_in_use; 512 used_in_words += (page_in_use >> kWordSizeLog2);
513 prev_page = page; 513 prev_page = page;
514 } 514 }
515 // Advance to the next page. 515 // Advance to the next page.
516 page = next_page; 516 page = next_page;
517 } 517 }
518 518
519 // Record data and print if requested. 519 // Record data and print if requested.
520 intptr_t in_use_before = in_use_; 520 intptr_t used_before_in_words = used_in_words_;
521 in_use_ = in_use; 521 used_in_words_ = used_in_words;
522 522
523 int64_t end = OS::GetCurrentTimeMicros(); 523 int64_t end = OS::GetCurrentTimeMicros();
524 524
525 // Record signals for growth control. 525 // Record signals for growth control.
526 page_space_controller_.EvaluateGarbageCollection(in_use_before, in_use, 526 page_space_controller_.EvaluateGarbageCollection(used_before_in_words,
527 used_in_words,
527 start, end); 528 start, end);
528 529
529 heap_->RecordTime(kMarkObjects, mid1 - start); 530 heap_->RecordTime(kMarkObjects, mid1 - start);
530 heap_->RecordTime(kResetFreeLists, mid2 - mid1); 531 heap_->RecordTime(kResetFreeLists, mid2 - mid1);
531 heap_->RecordTime(kSweepPages, mid3 - mid2); 532 heap_->RecordTime(kSweepPages, mid3 - mid2);
532 heap_->RecordTime(kSweepLargePages, end - mid3); 533 heap_->RecordTime(kSweepLargePages, end - mid3);
533 534
534 if (FLAG_print_free_list_after_gc) { 535 if (FLAG_print_free_list_after_gc) {
535 OS::Print("Data Freelist (after GC):\n"); 536 OS::Print("Data Freelist (after GC):\n");
536 freelist_[HeapPage::kData].Print(); 537 freelist_[HeapPage::kData].Print();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 } 578 }
578 if (grow_heap_ <= 0) { 579 if (grow_heap_ <= 0) {
579 return false; 580 return false;
580 } 581 }
581 grow_heap_ -= size_in_pages; 582 grow_heap_ -= size_in_pages;
582 return true; 583 return true;
583 } 584 }
584 585
585 586
586 void PageSpaceController::EvaluateGarbageCollection( 587 void PageSpaceController::EvaluateGarbageCollection(
587 intptr_t in_use_before, intptr_t in_use_after, int64_t start, int64_t end) { 588 intptr_t used_before_in_words, intptr_t used_after_in_words,
588 ASSERT(in_use_before >= in_use_after); 589 int64_t start, int64_t end) {
590 // TODO(iposva): Reevaluate the growth policies.
591 ASSERT(used_before_in_words >= used_after_in_words);
589 ASSERT(end >= start); 592 ASSERT(end >= start);
590 history_.AddGarbageCollectionTime(start, end); 593 history_.AddGarbageCollectionTime(start, end);
591 int collected_garbage_ratio = 594 int collected_garbage_ratio = static_cast<int>(
592 static_cast<int>((static_cast<double>(in_use_before - in_use_after) / 595 (static_cast<double>(used_before_in_words - used_after_in_words) /
593 static_cast<double>(in_use_before)) 596 static_cast<double>(used_before_in_words))
594 * 100.0); 597 * 100.0);
595 bool enough_free_space = 598 bool enough_free_space =
596 (collected_garbage_ratio >= heap_growth_ratio_); 599 (collected_garbage_ratio >= heap_growth_ratio_);
597 int garbage_collection_time_fraction = 600 int garbage_collection_time_fraction =
598 history_.GarbageCollectionTimeFraction(); 601 history_.GarbageCollectionTimeFraction();
599 bool enough_free_time = 602 bool enough_free_time =
600 (garbage_collection_time_fraction <= garbage_collection_time_ratio_); 603 (garbage_collection_time_fraction <= garbage_collection_time_ratio_);
601 604
602 Heap* heap = Isolate::Current()->heap(); 605 Heap* heap = Isolate::Current()->heap();
603 if (enough_free_space && enough_free_time) { 606 if (enough_free_space && enough_free_time) {
604 grow_heap_ = 0; 607 grow_heap_ = 0;
605 } else { 608 } else {
606 intptr_t growth_target = static_cast<intptr_t>(in_use_after / 609 intptr_t growth_target = static_cast<intptr_t>(
607 desired_utilization_); 610 used_after_in_words / desired_utilization_);
608 intptr_t growth_in_bytes = Utils::RoundUp(growth_target - in_use_after, 611 intptr_t growth_in_words = Utils::RoundUp(
609 PageSpace::kPageSize); 612 growth_target - used_after_in_words,
610 int growth_in_pages = growth_in_bytes / PageSpace::kPageSize; 613 PageSpace::kPageSize >> kWordSizeLog2);
614 int growth_in_pages =
615 growth_in_words / (PageSpace::kPageSize >> kWordSizeLog2);
611 grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_); 616 grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_);
612 heap->RecordData(PageSpace::kPageGrowth, growth_in_pages); 617 heap->RecordData(PageSpace::kPageGrowth, growth_in_pages);
613 } 618 }
614 heap->RecordData(PageSpace::kGarbageRatio, collected_garbage_ratio); 619 heap->RecordData(PageSpace::kGarbageRatio, collected_garbage_ratio);
615 heap->RecordData(PageSpace::kGCTimeFraction, 620 heap->RecordData(PageSpace::kGCTimeFraction,
616 garbage_collection_time_fraction); 621 garbage_collection_time_fraction);
617 heap->RecordData(PageSpace::kAllowedGrowth, grow_heap_); 622 heap->RecordData(PageSpace::kAllowedGrowth, grow_heap_);
618 } 623 }
619 624
620 625
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 return 0; 660 return 0;
656 } else { 661 } else {
657 ASSERT(total_time >= gc_time); 662 ASSERT(total_time >= gc_time);
658 int result= static_cast<int>((static_cast<double>(gc_time) / 663 int result= static_cast<int>((static_cast<double>(gc_time) /
659 static_cast<double>(total_time)) * 100); 664 static_cast<double>(total_time)) * 100);
660 return result; 665 return result;
661 } 666 }
662 } 667 }
663 668
664 } // namespace dart 669 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/pages.h ('k') | runtime/vm/pages_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698