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

Side by Side Diff: src/heap/mark-compact.cc

Issue 1420423009: [heap] Black allocation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); 112 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
113 CHECK(current >= next_object_must_be_here_or_later); 113 CHECK(current >= next_object_must_be_here_or_later);
114 object->Iterate(&visitor); 114 object->Iterate(&visitor);
115 next_object_must_be_here_or_later = current + object->Size(); 115 next_object_must_be_here_or_later = current + object->Size();
116 // The next word for sure belongs to the current object, jump over it. 116 // The next word for sure belongs to the current object, jump over it.
117 current += kPointerSize; 117 current += kPointerSize;
118 } 118 }
119 } 119 }
120 } 120 }
121 121
122 static void VerifyMarkingBlackPage(Heap* heap, Page* page) {
123 CHECK(page->IsFlagSet(Page::BLACK_PAGE));
124 VerifyMarkingVisitor visitor(heap);
125 HeapObjectIterator it(page);
126 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
127 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
128 object->Iterate(&visitor);
129 }
130 }
122 131
123 static void VerifyMarking(NewSpace* space) { 132 static void VerifyMarking(NewSpace* space) {
124 Address end = space->top(); 133 Address end = space->top();
125 NewSpacePageIterator it(space->bottom(), end); 134 NewSpacePageIterator it(space->bottom(), end);
126 // The bottom position is at the start of its page. Allows us to use 135 // The bottom position is at the start of its page. Allows us to use
127 // page->area_start() as start of range on all pages. 136 // page->area_start() as start of range on all pages.
128 CHECK_EQ(space->bottom(), 137 CHECK_EQ(space->bottom(),
129 NewSpacePage::FromAddress(space->bottom())->area_start()); 138 NewSpacePage::FromAddress(space->bottom())->area_start());
130 while (it.has_next()) { 139 while (it.has_next()) {
131 NewSpacePage* page = it.next(); 140 NewSpacePage* page = it.next();
132 Address limit = it.has_next() ? page->area_end() : end; 141 Address limit = it.has_next() ? page->area_end() : end;
133 CHECK(limit == end || !page->Contains(end)); 142 CHECK(limit == end || !page->Contains(end));
134 VerifyMarking(space->heap(), page->area_start(), limit); 143 VerifyMarking(space->heap(), page->area_start(), limit);
135 } 144 }
136 } 145 }
137 146
138 147
139 static void VerifyMarking(PagedSpace* space) { 148 static void VerifyMarking(PagedSpace* space) {
140 PageIterator it(space); 149 PageIterator it(space);
141 150
142 while (it.has_next()) { 151 while (it.has_next()) {
143 Page* p = it.next(); 152 Page* p = it.next();
144 VerifyMarking(space->heap(), p->area_start(), p->area_end()); 153 if (p->IsFlagSet(Page::BLACK_PAGE)) {
154 VerifyMarkingBlackPage(space->heap(), p);
155 } else {
156 VerifyMarking(space->heap(), p->area_start(), p->area_end());
157 }
145 } 158 }
146 } 159 }
147 160
148 161
149 static void VerifyMarking(Heap* heap) { 162 static void VerifyMarking(Heap* heap) {
150 VerifyMarking(heap->old_space()); 163 VerifyMarking(heap->old_space());
151 VerifyMarking(heap->code_space()); 164 VerifyMarking(heap->code_space());
152 VerifyMarking(heap->map_space()); 165 VerifyMarking(heap->map_space());
153 VerifyMarking(heap->new_space()); 166 VerifyMarking(heap->new_space());
154 167
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 map->VerifyOmittedMapChecks(); 420 map->VerifyOmittedMapChecks();
408 } 421 }
409 } 422 }
410 #endif // VERIFY_HEAP 423 #endif // VERIFY_HEAP
411 424
412 425
413 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { 426 static void ClearMarkbitsInPagedSpace(PagedSpace* space) {
414 PageIterator it(space); 427 PageIterator it(space);
415 428
416 while (it.has_next()) { 429 while (it.has_next()) {
417 Bitmap::Clear(it.next()); 430 Page* p = it.next();
431 Bitmap::Clear(p);
432 if (p->IsFlagSet(Page::BLACK_PAGE)) {
433 p->ClearFlag(Page::BLACK_PAGE);
434 }
418 } 435 }
419 } 436 }
420 437
421 438
422 static void ClearMarkbitsInNewSpace(NewSpace* space) { 439 static void ClearMarkbitsInNewSpace(NewSpace* space) {
423 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); 440 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd());
424 441
425 while (it.has_next()) { 442 while (it.has_next()) {
426 Bitmap::Clear(it.next()); 443 Bitmap::Clear(it.next());
427 } 444 }
428 } 445 }
429 446
430 447
431 void MarkCompactCollector::ClearMarkbits() { 448 void MarkCompactCollector::ClearMarkbits() {
432 ClearMarkbitsInPagedSpace(heap_->code_space()); 449 ClearMarkbitsInPagedSpace(heap_->code_space());
433 ClearMarkbitsInPagedSpace(heap_->map_space()); 450 ClearMarkbitsInPagedSpace(heap_->map_space());
434 ClearMarkbitsInPagedSpace(heap_->old_space()); 451 ClearMarkbitsInPagedSpace(heap_->old_space());
435 ClearMarkbitsInNewSpace(heap_->new_space()); 452 ClearMarkbitsInNewSpace(heap_->new_space());
436 453
437 LargeObjectIterator it(heap_->lo_space()); 454 LargeObjectIterator it(heap_->lo_space());
438 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 455 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
439 Marking::MarkWhite(Marking::MarkBitFrom(obj)); 456 Marking::MarkWhite(Marking::MarkBitFrom(obj));
440 Page::FromAddress(obj->address())->ResetProgressBar(); 457 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
441 Page::FromAddress(obj->address())->ResetLiveBytes(); 458 chunk->ResetProgressBar();
459 chunk->ResetLiveBytes();
460 if (chunk->IsFlagSet(Page::BLACK_PAGE)) {
461 chunk->ClearFlag(Page::BLACK_PAGE);
462 }
442 } 463 }
443 } 464 }
444 465
445 466
446 class MarkCompactCollector::SweeperTask : public v8::Task { 467 class MarkCompactCollector::SweeperTask : public v8::Task {
447 public: 468 public:
448 SweeperTask(Heap* heap, AllocationSpace space_to_start) 469 SweeperTask(Heap* heap, AllocationSpace space_to_start)
449 : heap_(heap), space_to_start_(space_to_start) {} 470 : heap_(heap), space_to_start_(space_to_start) {}
450 471
451 virtual ~SweeperTask() {} 472 virtual ~SweeperTask() {}
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 pending_sweeper_tasks_semaphore_.Signal(); 569 pending_sweeper_tasks_semaphore_.Signal();
549 return true; 570 return true;
550 } 571 }
551 572
552 573
553 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { 574 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) {
554 // This is only used when resizing an object. 575 // This is only used when resizing an object.
555 DCHECK(MemoryChunk::FromAddress(old_start) == 576 DCHECK(MemoryChunk::FromAddress(old_start) ==
556 MemoryChunk::FromAddress(new_start)); 577 MemoryChunk::FromAddress(new_start));
557 578
558 if (!heap->incremental_marking()->IsMarking()) return; 579 if (!heap->incremental_marking()->IsMarking() ||
580 Page::FromAddress(old_start)->IsFlagSet(Page::BLACK_PAGE))
581 return;
559 582
560 // If the mark doesn't move, we don't check the color of the object. 583 // If the mark doesn't move, we don't check the color of the object.
561 // It doesn't matter whether the object is black, since it hasn't changed 584 // It doesn't matter whether the object is black, since it hasn't changed
562 // size, so the adjustment to the live data count will be zero anyway. 585 // size, so the adjustment to the live data count will be zero anyway.
563 if (old_start == new_start) return; 586 if (old_start == new_start) return;
564 587
565 MarkBit new_mark_bit = MarkBitFrom(new_start); 588 MarkBit new_mark_bit = MarkBitFrom(new_start);
566 MarkBit old_mark_bit = MarkBitFrom(old_start); 589 MarkBit old_mark_bit = MarkBitFrom(old_start);
567 590
568 #ifdef DEBUG 591 #ifdef DEBUG
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 680
658 // Pairs of (live_bytes_in_page, page). 681 // Pairs of (live_bytes_in_page, page).
659 typedef std::pair<int, Page*> LiveBytesPagePair; 682 typedef std::pair<int, Page*> LiveBytesPagePair;
660 std::vector<LiveBytesPagePair> pages; 683 std::vector<LiveBytesPagePair> pages;
661 pages.reserve(number_of_pages); 684 pages.reserve(number_of_pages);
662 685
663 PageIterator it(space); 686 PageIterator it(space);
664 while (it.has_next()) { 687 while (it.has_next()) {
665 Page* p = it.next(); 688 Page* p = it.next();
666 if (p->NeverEvacuate()) continue; 689 if (p->NeverEvacuate()) continue;
690 if (p->IsFlagSet(Page::BLACK_PAGE)) continue;
667 // Invariant: Evacuation candidates are just created when marking is 691 // Invariant: Evacuation candidates are just created when marking is
668 // started. This means that sweeping has finished. Furthermore, at the end 692 // started. This means that sweeping has finished. Furthermore, at the end
669 // of a GC all evacuation candidates are cleared and their slot buffers are 693 // of a GC all evacuation candidates are cleared and their slot buffers are
670 // released. 694 // released.
671 CHECK(!p->IsEvacuationCandidate()); 695 CHECK(!p->IsEvacuationCandidate());
672 CHECK_NULL(p->old_to_old_slots()); 696 CHECK_NULL(p->old_to_old_slots());
673 CHECK_NULL(p->typed_old_to_old_slots()); 697 CHECK_NULL(p->typed_old_to_old_slots());
674 CHECK(p->SweepingDone()); 698 CHECK(p->SweepingDone());
675 DCHECK(p->area_size() == area_size); 699 DCHECK(p->area_size() == area_size);
676 pages.push_back(std::make_pair(p->LiveBytesFromFreeList(), p)); 700 pages.push_back(std::make_pair(p->LiveBytesFromFreeList(), p));
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) { 1484 for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) {
1461 MarkBit markbit = Marking::MarkBitFrom(object); 1485 MarkBit markbit = Marking::MarkBitFrom(object);
1462 if ((object->map() != filler_map) && Marking::IsGrey(markbit)) { 1486 if ((object->map() != filler_map) && Marking::IsGrey(markbit)) {
1463 Marking::GreyToBlack(markbit); 1487 Marking::GreyToBlack(markbit);
1464 PushBlack(object); 1488 PushBlack(object);
1465 if (marking_deque()->IsFull()) return; 1489 if (marking_deque()->IsFull()) return;
1466 } 1490 }
1467 } 1491 }
1468 } 1492 }
1469 1493
1470 1494 template <LiveObjectIterationMode T>
1471 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) { 1495 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) {
1472 DCHECK(!marking_deque()->IsFull()); 1496 DCHECK(!marking_deque()->IsFull());
1473 LiveObjectIterator<kGreyObjects> it(p); 1497 DCHECK(T == kGreyObjects || T == kGreyObjectsOnBlackPage);
1498 LiveObjectIterator<T> it(p);
1474 HeapObject* object = NULL; 1499 HeapObject* object = NULL;
1475 while ((object = it.Next()) != NULL) { 1500 while ((object = it.Next()) != NULL) {
1476 MarkBit markbit = Marking::MarkBitFrom(object); 1501 MarkBit markbit = Marking::MarkBitFrom(object);
1477 DCHECK(Marking::IsGrey(markbit)); 1502 DCHECK(Marking::IsGrey(markbit));
1478 Marking::GreyToBlack(markbit); 1503 Marking::GreyToBlack(markbit);
1479 PushBlack(object); 1504 PushBlack(object);
1480 if (marking_deque()->IsFull()) return; 1505 if (marking_deque()->IsFull()) return;
1481 } 1506 }
1482 } 1507 }
1483 1508
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 } 1722 }
1698 return false; 1723 return false;
1699 } 1724 }
1700 }; 1725 };
1701 1726
1702 1727
1703 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { 1728 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) {
1704 PageIterator it(space); 1729 PageIterator it(space);
1705 while (it.has_next()) { 1730 while (it.has_next()) {
1706 Page* p = it.next(); 1731 Page* p = it.next();
1707 DiscoverGreyObjectsOnPage(p); 1732 if (p->IsFlagSet(Page::BLACK_PAGE)) {
1733 DiscoverGreyObjectsOnPage<kGreyObjectsOnBlackPage>(p);
1734 } else {
1735 DiscoverGreyObjectsOnPage<kGreyObjects>(p);
1736 }
1708 if (marking_deque()->IsFull()) return; 1737 if (marking_deque()->IsFull()) return;
1709 } 1738 }
1710 } 1739 }
1711 1740
1712 1741
1713 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { 1742 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() {
1714 NewSpace* space = heap()->new_space(); 1743 NewSpace* space = heap()->new_space();
1715 NewSpacePageIterator it(space->bottom(), space->top()); 1744 NewSpacePageIterator it(space->bottom(), space->top());
1716 while (it.has_next()) { 1745 while (it.has_next()) {
1717 NewSpacePage* page = it.next(); 1746 NewSpacePage* page = it.next();
1718 DiscoverGreyObjectsOnPage(page); 1747 DiscoverGreyObjectsOnPage<kGreyObjects>(page);
1719 if (marking_deque()->IsFull()) return; 1748 if (marking_deque()->IsFull()) return;
1720 } 1749 }
1721 } 1750 }
1722 1751
1723 1752
1724 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 1753 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
1725 Object* o = *p; 1754 Object* o = *p;
1726 if (!o->IsHeapObject()) return false; 1755 if (!o->IsHeapObject()) return false;
1727 HeapObject* heap_object = HeapObject::cast(o); 1756 HeapObject* heap_object = HeapObject::cast(o);
1728 MarkBit mark = Marking::MarkBitFrom(heap_object); 1757 MarkBit mark = Marking::MarkBitFrom(heap_object);
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after
2798 // for it. 2827 // for it.
2799 CHECK(large_object->IsHeapObject()); 2828 CHECK(large_object->IsHeapObject());
2800 HeapObject* large_heap_object = HeapObject::cast(large_object); 2829 HeapObject* large_heap_object = HeapObject::cast(large_object);
2801 if (IsMarked(large_heap_object)) { 2830 if (IsMarked(large_heap_object)) {
2802 *out_object = large_heap_object; 2831 *out_object = large_heap_object;
2803 return true; 2832 return true;
2804 } 2833 }
2805 return false; 2834 return false;
2806 } 2835 }
2807 2836
2837 // If we are on a black page, we cannot find the actual object start
2838 // easiliy. We just return true but do not set the out_object.
2839 if (p->IsFlagSet(Page::BLACK_PAGE)) {
2840 return true;
2841 }
2842
2808 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); 2843 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot);
2809 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; 2844 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2;
2810 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); 2845 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index);
2811 MarkBit::CellType* cells = p->markbits()->cells(); 2846 MarkBit::CellType* cells = p->markbits()->cells();
2812 Address base_address = p->area_start(); 2847 Address base_address = p->area_start();
2813 unsigned int base_address_cell_index = Bitmap::IndexToCell( 2848 unsigned int base_address_cell_index = Bitmap::IndexToCell(
2814 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); 2849 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address)));
2815 2850
2816 // Check if the slot points to the start of an object. This can happen e.g. 2851 // Check if the slot points to the start of an object. This can happen e.g.
2817 // when we left trim a fixed array. Such slots are invalid and we can remove 2852 // 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
2878 // Slots pointing to the first word of an object are invalid and removed. 2913 // Slots pointing to the first word of an object are invalid and removed.
2879 // This can happen when we move the object header while left trimming. 2914 // This can happen when we move the object header while left trimming.
2880 *out_object = object; 2915 *out_object = object;
2881 return true; 2916 return true;
2882 } 2917 }
2883 return false; 2918 return false;
2884 } 2919 }
2885 2920
2886 HeapObject* MarkCompactCollector::FindBlackObjectBySlotSlow(Address slot) { 2921 HeapObject* MarkCompactCollector::FindBlackObjectBySlotSlow(Address slot) {
2887 Page* p = Page::FromAddress(slot); 2922 Page* p = Page::FromAddress(slot);
2888 // This function does not support large objects right now.
2889 Space* owner = p->owner(); 2923 Space* owner = p->owner();
2890 if (owner == heap_->lo_space() || owner == nullptr) { 2924 if (owner == heap_->lo_space() || owner == nullptr) {
2891 Object* large_object = heap_->lo_space()->FindObject(slot); 2925 Object* large_object = heap_->lo_space()->FindObject(slot);
2892 // This object has to exist, otherwise we would not have recorded a slot 2926 // This object has to exist, otherwise we would not have recorded a slot
2893 // for it. 2927 // for it.
2894 CHECK(large_object->IsHeapObject()); 2928 CHECK(large_object->IsHeapObject());
2895 HeapObject* large_heap_object = HeapObject::cast(large_object); 2929 HeapObject* large_heap_object = HeapObject::cast(large_object);
2896 2930
2897 if (IsMarked(large_heap_object)) { 2931 if (IsMarked(large_heap_object)) {
2898 return large_heap_object; 2932 return large_heap_object;
2899 } 2933 }
2900 return nullptr; 2934 return nullptr;
2901 } 2935 }
2902 2936
2903 LiveObjectIterator<kBlackObjects> it(p); 2937 if (p->IsFlagSet(Page::BLACK_PAGE)) {
2904 HeapObject* object = nullptr; 2938 HeapObjectIterator it(p);
2905 while ((object = it.Next()) != nullptr) { 2939 HeapObject* object = nullptr;
2906 int size = object->Size(); 2940 while ((object = it.Next()) != nullptr) {
2907 if (object->address() > slot) return nullptr; 2941 int size = object->Size();
2908 if (object->address() <= slot && slot < (object->address() + size)) { 2942 if (object->address() > slot) return nullptr;
2909 return object; 2943 if (object->address() <= slot && slot < (object->address() + size)) {
2944 return object;
2945 }
2946 }
2947 } else {
2948 LiveObjectIterator<kBlackObjects> it(p);
2949 HeapObject* object = nullptr;
2950 while ((object = it.Next()) != nullptr) {
2951 int size = object->Size();
2952 if (object->address() > slot) return nullptr;
2953 if (object->address() <= slot && slot < (object->address() + size)) {
2954 return object;
2955 }
2910 } 2956 }
2911 } 2957 }
2912 return nullptr; 2958 return nullptr;
2913 } 2959 }
2914 2960
2915 2961
2916 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { 2962 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) {
2917 HeapObject* object = NULL;
2918 // The target object is black but we don't know if the source slot is black. 2963 // The target object is black but we don't know if the source slot is black.
2919 // The source object could have died and the slot could be part of a free 2964 // The source object could have died and the slot could be part of a free
2920 // space. Find out based on mark bits if the slot is part of a live object. 2965 // space. Find out based on mark bits if the slot is part of a live object.
2921 if (!IsSlotInBlackObject(Page::FromAddress(slot), slot, &object)) { 2966 Page* page = Page::FromAddress(slot);
2967 HeapObject* object = NULL;
2968 if (!IsSlotInBlackObject(page, slot, &object)) {
2922 return false; 2969 return false;
2923 } 2970 }
2924 2971
2925 DCHECK(object != NULL); 2972 // If the slot is on a black page, the object will be live.
2973 DCHECK(object != NULL || page->IsFlagSet(Page::BLACK_PAGE));
2974 if (page->IsFlagSet(Page::BLACK_PAGE)) {
2975 return true;
2976 }
2977
2926 int offset = static_cast<int>(slot - object->address()); 2978 int offset = static_cast<int>(slot - object->address());
2927 return object->IsValidSlot(offset); 2979 return object->IsValidSlot(offset);
2928 } 2980 }
2929 2981
2930 2982
2931 void MarkCompactCollector::EvacuateNewSpacePrologue() { 2983 void MarkCompactCollector::EvacuateNewSpacePrologue() {
2932 NewSpace* new_space = heap()->new_space(); 2984 NewSpace* new_space = heap()->new_space();
2933 NewSpacePageIterator it(new_space->bottom(), new_space->top()); 2985 NewSpacePageIterator it(new_space->bottom(), new_space->top());
2934 // Append the list of new space pages to be processed. 2986 // Append the list of new space pages to be processed.
2935 while (it.has_next()) { 2987 while (it.has_next()) {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
3219 // Slots in live objects pointing into evacuation candidates are updated 3271 // Slots in live objects pointing into evacuation candidates are updated
3220 // if requested. 3272 // if requested.
3221 // Returns the size of the biggest continuous freed memory chunk in bytes. 3273 // Returns the size of the biggest continuous freed memory chunk in bytes.
3222 template <SweepingMode sweeping_mode, 3274 template <SweepingMode sweeping_mode,
3223 MarkCompactCollector::SweepingParallelism parallelism, 3275 MarkCompactCollector::SweepingParallelism parallelism,
3224 SkipListRebuildingMode skip_list_mode, 3276 SkipListRebuildingMode skip_list_mode,
3225 FreeSpaceTreatmentMode free_space_mode> 3277 FreeSpaceTreatmentMode free_space_mode>
3226 static int Sweep(PagedSpace* space, FreeList* free_list, Page* p, 3278 static int Sweep(PagedSpace* space, FreeList* free_list, Page* p,
3227 ObjectVisitor* v) { 3279 ObjectVisitor* v) {
3228 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); 3280 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone());
3281 DCHECK(!p->IsFlagSet(Page::BLACK_PAGE));
3229 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, 3282 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST,
3230 space->identity() == CODE_SPACE); 3283 space->identity() == CODE_SPACE);
3231 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); 3284 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST));
3232 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || 3285 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD ||
3233 sweeping_mode == SWEEP_ONLY); 3286 sweeping_mode == SWEEP_ONLY);
3234 3287
3235 Address free_start = p->area_start(); 3288 Address free_start = p->area_start();
3236 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 3289 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
3237 3290
3238 // If we use the skip list for code space pages, we have to lock the skip 3291 // If we use the skip list for code space pages, we have to lock the skip
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
3691 while (it.has_next()) { 3744 while (it.has_next()) {
3692 Page* p = it.next(); 3745 Page* p = it.next();
3693 DCHECK(p->SweepingDone()); 3746 DCHECK(p->SweepingDone());
3694 3747
3695 if (p->IsEvacuationCandidate()) { 3748 if (p->IsEvacuationCandidate()) {
3696 // Will be processed in EvacuateNewSpaceAndCandidates. 3749 // Will be processed in EvacuateNewSpaceAndCandidates.
3697 DCHECK(evacuation_candidates_.length() > 0); 3750 DCHECK(evacuation_candidates_.length() > 0);
3698 continue; 3751 continue;
3699 } 3752 }
3700 3753
3754 // We can not sweep black pages, since all mark bits are set for these
3755 // pages.
3756 if (p->IsFlagSet(Page::BLACK_PAGE)) {
3757 Bitmap::Clear(p);
3758 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone);
3759 p->ClearFlag(Page::BLACK_PAGE);
3760 // TODO(hpayer): Free unused memory of last black page.
3761 continue;
3762 }
3763
3701 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { 3764 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) {
3702 // We need to sweep the page to get it into an iterable state again. Note 3765 // We need to sweep the page to get it into an iterable state again. Note
3703 // that this adds unusable memory into the free list that is later on 3766 // that this adds unusable memory into the free list that is later on
3704 // (in the free list) dropped again. Since we only use the flag for 3767 // (in the free list) dropped again. Since we only use the flag for
3705 // testing this is fine. 3768 // testing this is fine.
3706 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); 3769 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress);
3707 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, 3770 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
3708 IGNORE_FREE_SPACE>(space, nullptr, p, nullptr); 3771 IGNORE_FREE_SPACE>(space, nullptr, p, nullptr);
3709 continue; 3772 continue;
3710 } 3773 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3814 MarkBit mark_bit = Marking::MarkBitFrom(host); 3877 MarkBit mark_bit = Marking::MarkBitFrom(host);
3815 if (Marking::IsBlack(mark_bit)) { 3878 if (Marking::IsBlack(mark_bit)) {
3816 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 3879 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
3817 RecordRelocSlot(host, &rinfo, target); 3880 RecordRelocSlot(host, &rinfo, target);
3818 } 3881 }
3819 } 3882 }
3820 } 3883 }
3821 3884
3822 } // namespace internal 3885 } // namespace internal
3823 } // namespace v8 3886 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698