 Chromium Code Reviews
 Chromium Code Reviews Issue 2494723002:
  [heap] Record pretenuring feedback for moved pages  (Closed)
    
  
    Issue 2494723002:
  [heap] Record pretenuring feedback for moved pages  (Closed) 
  | 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 |