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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 97 | 97 |
| 98 private: | 98 private: |
| 99 Heap* heap_; | 99 Heap* heap_; |
| 100 }; | 100 }; |
| 101 | 101 |
| 102 | 102 |
| 103 static void VerifyMarking(Heap* heap, Address bottom, Address top) { | 103 static void VerifyMarking(Heap* heap, Address bottom, Address top) { |
| 104 VerifyMarkingVisitor visitor(heap); | 104 VerifyMarkingVisitor visitor(heap); |
| 105 HeapObject* object; | 105 HeapObject* object; |
| 106 Address next_object_must_be_here_or_later = bottom; | 106 Address next_object_must_be_here_or_later = bottom; |
| 107 | 107 for (Address current = bottom; current < top;) { |
| 108 for (Address current = bottom; current < top; current += kPointerSize) { | |
| 109 object = HeapObject::FromAddress(current); | 108 object = HeapObject::FromAddress(current); |
| 110 if (MarkCompactCollector::IsMarked(object)) { | 109 if (MarkCompactCollector::IsMarked(object)) { |
| 111 CHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object))); | 110 CHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object))); |
| 112 CHECK(current >= next_object_must_be_here_or_later); | 111 CHECK(current >= next_object_must_be_here_or_later); |
| 113 object->Iterate(&visitor); | 112 object->Iterate(&visitor); |
| 114 next_object_must_be_here_or_later = current + object->Size(); | 113 next_object_must_be_here_or_later = current + object->Size(); |
| 115 // The next word for sure belongs to the current object, jump over it. | 114 // The next word for sure belongs to the current object, jump over it. |
| 115 current = next_object_must_be_here_or_later; | |
|
ulan
2016/07/19 13:23:32
This is making verification less strict.
How abou
Hannes Payer (out of office)
2016/07/19 14:42:53
Good idea! Done.
| |
| 116 } else { | |
| 116 current += kPointerSize; | 117 current += kPointerSize; |
| 117 } | 118 } |
| 118 } | 119 } |
| 119 } | 120 } |
| 120 | 121 |
| 121 static void VerifyMarkingBlackPage(Heap* heap, Page* page) { | |
| 122 CHECK(page->IsFlagSet(Page::BLACK_PAGE)); | |
| 123 VerifyMarkingVisitor visitor(heap); | |
| 124 HeapObjectIterator it(page); | |
| 125 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { | |
| 126 CHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object))); | |
| 127 object->Iterate(&visitor); | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 static void VerifyMarking(NewSpace* space) { | 122 static void VerifyMarking(NewSpace* space) { |
| 132 Address end = space->top(); | 123 Address end = space->top(); |
| 133 // The bottom position is at the start of its page. Allows us to use | 124 // The bottom position is at the start of its page. Allows us to use |
| 134 // page->area_start() as start of range on all pages. | 125 // page->area_start() as start of range on all pages. |
| 135 CHECK_EQ(space->bottom(), Page::FromAddress(space->bottom())->area_start()); | 126 CHECK_EQ(space->bottom(), Page::FromAddress(space->bottom())->area_start()); |
| 136 | 127 |
| 137 NewSpacePageRange range(space->bottom(), end); | 128 NewSpacePageRange range(space->bottom(), end); |
| 138 for (auto it = range.begin(); it != range.end();) { | 129 for (auto it = range.begin(); it != range.end();) { |
| 139 Page* page = *(it++); | 130 Page* page = *(it++); |
| 140 Address limit = it != range.end() ? page->area_end() : end; | 131 Address limit = it != range.end() ? page->area_end() : end; |
| 141 CHECK(limit == end || !page->Contains(end)); | 132 CHECK(limit == end || !page->Contains(end)); |
| 142 VerifyMarking(space->heap(), page->area_start(), limit); | 133 VerifyMarking(space->heap(), page->area_start(), limit); |
| 143 } | 134 } |
| 144 } | 135 } |
| 145 | 136 |
| 146 | 137 |
| 147 static void VerifyMarking(PagedSpace* space) { | 138 static void VerifyMarking(PagedSpace* space) { |
| 148 for (Page* p : *space) { | 139 for (Page* p : *space) { |
| 149 if (p->IsFlagSet(Page::BLACK_PAGE)) { | 140 VerifyMarking(space->heap(), p->area_start(), p->area_end()); |
| 150 VerifyMarkingBlackPage(space->heap(), p); | |
| 151 } else { | |
| 152 VerifyMarking(space->heap(), p->area_start(), p->area_end()); | |
| 153 } | |
| 154 } | 141 } |
| 155 } | 142 } |
| 156 | 143 |
| 157 | 144 |
| 158 static void VerifyMarking(Heap* heap) { | 145 static void VerifyMarking(Heap* heap) { |
| 159 VerifyMarking(heap->old_space()); | 146 VerifyMarking(heap->old_space()); |
| 160 VerifyMarking(heap->code_space()); | 147 VerifyMarking(heap->code_space()); |
| 161 VerifyMarking(heap->map_space()); | 148 VerifyMarking(heap->map_space()); |
| 162 VerifyMarking(heap->new_space()); | 149 VerifyMarking(heap->new_space()); |
| 163 | 150 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 Map* map = Map::cast(obj); | 389 Map* map = Map::cast(obj); |
| 403 map->VerifyOmittedMapChecks(); | 390 map->VerifyOmittedMapChecks(); |
| 404 } | 391 } |
| 405 } | 392 } |
| 406 #endif // VERIFY_HEAP | 393 #endif // VERIFY_HEAP |
| 407 | 394 |
| 408 | 395 |
| 409 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { | 396 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { |
| 410 for (Page* p : *space) { | 397 for (Page* p : *space) { |
| 411 p->ClearLiveness(); | 398 p->ClearLiveness(); |
| 412 if (p->IsFlagSet(Page::BLACK_PAGE)) { | |
| 413 p->ClearFlag(Page::BLACK_PAGE); | |
| 414 } | |
| 415 } | 399 } |
| 416 } | 400 } |
| 417 | 401 |
| 418 | 402 |
| 419 static void ClearMarkbitsInNewSpace(NewSpace* space) { | 403 static void ClearMarkbitsInNewSpace(NewSpace* space) { |
| 420 for (Page* page : *space) { | 404 for (Page* page : *space) { |
| 421 page->ClearLiveness(); | 405 page->ClearLiveness(); |
| 422 } | 406 } |
| 423 } | 407 } |
| 424 | 408 |
| 425 | 409 |
| 426 void MarkCompactCollector::ClearMarkbits() { | 410 void MarkCompactCollector::ClearMarkbits() { |
| 427 ClearMarkbitsInPagedSpace(heap_->code_space()); | 411 ClearMarkbitsInPagedSpace(heap_->code_space()); |
| 428 ClearMarkbitsInPagedSpace(heap_->map_space()); | 412 ClearMarkbitsInPagedSpace(heap_->map_space()); |
| 429 ClearMarkbitsInPagedSpace(heap_->old_space()); | 413 ClearMarkbitsInPagedSpace(heap_->old_space()); |
| 430 ClearMarkbitsInNewSpace(heap_->new_space()); | 414 ClearMarkbitsInNewSpace(heap_->new_space()); |
| 431 | 415 |
| 432 LargeObjectIterator it(heap_->lo_space()); | 416 LargeObjectIterator it(heap_->lo_space()); |
| 433 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 417 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
| 434 Marking::MarkWhite(ObjectMarking::MarkBitFrom(obj)); | 418 Marking::MarkWhite(ObjectMarking::MarkBitFrom(obj)); |
| 435 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); | 419 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
| 436 chunk->ResetProgressBar(); | 420 chunk->ResetProgressBar(); |
| 437 chunk->ResetLiveBytes(); | 421 chunk->ResetLiveBytes(); |
| 438 if (chunk->IsFlagSet(Page::BLACK_PAGE)) { | |
| 439 chunk->ClearFlag(Page::BLACK_PAGE); | |
| 440 } | |
| 441 } | 422 } |
| 442 } | 423 } |
| 443 | 424 |
| 444 class MarkCompactCollector::Sweeper::SweeperTask : public v8::Task { | 425 class MarkCompactCollector::Sweeper::SweeperTask : public v8::Task { |
| 445 public: | 426 public: |
| 446 SweeperTask(Sweeper* sweeper, base::Semaphore* pending_sweeper_tasks, | 427 SweeperTask(Sweeper* sweeper, base::Semaphore* pending_sweeper_tasks, |
| 447 AllocationSpace space_to_start) | 428 AllocationSpace space_to_start) |
| 448 : sweeper_(sweeper), | 429 : sweeper_(sweeper), |
| 449 pending_sweeper_tasks_(pending_sweeper_tasks), | 430 pending_sweeper_tasks_(pending_sweeper_tasks), |
| 450 space_to_start_(space_to_start) {} | 431 space_to_start_(space_to_start) {} |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 652 int number_of_pages = space->CountTotalPages(); | 633 int number_of_pages = space->CountTotalPages(); |
| 653 int area_size = space->AreaSize(); | 634 int area_size = space->AreaSize(); |
| 654 | 635 |
| 655 // Pairs of (live_bytes_in_page, page). | 636 // Pairs of (live_bytes_in_page, page). |
| 656 typedef std::pair<int, Page*> LiveBytesPagePair; | 637 typedef std::pair<int, Page*> LiveBytesPagePair; |
| 657 std::vector<LiveBytesPagePair> pages; | 638 std::vector<LiveBytesPagePair> pages; |
| 658 pages.reserve(number_of_pages); | 639 pages.reserve(number_of_pages); |
| 659 | 640 |
| 660 for (Page* p : *space) { | 641 for (Page* p : *space) { |
| 661 if (p->NeverEvacuate()) continue; | 642 if (p->NeverEvacuate()) continue; |
| 662 if (p->IsFlagSet(Page::BLACK_PAGE)) continue; | |
| 663 // Invariant: Evacuation candidates are just created when marking is | 643 // Invariant: Evacuation candidates are just created when marking is |
| 664 // started. This means that sweeping has finished. Furthermore, at the end | 644 // started. This means that sweeping has finished. Furthermore, at the end |
| 665 // of a GC all evacuation candidates are cleared and their slot buffers are | 645 // of a GC all evacuation candidates are cleared and their slot buffers are |
| 666 // released. | 646 // released. |
| 667 CHECK(!p->IsEvacuationCandidate()); | 647 CHECK(!p->IsEvacuationCandidate()); |
| 668 CHECK_NULL(p->old_to_old_slots()); | 648 CHECK_NULL(p->old_to_old_slots()); |
| 669 CHECK_NULL(p->typed_old_to_old_slots()); | 649 CHECK_NULL(p->typed_old_to_old_slots()); |
| 670 CHECK(p->SweepingDone()); | 650 CHECK(p->SweepingDone()); |
| 671 DCHECK(p->area_size() == area_size); | 651 DCHECK(p->area_size() == area_size); |
| 672 pages.push_back(std::make_pair(p->LiveBytesFromFreeList(), p)); | 652 pages.push_back(std::make_pair(p->LiveBytesFromFreeList(), p)); |
| (...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1906 object->IterateBody(&visitor); | 1886 object->IterateBody(&visitor); |
| 1907 return true; | 1887 return true; |
| 1908 } | 1888 } |
| 1909 | 1889 |
| 1910 private: | 1890 private: |
| 1911 Heap* heap_; | 1891 Heap* heap_; |
| 1912 }; | 1892 }; |
| 1913 | 1893 |
| 1914 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { | 1894 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { |
| 1915 for (Page* p : *space) { | 1895 for (Page* p : *space) { |
| 1916 if (!p->IsFlagSet(Page::BLACK_PAGE)) { | 1896 DiscoverGreyObjectsOnPage(p); |
| 1917 DiscoverGreyObjectsOnPage(p); | |
| 1918 } | |
| 1919 if (marking_deque()->IsFull()) return; | 1897 if (marking_deque()->IsFull()) return; |
| 1920 } | 1898 } |
| 1921 } | 1899 } |
| 1922 | 1900 |
| 1923 | 1901 |
| 1924 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { | 1902 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { |
| 1925 NewSpace* space = heap()->new_space(); | 1903 NewSpace* space = heap()->new_space(); |
| 1926 for (Page* page : NewSpacePageRange(space->bottom(), space->top())) { | 1904 for (Page* page : NewSpacePageRange(space->bottom(), space->top())) { |
| 1927 DiscoverGreyObjectsOnPage(page); | 1905 DiscoverGreyObjectsOnPage(page); |
| 1928 if (marking_deque()->IsFull()) return; | 1906 if (marking_deque()->IsFull()) return; |
| (...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2922 } | 2900 } |
| 2923 | 2901 |
| 2924 return String::cast(*p); | 2902 return String::cast(*p); |
| 2925 } | 2903 } |
| 2926 | 2904 |
| 2927 bool MarkCompactCollector::IsSlotInBlackObject(MemoryChunk* p, Address slot) { | 2905 bool MarkCompactCollector::IsSlotInBlackObject(MemoryChunk* p, Address slot) { |
| 2928 Space* owner = p->owner(); | 2906 Space* owner = p->owner(); |
| 2929 DCHECK(owner != heap_->lo_space() && owner != nullptr); | 2907 DCHECK(owner != heap_->lo_space() && owner != nullptr); |
| 2930 USE(owner); | 2908 USE(owner); |
| 2931 | 2909 |
| 2932 // If we are on a black page, we cannot find the actual object start | 2910 // We may be part of a black area. |
| 2933 // easiliy. We just return true but do not set the out_object. | 2911 if (Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(slot))) { |
| 2934 if (p->IsFlagSet(Page::BLACK_PAGE)) { | |
| 2935 return true; | 2912 return true; |
| 2936 } | 2913 } |
| 2937 | 2914 |
| 2938 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); | 2915 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); |
| 2939 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; | 2916 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; |
| 2940 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); | 2917 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); |
| 2941 MarkBit::CellType* cells = p->markbits()->cells(); | 2918 MarkBit::CellType* cells = p->markbits()->cells(); |
| 2942 Address base_address = p->area_start(); | 2919 Address base_address = p->area_start(); |
| 2943 unsigned int base_address_cell_index = Bitmap::IndexToCell( | 2920 unsigned int base_address_cell_index = Bitmap::IndexToCell( |
| 2944 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); | 2921 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3021 // for it. | 2998 // for it. |
| 3022 CHECK(large_object->IsHeapObject()); | 2999 CHECK(large_object->IsHeapObject()); |
| 3023 HeapObject* large_heap_object = HeapObject::cast(large_object); | 3000 HeapObject* large_heap_object = HeapObject::cast(large_object); |
| 3024 | 3001 |
| 3025 if (IsMarked(large_heap_object)) { | 3002 if (IsMarked(large_heap_object)) { |
| 3026 return large_heap_object; | 3003 return large_heap_object; |
| 3027 } | 3004 } |
| 3028 return nullptr; | 3005 return nullptr; |
| 3029 } | 3006 } |
| 3030 | 3007 |
| 3031 if (p->IsFlagSet(Page::BLACK_PAGE)) { | 3008 LiveObjectIterator<kBlackObjects> it(p); |
| 3032 HeapObjectIterator it(p); | 3009 HeapObject* object = nullptr; |
| 3033 HeapObject* object = nullptr; | 3010 while ((object = it.Next()) != nullptr) { |
| 3034 while ((object = it.Next()) != nullptr) { | 3011 int size = object->Size(); |
| 3035 int size = object->Size(); | 3012 if (object->address() > slot) return nullptr; |
| 3036 if (object->address() > slot) return nullptr; | 3013 if (object->address() <= slot && slot < (object->address() + size)) { |
| 3037 if (object->address() <= slot && slot < (object->address() + size)) { | 3014 return object; |
| 3038 return object; | |
| 3039 } | |
| 3040 } | |
| 3041 } else { | |
| 3042 LiveObjectIterator<kBlackObjects> it(p); | |
| 3043 HeapObject* object = nullptr; | |
| 3044 while ((object = it.Next()) != nullptr) { | |
| 3045 int size = object->Size(); | |
| 3046 if (object->address() > slot) return nullptr; | |
| 3047 if (object->address() <= slot && slot < (object->address() + size)) { | |
| 3048 return object; | |
| 3049 } | |
| 3050 } | 3015 } |
| 3051 } | 3016 } |
| 3017 | |
| 3052 return nullptr; | 3018 return nullptr; |
| 3053 } | 3019 } |
| 3054 | 3020 |
| 3055 | 3021 |
| 3056 void MarkCompactCollector::EvacuateNewSpacePrologue() { | 3022 void MarkCompactCollector::EvacuateNewSpacePrologue() { |
| 3057 NewSpace* new_space = heap()->new_space(); | 3023 NewSpace* new_space = heap()->new_space(); |
| 3058 // Append the list of new space pages to be processed. | 3024 // Append the list of new space pages to be processed. |
| 3059 for (Page* p : NewSpacePageRange(new_space->bottom(), new_space->top())) { | 3025 for (Page* p : NewSpacePageRange(new_space->bottom(), new_space->top())) { |
| 3060 newspace_evacuation_candidates_.Add(p); | 3026 newspace_evacuation_candidates_.Add(p); |
| 3061 } | 3027 } |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3378 }; | 3344 }; |
| 3379 | 3345 |
| 3380 int MarkCompactCollector::Sweeper::RawSweep( | 3346 int MarkCompactCollector::Sweeper::RawSweep( |
| 3381 Page* p, FreeListRebuildingMode free_list_mode, | 3347 Page* p, FreeListRebuildingMode free_list_mode, |
| 3382 FreeSpaceTreatmentMode free_space_mode) { | 3348 FreeSpaceTreatmentMode free_space_mode) { |
| 3383 Space* space = p->owner(); | 3349 Space* space = p->owner(); |
| 3384 DCHECK_NOT_NULL(space); | 3350 DCHECK_NOT_NULL(space); |
| 3385 DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || | 3351 DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || |
| 3386 space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); | 3352 space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); |
| 3387 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); | 3353 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); |
| 3388 DCHECK(!p->IsFlagSet(Page::BLACK_PAGE)); | |
| 3389 | 3354 |
| 3390 // Before we sweep objects on the page, we free dead array buffers which | 3355 // Before we sweep objects on the page, we free dead array buffers which |
| 3391 // requires valid mark bits. | 3356 // requires valid mark bits. |
| 3392 ArrayBufferTracker::FreeDead(p); | 3357 ArrayBufferTracker::FreeDead(p); |
| 3393 | 3358 |
| 3394 Address free_start = p->area_start(); | 3359 Address free_start = p->area_start(); |
| 3395 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3360 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
| 3396 | 3361 |
| 3397 // If we use the skip list for code space pages, we have to lock the skip | 3362 // If we use the skip list for code space pages, we have to lock the skip |
| 3398 // list because it could be accessed concurrently by the runtime or the | 3363 // list because it could be accessed concurrently by the runtime or the |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3931 return page; | 3896 return page; |
| 3932 } | 3897 } |
| 3933 | 3898 |
| 3934 void MarkCompactCollector::Sweeper::AddSweepingPageSafe(AllocationSpace space, | 3899 void MarkCompactCollector::Sweeper::AddSweepingPageSafe(AllocationSpace space, |
| 3935 Page* page) { | 3900 Page* page) { |
| 3936 base::LockGuard<base::Mutex> guard(&mutex_); | 3901 base::LockGuard<base::Mutex> guard(&mutex_); |
| 3937 sweeping_list_[space].push_back(page); | 3902 sweeping_list_[space].push_back(page); |
| 3938 } | 3903 } |
| 3939 | 3904 |
| 3940 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { | 3905 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { |
| 3941 Address space_top = space->top(); | |
| 3942 space->ClearStats(); | 3906 space->ClearStats(); |
| 3943 | 3907 |
| 3944 int will_be_swept = 0; | 3908 int will_be_swept = 0; |
| 3945 bool unused_page_present = false; | 3909 bool unused_page_present = false; |
| 3946 | 3910 |
| 3947 // Loop needs to support deletion if live bytes == 0 for a page. | 3911 // Loop needs to support deletion if live bytes == 0 for a page. |
| 3948 for (auto it = space->begin(); it != space->end();) { | 3912 for (auto it = space->begin(); it != space->end();) { |
| 3949 Page* p = *(it++); | 3913 Page* p = *(it++); |
| 3950 DCHECK(p->SweepingDone()); | 3914 DCHECK(p->SweepingDone()); |
| 3951 | 3915 |
| 3952 if (p->IsEvacuationCandidate()) { | 3916 if (p->IsEvacuationCandidate()) { |
| 3953 // Will be processed in EvacuateNewSpaceAndCandidates. | 3917 // Will be processed in EvacuateNewSpaceAndCandidates. |
| 3954 DCHECK(evacuation_candidates_.length() > 0); | 3918 DCHECK(evacuation_candidates_.length() > 0); |
| 3955 continue; | 3919 continue; |
| 3956 } | 3920 } |
| 3957 | 3921 |
| 3958 // We can not sweep black pages, since all mark bits are set for these | |
| 3959 // pages. | |
| 3960 if (p->IsFlagSet(Page::BLACK_PAGE)) { | |
| 3961 p->ClearLiveness(); | |
| 3962 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); | |
| 3963 p->ClearFlag(Page::BLACK_PAGE); | |
| 3964 // Area above the high watermark is free. | |
| 3965 Address free_start = p->HighWaterMark(); | |
| 3966 // Check if the space top was in this page, which means that the | |
| 3967 // high watermark is not up-to-date. | |
| 3968 if (free_start < space_top && space_top <= p->area_end()) { | |
| 3969 free_start = space_top; | |
| 3970 } | |
| 3971 int size = static_cast<int>(p->area_end() - free_start); | |
| 3972 space->Free(free_start, size); | |
| 3973 continue; | |
| 3974 } | |
| 3975 | |
| 3976 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { | 3922 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { |
| 3977 // We need to sweep the page to get it into an iterable state again. Note | 3923 // We need to sweep the page to get it into an iterable state again. Note |
| 3978 // that this adds unusable memory into the free list that is later on | 3924 // that this adds unusable memory into the free list that is later on |
| 3979 // (in the free list) dropped again. Since we only use the flag for | 3925 // (in the free list) dropped again. Since we only use the flag for |
| 3980 // testing this is fine. | 3926 // testing this is fine. |
| 3981 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); | 3927 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); |
| 3982 Sweeper::RawSweep(p, Sweeper::IGNORE_FREE_LIST, | 3928 Sweeper::RawSweep(p, Sweeper::IGNORE_FREE_LIST, |
| 3983 Heap::ShouldZapGarbage() ? Sweeper::ZAP_FREE_SPACE | 3929 Heap::ShouldZapGarbage() ? Sweeper::ZAP_FREE_SPACE |
| 3984 : Sweeper::IGNORE_FREE_SPACE); | 3930 : Sweeper::IGNORE_FREE_SPACE); |
| 3985 continue; | 3931 continue; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4083 // The target is always in old space, we don't have to record the slot in | 4029 // The target is always in old space, we don't have to record the slot in |
| 4084 // the old-to-new remembered set. | 4030 // the old-to-new remembered set. |
| 4085 DCHECK(!heap()->InNewSpace(target)); | 4031 DCHECK(!heap()->InNewSpace(target)); |
| 4086 RecordRelocSlot(host, &rinfo, target); | 4032 RecordRelocSlot(host, &rinfo, target); |
| 4087 } | 4033 } |
| 4088 } | 4034 } |
| 4089 } | 4035 } |
| 4090 | 4036 |
| 4091 } // namespace internal | 4037 } // namespace internal |
| 4092 } // namespace v8 | 4038 } // namespace v8 |
| OLD | NEW |