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

Side by Side Diff: vm/pages.cc

Issue 11265026: - Consolidate code into the old generation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 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
« vm/pages.h ('K') | « vm/pages.h ('k') | vm/raw_object.h » ('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/gc_marker.h" 8 #include "vm/gc_marker.h"
9 #include "vm/gc_sweeper.h" 9 #include "vm/gc_sweeper.h"
10 #include "vm/object.h" 10 #include "vm/object.h"
11 #include "vm/virtual_memory.h" 11 #include "vm/virtual_memory.h"
12 12
13 namespace dart { 13 namespace dart {
14 14
15 DEFINE_FLAG(int, heap_growth_space_ratio, 10, 15 DEFINE_FLAG(int, heap_growth_space_ratio, 10,
16 "The desired maximum percentage of free space after GC"); 16 "The desired maximum percentage of free space after GC");
17 DEFINE_FLAG(int, heap_growth_time_ratio, 3, 17 DEFINE_FLAG(int, heap_growth_time_ratio, 3,
18 "The desired maximum percentage of time spent in GC"); 18 "The desired maximum percentage of time spent in GC");
19 DEFINE_FLAG(int, heap_growth_rate, 4, 19 DEFINE_FLAG(int, heap_growth_rate, 4,
20 "The size the heap is grown, in heap pages"); 20 "The size the heap is grown, in heap pages");
21 DEFINE_FLAG(bool, print_free_list_before_gc, false, 21 DEFINE_FLAG(bool, print_free_list_before_gc, false,
22 "Print free list statistics before a GC"); 22 "Print free list statistics before a GC");
23 DEFINE_FLAG(bool, print_free_list_after_gc, false, 23 DEFINE_FLAG(bool, print_free_list_after_gc, false,
24 "Print free list statistics after a GC"); 24 "Print free list statistics after a GC");
25 25
26 HeapPage* HeapPage::Initialize(VirtualMemory* memory, bool is_executable) { 26 HeapPage* HeapPage::Initialize(VirtualMemory* memory, PageType type) {
27 ASSERT(memory->size() > VirtualMemory::PageSize()); 27 ASSERT(memory->size() > VirtualMemory::PageSize());
28 bool is_executable = (type == kExecutable);
28 memory->Commit(is_executable); 29 memory->Commit(is_executable);
29 30
30 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); 31 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address());
31 result->memory_ = memory; 32 result->memory_ = memory;
32 result->next_ = NULL; 33 result->next_ = NULL;
33 result->used_ = 0; 34 result->used_ = 0;
35 result->executable_ = is_executable;
34 return result; 36 return result;
35 } 37 }
36 38
37 39
38 HeapPage* HeapPage::Allocate(intptr_t size, bool is_executable) { 40 HeapPage* HeapPage::Allocate(intptr_t size, PageType type) {
39 VirtualMemory* memory = 41 VirtualMemory* memory =
40 VirtualMemory::ReserveAligned(size, PageSpace::kPageAlignment); 42 VirtualMemory::ReserveAligned(size, PageSpace::kPageAlignment);
41 return Initialize(memory, is_executable); 43 return Initialize(memory, type);
42 } 44 }
43 45
44 46
45 void HeapPage::Deallocate() { 47 void HeapPage::Deallocate() {
46 // The memory for this object will become unavailable after the delete below. 48 // The memory for this object will become unavailable after the delete below.
47 delete memory_; 49 delete memory_;
48 } 50 }
49 51
50 52
51 void HeapPage::VisitObjects(ObjectVisitor* visitor) const { 53 void HeapPage::VisitObjects(ObjectVisitor* visitor) const {
(...skipping 28 matching lines...) Expand all
80 return raw_obj; // Found object, return it. 82 return raw_obj; // Found object, return it.
81 } 83 }
82 obj_addr += raw_obj->Size(); 84 obj_addr += raw_obj->Size();
83 } 85 }
84 ASSERT(obj_addr == end_addr); 86 ASSERT(obj_addr == end_addr);
85 return Object::null(); 87 return Object::null();
86 } 88 }
87 89
88 90
89 void HeapPage::WriteProtect(bool read_only) { 91 void HeapPage::WriteProtect(bool read_only) {
90 memory_->Protect( 92 VirtualMemory::Protection prot;
91 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); 93 if (read_only) {
94 if (executable_) {
95 prot = VirtualMemory::kReadExecute;
96 } else {
97 prot = VirtualMemory::kReadOnly;
98 }
99 } else {
100 if (executable_) {
101 prot = VirtualMemory::kReadWriteExecute;
102 } else {
103 prot = VirtualMemory::kReadWrite;
104 }
105 }
106 memory_->Protect(prot);
92 } 107 }
93 108
94 109
95 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable) 110 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity)
96 : freelist_(), 111 : freelist_(),
97 heap_(heap), 112 heap_(heap),
98 pages_(NULL), 113 pages_(NULL),
99 pages_tail_(NULL), 114 pages_tail_(NULL),
100 large_pages_(NULL), 115 large_pages_(NULL),
101 max_capacity_(max_capacity), 116 max_capacity_(max_capacity),
102 capacity_(0), 117 capacity_(0),
103 in_use_(0), 118 in_use_(0),
104 count_(0), 119 count_(0),
105 is_executable_(is_executable),
106 sweeping_(false), 120 sweeping_(false),
107 page_space_controller_(FLAG_heap_growth_space_ratio, 121 page_space_controller_(FLAG_heap_growth_space_ratio,
108 FLAG_heap_growth_rate, 122 FLAG_heap_growth_rate,
109 FLAG_heap_growth_time_ratio) { 123 FLAG_heap_growth_time_ratio) {
110 } 124 }
111 125
112 126
113 PageSpace::~PageSpace() { 127 PageSpace::~PageSpace() {
114 FreePages(pages_); 128 FreePages(pages_);
115 FreePages(large_pages_); 129 FreePages(large_pages_);
116 } 130 }
117 131
118 132
119 intptr_t PageSpace::LargePageSizeFor(intptr_t size) { 133 intptr_t PageSpace::LargePageSizeFor(intptr_t size) {
120 intptr_t page_size = Utils::RoundUp(size + sizeof(HeapPage), 134 intptr_t page_size = Utils::RoundUp(size + sizeof(HeapPage),
121 VirtualMemory::PageSize()); 135 VirtualMemory::PageSize());
122 return page_size; 136 return page_size;
123 } 137 }
124 138
125 139
126 HeapPage* PageSpace::AllocatePage() { 140 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) {
127 HeapPage* page = HeapPage::Allocate(kPageSize, is_executable_); 141 HeapPage* page = HeapPage::Allocate(kPageSize, type);
128 if (pages_ == NULL) { 142 if (pages_ == NULL) {
129 pages_ = page; 143 pages_ = page;
130 } else { 144 } else {
131 pages_tail_->set_next(page); 145 pages_tail_->set_next(page);
132 } 146 }
133 pages_tail_ = page; 147 pages_tail_ = page;
134 capacity_ += kPageSize; 148 capacity_ += kPageSize;
135 page->set_object_end(page->memory_->end()); 149 page->set_object_end(page->memory_->end());
136 return page; 150 return page;
137 } 151 }
138 152
139 153
140 HeapPage* PageSpace::AllocateLargePage(intptr_t size) { 154 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) {
141 intptr_t page_size = LargePageSizeFor(size); 155 intptr_t page_size = LargePageSizeFor(size);
142 HeapPage* page = HeapPage::Allocate(page_size, is_executable_); 156 HeapPage* page = HeapPage::Allocate(page_size, type);
143 page->set_next(large_pages_); 157 page->set_next(large_pages_);
144 large_pages_ = page; 158 large_pages_ = page;
145 capacity_ += page_size; 159 capacity_ += page_size;
146 // Only one object in this page. 160 // Only one object in this page.
147 page->set_object_end(page->object_start() + size); 161 page->set_object_end(page->object_start() + size);
148 return page; 162 return page;
149 } 163 }
150 164
151 165
152 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) { 166 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) {
(...skipping 27 matching lines...) Expand all
180 void PageSpace::FreePages(HeapPage* pages) { 194 void PageSpace::FreePages(HeapPage* pages) {
181 HeapPage* page = pages; 195 HeapPage* page = pages;
182 while (page != NULL) { 196 while (page != NULL) {
183 HeapPage* next = page->next(); 197 HeapPage* next = page->next();
184 page->Deallocate(); 198 page->Deallocate();
185 page = next; 199 page = next;
186 } 200 }
187 } 201 }
188 202
189 203
190 uword PageSpace::TryAllocate(intptr_t size) { 204 uword PageSpace::TryAllocate(intptr_t size,
191 return TryAllocate(size, kControlGrowth); 205 HeapPage::PageType type,
192 } 206 GrowthPolicy growth_policy) {
193
194
195 uword PageSpace::TryAllocate(intptr_t size, GrowthPolicy growth_policy) {
196 ASSERT(size >= kObjectAlignment); 207 ASSERT(size >= kObjectAlignment);
197 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 208 ASSERT(Utils::IsAligned(size, kObjectAlignment));
198 uword result = 0; 209 uword result = 0;
199 if (size < kAllocatablePageSize) { 210 if (size < kAllocatablePageSize) {
200 result = freelist_.TryAllocate(size); 211 result = freelist_[type].TryAllocate(size);
201 if ((result == 0) && 212 if ((result == 0) &&
202 (page_space_controller_.CanGrowPageSpace(size) || 213 (page_space_controller_.CanGrowPageSpace(size) ||
203 growth_policy == kForceGrowth) && 214 growth_policy == kForceGrowth) &&
204 CanIncreaseCapacity(kPageSize)) { 215 CanIncreaseCapacity(kPageSize)) {
205 HeapPage* page = AllocatePage(); 216 HeapPage* page = AllocatePage(type);
206 ASSERT(page != NULL); 217 ASSERT(page != NULL);
207 // Start of the newly allocated page is the allocated object. 218 // Start of the newly allocated page is the allocated object.
208 result = page->object_start(); 219 result = page->object_start();
209 // Enqueue the remainder in the free list. 220 // Enqueue the remainder in the free list.
210 uword free_start = result + size; 221 uword free_start = result + size;
211 freelist_.Free(free_start, page->object_end() - free_start); 222 freelist_[type].Free(free_start, page->object_end() - free_start);
212 } 223 }
213 } else { 224 } else {
214 // Large page allocation. 225 // Large page allocation.
215 intptr_t page_size = LargePageSizeFor(size); 226 intptr_t page_size = LargePageSizeFor(size);
216 if (page_size < size) { 227 if (page_size < size) {
217 // On overflow we fail to allocate. 228 // On overflow we fail to allocate.
218 return 0; 229 return 0;
219 } 230 }
220 if (CanIncreaseCapacity(page_size)) { 231 if (CanIncreaseCapacity(page_size)) {
221 HeapPage* page = AllocateLargePage(size); 232 HeapPage* page = AllocateLargePage(size, type);
222 if (page != NULL) { 233 if (page != NULL) {
223 result = page->object_start(); 234 result = page->object_start();
224 } 235 }
225 } 236 }
226 } 237 }
227 if (result != 0) { 238 if (result != 0) {
228 in_use_ += size; 239 in_use_ += size;
229 } 240 }
230 ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset); 241 ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset);
231 return result; 242 return result;
(...skipping 13 matching lines...) Expand all
245 while (page != NULL) { 256 while (page != NULL) {
246 if (page->Contains(addr)) { 257 if (page->Contains(addr)) {
247 return true; 258 return true;
248 } 259 }
249 page = page->next(); 260 page = page->next();
250 } 261 }
251 return false; 262 return false;
252 } 263 }
253 264
254 265
266 bool PageSpace::Contains(uword addr, HeapPage::PageType type) const {
267 HeapPage* page = pages_;
268 while (page != NULL) {
269 if ((page->type() == type) && page->Contains(addr)) {
270 return true;
271 }
272 page = page->next();
273 }
274
275 page = large_pages_;
276 while (page != NULL) {
277 if ((page->type() == type) && page->Contains(addr)) {
278 return true;
279 }
280 page = page->next();
281 }
282 return false;
283 }
284
285
255 void PageSpace::StartEndAddress(uword* start, uword* end) const { 286 void PageSpace::StartEndAddress(uword* start, uword* end) const {
256 ASSERT(pages_ != NULL || large_pages_ != NULL); 287 ASSERT(pages_ != NULL || large_pages_ != NULL);
257 *start = static_cast<uword>(~0); 288 *start = static_cast<uword>(~0);
258 *end = 0; 289 *end = 0;
259 for (HeapPage* page = pages_; page != NULL; page = page->next()) { 290 for (HeapPage* page = pages_; page != NULL; page = page->next()) {
260 *start = Utils::Minimum(*start, page->object_start()); 291 *start = Utils::Minimum(*start, page->object_start());
261 *end = Utils::Maximum(*end, page->object_end()); 292 *end = Utils::Maximum(*end, page->object_end());
262 } 293 }
263 for (HeapPage* page = large_pages_; page != NULL; page = page->next()) { 294 for (HeapPage* page = large_pages_; page != NULL; page = page->next()) {
264 *start = Utils::Minimum(*start, page->object_start()); 295 *start = Utils::Minimum(*start, page->object_start());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 388
358 389
359 void PageSpace::MarkSweep(bool invoke_api_callbacks, const char* gc_reason) { 390 void PageSpace::MarkSweep(bool invoke_api_callbacks, const char* gc_reason) {
360 // MarkSweep is not reentrant. Make sure that is the case. 391 // MarkSweep is not reentrant. Make sure that is the case.
361 ASSERT(!sweeping_); 392 ASSERT(!sweeping_);
362 sweeping_ = true; 393 sweeping_ = true;
363 Isolate* isolate = Isolate::Current(); 394 Isolate* isolate = Isolate::Current();
364 NoHandleScope no_handles(isolate); 395 NoHandleScope no_handles(isolate);
365 396
366 if (FLAG_print_free_list_before_gc) { 397 if (FLAG_print_free_list_before_gc) {
367 freelist_.Print(); 398 OS::Print("Data Freelist:\n");
399 freelist_[HeapPage::kData].Print();
400 OS::Print("Executable Freelist:\n");
401 freelist_[HeapPage::kExecutable].Print();
368 } 402 }
369 403
370 if (FLAG_verify_before_gc) { 404 if (FLAG_verify_before_gc) {
371 OS::PrintErr("Verifying before MarkSweep..."); 405 OS::PrintErr("Verifying before MarkSweep...");
372 heap_->Verify(); 406 heap_->Verify();
373 OS::PrintErr(" done.\n"); 407 OS::PrintErr(" done.\n");
374 } 408 }
375 409
376 if (FLAG_verbose_gc) { 410 if (FLAG_verbose_gc) {
377 OS::PrintErr("Start mark sweep for %s collection\n", gc_reason); 411 OS::PrintErr("Start mark sweep for %s collection\n", gc_reason);
378 } 412 }
379 Timer timer(true, "MarkSweep"); 413 Timer timer(true, "MarkSweep");
380 timer.Start(); 414 timer.Start();
381 int64_t start = OS::GetCurrentTimeMillis(); 415 int64_t start = OS::GetCurrentTimeMillis();
382 416
383 // Mark all reachable old-gen objects. 417 // Mark all reachable old-gen objects.
384 GCMarker marker(heap_); 418 GCMarker marker(heap_);
385 marker.MarkObjects(isolate, this, invoke_api_callbacks); 419 marker.MarkObjects(isolate, this, invoke_api_callbacks);
386 420
387 // Reset the bump allocation page to unused. 421 // Reset the bump allocation page to unused.
388 // Reset the freelists and setup sweeping. 422 // Reset the freelists and setup sweeping.
siva 2012/10/25 22:29:52 It is probably more generic to write this as: for
Ivan Posva 2012/10/25 23:45:41 Yes, once we have more page types.
389 freelist_.Reset(); 423 freelist_[HeapPage::kData].Reset();
424 freelist_[HeapPage::kExecutable].Reset();
390 GCSweeper sweeper(heap_); 425 GCSweeper sweeper(heap_);
391 intptr_t in_use = 0; 426 intptr_t in_use = 0;
392 427
393 HeapPage* prev_page = NULL; 428 HeapPage* prev_page = NULL;
394 HeapPage* page = pages_; 429 HeapPage* page = pages_;
395 while (page != NULL) { 430 while (page != NULL) {
396 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_);
397 HeapPage* next_page = page->next(); 431 HeapPage* next_page = page->next();
432 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]);
398 if (page_in_use == 0) { 433 if (page_in_use == 0) {
399 FreePage(page, prev_page); 434 FreePage(page, prev_page);
400 } else { 435 } else {
401 in_use += page_in_use; 436 in_use += page_in_use;
402 prev_page = page; 437 prev_page = page;
403 } 438 }
404 // Advance to the next page. 439 // Advance to the next page.
405 page = next_page; 440 page = next_page;
406 } 441 }
407 442
(...skipping 27 matching lines...) Expand all
435 const intptr_t KB2 = KB / 2; 470 const intptr_t KB2 = KB / 2;
436 OS::PrintErr("Mark-Sweep[%d]: %"Pd64"us (%"Pd"K -> %"Pd"K, %"Pd"K)\n", 471 OS::PrintErr("Mark-Sweep[%d]: %"Pd64"us (%"Pd"K -> %"Pd"K, %"Pd"K)\n",
437 count_, 472 count_,
438 timer.TotalElapsedTime(), 473 timer.TotalElapsedTime(),
439 (in_use_before + (KB2)) / KB, 474 (in_use_before + (KB2)) / KB,
440 (in_use + (KB2)) / KB, 475 (in_use + (KB2)) / KB,
441 (capacity_ + KB2) / KB); 476 (capacity_ + KB2) / KB);
442 } 477 }
443 478
444 if (FLAG_print_free_list_after_gc) { 479 if (FLAG_print_free_list_after_gc) {
445 freelist_.Print(); 480 OS::Print("Data Freelist:\n");
481 freelist_[HeapPage::kData].Print();
482 OS::Print("Executable Freelist:\n");
483 freelist_[HeapPage::kExecutable].Print();
siva 2012/10/25 22:29:52 Ditto comment: It is probably more generic to writ
Ivan Posva 2012/10/25 23:45:41 ditto
446 } 484 }
447 485
448 if (FLAG_verify_after_gc) { 486 if (FLAG_verify_after_gc) {
449 OS::PrintErr("Verifying after MarkSweep..."); 487 OS::PrintErr("Verifying after MarkSweep...");
450 heap_->Verify(); 488 heap_->Verify();
451 OS::PrintErr(" done.\n"); 489 OS::PrintErr(" done.\n");
452 } 490 }
453 491
454 count_++; 492 count_++;
455 // Done, reset the marker. 493 // Done, reset the marker.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 return 0; 614 return 0;
577 } else { 615 } else {
578 ASSERT(total_time >= gc_time); 616 ASSERT(total_time >= gc_time);
579 int result= static_cast<int>((static_cast<double>(gc_time) / 617 int result= static_cast<int>((static_cast<double>(gc_time) /
580 static_cast<double>(total_time)) * 100); 618 static_cast<double>(total_time)) * 100);
581 return result; 619 return result;
582 } 620 }
583 } 621 }
584 622
585 } // namespace dart 623 } // namespace dart
OLDNEW
« vm/pages.h ('K') | « vm/pages.h ('k') | vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698