Chromium Code Reviews| 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 3122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3133 &local_pretenuring_feedback_), | 3133 &local_pretenuring_feedback_), |
| 3134 new_to_old_page_visitor_(heap_, record_visitor, | 3134 new_to_old_page_visitor_(heap_, record_visitor, |
| 3135 &local_pretenuring_feedback_), | 3135 &local_pretenuring_feedback_), |
| 3136 | 3136 |
| 3137 old_space_visitor_(heap_, &compaction_spaces_, record_visitor), | 3137 old_space_visitor_(heap_, &compaction_spaces_, record_visitor), |
| 3138 duration_(0.0), | 3138 duration_(0.0), |
| 3139 bytes_compacted_(0) {} | 3139 bytes_compacted_(0) {} |
| 3140 | 3140 |
| 3141 virtual ~Evacuator() {} | 3141 virtual ~Evacuator() {} |
| 3142 | 3142 |
| 3143 virtual bool EvacuatePage(Page* page, const MarkingState& state) = 0; | 3143 bool EvacuatePage(Page* page, const MarkingState& state); |
| 3144 | 3144 |
| 3145 // Merge back locally cached info sequentially. Note that this method needs | 3145 // Merge back locally cached info sequentially. Note that this method needs |
| 3146 // to be called from the main thread. | 3146 // to be called from the main thread. |
| 3147 inline void Finalize(); | 3147 inline void Finalize(); |
| 3148 | 3148 |
| 3149 CompactionSpaceCollection* compaction_spaces() { return &compaction_spaces_; } | 3149 CompactionSpaceCollection* compaction_spaces() { return &compaction_spaces_; } |
| 3150 AllocationInfo CloseNewSpaceLAB() { return new_space_visitor_.CloseLAB(); } | 3150 AllocationInfo CloseNewSpaceLAB() { return new_space_visitor_.CloseLAB(); } |
| 3151 | 3151 |
| 3152 protected: | 3152 protected: |
| 3153 static const int kInitialLocalPretenuringFeedbackCapacity = 256; | 3153 static const int kInitialLocalPretenuringFeedbackCapacity = 256; |
| 3154 | 3154 |
| 3155 virtual bool EvacuatePageImpl(Page* page, const MarkingState& state) = 0; | |
| 3156 | |
| 3155 inline Heap* heap() { return heap_; } | 3157 inline Heap* heap() { return heap_; } |
| 3156 | 3158 |
| 3157 void ReportCompactionProgress(double duration, intptr_t bytes_compacted) { | 3159 void ReportCompactionProgress(double duration, intptr_t bytes_compacted) { |
| 3158 duration_ += duration; | 3160 duration_ += duration; |
| 3159 bytes_compacted_ += bytes_compacted; | 3161 bytes_compacted_ += bytes_compacted; |
| 3160 } | 3162 } |
| 3161 | 3163 |
| 3162 Heap* heap_; | 3164 Heap* heap_; |
| 3163 | 3165 |
| 3164 // Locally cached collector data. | 3166 // Locally cached collector data. |
| 3165 CompactionSpaceCollection compaction_spaces_; | 3167 CompactionSpaceCollection compaction_spaces_; |
| 3166 base::HashMap local_pretenuring_feedback_; | 3168 base::HashMap local_pretenuring_feedback_; |
| 3167 | 3169 |
| 3168 // Visitors for the corresponding spaces. | 3170 // Visitors for the corresponding spaces. |
| 3169 EvacuateNewSpaceVisitor new_space_visitor_; | 3171 EvacuateNewSpaceVisitor new_space_visitor_; |
| 3170 EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_NEW> | 3172 EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_NEW> |
| 3171 new_to_new_page_visitor_; | 3173 new_to_new_page_visitor_; |
| 3172 EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_OLD> | 3174 EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_OLD> |
| 3173 new_to_old_page_visitor_; | 3175 new_to_old_page_visitor_; |
| 3174 EvacuateOldSpaceVisitor old_space_visitor_; | 3176 EvacuateOldSpaceVisitor old_space_visitor_; |
| 3175 | 3177 |
| 3176 // Book keeping info. | 3178 // Book keeping info. |
| 3177 double duration_; | 3179 double duration_; |
| 3178 intptr_t bytes_compacted_; | 3180 intptr_t bytes_compacted_; |
| 3179 }; | 3181 }; |
| 3180 | 3182 |
| 3183 bool Evacuator::EvacuatePage(Page* page, const MarkingState& state) { | |
| 3184 bool success = false; | |
| 3185 DCHECK(page->SweepingDone()); | |
| 3186 intptr_t saved_live_bytes = state.live_bytes(); | |
| 3187 double evacuation_time = 0.0; | |
| 3188 { | |
| 3189 AlwaysAllocateScope always_allocate(heap()->isolate()); | |
| 3190 TimedScope timed_scope(&evacuation_time); | |
| 3191 success = EvacuatePageImpl(page, state); | |
| 3192 } | |
| 3193 ReportCompactionProgress(evacuation_time, saved_live_bytes); | |
| 3194 if (FLAG_trace_evacuation) { | |
| 3195 PrintIsolate( | |
| 3196 heap()->isolate(), | |
| 3197 "evacuation[%p]: page=%p new_space=%d " | |
| 3198 "page_evacuation=%d executable=%d contains_age_mark=%d " | |
| 3199 "live_bytes=%" V8PRIdPTR " time=%f page_promotion_qualifies=%d\n", | |
| 3200 static_cast<void*>(this), static_cast<void*>(page), page->InNewSpace(), | |
| 3201 page->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION) || | |
| 3202 page->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION), | |
| 3203 page->IsFlagSet(MemoryChunk::IS_EXECUTABLE), | |
| 3204 page->Contains(heap()->new_space()->age_mark()), saved_live_bytes, | |
| 3205 evacuation_time, | |
| 3206 saved_live_bytes > Evacuator::PageEvacuationThreshold()); | |
| 3207 } | |
| 3208 return success; | |
| 3209 } | |
| 3210 | |
| 3181 void Evacuator::Finalize() { | 3211 void Evacuator::Finalize() { |
| 3182 heap()->old_space()->MergeCompactionSpace(compaction_spaces_.Get(OLD_SPACE)); | 3212 heap()->old_space()->MergeCompactionSpace(compaction_spaces_.Get(OLD_SPACE)); |
| 3183 heap()->code_space()->MergeCompactionSpace( | 3213 heap()->code_space()->MergeCompactionSpace( |
| 3184 compaction_spaces_.Get(CODE_SPACE)); | 3214 compaction_spaces_.Get(CODE_SPACE)); |
| 3185 heap()->tracer()->AddCompactionEvent(duration_, bytes_compacted_); | 3215 heap()->tracer()->AddCompactionEvent(duration_, bytes_compacted_); |
| 3186 heap()->IncrementPromotedObjectsSize(new_space_visitor_.promoted_size() + | 3216 heap()->IncrementPromotedObjectsSize(new_space_visitor_.promoted_size() + |
| 3187 new_to_old_page_visitor_.moved_bytes()); | 3217 new_to_old_page_visitor_.moved_bytes()); |
| 3188 heap()->IncrementSemiSpaceCopiedObjectSize( | 3218 heap()->IncrementSemiSpaceCopiedObjectSize( |
| 3189 new_space_visitor_.semispace_copied_size() + | 3219 new_space_visitor_.semispace_copied_size() + |
| 3190 new_to_new_page_visitor_.moved_bytes()); | 3220 new_to_new_page_visitor_.moved_bytes()); |
| 3191 heap()->IncrementYoungSurvivorsCounter( | 3221 heap()->IncrementYoungSurvivorsCounter( |
| 3192 new_space_visitor_.promoted_size() + | 3222 new_space_visitor_.promoted_size() + |
| 3193 new_space_visitor_.semispace_copied_size() + | 3223 new_space_visitor_.semispace_copied_size() + |
| 3194 new_to_old_page_visitor_.moved_bytes() + | 3224 new_to_old_page_visitor_.moved_bytes() + |
| 3195 new_to_new_page_visitor_.moved_bytes()); | 3225 new_to_new_page_visitor_.moved_bytes()); |
| 3196 heap()->MergeAllocationSitePretenuringFeedback(local_pretenuring_feedback_); | 3226 heap()->MergeAllocationSitePretenuringFeedback(local_pretenuring_feedback_); |
| 3197 } | 3227 } |
| 3198 | 3228 |
| 3199 class FullEvacuator : public Evacuator { | 3229 class FullEvacuator : public Evacuator { |
| 3200 public: | 3230 public: |
| 3201 FullEvacuator(Heap* heap, RecordMigratedSlotVisitor* record_visitor) | 3231 FullEvacuator(Heap* heap, RecordMigratedSlotVisitor* record_visitor) |
| 3202 : Evacuator(heap, record_visitor) {} | 3232 : Evacuator(heap, record_visitor) {} |
| 3203 | 3233 |
| 3204 bool EvacuatePage(Page* page, const MarkingState& state) override; | 3234 protected: |
| 3235 bool EvacuatePageImpl(Page* page, const MarkingState& state) override; | |
|
Hannes Payer (out of office)
2017/04/21 13:09:15
I do not like the name. I do not think this is how
Michael Lippautz
2017/04/21 15:02:25
In other parts of V8 we use *Impl suffixes. Change
| |
| 3205 }; | 3236 }; |
| 3206 | 3237 |
| 3207 bool FullEvacuator::EvacuatePage(Page* page, const MarkingState& state) { | 3238 bool FullEvacuator::EvacuatePageImpl(Page* page, const MarkingState& state) { |
| 3208 bool success = false; | 3239 bool success = false; |
| 3209 DCHECK(page->SweepingDone()); | 3240 LiveObjectVisitor object_visitor; |
| 3210 intptr_t saved_live_bytes = state.live_bytes(); | 3241 switch (ComputeEvacuationMode(page)) { |
| 3211 double evacuation_time = 0.0; | 3242 case kObjectsNewToOld: |
| 3212 { | 3243 success = object_visitor.VisitBlackObjects( |
| 3213 AlwaysAllocateScope always_allocate(heap()->isolate()); | 3244 page, state, &new_space_visitor_, LiveObjectVisitor::kClearMarkbits); |
| 3214 TimedScope timed_scope(&evacuation_time); | 3245 DCHECK(success); |
| 3215 LiveObjectVisitor object_visitor; | 3246 ArrayBufferTracker::ProcessBuffers( |
| 3216 switch (ComputeEvacuationMode(page)) { | 3247 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); |
| 3217 case kObjectsNewToOld: | 3248 break; |
| 3218 success = | 3249 case kPageNewToOld: |
| 3219 object_visitor.VisitBlackObjects(page, state, &new_space_visitor_, | 3250 success = object_visitor.VisitBlackObjects( |
| 3220 LiveObjectVisitor::kClearMarkbits); | 3251 page, state, &new_to_old_page_visitor_, |
| 3252 LiveObjectVisitor::kKeepMarking); | |
| 3253 DCHECK(success); | |
| 3254 new_to_old_page_visitor_.account_moved_bytes( | |
| 3255 MarkingState::Internal(page).live_bytes()); | |
| 3256 // ArrayBufferTracker will be updated during sweeping. | |
| 3257 break; | |
| 3258 case kPageNewToNew: | |
| 3259 success = object_visitor.VisitBlackObjects( | |
| 3260 page, state, &new_to_new_page_visitor_, | |
| 3261 LiveObjectVisitor::kKeepMarking); | |
| 3262 DCHECK(success); | |
| 3263 new_to_new_page_visitor_.account_moved_bytes( | |
| 3264 MarkingState::Internal(page).live_bytes()); | |
| 3265 // ArrayBufferTracker will be updated during sweeping. | |
| 3266 break; | |
| 3267 case kObjectsOldToOld: | |
| 3268 success = object_visitor.VisitBlackObjects( | |
| 3269 page, state, &old_space_visitor_, LiveObjectVisitor::kClearMarkbits); | |
| 3270 if (!success) { | |
| 3271 // Aborted compaction page. We have to record slots here, since we | |
| 3272 // might not have recorded them in first place. | |
| 3273 // Note: We mark the page as aborted here to be able to record slots | |
| 3274 // for code objects in |RecordMigratedSlotVisitor|. | |
| 3275 page->SetFlag(Page::COMPACTION_WAS_ABORTED); | |
| 3276 EvacuateRecordOnlyVisitor record_visitor(heap()); | |
| 3277 success = object_visitor.VisitBlackObjects( | |
| 3278 page, state, &record_visitor, LiveObjectVisitor::kKeepMarking); | |
| 3279 ArrayBufferTracker::ProcessBuffers( | |
| 3280 page, ArrayBufferTracker::kUpdateForwardedKeepOthers); | |
| 3221 DCHECK(success); | 3281 DCHECK(success); |
| 3282 // We need to return failure here to indicate that we want this page | |
| 3283 // added to the sweeper. | |
| 3284 success = false; | |
| 3285 } else { | |
| 3222 ArrayBufferTracker::ProcessBuffers( | 3286 ArrayBufferTracker::ProcessBuffers( |
| 3223 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); | 3287 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); |
| 3224 break; | 3288 } |
| 3225 case kPageNewToOld: | 3289 break; |
| 3226 success = object_visitor.VisitBlackObjects( | |
| 3227 page, state, &new_to_old_page_visitor_, | |
| 3228 LiveObjectVisitor::kKeepMarking); | |
| 3229 DCHECK(success); | |
| 3230 new_to_old_page_visitor_.account_moved_bytes( | |
| 3231 MarkingState::Internal(page).live_bytes()); | |
| 3232 // ArrayBufferTracker will be updated during sweeping. | |
| 3233 break; | |
| 3234 case kPageNewToNew: | |
| 3235 success = object_visitor.VisitBlackObjects( | |
| 3236 page, state, &new_to_new_page_visitor_, | |
| 3237 LiveObjectVisitor::kKeepMarking); | |
| 3238 DCHECK(success); | |
| 3239 new_to_new_page_visitor_.account_moved_bytes( | |
| 3240 MarkingState::Internal(page).live_bytes()); | |
| 3241 // ArrayBufferTracker will be updated during sweeping. | |
| 3242 break; | |
| 3243 case kObjectsOldToOld: | |
| 3244 success = | |
| 3245 object_visitor.VisitBlackObjects(page, state, &old_space_visitor_, | |
| 3246 LiveObjectVisitor::kClearMarkbits); | |
| 3247 if (!success) { | |
| 3248 // Aborted compaction page. We have to record slots here, since we | |
| 3249 // might not have recorded them in first place. | |
| 3250 // Note: We mark the page as aborted here to be able to record slots | |
| 3251 // for code objects in |RecordMigratedSlotVisitor|. | |
| 3252 page->SetFlag(Page::COMPACTION_WAS_ABORTED); | |
| 3253 EvacuateRecordOnlyVisitor record_visitor(heap()); | |
| 3254 success = object_visitor.VisitBlackObjects( | |
| 3255 page, state, &record_visitor, LiveObjectVisitor::kKeepMarking); | |
| 3256 ArrayBufferTracker::ProcessBuffers( | |
| 3257 page, ArrayBufferTracker::kUpdateForwardedKeepOthers); | |
| 3258 DCHECK(success); | |
| 3259 // We need to return failure here to indicate that we want this page | |
| 3260 // added to the sweeper. | |
| 3261 success = false; | |
| 3262 } else { | |
| 3263 ArrayBufferTracker::ProcessBuffers( | |
| 3264 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); | |
| 3265 } | |
| 3266 break; | |
| 3267 } | |
| 3268 } | |
| 3269 ReportCompactionProgress(evacuation_time, saved_live_bytes); | |
| 3270 if (FLAG_trace_evacuation) { | |
| 3271 PrintIsolate(heap()->isolate(), | |
| 3272 "evacuation[%p]: page=%p new_space=%d " | |
| 3273 "page_evacuation=%d executable=%d contains_age_mark=%d " | |
| 3274 "live_bytes=%" V8PRIdPTR " time=%f\n", | |
| 3275 static_cast<void*>(this), static_cast<void*>(page), | |
| 3276 page->InNewSpace(), | |
| 3277 page->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION) || | |
| 3278 page->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION), | |
| 3279 page->IsFlagSet(MemoryChunk::IS_EXECUTABLE), | |
| 3280 page->Contains(heap()->new_space()->age_mark()), | |
| 3281 saved_live_bytes, evacuation_time); | |
| 3282 } | 3290 } |
| 3283 return success; | 3291 return success; |
| 3284 } | 3292 } |
| 3285 | 3293 |
| 3286 int MarkCompactCollector::NumberOfParallelCompactionTasks(int pages, | |
| 3287 intptr_t live_bytes) { | |
| 3288 if (!FLAG_parallel_compaction) return 1; | |
| 3289 // Compute the number of needed tasks based on a target compaction time, the | |
| 3290 // profiled compaction speed and marked live memory. | |
| 3291 // | |
| 3292 // The number of parallel compaction tasks is limited by: | |
| 3293 // - #evacuation pages | |
| 3294 // - #cores | |
| 3295 const double kTargetCompactionTimeInMs = .5; | |
| 3296 | |
| 3297 double compaction_speed = | |
| 3298 heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); | |
| 3299 | |
| 3300 const int available_cores = Max( | |
| 3301 1, static_cast<int>( | |
| 3302 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())); | |
| 3303 int tasks; | |
| 3304 if (compaction_speed > 0) { | |
| 3305 tasks = 1 + static_cast<int>(live_bytes / compaction_speed / | |
| 3306 kTargetCompactionTimeInMs); | |
| 3307 } else { | |
| 3308 tasks = pages; | |
| 3309 } | |
| 3310 const int tasks_capped_pages = Min(pages, tasks); | |
| 3311 return Min(available_cores, tasks_capped_pages); | |
| 3312 } | |
| 3313 | |
| 3314 class EvacuationJobTraits { | 3294 class EvacuationJobTraits { |
| 3315 public: | 3295 public: |
| 3316 typedef int* PerPageData; // Pointer to number of aborted pages. | 3296 typedef int* PerPageData; // Pointer to number of aborted pages. |
| 3317 typedef Evacuator* PerTaskData; | 3297 typedef Evacuator* PerTaskData; |
| 3318 | 3298 |
| 3319 static const bool NeedSequentialFinalization = true; | 3299 static const bool NeedSequentialFinalization = true; |
| 3320 | 3300 |
| 3321 static bool ProcessPageInParallel(Heap* heap, PerTaskData evacuator, | 3301 static bool ProcessPageInParallel(Heap* heap, PerTaskData evacuator, |
| 3322 MemoryChunk* chunk, PerPageData) { | 3302 MemoryChunk* chunk, PerPageData) { |
| 3323 return evacuator->EvacuatePage(reinterpret_cast<Page*>(chunk), | 3303 return evacuator->EvacuatePage(reinterpret_cast<Page*>(chunk), |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 3349 // sweeper, which will happen after updating pointers. | 3329 // sweeper, which will happen after updating pointers. |
| 3350 *data += 1; | 3330 *data += 1; |
| 3351 } | 3331 } |
| 3352 break; | 3332 break; |
| 3353 default: | 3333 default: |
| 3354 UNREACHABLE(); | 3334 UNREACHABLE(); |
| 3355 } | 3335 } |
| 3356 } | 3336 } |
| 3357 }; | 3337 }; |
| 3358 | 3338 |
| 3339 namespace { | |
|
Hannes Payer (out of office)
2017/04/21 13:09:15
Why are you moving this into a separate namespace?
Michael Lippautz
2017/04/21 15:02:25
Will be used by the minor MC. Let's see if we add
| |
| 3340 | |
| 3341 // The number of parallel compaction tasks, including the main thread. | |
| 3342 int NumberOfParallelCompactionTasks(Heap* heap, int pages, | |
| 3343 intptr_t live_bytes) { | |
| 3344 if (!FLAG_parallel_compaction) return 1; | |
| 3345 // Compute the number of needed tasks based on a target compaction time, the | |
| 3346 // profiled compaction speed and marked live memory. | |
| 3347 // | |
| 3348 // The number of parallel compaction tasks is limited by: | |
| 3349 // - #evacuation pages | |
| 3350 // - #cores | |
| 3351 const double kTargetCompactionTimeInMs = .5; | |
| 3352 | |
| 3353 double compaction_speed = | |
| 3354 heap->tracer()->CompactionSpeedInBytesPerMillisecond(); | |
| 3355 | |
| 3356 const int available_cores = Max( | |
| 3357 1, static_cast<int>( | |
| 3358 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())); | |
| 3359 int tasks; | |
| 3360 if (compaction_speed > 0) { | |
| 3361 tasks = 1 + static_cast<int>(live_bytes / compaction_speed / | |
| 3362 kTargetCompactionTimeInMs); | |
| 3363 } else { | |
| 3364 tasks = pages; | |
| 3365 } | |
| 3366 const int tasks_capped_pages = Min(pages, tasks); | |
| 3367 return Min(available_cores, tasks_capped_pages); | |
| 3368 } | |
| 3369 | |
| 3370 } // namespace | |
| 3371 | |
| 3359 void MarkCompactCollector::EvacuatePagesInParallel() { | 3372 void MarkCompactCollector::EvacuatePagesInParallel() { |
| 3360 PageParallelJob<EvacuationJobTraits> job( | 3373 PageParallelJob<EvacuationJobTraits> job( |
| 3361 heap_, heap_->isolate()->cancelable_task_manager(), | 3374 heap_, heap_->isolate()->cancelable_task_manager(), |
| 3362 &page_parallel_job_semaphore_); | 3375 &page_parallel_job_semaphore_); |
| 3363 | 3376 |
| 3364 int abandoned_pages = 0; | 3377 int abandoned_pages = 0; |
| 3365 intptr_t live_bytes = 0; | 3378 intptr_t live_bytes = 0; |
| 3366 for (Page* page : old_space_evacuation_pages_) { | 3379 for (Page* page : old_space_evacuation_pages_) { |
| 3367 live_bytes += MarkingState::Internal(page).live_bytes(); | 3380 live_bytes += MarkingState::Internal(page).live_bytes(); |
| 3368 job.AddPage(page, &abandoned_pages); | 3381 job.AddPage(page, &abandoned_pages); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 3388 } | 3401 } |
| 3389 DCHECK_GE(job.NumberOfPages(), 1); | 3402 DCHECK_GE(job.NumberOfPages(), 1); |
| 3390 | 3403 |
| 3391 // Used for trace summary. | 3404 // Used for trace summary. |
| 3392 double compaction_speed = 0; | 3405 double compaction_speed = 0; |
| 3393 if (FLAG_trace_evacuation) { | 3406 if (FLAG_trace_evacuation) { |
| 3394 compaction_speed = heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); | 3407 compaction_speed = heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); |
| 3395 } | 3408 } |
| 3396 | 3409 |
| 3397 const int wanted_num_tasks = | 3410 const int wanted_num_tasks = |
| 3398 NumberOfParallelCompactionTasks(job.NumberOfPages(), live_bytes); | 3411 NumberOfParallelCompactionTasks(heap(), job.NumberOfPages(), live_bytes); |
| 3399 FullEvacuator** evacuators = new FullEvacuator*[wanted_num_tasks]; | 3412 FullEvacuator** evacuators = new FullEvacuator*[wanted_num_tasks]; |
| 3400 RecordMigratedSlotVisitor record_visitor(this); | 3413 RecordMigratedSlotVisitor record_visitor(this); |
| 3401 for (int i = 0; i < wanted_num_tasks; i++) { | 3414 for (int i = 0; i < wanted_num_tasks; i++) { |
| 3402 evacuators[i] = new FullEvacuator(heap(), &record_visitor); | 3415 evacuators[i] = new FullEvacuator(heap(), &record_visitor); |
| 3403 } | 3416 } |
| 3404 job.Run(wanted_num_tasks, [evacuators](int i) { return evacuators[i]; }); | 3417 job.Run(wanted_num_tasks, [evacuators](int i) { return evacuators[i]; }); |
| 3405 const Address top = heap()->new_space()->top(); | 3418 const Address top = heap()->new_space()->top(); |
| 3406 for (int i = 0; i < wanted_num_tasks; i++) { | 3419 for (int i = 0; i < wanted_num_tasks; i++) { |
| 3407 evacuators[i]->Finalize(); | 3420 evacuators[i]->Finalize(); |
| 3408 // Try to find the last LAB that was used for new space allocation in | 3421 // Try to find the last LAB that was used for new space allocation in |
| (...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4169 // The target is always in old space, we don't have to record the slot in | 4182 // The target is always in old space, we don't have to record the slot in |
| 4170 // the old-to-new remembered set. | 4183 // the old-to-new remembered set. |
| 4171 DCHECK(!heap()->InNewSpace(target)); | 4184 DCHECK(!heap()->InNewSpace(target)); |
| 4172 RecordRelocSlot(host, &rinfo, target); | 4185 RecordRelocSlot(host, &rinfo, target); |
| 4173 } | 4186 } |
| 4174 } | 4187 } |
| 4175 } | 4188 } |
| 4176 | 4189 |
| 4177 } // namespace internal | 4190 } // namespace internal |
| 4178 } // namespace v8 | 4191 } // namespace v8 |
| OLD | NEW |