| 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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 127 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
| 128 object->Iterate(&visitor); | 128 object->Iterate(&visitor); |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 | 131 |
| 132 static void VerifyMarking(NewSpace* space) { | 132 static void VerifyMarking(NewSpace* space) { |
| 133 Address end = space->top(); | 133 Address end = space->top(); |
| 134 NewSpacePageIterator it(space->bottom(), end); | 134 NewSpacePageIterator it(space->bottom(), end); |
| 135 // The bottom position is at the start of its page. Allows us to use | 135 // The bottom position is at the start of its page. Allows us to use |
| 136 // page->area_start() as start of range on all pages. | 136 // page->area_start() as start of range on all pages. |
| 137 CHECK_EQ(space->bottom(), | 137 CHECK_EQ(space->bottom(), Page::FromAddress(space->bottom())->area_start()); |
| 138 NewSpacePage::FromAddress(space->bottom())->area_start()); | |
| 139 while (it.has_next()) { | 138 while (it.has_next()) { |
| 140 NewSpacePage* page = it.next(); | 139 Page* page = it.next(); |
| 141 Address limit = it.has_next() ? page->area_end() : end; | 140 Address limit = it.has_next() ? page->area_end() : end; |
| 142 CHECK(limit == end || !page->Contains(end)); | 141 CHECK(limit == end || !page->Contains(end)); |
| 143 VerifyMarking(space->heap(), page->area_start(), limit); | 142 VerifyMarking(space->heap(), page->area_start(), limit); |
| 144 } | 143 } |
| 145 } | 144 } |
| 146 | 145 |
| 147 | 146 |
| 148 static void VerifyMarking(PagedSpace* space) { | 147 static void VerifyMarking(PagedSpace* space) { |
| 149 PageIterator it(space); | 148 PageIterator it(space); |
| 150 | 149 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 } | 201 } |
| 203 } | 202 } |
| 204 } | 203 } |
| 205 | 204 |
| 206 | 205 |
| 207 static void VerifyEvacuation(NewSpace* space) { | 206 static void VerifyEvacuation(NewSpace* space) { |
| 208 NewSpacePageIterator it(space->bottom(), space->top()); | 207 NewSpacePageIterator it(space->bottom(), space->top()); |
| 209 VerifyEvacuationVisitor visitor; | 208 VerifyEvacuationVisitor visitor; |
| 210 | 209 |
| 211 while (it.has_next()) { | 210 while (it.has_next()) { |
| 212 NewSpacePage* page = it.next(); | 211 Page* page = it.next(); |
| 213 Address current = page->area_start(); | 212 Address current = page->area_start(); |
| 214 Address limit = it.has_next() ? page->area_end() : space->top(); | 213 Address limit = it.has_next() ? page->area_end() : space->top(); |
| 215 CHECK(limit == space->top() || !page->Contains(space->top())); | 214 CHECK(limit == space->top() || !page->Contains(space->top())); |
| 216 while (current < limit) { | 215 while (current < limit) { |
| 217 HeapObject* object = HeapObject::FromAddress(current); | 216 HeapObject* object = HeapObject::FromAddress(current); |
| 218 object->Iterate(&visitor); | 217 object->Iterate(&visitor); |
| 219 current += object->Size(); | 218 current += object->Size(); |
| 220 } | 219 } |
| 221 } | 220 } |
| 222 } | 221 } |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 CHECK(p->markbits()->IsClean()); | 367 CHECK(p->markbits()->IsClean()); |
| 369 CHECK_EQ(0, p->LiveBytes()); | 368 CHECK_EQ(0, p->LiveBytes()); |
| 370 } | 369 } |
| 371 } | 370 } |
| 372 | 371 |
| 373 | 372 |
| 374 void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) { | 373 void MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) { |
| 375 NewSpacePageIterator it(space->bottom(), space->top()); | 374 NewSpacePageIterator it(space->bottom(), space->top()); |
| 376 | 375 |
| 377 while (it.has_next()) { | 376 while (it.has_next()) { |
| 378 NewSpacePage* p = it.next(); | 377 Page* p = it.next(); |
| 379 CHECK(p->markbits()->IsClean()); | 378 CHECK(p->markbits()->IsClean()); |
| 380 CHECK_EQ(0, p->LiveBytes()); | 379 CHECK_EQ(0, p->LiveBytes()); |
| 381 } | 380 } |
| 382 } | 381 } |
| 383 | 382 |
| 384 | 383 |
| 385 void MarkCompactCollector::VerifyMarkbitsAreClean() { | 384 void MarkCompactCollector::VerifyMarkbitsAreClean() { |
| 386 VerifyMarkbitsAreClean(heap_->old_space()); | 385 VerifyMarkbitsAreClean(heap_->old_space()); |
| 387 VerifyMarkbitsAreClean(heap_->code_space()); | 386 VerifyMarkbitsAreClean(heap_->code_space()); |
| 388 VerifyMarkbitsAreClean(heap_->map_space()); | 387 VerifyMarkbitsAreClean(heap_->map_space()); |
| (...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1796 intptr_t promoted_size_; | 1795 intptr_t promoted_size_; |
| 1797 intptr_t semispace_copied_size_; | 1796 intptr_t semispace_copied_size_; |
| 1798 HashMap* local_pretenuring_feedback_; | 1797 HashMap* local_pretenuring_feedback_; |
| 1799 }; | 1798 }; |
| 1800 | 1799 |
| 1801 class MarkCompactCollector::EvacuateNewSpacePageVisitor final | 1800 class MarkCompactCollector::EvacuateNewSpacePageVisitor final |
| 1802 : public MarkCompactCollector::HeapObjectVisitor { | 1801 : public MarkCompactCollector::HeapObjectVisitor { |
| 1803 public: | 1802 public: |
| 1804 EvacuateNewSpacePageVisitor() : promoted_size_(0) {} | 1803 EvacuateNewSpacePageVisitor() : promoted_size_(0) {} |
| 1805 | 1804 |
| 1806 static void MoveToOldSpace(NewSpacePage* page, PagedSpace* owner) { | 1805 static void MoveToOldSpace(Page* page, PagedSpace* owner) { |
| 1807 page->heap()->new_space()->ReplaceWithEmptyPage(page); | 1806 page->heap()->new_space()->ReplaceWithEmptyPage(page); |
| 1808 Page* new_page = Page::Convert(page, owner); | 1807 Page* new_page = Page::ConvertNewToOld(page, owner); |
| 1809 new_page->SetFlag(Page::PAGE_NEW_OLD_PROMOTION); | 1808 new_page->SetFlag(Page::PAGE_NEW_OLD_PROMOTION); |
| 1810 } | 1809 } |
| 1811 | 1810 |
| 1812 inline bool Visit(HeapObject* object) { | 1811 inline bool Visit(HeapObject* object) { |
| 1813 if (V8_UNLIKELY(object->IsJSArrayBuffer())) { | 1812 if (V8_UNLIKELY(object->IsJSArrayBuffer())) { |
| 1814 object->GetHeap()->array_buffer_tracker()->Promote( | 1813 object->GetHeap()->array_buffer_tracker()->Promote( |
| 1815 JSArrayBuffer::cast(object)); | 1814 JSArrayBuffer::cast(object)); |
| 1816 } | 1815 } |
| 1817 RecordMigratedSlotVisitor visitor; | 1816 RecordMigratedSlotVisitor visitor; |
| 1818 object->IterateBodyFast(&visitor); | 1817 object->IterateBodyFast(&visitor); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1877 } | 1876 } |
| 1878 if (marking_deque()->IsFull()) return; | 1877 if (marking_deque()->IsFull()) return; |
| 1879 } | 1878 } |
| 1880 } | 1879 } |
| 1881 | 1880 |
| 1882 | 1881 |
| 1883 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { | 1882 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { |
| 1884 NewSpace* space = heap()->new_space(); | 1883 NewSpace* space = heap()->new_space(); |
| 1885 NewSpacePageIterator it(space->bottom(), space->top()); | 1884 NewSpacePageIterator it(space->bottom(), space->top()); |
| 1886 while (it.has_next()) { | 1885 while (it.has_next()) { |
| 1887 NewSpacePage* page = it.next(); | 1886 Page* page = it.next(); |
| 1888 DiscoverGreyObjectsOnPage(page); | 1887 DiscoverGreyObjectsOnPage(page); |
| 1889 if (marking_deque()->IsFull()) return; | 1888 if (marking_deque()->IsFull()) return; |
| 1890 } | 1889 } |
| 1891 } | 1890 } |
| 1892 | 1891 |
| 1893 | 1892 |
| 1894 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { | 1893 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { |
| 1895 Object* o = *p; | 1894 Object* o = *p; |
| 1896 if (!o->IsHeapObject()) return false; | 1895 if (!o->IsHeapObject()) return false; |
| 1897 HeapObject* heap_object = HeapObject::cast(o); | 1896 HeapObject* heap_object = HeapObject::cast(o); |
| (...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3043 void MarkCompactCollector::EvacuateNewSpaceEpilogue() { | 3042 void MarkCompactCollector::EvacuateNewSpaceEpilogue() { |
| 3044 newspace_evacuation_candidates_.Rewind(0); | 3043 newspace_evacuation_candidates_.Rewind(0); |
| 3045 } | 3044 } |
| 3046 | 3045 |
| 3047 class MarkCompactCollector::Evacuator : public Malloced { | 3046 class MarkCompactCollector::Evacuator : public Malloced { |
| 3048 public: | 3047 public: |
| 3049 // NewSpacePages with more live bytes than this threshold qualify for fast | 3048 // NewSpacePages with more live bytes than this threshold qualify for fast |
| 3050 // evacuation. | 3049 // evacuation. |
| 3051 static int PageEvacuationThreshold() { | 3050 static int PageEvacuationThreshold() { |
| 3052 if (FLAG_page_promotion) | 3051 if (FLAG_page_promotion) |
| 3053 return FLAG_page_promotion_threshold * NewSpacePage::kAllocatableMemory / | 3052 return FLAG_page_promotion_threshold * Page::kAllocatableMemory / 100; |
| 3054 100; | 3053 return Page::kAllocatableMemory + kPointerSize; |
| 3055 return NewSpacePage::kAllocatableMemory + kPointerSize; | |
| 3056 } | 3054 } |
| 3057 | 3055 |
| 3058 explicit Evacuator(MarkCompactCollector* collector) | 3056 explicit Evacuator(MarkCompactCollector* collector) |
| 3059 : collector_(collector), | 3057 : collector_(collector), |
| 3060 compaction_spaces_(collector->heap()), | 3058 compaction_spaces_(collector->heap()), |
| 3061 local_pretenuring_feedback_(HashMap::PointersMatch, | 3059 local_pretenuring_feedback_(HashMap::PointersMatch, |
| 3062 kInitialLocalPretenuringFeedbackCapacity), | 3060 kInitialLocalPretenuringFeedbackCapacity), |
| 3063 new_space_visitor_(collector->heap(), &compaction_spaces_, | 3061 new_space_visitor_(collector->heap(), &compaction_spaces_, |
| 3064 &local_pretenuring_feedback_), | 3062 &local_pretenuring_feedback_), |
| 3065 new_space_page_visitor(), | 3063 new_space_page_visitor(), |
| 3066 old_space_visitor_(collector->heap(), &compaction_spaces_), | 3064 old_space_visitor_(collector->heap(), &compaction_spaces_), |
| 3067 duration_(0.0), | 3065 duration_(0.0), |
| 3068 bytes_compacted_(0) {} | 3066 bytes_compacted_(0) {} |
| 3069 | 3067 |
| 3070 inline bool EvacuatePage(MemoryChunk* chunk); | 3068 inline bool EvacuatePage(Page* chunk); |
| 3071 | 3069 |
| 3072 // Merge back locally cached info sequentially. Note that this method needs | 3070 // Merge back locally cached info sequentially. Note that this method needs |
| 3073 // to be called from the main thread. | 3071 // to be called from the main thread. |
| 3074 inline void Finalize(); | 3072 inline void Finalize(); |
| 3075 | 3073 |
| 3076 CompactionSpaceCollection* compaction_spaces() { return &compaction_spaces_; } | 3074 CompactionSpaceCollection* compaction_spaces() { return &compaction_spaces_; } |
| 3077 | 3075 |
| 3078 private: | 3076 private: |
| 3079 enum EvacuationMode { | 3077 enum EvacuationMode { |
| 3080 kObjectsNewToOld, | 3078 kObjectsNewToOld, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3094 DCHECK(chunk->IsEvacuationCandidate()); | 3092 DCHECK(chunk->IsEvacuationCandidate()); |
| 3095 return kObjectsOldToOld; | 3093 return kObjectsOldToOld; |
| 3096 } | 3094 } |
| 3097 | 3095 |
| 3098 void ReportCompactionProgress(double duration, intptr_t bytes_compacted) { | 3096 void ReportCompactionProgress(double duration, intptr_t bytes_compacted) { |
| 3099 duration_ += duration; | 3097 duration_ += duration; |
| 3100 bytes_compacted_ += bytes_compacted; | 3098 bytes_compacted_ += bytes_compacted; |
| 3101 } | 3099 } |
| 3102 | 3100 |
| 3103 template <IterationMode mode, class Visitor> | 3101 template <IterationMode mode, class Visitor> |
| 3104 inline bool EvacuateSinglePage(MemoryChunk* p, Visitor* visitor); | 3102 inline bool EvacuateSinglePage(Page* p, Visitor* visitor); |
| 3105 | 3103 |
| 3106 MarkCompactCollector* collector_; | 3104 MarkCompactCollector* collector_; |
| 3107 | 3105 |
| 3108 // Locally cached collector data. | 3106 // Locally cached collector data. |
| 3109 CompactionSpaceCollection compaction_spaces_; | 3107 CompactionSpaceCollection compaction_spaces_; |
| 3110 HashMap local_pretenuring_feedback_; | 3108 HashMap local_pretenuring_feedback_; |
| 3111 | 3109 |
| 3112 // Visitors for the corresponding spaces. | 3110 // Visitors for the corresponding spaces. |
| 3113 EvacuateNewSpaceVisitor new_space_visitor_; | 3111 EvacuateNewSpaceVisitor new_space_visitor_; |
| 3114 EvacuateNewSpacePageVisitor new_space_page_visitor; | 3112 EvacuateNewSpacePageVisitor new_space_page_visitor; |
| 3115 EvacuateOldSpaceVisitor old_space_visitor_; | 3113 EvacuateOldSpaceVisitor old_space_visitor_; |
| 3116 | 3114 |
| 3117 // Book keeping info. | 3115 // Book keeping info. |
| 3118 double duration_; | 3116 double duration_; |
| 3119 intptr_t bytes_compacted_; | 3117 intptr_t bytes_compacted_; |
| 3120 }; | 3118 }; |
| 3121 | 3119 |
| 3122 template <MarkCompactCollector::IterationMode mode, class Visitor> | 3120 template <MarkCompactCollector::IterationMode mode, class Visitor> |
| 3123 bool MarkCompactCollector::Evacuator::EvacuateSinglePage(MemoryChunk* p, | 3121 bool MarkCompactCollector::Evacuator::EvacuateSinglePage(Page* p, |
| 3124 Visitor* visitor) { | 3122 Visitor* visitor) { |
| 3125 bool success = false; | 3123 bool success = false; |
| 3126 DCHECK(p->IsEvacuationCandidate() || p->InNewSpace() || | 3124 DCHECK(p->IsEvacuationCandidate() || p->InNewSpace() || |
| 3127 p->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION)); | 3125 p->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION)); |
| 3128 int saved_live_bytes = p->LiveBytes(); | 3126 int saved_live_bytes = p->LiveBytes(); |
| 3129 double evacuation_time; | 3127 double evacuation_time; |
| 3130 { | 3128 { |
| 3131 AlwaysAllocateScope always_allocate(heap()->isolate()); | 3129 AlwaysAllocateScope always_allocate(heap()->isolate()); |
| 3132 TimedScope timed_scope(&evacuation_time); | 3130 TimedScope timed_scope(&evacuation_time); |
| 3133 success = collector_->VisitLiveObjects<Visitor>(p, visitor, mode); | 3131 success = collector_->VisitLiveObjects<Visitor>(p, visitor, mode); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3147 p->IsFlagSet(MemoryChunk::PAGE_NEW_OLD_PROMOTION), | 3145 p->IsFlagSet(MemoryChunk::PAGE_NEW_OLD_PROMOTION), |
| 3148 p->IsFlagSet(MemoryChunk::IS_EXECUTABLE), saved_live_bytes, | 3146 p->IsFlagSet(MemoryChunk::IS_EXECUTABLE), saved_live_bytes, |
| 3149 evacuation_time); | 3147 evacuation_time); |
| 3150 } | 3148 } |
| 3151 if (success) { | 3149 if (success) { |
| 3152 ReportCompactionProgress(evacuation_time, saved_live_bytes); | 3150 ReportCompactionProgress(evacuation_time, saved_live_bytes); |
| 3153 } | 3151 } |
| 3154 return success; | 3152 return success; |
| 3155 } | 3153 } |
| 3156 | 3154 |
| 3157 bool MarkCompactCollector::Evacuator::EvacuatePage(MemoryChunk* chunk) { | 3155 bool MarkCompactCollector::Evacuator::EvacuatePage(Page* page) { |
| 3158 bool result = false; | 3156 bool result = false; |
| 3159 DCHECK_EQ(chunk->concurrent_sweeping_state().Value(), | 3157 DCHECK(page->SweepingDone()); |
| 3160 NewSpacePage::kSweepingDone); | 3158 switch (ComputeEvacuationMode(page)) { |
| 3161 switch (ComputeEvacuationMode(chunk)) { | |
| 3162 case kObjectsNewToOld: | 3159 case kObjectsNewToOld: |
| 3163 result = EvacuateSinglePage<kClearMarkbits>(chunk, &new_space_visitor_); | 3160 result = EvacuateSinglePage<kClearMarkbits>(page, &new_space_visitor_); |
| 3164 DCHECK(result); | 3161 DCHECK(result); |
| 3165 USE(result); | 3162 USE(result); |
| 3166 break; | 3163 break; |
| 3167 case kPageNewToOld: | 3164 case kPageNewToOld: |
| 3168 result = EvacuateSinglePage<kKeepMarking>(chunk, &new_space_page_visitor); | 3165 result = EvacuateSinglePage<kKeepMarking>(page, &new_space_page_visitor); |
| 3169 DCHECK(result); | 3166 DCHECK(result); |
| 3170 USE(result); | 3167 USE(result); |
| 3171 break; | 3168 break; |
| 3172 case kObjectsOldToOld: | 3169 case kObjectsOldToOld: |
| 3173 result = EvacuateSinglePage<kClearMarkbits>(chunk, &old_space_visitor_); | 3170 result = EvacuateSinglePage<kClearMarkbits>(page, &old_space_visitor_); |
| 3174 if (!result) { | 3171 if (!result) { |
| 3175 // Aborted compaction page. We can record slots here to have them | 3172 // Aborted compaction page. We can record slots here to have them |
| 3176 // processed in parallel later on. | 3173 // processed in parallel later on. |
| 3177 EvacuateRecordOnlyVisitor record_visitor(chunk->owner()->identity()); | 3174 EvacuateRecordOnlyVisitor record_visitor(page->owner()->identity()); |
| 3178 result = EvacuateSinglePage<kKeepMarking>(chunk, &record_visitor); | 3175 result = EvacuateSinglePage<kKeepMarking>(page, &record_visitor); |
| 3179 DCHECK(result); | 3176 DCHECK(result); |
| 3180 USE(result); | 3177 USE(result); |
| 3181 // We need to return failure here to indicate that we want this page | 3178 // We need to return failure here to indicate that we want this page |
| 3182 // added to the sweeper. | 3179 // added to the sweeper. |
| 3183 return false; | 3180 return false; |
| 3184 } | 3181 } |
| 3185 break; | 3182 break; |
| 3186 default: | 3183 default: |
| 3187 UNREACHABLE(); | 3184 UNREACHABLE(); |
| 3188 } | 3185 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3237 | 3234 |
| 3238 class EvacuationJobTraits { | 3235 class EvacuationJobTraits { |
| 3239 public: | 3236 public: |
| 3240 typedef int* PerPageData; // Pointer to number of aborted pages. | 3237 typedef int* PerPageData; // Pointer to number of aborted pages. |
| 3241 typedef MarkCompactCollector::Evacuator* PerTaskData; | 3238 typedef MarkCompactCollector::Evacuator* PerTaskData; |
| 3242 | 3239 |
| 3243 static const bool NeedSequentialFinalization = true; | 3240 static const bool NeedSequentialFinalization = true; |
| 3244 | 3241 |
| 3245 static bool ProcessPageInParallel(Heap* heap, PerTaskData evacuator, | 3242 static bool ProcessPageInParallel(Heap* heap, PerTaskData evacuator, |
| 3246 MemoryChunk* chunk, PerPageData) { | 3243 MemoryChunk* chunk, PerPageData) { |
| 3247 return evacuator->EvacuatePage(chunk); | 3244 return evacuator->EvacuatePage(reinterpret_cast<Page*>(chunk)); |
| 3248 } | 3245 } |
| 3249 | 3246 |
| 3250 static void FinalizePageSequentially(Heap* heap, MemoryChunk* chunk, | 3247 static void FinalizePageSequentially(Heap* heap, MemoryChunk* chunk, |
| 3251 bool success, PerPageData data) { | 3248 bool success, PerPageData data) { |
| 3252 if (chunk->InNewSpace()) { | 3249 if (chunk->InNewSpace()) { |
| 3253 DCHECK(success); | 3250 DCHECK(success); |
| 3254 } else if (chunk->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION)) { | 3251 } else if (chunk->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION)) { |
| 3255 DCHECK(success); | 3252 DCHECK(success); |
| 3256 Page* p = static_cast<Page*>(chunk); | 3253 Page* p = static_cast<Page*>(chunk); |
| 3257 p->ClearFlag(Page::PAGE_NEW_OLD_PROMOTION); | 3254 p->ClearFlag(Page::PAGE_NEW_OLD_PROMOTION); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3281 void MarkCompactCollector::EvacuatePagesInParallel() { | 3278 void MarkCompactCollector::EvacuatePagesInParallel() { |
| 3282 PageParallelJob<EvacuationJobTraits> job( | 3279 PageParallelJob<EvacuationJobTraits> job( |
| 3283 heap_, heap_->isolate()->cancelable_task_manager()); | 3280 heap_, heap_->isolate()->cancelable_task_manager()); |
| 3284 | 3281 |
| 3285 int abandoned_pages = 0; | 3282 int abandoned_pages = 0; |
| 3286 intptr_t live_bytes = 0; | 3283 intptr_t live_bytes = 0; |
| 3287 for (Page* page : evacuation_candidates_) { | 3284 for (Page* page : evacuation_candidates_) { |
| 3288 live_bytes += page->LiveBytes(); | 3285 live_bytes += page->LiveBytes(); |
| 3289 job.AddPage(page, &abandoned_pages); | 3286 job.AddPage(page, &abandoned_pages); |
| 3290 } | 3287 } |
| 3288 |
| 3291 const Address age_mark = heap()->new_space()->age_mark(); | 3289 const Address age_mark = heap()->new_space()->age_mark(); |
| 3292 for (NewSpacePage* page : newspace_evacuation_candidates_) { | 3290 for (Page* page : newspace_evacuation_candidates_) { |
| 3293 live_bytes += page->LiveBytes(); | 3291 live_bytes += page->LiveBytes(); |
| 3294 if (!page->NeverEvacuate() && | 3292 if (!page->NeverEvacuate() && |
| 3295 (page->LiveBytes() > Evacuator::PageEvacuationThreshold()) && | 3293 (page->LiveBytes() > Evacuator::PageEvacuationThreshold()) && |
| 3296 page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK) && | 3294 page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK) && |
| 3297 !page->Contains(age_mark)) { | 3295 !page->Contains(age_mark)) { |
| 3298 EvacuateNewSpacePageVisitor::MoveToOldSpace(page, heap()->old_space()); | 3296 EvacuateNewSpacePageVisitor::MoveToOldSpace(page, heap()->old_space()); |
| 3299 } | 3297 } |
| 3300 job.AddPage(page, &abandoned_pages); | 3298 job.AddPage(page, &abandoned_pages); |
| 3301 } | 3299 } |
| 3302 DCHECK_GE(job.NumberOfPages(), 1); | 3300 DCHECK_GE(job.NumberOfPages(), 1); |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3667 } | 3665 } |
| 3668 }; | 3666 }; |
| 3669 | 3667 |
| 3670 void UpdateToSpacePointersInParallel(Heap* heap) { | 3668 void UpdateToSpacePointersInParallel(Heap* heap) { |
| 3671 PageParallelJob<ToSpacePointerUpdateJobTraits> job( | 3669 PageParallelJob<ToSpacePointerUpdateJobTraits> job( |
| 3672 heap, heap->isolate()->cancelable_task_manager()); | 3670 heap, heap->isolate()->cancelable_task_manager()); |
| 3673 Address space_start = heap->new_space()->bottom(); | 3671 Address space_start = heap->new_space()->bottom(); |
| 3674 Address space_end = heap->new_space()->top(); | 3672 Address space_end = heap->new_space()->top(); |
| 3675 NewSpacePageIterator it(space_start, space_end); | 3673 NewSpacePageIterator it(space_start, space_end); |
| 3676 while (it.has_next()) { | 3674 while (it.has_next()) { |
| 3677 NewSpacePage* page = it.next(); | 3675 Page* page = it.next(); |
| 3678 Address start = | 3676 Address start = |
| 3679 page->Contains(space_start) ? space_start : page->area_start(); | 3677 page->Contains(space_start) ? space_start : page->area_start(); |
| 3680 Address end = page->Contains(space_end) ? space_end : page->area_end(); | 3678 Address end = page->Contains(space_end) ? space_end : page->area_end(); |
| 3681 job.AddPage(page, std::make_pair(start, end)); | 3679 job.AddPage(page, std::make_pair(start, end)); |
| 3682 } | 3680 } |
| 3683 PointersUpdatingVisitor visitor(heap); | 3681 PointersUpdatingVisitor visitor(heap); |
| 3684 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; | 3682 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; |
| 3685 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); | 3683 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); |
| 3686 } | 3684 } |
| 3687 | 3685 |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3948 MarkBit mark_bit = Marking::MarkBitFrom(host); | 3946 MarkBit mark_bit = Marking::MarkBitFrom(host); |
| 3949 if (Marking::IsBlack(mark_bit)) { | 3947 if (Marking::IsBlack(mark_bit)) { |
| 3950 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 3948 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
| 3951 RecordRelocSlot(host, &rinfo, target); | 3949 RecordRelocSlot(host, &rinfo, target); |
| 3952 } | 3950 } |
| 3953 } | 3951 } |
| 3954 } | 3952 } |
| 3955 | 3953 |
| 3956 } // namespace internal | 3954 } // namespace internal |
| 3957 } // namespace v8 | 3955 } // namespace v8 |
| OLD | NEW |