| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
| 6 | 6 |
| 7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 VerifyMarkingVisitor visitor(heap); | 124 VerifyMarkingVisitor visitor(heap); |
| 125 HeapObjectIterator it(page); | 125 HeapObjectIterator it(page); |
| 126 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { | 126 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
| 127 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 127 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
| 128 object->Iterate(&visitor); | 128 object->Iterate(&visitor); |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 | 131 |
| 132 static void VerifyMarking(NewSpace* space) { | 132 static void VerifyMarking(NewSpace* space) { |
| 133 Address end = space->top(); | 133 Address end = space->top(); |
| 134 NewSpacePageIterator it(space->bottom(), end); | |
| 135 // The bottom position is at the start of its page. Allows us to use | 134 // The bottom position is at the start of its page. Allows us to use |
| 136 // page->area_start() as start of range on all pages. | 135 // page->area_start() as start of range on all pages. |
| 137 CHECK_EQ(space->bottom(), Page::FromAddress(space->bottom())->area_start()); | 136 CHECK_EQ(space->bottom(), Page::FromAddress(space->bottom())->area_start()); |
| 138 while (it.has_next()) { | 137 |
| 139 Page* page = it.next(); | 138 NewSpacePageRange range(space->bottom(), end); |
| 140 Address limit = it.has_next() ? page->area_end() : end; | 139 for (auto it = range.begin(); it != range.end();) { |
| 140 Page* page = *(it++); |
| 141 Address limit = it != range.end() ? page->area_end() : end; |
| 141 CHECK(limit == end || !page->Contains(end)); | 142 CHECK(limit == end || !page->Contains(end)); |
| 142 VerifyMarking(space->heap(), page->area_start(), limit); | 143 VerifyMarking(space->heap(), page->area_start(), limit); |
| 143 } | 144 } |
| 144 } | 145 } |
| 145 | 146 |
| 146 | 147 |
| 147 static void VerifyMarking(PagedSpace* space) { | 148 static void VerifyMarking(PagedSpace* space) { |
| 148 PageIterator it(space); | 149 for (Page* p : *space) { |
| 149 | |
| 150 while (it.has_next()) { | |
| 151 Page* p = it.next(); | |
| 152 if (p->IsFlagSet(Page::BLACK_PAGE)) { | 150 if (p->IsFlagSet(Page::BLACK_PAGE)) { |
| 153 VerifyMarkingBlackPage(space->heap(), p); | 151 VerifyMarkingBlackPage(space->heap(), p); |
| 154 } else { | 152 } else { |
| 155 VerifyMarking(space->heap(), p->area_start(), p->area_end()); | 153 VerifyMarking(space->heap(), p->area_start(), p->area_end()); |
| 156 } | 154 } |
| 157 } | 155 } |
| 158 } | 156 } |
| 159 | 157 |
| 160 | 158 |
| 161 static void VerifyMarking(Heap* heap) { | 159 static void VerifyMarking(Heap* heap) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 heap_object = iterator.Next()) { | 195 heap_object = iterator.Next()) { |
| 198 // We skip free space objects. | 196 // We skip free space objects. |
| 199 if (!heap_object->IsFiller()) { | 197 if (!heap_object->IsFiller()) { |
| 200 heap_object->Iterate(&visitor); | 198 heap_object->Iterate(&visitor); |
| 201 } | 199 } |
| 202 } | 200 } |
| 203 } | 201 } |
| 204 | 202 |
| 205 | 203 |
| 206 static void VerifyEvacuation(NewSpace* space) { | 204 static void VerifyEvacuation(NewSpace* space) { |
| 207 NewSpacePageIterator it(space->bottom(), space->top()); | |
| 208 VerifyEvacuationVisitor visitor; | 205 VerifyEvacuationVisitor visitor; |
| 209 | 206 NewSpacePageRange range(space->bottom(), space->top()); |
| 210 while (it.has_next()) { | 207 for (auto it = range.begin(); it != range.end();) { |
| 211 Page* page = it.next(); | 208 Page* page = *(it++); |
| 212 Address current = page->area_start(); | 209 Address current = page->area_start(); |
| 213 Address limit = it.has_next() ? page->area_end() : space->top(); | 210 Address limit = it != range.end() ? page->area_end() : space->top(); |
| 214 CHECK(limit == space->top() || !page->Contains(space->top())); | 211 CHECK(limit == space->top() || !page->Contains(space->top())); |
| 215 while (current < limit) { | 212 while (current < limit) { |
| 216 HeapObject* object = HeapObject::FromAddress(current); | 213 HeapObject* object = HeapObject::FromAddress(current); |
| 217 object->Iterate(&visitor); | 214 object->Iterate(&visitor); |
| 218 current += object->Size(); | 215 current += object->Size(); |
| 219 } | 216 } |
| 220 } | 217 } |
| 221 } | 218 } |
| 222 | 219 |
| 223 | 220 |
| 224 static void VerifyEvacuation(Heap* heap, PagedSpace* space) { | 221 static void VerifyEvacuation(Heap* heap, PagedSpace* space) { |
| 225 if (FLAG_use_allocation_folding && (space == heap->old_space())) { | 222 if (FLAG_use_allocation_folding && (space == heap->old_space())) { |
| 226 return; | 223 return; |
| 227 } | 224 } |
| 228 PageIterator it(space); | 225 for (Page* p : *space) { |
| 229 | |
| 230 while (it.has_next()) { | |
| 231 Page* p = it.next(); | |
| 232 if (p->IsEvacuationCandidate()) continue; | 226 if (p->IsEvacuationCandidate()) continue; |
| 233 VerifyEvacuation(p); | 227 VerifyEvacuation(p); |
| 234 } | 228 } |
| 235 } | 229 } |
| 236 | 230 |
| 237 | 231 |
| 238 static void VerifyEvacuation(Heap* heap) { | 232 static void VerifyEvacuation(Heap* heap) { |
| 239 VerifyEvacuation(heap, heap->old_space()); | 233 VerifyEvacuation(heap, heap->old_space()); |
| 240 VerifyEvacuation(heap, heap->code_space()); | 234 VerifyEvacuation(heap, heap->code_space()); |
| 241 VerifyEvacuation(heap, heap->map_space()); | 235 VerifyEvacuation(heap, heap->map_space()); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 SweepSpaces(); | 347 SweepSpaces(); |
| 354 | 348 |
| 355 EvacuateNewSpaceAndCandidates(); | 349 EvacuateNewSpaceAndCandidates(); |
| 356 | 350 |
| 357 Finish(); | 351 Finish(); |
| 358 } | 352 } |
| 359 | 353 |
| 360 | 354 |
| 361 #ifdef VERIFY_HEAP | 355 #ifdef VERIFY_HEAP |
| 362 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { | 356 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { |
| 363 PageIterator it(space); | 357 for (Page* p : *space) { |
| 364 | |
| 365 while (it.has_next()) { | |
| 366 Page* p = it.next(); | |
| 367 CHECK(p->markbits()->IsClean()); | 358 CHECK(p->markbits()->IsClean()); |
| 368 CHECK_EQ(0, p->LiveBytes()); | 359 CHECK_EQ(0, p->LiveBytes()); |
| 369 } | 360 } |
| 370 } | 361 } |
| 371 | 362 |
| 372 | 363 |
| 373 void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) { | 364 void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) { |
| 374 NewSpacePageIterator it(space->bottom(), space->top()); | 365 for (Page* p : NewSpacePageRange(space->bottom(), space->top())) { |
| 375 | |
| 376 while (it.has_next()) { | |
| 377 Page* p = it.next(); | |
| 378 CHECK(p->markbits()->IsClean()); | 366 CHECK(p->markbits()->IsClean()); |
| 379 CHECK_EQ(0, p->LiveBytes()); | 367 CHECK_EQ(0, p->LiveBytes()); |
| 380 } | 368 } |
| 381 } | 369 } |
| 382 | 370 |
| 383 | 371 |
| 384 void MarkCompactCollector::VerifyMarkbitsAreClean() { | 372 void MarkCompactCollector::VerifyMarkbitsAreClean() { |
| 385 VerifyMarkbitsAreClean(heap_->old_space()); | 373 VerifyMarkbitsAreClean(heap_->old_space()); |
| 386 VerifyMarkbitsAreClean(heap_->code_space()); | 374 VerifyMarkbitsAreClean(heap_->code_space()); |
| 387 VerifyMarkbitsAreClean(heap_->map_space()); | 375 VerifyMarkbitsAreClean(heap_->map_space()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 412 HeapObjectIterator iterator(heap()->map_space()); | 400 HeapObjectIterator iterator(heap()->map_space()); |
| 413 for (HeapObject* obj = iterator.Next(); obj != NULL; obj = iterator.Next()) { | 401 for (HeapObject* obj = iterator.Next(); obj != NULL; obj = iterator.Next()) { |
| 414 Map* map = Map::cast(obj); | 402 Map* map = Map::cast(obj); |
| 415 map->VerifyOmittedMapChecks(); | 403 map->VerifyOmittedMapChecks(); |
| 416 } | 404 } |
| 417 } | 405 } |
| 418 #endif // VERIFY_HEAP | 406 #endif // VERIFY_HEAP |
| 419 | 407 |
| 420 | 408 |
| 421 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { | 409 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { |
| 422 PageIterator it(space); | 410 for (Page* p : *space) { |
| 423 | |
| 424 while (it.has_next()) { | |
| 425 Page* p = it.next(); | |
| 426 Bitmap::Clear(p); | 411 Bitmap::Clear(p); |
| 427 if (p->IsFlagSet(Page::BLACK_PAGE)) { | 412 if (p->IsFlagSet(Page::BLACK_PAGE)) { |
| 428 p->ClearFlag(Page::BLACK_PAGE); | 413 p->ClearFlag(Page::BLACK_PAGE); |
| 429 } | 414 } |
| 430 } | 415 } |
| 431 } | 416 } |
| 432 | 417 |
| 433 | 418 |
| 434 static void ClearMarkbitsInNewSpace(NewSpace* space) { | 419 static void ClearMarkbitsInNewSpace(NewSpace* space) { |
| 435 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); | 420 for (Page* page : *space) { |
| 436 | 421 Bitmap::Clear(page); |
| 437 while (it.has_next()) { | |
| 438 Bitmap::Clear(it.next()); | |
| 439 } | 422 } |
| 440 } | 423 } |
| 441 | 424 |
| 442 | 425 |
| 443 void MarkCompactCollector::ClearMarkbits() { | 426 void MarkCompactCollector::ClearMarkbits() { |
| 444 ClearMarkbitsInPagedSpace(heap_->code_space()); | 427 ClearMarkbitsInPagedSpace(heap_->code_space()); |
| 445 ClearMarkbitsInPagedSpace(heap_->map_space()); | 428 ClearMarkbitsInPagedSpace(heap_->map_space()); |
| 446 ClearMarkbitsInPagedSpace(heap_->old_space()); | 429 ClearMarkbitsInPagedSpace(heap_->old_space()); |
| 447 ClearMarkbitsInNewSpace(heap_->new_space()); | 430 ClearMarkbitsInNewSpace(heap_->new_space()); |
| 448 | 431 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 } | 549 } |
| 567 DCHECK(sweeping_list_[space].empty()); | 550 DCHECK(sweeping_list_[space].empty()); |
| 568 }); | 551 }); |
| 569 late_pages_ = false; | 552 late_pages_ = false; |
| 570 sweeping_in_progress_ = false; | 553 sweeping_in_progress_ = false; |
| 571 } | 554 } |
| 572 | 555 |
| 573 void MarkCompactCollector::Sweeper::EnsureNewSpaceCompleted() { | 556 void MarkCompactCollector::Sweeper::EnsureNewSpaceCompleted() { |
| 574 if (!sweeping_in_progress_) return; | 557 if (!sweeping_in_progress_) return; |
| 575 if (!FLAG_concurrent_sweeping || !IsSweepingCompleted()) { | 558 if (!FLAG_concurrent_sweeping || !IsSweepingCompleted()) { |
| 576 NewSpacePageIterator pit(heap_->new_space()); | 559 for (Page* p : *heap_->new_space()) { |
| 577 while (pit.has_next()) { | 560 SweepOrWaitUntilSweepingCompleted(p); |
| 578 Page* page = pit.next(); | |
| 579 SweepOrWaitUntilSweepingCompleted(page); | |
| 580 } | 561 } |
| 581 } | 562 } |
| 582 } | 563 } |
| 583 | 564 |
| 584 void MarkCompactCollector::EnsureSweepingCompleted() { | 565 void MarkCompactCollector::EnsureSweepingCompleted() { |
| 585 if (!sweeper().sweeping_in_progress()) return; | 566 if (!sweeper().sweeping_in_progress()) return; |
| 586 | 567 |
| 587 sweeper().EnsureCompleted(); | 568 sweeper().EnsureCompleted(); |
| 588 heap()->old_space()->RefillFreeList(); | 569 heap()->old_space()->RefillFreeList(); |
| 589 heap()->code_space()->RefillFreeList(); | 570 heap()->code_space()->RefillFreeList(); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 DCHECK(space->identity() == OLD_SPACE || space->identity() == CODE_SPACE); | 690 DCHECK(space->identity() == OLD_SPACE || space->identity() == CODE_SPACE); |
| 710 | 691 |
| 711 int number_of_pages = space->CountTotalPages(); | 692 int number_of_pages = space->CountTotalPages(); |
| 712 int area_size = space->AreaSize(); | 693 int area_size = space->AreaSize(); |
| 713 | 694 |
| 714 // Pairs of (live_bytes_in_page, page). | 695 // Pairs of (live_bytes_in_page, page). |
| 715 typedef std::pair<int, Page*> LiveBytesPagePair; | 696 typedef std::pair<int, Page*> LiveBytesPagePair; |
| 716 std::vector<LiveBytesPagePair> pages; | 697 std::vector<LiveBytesPagePair> pages; |
| 717 pages.reserve(number_of_pages); | 698 pages.reserve(number_of_pages); |
| 718 | 699 |
| 719 PageIterator it(space); | 700 for (Page* p : *space) { |
| 720 while (it.has_next()) { | |
| 721 Page* p = it.next(); | |
| 722 if (p->NeverEvacuate()) continue; | 701 if (p->NeverEvacuate()) continue; |
| 723 if (p->IsFlagSet(Page::BLACK_PAGE)) continue; | 702 if (p->IsFlagSet(Page::BLACK_PAGE)) continue; |
| 724 // Invariant: Evacuation candidates are just created when marking is | 703 // Invariant: Evacuation candidates are just created when marking is |
| 725 // started. This means that sweeping has finished. Furthermore, at the end | 704 // started. This means that sweeping has finished. Furthermore, at the end |
| 726 // of a GC all evacuation candidates are cleared and their slot buffers are | 705 // of a GC all evacuation candidates are cleared and their slot buffers are |
| 727 // released. | 706 // released. |
| 728 CHECK(!p->IsEvacuationCandidate()); | 707 CHECK(!p->IsEvacuationCandidate()); |
| 729 CHECK_NULL(p->old_to_old_slots()); | 708 CHECK_NULL(p->old_to_old_slots()); |
| 730 CHECK_NULL(p->typed_old_to_old_slots()); | 709 CHECK_NULL(p->typed_old_to_old_slots()); |
| 731 CHECK(p->SweepingDone()); | 710 CHECK(p->SweepingDone()); |
| (...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1985 RecordMigratedSlotVisitor visitor(heap_->mark_compact_collector()); | 1964 RecordMigratedSlotVisitor visitor(heap_->mark_compact_collector()); |
| 1986 object->IterateBody(&visitor); | 1965 object->IterateBody(&visitor); |
| 1987 return true; | 1966 return true; |
| 1988 } | 1967 } |
| 1989 | 1968 |
| 1990 private: | 1969 private: |
| 1991 Heap* heap_; | 1970 Heap* heap_; |
| 1992 }; | 1971 }; |
| 1993 | 1972 |
| 1994 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { | 1973 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { |
| 1995 PageIterator it(space); | 1974 for (Page* p : *space) { |
| 1996 while (it.has_next()) { | |
| 1997 Page* p = it.next(); | |
| 1998 if (!p->IsFlagSet(Page::BLACK_PAGE)) { | 1975 if (!p->IsFlagSet(Page::BLACK_PAGE)) { |
| 1999 DiscoverGreyObjectsOnPage(p); | 1976 DiscoverGreyObjectsOnPage(p); |
| 2000 } | 1977 } |
| 2001 if (marking_deque()->IsFull()) return; | 1978 if (marking_deque()->IsFull()) return; |
| 2002 } | 1979 } |
| 2003 } | 1980 } |
| 2004 | 1981 |
| 2005 | 1982 |
| 2006 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { | 1983 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { |
| 2007 NewSpace* space = heap()->new_space(); | 1984 NewSpace* space = heap()->new_space(); |
| 2008 NewSpacePageIterator it(space->bottom(), space->top()); | 1985 for (Page* page : NewSpacePageRange(space->bottom(), space->top())) { |
| 2009 while (it.has_next()) { | |
| 2010 Page* page = it.next(); | |
| 2011 DiscoverGreyObjectsOnPage(page); | 1986 DiscoverGreyObjectsOnPage(page); |
| 2012 if (marking_deque()->IsFull()) return; | 1987 if (marking_deque()->IsFull()) return; |
| 2013 } | 1988 } |
| 2014 } | 1989 } |
| 2015 | 1990 |
| 2016 | 1991 |
| 2017 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { | 1992 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { |
| 2018 Object* o = *p; | 1993 Object* o = *p; |
| 2019 if (!o->IsHeapObject()) return false; | 1994 if (!o->IsHeapObject()) return false; |
| 2020 HeapObject* heap_object = HeapObject::cast(o); | 1995 HeapObject* heap_object = HeapObject::cast(o); |
| (...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3078 return object; | 3053 return object; |
| 3079 } | 3054 } |
| 3080 } | 3055 } |
| 3081 } | 3056 } |
| 3082 return nullptr; | 3057 return nullptr; |
| 3083 } | 3058 } |
| 3084 | 3059 |
| 3085 | 3060 |
| 3086 void MarkCompactCollector::EvacuateNewSpacePrologue() { | 3061 void MarkCompactCollector::EvacuateNewSpacePrologue() { |
| 3087 NewSpace* new_space = heap()->new_space(); | 3062 NewSpace* new_space = heap()->new_space(); |
| 3088 NewSpacePageIterator it(new_space->bottom(), new_space->top()); | |
| 3089 // Append the list of new space pages to be processed. | 3063 // Append the list of new space pages to be processed. |
| 3090 while (it.has_next()) { | 3064 for (Page* p : NewSpacePageRange(new_space->bottom(), new_space->top())) { |
| 3091 newspace_evacuation_candidates_.Add(it.next()); | 3065 newspace_evacuation_candidates_.Add(p); |
| 3092 } | 3066 } |
| 3093 new_space->Flip(); | 3067 new_space->Flip(); |
| 3094 new_space->ResetAllocationInfo(); | 3068 new_space->ResetAllocationInfo(); |
| 3095 } | 3069 } |
| 3096 | 3070 |
| 3097 class MarkCompactCollector::Evacuator : public Malloced { | 3071 class MarkCompactCollector::Evacuator : public Malloced { |
| 3098 public: | 3072 public: |
| 3099 enum EvacuationMode { | 3073 enum EvacuationMode { |
| 3100 kObjectsNewToOld, | 3074 kObjectsNewToOld, |
| 3101 kPageNewToOld, | 3075 kPageNewToOld, |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3813 object->IterateBody(map->instance_type(), size, visitor); | 3787 object->IterateBody(map->instance_type(), size, visitor); |
| 3814 } | 3788 } |
| 3815 } | 3789 } |
| 3816 }; | 3790 }; |
| 3817 | 3791 |
| 3818 void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) { | 3792 void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) { |
| 3819 PageParallelJob<ToSpacePointerUpdateJobTraits> job( | 3793 PageParallelJob<ToSpacePointerUpdateJobTraits> job( |
| 3820 heap, heap->isolate()->cancelable_task_manager(), semaphore); | 3794 heap, heap->isolate()->cancelable_task_manager(), semaphore); |
| 3821 Address space_start = heap->new_space()->bottom(); | 3795 Address space_start = heap->new_space()->bottom(); |
| 3822 Address space_end = heap->new_space()->top(); | 3796 Address space_end = heap->new_space()->top(); |
| 3823 NewSpacePageIterator it(space_start, space_end); | 3797 for (Page* page : NewSpacePageRange(space_start, space_end)) { |
| 3824 while (it.has_next()) { | |
| 3825 Page* page = it.next(); | |
| 3826 Address start = | 3798 Address start = |
| 3827 page->Contains(space_start) ? space_start : page->area_start(); | 3799 page->Contains(space_start) ? space_start : page->area_start(); |
| 3828 Address end = page->Contains(space_end) ? space_end : page->area_end(); | 3800 Address end = page->Contains(space_end) ? space_end : page->area_end(); |
| 3829 job.AddPage(page, std::make_pair(start, end)); | 3801 job.AddPage(page, std::make_pair(start, end)); |
| 3830 } | 3802 } |
| 3831 PointersUpdatingVisitor visitor; | 3803 PointersUpdatingVisitor visitor; |
| 3832 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; | 3804 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; |
| 3833 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); | 3805 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); |
| 3834 } | 3806 } |
| 3835 | 3807 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3970 void MarkCompactCollector::Sweeper::AddSweepingPageSafe(AllocationSpace space, | 3942 void MarkCompactCollector::Sweeper::AddSweepingPageSafe(AllocationSpace space, |
| 3971 Page* page) { | 3943 Page* page) { |
| 3972 base::LockGuard<base::Mutex> guard(&mutex_); | 3944 base::LockGuard<base::Mutex> guard(&mutex_); |
| 3973 sweeping_list_[space].push_back(page); | 3945 sweeping_list_[space].push_back(page); |
| 3974 } | 3946 } |
| 3975 | 3947 |
| 3976 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { | 3948 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { |
| 3977 Address space_top = space->top(); | 3949 Address space_top = space->top(); |
| 3978 space->ClearStats(); | 3950 space->ClearStats(); |
| 3979 | 3951 |
| 3980 PageIterator it(space); | |
| 3981 | |
| 3982 int will_be_swept = 0; | 3952 int will_be_swept = 0; |
| 3983 bool unused_page_present = false; | 3953 bool unused_page_present = false; |
| 3984 | 3954 |
| 3985 while (it.has_next()) { | 3955 // Loop needs to support deletion if live bytes == 0 for a page. |
| 3986 Page* p = it.next(); | 3956 for (auto it = space->begin(); it != space->end();) { |
| 3957 Page* p = *(it++); |
| 3987 DCHECK(p->SweepingDone()); | 3958 DCHECK(p->SweepingDone()); |
| 3988 | 3959 |
| 3989 if (p->IsEvacuationCandidate()) { | 3960 if (p->IsEvacuationCandidate()) { |
| 3990 // Will be processed in EvacuateNewSpaceAndCandidates. | 3961 // Will be processed in EvacuateNewSpaceAndCandidates. |
| 3991 DCHECK(evacuation_candidates_.length() > 0); | 3962 DCHECK(evacuation_candidates_.length() > 0); |
| 3992 continue; | 3963 continue; |
| 3993 } | 3964 } |
| 3994 | 3965 |
| 3995 // We can not sweep black pages, since all mark bits are set for these | 3966 // We can not sweep black pages, since all mark bits are set for these |
| 3996 // pages. | 3967 // pages. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4117 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4088 MarkBit mark_bit = Marking::MarkBitFrom(host); |
| 4118 if (Marking::IsBlack(mark_bit)) { | 4089 if (Marking::IsBlack(mark_bit)) { |
| 4119 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 4090 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
| 4120 RecordRelocSlot(host, &rinfo, target); | 4091 RecordRelocSlot(host, &rinfo, target); |
| 4121 } | 4092 } |
| 4122 } | 4093 } |
| 4123 } | 4094 } |
| 4124 | 4095 |
| 4125 } // namespace internal | 4096 } // namespace internal |
| 4126 } // namespace v8 | 4097 } // namespace v8 |
| OLD | NEW |