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 |