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