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

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
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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); 113 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
114 CHECK(current >= next_object_must_be_here_or_later); 114 CHECK(current >= next_object_must_be_here_or_later);
115 object->Iterate(&visitor); 115 object->Iterate(&visitor);
116 next_object_must_be_here_or_later = current + object->Size(); 116 next_object_must_be_here_or_later = current + object->Size();
117 // The next word for sure belongs to the current object, jump over it. 117 // The next word for sure belongs to the current object, jump over it.
118 current += kPointerSize; 118 current += kPointerSize;
119 } 119 }
120 } 120 }
121 } 121 }
122 122
123 static void VerifyMarkingBlackPage(Heap* heap, Page* page) {
124 CHECK(page->IsFlagSet(Page::BLACK_PAGE));
125 VerifyMarkingVisitor visitor(heap);
126 HeapObjectIterator it(page);
127 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
128 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
129 object->Iterate(&visitor);
130 }
131 }
123 132
124 static void VerifyMarking(NewSpace* space) { 133 static void VerifyMarking(NewSpace* space) {
125 Address end = space->top(); 134 Address end = space->top();
126 NewSpacePageIterator it(space->bottom(), end); 135 NewSpacePageIterator it(space->bottom(), end);
127 // The bottom position is at the start of its page. Allows us to use 136 // The bottom position is at the start of its page. Allows us to use
128 // page->area_start() as start of range on all pages. 137 // page->area_start() as start of range on all pages.
129 CHECK_EQ(space->bottom(), 138 CHECK_EQ(space->bottom(),
130 NewSpacePage::FromAddress(space->bottom())->area_start()); 139 NewSpacePage::FromAddress(space->bottom())->area_start());
131 while (it.has_next()) { 140 while (it.has_next()) {
132 NewSpacePage* page = it.next(); 141 NewSpacePage* page = it.next();
133 Address limit = it.has_next() ? page->area_end() : end; 142 Address limit = it.has_next() ? page->area_end() : end;
134 CHECK(limit == end || !page->Contains(end)); 143 CHECK(limit == end || !page->Contains(end));
135 VerifyMarking(space->heap(), page->area_start(), limit); 144 VerifyMarking(space->heap(), page->area_start(), limit);
136 } 145 }
137 } 146 }
138 147
139 148
140 static void VerifyMarking(PagedSpace* space) { 149 static void VerifyMarking(PagedSpace* space) {
141 PageIterator it(space); 150 PageIterator it(space);
142 151
143 while (it.has_next()) { 152 while (it.has_next()) {
144 Page* p = it.next(); 153 Page* p = it.next();
145 VerifyMarking(space->heap(), p->area_start(), p->area_end()); 154 if (p->IsFlagSet(Page::BLACK_PAGE)) {
155 VerifyMarkingBlackPage(space->heap(), p);
156 } else {
157 VerifyMarking(space->heap(), p->area_start(), p->area_end());
158 }
146 } 159 }
147 } 160 }
148 161
149 162
150 static void VerifyMarking(Heap* heap) { 163 static void VerifyMarking(Heap* heap) {
151 VerifyMarking(heap->old_space()); 164 VerifyMarking(heap->old_space());
152 VerifyMarking(heap->code_space()); 165 VerifyMarking(heap->code_space());
153 VerifyMarking(heap->map_space()); 166 VerifyMarking(heap->map_space());
154 VerifyMarking(heap->new_space()); 167 VerifyMarking(heap->new_space());
155 168
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 map->VerifyOmittedMapChecks(); 421 map->VerifyOmittedMapChecks();
409 } 422 }
410 } 423 }
411 #endif // VERIFY_HEAP 424 #endif // VERIFY_HEAP
412 425
413 426
414 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { 427 static void ClearMarkbitsInPagedSpace(PagedSpace* space) {
415 PageIterator it(space); 428 PageIterator it(space);
416 429
417 while (it.has_next()) { 430 while (it.has_next()) {
418 Bitmap::Clear(it.next()); 431 Page* p = it.next();
432 Bitmap::Clear(p);
433 if (p->IsFlagSet(Page::BLACK_PAGE)) {
434 p->ClearFlag(Page::BLACK_PAGE);
435 }
419 } 436 }
420 } 437 }
421 438
422 439
423 static void ClearMarkbitsInNewSpace(NewSpace* space) { 440 static void ClearMarkbitsInNewSpace(NewSpace* space) {
424 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); 441 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd());
425 442
426 while (it.has_next()) { 443 while (it.has_next()) {
427 Bitmap::Clear(it.next()); 444 Bitmap::Clear(it.next());
428 } 445 }
429 } 446 }
430 447
431 448
432 void MarkCompactCollector::ClearMarkbits() { 449 void MarkCompactCollector::ClearMarkbits() {
433 ClearMarkbitsInPagedSpace(heap_->code_space()); 450 ClearMarkbitsInPagedSpace(heap_->code_space());
434 ClearMarkbitsInPagedSpace(heap_->map_space()); 451 ClearMarkbitsInPagedSpace(heap_->map_space());
435 ClearMarkbitsInPagedSpace(heap_->old_space()); 452 ClearMarkbitsInPagedSpace(heap_->old_space());
436 ClearMarkbitsInNewSpace(heap_->new_space()); 453 ClearMarkbitsInNewSpace(heap_->new_space());
437 454
438 LargeObjectIterator it(heap_->lo_space()); 455 LargeObjectIterator it(heap_->lo_space());
439 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 456 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
440 Marking::MarkWhite(Marking::MarkBitFrom(obj)); 457 Marking::MarkWhite(Marking::MarkBitFrom(obj));
441 Page::FromAddress(obj->address())->ResetProgressBar(); 458 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
442 Page::FromAddress(obj->address())->ResetLiveBytes(); 459 chunk->ResetProgressBar();
460 chunk->ResetLiveBytes();
461 if (chunk->IsFlagSet(Page::BLACK_PAGE)) {
462 chunk->ClearFlag(Page::BLACK_PAGE);
463 }
443 } 464 }
444 } 465 }
445 466
446 467
447 class MarkCompactCollector::SweeperTask : public v8::Task { 468 class MarkCompactCollector::SweeperTask : public v8::Task {
448 public: 469 public:
449 SweeperTask(Heap* heap, AllocationSpace space_to_start) 470 SweeperTask(Heap* heap, AllocationSpace space_to_start)
450 : heap_(heap), space_to_start_(space_to_start) {} 471 : heap_(heap), space_to_start_(space_to_start) {}
451 472
452 virtual ~SweeperTask() {} 473 virtual ~SweeperTask() {}
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 pending_sweeper_tasks_semaphore_.Signal(); 570 pending_sweeper_tasks_semaphore_.Signal();
550 return true; 571 return true;
551 } 572 }
552 573
553 574
554 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { 575 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) {
555 // This is only used when resizing an object. 576 // This is only used when resizing an object.
556 DCHECK(MemoryChunk::FromAddress(old_start) == 577 DCHECK(MemoryChunk::FromAddress(old_start) ==
557 MemoryChunk::FromAddress(new_start)); 578 MemoryChunk::FromAddress(new_start));
558 579
559 if (!heap->incremental_marking()->IsMarking()) return; 580 if (!heap->incremental_marking()->IsMarking() ||
581 Page::FromAddress(old_start)->IsFlagSet(Page::BLACK_PAGE))
582 return;
560 583
561 // If the mark doesn't move, we don't check the color of the object. 584 // If the mark doesn't move, we don't check the color of the object.
562 // It doesn't matter whether the object is black, since it hasn't changed 585 // It doesn't matter whether the object is black, since it hasn't changed
563 // size, so the adjustment to the live data count will be zero anyway. 586 // size, so the adjustment to the live data count will be zero anyway.
564 if (old_start == new_start) return; 587 if (old_start == new_start) return;
565 588
566 MarkBit new_mark_bit = MarkBitFrom(new_start); 589 MarkBit new_mark_bit = MarkBitFrom(new_start);
567 MarkBit old_mark_bit = MarkBitFrom(old_start); 590 MarkBit old_mark_bit = MarkBitFrom(old_start);
568 591
569 #ifdef DEBUG 592 #ifdef DEBUG
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 681
659 // Pairs of (live_bytes_in_page, page). 682 // Pairs of (live_bytes_in_page, page).
660 typedef std::pair<int, Page*> LiveBytesPagePair; 683 typedef std::pair<int, Page*> LiveBytesPagePair;
661 std::vector<LiveBytesPagePair> pages; 684 std::vector<LiveBytesPagePair> pages;
662 pages.reserve(number_of_pages); 685 pages.reserve(number_of_pages);
663 686
664 PageIterator it(space); 687 PageIterator it(space);
665 while (it.has_next()) { 688 while (it.has_next()) {
666 Page* p = it.next(); 689 Page* p = it.next();
667 if (p->NeverEvacuate()) continue; 690 if (p->NeverEvacuate()) continue;
691 if (p->IsFlagSet(Page::BLACK_PAGE)) continue;
668 // Invariant: Evacuation candidates are just created when marking is 692 // Invariant: Evacuation candidates are just created when marking is
669 // started. This means that sweeping has finished. Furthermore, at the end 693 // started. This means that sweeping has finished. Furthermore, at the end
670 // of a GC all evacuation candidates are cleared and their slot buffers are 694 // of a GC all evacuation candidates are cleared and their slot buffers are
671 // released. 695 // released.
672 CHECK(!p->IsEvacuationCandidate()); 696 CHECK(!p->IsEvacuationCandidate());
673 CHECK_NULL(p->old_to_old_slots()); 697 CHECK_NULL(p->old_to_old_slots());
674 CHECK_NULL(p->typed_old_to_old_slots()); 698 CHECK_NULL(p->typed_old_to_old_slots());
675 CHECK(p->SweepingDone()); 699 CHECK(p->SweepingDone());
676 DCHECK(p->area_size() == area_size); 700 DCHECK(p->area_size() == area_size);
677 pages.push_back(std::make_pair(p->LiveBytesFromFreeList(), p)); 701 pages.push_back(std::make_pair(p->LiveBytesFromFreeList(), p));
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) { 1486 for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) {
1463 MarkBit markbit = Marking::MarkBitFrom(object); 1487 MarkBit markbit = Marking::MarkBitFrom(object);
1464 if ((object->map() != filler_map) && Marking::IsGrey(markbit)) { 1488 if ((object->map() != filler_map) && Marking::IsGrey(markbit)) {
1465 Marking::GreyToBlack(markbit); 1489 Marking::GreyToBlack(markbit);
1466 PushBlack(object); 1490 PushBlack(object);
1467 if (marking_deque()->IsFull()) return; 1491 if (marking_deque()->IsFull()) return;
1468 } 1492 }
1469 } 1493 }
1470 } 1494 }
1471 1495
1472 1496 template <LiveObjectIterationMode T>
1473 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) { 1497 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) {
1474 DCHECK(!marking_deque()->IsFull()); 1498 DCHECK(!marking_deque()->IsFull());
1475 LiveObjectIterator<kGreyObjects> it(p); 1499 DCHECK(T == kGreyObjects || T == kGreyObjectsOnBlackPage);
1500 LiveObjectIterator<T> it(p);
1476 HeapObject* object = NULL; 1501 HeapObject* object = NULL;
1477 while ((object = it.Next()) != NULL) { 1502 while ((object = it.Next()) != NULL) {
1478 MarkBit markbit = Marking::MarkBitFrom(object); 1503 MarkBit markbit = Marking::MarkBitFrom(object);
1479 DCHECK(Marking::IsGrey(markbit)); 1504 DCHECK(Marking::IsGrey(markbit));
1480 Marking::GreyToBlack(markbit); 1505 Marking::GreyToBlack(markbit);
1481 PushBlack(object); 1506 PushBlack(object);
1482 if (marking_deque()->IsFull()) return; 1507 if (marking_deque()->IsFull()) return;
1483 } 1508 }
1484 } 1509 }
1485 1510
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 } 1724 }
1700 return false; 1725 return false;
1701 } 1726 }
1702 }; 1727 };
1703 1728
1704 1729
1705 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { 1730 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) {
1706 PageIterator it(space); 1731 PageIterator it(space);
1707 while (it.has_next()) { 1732 while (it.has_next()) {
1708 Page* p = it.next(); 1733 Page* p = it.next();
1709 DiscoverGreyObjectsOnPage(p); 1734 if (p->IsFlagSet(Page::BLACK_PAGE)) {
1735 DiscoverGreyObjectsOnPage<kGreyObjectsOnBlackPage>(p);
1736 } else {
1737 DiscoverGreyObjectsOnPage<kGreyObjects>(p);
1738 }
1710 if (marking_deque()->IsFull()) return; 1739 if (marking_deque()->IsFull()) return;
1711 } 1740 }
1712 } 1741 }
1713 1742
1714 1743
1715 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { 1744 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() {
1716 NewSpace* space = heap()->new_space(); 1745 NewSpace* space = heap()->new_space();
1717 NewSpacePageIterator it(space->bottom(), space->top()); 1746 NewSpacePageIterator it(space->bottom(), space->top());
1718 while (it.has_next()) { 1747 while (it.has_next()) {
1719 NewSpacePage* page = it.next(); 1748 NewSpacePage* page = it.next();
1720 DiscoverGreyObjectsOnPage(page); 1749 DiscoverGreyObjectsOnPage<kGreyObjects>(page);
1721 if (marking_deque()->IsFull()) return; 1750 if (marking_deque()->IsFull()) return;
1722 } 1751 }
1723 } 1752 }
1724 1753
1725 1754
1726 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 1755 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
1727 Object* o = *p; 1756 Object* o = *p;
1728 if (!o->IsHeapObject()) return false; 1757 if (!o->IsHeapObject()) return false;
1729 HeapObject* heap_object = HeapObject::cast(o); 1758 HeapObject* heap_object = HeapObject::cast(o);
1730 MarkBit mark = Marking::MarkBitFrom(heap_object); 1759 MarkBit mark = Marking::MarkBitFrom(heap_object);
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
2805 // for it. 2834 // for it.
2806 CHECK(large_object->IsHeapObject()); 2835 CHECK(large_object->IsHeapObject());
2807 HeapObject* large_heap_object = HeapObject::cast(large_object); 2836 HeapObject* large_heap_object = HeapObject::cast(large_object);
2808 if (IsMarked(large_heap_object)) { 2837 if (IsMarked(large_heap_object)) {
2809 *out_object = large_heap_object; 2838 *out_object = large_heap_object;
2810 return true; 2839 return true;
2811 } 2840 }
2812 return false; 2841 return false;
2813 } 2842 }
2814 2843
2844 // If we are on a black page, we cannot find the actual object start
2845 // easiliy. We just return true but do not set the out_object.
2846 if (p->IsFlagSet(Page::BLACK_PAGE)) {
2847 return true;
2848 }
2849
2815 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); 2850 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot);
2816 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; 2851 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2;
2817 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); 2852 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index);
2818 MarkBit::CellType* cells = p->markbits()->cells(); 2853 MarkBit::CellType* cells = p->markbits()->cells();
2819 Address base_address = p->area_start(); 2854 Address base_address = p->area_start();
2820 unsigned int base_address_cell_index = Bitmap::IndexToCell( 2855 unsigned int base_address_cell_index = Bitmap::IndexToCell(
2821 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); 2856 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address)));
2822 2857
2823 // Check if the slot points to the start of an object. This can happen e.g. 2858 // Check if the slot points to the start of an object. This can happen e.g.
2824 // when we left trim a fixed array. Such slots are invalid and we can remove 2859 // 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
2885 // Slots pointing to the first word of an object are invalid and removed. 2920 // Slots pointing to the first word of an object are invalid and removed.
2886 // This can happen when we move the object header while left trimming. 2921 // This can happen when we move the object header while left trimming.
2887 *out_object = object; 2922 *out_object = object;
2888 return true; 2923 return true;
2889 } 2924 }
2890 return false; 2925 return false;
2891 } 2926 }
2892 2927
2893 HeapObject* MarkCompactCollector::FindBlackObjectBySlotSlow(Address slot) { 2928 HeapObject* MarkCompactCollector::FindBlackObjectBySlotSlow(Address slot) {
2894 Page* p = Page::FromAddress(slot); 2929 Page* p = Page::FromAddress(slot);
2895 // This function does not support large objects right now.
2896 Space* owner = p->owner(); 2930 Space* owner = p->owner();
2897 if (owner == heap_->lo_space() || owner == nullptr) { 2931 if (owner == heap_->lo_space() || owner == nullptr) {
2898 Object* large_object = heap_->lo_space()->FindObject(slot); 2932 Object* large_object = heap_->lo_space()->FindObject(slot);
2899 // This object has to exist, otherwise we would not have recorded a slot 2933 // This object has to exist, otherwise we would not have recorded a slot
2900 // for it. 2934 // for it.
2901 CHECK(large_object->IsHeapObject()); 2935 CHECK(large_object->IsHeapObject());
2902 HeapObject* large_heap_object = HeapObject::cast(large_object); 2936 HeapObject* large_heap_object = HeapObject::cast(large_object);
2903 2937
2904 if (IsMarked(large_heap_object)) { 2938 if (IsMarked(large_heap_object)) {
2905 return large_heap_object; 2939 return large_heap_object;
2906 } 2940 }
2907 return nullptr; 2941 return nullptr;
2908 } 2942 }
2909 2943
2944 // The LiveObjectIterator does not work on black pages. Hence, we cannot call
2945 // this function black pages.
2946 DCHECK(!Page::FromAddress(slot)->IsFlagSet(Page::BLACK_PAGE));
2947
2910 LiveObjectIterator<kBlackObjects> it(p); 2948 LiveObjectIterator<kBlackObjects> it(p);
2911 HeapObject* object = nullptr; 2949 HeapObject* object = nullptr;
2912 while ((object = it.Next()) != nullptr) { 2950 while ((object = it.Next()) != nullptr) {
2913 int size = object->Size(); 2951 int size = object->Size();
2914 if (object->address() > slot) return nullptr; 2952 if (object->address() > slot) return nullptr;
2915 if (object->address() <= slot && slot < (object->address() + size)) { 2953 if (object->address() <= slot && slot < (object->address() + size)) {
2916 return object; 2954 return object;
2917 } 2955 }
2918 } 2956 }
2919 return nullptr; 2957 return nullptr;
2920 } 2958 }
2921 2959
2922 2960
2923 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { 2961 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) {
2924 HeapObject* object = NULL;
2925 // The target object is black but we don't know if the source slot is black. 2962 // The target object is black but we don't know if the source slot is black.
2926 // The source object could have died and the slot could be part of a free 2963 // The source object could have died and the slot could be part of a free
2927 // space. Find out based on mark bits if the slot is part of a live object. 2964 // space. Find out based on mark bits if the slot is part of a live object.
2928 if (!IsSlotInBlackObject(Page::FromAddress(slot), slot, &object)) { 2965 Page* page = Page::FromAddress(slot);
2966 HeapObject* object = NULL;
2967 if (!IsSlotInBlackObject(page, slot, &object)) {
2929 return false; 2968 return false;
2930 } 2969 }
2931 2970
2932 DCHECK(object != NULL); 2971 // If the slot is on a black page, the object will be live.
2972 DCHECK(object != NULL || page->IsFlagSet(Page::BLACK_PAGE));
2973 if (page->IsFlagSet(Page::BLACK_PAGE)) {
2974 return true;
2975 }
2976
2933 int offset = static_cast<int>(slot - object->address()); 2977 int offset = static_cast<int>(slot - object->address());
2934 return object->IsValidSlot(offset); 2978 return object->IsValidSlot(offset);
2935 } 2979 }
2936 2980
2937 2981
2938 void MarkCompactCollector::EvacuateNewSpacePrologue() { 2982 void MarkCompactCollector::EvacuateNewSpacePrologue() {
2939 NewSpace* new_space = heap()->new_space(); 2983 NewSpace* new_space = heap()->new_space();
2940 NewSpacePageIterator it(new_space->bottom(), new_space->top()); 2984 NewSpacePageIterator it(new_space->bottom(), new_space->top());
2941 // Append the list of new space pages to be processed. 2985 // Append the list of new space pages to be processed.
2942 while (it.has_next()) { 2986 while (it.has_next()) {
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
3227 // Slots in live objects pointing into evacuation candidates are updated 3271 // Slots in live objects pointing into evacuation candidates are updated
3228 // if requested. 3272 // if requested.
3229 // 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.
3230 template <SweepingMode sweeping_mode, 3274 template <SweepingMode sweeping_mode,
3231 MarkCompactCollector::SweepingParallelism parallelism, 3275 MarkCompactCollector::SweepingParallelism parallelism,
3232 SkipListRebuildingMode skip_list_mode, 3276 SkipListRebuildingMode skip_list_mode,
3233 FreeSpaceTreatmentMode free_space_mode> 3277 FreeSpaceTreatmentMode free_space_mode>
3234 static int Sweep(PagedSpace* space, FreeList* free_list, Page* p, 3278 static int Sweep(PagedSpace* space, FreeList* free_list, Page* p,
3235 ObjectVisitor* v) { 3279 ObjectVisitor* v) {
3236 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); 3280 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone());
3281 DCHECK(!p->IsFlagSet(Page::BLACK_PAGE));
3237 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, 3282 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST,
3238 space->identity() == CODE_SPACE); 3283 space->identity() == CODE_SPACE);
3239 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); 3284 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST));
3240 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || 3285 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD ||
3241 sweeping_mode == SWEEP_ONLY); 3286 sweeping_mode == SWEEP_ONLY);
3242 3287
3243 Address free_start = p->area_start(); 3288 Address free_start = p->area_start();
3244 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 3289 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
3245 3290
3246 // 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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
3729 3774
3730 PageIterator it(space); 3775 PageIterator it(space);
3731 3776
3732 int will_be_swept = 0; 3777 int will_be_swept = 0;
3733 bool unused_page_present = false; 3778 bool unused_page_present = false;
3734 3779
3735 while (it.has_next()) { 3780 while (it.has_next()) {
3736 Page* p = it.next(); 3781 Page* p = it.next();
3737 DCHECK(p->SweepingDone()); 3782 DCHECK(p->SweepingDone());
3738 3783
3784 // We can not sweep black pages, since all mark bits are set for these
3785 // pages.
3786 if (p->IsFlagSet(Page::BLACK_PAGE)) {
3787 Bitmap::Clear(p);
3788 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone);
3789 p->ClearFlag(Page::BLACK_PAGE);
3790 // TODO(hpayer): Free unused memory of last black page.
3791 continue;
3792 }
3793
3739 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION) || 3794 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION) ||
3740 p->IsEvacuationCandidate()) { 3795 p->IsEvacuationCandidate()) {
3741 // Will be processed in EvacuateNewSpaceAndCandidates. 3796 // Will be processed in EvacuateNewSpaceAndCandidates.
3742 DCHECK(evacuation_candidates_.length() > 0); 3797 DCHECK(evacuation_candidates_.length() > 0);
3743 continue; 3798 continue;
3744 } 3799 }
3745 3800
3746 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { 3801 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) {
3747 // We need to sweep the page to get it into an iterable state again. Note 3802 // We need to sweep the page to get it into an iterable state again. Note
3748 // that this adds unusable memory into the free list that is later on 3803 // that this adds unusable memory into the free list that is later on
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3859 MarkBit mark_bit = Marking::MarkBitFrom(host); 3914 MarkBit mark_bit = Marking::MarkBitFrom(host);
3860 if (Marking::IsBlack(mark_bit)) { 3915 if (Marking::IsBlack(mark_bit)) {
3861 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 3916 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
3862 RecordRelocSlot(host, &rinfo, target); 3917 RecordRelocSlot(host, &rinfo, target);
3863 } 3918 }
3864 } 3919 }
3865 } 3920 }
3866 3921
3867 } // namespace internal 3922 } // namespace internal
3868 } // namespace v8 3923 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698