| 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 |