Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: src/heap/mark-compact.cc

Issue 2494723002: [heap] Record pretenuring feedback for moved pages (Closed)
Patch Set: Fix comilaton issue Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/spaces.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1816 matching lines...) Expand 10 before | Expand all | Expand 10 after
1827 return allocation; 1827 return allocation;
1828 } 1828 }
1829 1829
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 template <PageEvacuationMode mode>
1837 class MarkCompactCollector::EvacuateNewSpacePageVisitor final 1838 class MarkCompactCollector::EvacuateNewSpacePageVisitor final
1838 : public MarkCompactCollector::HeapObjectVisitor { 1839 : public MarkCompactCollector::HeapObjectVisitor {
1839 public: 1840 public:
1840 explicit EvacuateNewSpacePageVisitor(Heap* heap) 1841 explicit EvacuateNewSpacePageVisitor(
1841 : heap_(heap), promoted_size_(0), semispace_copied_size_(0) {} 1842 Heap* heap, base::HashMap* local_pretenuring_feedback)
1843 : heap_(heap),
1844 moved_bytes_(0),
1845 local_pretenuring_feedback_(local_pretenuring_feedback) {}
1842 1846
1843 static void MoveToOldSpace(Page* page, PagedSpace* owner) { 1847 static void Move(Page* page) {
1844 page->Unlink(); 1848 switch (mode) {
1845 Page* new_page = Page::ConvertNewToOld(page, owner); 1849 case NEW_TO_NEW:
1846 new_page->SetFlag(Page::PAGE_NEW_OLD_PROMOTION); 1850 page->heap()->new_space()->MovePageFromSpaceToSpace(page);
1847 } 1851 page->SetFlag(Page::PAGE_NEW_NEW_PROMOTION);
1848 1852 break;
1849 static void MoveToToSpace(Page* page) { 1853 case NEW_TO_OLD: {
1850 page->heap()->new_space()->MovePageFromSpaceToSpace(page); 1854 page->Unlink();
1851 page->SetFlag(Page::PAGE_NEW_NEW_PROMOTION); 1855 Page* new_page = Page::ConvertNewToOld(page);
1856 new_page->SetFlag(Page::PAGE_NEW_OLD_PROMOTION);
1857 break;
1858 }
1859 }
1852 } 1860 }
1853 1861
1854 inline bool Visit(HeapObject* object) { 1862 inline bool Visit(HeapObject* object) {
1855 RecordMigratedSlotVisitor visitor(heap_->mark_compact_collector()); 1863 heap_->UpdateAllocationSite<Heap::kCached>(object,
1856 object->IterateBodyFast(&visitor); 1864 local_pretenuring_feedback_);
1857 promoted_size_ += object->Size(); 1865 if (mode == NEW_TO_OLD) {
1866 RecordMigratedSlotVisitor visitor(heap_->mark_compact_collector());
1867 object->IterateBodyFast(&visitor);
1868 }
1858 return true; 1869 return true;
1859 } 1870 }
1860 1871
1861 intptr_t promoted_size() { return promoted_size_; } 1872 intptr_t moved_bytes() { return moved_bytes_; }
1862 intptr_t semispace_copied_size() { return semispace_copied_size_; } 1873 void account_moved_bytes(intptr_t bytes) { moved_bytes_ += bytes; }
1863
1864 void account_semispace_copied(intptr_t copied) {
1865 semispace_copied_size_ += copied;
1866 }
1867 1874
1868 private: 1875 private:
1869 Heap* heap_; 1876 Heap* heap_;
1870 intptr_t promoted_size_; 1877 intptr_t moved_bytes_;
1871 intptr_t semispace_copied_size_; 1878 base::HashMap* local_pretenuring_feedback_;
1872 }; 1879 };
1873 1880
1874 class MarkCompactCollector::EvacuateOldSpaceVisitor final 1881 class MarkCompactCollector::EvacuateOldSpaceVisitor final
1875 : public MarkCompactCollector::EvacuateVisitorBase { 1882 : public MarkCompactCollector::EvacuateVisitorBase {
1876 public: 1883 public:
1877 EvacuateOldSpaceVisitor(Heap* heap, 1884 EvacuateOldSpaceVisitor(Heap* heap,
1878 CompactionSpaceCollection* compaction_spaces) 1885 CompactionSpaceCollection* compaction_spaces)
1879 : EvacuateVisitorBase(heap, compaction_spaces) {} 1886 : EvacuateVisitorBase(heap, compaction_spaces) {}
1880 1887
1881 inline bool Visit(HeapObject* object) override { 1888 inline bool Visit(HeapObject* object) override {
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after
2918 return FLAG_page_promotion_threshold * Page::kAllocatableMemory / 100; 2925 return FLAG_page_promotion_threshold * Page::kAllocatableMemory / 100;
2919 return Page::kAllocatableMemory + kPointerSize; 2926 return Page::kAllocatableMemory + kPointerSize;
2920 } 2927 }
2921 2928
2922 explicit Evacuator(MarkCompactCollector* collector) 2929 explicit Evacuator(MarkCompactCollector* collector)
2923 : collector_(collector), 2930 : collector_(collector),
2924 compaction_spaces_(collector->heap()), 2931 compaction_spaces_(collector->heap()),
2925 local_pretenuring_feedback_(kInitialLocalPretenuringFeedbackCapacity), 2932 local_pretenuring_feedback_(kInitialLocalPretenuringFeedbackCapacity),
2926 new_space_visitor_(collector->heap(), &compaction_spaces_, 2933 new_space_visitor_(collector->heap(), &compaction_spaces_,
2927 &local_pretenuring_feedback_), 2934 &local_pretenuring_feedback_),
2928 new_space_page_visitor(collector->heap()), 2935 new_to_new_page_visitor_(collector->heap(),
2936 &local_pretenuring_feedback_),
2937 new_to_old_page_visitor_(collector->heap(),
2938 &local_pretenuring_feedback_),
2939
2929 old_space_visitor_(collector->heap(), &compaction_spaces_), 2940 old_space_visitor_(collector->heap(), &compaction_spaces_),
2930 duration_(0.0), 2941 duration_(0.0),
2931 bytes_compacted_(0) {} 2942 bytes_compacted_(0) {}
2932 2943
2933 inline bool EvacuatePage(Page* chunk); 2944 inline bool EvacuatePage(Page* chunk);
2934 2945
2935 // Merge back locally cached info sequentially. Note that this method needs 2946 // Merge back locally cached info sequentially. Note that this method needs
2936 // to be called from the main thread. 2947 // to be called from the main thread.
2937 inline void Finalize(); 2948 inline void Finalize();
2938 2949
(...skipping 10 matching lines...) Expand all
2949 } 2960 }
2950 2961
2951 MarkCompactCollector* collector_; 2962 MarkCompactCollector* collector_;
2952 2963
2953 // Locally cached collector data. 2964 // Locally cached collector data.
2954 CompactionSpaceCollection compaction_spaces_; 2965 CompactionSpaceCollection compaction_spaces_;
2955 base::HashMap local_pretenuring_feedback_; 2966 base::HashMap local_pretenuring_feedback_;
2956 2967
2957 // Visitors for the corresponding spaces. 2968 // Visitors for the corresponding spaces.
2958 EvacuateNewSpaceVisitor new_space_visitor_; 2969 EvacuateNewSpaceVisitor new_space_visitor_;
2959 EvacuateNewSpacePageVisitor new_space_page_visitor; 2970 EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_NEW>
2971 new_to_new_page_visitor_;
2972 EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_OLD>
2973 new_to_old_page_visitor_;
2960 EvacuateOldSpaceVisitor old_space_visitor_; 2974 EvacuateOldSpaceVisitor old_space_visitor_;
2961 2975
2962 // Book keeping info. 2976 // Book keeping info.
2963 double duration_; 2977 double duration_;
2964 intptr_t bytes_compacted_; 2978 intptr_t bytes_compacted_;
2965 }; 2979 };
2966 2980
2967 bool MarkCompactCollector::Evacuator::EvacuatePage(Page* page) { 2981 bool MarkCompactCollector::Evacuator::EvacuatePage(Page* page) {
2968 bool success = false; 2982 bool success = false;
2969 DCHECK(page->SweepingDone()); 2983 DCHECK(page->SweepingDone());
2970 int saved_live_bytes = page->LiveBytes(); 2984 int saved_live_bytes = page->LiveBytes();
2971 double evacuation_time = 0.0; 2985 double evacuation_time = 0.0;
2972 Heap* heap = page->heap(); 2986 Heap* heap = page->heap();
2973 { 2987 {
2974 AlwaysAllocateScope always_allocate(heap->isolate()); 2988 AlwaysAllocateScope always_allocate(heap->isolate());
2975 TimedScope timed_scope(&evacuation_time); 2989 TimedScope timed_scope(&evacuation_time);
2976 switch (ComputeEvacuationMode(page)) { 2990 switch (ComputeEvacuationMode(page)) {
2977 case kObjectsNewToOld: 2991 case kObjectsNewToOld:
2978 success = collector_->VisitLiveObjects(page, &new_space_visitor_, 2992 success = collector_->VisitLiveObjects(page, &new_space_visitor_,
2979 kClearMarkbits); 2993 kClearMarkbits);
2994 DCHECK(success);
2980 ArrayBufferTracker::ProcessBuffers( 2995 ArrayBufferTracker::ProcessBuffers(
2981 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); 2996 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers);
2982 DCHECK(success);
2983 break; 2997 break;
2984 case kPageNewToOld: 2998 case kPageNewToOld:
2985 success = collector_->VisitLiveObjects(page, &new_space_page_visitor, 2999 success = collector_->VisitLiveObjects(page, &new_to_old_page_visitor_,
2986 kKeepMarking); 3000 kKeepMarking);
3001 DCHECK(success);
3002 new_to_old_page_visitor_.account_moved_bytes(page->LiveBytes());
2987 // ArrayBufferTracker will be updated during sweeping. 3003 // ArrayBufferTracker will be updated during sweeping.
2988 DCHECK(success);
2989 break; 3004 break;
2990 case kPageNewToNew: 3005 case kPageNewToNew:
2991 new_space_page_visitor.account_semispace_copied(page->LiveBytes()); 3006 success = collector_->VisitLiveObjects(page, &new_to_new_page_visitor_,
3007 kKeepMarking);
3008 DCHECK(success);
3009 new_to_new_page_visitor_.account_moved_bytes(page->LiveBytes());
2992 // ArrayBufferTracker will be updated during sweeping. 3010 // ArrayBufferTracker will be updated during sweeping.
2993 success = true;
2994 break; 3011 break;
2995 case kObjectsOldToOld: 3012 case kObjectsOldToOld:
2996 success = collector_->VisitLiveObjects(page, &old_space_visitor_, 3013 success = collector_->VisitLiveObjects(page, &old_space_visitor_,
2997 kClearMarkbits); 3014 kClearMarkbits);
2998 if (!success) { 3015 if (!success) {
2999 // Aborted compaction page. We have to record slots here, since we 3016 // Aborted compaction page. We have to record slots here, since we
3000 // might not have recorded them in first place. 3017 // might not have recorded them in first place.
3001 // Note: We mark the page as aborted here to be able to record slots 3018 // Note: We mark the page as aborted here to be able to record slots
3002 // for code objects in |RecordMigratedSlotVisitor|. 3019 // for code objects in |RecordMigratedSlotVisitor|.
3003 page->SetFlag(Page::COMPACTION_WAS_ABORTED); 3020 page->SetFlag(Page::COMPACTION_WAS_ABORTED);
3004 EvacuateRecordOnlyVisitor record_visitor(collector_->heap()); 3021 EvacuateRecordOnlyVisitor record_visitor(collector_->heap());
3005 success = 3022 success =
3006 collector_->VisitLiveObjects(page, &record_visitor, kKeepMarking); 3023 collector_->VisitLiveObjects(page, &record_visitor, kKeepMarking);
3007 ArrayBufferTracker::ProcessBuffers( 3024 ArrayBufferTracker::ProcessBuffers(
3008 page, ArrayBufferTracker::kUpdateForwardedKeepOthers); 3025 page, ArrayBufferTracker::kUpdateForwardedKeepOthers);
3009 DCHECK(success); 3026 DCHECK(success);
3010 // We need to return failure here to indicate that we want this page 3027 // We need to return failure here to indicate that we want this page
3011 // added to the sweeper. 3028 // added to the sweeper.
3012 success = false; 3029 success = false;
3013 } else { 3030 } else {
3014 ArrayBufferTracker::ProcessBuffers( 3031 ArrayBufferTracker::ProcessBuffers(
3015 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); 3032 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers);
3016 } 3033 }
3017 break; 3034 break;
3018 default:
3019 UNREACHABLE();
3020 } 3035 }
3021 } 3036 }
3022 ReportCompactionProgress(evacuation_time, saved_live_bytes); 3037 ReportCompactionProgress(evacuation_time, saved_live_bytes);
3023 if (FLAG_trace_evacuation) { 3038 if (FLAG_trace_evacuation) {
3024 PrintIsolate(heap->isolate(), 3039 PrintIsolate(heap->isolate(),
3025 "evacuation[%p]: page=%p new_space=%d " 3040 "evacuation[%p]: page=%p new_space=%d "
3026 "page_evacuation=%d executable=%d contains_age_mark=%d " 3041 "page_evacuation=%d executable=%d contains_age_mark=%d "
3027 "live_bytes=%d time=%f\n", 3042 "live_bytes=%d time=%f\n",
3028 static_cast<void*>(this), static_cast<void*>(page), 3043 static_cast<void*>(this), static_cast<void*>(page),
3029 page->InNewSpace(), 3044 page->InNewSpace(),
3030 page->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION) || 3045 page->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION) ||
3031 page->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION), 3046 page->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION),
3032 page->IsFlagSet(MemoryChunk::IS_EXECUTABLE), 3047 page->IsFlagSet(MemoryChunk::IS_EXECUTABLE),
3033 page->Contains(heap->new_space()->age_mark()), 3048 page->Contains(heap->new_space()->age_mark()),
3034 saved_live_bytes, evacuation_time); 3049 saved_live_bytes, evacuation_time);
3035 } 3050 }
3036 return success; 3051 return success;
3037 } 3052 }
3038 3053
3039 void MarkCompactCollector::Evacuator::Finalize() { 3054 void MarkCompactCollector::Evacuator::Finalize() {
3040 heap()->old_space()->MergeCompactionSpace(compaction_spaces_.Get(OLD_SPACE)); 3055 heap()->old_space()->MergeCompactionSpace(compaction_spaces_.Get(OLD_SPACE));
3041 heap()->code_space()->MergeCompactionSpace( 3056 heap()->code_space()->MergeCompactionSpace(
3042 compaction_spaces_.Get(CODE_SPACE)); 3057 compaction_spaces_.Get(CODE_SPACE));
3043 heap()->tracer()->AddCompactionEvent(duration_, bytes_compacted_); 3058 heap()->tracer()->AddCompactionEvent(duration_, bytes_compacted_);
3044 heap()->IncrementPromotedObjectsSize(new_space_visitor_.promoted_size() + 3059 heap()->IncrementPromotedObjectsSize(new_space_visitor_.promoted_size() +
3045 new_space_page_visitor.promoted_size()); 3060 new_to_old_page_visitor_.moved_bytes());
3046 heap()->IncrementSemiSpaceCopiedObjectSize( 3061 heap()->IncrementSemiSpaceCopiedObjectSize(
3047 new_space_visitor_.semispace_copied_size() + 3062 new_space_visitor_.semispace_copied_size() +
3048 new_space_page_visitor.semispace_copied_size()); 3063 new_to_new_page_visitor_.moved_bytes());
3049 heap()->IncrementYoungSurvivorsCounter( 3064 heap()->IncrementYoungSurvivorsCounter(
3050 new_space_visitor_.promoted_size() + 3065 new_space_visitor_.promoted_size() +
3051 new_space_visitor_.semispace_copied_size() + 3066 new_space_visitor_.semispace_copied_size() +
3052 new_space_page_visitor.promoted_size() + 3067 new_to_old_page_visitor_.moved_bytes() +
3053 new_space_page_visitor.semispace_copied_size()); 3068 new_to_new_page_visitor_.moved_bytes());
3054 heap()->MergeAllocationSitePretenuringFeedback(local_pretenuring_feedback_); 3069 heap()->MergeAllocationSitePretenuringFeedback(local_pretenuring_feedback_);
3055 } 3070 }
3056 3071
3057 int MarkCompactCollector::NumberOfParallelCompactionTasks(int pages, 3072 int MarkCompactCollector::NumberOfParallelCompactionTasks(int pages,
3058 intptr_t live_bytes) { 3073 intptr_t live_bytes) {
3059 if (!FLAG_parallel_compaction) return 1; 3074 if (!FLAG_parallel_compaction) return 1;
3060 // Compute the number of needed tasks based on a target compaction time, the 3075 // Compute the number of needed tasks based on a target compaction time, the
3061 // profiled compaction speed and marked live memory. 3076 // profiled compaction speed and marked live memory.
3062 // 3077 //
3063 // The number of parallel compaction tasks is limited by: 3078 // The number of parallel compaction tasks is limited by:
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3140 } 3155 }
3141 3156
3142 const bool reduce_memory = heap()->ShouldReduceMemory(); 3157 const bool reduce_memory = heap()->ShouldReduceMemory();
3143 const Address age_mark = heap()->new_space()->age_mark(); 3158 const Address age_mark = heap()->new_space()->age_mark();
3144 for (Page* page : newspace_evacuation_candidates_) { 3159 for (Page* page : newspace_evacuation_candidates_) {
3145 live_bytes += page->LiveBytes(); 3160 live_bytes += page->LiveBytes();
3146 if (!reduce_memory && !page->NeverEvacuate() && 3161 if (!reduce_memory && !page->NeverEvacuate() &&
3147 (page->LiveBytes() > Evacuator::PageEvacuationThreshold()) && 3162 (page->LiveBytes() > Evacuator::PageEvacuationThreshold()) &&
3148 !page->Contains(age_mark)) { 3163 !page->Contains(age_mark)) {
3149 if (page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK)) { 3164 if (page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK)) {
3150 EvacuateNewSpacePageVisitor::MoveToOldSpace(page, heap()->old_space()); 3165 EvacuateNewSpacePageVisitor<NEW_TO_OLD>::Move(page);
3151 } else { 3166 } else {
3152 EvacuateNewSpacePageVisitor::MoveToToSpace(page); 3167 EvacuateNewSpacePageVisitor<NEW_TO_NEW>::Move(page);
3153 } 3168 }
3154 } 3169 }
3155 3170
3156 job.AddPage(page, &abandoned_pages); 3171 job.AddPage(page, &abandoned_pages);
3157 } 3172 }
3158 DCHECK_GE(job.NumberOfPages(), 1); 3173 DCHECK_GE(job.NumberOfPages(), 1);
3159 3174
3160 // Used for trace summary. 3175 // Used for trace summary.
3161 double compaction_speed = 0; 3176 double compaction_speed = 0;
3162 if (FLAG_trace_evacuation) { 3177 if (FLAG_trace_evacuation) {
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
3921 // The target is always in old space, we don't have to record the slot in 3936 // The target is always in old space, we don't have to record the slot in
3922 // the old-to-new remembered set. 3937 // the old-to-new remembered set.
3923 DCHECK(!heap()->InNewSpace(target)); 3938 DCHECK(!heap()->InNewSpace(target));
3924 RecordRelocSlot(host, &rinfo, target); 3939 RecordRelocSlot(host, &rinfo, target);
3925 } 3940 }
3926 } 3941 }
3927 } 3942 }
3928 3943
3929 } // namespace internal 3944 } // namespace internal
3930 } // namespace v8 3945 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698