Chromium Code Reviews| 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 VerifyMarking(space->heap(), page->area_start(), limit); | 137 VerifyMarking(space->heap(), page->area_start(), limit); |
| 138 } | 138 } |
| 139 } | 139 } |
| 140 | 140 |
| 141 | 141 |
| 142 static void VerifyMarking(PagedSpace* space) { | 142 static void VerifyMarking(PagedSpace* space) { |
| 143 PageIterator it(space); | 143 PageIterator it(space); |
| 144 | 144 |
| 145 while (it.has_next()) { | 145 while (it.has_next()) { |
| 146 Page* p = it.next(); | 146 Page* p = it.next(); |
| 147 VerifyMarking(space->heap(), p->area_start(), p->area_end()); | 147 if (!p->IsFlagSet(Page::BLACK_PAGE)) { |
| 148 VerifyMarking(space->heap(), p->area_start(), p->area_end()); | |
| 149 } | |
|
ulan
2016/02/10 10:27:39
It would be great to verify coloring invariant for
Hannes Payer (out of office)
2016/02/11 18:18:07
Done.
| |
| 148 } | 150 } |
| 149 } | 151 } |
| 150 | 152 |
| 151 | 153 |
| 152 static void VerifyMarking(Heap* heap) { | 154 static void VerifyMarking(Heap* heap) { |
| 153 VerifyMarking(heap->old_space()); | 155 VerifyMarking(heap->old_space()); |
| 154 VerifyMarking(heap->code_space()); | 156 VerifyMarking(heap->code_space()); |
| 155 VerifyMarking(heap->map_space()); | 157 VerifyMarking(heap->map_space()); |
| 156 VerifyMarking(heap->new_space()); | 158 VerifyMarking(heap->new_space()); |
| 157 | 159 |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 441 map->VerifyOmittedMapChecks(); | 443 map->VerifyOmittedMapChecks(); |
| 442 } | 444 } |
| 443 } | 445 } |
| 444 #endif // VERIFY_HEAP | 446 #endif // VERIFY_HEAP |
| 445 | 447 |
| 446 | 448 |
| 447 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { | 449 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { |
| 448 PageIterator it(space); | 450 PageIterator it(space); |
| 449 | 451 |
| 450 while (it.has_next()) { | 452 while (it.has_next()) { |
| 451 Bitmap::Clear(it.next()); | 453 Page* p = it.next(); |
| 454 Bitmap::Clear(p); | |
| 455 if (p->IsFlagSet(Page::BLACK_PAGE)) { | |
| 456 p->ClearFlag(Page::BLACK_PAGE); | |
| 457 } | |
| 452 } | 458 } |
| 453 } | 459 } |
| 454 | 460 |
| 455 | 461 |
| 456 static void ClearMarkbitsInNewSpace(NewSpace* space) { | 462 static void ClearMarkbitsInNewSpace(NewSpace* space) { |
| 457 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); | 463 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); |
| 458 | 464 |
| 459 while (it.has_next()) { | 465 while (it.has_next()) { |
| 460 Bitmap::Clear(it.next()); | 466 Bitmap::Clear(it.next()); |
| 461 } | 467 } |
| 462 } | 468 } |
| 463 | 469 |
| 464 | 470 |
| 465 void MarkCompactCollector::ClearMarkbits() { | 471 void MarkCompactCollector::ClearMarkbits() { |
| 466 ClearMarkbitsInPagedSpace(heap_->code_space()); | 472 ClearMarkbitsInPagedSpace(heap_->code_space()); |
| 467 ClearMarkbitsInPagedSpace(heap_->map_space()); | 473 ClearMarkbitsInPagedSpace(heap_->map_space()); |
| 468 ClearMarkbitsInPagedSpace(heap_->old_space()); | 474 ClearMarkbitsInPagedSpace(heap_->old_space()); |
| 469 ClearMarkbitsInNewSpace(heap_->new_space()); | 475 ClearMarkbitsInNewSpace(heap_->new_space()); |
| 470 | 476 |
| 471 LargeObjectIterator it(heap_->lo_space()); | 477 LargeObjectIterator it(heap_->lo_space()); |
| 472 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 478 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
| 473 Marking::MarkWhite(Marking::MarkBitFrom(obj)); | 479 Marking::MarkWhite(Marking::MarkBitFrom(obj)); |
| 474 Page::FromAddress(obj->address())->ResetProgressBar(); | 480 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
| 475 Page::FromAddress(obj->address())->ResetLiveBytes(); | 481 chunk->ResetProgressBar(); |
| 482 chunk->ResetLiveBytes(); | |
| 483 if (chunk->IsFlagSet(Page::BLACK_PAGE)) { | |
| 484 chunk->ClearFlag(Page::BLACK_PAGE); | |
| 485 } | |
| 476 } | 486 } |
| 477 } | 487 } |
| 478 | 488 |
| 479 | 489 |
| 480 class MarkCompactCollector::SweeperTask : public v8::Task { | 490 class MarkCompactCollector::SweeperTask : public v8::Task { |
| 481 public: | 491 public: |
| 482 SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {} | 492 SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {} |
| 483 | 493 |
| 484 virtual ~SweeperTask() {} | 494 virtual ~SweeperTask() {} |
| 485 | 495 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 574 pending_sweeper_tasks_semaphore_.Signal(); | 584 pending_sweeper_tasks_semaphore_.Signal(); |
| 575 return true; | 585 return true; |
| 576 } | 586 } |
| 577 | 587 |
| 578 | 588 |
| 579 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { | 589 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { |
| 580 // This is only used when resizing an object. | 590 // This is only used when resizing an object. |
| 581 DCHECK(MemoryChunk::FromAddress(old_start) == | 591 DCHECK(MemoryChunk::FromAddress(old_start) == |
| 582 MemoryChunk::FromAddress(new_start)); | 592 MemoryChunk::FromAddress(new_start)); |
| 583 | 593 |
| 584 if (!heap->incremental_marking()->IsMarking()) return; | 594 if (!heap->incremental_marking()->IsMarking() || |
| 595 Page::FromAddress(old_start)->IsFlagSet(Page::BLACK_PAGE)) | |
| 596 return; | |
| 585 | 597 |
| 586 // If the mark doesn't move, we don't check the color of the object. | 598 // If the mark doesn't move, we don't check the color of the object. |
| 587 // It doesn't matter whether the object is black, since it hasn't changed | 599 // It doesn't matter whether the object is black, since it hasn't changed |
| 588 // size, so the adjustment to the live data count will be zero anyway. | 600 // size, so the adjustment to the live data count will be zero anyway. |
| 589 if (old_start == new_start) return; | 601 if (old_start == new_start) return; |
| 590 | 602 |
| 591 MarkBit new_mark_bit = MarkBitFrom(new_start); | 603 MarkBit new_mark_bit = MarkBitFrom(new_start); |
| 592 MarkBit old_mark_bit = MarkBitFrom(old_start); | 604 MarkBit old_mark_bit = MarkBitFrom(old_start); |
| 593 | 605 |
| 594 #ifdef DEBUG | 606 #ifdef DEBUG |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 683 | 695 |
| 684 // Pairs of (live_bytes_in_page, page). | 696 // Pairs of (live_bytes_in_page, page). |
| 685 typedef std::pair<int, Page*> LiveBytesPagePair; | 697 typedef std::pair<int, Page*> LiveBytesPagePair; |
| 686 std::vector<LiveBytesPagePair> pages; | 698 std::vector<LiveBytesPagePair> pages; |
| 687 pages.reserve(number_of_pages); | 699 pages.reserve(number_of_pages); |
| 688 | 700 |
| 689 PageIterator it(space); | 701 PageIterator it(space); |
| 690 while (it.has_next()) { | 702 while (it.has_next()) { |
| 691 Page* p = it.next(); | 703 Page* p = it.next(); |
| 692 if (p->NeverEvacuate()) continue; | 704 if (p->NeverEvacuate()) continue; |
| 705 if (p->IsFlagSet(Page::BLACK_PAGE)) continue; | |
| 693 if (p->IsFlagSet(Page::POPULAR_PAGE)) { | 706 if (p->IsFlagSet(Page::POPULAR_PAGE)) { |
| 694 // This page had slots buffer overflow on previous GC, skip it. | 707 // This page had slots buffer overflow on previous GC, skip it. |
| 695 p->ClearFlag(Page::POPULAR_PAGE); | 708 p->ClearFlag(Page::POPULAR_PAGE); |
| 696 continue; | 709 continue; |
| 697 } | 710 } |
| 698 // Invariant: Evacuation candidates are just created when marking is | 711 // Invariant: Evacuation candidates are just created when marking is |
| 699 // started. This means that sweeping has finished. Furthermore, at the end | 712 // started. This means that sweeping has finished. Furthermore, at the end |
| 700 // of a GC all evacuation candidates are cleared and their slot buffers are | 713 // of a GC all evacuation candidates are cleared and their slot buffers are |
| 701 // released. | 714 // released. |
| 702 CHECK(!p->IsEvacuationCandidate()); | 715 CHECK(!p->IsEvacuationCandidate()); |
| (...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1726 } | 1739 } |
| 1727 return false; | 1740 return false; |
| 1728 } | 1741 } |
| 1729 }; | 1742 }; |
| 1730 | 1743 |
| 1731 | 1744 |
| 1732 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { | 1745 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { |
| 1733 PageIterator it(space); | 1746 PageIterator it(space); |
| 1734 while (it.has_next()) { | 1747 while (it.has_next()) { |
| 1735 Page* p = it.next(); | 1748 Page* p = it.next(); |
| 1736 DiscoverGreyObjectsOnPage(p); | 1749 if (!p->IsFlagSet(Page::BLACK_PAGE)) { |
| 1737 if (marking_deque()->IsFull()) return; | 1750 DiscoverGreyObjectsOnPage(p); |
| 1751 if (marking_deque()->IsFull()) return; | |
| 1752 } | |
| 1738 } | 1753 } |
| 1739 } | 1754 } |
| 1740 | 1755 |
| 1741 | 1756 |
| 1742 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { | 1757 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { |
| 1743 NewSpace* space = heap()->new_space(); | 1758 NewSpace* space = heap()->new_space(); |
| 1744 NewSpacePageIterator it(space->bottom(), space->top()); | 1759 NewSpacePageIterator it(space->bottom(), space->top()); |
| 1745 while (it.has_next()) { | 1760 while (it.has_next()) { |
| 1746 NewSpacePage* page = it.next(); | 1761 NewSpacePage* page = it.next(); |
| 1747 DiscoverGreyObjectsOnPage(page); | 1762 DiscoverGreyObjectsOnPage(page); |
| (...skipping 1158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2906 // for it. | 2921 // for it. |
| 2907 CHECK(large_object->IsHeapObject()); | 2922 CHECK(large_object->IsHeapObject()); |
| 2908 HeapObject* large_heap_object = HeapObject::cast(large_object); | 2923 HeapObject* large_heap_object = HeapObject::cast(large_object); |
| 2909 if (IsMarked(large_heap_object)) { | 2924 if (IsMarked(large_heap_object)) { |
| 2910 *out_object = large_heap_object; | 2925 *out_object = large_heap_object; |
| 2911 return true; | 2926 return true; |
| 2912 } | 2927 } |
| 2913 return false; | 2928 return false; |
| 2914 } | 2929 } |
| 2915 | 2930 |
| 2931 // If we are on a black page, we cannot find the actual object start | |
| 2932 // easiliy. We just return true but do not set the out_object. | |
| 2933 if (p->IsFlagSet(Page::BLACK_PAGE)) { | |
| 2934 return true; | |
| 2935 } | |
| 2936 | |
| 2916 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); | 2937 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); |
| 2917 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; | 2938 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; |
| 2918 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); | 2939 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); |
| 2919 MarkBit::CellType* cells = p->markbits()->cells(); | 2940 MarkBit::CellType* cells = p->markbits()->cells(); |
| 2920 Address base_address = p->area_start(); | 2941 Address base_address = p->area_start(); |
| 2921 unsigned int base_address_cell_index = Bitmap::IndexToCell( | 2942 unsigned int base_address_cell_index = Bitmap::IndexToCell( |
| 2922 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); | 2943 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); |
| 2923 | 2944 |
| 2924 // Check if the slot points to the start of an object. This can happen e.g. | 2945 // Check if the slot points to the start of an object. This can happen e.g. |
| 2925 // when we left trim a fixed array. Such slots are invalid and we can remove | 2946 // when we left trim a fixed array. Such slots are invalid and we can remove |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2986 // Slots pointing to the first word of an object are invalid and removed. | 3007 // Slots pointing to the first word of an object are invalid and removed. |
| 2987 // This can happen when we move the object header while left trimming. | 3008 // This can happen when we move the object header while left trimming. |
| 2988 *out_object = object; | 3009 *out_object = object; |
| 2989 return true; | 3010 return true; |
| 2990 } | 3011 } |
| 2991 return false; | 3012 return false; |
| 2992 } | 3013 } |
| 2993 | 3014 |
| 2994 | 3015 |
| 2995 bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) { | 3016 bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) { |
| 2996 // This function does not support large objects right now. | |
| 2997 Space* owner = p->owner(); | 3017 Space* owner = p->owner(); |
| 2998 if (owner == heap_->lo_space() || owner == NULL) { | 3018 if (owner == heap_->lo_space() || owner == NULL) { |
| 2999 Object* large_object = heap_->lo_space()->FindObject(slot); | 3019 Object* large_object = heap_->lo_space()->FindObject(slot); |
| 3000 // This object has to exist, otherwise we would not have recorded a slot | 3020 // This object has to exist, otherwise we would not have recorded a slot |
| 3001 // for it. | 3021 // for it. |
| 3002 CHECK(large_object->IsHeapObject()); | 3022 CHECK(large_object->IsHeapObject()); |
| 3003 HeapObject* large_heap_object = HeapObject::cast(large_object); | 3023 HeapObject* large_heap_object = HeapObject::cast(large_object); |
| 3004 if (IsMarked(large_heap_object)) { | 3024 if (IsMarked(large_heap_object)) { |
| 3005 return true; | 3025 return true; |
| 3006 } | 3026 } |
| 3007 return false; | 3027 return false; |
| 3008 } | 3028 } |
| 3009 | 3029 |
| 3030 if (p->IsFlagSet(Page::BLACK_PAGE)) return true; | |
| 3031 | |
| 3010 LiveObjectIterator<kBlackObjects> it(p); | 3032 LiveObjectIterator<kBlackObjects> it(p); |
| 3011 HeapObject* object = NULL; | 3033 HeapObject* object = NULL; |
| 3012 while ((object = it.Next()) != NULL) { | 3034 while ((object = it.Next()) != NULL) { |
| 3013 int size = object->Size(); | 3035 int size = object->Size(); |
| 3014 | 3036 |
| 3015 if (object->address() > slot) return false; | 3037 if (object->address() > slot) return false; |
| 3016 if (object->address() <= slot && slot < (object->address() + size)) { | 3038 if (object->address() <= slot && slot < (object->address() + size)) { |
| 3017 return true; | 3039 return true; |
| 3018 } | 3040 } |
| 3019 } | 3041 } |
| 3020 return false; | 3042 return false; |
| 3021 } | 3043 } |
| 3022 | 3044 |
| 3023 | 3045 |
| 3024 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { | 3046 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { |
| 3025 HeapObject* object = NULL; | |
| 3026 // The target object is black but we don't know if the source slot is black. | 3047 // The target object is black but we don't know if the source slot is black. |
| 3027 // The source object could have died and the slot could be part of a free | 3048 // The source object could have died and the slot could be part of a free |
| 3028 // space. Find out based on mark bits if the slot is part of a live object. | 3049 // space. Find out based on mark bits if the slot is part of a live object. |
| 3029 if (!IsSlotInBlackObject(Page::FromAddress(slot), slot, &object)) { | 3050 Page* page = Page::FromAddress(slot); |
| 3051 HeapObject* object = NULL; | |
| 3052 if (!IsSlotInBlackObject(page, slot, &object)) { | |
| 3030 return false; | 3053 return false; |
| 3031 } | 3054 } |
| 3032 | 3055 |
| 3033 DCHECK(object != NULL); | 3056 // If the slot is on a black page, the object will be live. |
| 3057 DCHECK(object != NULL || page->IsFlagSet(Page::BLACK_PAGE)); | |
| 3058 if (page->IsFlagSet(Page::BLACK_PAGE)) { | |
| 3059 return true; | |
| 3060 } | |
| 3061 | |
| 3034 int offset = static_cast<int>(slot - object->address()); | 3062 int offset = static_cast<int>(slot - object->address()); |
| 3035 return object->IsValidSlot(offset); | 3063 return object->IsValidSlot(offset); |
| 3036 } | 3064 } |
| 3037 | 3065 |
| 3038 | 3066 |
| 3039 void MarkCompactCollector::VerifyIsSlotInLiveObject(Address slot, | 3067 void MarkCompactCollector::VerifyIsSlotInLiveObject(Address slot, |
| 3040 HeapObject* object) { | 3068 HeapObject* object) { |
| 3041 // The target object has to be black. | 3069 // The target object has to be black. |
| 3042 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 3070 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
| 3043 | 3071 |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3426 // Slots in live objects pointing into evacuation candidates are updated | 3454 // Slots in live objects pointing into evacuation candidates are updated |
| 3427 // if requested. | 3455 // if requested. |
| 3428 // Returns the size of the biggest continuous freed memory chunk in bytes. | 3456 // Returns the size of the biggest continuous freed memory chunk in bytes. |
| 3429 template <SweepingMode sweeping_mode, | 3457 template <SweepingMode sweeping_mode, |
| 3430 MarkCompactCollector::SweepingParallelism parallelism, | 3458 MarkCompactCollector::SweepingParallelism parallelism, |
| 3431 SkipListRebuildingMode skip_list_mode, | 3459 SkipListRebuildingMode skip_list_mode, |
| 3432 FreeSpaceTreatmentMode free_space_mode> | 3460 FreeSpaceTreatmentMode free_space_mode> |
| 3433 static int Sweep(PagedSpace* space, FreeList* free_list, Page* p, | 3461 static int Sweep(PagedSpace* space, FreeList* free_list, Page* p, |
| 3434 ObjectVisitor* v) { | 3462 ObjectVisitor* v) { |
| 3435 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); | 3463 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); |
| 3464 DCHECK(!p->IsFlagSet(Page::BLACK_PAGE)); | |
| 3436 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, | 3465 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, |
| 3437 space->identity() == CODE_SPACE); | 3466 space->identity() == CODE_SPACE); |
| 3438 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); | 3467 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); |
| 3439 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || | 3468 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || |
| 3440 sweeping_mode == SWEEP_ONLY); | 3469 sweeping_mode == SWEEP_ONLY); |
| 3441 | 3470 |
| 3442 Address free_start = p->area_start(); | 3471 Address free_start = p->area_start(); |
| 3443 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3472 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
| 3444 | 3473 |
| 3445 // If we use the skip list for code space pages, we have to lock the skip | 3474 // If we use the skip list for code space pages, we have to lock the skip |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3882 | 3911 |
| 3883 PageIterator it(space); | 3912 PageIterator it(space); |
| 3884 | 3913 |
| 3885 int will_be_swept = 0; | 3914 int will_be_swept = 0; |
| 3886 bool unused_page_present = false; | 3915 bool unused_page_present = false; |
| 3887 | 3916 |
| 3888 while (it.has_next()) { | 3917 while (it.has_next()) { |
| 3889 Page* p = it.next(); | 3918 Page* p = it.next(); |
| 3890 DCHECK(p->SweepingDone()); | 3919 DCHECK(p->SweepingDone()); |
| 3891 | 3920 |
| 3921 // We can not sweep black pages, since all mark bits are set for these | |
| 3922 // pages. | |
| 3923 if (p->IsFlagSet(Page::BLACK_PAGE)) { | |
| 3924 Bitmap::Clear(p); | |
| 3925 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); | |
| 3926 p->ClearFlag(Page::BLACK_PAGE); | |
| 3927 // TODO(hpayer): Free unused memory of last black page. | |
| 3928 continue; | |
| 3929 } | |
| 3930 | |
| 3892 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION) || | 3931 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION) || |
| 3893 p->IsEvacuationCandidate()) { | 3932 p->IsEvacuationCandidate()) { |
| 3894 // Will be processed in EvacuateNewSpaceAndCandidates. | 3933 // Will be processed in EvacuateNewSpaceAndCandidates. |
| 3895 DCHECK(evacuation_candidates_.length() > 0); | 3934 DCHECK(evacuation_candidates_.length() > 0); |
| 3896 continue; | 3935 continue; |
| 3897 } | 3936 } |
| 3898 | 3937 |
| 3899 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { | 3938 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { |
| 3900 // We need to sweep the page to get it into an iterable state again. Note | 3939 // We need to sweep the page to get it into an iterable state again. Note |
| 3901 // that this adds unusable memory into the free list that is later on | 3940 // that this adds unusable memory into the free list that is later on |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4056 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4095 MarkBit mark_bit = Marking::MarkBitFrom(host); |
| 4057 if (Marking::IsBlack(mark_bit)) { | 4096 if (Marking::IsBlack(mark_bit)) { |
| 4058 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 4097 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
| 4059 RecordRelocSlot(&rinfo, target); | 4098 RecordRelocSlot(&rinfo, target); |
| 4060 } | 4099 } |
| 4061 } | 4100 } |
| 4062 } | 4101 } |
| 4063 | 4102 |
| 4064 } // namespace internal | 4103 } // namespace internal |
| 4065 } // namespace v8 | 4104 } // namespace v8 |
| OLD | NEW |