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 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2922 } | 2909 } |
2923 | 2910 |
2924 return String::cast(*p); | 2911 return String::cast(*p); |
2925 } | 2912 } |
2926 | 2913 |
2927 bool MarkCompactCollector::IsSlotInBlackObject(MemoryChunk* p, Address slot) { | 2914 bool MarkCompactCollector::IsSlotInBlackObject(MemoryChunk* p, Address slot) { |
2928 Space* owner = p->owner(); | 2915 Space* owner = p->owner(); |
2929 DCHECK(owner != heap_->lo_space() && owner != nullptr); | 2916 DCHECK(owner != heap_->lo_space() && owner != nullptr); |
2930 USE(owner); | 2917 USE(owner); |
2931 | 2918 |
2932 // If we are on a black page, we cannot find the actual object start | 2919 // We may be part of a black area. |
2933 // easiliy. We just return true but do not set the out_object. | 2920 if (Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(slot))) { |
2934 if (p->IsFlagSet(Page::BLACK_PAGE)) { | |
2935 return true; | 2921 return true; |
2936 } | 2922 } |
2937 | 2923 |
2938 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); | 2924 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); |
2939 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; | 2925 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; |
2940 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); | 2926 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); |
2941 MarkBit::CellType* cells = p->markbits()->cells(); | 2927 MarkBit::CellType* cells = p->markbits()->cells(); |
2942 Address base_address = p->area_start(); | 2928 Address base_address = p->area_start(); |
2943 unsigned int base_address_cell_index = Bitmap::IndexToCell( | 2929 unsigned int base_address_cell_index = Bitmap::IndexToCell( |
2944 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); | 2930 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3021 // for it. | 3007 // for it. |
3022 CHECK(large_object->IsHeapObject()); | 3008 CHECK(large_object->IsHeapObject()); |
3023 HeapObject* large_heap_object = HeapObject::cast(large_object); | 3009 HeapObject* large_heap_object = HeapObject::cast(large_object); |
3024 | 3010 |
3025 if (IsMarked(large_heap_object)) { | 3011 if (IsMarked(large_heap_object)) { |
3026 return large_heap_object; | 3012 return large_heap_object; |
3027 } | 3013 } |
3028 return nullptr; | 3014 return nullptr; |
3029 } | 3015 } |
3030 | 3016 |
3031 if (p->IsFlagSet(Page::BLACK_PAGE)) { | 3017 LiveObjectIterator<kBlackObjects> it(p); |
3032 HeapObjectIterator it(p); | 3018 HeapObject* object = nullptr; |
3033 HeapObject* object = nullptr; | 3019 while ((object = it.Next()) != nullptr) { |
3034 while ((object = it.Next()) != nullptr) { | 3020 int size = object->Size(); |
3035 int size = object->Size(); | 3021 if (object->address() > slot) return nullptr; |
3036 if (object->address() > slot) return nullptr; | 3022 if (object->address() <= slot && slot < (object->address() + size)) { |
3037 if (object->address() <= slot && slot < (object->address() + size)) { | 3023 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 } | 3024 } |
3051 } | 3025 } |
| 3026 |
3052 return nullptr; | 3027 return nullptr; |
3053 } | 3028 } |
3054 | 3029 |
3055 | 3030 |
3056 void MarkCompactCollector::EvacuateNewSpacePrologue() { | 3031 void MarkCompactCollector::EvacuateNewSpacePrologue() { |
3057 NewSpace* new_space = heap()->new_space(); | 3032 NewSpace* new_space = heap()->new_space(); |
3058 // Append the list of new space pages to be processed. | 3033 // Append the list of new space pages to be processed. |
3059 for (Page* p : NewSpacePageRange(new_space->bottom(), new_space->top())) { | 3034 for (Page* p : NewSpacePageRange(new_space->bottom(), new_space->top())) { |
3060 newspace_evacuation_candidates_.Add(p); | 3035 newspace_evacuation_candidates_.Add(p); |
3061 } | 3036 } |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3378 }; | 3353 }; |
3379 | 3354 |
3380 int MarkCompactCollector::Sweeper::RawSweep( | 3355 int MarkCompactCollector::Sweeper::RawSweep( |
3381 Page* p, FreeListRebuildingMode free_list_mode, | 3356 Page* p, FreeListRebuildingMode free_list_mode, |
3382 FreeSpaceTreatmentMode free_space_mode) { | 3357 FreeSpaceTreatmentMode free_space_mode) { |
3383 Space* space = p->owner(); | 3358 Space* space = p->owner(); |
3384 DCHECK_NOT_NULL(space); | 3359 DCHECK_NOT_NULL(space); |
3385 DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || | 3360 DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || |
3386 space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); | 3361 space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); |
3387 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); | 3362 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); |
3388 DCHECK(!p->IsFlagSet(Page::BLACK_PAGE)); | |
3389 | 3363 |
3390 // Before we sweep objects on the page, we free dead array buffers which | 3364 // Before we sweep objects on the page, we free dead array buffers which |
3391 // requires valid mark bits. | 3365 // requires valid mark bits. |
3392 ArrayBufferTracker::FreeDead(p); | 3366 ArrayBufferTracker::FreeDead(p); |
3393 | 3367 |
3394 Address free_start = p->area_start(); | 3368 Address free_start = p->area_start(); |
3395 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3369 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
3396 | 3370 |
3397 // If we use the skip list for code space pages, we have to lock the skip | 3371 // 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 | 3372 // 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; | 3905 return page; |
3932 } | 3906 } |
3933 | 3907 |
3934 void MarkCompactCollector::Sweeper::AddSweepingPageSafe(AllocationSpace space, | 3908 void MarkCompactCollector::Sweeper::AddSweepingPageSafe(AllocationSpace space, |
3935 Page* page) { | 3909 Page* page) { |
3936 base::LockGuard<base::Mutex> guard(&mutex_); | 3910 base::LockGuard<base::Mutex> guard(&mutex_); |
3937 sweeping_list_[space].push_back(page); | 3911 sweeping_list_[space].push_back(page); |
3938 } | 3912 } |
3939 | 3913 |
3940 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { | 3914 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { |
3941 Address space_top = space->top(); | |
3942 space->ClearStats(); | 3915 space->ClearStats(); |
3943 | 3916 |
3944 int will_be_swept = 0; | 3917 int will_be_swept = 0; |
3945 bool unused_page_present = false; | 3918 bool unused_page_present = false; |
3946 | 3919 |
3947 // Loop needs to support deletion if live bytes == 0 for a page. | 3920 // Loop needs to support deletion if live bytes == 0 for a page. |
3948 for (auto it = space->begin(); it != space->end();) { | 3921 for (auto it = space->begin(); it != space->end();) { |
3949 Page* p = *(it++); | 3922 Page* p = *(it++); |
3950 DCHECK(p->SweepingDone()); | 3923 DCHECK(p->SweepingDone()); |
3951 | 3924 |
3952 if (p->IsEvacuationCandidate()) { | 3925 if (p->IsEvacuationCandidate()) { |
3953 // Will be processed in EvacuateNewSpaceAndCandidates. | 3926 // Will be processed in EvacuateNewSpaceAndCandidates. |
3954 DCHECK(evacuation_candidates_.length() > 0); | 3927 DCHECK(evacuation_candidates_.length() > 0); |
3955 continue; | 3928 continue; |
3956 } | 3929 } |
3957 | 3930 |
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)) { | 3931 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { |
3977 // We need to sweep the page to get it into an iterable state again. Note | 3932 // 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 | 3933 // 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 | 3934 // (in the free list) dropped again. Since we only use the flag for |
3980 // testing this is fine. | 3935 // testing this is fine. |
3981 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); | 3936 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); |
3982 Sweeper::RawSweep(p, Sweeper::IGNORE_FREE_LIST, | 3937 Sweeper::RawSweep(p, Sweeper::IGNORE_FREE_LIST, |
3983 Heap::ShouldZapGarbage() ? Sweeper::ZAP_FREE_SPACE | 3938 Heap::ShouldZapGarbage() ? Sweeper::ZAP_FREE_SPACE |
3984 : Sweeper::IGNORE_FREE_SPACE); | 3939 : Sweeper::IGNORE_FREE_SPACE); |
3985 continue; | 3940 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 | 4038 // The target is always in old space, we don't have to record the slot in |
4084 // the old-to-new remembered set. | 4039 // the old-to-new remembered set. |
4085 DCHECK(!heap()->InNewSpace(target)); | 4040 DCHECK(!heap()->InNewSpace(target)); |
4086 RecordRelocSlot(host, &rinfo, target); | 4041 RecordRelocSlot(host, &rinfo, target); |
4087 } | 4042 } |
4088 } | 4043 } |
4089 } | 4044 } |
4090 | 4045 |
4091 } // namespace internal | 4046 } // namespace internal |
4092 } // namespace v8 | 4047 } // namespace v8 |
OLD | NEW |