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 3766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3777 | 3777 |
3778 int MarkCompactCollector::Sweeper::RawSweep( | 3778 int MarkCompactCollector::Sweeper::RawSweep( |
3779 Page* p, FreeListRebuildingMode free_list_mode, | 3779 Page* p, FreeListRebuildingMode free_list_mode, |
3780 FreeSpaceTreatmentMode free_space_mode) { | 3780 FreeSpaceTreatmentMode free_space_mode) { |
3781 Space* space = p->owner(); | 3781 Space* space = p->owner(); |
3782 DCHECK_NOT_NULL(space); | 3782 DCHECK_NOT_NULL(space); |
3783 DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || | 3783 DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || |
3784 space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); | 3784 space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); |
3785 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); | 3785 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); |
3786 | 3786 |
| 3787 // Sweeper takes the marking state of the full collector. |
| 3788 const MarkingState state = MarkingState::Internal(p); |
| 3789 |
3787 // If there are old-to-new slots in that page, we have to filter out slots | 3790 // If there are old-to-new slots in that page, we have to filter out slots |
3788 // that are in dead memory which is freed by the sweeper. | 3791 // that are in dead memory which is freed by the sweeper. |
3789 ClearOldToNewSlotsMode slots_clearing_mode = GetClearOldToNewSlotsMode(p); | 3792 ClearOldToNewSlotsMode slots_clearing_mode = GetClearOldToNewSlotsMode(p); |
3790 | 3793 |
3791 // The free ranges map is used for filtering typed slots. | 3794 // The free ranges map is used for filtering typed slots. |
3792 std::map<uint32_t, uint32_t> free_ranges; | 3795 std::map<uint32_t, uint32_t> free_ranges; |
3793 | 3796 |
3794 // Before we sweep objects on the page, we free dead array buffers which | 3797 // Before we sweep objects on the page, we free dead array buffers which |
3795 // requires valid mark bits. | 3798 // requires valid mark bits. |
3796 ArrayBufferTracker::FreeDead(p); | 3799 ArrayBufferTracker::FreeDead(p, state); |
3797 | 3800 |
3798 Address free_start = p->area_start(); | 3801 Address free_start = p->area_start(); |
3799 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3802 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
3800 | 3803 |
3801 // If we use the skip list for code space pages, we have to lock the skip | 3804 // If we use the skip list for code space pages, we have to lock the skip |
3802 // list because it could be accessed concurrently by the runtime or the | 3805 // list because it could be accessed concurrently by the runtime or the |
3803 // deoptimizer. | 3806 // deoptimizer. |
3804 const bool rebuild_skip_list = | 3807 const bool rebuild_skip_list = |
3805 space->identity() == CODE_SPACE && p->skip_list() != nullptr; | 3808 space->identity() == CODE_SPACE && p->skip_list() != nullptr; |
3806 SkipList* skip_list = p->skip_list(); | 3809 SkipList* skip_list = p->skip_list(); |
3807 if (rebuild_skip_list) { | 3810 if (rebuild_skip_list) { |
3808 skip_list->Clear(); | 3811 skip_list->Clear(); |
3809 } | 3812 } |
3810 | 3813 |
3811 intptr_t freed_bytes = 0; | 3814 intptr_t freed_bytes = 0; |
3812 intptr_t max_freed_bytes = 0; | 3815 intptr_t max_freed_bytes = 0; |
3813 int curr_region = -1; | 3816 int curr_region = -1; |
3814 | 3817 |
3815 LiveObjectIterator<kBlackObjects> it(p, MarkingState::Internal(p)); | 3818 LiveObjectIterator<kBlackObjects> it(p, state); |
3816 HeapObject* object = NULL; | 3819 HeapObject* object = NULL; |
3817 | 3820 |
3818 while ((object = it.Next()) != NULL) { | 3821 while ((object = it.Next()) != NULL) { |
3819 DCHECK(ObjectMarking::IsBlack(object, MarkingState::Internal(object))); | 3822 DCHECK(ObjectMarking::IsBlack(object, state)); |
3820 Address free_end = object->address(); | 3823 Address free_end = object->address(); |
3821 if (free_end != free_start) { | 3824 if (free_end != free_start) { |
3822 CHECK_GT(free_end, free_start); | 3825 CHECK_GT(free_end, free_start); |
3823 size_t size = static_cast<size_t>(free_end - free_start); | 3826 size_t size = static_cast<size_t>(free_end - free_start); |
3824 if (free_space_mode == ZAP_FREE_SPACE) { | 3827 if (free_space_mode == ZAP_FREE_SPACE) { |
3825 memset(free_start, 0xcc, size); | 3828 memset(free_start, 0xcc, size); |
3826 } | 3829 } |
3827 if (free_list_mode == REBUILD_FREE_LIST) { | 3830 if (free_list_mode == REBUILD_FREE_LIST) { |
3828 freed_bytes = reinterpret_cast<PagedSpace*>(space)->UnaccountedFree( | 3831 freed_bytes = reinterpret_cast<PagedSpace*>(space)->UnaccountedFree( |
3829 free_start, size); | 3832 free_start, size); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3883 | 3886 |
3884 // Clear invalid typed slots after collection all free ranges. | 3887 // Clear invalid typed slots after collection all free ranges. |
3885 if (slots_clearing_mode == CLEAR_TYPED_SLOTS) { | 3888 if (slots_clearing_mode == CLEAR_TYPED_SLOTS) { |
3886 TypedSlotSet* typed_slot_set = p->typed_slot_set<OLD_TO_NEW>(); | 3889 TypedSlotSet* typed_slot_set = p->typed_slot_set<OLD_TO_NEW>(); |
3887 if (typed_slot_set != nullptr) { | 3890 if (typed_slot_set != nullptr) { |
3888 typed_slot_set->RemoveInvaldSlots(free_ranges); | 3891 typed_slot_set->RemoveInvaldSlots(free_ranges); |
3889 } | 3892 } |
3890 } | 3893 } |
3891 | 3894 |
3892 // Clear the mark bits of that page and reset live bytes count. | 3895 // Clear the mark bits of that page and reset live bytes count. |
3893 MarkingState::Internal(p).ClearLiveness(); | 3896 state.ClearLiveness(); |
3894 | 3897 |
3895 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); | 3898 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); |
3896 if (free_list_mode == IGNORE_FREE_LIST) return 0; | 3899 if (free_list_mode == IGNORE_FREE_LIST) return 0; |
3897 return static_cast<int>(FreeList::GuaranteedAllocatable(max_freed_bytes)); | 3900 return static_cast<int>(FreeList::GuaranteedAllocatable(max_freed_bytes)); |
3898 } | 3901 } |
3899 | 3902 |
3900 void MarkCompactCollector::InvalidateCode(Code* code) { | 3903 void MarkCompactCollector::InvalidateCode(Code* code) { |
3901 Page* page = Page::FromAddress(code->address()); | 3904 Page* page = Page::FromAddress(code->address()); |
3902 Address start = code->instruction_start(); | 3905 Address start = code->instruction_start(); |
3903 Address end = code->address() + code->Size(); | 3906 Address end = code->address() + code->Size(); |
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4527 // The target is always in old space, we don't have to record the slot in | 4530 // The target is always in old space, we don't have to record the slot in |
4528 // the old-to-new remembered set. | 4531 // the old-to-new remembered set. |
4529 DCHECK(!heap()->InNewSpace(target)); | 4532 DCHECK(!heap()->InNewSpace(target)); |
4530 RecordRelocSlot(host, &rinfo, target); | 4533 RecordRelocSlot(host, &rinfo, target); |
4531 } | 4534 } |
4532 } | 4535 } |
4533 } | 4536 } |
4534 | 4537 |
4535 } // namespace internal | 4538 } // namespace internal |
4536 } // namespace v8 | 4539 } // namespace v8 |
OLD | NEW |