| 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 object is either part of a black area of black allocation or a | 
|  | 115       // regular black object | 
|  | 116       Page* page = Page::FromAddress(current); | 
|  | 117       CHECK( | 
|  | 118           page->markbits()->AllBitsSetInRange( | 
|  | 119               page->AddressToMarkbitIndex(current), | 
|  | 120               page->AddressToMarkbitIndex(next_object_must_be_here_or_later)) || | 
|  | 121           page->markbits()->AllBitsClearInRange( | 
|  | 122               page->AddressToMarkbitIndex(current + kPointerSize * 2), | 
|  | 123               page->AddressToMarkbitIndex(next_object_must_be_here_or_later))); | 
|  | 124       current = next_object_must_be_here_or_later; | 
|  | 125     } else { | 
| 116       current += kPointerSize; | 126       current += kPointerSize; | 
| 117     } | 127     } | 
| 118   } | 128   } | 
| 119 } | 129 } | 
| 120 | 130 | 
| 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) { | 131 static void VerifyMarking(NewSpace* space) { | 
| 132   Address end = space->top(); | 132   Address end = space->top(); | 
| 133   // The bottom position is at the start of its page. Allows us to use | 133   // 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. | 134   // page->area_start() as start of range on all pages. | 
| 135   CHECK_EQ(space->bottom(), Page::FromAddress(space->bottom())->area_start()); | 135   CHECK_EQ(space->bottom(), Page::FromAddress(space->bottom())->area_start()); | 
| 136 | 136 | 
| 137   NewSpacePageRange range(space->bottom(), end); | 137   NewSpacePageRange range(space->bottom(), end); | 
| 138   for (auto it = range.begin(); it != range.end();) { | 138   for (auto it = range.begin(); it != range.end();) { | 
| 139     Page* page = *(it++); | 139     Page* page = *(it++); | 
| 140     Address limit = it != range.end() ? page->area_end() : end; | 140     Address limit = it != range.end() ? page->area_end() : end; | 
| 141     CHECK(limit == end || !page->Contains(end)); | 141     CHECK(limit == end || !page->Contains(end)); | 
| 142     VerifyMarking(space->heap(), page->area_start(), limit); | 142     VerifyMarking(space->heap(), page->area_start(), limit); | 
| 143   } | 143   } | 
| 144 } | 144 } | 
| 145 | 145 | 
| 146 | 146 | 
| 147 static void VerifyMarking(PagedSpace* space) { | 147 static void VerifyMarking(PagedSpace* space) { | 
| 148   for (Page* p : *space) { | 148   for (Page* p : *space) { | 
| 149     if (p->IsFlagSet(Page::BLACK_PAGE)) { | 149     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   } | 150   } | 
| 155 } | 151 } | 
| 156 | 152 | 
| 157 | 153 | 
| 158 static void VerifyMarking(Heap* heap) { | 154 static void VerifyMarking(Heap* heap) { | 
| 159   VerifyMarking(heap->old_space()); | 155   VerifyMarking(heap->old_space()); | 
| 160   VerifyMarking(heap->code_space()); | 156   VerifyMarking(heap->code_space()); | 
| 161   VerifyMarking(heap->map_space()); | 157   VerifyMarking(heap->map_space()); | 
| 162   VerifyMarking(heap->new_space()); | 158   VerifyMarking(heap->new_space()); | 
| 163 | 159 | 
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 402     Map* map = Map::cast(obj); | 398     Map* map = Map::cast(obj); | 
| 403     map->VerifyOmittedMapChecks(); | 399     map->VerifyOmittedMapChecks(); | 
| 404   } | 400   } | 
| 405 } | 401 } | 
| 406 #endif  // VERIFY_HEAP | 402 #endif  // VERIFY_HEAP | 
| 407 | 403 | 
| 408 | 404 | 
| 409 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { | 405 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { | 
| 410   for (Page* p : *space) { | 406   for (Page* p : *space) { | 
| 411     p->ClearLiveness(); | 407     p->ClearLiveness(); | 
| 412     if (p->IsFlagSet(Page::BLACK_PAGE)) { |  | 
| 413       p->ClearFlag(Page::BLACK_PAGE); |  | 
| 414     } |  | 
| 415   } | 408   } | 
| 416 } | 409 } | 
| 417 | 410 | 
| 418 | 411 | 
| 419 static void ClearMarkbitsInNewSpace(NewSpace* space) { | 412 static void ClearMarkbitsInNewSpace(NewSpace* space) { | 
| 420   for (Page* page : *space) { | 413   for (Page* page : *space) { | 
| 421     page->ClearLiveness(); | 414     page->ClearLiveness(); | 
| 422   } | 415   } | 
| 423 } | 416 } | 
| 424 | 417 | 
| 425 | 418 | 
| 426 void MarkCompactCollector::ClearMarkbits() { | 419 void MarkCompactCollector::ClearMarkbits() { | 
| 427   ClearMarkbitsInPagedSpace(heap_->code_space()); | 420   ClearMarkbitsInPagedSpace(heap_->code_space()); | 
| 428   ClearMarkbitsInPagedSpace(heap_->map_space()); | 421   ClearMarkbitsInPagedSpace(heap_->map_space()); | 
| 429   ClearMarkbitsInPagedSpace(heap_->old_space()); | 422   ClearMarkbitsInPagedSpace(heap_->old_space()); | 
| 430   ClearMarkbitsInNewSpace(heap_->new_space()); | 423   ClearMarkbitsInNewSpace(heap_->new_space()); | 
| 431 | 424 | 
| 432   LargeObjectIterator it(heap_->lo_space()); | 425   LargeObjectIterator it(heap_->lo_space()); | 
| 433   for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 426   for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 
| 434     Marking::MarkWhite(ObjectMarking::MarkBitFrom(obj)); | 427     Marking::MarkWhite(ObjectMarking::MarkBitFrom(obj)); | 
| 435     MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); | 428     MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); | 
| 436     chunk->ResetProgressBar(); | 429     chunk->ResetProgressBar(); | 
| 437     chunk->ResetLiveBytes(); | 430     chunk->ResetLiveBytes(); | 
| 438     if (chunk->IsFlagSet(Page::BLACK_PAGE)) { |  | 
| 439       chunk->ClearFlag(Page::BLACK_PAGE); |  | 
| 440     } |  | 
| 441   } | 431   } | 
| 442 } | 432 } | 
| 443 | 433 | 
| 444 class MarkCompactCollector::Sweeper::SweeperTask : public v8::Task { | 434 class MarkCompactCollector::Sweeper::SweeperTask : public v8::Task { | 
| 445  public: | 435  public: | 
| 446   SweeperTask(Sweeper* sweeper, base::Semaphore* pending_sweeper_tasks, | 436   SweeperTask(Sweeper* sweeper, base::Semaphore* pending_sweeper_tasks, | 
| 447               AllocationSpace space_to_start) | 437               AllocationSpace space_to_start) | 
| 448       : sweeper_(sweeper), | 438       : sweeper_(sweeper), | 
| 449         pending_sweeper_tasks_(pending_sweeper_tasks), | 439         pending_sweeper_tasks_(pending_sweeper_tasks), | 
| 450         space_to_start_(space_to_start) {} | 440         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(); | 642   int number_of_pages = space->CountTotalPages(); | 
| 653   int area_size = space->AreaSize(); | 643   int area_size = space->AreaSize(); | 
| 654 | 644 | 
| 655   // Pairs of (live_bytes_in_page, page). | 645   // Pairs of (live_bytes_in_page, page). | 
| 656   typedef std::pair<int, Page*> LiveBytesPagePair; | 646   typedef std::pair<int, Page*> LiveBytesPagePair; | 
| 657   std::vector<LiveBytesPagePair> pages; | 647   std::vector<LiveBytesPagePair> pages; | 
| 658   pages.reserve(number_of_pages); | 648   pages.reserve(number_of_pages); | 
| 659 | 649 | 
| 660   for (Page* p : *space) { | 650   for (Page* p : *space) { | 
| 661     if (p->NeverEvacuate()) continue; | 651     if (p->NeverEvacuate()) continue; | 
| 662     if (p->IsFlagSet(Page::BLACK_PAGE)) continue; |  | 
| 663     // Invariant: Evacuation candidates are just created when marking is | 652     // Invariant: Evacuation candidates are just created when marking is | 
| 664     // started. This means that sweeping has finished. Furthermore, at the end | 653     // 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 | 654     // of a GC all evacuation candidates are cleared and their slot buffers are | 
| 666     // released. | 655     // released. | 
| 667     CHECK(!p->IsEvacuationCandidate()); | 656     CHECK(!p->IsEvacuationCandidate()); | 
| 668     CHECK_NULL(p->old_to_old_slots()); | 657     CHECK_NULL(p->old_to_old_slots()); | 
| 669     CHECK_NULL(p->typed_old_to_old_slots()); | 658     CHECK_NULL(p->typed_old_to_old_slots()); | 
| 670     CHECK(p->SweepingDone()); | 659     CHECK(p->SweepingDone()); | 
| 671     DCHECK(p->area_size() == area_size); | 660     DCHECK(p->area_size() == area_size); | 
| 672     pages.push_back(std::make_pair(p->LiveBytesFromFreeList(), p)); | 661     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); | 1895     object->IterateBody(&visitor); | 
| 1907     return true; | 1896     return true; | 
| 1908   } | 1897   } | 
| 1909 | 1898 | 
| 1910  private: | 1899  private: | 
| 1911   Heap* heap_; | 1900   Heap* heap_; | 
| 1912 }; | 1901 }; | 
| 1913 | 1902 | 
| 1914 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { | 1903 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { | 
| 1915   for (Page* p : *space) { | 1904   for (Page* p : *space) { | 
| 1916     if (!p->IsFlagSet(Page::BLACK_PAGE)) { | 1905     DiscoverGreyObjectsOnPage(p); | 
| 1917       DiscoverGreyObjectsOnPage(p); |  | 
| 1918     } |  | 
| 1919     if (marking_deque()->IsFull()) return; | 1906     if (marking_deque()->IsFull()) return; | 
| 1920   } | 1907   } | 
| 1921 } | 1908 } | 
| 1922 | 1909 | 
| 1923 | 1910 | 
| 1924 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { | 1911 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { | 
| 1925   NewSpace* space = heap()->new_space(); | 1912   NewSpace* space = heap()->new_space(); | 
| 1926   for (Page* page : NewSpacePageRange(space->bottom(), space->top())) { | 1913   for (Page* page : NewSpacePageRange(space->bottom(), space->top())) { | 
| 1927     DiscoverGreyObjectsOnPage(page); | 1914     DiscoverGreyObjectsOnPage(page); | 
| 1928     if (marking_deque()->IsFull()) return; | 1915     if (marking_deque()->IsFull()) return; | 
| (...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2925   } | 2912   } | 
| 2926 | 2913 | 
| 2927   return String::cast(*p); | 2914   return String::cast(*p); | 
| 2928 } | 2915 } | 
| 2929 | 2916 | 
| 2930 bool MarkCompactCollector::IsSlotInBlackObject(MemoryChunk* p, Address slot) { | 2917 bool MarkCompactCollector::IsSlotInBlackObject(MemoryChunk* p, Address slot) { | 
| 2931   Space* owner = p->owner(); | 2918   Space* owner = p->owner(); | 
| 2932   DCHECK(owner != heap_->lo_space() && owner != nullptr); | 2919   DCHECK(owner != heap_->lo_space() && owner != nullptr); | 
| 2933   USE(owner); | 2920   USE(owner); | 
| 2934 | 2921 | 
| 2935   // If we are on a black page, we cannot find the actual object start | 2922   // We may be part of a black area. | 
| 2936   // easiliy. We just return true but do not set the out_object. | 2923   if (Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(slot))) { | 
| 2937   if (p->IsFlagSet(Page::BLACK_PAGE)) { |  | 
| 2938     return true; | 2924     return true; | 
| 2939   } | 2925   } | 
| 2940 | 2926 | 
| 2941   uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); | 2927   uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); | 
| 2942   unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; | 2928   unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; | 
| 2943   MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); | 2929   MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); | 
| 2944   MarkBit::CellType* cells = p->markbits()->cells(); | 2930   MarkBit::CellType* cells = p->markbits()->cells(); | 
| 2945   Address base_address = p->area_start(); | 2931   Address base_address = p->area_start(); | 
| 2946   unsigned int base_address_cell_index = Bitmap::IndexToCell( | 2932   unsigned int base_address_cell_index = Bitmap::IndexToCell( | 
| 2947       Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); | 2933       Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3024     // for it. | 3010     // for it. | 
| 3025     CHECK(large_object->IsHeapObject()); | 3011     CHECK(large_object->IsHeapObject()); | 
| 3026     HeapObject* large_heap_object = HeapObject::cast(large_object); | 3012     HeapObject* large_heap_object = HeapObject::cast(large_object); | 
| 3027 | 3013 | 
| 3028     if (IsMarked(large_heap_object)) { | 3014     if (IsMarked(large_heap_object)) { | 
| 3029       return large_heap_object; | 3015       return large_heap_object; | 
| 3030     } | 3016     } | 
| 3031     return nullptr; | 3017     return nullptr; | 
| 3032   } | 3018   } | 
| 3033 | 3019 | 
| 3034   if (p->IsFlagSet(Page::BLACK_PAGE)) { | 3020   LiveObjectIterator<kBlackObjects> it(p); | 
| 3035     HeapObjectIterator it(p); | 3021   HeapObject* object = nullptr; | 
| 3036     HeapObject* object = nullptr; | 3022   while ((object = it.Next()) != nullptr) { | 
| 3037     while ((object = it.Next()) != nullptr) { | 3023     int size = object->Size(); | 
| 3038       int size = object->Size(); | 3024     if (object->address() > slot) return nullptr; | 
| 3039       if (object->address() > slot) return nullptr; | 3025     if (object->address() <= slot && slot < (object->address() + size)) { | 
| 3040       if (object->address() <= slot && slot < (object->address() + size)) { | 3026       return object; | 
| 3041         return object; |  | 
| 3042       } |  | 
| 3043     } |  | 
| 3044   } else { |  | 
| 3045     LiveObjectIterator<kBlackObjects> it(p); |  | 
| 3046     HeapObject* object = nullptr; |  | 
| 3047     while ((object = it.Next()) != nullptr) { |  | 
| 3048       int size = object->Size(); |  | 
| 3049       if (object->address() > slot) return nullptr; |  | 
| 3050       if (object->address() <= slot && slot < (object->address() + size)) { |  | 
| 3051         return object; |  | 
| 3052       } |  | 
| 3053     } | 3027     } | 
| 3054   } | 3028   } | 
|  | 3029 | 
| 3055   return nullptr; | 3030   return nullptr; | 
| 3056 } | 3031 } | 
| 3057 | 3032 | 
| 3058 | 3033 | 
| 3059 void MarkCompactCollector::EvacuateNewSpacePrologue() { | 3034 void MarkCompactCollector::EvacuateNewSpacePrologue() { | 
| 3060   NewSpace* new_space = heap()->new_space(); | 3035   NewSpace* new_space = heap()->new_space(); | 
| 3061   // Append the list of new space pages to be processed. | 3036   // Append the list of new space pages to be processed. | 
| 3062   for (Page* p : NewSpacePageRange(new_space->bottom(), new_space->top())) { | 3037   for (Page* p : NewSpacePageRange(new_space->bottom(), new_space->top())) { | 
| 3063     newspace_evacuation_candidates_.Add(p); | 3038     newspace_evacuation_candidates_.Add(p); | 
| 3064   } | 3039   } | 
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3381 }; | 3356 }; | 
| 3382 | 3357 | 
| 3383 int MarkCompactCollector::Sweeper::RawSweep( | 3358 int MarkCompactCollector::Sweeper::RawSweep( | 
| 3384     Page* p, FreeListRebuildingMode free_list_mode, | 3359     Page* p, FreeListRebuildingMode free_list_mode, | 
| 3385     FreeSpaceTreatmentMode free_space_mode) { | 3360     FreeSpaceTreatmentMode free_space_mode) { | 
| 3386   Space* space = p->owner(); | 3361   Space* space = p->owner(); | 
| 3387   DCHECK_NOT_NULL(space); | 3362   DCHECK_NOT_NULL(space); | 
| 3388   DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || | 3363   DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || | 
| 3389          space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); | 3364          space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); | 
| 3390   DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); | 3365   DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); | 
| 3391   DCHECK(!p->IsFlagSet(Page::BLACK_PAGE)); |  | 
| 3392 | 3366 | 
| 3393   // Before we sweep objects on the page, we free dead array buffers which | 3367   // Before we sweep objects on the page, we free dead array buffers which | 
| 3394   // requires valid mark bits. | 3368   // requires valid mark bits. | 
| 3395   ArrayBufferTracker::FreeDead(p); | 3369   ArrayBufferTracker::FreeDead(p); | 
| 3396 | 3370 | 
| 3397   Address free_start = p->area_start(); | 3371   Address free_start = p->area_start(); | 
| 3398   DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3372   DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 
| 3399 | 3373 | 
| 3400   // If we use the skip list for code space pages, we have to lock the skip | 3374   // If we use the skip list for code space pages, we have to lock the skip | 
| 3401   // list because it could be accessed concurrently by the runtime or the | 3375   // 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... | 
| 3934   return page; | 3908   return page; | 
| 3935 } | 3909 } | 
| 3936 | 3910 | 
| 3937 void MarkCompactCollector::Sweeper::AddSweepingPageSafe(AllocationSpace space, | 3911 void MarkCompactCollector::Sweeper::AddSweepingPageSafe(AllocationSpace space, | 
| 3938                                                         Page* page) { | 3912                                                         Page* page) { | 
| 3939   base::LockGuard<base::Mutex> guard(&mutex_); | 3913   base::LockGuard<base::Mutex> guard(&mutex_); | 
| 3940   sweeping_list_[space].push_back(page); | 3914   sweeping_list_[space].push_back(page); | 
| 3941 } | 3915 } | 
| 3942 | 3916 | 
| 3943 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { | 3917 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { | 
| 3944   Address space_top = space->top(); |  | 
| 3945   space->ClearStats(); | 3918   space->ClearStats(); | 
| 3946 | 3919 | 
| 3947   int will_be_swept = 0; | 3920   int will_be_swept = 0; | 
| 3948   bool unused_page_present = false; | 3921   bool unused_page_present = false; | 
| 3949 | 3922 | 
| 3950   // Loop needs to support deletion if live bytes == 0 for a page. | 3923   // Loop needs to support deletion if live bytes == 0 for a page. | 
| 3951   for (auto it = space->begin(); it != space->end();) { | 3924   for (auto it = space->begin(); it != space->end();) { | 
| 3952     Page* p = *(it++); | 3925     Page* p = *(it++); | 
| 3953     DCHECK(p->SweepingDone()); | 3926     DCHECK(p->SweepingDone()); | 
| 3954 | 3927 | 
| 3955     if (p->IsEvacuationCandidate()) { | 3928     if (p->IsEvacuationCandidate()) { | 
| 3956       // Will be processed in EvacuateNewSpaceAndCandidates. | 3929       // Will be processed in EvacuateNewSpaceAndCandidates. | 
| 3957       DCHECK(evacuation_candidates_.length() > 0); | 3930       DCHECK(evacuation_candidates_.length() > 0); | 
| 3958       continue; | 3931       continue; | 
| 3959     } | 3932     } | 
| 3960 | 3933 | 
| 3961     // We can not sweep black pages, since all mark bits are set for these |  | 
| 3962     // pages. |  | 
| 3963     if (p->IsFlagSet(Page::BLACK_PAGE)) { |  | 
| 3964       p->ClearLiveness(); |  | 
| 3965       p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); |  | 
| 3966       p->ClearFlag(Page::BLACK_PAGE); |  | 
| 3967       // Area above the high watermark is free. |  | 
| 3968       Address free_start = p->HighWaterMark(); |  | 
| 3969       // Check if the space top was in this page, which means that the |  | 
| 3970       // high watermark is not up-to-date. |  | 
| 3971       if (free_start < space_top && space_top <= p->area_end()) { |  | 
| 3972         free_start = space_top; |  | 
| 3973       } |  | 
| 3974       int size = static_cast<int>(p->area_end() - free_start); |  | 
| 3975       space->Free(free_start, size); |  | 
| 3976       continue; |  | 
| 3977     } |  | 
| 3978 |  | 
| 3979     if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { | 3934     if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { | 
| 3980       // We need to sweep the page to get it into an iterable state again. Note | 3935       // We need to sweep the page to get it into an iterable state again. Note | 
| 3981       // that this adds unusable memory into the free list that is later on | 3936       // that this adds unusable memory into the free list that is later on | 
| 3982       // (in the free list) dropped again. Since we only use the flag for | 3937       // (in the free list) dropped again. Since we only use the flag for | 
| 3983       // testing this is fine. | 3938       // testing this is fine. | 
| 3984       p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); | 3939       p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); | 
| 3985       Sweeper::RawSweep(p, Sweeper::IGNORE_FREE_LIST, | 3940       Sweeper::RawSweep(p, Sweeper::IGNORE_FREE_LIST, | 
| 3986                         Heap::ShouldZapGarbage() ? Sweeper::ZAP_FREE_SPACE | 3941                         Heap::ShouldZapGarbage() ? Sweeper::ZAP_FREE_SPACE | 
| 3987                                                  : Sweeper::IGNORE_FREE_SPACE); | 3942                                                  : Sweeper::IGNORE_FREE_SPACE); | 
| 3988       continue; | 3943       continue; | 
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4086       // The target is always in old space, we don't have to record the slot in | 4041       // The target is always in old space, we don't have to record the slot in | 
| 4087       // the old-to-new remembered set. | 4042       // the old-to-new remembered set. | 
| 4088       DCHECK(!heap()->InNewSpace(target)); | 4043       DCHECK(!heap()->InNewSpace(target)); | 
| 4089       RecordRelocSlot(host, &rinfo, target); | 4044       RecordRelocSlot(host, &rinfo, target); | 
| 4090     } | 4045     } | 
| 4091   } | 4046   } | 
| 4092 } | 4047 } | 
| 4093 | 4048 | 
| 4094 }  // namespace internal | 4049 }  // namespace internal | 
| 4095 }  // namespace v8 | 4050 }  // namespace v8 | 
| OLD | NEW | 
|---|