Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 "vm/assert.h" | 7 #include "vm/assert.h" |
| 8 #include "vm/gc_marker.h" | 8 #include "vm/gc_marker.h" |
| 9 #include "vm/gc_sweeper.h" | |
| 9 #include "vm/object.h" | 10 #include "vm/object.h" |
| 10 #include "vm/virtual_memory.h" | 11 #include "vm/virtual_memory.h" |
| 11 | 12 |
| 12 namespace dart { | 13 namespace dart { |
| 13 | 14 |
| 14 HeapPage* HeapPage::Initialize(VirtualMemory* memory, bool is_executable) { | 15 HeapPage* HeapPage::Initialize(VirtualMemory* memory, bool is_executable) { |
| 15 ASSERT(memory->size() > VirtualMemory::PageSize()); | 16 ASSERT(memory->size() > VirtualMemory::PageSize()); |
| 16 memory->Commit(is_executable); | 17 memory->Commit(is_executable); |
| 17 | 18 |
| 18 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); | 19 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 42 uword end_addr = top(); | 43 uword end_addr = top(); |
| 43 while (obj_addr < end_addr) { | 44 while (obj_addr < end_addr) { |
| 44 RawObject* raw_obj = RawObject::FromAddr(obj_addr); | 45 RawObject* raw_obj = RawObject::FromAddr(obj_addr); |
| 45 obj_addr += raw_obj->VisitPointers(visitor); | 46 obj_addr += raw_obj->VisitPointers(visitor); |
| 46 } | 47 } |
| 47 ASSERT(obj_addr == end_addr); | 48 ASSERT(obj_addr == end_addr); |
| 48 } | 49 } |
| 49 | 50 |
| 50 | 51 |
| 51 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable) | 52 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable) |
| 52 : heap_(heap), | 53 : freelist_(), |
| 54 heap_(heap), | |
| 53 pages_(NULL), | 55 pages_(NULL), |
| 54 pages_tail_(NULL), | 56 pages_tail_(NULL), |
| 55 large_pages_(NULL), | 57 large_pages_(NULL), |
| 56 max_capacity_(max_capacity), | 58 max_capacity_(max_capacity), |
| 57 capacity_(0), | 59 capacity_(0), |
| 58 in_use_(0), | 60 in_use_(0), |
| 59 count_(0), | 61 count_(0), |
| 60 is_executable_(is_executable), | 62 is_executable_(is_executable), |
| 61 sweeping_(false) { } | 63 sweeping_(false) { } |
| 62 | 64 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 83 intptr_t page_size = Utils::RoundUp(size + sizeof(HeapPage), | 85 intptr_t page_size = Utils::RoundUp(size + sizeof(HeapPage), |
| 84 VirtualMemory::PageSize()); | 86 VirtualMemory::PageSize()); |
| 85 HeapPage* page = HeapPage::Allocate(page_size, is_executable_); | 87 HeapPage* page = HeapPage::Allocate(page_size, is_executable_); |
| 86 page->set_next(large_pages_); | 88 page->set_next(large_pages_); |
| 87 large_pages_ = page; | 89 large_pages_ = page; |
| 88 capacity_ += page_size; | 90 capacity_ += page_size; |
| 89 return page; | 91 return page; |
| 90 } | 92 } |
| 91 | 93 |
| 92 | 94 |
| 95 void PageSpace::FreeLargePage(HeapPage* page, HeapPage* previous_page) { | |
| 96 capacity_ -= page->memory_->size(); | |
| 97 // Remove the page from the list. | |
| 98 if (previous_page != NULL) { | |
| 99 previous_page->set_next(page->next()); | |
| 100 } else { | |
| 101 large_pages_ = page->next(); | |
| 102 } | |
| 103 page->Deallocate(); | |
| 104 } | |
| 105 | |
| 106 | |
| 93 void PageSpace::FreePages(HeapPage* pages) { | 107 void PageSpace::FreePages(HeapPage* pages) { |
| 94 HeapPage* page = pages; | 108 HeapPage* page = pages; |
| 95 while (page != NULL) { | 109 while (page != NULL) { |
| 96 HeapPage* next = page->next(); | 110 HeapPage* next = page->next(); |
| 97 page->Deallocate(); | 111 page->Deallocate(); |
| 98 page = next; | 112 page = next; |
| 99 } | 113 } |
| 100 } | 114 } |
| 101 | 115 |
| 102 | 116 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 } | 192 } |
| 179 | 193 |
| 180 | 194 |
| 181 void PageSpace::MarkSweep() { | 195 void PageSpace::MarkSweep() { |
| 182 // MarkSweep is not reentrant. Make sure that is the case. | 196 // MarkSweep is not reentrant. Make sure that is the case. |
| 183 ASSERT(!sweeping_); | 197 ASSERT(!sweeping_); |
| 184 sweeping_ = true; | 198 sweeping_ = true; |
| 185 Isolate* isolate = Isolate::Current(); | 199 Isolate* isolate = Isolate::Current(); |
| 186 NoHandleScope no_handles(isolate); | 200 NoHandleScope no_handles(isolate); |
| 187 | 201 |
| 202 if (FLAG_verify_before_gc) { | |
| 203 OS::PrintErr("Verifying before MarkSweep... "); | |
| 204 heap_->Verify(); | |
| 205 OS::PrintErr(" done.\n"); | |
| 206 } | |
| 207 | |
| 188 Timer timer(FLAG_verbose_gc, "MarkSweep"); | 208 Timer timer(FLAG_verbose_gc, "MarkSweep"); |
| 189 timer.Start(); | 209 timer.Start(); |
| 190 | 210 |
| 191 // Mark all reachable old-gen objects. | 211 // Mark all reachable old-gen objects. |
| 192 GCMarker marker(heap_); | 212 GCMarker marker(heap_); |
| 193 marker.MarkObjects(isolate, this); | 213 marker.MarkObjects(isolate, this); |
| 194 | 214 |
| 195 UNIMPLEMENTED(); | 215 // Reset the freelists and setup sweeping. |
| 216 freelist_.Reset(); | |
| 217 GCSweeper sweeper(heap_); | |
| 218 intptr_t in_use = 0; | |
| 219 | |
| 220 HeapPage* page = pages_; | |
| 221 while (page != NULL) { | |
| 222 in_use += sweeper.SweepPage(page, &freelist_); | |
| 223 page = page->next(); | |
| 224 } | |
| 225 | |
| 226 HeapPage* prev_page = NULL; | |
| 227 page = large_pages_; | |
| 228 while (page != NULL) { | |
| 229 intptr_t page_in_use = sweeper.SweepLargePage(page); | |
| 230 HeapPage* next_page = page->next(); | |
| 231 if (page_in_use == 0) { | |
| 232 FreeLargePage(page, prev_page); | |
| 233 } else { | |
| 234 prev_page = page; | |
| 235 } | |
| 236 // Advance to the next page. | |
| 237 page = next_page; | |
| 238 } | |
| 239 | |
| 240 // Record data and print if requested. | |
| 241 intptr_t in_use_before = in_use_; | |
| 242 in_use_ = in_use; | |
|
siva
2011/12/14 16:20:13
in_use here is not accounting for the large pages
Ivan Posva
2011/12/15 22:29:19
Done.
| |
| 243 | |
| 196 timer.Stop(); | 244 timer.Stop(); |
| 197 if (FLAG_verbose_gc) { | 245 if (FLAG_verbose_gc) { |
| 198 OS::PrintErr("Mark-Sweep[%d]: %dus\n", count_, timer.TotalElapsedTime()); | 246 const intptr_t KB2 = KB / 2; |
| 247 OS::PrintErr("Mark-Sweep[%d]: %lldus (%dK -> %dK, %dK)\n", | |
|
cshapiro
2011/12/14 18:48:11
Maybe report marking and sweeping time separately?
Ivan Posva
2011/12/15 22:29:19
Many more counters to come here.
| |
| 248 count_, | |
| 249 timer.TotalElapsedTime(), | |
| 250 (in_use_before + (KB2)) / KB, | |
| 251 (in_use + (KB2)) / KB, | |
| 252 (capacity_ + KB2) / KB); | |
| 253 } | |
| 254 | |
| 255 if (FLAG_verify_after_gc) { | |
| 256 OS::PrintErr("Verifying after MarkSweep... "); | |
| 257 heap_->Verify(); | |
| 258 OS::PrintErr(" done.\n"); | |
| 199 } | 259 } |
| 200 | 260 |
| 201 count_++; | 261 count_++; |
| 202 // Done, reset the marker. | 262 // Done, reset the marker. |
| 203 ASSERT(sweeping_); | 263 ASSERT(sweeping_); |
| 204 sweeping_ = false; | 264 sweeping_ = false; |
| 205 } | 265 } |
| 206 | 266 |
| 207 } // namespace dart | 267 } // namespace dart |
| OLD | NEW |