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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 VerifyEvacuation(heap_->old_space()); | 276 VerifyEvacuation(heap_->old_space()); |
277 VerifyEvacuation(heap_->code_space()); | 277 VerifyEvacuation(heap_->code_space()); |
278 VerifyEvacuation(heap_->map_space()); | 278 VerifyEvacuation(heap_->map_space()); |
279 } | 279 } |
280 }; | 280 }; |
281 | 281 |
282 } // namespace | 282 } // namespace |
283 #endif // VERIFY_HEAP | 283 #endif // VERIFY_HEAP |
284 | 284 |
285 // ============================================================================= | 285 // ============================================================================= |
286 // MarkCompactCollector | 286 // MarkCompactCollectorBase, MinorMarkCompactCollector, MarkCompactCollector |
287 // ============================================================================= | 287 // ============================================================================= |
288 | 288 |
| 289 int MarkCompactCollectorBase::NumberOfParallelCompactionTasks( |
| 290 int pages, intptr_t live_bytes) { |
| 291 if (!FLAG_parallel_compaction) return 1; |
| 292 // Compute the number of needed tasks based on a target compaction time, the |
| 293 // profiled compaction speed and marked live memory. |
| 294 // |
| 295 // The number of parallel compaction tasks is limited by: |
| 296 // - #evacuation pages |
| 297 // - #cores |
| 298 const double kTargetCompactionTimeInMs = .5; |
| 299 |
| 300 double compaction_speed = |
| 301 heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); |
| 302 |
| 303 const int available_cores = Max( |
| 304 1, static_cast<int>( |
| 305 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())); |
| 306 int tasks; |
| 307 if (compaction_speed > 0) { |
| 308 tasks = 1 + static_cast<int>(live_bytes / compaction_speed / |
| 309 kTargetCompactionTimeInMs); |
| 310 } else { |
| 311 tasks = pages; |
| 312 } |
| 313 const int tasks_capped_pages = Min(pages, tasks); |
| 314 return Min(available_cores, tasks_capped_pages); |
| 315 } |
| 316 |
289 MarkCompactCollector::MarkCompactCollector(Heap* heap) | 317 MarkCompactCollector::MarkCompactCollector(Heap* heap) |
290 : // NOLINT | 318 : MarkCompactCollectorBase(heap), |
291 heap_(heap), | |
292 page_parallel_job_semaphore_(0), | 319 page_parallel_job_semaphore_(0), |
293 #ifdef DEBUG | 320 #ifdef DEBUG |
294 state_(IDLE), | 321 state_(IDLE), |
295 #endif | 322 #endif |
296 was_marked_incrementally_(false), | 323 was_marked_incrementally_(false), |
297 evacuation_(false), | 324 evacuation_(false), |
298 compacting_(false), | 325 compacting_(false), |
299 black_allocation_(false), | 326 black_allocation_(false), |
300 have_code_to_deoptimize_(false), | 327 have_code_to_deoptimize_(false), |
301 marking_deque_(heap), | 328 marking_deque_(heap), |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 #endif | 636 #endif |
610 | 637 |
611 if (heap()->memory_allocator()->unmapper()->has_delayed_chunks()) | 638 if (heap()->memory_allocator()->unmapper()->has_delayed_chunks()) |
612 heap()->memory_allocator()->unmapper()->FreeQueuedChunks(); | 639 heap()->memory_allocator()->unmapper()->FreeQueuedChunks(); |
613 } | 640 } |
614 | 641 |
615 bool MarkCompactCollector::Sweeper::AreSweeperTasksRunning() { | 642 bool MarkCompactCollector::Sweeper::AreSweeperTasksRunning() { |
616 return num_sweeping_tasks_.Value() != 0; | 643 return num_sweeping_tasks_.Value() != 0; |
617 } | 644 } |
618 | 645 |
619 const char* AllocationSpaceName(AllocationSpace space) { | |
620 switch (space) { | |
621 case NEW_SPACE: | |
622 return "NEW_SPACE"; | |
623 case OLD_SPACE: | |
624 return "OLD_SPACE"; | |
625 case CODE_SPACE: | |
626 return "CODE_SPACE"; | |
627 case MAP_SPACE: | |
628 return "MAP_SPACE"; | |
629 case LO_SPACE: | |
630 return "LO_SPACE"; | |
631 default: | |
632 UNREACHABLE(); | |
633 } | |
634 | |
635 return NULL; | |
636 } | |
637 | |
638 void MarkCompactCollector::ComputeEvacuationHeuristics( | 646 void MarkCompactCollector::ComputeEvacuationHeuristics( |
639 size_t area_size, int* target_fragmentation_percent, | 647 size_t area_size, int* target_fragmentation_percent, |
640 size_t* max_evacuated_bytes) { | 648 size_t* max_evacuated_bytes) { |
641 // For memory reducing and optimize for memory mode we directly define both | 649 // For memory reducing and optimize for memory mode we directly define both |
642 // constants. | 650 // constants. |
643 const int kTargetFragmentationPercentForReduceMemory = 20; | 651 const int kTargetFragmentationPercentForReduceMemory = 20; |
644 const size_t kMaxEvacuatedBytesForReduceMemory = 12 * MB; | 652 const size_t kMaxEvacuatedBytesForReduceMemory = 12 * MB; |
645 const int kTargetFragmentationPercentForOptimizeMemory = 20; | 653 const int kTargetFragmentationPercentForOptimizeMemory = 20; |
646 const size_t kMaxEvacuatedBytesForOptimizeMemory = 6 * MB; | 654 const size_t kMaxEvacuatedBytesForOptimizeMemory = 6 * MB; |
647 | 655 |
(...skipping 2485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3133 &local_pretenuring_feedback_), | 3141 &local_pretenuring_feedback_), |
3134 new_to_old_page_visitor_(heap_, record_visitor, | 3142 new_to_old_page_visitor_(heap_, record_visitor, |
3135 &local_pretenuring_feedback_), | 3143 &local_pretenuring_feedback_), |
3136 | 3144 |
3137 old_space_visitor_(heap_, &compaction_spaces_, record_visitor), | 3145 old_space_visitor_(heap_, &compaction_spaces_, record_visitor), |
3138 duration_(0.0), | 3146 duration_(0.0), |
3139 bytes_compacted_(0) {} | 3147 bytes_compacted_(0) {} |
3140 | 3148 |
3141 virtual ~Evacuator() {} | 3149 virtual ~Evacuator() {} |
3142 | 3150 |
3143 virtual bool EvacuatePage(Page* page, const MarkingState& state) = 0; | 3151 bool EvacuatePage(Page* page, const MarkingState& state); |
3144 | 3152 |
3145 // Merge back locally cached info sequentially. Note that this method needs | 3153 // Merge back locally cached info sequentially. Note that this method needs |
3146 // to be called from the main thread. | 3154 // to be called from the main thread. |
3147 inline void Finalize(); | 3155 inline void Finalize(); |
3148 | 3156 |
3149 CompactionSpaceCollection* compaction_spaces() { return &compaction_spaces_; } | 3157 CompactionSpaceCollection* compaction_spaces() { return &compaction_spaces_; } |
3150 AllocationInfo CloseNewSpaceLAB() { return new_space_visitor_.CloseLAB(); } | 3158 AllocationInfo CloseNewSpaceLAB() { return new_space_visitor_.CloseLAB(); } |
3151 | 3159 |
3152 protected: | 3160 protected: |
3153 static const int kInitialLocalPretenuringFeedbackCapacity = 256; | 3161 static const int kInitialLocalPretenuringFeedbackCapacity = 256; |
3154 | 3162 |
| 3163 virtual bool RawEvacuatePage(Page* page, const MarkingState& state) = 0; |
| 3164 |
3155 inline Heap* heap() { return heap_; } | 3165 inline Heap* heap() { return heap_; } |
3156 | 3166 |
3157 void ReportCompactionProgress(double duration, intptr_t bytes_compacted) { | 3167 void ReportCompactionProgress(double duration, intptr_t bytes_compacted) { |
3158 duration_ += duration; | 3168 duration_ += duration; |
3159 bytes_compacted_ += bytes_compacted; | 3169 bytes_compacted_ += bytes_compacted; |
3160 } | 3170 } |
3161 | 3171 |
3162 Heap* heap_; | 3172 Heap* heap_; |
3163 | 3173 |
3164 // Locally cached collector data. | 3174 // Locally cached collector data. |
3165 CompactionSpaceCollection compaction_spaces_; | 3175 CompactionSpaceCollection compaction_spaces_; |
3166 base::HashMap local_pretenuring_feedback_; | 3176 base::HashMap local_pretenuring_feedback_; |
3167 | 3177 |
3168 // Visitors for the corresponding spaces. | 3178 // Visitors for the corresponding spaces. |
3169 EvacuateNewSpaceVisitor new_space_visitor_; | 3179 EvacuateNewSpaceVisitor new_space_visitor_; |
3170 EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_NEW> | 3180 EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_NEW> |
3171 new_to_new_page_visitor_; | 3181 new_to_new_page_visitor_; |
3172 EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_OLD> | 3182 EvacuateNewSpacePageVisitor<PageEvacuationMode::NEW_TO_OLD> |
3173 new_to_old_page_visitor_; | 3183 new_to_old_page_visitor_; |
3174 EvacuateOldSpaceVisitor old_space_visitor_; | 3184 EvacuateOldSpaceVisitor old_space_visitor_; |
3175 | 3185 |
3176 // Book keeping info. | 3186 // Book keeping info. |
3177 double duration_; | 3187 double duration_; |
3178 intptr_t bytes_compacted_; | 3188 intptr_t bytes_compacted_; |
3179 }; | 3189 }; |
3180 | 3190 |
| 3191 bool Evacuator::EvacuatePage(Page* page, const MarkingState& state) { |
| 3192 bool success = false; |
| 3193 DCHECK(page->SweepingDone()); |
| 3194 intptr_t saved_live_bytes = state.live_bytes(); |
| 3195 double evacuation_time = 0.0; |
| 3196 { |
| 3197 AlwaysAllocateScope always_allocate(heap()->isolate()); |
| 3198 TimedScope timed_scope(&evacuation_time); |
| 3199 success = RawEvacuatePage(page, state); |
| 3200 } |
| 3201 ReportCompactionProgress(evacuation_time, saved_live_bytes); |
| 3202 if (FLAG_trace_evacuation) { |
| 3203 PrintIsolate( |
| 3204 heap()->isolate(), |
| 3205 "evacuation[%p]: page=%p new_space=%d " |
| 3206 "page_evacuation=%d executable=%d contains_age_mark=%d " |
| 3207 "live_bytes=%" V8PRIdPTR " time=%f page_promotion_qualifies=%d\n", |
| 3208 static_cast<void*>(this), static_cast<void*>(page), page->InNewSpace(), |
| 3209 page->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION) || |
| 3210 page->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION), |
| 3211 page->IsFlagSet(MemoryChunk::IS_EXECUTABLE), |
| 3212 page->Contains(heap()->new_space()->age_mark()), saved_live_bytes, |
| 3213 evacuation_time, |
| 3214 saved_live_bytes > Evacuator::PageEvacuationThreshold()); |
| 3215 } |
| 3216 return success; |
| 3217 } |
| 3218 |
3181 void Evacuator::Finalize() { | 3219 void Evacuator::Finalize() { |
3182 heap()->old_space()->MergeCompactionSpace(compaction_spaces_.Get(OLD_SPACE)); | 3220 heap()->old_space()->MergeCompactionSpace(compaction_spaces_.Get(OLD_SPACE)); |
3183 heap()->code_space()->MergeCompactionSpace( | 3221 heap()->code_space()->MergeCompactionSpace( |
3184 compaction_spaces_.Get(CODE_SPACE)); | 3222 compaction_spaces_.Get(CODE_SPACE)); |
3185 heap()->tracer()->AddCompactionEvent(duration_, bytes_compacted_); | 3223 heap()->tracer()->AddCompactionEvent(duration_, bytes_compacted_); |
3186 heap()->IncrementPromotedObjectsSize(new_space_visitor_.promoted_size() + | 3224 heap()->IncrementPromotedObjectsSize(new_space_visitor_.promoted_size() + |
3187 new_to_old_page_visitor_.moved_bytes()); | 3225 new_to_old_page_visitor_.moved_bytes()); |
3188 heap()->IncrementSemiSpaceCopiedObjectSize( | 3226 heap()->IncrementSemiSpaceCopiedObjectSize( |
3189 new_space_visitor_.semispace_copied_size() + | 3227 new_space_visitor_.semispace_copied_size() + |
3190 new_to_new_page_visitor_.moved_bytes()); | 3228 new_to_new_page_visitor_.moved_bytes()); |
3191 heap()->IncrementYoungSurvivorsCounter( | 3229 heap()->IncrementYoungSurvivorsCounter( |
3192 new_space_visitor_.promoted_size() + | 3230 new_space_visitor_.promoted_size() + |
3193 new_space_visitor_.semispace_copied_size() + | 3231 new_space_visitor_.semispace_copied_size() + |
3194 new_to_old_page_visitor_.moved_bytes() + | 3232 new_to_old_page_visitor_.moved_bytes() + |
3195 new_to_new_page_visitor_.moved_bytes()); | 3233 new_to_new_page_visitor_.moved_bytes()); |
3196 heap()->MergeAllocationSitePretenuringFeedback(local_pretenuring_feedback_); | 3234 heap()->MergeAllocationSitePretenuringFeedback(local_pretenuring_feedback_); |
3197 } | 3235 } |
3198 | 3236 |
3199 class FullEvacuator : public Evacuator { | 3237 class FullEvacuator : public Evacuator { |
3200 public: | 3238 public: |
3201 FullEvacuator(Heap* heap, RecordMigratedSlotVisitor* record_visitor) | 3239 FullEvacuator(Heap* heap, RecordMigratedSlotVisitor* record_visitor) |
3202 : Evacuator(heap, record_visitor) {} | 3240 : Evacuator(heap, record_visitor) {} |
3203 | 3241 |
3204 bool EvacuatePage(Page* page, const MarkingState& state) override; | 3242 protected: |
| 3243 bool RawEvacuatePage(Page* page, const MarkingState& state) override; |
3205 }; | 3244 }; |
3206 | 3245 |
3207 bool FullEvacuator::EvacuatePage(Page* page, const MarkingState& state) { | 3246 bool FullEvacuator::RawEvacuatePage(Page* page, const MarkingState& state) { |
3208 bool success = false; | 3247 bool success = false; |
3209 DCHECK(page->SweepingDone()); | 3248 LiveObjectVisitor object_visitor; |
3210 intptr_t saved_live_bytes = state.live_bytes(); | 3249 switch (ComputeEvacuationMode(page)) { |
3211 double evacuation_time = 0.0; | 3250 case kObjectsNewToOld: |
3212 { | 3251 success = object_visitor.VisitBlackObjects( |
3213 AlwaysAllocateScope always_allocate(heap()->isolate()); | 3252 page, state, &new_space_visitor_, LiveObjectVisitor::kClearMarkbits); |
3214 TimedScope timed_scope(&evacuation_time); | 3253 DCHECK(success); |
3215 LiveObjectVisitor object_visitor; | 3254 ArrayBufferTracker::ProcessBuffers( |
3216 switch (ComputeEvacuationMode(page)) { | 3255 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); |
3217 case kObjectsNewToOld: | 3256 break; |
3218 success = | 3257 case kPageNewToOld: |
3219 object_visitor.VisitBlackObjects(page, state, &new_space_visitor_, | 3258 success = object_visitor.VisitBlackObjects( |
3220 LiveObjectVisitor::kClearMarkbits); | 3259 page, state, &new_to_old_page_visitor_, |
| 3260 LiveObjectVisitor::kKeepMarking); |
| 3261 DCHECK(success); |
| 3262 new_to_old_page_visitor_.account_moved_bytes( |
| 3263 MarkingState::Internal(page).live_bytes()); |
| 3264 // ArrayBufferTracker will be updated during sweeping. |
| 3265 break; |
| 3266 case kPageNewToNew: |
| 3267 success = object_visitor.VisitBlackObjects( |
| 3268 page, state, &new_to_new_page_visitor_, |
| 3269 LiveObjectVisitor::kKeepMarking); |
| 3270 DCHECK(success); |
| 3271 new_to_new_page_visitor_.account_moved_bytes( |
| 3272 MarkingState::Internal(page).live_bytes()); |
| 3273 // ArrayBufferTracker will be updated during sweeping. |
| 3274 break; |
| 3275 case kObjectsOldToOld: |
| 3276 success = object_visitor.VisitBlackObjects( |
| 3277 page, state, &old_space_visitor_, LiveObjectVisitor::kClearMarkbits); |
| 3278 if (!success) { |
| 3279 // Aborted compaction page. We have to record slots here, since we |
| 3280 // might not have recorded them in first place. |
| 3281 // Note: We mark the page as aborted here to be able to record slots |
| 3282 // for code objects in |RecordMigratedSlotVisitor|. |
| 3283 page->SetFlag(Page::COMPACTION_WAS_ABORTED); |
| 3284 EvacuateRecordOnlyVisitor record_visitor(heap()); |
| 3285 success = object_visitor.VisitBlackObjects( |
| 3286 page, state, &record_visitor, LiveObjectVisitor::kKeepMarking); |
| 3287 ArrayBufferTracker::ProcessBuffers( |
| 3288 page, ArrayBufferTracker::kUpdateForwardedKeepOthers); |
3221 DCHECK(success); | 3289 DCHECK(success); |
| 3290 // We need to return failure here to indicate that we want this page |
| 3291 // added to the sweeper. |
| 3292 success = false; |
| 3293 } else { |
3222 ArrayBufferTracker::ProcessBuffers( | 3294 ArrayBufferTracker::ProcessBuffers( |
3223 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); | 3295 page, ArrayBufferTracker::kUpdateForwardedRemoveOthers); |
3224 break; | 3296 } |
3225 case kPageNewToOld: | 3297 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 } | 3298 } |
3283 return success; | 3299 return success; |
3284 } | 3300 } |
3285 | 3301 |
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 { | 3302 class EvacuationJobTraits { |
3315 public: | 3303 public: |
3316 typedef int* PerPageData; // Pointer to number of aborted pages. | 3304 typedef int* PerPageData; // Pointer to number of aborted pages. |
3317 typedef Evacuator* PerTaskData; | 3305 typedef Evacuator* PerTaskData; |
3318 | 3306 |
3319 static const bool NeedSequentialFinalization = true; | 3307 static const bool NeedSequentialFinalization = true; |
3320 | 3308 |
3321 static bool ProcessPageInParallel(Heap* heap, PerTaskData evacuator, | 3309 static bool ProcessPageInParallel(Heap* heap, PerTaskData evacuator, |
3322 MemoryChunk* chunk, PerPageData) { | 3310 MemoryChunk* chunk, PerPageData) { |
3323 return evacuator->EvacuatePage(reinterpret_cast<Page*>(chunk), | 3311 return evacuator->EvacuatePage(reinterpret_cast<Page*>(chunk), |
(...skipping 845 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 | 4157 // The target is always in old space, we don't have to record the slot in |
4170 // the old-to-new remembered set. | 4158 // the old-to-new remembered set. |
4171 DCHECK(!heap()->InNewSpace(target)); | 4159 DCHECK(!heap()->InNewSpace(target)); |
4172 RecordRelocSlot(host, &rinfo, target); | 4160 RecordRelocSlot(host, &rinfo, target); |
4173 } | 4161 } |
4174 } | 4162 } |
4175 } | 4163 } |
4176 | 4164 |
4177 } // namespace internal | 4165 } // namespace internal |
4178 } // namespace v8 | 4166 } // namespace v8 |
OLD | NEW |