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 1819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1830 LocalAllocationBuffer buffer_; | 1830 LocalAllocationBuffer buffer_; |
1831 AllocationSpace space_to_allocate_; | 1831 AllocationSpace space_to_allocate_; |
1832 intptr_t promoted_size_; | 1832 intptr_t promoted_size_; |
1833 intptr_t semispace_copied_size_; | 1833 intptr_t semispace_copied_size_; |
1834 base::HashMap* local_pretenuring_feedback_; | 1834 base::HashMap* local_pretenuring_feedback_; |
1835 }; | 1835 }; |
1836 | 1836 |
1837 class MarkCompactCollector::EvacuateNewSpacePageVisitor final | 1837 class MarkCompactCollector::EvacuateNewSpacePageVisitor final |
1838 : public MarkCompactCollector::HeapObjectVisitor { | 1838 : public MarkCompactCollector::HeapObjectVisitor { |
1839 public: | 1839 public: |
1840 explicit EvacuateNewSpacePageVisitor(Heap* heap) | 1840 enum VisitationMode { kNewToOld, kNewToNew }; |
1841 : heap_(heap), promoted_size_(0), semispace_copied_size_(0) {} | 1841 |
1842 explicit EvacuateNewSpacePageVisitor( | |
1843 Heap* heap, base::HashMap* local_pretenuring_feedback) | |
1844 : heap_(heap), | |
1845 promoted_size_(0), | |
1846 semispace_copied_size_(0), | |
1847 local_pretenuring_feedback_(local_pretenuring_feedback), | |
1848 mode_(VisitationMode::kNewToNew) {} | |
1842 | 1849 |
1843 static void MoveToOldSpace(Page* page, PagedSpace* owner) { | 1850 static void MoveToOldSpace(Page* page, PagedSpace* owner) { |
1844 page->Unlink(); | 1851 page->Unlink(); |
1845 Page* new_page = Page::ConvertNewToOld(page, owner); | 1852 Page* new_page = Page::ConvertNewToOld(page, owner); |
1846 new_page->SetFlag(Page::PAGE_NEW_OLD_PROMOTION); | 1853 new_page->SetFlag(Page::PAGE_NEW_OLD_PROMOTION); |
1847 } | 1854 } |
1848 | 1855 |
1849 static void MoveToToSpace(Page* page) { | 1856 static void MoveToToSpace(Page* page) { |
1850 page->heap()->new_space()->MovePageFromSpaceToSpace(page); | 1857 page->heap()->new_space()->MovePageFromSpaceToSpace(page); |
1851 page->SetFlag(Page::PAGE_NEW_NEW_PROMOTION); | 1858 page->SetFlag(Page::PAGE_NEW_NEW_PROMOTION); |
1852 } | 1859 } |
1853 | 1860 |
1854 inline bool Visit(HeapObject* object) { | 1861 inline bool Visit(HeapObject* object) { |
1855 RecordMigratedSlotVisitor visitor(heap_->mark_compact_collector()); | 1862 heap_->UpdateAllocationSite<Heap::kCached>(object, |
1856 object->IterateBodyFast(&visitor); | 1863 local_pretenuring_feedback_); |
1857 promoted_size_ += object->Size(); | 1864 if (mode_ == kNewToOld) { |
1865 RecordMigratedSlotVisitor visitor(heap_->mark_compact_collector()); | |
1866 object->IterateBodyFast(&visitor); | |
1867 } | |
1858 return true; | 1868 return true; |
1859 } | 1869 } |
1860 | 1870 |
1861 intptr_t promoted_size() { return promoted_size_; } | 1871 intptr_t promoted_size() { return promoted_size_; } |
1862 intptr_t semispace_copied_size() { return semispace_copied_size_; } | 1872 intptr_t semispace_copied_size() { return semispace_copied_size_; } |
1863 | 1873 |
1864 void account_semispace_copied(intptr_t copied) { | 1874 void account_semispace_copied(intptr_t bytes) { |
1865 semispace_copied_size_ += copied; | 1875 semispace_copied_size_ += bytes; |
1866 } | 1876 } |
1867 | 1877 |
1878 void account_promoted(intptr_t bytes) { promoted_size_ += bytes; } | |
1879 | |
1880 void set_mode(VisitationMode mode) { mode_ = mode; } | |
1881 | |
1868 private: | 1882 private: |
1869 Heap* heap_; | 1883 Heap* heap_; |
1870 intptr_t promoted_size_; | 1884 intptr_t promoted_size_; |
1871 intptr_t semispace_copied_size_; | 1885 intptr_t semispace_copied_size_; |
1886 base::HashMap* local_pretenuring_feedback_; | |
1887 VisitationMode mode_; | |
1872 }; | 1888 }; |
1873 | 1889 |
1874 class MarkCompactCollector::EvacuateOldSpaceVisitor final | 1890 class MarkCompactCollector::EvacuateOldSpaceVisitor final |
1875 : public MarkCompactCollector::EvacuateVisitorBase { | 1891 : public MarkCompactCollector::EvacuateVisitorBase { |
1876 public: | 1892 public: |
1877 EvacuateOldSpaceVisitor(Heap* heap, | 1893 EvacuateOldSpaceVisitor(Heap* heap, |
1878 CompactionSpaceCollection* compaction_spaces) | 1894 CompactionSpaceCollection* compaction_spaces) |
1879 : EvacuateVisitorBase(heap, compaction_spaces) {} | 1895 : EvacuateVisitorBase(heap, compaction_spaces) {} |
1880 | 1896 |
1881 inline bool Visit(HeapObject* object) override { | 1897 inline bool Visit(HeapObject* object) override { |
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2918 return FLAG_page_promotion_threshold * Page::kAllocatableMemory / 100; | 2934 return FLAG_page_promotion_threshold * Page::kAllocatableMemory / 100; |
2919 return Page::kAllocatableMemory + kPointerSize; | 2935 return Page::kAllocatableMemory + kPointerSize; |
2920 } | 2936 } |
2921 | 2937 |
2922 explicit Evacuator(MarkCompactCollector* collector) | 2938 explicit Evacuator(MarkCompactCollector* collector) |
2923 : collector_(collector), | 2939 : collector_(collector), |
2924 compaction_spaces_(collector->heap()), | 2940 compaction_spaces_(collector->heap()), |
2925 local_pretenuring_feedback_(kInitialLocalPretenuringFeedbackCapacity), | 2941 local_pretenuring_feedback_(kInitialLocalPretenuringFeedbackCapacity), |
2926 new_space_visitor_(collector->heap(), &compaction_spaces_, | 2942 new_space_visitor_(collector->heap(), &compaction_spaces_, |
2927 &local_pretenuring_feedback_), | 2943 &local_pretenuring_feedback_), |
2928 new_space_page_visitor(collector->heap()), | 2944 new_space_page_visitor(collector->heap(), &local_pretenuring_feedback_), |
2929 old_space_visitor_(collector->heap(), &compaction_spaces_), | 2945 old_space_visitor_(collector->heap(), &compaction_spaces_), |
2930 duration_(0.0), | 2946 duration_(0.0), |
2931 bytes_compacted_(0) {} | 2947 bytes_compacted_(0) {} |
2932 | 2948 |
2933 inline bool EvacuatePage(Page* chunk); | 2949 inline bool EvacuatePage(Page* chunk); |
2934 | 2950 |
2935 // Merge back locally cached info sequentially. Note that this method needs | 2951 // Merge back locally cached info sequentially. Note that this method needs |
2936 // to be called from the main thread. | 2952 // to be called from the main thread. |
2937 inline void Finalize(); | 2953 inline void Finalize(); |
2938 | 2954 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2975 TimedScope timed_scope(&evacuation_time); | 2991 TimedScope timed_scope(&evacuation_time); |
2976 switch (ComputeEvacuationMode(page)) { | 2992 switch (ComputeEvacuationMode(page)) { |
2977 case kObjectsNewToOld: | 2993 case kObjectsNewToOld: |
2978 success = collector_->VisitLiveObjects(page, &new_space_visitor_, | 2994 success = collector_->VisitLiveObjects(page, &new_space_visitor_, |
2979 kClearMarkbits); | 2995 kClearMarkbits); |
2980 ArrayBufferTracker::ProcessBuffers( | 2996 ArrayBufferTracker::ProcessBuffers( |
2981 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); | 2997 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); |
2982 DCHECK(success); | 2998 DCHECK(success); |
2983 break; | 2999 break; |
2984 case kPageNewToOld: | 3000 case kPageNewToOld: |
3001 new_space_page_visitor.set_mode(EvacuateNewSpacePageVisitor::kNewToOld); | |
2985 success = collector_->VisitLiveObjects(page, &new_space_page_visitor, | 3002 success = collector_->VisitLiveObjects(page, &new_space_page_visitor, |
2986 kKeepMarking); | 3003 kKeepMarking); |
3004 new_space_page_visitor.account_promoted(page->LiveBytes()); | |
2987 // ArrayBufferTracker will be updated during sweeping. | 3005 // ArrayBufferTracker will be updated during sweeping. |
2988 DCHECK(success); | 3006 DCHECK(success); |
2989 break; | 3007 break; |
2990 case kPageNewToNew: | 3008 case kPageNewToNew: |
3009 new_space_page_visitor.set_mode(EvacuateNewSpacePageVisitor::kNewToNew); | |
3010 success = collector_->VisitLiveObjects(page, &new_space_page_visitor, | |
Michael Lippautz
2016/11/10 14:06:02
Measured the impact on ToT splay w/ --gc-global. I
| |
3011 kKeepMarking); | |
2991 new_space_page_visitor.account_semispace_copied(page->LiveBytes()); | 3012 new_space_page_visitor.account_semispace_copied(page->LiveBytes()); |
2992 // ArrayBufferTracker will be updated during sweeping. | 3013 // ArrayBufferTracker will be updated during sweeping. |
2993 success = true; | |
2994 break; | 3014 break; |
2995 case kObjectsOldToOld: | 3015 case kObjectsOldToOld: |
2996 success = collector_->VisitLiveObjects(page, &old_space_visitor_, | 3016 success = collector_->VisitLiveObjects(page, &old_space_visitor_, |
2997 kClearMarkbits); | 3017 kClearMarkbits); |
2998 if (!success) { | 3018 if (!success) { |
2999 // Aborted compaction page. We have to record slots here, since we | 3019 // Aborted compaction page. We have to record slots here, since we |
3000 // might not have recorded them in first place. | 3020 // might not have recorded them in first place. |
3001 // Note: We mark the page as aborted here to be able to record slots | 3021 // Note: We mark the page as aborted here to be able to record slots |
3002 // for code objects in |RecordMigratedSlotVisitor|. | 3022 // for code objects in |RecordMigratedSlotVisitor|. |
3003 page->SetFlag(Page::COMPACTION_WAS_ABORTED); | 3023 page->SetFlag(Page::COMPACTION_WAS_ABORTED); |
3004 EvacuateRecordOnlyVisitor record_visitor(collector_->heap()); | 3024 EvacuateRecordOnlyVisitor record_visitor(collector_->heap()); |
3005 success = | 3025 success = |
3006 collector_->VisitLiveObjects(page, &record_visitor, kKeepMarking); | 3026 collector_->VisitLiveObjects(page, &record_visitor, kKeepMarking); |
3007 ArrayBufferTracker::ProcessBuffers( | 3027 ArrayBufferTracker::ProcessBuffers( |
3008 page, ArrayBufferTracker::kUpdateForwardedKeepOthers); | 3028 page, ArrayBufferTracker::kUpdateForwardedKeepOthers); |
3009 DCHECK(success); | 3029 DCHECK(success); |
3010 // We need to return failure here to indicate that we want this page | 3030 // We need to return failure here to indicate that we want this page |
3011 // added to the sweeper. | 3031 // added to the sweeper. |
3012 success = false; | 3032 success = false; |
3013 } else { | 3033 } else { |
3014 ArrayBufferTracker::ProcessBuffers( | 3034 ArrayBufferTracker::ProcessBuffers( |
3015 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); | 3035 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); |
3016 } | 3036 } |
3017 break; | 3037 break; |
3018 default: | |
3019 UNREACHABLE(); | |
3020 } | 3038 } |
3021 } | 3039 } |
3022 ReportCompactionProgress(evacuation_time, saved_live_bytes); | 3040 ReportCompactionProgress(evacuation_time, saved_live_bytes); |
3023 if (FLAG_trace_evacuation) { | 3041 if (FLAG_trace_evacuation) { |
3024 PrintIsolate(heap->isolate(), | 3042 PrintIsolate(heap->isolate(), |
3025 "evacuation[%p]: page=%p new_space=%d " | 3043 "evacuation[%p]: page=%p new_space=%d " |
3026 "page_evacuation=%d executable=%d contains_age_mark=%d " | 3044 "page_evacuation=%d executable=%d contains_age_mark=%d " |
3027 "live_bytes=%d time=%f\n", | 3045 "live_bytes=%d time=%f\n", |
3028 static_cast<void*>(this), static_cast<void*>(page), | 3046 static_cast<void*>(this), static_cast<void*>(page), |
3029 page->InNewSpace(), | 3047 page->InNewSpace(), |
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3921 // The target is always in old space, we don't have to record the slot in | 3939 // The target is always in old space, we don't have to record the slot in |
3922 // the old-to-new remembered set. | 3940 // the old-to-new remembered set. |
3923 DCHECK(!heap()->InNewSpace(target)); | 3941 DCHECK(!heap()->InNewSpace(target)); |
3924 RecordRelocSlot(host, &rinfo, target); | 3942 RecordRelocSlot(host, &rinfo, target); |
3925 } | 3943 } |
3926 } | 3944 } |
3927 } | 3945 } |
3928 | 3946 |
3929 } // namespace internal | 3947 } // namespace internal |
3930 } // namespace v8 | 3948 } // namespace v8 |
OLD | NEW |