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 2855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2866 void MarkCompactCollector::UpdateSlotsRecordedIn(SlotsBuffer* buffer) { | 2866 void MarkCompactCollector::UpdateSlotsRecordedIn(SlotsBuffer* buffer) { |
2867 while (buffer != NULL) { | 2867 while (buffer != NULL) { |
2868 UpdateSlots(buffer); | 2868 UpdateSlots(buffer); |
2869 buffer = buffer->next(); | 2869 buffer = buffer->next(); |
2870 } | 2870 } |
2871 } | 2871 } |
2872 | 2872 |
2873 | 2873 |
2874 static void UpdatePointer(HeapObject** address, HeapObject* object) { | 2874 static void UpdatePointer(HeapObject** address, HeapObject* object) { |
2875 MapWord map_word = object->map_word(); | 2875 MapWord map_word = object->map_word(); |
2876 // The store buffer can still contain stale pointers in dead large objects. | 2876 // Since we only filter invalid slots in old space, the store buffer can |
2877 // Ignore these pointers here. | 2877 // still contain stale pointers in large object and in map spaces. Ignore |
| 2878 // these pointers here. |
2878 DCHECK(map_word.IsForwardingAddress() || | 2879 DCHECK(map_word.IsForwardingAddress() || |
2879 object->GetHeap()->lo_space()->FindPage( | 2880 !object->GetHeap()->old_space()->Contains( |
2880 reinterpret_cast<Address>(address)) != NULL); | 2881 reinterpret_cast<Address>(address))); |
2881 if (map_word.IsForwardingAddress()) { | 2882 if (map_word.IsForwardingAddress()) { |
2882 // Update the corresponding slot. | 2883 // Update the corresponding slot. |
2883 *address = map_word.ToForwardingAddress(); | 2884 *address = map_word.ToForwardingAddress(); |
2884 } | 2885 } |
2885 } | 2886 } |
2886 | 2887 |
2887 | 2888 |
2888 static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, | 2889 static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, |
2889 Object** p) { | 2890 Object** p) { |
2890 MapWord map_word = HeapObject::cast(*p)->map_word(); | 2891 MapWord map_word = HeapObject::cast(*p)->map_word(); |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3320 // - Rescan the page as slot recording in the migration buffer only | 3321 // - Rescan the page as slot recording in the migration buffer only |
3321 // happens upon moving (which we potentially didn't do). | 3322 // happens upon moving (which we potentially didn't do). |
3322 // - Leave the page in the list of pages of a space since we could not | 3323 // - Leave the page in the list of pages of a space since we could not |
3323 // fully evacuate it. | 3324 // fully evacuate it. |
3324 // - Mark them for rescanning for store buffer entries as we otherwise | 3325 // - Mark them for rescanning for store buffer entries as we otherwise |
3325 // might have stale store buffer entries that become "valid" again | 3326 // might have stale store buffer entries that become "valid" again |
3326 // after reusing the memory. Note that all existing store buffer | 3327 // after reusing the memory. Note that all existing store buffer |
3327 // entries of such pages are filtered before rescanning. | 3328 // entries of such pages are filtered before rescanning. |
3328 DCHECK(p->IsEvacuationCandidate()); | 3329 DCHECK(p->IsEvacuationCandidate()); |
3329 p->SetFlag(Page::COMPACTION_WAS_ABORTED); | 3330 p->SetFlag(Page::COMPACTION_WAS_ABORTED); |
3330 p->set_scan_on_scavenge(true); | |
3331 abandoned_pages++; | 3331 abandoned_pages++; |
3332 break; | 3332 break; |
3333 case MemoryChunk::kCompactingFinalize: | 3333 case MemoryChunk::kCompactingFinalize: |
3334 DCHECK(p->IsEvacuationCandidate()); | 3334 DCHECK(p->IsEvacuationCandidate()); |
3335 DCHECK(p->SweepingDone()); | 3335 DCHECK(p->SweepingDone()); |
3336 p->Unlink(); | 3336 p->Unlink(); |
3337 break; | 3337 break; |
3338 case MemoryChunk::kCompactingDone: | 3338 case MemoryChunk::kCompactingDone: |
3339 DCHECK(p->IsFlagSet(Page::POPULAR_PAGE)); | 3339 DCHECK(p->IsFlagSet(Page::POPULAR_PAGE)); |
3340 DCHECK(p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); | 3340 DCHECK(p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3559 | 3559 |
3560 LiveObjectIterator<kBlackObjects> it(page); | 3560 LiveObjectIterator<kBlackObjects> it(page); |
3561 HeapObject* object = nullptr; | 3561 HeapObject* object = nullptr; |
3562 while ((object = it.Next()) != nullptr) { | 3562 while ((object = it.Next()) != nullptr) { |
3563 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 3563 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
3564 if (!visitor->Visit(object)) { | 3564 if (!visitor->Visit(object)) { |
3565 if (mode == kClearMarkbits) { | 3565 if (mode == kClearMarkbits) { |
3566 page->markbits()->ClearRange( | 3566 page->markbits()->ClearRange( |
3567 page->AddressToMarkbitIndex(page->area_start()), | 3567 page->AddressToMarkbitIndex(page->area_start()), |
3568 page->AddressToMarkbitIndex(object->address())); | 3568 page->AddressToMarkbitIndex(object->address())); |
| 3569 if (page->old_to_new_slots() != nullptr) { |
| 3570 page->old_to_new_slots()->RemoveRange( |
| 3571 0, static_cast<int>(object->address() - page->address())); |
| 3572 } |
3569 RecomputeLiveBytes(page); | 3573 RecomputeLiveBytes(page); |
3570 } | 3574 } |
3571 return false; | 3575 return false; |
3572 } | 3576 } |
3573 } | 3577 } |
3574 if (mode == kClearMarkbits) { | 3578 if (mode == kClearMarkbits) { |
3575 Bitmap::Clear(page); | 3579 Bitmap::Clear(page); |
3576 } | 3580 } |
3577 return true; | 3581 return true; |
3578 } | 3582 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3713 SemiSpaceIterator to_it(heap()->new_space()); | 3717 SemiSpaceIterator to_it(heap()->new_space()); |
3714 for (HeapObject* object = to_it.Next(); object != NULL; | 3718 for (HeapObject* object = to_it.Next(); object != NULL; |
3715 object = to_it.Next()) { | 3719 object = to_it.Next()) { |
3716 Map* map = object->map(); | 3720 Map* map = object->map(); |
3717 object->IterateBody(map->instance_type(), object->SizeFromMap(map), | 3721 object->IterateBody(map->instance_type(), object->SizeFromMap(map), |
3718 &updating_visitor); | 3722 &updating_visitor); |
3719 } | 3723 } |
3720 // Update roots. | 3724 // Update roots. |
3721 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); | 3725 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); |
3722 | 3726 |
3723 StoreBufferRebuildScope scope(heap_, heap_->store_buffer(), | |
3724 &Heap::ScavengeStoreBufferCallback); | |
3725 heap_->store_buffer()->IteratePointersToNewSpace(&UpdatePointer); | 3727 heap_->store_buffer()->IteratePointersToNewSpace(&UpdatePointer); |
3726 } | 3728 } |
3727 | 3729 |
3728 { | 3730 { |
3729 GCTracer::Scope gc_scope( | 3731 GCTracer::Scope gc_scope( |
3730 heap()->tracer(), | 3732 heap()->tracer(), |
3731 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_BETWEEN_EVACUATED); | 3733 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_BETWEEN_EVACUATED); |
3732 for (Page* p : evacuation_candidates_) { | 3734 for (Page* p : evacuation_candidates_) { |
3733 DCHECK(p->IsEvacuationCandidate() || | 3735 DCHECK(p->IsEvacuationCandidate() || |
3734 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); | 3736 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3801 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); | 3803 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); |
3802 } | 3804 } |
3803 } | 3805 } |
3804 | 3806 |
3805 | 3807 |
3806 void MarkCompactCollector::ReleaseEvacuationCandidates() { | 3808 void MarkCompactCollector::ReleaseEvacuationCandidates() { |
3807 for (Page* p : evacuation_candidates_) { | 3809 for (Page* p : evacuation_candidates_) { |
3808 if (!p->IsEvacuationCandidate()) continue; | 3810 if (!p->IsEvacuationCandidate()) continue; |
3809 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); | 3811 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); |
3810 space->Free(p->area_start(), p->area_size()); | 3812 space->Free(p->area_start(), p->area_size()); |
3811 p->set_scan_on_scavenge(false); | |
3812 p->ResetLiveBytes(); | 3813 p->ResetLiveBytes(); |
3813 CHECK(p->SweepingDone()); | 3814 CHECK(p->SweepingDone()); |
3814 space->ReleasePage(p, true); | 3815 space->ReleasePage(p, true); |
3815 } | 3816 } |
3816 evacuation_candidates_.Rewind(0); | 3817 evacuation_candidates_.Rewind(0); |
3817 compacting_ = false; | 3818 compacting_ = false; |
3818 heap()->FilterStoreBufferEntriesOnAboutToBeFreedPages(); | |
3819 heap()->FreeQueuedChunks(); | 3819 heap()->FreeQueuedChunks(); |
3820 } | 3820 } |
3821 | 3821 |
3822 | 3822 |
3823 int MarkCompactCollector::SweepInParallel(PagedSpace* space, | 3823 int MarkCompactCollector::SweepInParallel(PagedSpace* space, |
3824 int required_freed_bytes, | 3824 int required_freed_bytes, |
3825 int max_pages) { | 3825 int max_pages) { |
3826 int max_freed = 0; | 3826 int max_freed = 0; |
3827 int max_freed_overall = 0; | 3827 int max_freed_overall = 0; |
3828 int page_count = 0; | 3828 int page_count = 0; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4056 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4056 MarkBit mark_bit = Marking::MarkBitFrom(host); |
4057 if (Marking::IsBlack(mark_bit)) { | 4057 if (Marking::IsBlack(mark_bit)) { |
4058 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 4058 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
4059 RecordRelocSlot(&rinfo, target); | 4059 RecordRelocSlot(&rinfo, target); |
4060 } | 4060 } |
4061 } | 4061 } |
4062 } | 4062 } |
4063 | 4063 |
4064 } // namespace internal | 4064 } // namespace internal |
4065 } // namespace v8 | 4065 } // namespace v8 |
OLD | NEW |