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

Side by Side Diff: vm/pages.cc

Issue 10093010: - Free completely empty pages as part of sweep. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 8 months 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 | « vm/pages.h ('k') | no next file » | 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"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 } 61 }
62 ASSERT(obj_addr == end_addr); 62 ASSERT(obj_addr == end_addr);
63 return Object::null(); 63 return Object::null();
64 } 64 }
65 65
66 66
67 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable) 67 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable)
68 : freelist_(), 68 : freelist_(),
69 heap_(heap), 69 heap_(heap),
70 pages_(NULL), 70 pages_(NULL),
71 pages_tail_(NULL),
72 large_pages_(NULL), 71 large_pages_(NULL),
73 bump_page_(NULL), 72 bump_page_(NULL),
74 max_capacity_(max_capacity), 73 max_capacity_(max_capacity),
75 capacity_(0), 74 capacity_(0),
76 in_use_(0), 75 in_use_(0),
77 count_(0), 76 count_(0),
78 is_executable_(is_executable), 77 is_executable_(is_executable),
79 sweeping_(false) { } 78 sweeping_(false) { }
80 79
81 80
82 PageSpace::~PageSpace() { 81 PageSpace::~PageSpace() {
83 FreePages(pages_); 82 FreePages(pages_);
84 FreePages(large_pages_); 83 FreePages(large_pages_);
85 } 84 }
86 85
87 86
88 intptr_t PageSpace::LargePageSizeFor(intptr_t size) { 87 intptr_t PageSpace::LargePageSizeFor(intptr_t size) {
89 intptr_t page_size = Utils::RoundUp(size + sizeof(HeapPage), 88 intptr_t page_size = Utils::RoundUp(size + sizeof(HeapPage),
90 VirtualMemory::PageSize()); 89 VirtualMemory::PageSize());
91 return page_size; 90 return page_size;
92 } 91 }
93 92
94 93
95 void PageSpace::AllocatePage() { 94 void PageSpace::AllocatePage() {
96 HeapPage* page = HeapPage::Allocate(kPageSize, is_executable_); 95 HeapPage* page = HeapPage::Allocate(kPageSize, is_executable_);
97 if (pages_ == NULL) { 96 page->set_next(pages_);
98 pages_ = page; 97 pages_ = page;
99 } else {
100 pages_tail_->set_next(page);
101 }
102 pages_tail_ = page;
103 bump_page_ = NULL; // Reenable scanning of pages for bump allocation. 98 bump_page_ = NULL; // Reenable scanning of pages for bump allocation.
104 capacity_ += kPageSize; 99 capacity_ += kPageSize;
105 } 100 }
106 101
107 102
108 HeapPage* PageSpace::AllocateLargePage(intptr_t size) { 103 HeapPage* PageSpace::AllocateLargePage(intptr_t size) {
109 intptr_t page_size = LargePageSizeFor(size); 104 intptr_t page_size = LargePageSizeFor(size);
110 HeapPage* page = HeapPage::Allocate(page_size, is_executable_); 105 HeapPage* page = HeapPage::Allocate(page_size, is_executable_);
111 page->set_next(large_pages_); 106 page->set_next(large_pages_);
112 large_pages_ = page; 107 large_pages_ = page;
113 capacity_ += page_size; 108 capacity_ += page_size;
114 return page; 109 return page;
115 } 110 }
116 111
117 112
113 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) {
114 capacity_ -= page->memory_->size();
115 // Remove the page from the list.
116 if (previous_page != NULL) {
117 previous_page->set_next(page->next());
118 } else {
119 pages_ = page->next();
120 }
121 // TODO(iposva): Consider adding to a pool of empty pages.
122 page->Deallocate();
123 }
124
125
118 void PageSpace::FreeLargePage(HeapPage* page, HeapPage* previous_page) { 126 void PageSpace::FreeLargePage(HeapPage* page, HeapPage* previous_page) {
119 capacity_ -= page->memory_->size(); 127 capacity_ -= page->memory_->size();
120 // Remove the page from the list. 128 // Remove the page from the list.
121 if (previous_page != NULL) { 129 if (previous_page != NULL) {
122 previous_page->set_next(page->next()); 130 previous_page->set_next(page->next());
123 } else { 131 } else {
124 large_pages_ = page->next(); 132 large_pages_ = page->next();
125 } 133 }
126 page->Deallocate(); 134 page->Deallocate();
127 } 135 }
128 136
129 137
130 void PageSpace::FreePages(HeapPage* pages) { 138 void PageSpace::FreePages(HeapPage* pages) {
131 HeapPage* page = pages; 139 HeapPage* page = pages;
132 while (page != NULL) { 140 while (page != NULL) {
133 HeapPage* next = page->next(); 141 HeapPage* next = page->next();
134 page->Deallocate(); 142 page->Deallocate();
135 page = next; 143 page = next;
136 } 144 }
137 } 145 }
138 146
139 147
140 uword PageSpace::TryBumpAllocate(intptr_t size) { 148 uword PageSpace::TryBumpAllocate(intptr_t size) {
141 if (pages_tail_ == NULL) {
142 return 0;
143 }
144 uword result = pages_tail_->TryBumpAllocate(size);
145 if (result != 0) {
146 return result;
147 }
148 if (bump_page_ == NULL) { 149 if (bump_page_ == NULL) {
149 // The bump page has not yet been used: Start at the beginning of the list. 150 // The bump page has not yet been used: Start at the beginning of the list.
150 bump_page_ = pages_; 151 bump_page_ = pages_;
151 } 152 }
152 // The last page has already been attempted above. 153 while (bump_page_ != NULL) {
153 while (bump_page_ != pages_tail_) { 154 uword result = bump_page_->TryBumpAllocate(size);
154 ASSERT(bump_page_->next() != NULL);
155 result = bump_page_->TryBumpAllocate(size);
156 if (result != 0) { 155 if (result != 0) {
157 return result; 156 return result;
158 } 157 }
159 bump_page_ = bump_page_->next(); 158 bump_page_ = bump_page_->next();
160 } 159 }
161 // Ran through all of the pages trying to bump allocate: Give up. 160 // Ran through all of the pages trying to bump allocate: Give up.
162 return 0; 161 return 0;
163 } 162 }
164 163
165 164
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 GCMarker marker(heap_); 276 GCMarker marker(heap_);
278 marker.MarkObjects(isolate, this, invoke_api_callbacks); 277 marker.MarkObjects(isolate, this, invoke_api_callbacks);
279 278
280 // Reset the bump allocation page to unused. 279 // Reset the bump allocation page to unused.
281 bump_page_ = NULL; 280 bump_page_ = NULL;
282 // Reset the freelists and setup sweeping. 281 // Reset the freelists and setup sweeping.
283 freelist_.Reset(); 282 freelist_.Reset();
284 GCSweeper sweeper(heap_); 283 GCSweeper sweeper(heap_);
285 intptr_t in_use = 0; 284 intptr_t in_use = 0;
286 285
286 HeapPage* prev_page = NULL;
287 HeapPage* page = pages_; 287 HeapPage* page = pages_;
288 while (page != NULL) { 288 while (page != NULL) {
289 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_); 289 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_);
290 in_use += page_in_use; 290 HeapPage* next_page = page->next();
291 page = page->next(); 291 if (page_in_use == 0) {
292 FreePage(page, prev_page);
293 } else {
294 in_use += page_in_use;
295 prev_page = page;
296 }
297 // Advance to the next page.
298 page = next_page;
292 } 299 }
293 300
294 HeapPage* prev_page = NULL; 301 prev_page = NULL;
295 page = large_pages_; 302 page = large_pages_;
296 while (page != NULL) { 303 while (page != NULL) {
297 intptr_t page_in_use = sweeper.SweepLargePage(page); 304 intptr_t page_in_use = sweeper.SweepLargePage(page);
298 HeapPage* next_page = page->next(); 305 HeapPage* next_page = page->next();
299 if (page_in_use == 0) { 306 if (page_in_use == 0) {
300 FreeLargePage(page, prev_page); 307 FreeLargePage(page, prev_page);
301 } else { 308 } else {
302 in_use += page_in_use; 309 in_use += page_in_use;
303 prev_page = page; 310 prev_page = page;
304 } 311 }
(...skipping 22 matching lines...) Expand all
327 OS::PrintErr(" done.\n"); 334 OS::PrintErr(" done.\n");
328 } 335 }
329 336
330 count_++; 337 count_++;
331 // Done, reset the marker. 338 // Done, reset the marker.
332 ASSERT(sweeping_); 339 ASSERT(sweeping_);
333 sweeping_ = false; 340 sweeping_ = false;
334 } 341 }
335 342
336 } // namespace dart 343 } // namespace dart
OLDNEW
« no previous file with comments | « vm/pages.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698