Chromium Code Reviews| 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/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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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), | 71 pages_tail_(NULL), |
| 72 large_pages_(NULL), | 72 large_pages_(NULL), |
| 73 bump_page_(NULL), | |
| 73 max_capacity_(max_capacity), | 74 max_capacity_(max_capacity), |
| 74 capacity_(0), | 75 capacity_(0), |
| 75 in_use_(0), | 76 in_use_(0), |
| 76 count_(0), | 77 count_(0), |
| 77 is_executable_(is_executable), | 78 is_executable_(is_executable), |
| 78 sweeping_(false) { } | 79 sweeping_(false) { } |
| 79 | 80 |
| 80 | 81 |
| 81 PageSpace::~PageSpace() { | 82 PageSpace::~PageSpace() { |
| 82 FreePages(pages_); | 83 FreePages(pages_); |
| 83 FreePages(large_pages_); | 84 FreePages(large_pages_); |
| 84 } | 85 } |
| 85 | 86 |
| 86 | 87 |
| 87 intptr_t PageSpace::LargePageSizeFor(intptr_t size) { | 88 intptr_t PageSpace::LargePageSizeFor(intptr_t size) { |
| 88 intptr_t page_size = Utils::RoundUp(size + sizeof(HeapPage), | 89 intptr_t page_size = Utils::RoundUp(size + sizeof(HeapPage), |
| 89 VirtualMemory::PageSize()); | 90 VirtualMemory::PageSize()); |
| 90 return page_size; | 91 return page_size; |
| 91 } | 92 } |
| 92 | 93 |
| 93 | 94 |
| 94 void PageSpace::AllocatePage() { | 95 void PageSpace::AllocatePage() { |
| 95 HeapPage* page = HeapPage::Allocate(kPageSize, is_executable_); | 96 HeapPage* page = HeapPage::Allocate(kPageSize, is_executable_); |
| 96 if (pages_ == NULL) { | 97 if (pages_ == NULL) { |
| 97 pages_ = page; | 98 pages_ = page; |
| 98 } else { | 99 } else { |
| 99 pages_tail_->set_next(page); | 100 pages_tail_->set_next(page); |
| 100 } | 101 } |
| 101 pages_tail_ = page; | 102 pages_tail_ = page; |
| 103 bump_page_ = NULL; // Reenable scanning of pages for bump allocation. | |
| 102 capacity_ += kPageSize; | 104 capacity_ += kPageSize; |
| 103 } | 105 } |
| 104 | 106 |
| 105 | 107 |
| 106 HeapPage* PageSpace::AllocateLargePage(intptr_t size) { | 108 HeapPage* PageSpace::AllocateLargePage(intptr_t size) { |
| 107 intptr_t page_size = LargePageSizeFor(size); | 109 intptr_t page_size = LargePageSizeFor(size); |
| 108 HeapPage* page = HeapPage::Allocate(page_size, is_executable_); | 110 HeapPage* page = HeapPage::Allocate(page_size, is_executable_); |
| 109 page->set_next(large_pages_); | 111 page->set_next(large_pages_); |
| 110 large_pages_ = page; | 112 large_pages_ = page; |
| 111 capacity_ += page_size; | 113 capacity_ += page_size; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 129 HeapPage* page = pages; | 131 HeapPage* page = pages; |
| 130 while (page != NULL) { | 132 while (page != NULL) { |
| 131 HeapPage* next = page->next(); | 133 HeapPage* next = page->next(); |
| 132 page->Deallocate(); | 134 page->Deallocate(); |
| 133 page = next; | 135 page = next; |
| 134 } | 136 } |
| 135 } | 137 } |
| 136 | 138 |
| 137 | 139 |
| 138 uword PageSpace::TryBumpAllocate(intptr_t size) { | 140 uword PageSpace::TryBumpAllocate(intptr_t size) { |
| 139 HeapPage* page = pages_tail_; | 141 if (pages_tail_ == NULL) { |
| 140 if (page == NULL) { | |
| 141 return 0; | 142 return 0; |
| 142 } | 143 } |
| 143 uword result = page->top(); | 144 uword result = pages_tail_->TryBumpAllocate(size); |
| 144 intptr_t remaining_space = page->end() - result; | 145 if (result != 0) { |
| 145 if (remaining_space < size) { | 146 return result; |
| 146 return 0; | |
| 147 } | 147 } |
| 148 page->set_top(result + size); | 148 if (bump_page_ == NULL) { |
| 149 return result; | 149 // The bump page has not yet been used: Start at the beginning of the list. |
| 150 bump_page_ = pages_; | |
| 151 } | |
| 152 // The last page has already been attempted above. | |
| 153 while (bump_page_ != pages_tail_) { | |
| 154 ASSERT(bump_page_->next() != NULL); | |
| 155 result = bump_page_->TryBumpAllocate(size); | |
| 156 if (result != 0) { | |
| 157 return result; | |
| 158 } | |
| 159 bump_page_ = bump_page_->next(); | |
| 160 } | |
| 161 // Ran through all of the pages trying to bump allocate: Give up. | |
| 162 return 0; | |
| 150 } | 163 } |
| 151 | 164 |
| 152 | 165 |
| 153 uword PageSpace::TryAllocate(intptr_t size) { | 166 uword PageSpace::TryAllocate(intptr_t size) { |
| 154 ASSERT(size >= kObjectAlignment); | 167 ASSERT(size >= kObjectAlignment); |
| 155 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 168 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 156 uword result = 0; | 169 uword result = 0; |
| 157 if (size < kAllocatablePageSize) { | 170 if (size < kAllocatablePageSize) { |
| 158 result = TryBumpAllocate(size); | 171 result = TryBumpAllocate(size); |
| 159 if (result == 0) { | 172 if (result == 0) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 257 OS::PrintErr(" done.\n"); | 270 OS::PrintErr(" done.\n"); |
| 258 } | 271 } |
| 259 | 272 |
| 260 Timer timer(FLAG_verbose_gc, "MarkSweep"); | 273 Timer timer(FLAG_verbose_gc, "MarkSweep"); |
| 261 timer.Start(); | 274 timer.Start(); |
| 262 | 275 |
| 263 // Mark all reachable old-gen objects. | 276 // Mark all reachable old-gen objects. |
| 264 GCMarker marker(heap_); | 277 GCMarker marker(heap_); |
| 265 marker.MarkObjects(isolate, this, invoke_api_callbacks); | 278 marker.MarkObjects(isolate, this, invoke_api_callbacks); |
| 266 | 279 |
| 280 // Reset the bump allocation page to unused. | |
| 281 bump_page_ = NULL; | |
| 267 // Reset the freelists and setup sweeping. | 282 // Reset the freelists and setup sweeping. |
| 268 freelist_.Reset(); | 283 freelist_.Reset(); |
| 269 GCSweeper sweeper(heap_); | 284 GCSweeper sweeper(heap_); |
| 270 intptr_t in_use = 0; | 285 intptr_t in_use = 0; |
| 271 | 286 |
| 272 HeapPage* page = pages_; | 287 HeapPage* page = pages_; |
| 273 while (page != NULL) { | 288 while (page != NULL) { |
| 274 in_use += sweeper.SweepPage(page, &freelist_); | 289 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_); |
| 290 in_use += page_in_use; | |
|
ricow1
2012/04/11 10:23:30
Why this change? (easier debugging?)
Ivan Posva
2012/04/11 11:56:52
Yes, and preparation for the next step. Freeing of
| |
| 275 page = page->next(); | 291 page = page->next(); |
| 276 } | 292 } |
| 277 | 293 |
| 278 HeapPage* prev_page = NULL; | 294 HeapPage* prev_page = NULL; |
| 279 page = large_pages_; | 295 page = large_pages_; |
| 280 while (page != NULL) { | 296 while (page != NULL) { |
| 281 intptr_t page_in_use = sweeper.SweepLargePage(page); | 297 intptr_t page_in_use = sweeper.SweepLargePage(page); |
| 282 HeapPage* next_page = page->next(); | 298 HeapPage* next_page = page->next(); |
| 283 if (page_in_use == 0) { | 299 if (page_in_use == 0) { |
| 284 FreeLargePage(page, prev_page); | 300 FreeLargePage(page, prev_page); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 311 OS::PrintErr(" done.\n"); | 327 OS::PrintErr(" done.\n"); |
| 312 } | 328 } |
| 313 | 329 |
| 314 count_++; | 330 count_++; |
| 315 // Done, reset the marker. | 331 // Done, reset the marker. |
| 316 ASSERT(sweeping_); | 332 ASSERT(sweeping_); |
| 317 sweeping_ = false; | 333 sweeping_ = false; |
| 318 } | 334 } |
| 319 | 335 |
| 320 } // namespace dart | 336 } // namespace dart |
| OLD | NEW |