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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 ClearNonLiveReferences(); | 310 ClearNonLiveReferences(); |
311 | 311 |
312 RecordObjectStats(); | 312 RecordObjectStats(); |
313 | 313 |
314 #ifdef VERIFY_HEAP | 314 #ifdef VERIFY_HEAP |
315 if (FLAG_verify_heap) { | 315 if (FLAG_verify_heap) { |
316 VerifyMarking(heap_); | 316 VerifyMarking(heap_); |
317 } | 317 } |
318 #endif | 318 #endif |
319 | 319 |
320 SweepSpaces(); | 320 StartSweepSpaces(); |
321 | 321 |
322 EvacuateNewSpaceAndCandidates(); | 322 EvacuateNewSpaceAndCandidates(); |
323 | 323 |
324 Finish(); | 324 Finish(); |
325 } | 325 } |
326 | 326 |
327 | 327 |
328 #ifdef VERIFY_HEAP | 328 #ifdef VERIFY_HEAP |
329 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { | 329 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { |
330 for (Page* p : *space) { | 330 for (Page* p : *space) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 | 440 |
441 DISALLOW_COPY_AND_ASSIGN(SweeperTask); | 441 DISALLOW_COPY_AND_ASSIGN(SweeperTask); |
442 }; | 442 }; |
443 | 443 |
444 void MarkCompactCollector::Sweeper::StartSweeping() { | 444 void MarkCompactCollector::Sweeper::StartSweeping() { |
445 sweeping_in_progress_ = true; | 445 sweeping_in_progress_ = true; |
446 ForAllSweepingSpaces([this](AllocationSpace space) { | 446 ForAllSweepingSpaces([this](AllocationSpace space) { |
447 std::sort(sweeping_list_[space].begin(), sweeping_list_[space].end(), | 447 std::sort(sweeping_list_[space].begin(), sweeping_list_[space].end(), |
448 [](Page* a, Page* b) { return a->LiveBytes() < b->LiveBytes(); }); | 448 [](Page* a, Page* b) { return a->LiveBytes() < b->LiveBytes(); }); |
449 }); | 449 }); |
450 if (FLAG_concurrent_sweeping) { | 450 } |
| 451 |
| 452 void MarkCompactCollector::Sweeper::StartSweeperTasks() { |
| 453 if (FLAG_concurrent_sweeping && sweeping_in_progress_) { |
451 ForAllSweepingSpaces([this](AllocationSpace space) { | 454 ForAllSweepingSpaces([this](AllocationSpace space) { |
452 if (space == NEW_SPACE) return; | 455 if (space == NEW_SPACE) return; |
453 StartSweepingHelper(space); | 456 num_sweeping_tasks_.Increment(1); |
| 457 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 458 new SweeperTask(this, &pending_sweeper_tasks_semaphore_, space), |
| 459 v8::Platform::kShortRunningTask); |
454 }); | 460 }); |
455 } | 461 } |
456 } | 462 } |
457 | 463 |
458 void MarkCompactCollector::Sweeper::StartSweepingHelper( | |
459 AllocationSpace space_to_start) { | |
460 num_sweeping_tasks_.Increment(1); | |
461 V8::GetCurrentPlatform()->CallOnBackgroundThread( | |
462 new SweeperTask(this, &pending_sweeper_tasks_semaphore_, space_to_start), | |
463 v8::Platform::kShortRunningTask); | |
464 } | |
465 | |
466 void MarkCompactCollector::Sweeper::SweepOrWaitUntilSweepingCompleted( | 464 void MarkCompactCollector::Sweeper::SweepOrWaitUntilSweepingCompleted( |
467 Page* page) { | 465 Page* page) { |
468 if (!page->SweepingDone()) { | 466 if (!page->SweepingDone()) { |
469 ParallelSweepPage(page, page->owner()->identity()); | 467 ParallelSweepPage(page, page->owner()->identity()); |
470 if (!page->SweepingDone()) { | 468 if (!page->SweepingDone()) { |
471 // We were not able to sweep that page, i.e., a concurrent | 469 // We were not able to sweep that page, i.e., a concurrent |
472 // sweeper thread currently owns this page. Wait for the sweeper | 470 // sweeper thread currently owns this page. Wait for the sweeper |
473 // thread to be done with this page. | 471 // thread to be done with this page. |
474 page->WaitUntilSweepingCompleted(); | 472 page->WaitUntilSweepingCompleted(); |
475 } | 473 } |
476 } | 474 } |
477 } | 475 } |
478 | 476 |
479 void MarkCompactCollector::SweepAndRefill(CompactionSpace* space) { | 477 void MarkCompactCollector::SweepAndRefill(CompactionSpace* space) { |
480 if (FLAG_concurrent_sweeping && !sweeper().IsSweepingCompleted()) { | 478 if (FLAG_concurrent_sweeping && |
| 479 !sweeper().IsSweepingCompleted(space->identity())) { |
481 sweeper().ParallelSweepSpace(space->identity(), 0); | 480 sweeper().ParallelSweepSpace(space->identity(), 0); |
482 space->RefillFreeList(); | 481 space->RefillFreeList(); |
483 } | 482 } |
484 } | 483 } |
485 | 484 |
486 Page* MarkCompactCollector::Sweeper::GetSweptPageSafe(PagedSpace* space) { | 485 Page* MarkCompactCollector::Sweeper::GetSweptPageSafe(PagedSpace* space) { |
487 base::LockGuard<base::Mutex> guard(&mutex_); | 486 base::LockGuard<base::Mutex> guard(&mutex_); |
488 SweptList& list = swept_list_[space->identity()]; | 487 SweptList& list = swept_list_[space->identity()]; |
489 if (list.length() > 0) { | 488 if (list.length() > 0) { |
490 return list.RemoveLast(); | 489 return list.RemoveLast(); |
491 } | 490 } |
492 return nullptr; | 491 return nullptr; |
493 } | 492 } |
494 | 493 |
495 void MarkCompactCollector::Sweeper::EnsureCompleted() { | 494 void MarkCompactCollector::Sweeper::EnsureCompleted() { |
496 if (!sweeping_in_progress_) return; | 495 if (!sweeping_in_progress_) return; |
497 | 496 |
498 // If sweeping is not completed or not running at all, we try to complete it | 497 // If sweeping is not completed or not running at all, we try to complete it |
499 // here. | 498 // here. |
500 if (!FLAG_concurrent_sweeping || !IsSweepingCompleted()) { | 499 ForAllSweepingSpaces([this](AllocationSpace space) { |
501 ForAllSweepingSpaces( | 500 if (!FLAG_concurrent_sweeping || !this->IsSweepingCompleted(space)) { |
502 [this](AllocationSpace space) { ParallelSweepSpace(space, 0); }); | 501 ParallelSweepSpace(space, 0); |
503 } | 502 } |
| 503 }); |
504 | 504 |
505 if (FLAG_concurrent_sweeping) { | 505 if (FLAG_concurrent_sweeping) { |
506 while (num_sweeping_tasks_.Value() > 0) { | 506 while (num_sweeping_tasks_.Value() > 0) { |
507 pending_sweeper_tasks_semaphore_.Wait(); | 507 pending_sweeper_tasks_semaphore_.Wait(); |
508 num_sweeping_tasks_.Increment(-1); | 508 num_sweeping_tasks_.Increment(-1); |
509 } | 509 } |
510 } | 510 } |
511 | 511 |
512 ForAllSweepingSpaces([this](AllocationSpace space) { | 512 ForAllSweepingSpaces([this](AllocationSpace space) { |
513 if (space == NEW_SPACE) { | 513 if (space == NEW_SPACE) { |
514 swept_list_[NEW_SPACE].Clear(); | 514 swept_list_[NEW_SPACE].Clear(); |
515 } | 515 } |
516 DCHECK(sweeping_list_[space].empty()); | 516 DCHECK(sweeping_list_[space].empty()); |
517 }); | 517 }); |
518 late_pages_ = false; | |
519 sweeping_in_progress_ = false; | 518 sweeping_in_progress_ = false; |
520 } | 519 } |
521 | 520 |
522 void MarkCompactCollector::Sweeper::EnsureNewSpaceCompleted() { | 521 void MarkCompactCollector::Sweeper::EnsureNewSpaceCompleted() { |
523 if (!sweeping_in_progress_) return; | 522 if (!sweeping_in_progress_) return; |
524 if (!FLAG_concurrent_sweeping || !IsSweepingCompleted()) { | 523 if (!FLAG_concurrent_sweeping || !IsSweepingCompleted(NEW_SPACE)) { |
525 for (Page* p : *heap_->new_space()) { | 524 for (Page* p : *heap_->new_space()) { |
526 SweepOrWaitUntilSweepingCompleted(p); | 525 SweepOrWaitUntilSweepingCompleted(p); |
527 } | 526 } |
528 } | 527 } |
529 } | 528 } |
530 | 529 |
531 void MarkCompactCollector::EnsureSweepingCompleted() { | 530 void MarkCompactCollector::EnsureSweepingCompleted() { |
532 if (!sweeper().sweeping_in_progress()) return; | 531 if (!sweeper().sweeping_in_progress()) return; |
533 | 532 |
534 sweeper().EnsureCompleted(); | 533 sweeper().EnsureCompleted(); |
535 heap()->old_space()->RefillFreeList(); | 534 heap()->old_space()->RefillFreeList(); |
536 heap()->code_space()->RefillFreeList(); | 535 heap()->code_space()->RefillFreeList(); |
537 heap()->map_space()->RefillFreeList(); | 536 heap()->map_space()->RefillFreeList(); |
538 | 537 |
539 #ifdef VERIFY_HEAP | 538 #ifdef VERIFY_HEAP |
540 if (FLAG_verify_heap && !evacuation()) { | 539 if (FLAG_verify_heap && !evacuation()) { |
541 VerifyEvacuation(heap_); | 540 VerifyEvacuation(heap_); |
542 } | 541 } |
543 #endif | 542 #endif |
544 } | 543 } |
545 | 544 |
546 bool MarkCompactCollector::Sweeper::IsSweepingCompleted() { | 545 bool MarkCompactCollector::Sweeper::AreSweeperTasksRunning() { |
547 DCHECK(FLAG_concurrent_sweeping); | 546 DCHECK(FLAG_concurrent_sweeping); |
548 while (pending_sweeper_tasks_semaphore_.WaitFor( | 547 while (pending_sweeper_tasks_semaphore_.WaitFor( |
549 base::TimeDelta::FromSeconds(0))) { | 548 base::TimeDelta::FromSeconds(0))) { |
550 num_sweeping_tasks_.Increment(-1); | 549 num_sweeping_tasks_.Increment(-1); |
551 } | 550 } |
552 return num_sweeping_tasks_.Value() == 0; | 551 return num_sweeping_tasks_.Value() != 0; |
| 552 } |
| 553 |
| 554 bool MarkCompactCollector::Sweeper::IsSweepingCompleted(AllocationSpace space) { |
| 555 DCHECK(FLAG_concurrent_sweeping); |
| 556 if (AreSweeperTasksRunning()) return false; |
| 557 base::LockGuard<base::Mutex> guard(&mutex_); |
| 558 return sweeping_list_[space].empty(); |
553 } | 559 } |
554 | 560 |
555 const char* AllocationSpaceName(AllocationSpace space) { | 561 const char* AllocationSpaceName(AllocationSpace space) { |
556 switch (space) { | 562 switch (space) { |
557 case NEW_SPACE: | 563 case NEW_SPACE: |
558 return "NEW_SPACE"; | 564 return "NEW_SPACE"; |
559 case OLD_SPACE: | 565 case OLD_SPACE: |
560 return "OLD_SPACE"; | 566 return "OLD_SPACE"; |
561 case CODE_SPACE: | 567 case CODE_SPACE: |
562 return "CODE_SPACE"; | 568 return "CODE_SPACE"; |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 if (!was_marked_incrementally_ && FLAG_verify_heap) { | 832 if (!was_marked_incrementally_ && FLAG_verify_heap) { |
827 VerifyMarkbitsAreClean(); | 833 VerifyMarkbitsAreClean(); |
828 } | 834 } |
829 #endif | 835 #endif |
830 } | 836 } |
831 | 837 |
832 | 838 |
833 void MarkCompactCollector::Finish() { | 839 void MarkCompactCollector::Finish() { |
834 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_FINISH); | 840 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_FINISH); |
835 | 841 |
836 if (sweeper().contains_late_pages() && FLAG_concurrent_sweeping) { | 842 if (!heap()->delay_sweeper_tasks_for_testing_) { |
837 // If we added some more pages during MC, we need to start at least one | 843 sweeper().StartSweeperTasks(); |
838 // more task as all other tasks might already be finished. | |
839 sweeper().StartSweepingHelper(OLD_SPACE); | |
840 } | 844 } |
841 | 845 |
842 // The hashing of weak_object_to_code_table is no longer valid. | 846 // The hashing of weak_object_to_code_table is no longer valid. |
843 heap()->weak_object_to_code_table()->Rehash( | 847 heap()->weak_object_to_code_table()->Rehash( |
844 heap()->isolate()->factory()->undefined_value()); | 848 heap()->isolate()->factory()->undefined_value()); |
845 | 849 |
846 // Clear the marking state of live large objects. | 850 // Clear the marking state of live large objects. |
847 heap_->lo_space()->ClearMarkingStateOfLiveObjects(); | 851 heap_->lo_space()->ClearMarkingStateOfLiveObjects(); |
848 | 852 |
849 #ifdef DEBUG | 853 #ifdef DEBUG |
(...skipping 2175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3025 } | 3029 } |
3026 | 3030 |
3027 int MarkCompactCollector::NumberOfParallelCompactionTasks(int pages, | 3031 int MarkCompactCollector::NumberOfParallelCompactionTasks(int pages, |
3028 intptr_t live_bytes) { | 3032 intptr_t live_bytes) { |
3029 if (!FLAG_parallel_compaction) return 1; | 3033 if (!FLAG_parallel_compaction) return 1; |
3030 // Compute the number of needed tasks based on a target compaction time, the | 3034 // Compute the number of needed tasks based on a target compaction time, the |
3031 // profiled compaction speed and marked live memory. | 3035 // profiled compaction speed and marked live memory. |
3032 // | 3036 // |
3033 // The number of parallel compaction tasks is limited by: | 3037 // The number of parallel compaction tasks is limited by: |
3034 // - #evacuation pages | 3038 // - #evacuation pages |
3035 // - (#cores - 1) | 3039 // - #cores |
3036 const double kTargetCompactionTimeInMs = .5; | 3040 const double kTargetCompactionTimeInMs = .5; |
3037 const int kNumSweepingTasks = 3; | |
3038 | 3041 |
3039 double compaction_speed = | 3042 double compaction_speed = |
3040 heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); | 3043 heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); |
3041 | 3044 |
3042 const int available_cores = Max( | 3045 const int available_cores = Max( |
3043 1, static_cast<int>( | 3046 1, static_cast<int>( |
3044 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()) - | 3047 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())); |
3045 kNumSweepingTasks - 1); | |
3046 int tasks; | 3048 int tasks; |
3047 if (compaction_speed > 0) { | 3049 if (compaction_speed > 0) { |
3048 tasks = 1 + static_cast<int>(live_bytes / compaction_speed / | 3050 tasks = 1 + static_cast<int>(live_bytes / compaction_speed / |
3049 kTargetCompactionTimeInMs); | 3051 kTargetCompactionTimeInMs); |
3050 } else { | 3052 } else { |
3051 tasks = pages; | 3053 tasks = pages; |
3052 } | 3054 } |
3053 const int tasks_capped_pages = Min(pages, tasks); | 3055 const int tasks_capped_pages = Min(pages, tasks); |
3054 return Min(available_cores, tasks_capped_pages); | 3056 return Min(available_cores, tasks_capped_pages); |
3055 } | 3057 } |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3422 // still contain stale pointers. We only free the chunks after pointer updates | 3424 // still contain stale pointers. We only free the chunks after pointer updates |
3423 // to still have access to page headers. | 3425 // to still have access to page headers. |
3424 heap()->memory_allocator()->unmapper()->FreeQueuedChunks(); | 3426 heap()->memory_allocator()->unmapper()->FreeQueuedChunks(); |
3425 | 3427 |
3426 { | 3428 { |
3427 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_CLEAN_UP); | 3429 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_CLEAN_UP); |
3428 | 3430 |
3429 for (Page* p : newspace_evacuation_candidates_) { | 3431 for (Page* p : newspace_evacuation_candidates_) { |
3430 if (p->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION)) { | 3432 if (p->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION)) { |
3431 p->ClearFlag(Page::PAGE_NEW_NEW_PROMOTION); | 3433 p->ClearFlag(Page::PAGE_NEW_NEW_PROMOTION); |
3432 sweeper().AddLatePage(p->owner()->identity(), p); | 3434 sweeper().AddPage(p->owner()->identity(), p); |
3433 } else if (p->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION)) { | 3435 } else if (p->IsFlagSet(Page::PAGE_NEW_OLD_PROMOTION)) { |
3434 p->ClearFlag(Page::PAGE_NEW_OLD_PROMOTION); | 3436 p->ClearFlag(Page::PAGE_NEW_OLD_PROMOTION); |
3435 p->ForAllFreeListCategories( | 3437 p->ForAllFreeListCategories( |
3436 [](FreeListCategory* category) { DCHECK(!category->is_linked()); }); | 3438 [](FreeListCategory* category) { DCHECK(!category->is_linked()); }); |
3437 sweeper().AddLatePage(p->owner()->identity(), p); | 3439 sweeper().AddPage(p->owner()->identity(), p); |
3438 } | 3440 } |
3439 } | 3441 } |
3440 newspace_evacuation_candidates_.Rewind(0); | 3442 newspace_evacuation_candidates_.Rewind(0); |
3441 | 3443 |
3442 for (Page* p : evacuation_candidates_) { | 3444 for (Page* p : evacuation_candidates_) { |
3443 // Important: skip list should be cleared only after roots were updated | 3445 // Important: skip list should be cleared only after roots were updated |
3444 // because root iteration traverses the stack and might have to find | 3446 // because root iteration traverses the stack and might have to find |
3445 // code objects from non-updated pc pointing into evacuation candidate. | 3447 // code objects from non-updated pc pointing into evacuation candidate. |
3446 SkipList* list = p->skip_list(); | 3448 SkipList* list = p->skip_list(); |
3447 if (list != NULL) list->Clear(); | 3449 if (list != NULL) list->Clear(); |
3448 if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) { | 3450 if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) { |
3449 sweeper().AddLatePage(p->owner()->identity(), p); | 3451 sweeper().AddPage(p->owner()->identity(), p); |
3450 p->ClearFlag(Page::COMPACTION_WAS_ABORTED); | 3452 p->ClearFlag(Page::COMPACTION_WAS_ABORTED); |
3451 } | 3453 } |
3452 } | 3454 } |
3453 | 3455 |
3454 // Deallocate evacuated candidate pages. | 3456 // Deallocate evacuated candidate pages. |
3455 ReleaseEvacuationCandidates(); | 3457 ReleaseEvacuationCandidates(); |
3456 } | 3458 } |
3457 | 3459 |
3458 #ifdef VERIFY_HEAP | 3460 #ifdef VERIFY_HEAP |
3459 if (FLAG_verify_heap && !sweeper().sweeping_in_progress()) { | 3461 if (FLAG_verify_heap && !sweeper().sweeping_in_progress()) { |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3738 base::LockGuard<base::Mutex> guard(&mutex_); | 3740 base::LockGuard<base::Mutex> guard(&mutex_); |
3739 swept_list_[identity].Add(page); | 3741 swept_list_[identity].Add(page); |
3740 } | 3742 } |
3741 page->concurrent_sweeping_state().SetValue(Page::kSweepingDone); | 3743 page->concurrent_sweeping_state().SetValue(Page::kSweepingDone); |
3742 page->mutex()->Unlock(); | 3744 page->mutex()->Unlock(); |
3743 } | 3745 } |
3744 return max_freed; | 3746 return max_freed; |
3745 } | 3747 } |
3746 | 3748 |
3747 void MarkCompactCollector::Sweeper::AddPage(AllocationSpace space, Page* page) { | 3749 void MarkCompactCollector::Sweeper::AddPage(AllocationSpace space, Page* page) { |
3748 DCHECK(!sweeping_in_progress_); | 3750 DCHECK(!FLAG_concurrent_sweeping || !AreSweeperTasksRunning()); |
3749 PrepareToBeSweptPage(space, page); | 3751 PrepareToBeSweptPage(space, page); |
3750 sweeping_list_[space].push_back(page); | 3752 sweeping_list_[space].push_back(page); |
3751 } | 3753 } |
3752 | 3754 |
3753 void MarkCompactCollector::Sweeper::AddLatePage(AllocationSpace space, | |
3754 Page* page) { | |
3755 DCHECK(sweeping_in_progress_); | |
3756 PrepareToBeSweptPage(space, page); | |
3757 late_pages_ = true; | |
3758 AddSweepingPageSafe(space, page); | |
3759 } | |
3760 | |
3761 void MarkCompactCollector::Sweeper::PrepareToBeSweptPage(AllocationSpace space, | 3755 void MarkCompactCollector::Sweeper::PrepareToBeSweptPage(AllocationSpace space, |
3762 Page* page) { | 3756 Page* page) { |
3763 page->concurrent_sweeping_state().SetValue(Page::kSweepingPending); | 3757 page->concurrent_sweeping_state().SetValue(Page::kSweepingPending); |
3764 DCHECK_GE(page->area_size(), static_cast<size_t>(page->LiveBytes())); | 3758 DCHECK_GE(page->area_size(), static_cast<size_t>(page->LiveBytes())); |
3765 size_t to_sweep = page->area_size() - page->LiveBytes(); | 3759 size_t to_sweep = page->area_size() - page->LiveBytes(); |
3766 if (space != NEW_SPACE) | 3760 if (space != NEW_SPACE) |
3767 heap_->paged_space(space)->accounting_stats_.ShrinkSpace(to_sweep); | 3761 heap_->paged_space(space)->accounting_stats_.ShrinkSpace(to_sweep); |
3768 } | 3762 } |
3769 | 3763 |
3770 Page* MarkCompactCollector::Sweeper::GetSweepingPageSafe( | 3764 Page* MarkCompactCollector::Sweeper::GetSweepingPageSafe( |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3830 sweeper().AddPage(space->identity(), p); | 3824 sweeper().AddPage(space->identity(), p); |
3831 will_be_swept++; | 3825 will_be_swept++; |
3832 } | 3826 } |
3833 | 3827 |
3834 if (FLAG_gc_verbose) { | 3828 if (FLAG_gc_verbose) { |
3835 PrintIsolate(isolate(), "sweeping: space=%s initialized_for_sweeping=%d", | 3829 PrintIsolate(isolate(), "sweeping: space=%s initialized_for_sweeping=%d", |
3836 AllocationSpaceName(space->identity()), will_be_swept); | 3830 AllocationSpaceName(space->identity()), will_be_swept); |
3837 } | 3831 } |
3838 } | 3832 } |
3839 | 3833 |
3840 void MarkCompactCollector::SweepSpaces() { | 3834 void MarkCompactCollector::StartSweepSpaces() { |
3841 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_SWEEP); | 3835 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_SWEEP); |
3842 #ifdef DEBUG | 3836 #ifdef DEBUG |
3843 state_ = SWEEP_SPACES; | 3837 state_ = SWEEP_SPACES; |
3844 #endif | 3838 #endif |
3845 | 3839 |
3846 { | 3840 { |
3847 { | 3841 { |
3848 GCTracer::Scope sweep_scope(heap()->tracer(), | 3842 GCTracer::Scope sweep_scope(heap()->tracer(), |
3849 GCTracer::Scope::MC_SWEEP_OLD); | 3843 GCTracer::Scope::MC_SWEEP_OLD); |
3850 StartSweepSpace(heap()->old_space()); | 3844 StartSweepSpace(heap()->old_space()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3900 // The target is always in old space, we don't have to record the slot in | 3894 // The target is always in old space, we don't have to record the slot in |
3901 // the old-to-new remembered set. | 3895 // the old-to-new remembered set. |
3902 DCHECK(!heap()->InNewSpace(target)); | 3896 DCHECK(!heap()->InNewSpace(target)); |
3903 RecordRelocSlot(host, &rinfo, target); | 3897 RecordRelocSlot(host, &rinfo, target); |
3904 } | 3898 } |
3905 } | 3899 } |
3906 } | 3900 } |
3907 | 3901 |
3908 } // namespace internal | 3902 } // namespace internal |
3909 } // namespace v8 | 3903 } // namespace v8 |
OLD | NEW |