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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/compilation-cache.h" | 9 #include "src/compilation-cache.h" |
10 #include "src/cpu-profiler.h" | 10 #include "src/cpu-profiler.h" |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 581 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
582 new SweeperTask(heap(), heap()->old_data_space()), | 582 new SweeperTask(heap(), heap()->old_data_space()), |
583 v8::Platform::kShortRunningTask); | 583 v8::Platform::kShortRunningTask); |
584 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 584 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
585 new SweeperTask(heap(), heap()->old_pointer_space()), | 585 new SweeperTask(heap(), heap()->old_pointer_space()), |
586 v8::Platform::kShortRunningTask); | 586 v8::Platform::kShortRunningTask); |
587 } | 587 } |
588 } | 588 } |
589 | 589 |
590 | 590 |
591 void MarkCompactCollector::WaitUntilSweepingCompleted() { | 591 void MarkCompactCollector::WaitUntilSweepingCompleted() { |
Jarin
2014/07/11 07:40:52
Nit: WaitUntilSweepingCompleted -> EnsureSweepingC
Hannes Payer (out of office)
2014/07/11 09:36:13
Done.
| |
592 ASSERT(sweeping_pending_ == true); | 592 ASSERT(sweeping_pending_ == true); |
593 | |
594 // If sweeping is not completed, we try to complete it here. If we do not | |
595 // have sweeper threads we have to complete since we do not have a good | |
596 // indicator for a swept space in that case. | |
597 if (!AreSweeperThreadsActivated() || !IsSweepingCompleted()) { | |
598 SweepInParallel(heap()->paged_space(OLD_DATA_SPACE), 0); | |
599 SweepInParallel(heap()->paged_space(OLD_POINTER_SPACE), 0); | |
600 } | |
601 | |
593 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { | 602 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { |
594 isolate()->sweeper_threads()[i]->WaitForSweeperThread(); | 603 isolate()->sweeper_threads()[i]->WaitForSweeperThread(); |
595 } | 604 } |
596 if (FLAG_job_based_sweeping) { | 605 if (FLAG_job_based_sweeping) { |
597 // Wait twice for both jobs. | 606 // Wait twice for both jobs. |
598 pending_sweeper_jobs_semaphore_.Wait(); | 607 pending_sweeper_jobs_semaphore_.Wait(); |
599 pending_sweeper_jobs_semaphore_.Wait(); | 608 pending_sweeper_jobs_semaphore_.Wait(); |
600 } | 609 } |
601 ParallelSweepSpacesComplete(); | 610 ParallelSweepSpacesComplete(); |
602 sweeping_pending_ = false; | 611 sweeping_pending_ = false; |
603 RefillFreeList(heap()->paged_space(OLD_DATA_SPACE)); | 612 RefillFreeList(heap()->paged_space(OLD_DATA_SPACE)); |
604 RefillFreeList(heap()->paged_space(OLD_POINTER_SPACE)); | 613 RefillFreeList(heap()->paged_space(OLD_POINTER_SPACE)); |
605 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes(); | 614 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes(); |
606 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes(); | 615 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes(); |
607 } | 616 } |
608 | 617 |
609 | 618 |
610 bool MarkCompactCollector::IsSweepingCompleted() { | 619 bool MarkCompactCollector::IsSweepingCompleted() { |
Jarin
2014/07/11 07:40:52
Nit: rename IsSweepingCompleted to IsConcurrentSwe
Hannes Payer (out of office)
2014/07/11 09:36:13
I left a comment for non-concurrent sweeping, inst
| |
611 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { | 620 for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { |
612 if (!isolate()->sweeper_threads()[i]->SweepingCompleted()) { | 621 if (!isolate()->sweeper_threads()[i]->SweepingCompleted()) { |
613 return false; | 622 return false; |
614 } | 623 } |
615 } | 624 } |
625 | |
616 if (FLAG_job_based_sweeping) { | 626 if (FLAG_job_based_sweeping) { |
617 if (!pending_sweeper_jobs_semaphore_.WaitFor( | 627 if (!pending_sweeper_jobs_semaphore_.WaitFor( |
618 base::TimeDelta::FromSeconds(0))) { | 628 base::TimeDelta::FromSeconds(0))) { |
619 return false; | 629 return false; |
620 } | 630 } |
621 pending_sweeper_jobs_semaphore_.Signal(); | 631 pending_sweeper_jobs_semaphore_.Signal(); |
622 } | 632 } |
623 return true; | 633 return true; |
624 } | 634 } |
625 | 635 |
(...skipping 15 matching lines...) Expand all Loading... | |
641 space->AddToAccountingStats(freed_bytes); | 651 space->AddToAccountingStats(freed_bytes); |
642 space->DecrementUnsweptFreeBytes(freed_bytes); | 652 space->DecrementUnsweptFreeBytes(freed_bytes); |
643 } | 653 } |
644 | 654 |
645 | 655 |
646 bool MarkCompactCollector::AreSweeperThreadsActivated() { | 656 bool MarkCompactCollector::AreSweeperThreadsActivated() { |
647 return isolate()->sweeper_threads() != NULL || FLAG_job_based_sweeping; | 657 return isolate()->sweeper_threads() != NULL || FLAG_job_based_sweeping; |
648 } | 658 } |
649 | 659 |
650 | 660 |
651 bool MarkCompactCollector::IsConcurrentSweepingInProgress(PagedSpace* space) { | |
652 return (space == NULL || space->is_swept_concurrently()) && | |
653 sweeping_pending_; | |
654 } | |
655 | |
656 | |
657 void Marking::TransferMark(Address old_start, Address new_start) { | 661 void Marking::TransferMark(Address old_start, Address new_start) { |
658 // This is only used when resizing an object. | 662 // This is only used when resizing an object. |
659 ASSERT(MemoryChunk::FromAddress(old_start) == | 663 ASSERT(MemoryChunk::FromAddress(old_start) == |
660 MemoryChunk::FromAddress(new_start)); | 664 MemoryChunk::FromAddress(new_start)); |
661 | 665 |
662 if (!heap_->incremental_marking()->IsMarking()) return; | 666 if (!heap_->incremental_marking()->IsMarking()) return; |
663 | 667 |
664 // If the mark doesn't move, we don't check the color of the object. | 668 // If the mark doesn't move, we don't check the color of the object. |
665 // It doesn't matter whether the object is black, since it hasn't changed | 669 // It doesn't matter whether the object is black, since it hasn't changed |
666 // size, so the adjustment to the live data count will be zero anyway. | 670 // size, so the adjustment to the live data count will be zero anyway. |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
952 // variable. | 956 // variable. |
953 tracer_ = tracer; | 957 tracer_ = tracer; |
954 | 958 |
955 #ifdef DEBUG | 959 #ifdef DEBUG |
956 ASSERT(state_ == IDLE); | 960 ASSERT(state_ == IDLE); |
957 state_ = PREPARE_GC; | 961 state_ = PREPARE_GC; |
958 #endif | 962 #endif |
959 | 963 |
960 ASSERT(!FLAG_never_compact || !FLAG_always_compact); | 964 ASSERT(!FLAG_never_compact || !FLAG_always_compact); |
961 | 965 |
962 if (IsConcurrentSweepingInProgress()) { | 966 if (sweeping_pending()) { |
963 // Instead of waiting we could also abort the sweeper threads here. | 967 // Instead of waiting we could also abort the sweeper threads here. |
964 WaitUntilSweepingCompleted(); | 968 WaitUntilSweepingCompleted(); |
965 } | 969 } |
966 | 970 |
967 // Clear marking bits if incremental marking is aborted. | 971 // Clear marking bits if incremental marking is aborted. |
968 if (was_marked_incrementally_ && abort_incremental_marking_) { | 972 if (was_marked_incrementally_ && abort_incremental_marking_) { |
969 heap()->incremental_marking()->Abort(); | 973 heap()->incremental_marking()->Abort(); |
970 ClearMarkbits(); | 974 ClearMarkbits(); |
971 AbortCompaction(); | 975 AbortCompaction(); |
972 was_marked_incrementally_ = false; | 976 was_marked_incrementally_ = false; |
(...skipping 3117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4090 max_freed_overall = Max(max_freed, max_freed_overall); | 4094 max_freed_overall = Max(max_freed, max_freed_overall); |
4091 } | 4095 } |
4092 if (p == space->end_of_unswept_pages()) break; | 4096 if (p == space->end_of_unswept_pages()) break; |
4093 } | 4097 } |
4094 return max_freed_overall; | 4098 return max_freed_overall; |
4095 } | 4099 } |
4096 | 4100 |
4097 | 4101 |
4098 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { | 4102 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { |
4099 space->set_is_iterable(sweeper == PRECISE); | 4103 space->set_is_iterable(sweeper == PRECISE); |
4100 space->set_is_swept_concurrently(sweeper == CONCURRENT_CONSERVATIVE); | |
4101 space->ClearStats(); | 4104 space->ClearStats(); |
4102 | 4105 |
4103 // We defensively initialize end_of_unswept_pages_ here with the first page | 4106 // We defensively initialize end_of_unswept_pages_ here with the first page |
4104 // of the pages list. | 4107 // of the pages list. |
4105 space->set_end_of_unswept_pages(space->FirstPage()); | 4108 space->set_end_of_unswept_pages(space->FirstPage()); |
4106 | 4109 |
4107 PageIterator it(space); | 4110 PageIterator it(space); |
4108 | 4111 |
4109 int pages_swept = 0; | 4112 int pages_swept = 0; |
4110 bool unused_page_present = false; | 4113 bool unused_page_present = false; |
(...skipping 24 matching lines...) Expand all Loading... | |
4135 // Adjust unswept free bytes because releasing a page expects said | 4138 // Adjust unswept free bytes because releasing a page expects said |
4136 // counter to be accurate for unswept pages. | 4139 // counter to be accurate for unswept pages. |
4137 space->IncreaseUnsweptFreeBytes(p); | 4140 space->IncreaseUnsweptFreeBytes(p); |
4138 space->ReleasePage(p); | 4141 space->ReleasePage(p); |
4139 continue; | 4142 continue; |
4140 } | 4143 } |
4141 unused_page_present = true; | 4144 unused_page_present = true; |
4142 } | 4145 } |
4143 | 4146 |
4144 switch (sweeper) { | 4147 switch (sweeper) { |
4145 case CONSERVATIVE: { | |
4146 if (FLAG_gc_verbose) { | |
4147 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", | |
4148 reinterpret_cast<intptr_t>(p)); | |
4149 } | |
4150 SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p); | |
4151 pages_swept++; | |
4152 break; | |
4153 } | |
4154 case CONCURRENT_CONSERVATIVE: | 4148 case CONCURRENT_CONSERVATIVE: |
4155 case PARALLEL_CONSERVATIVE: { | 4149 case PARALLEL_CONSERVATIVE: { |
4156 if (!parallel_sweeping_active) { | 4150 if (!parallel_sweeping_active) { |
4157 if (FLAG_gc_verbose) { | 4151 if (FLAG_gc_verbose) { |
4158 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", | 4152 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", |
4159 reinterpret_cast<intptr_t>(p)); | 4153 reinterpret_cast<intptr_t>(p)); |
4160 } | 4154 } |
4161 SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p); | 4155 SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p); |
4162 pages_swept++; | 4156 pages_swept++; |
4163 parallel_sweeping_active = true; | 4157 parallel_sweeping_active = true; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4205 // Give pages that are queued to be freed back to the OS. | 4199 // Give pages that are queued to be freed back to the OS. |
4206 heap()->FreeQueuedChunks(); | 4200 heap()->FreeQueuedChunks(); |
4207 } | 4201 } |
4208 | 4202 |
4209 | 4203 |
4210 void MarkCompactCollector::SweepSpaces() { | 4204 void MarkCompactCollector::SweepSpaces() { |
4211 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); | 4205 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); |
4212 #ifdef DEBUG | 4206 #ifdef DEBUG |
4213 state_ = SWEEP_SPACES; | 4207 state_ = SWEEP_SPACES; |
4214 #endif | 4208 #endif |
4215 SweeperType how_to_sweep = CONSERVATIVE; | 4209 SweeperType how_to_sweep = CONCURRENT_CONSERVATIVE; |
4216 if (AreSweeperThreadsActivated()) { | 4210 if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE; |
4217 if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE; | 4211 if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE; |
Jarin
2014/07/11 07:40:52
Is this is needed? CONCURRENT_CONSERVATIVE is the
Hannes Payer (out of office)
2014/07/11 09:36:13
I think it is good to initialize it.
| |
4218 if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE; | 4212 |
4219 } | |
4220 if (sweep_precisely_) how_to_sweep = PRECISE; | 4213 if (sweep_precisely_) how_to_sweep = PRECISE; |
4221 | 4214 |
4222 MoveEvacuationCandidatesToEndOfPagesList(); | 4215 MoveEvacuationCandidatesToEndOfPagesList(); |
4223 | 4216 |
4224 // Noncompacting collections simply sweep the spaces to clear the mark | 4217 // Noncompacting collections simply sweep the spaces to clear the mark |
4225 // bits and free the nonlive blocks (for old and map spaces). We sweep | 4218 // bits and free the nonlive blocks (for old and map spaces). We sweep |
4226 // the map space last because freeing non-live maps overwrites them and | 4219 // the map space last because freeing non-live maps overwrites them and |
4227 // the other spaces rely on possibly non-live maps to get the sizes for | 4220 // the other spaces rely on possibly non-live maps to get the sizes for |
4228 // non-live objects. | 4221 // non-live objects. |
4229 { GCTracer::Scope sweep_scope(tracer_, GCTracer::Scope::MC_SWEEP_OLDSPACE); | 4222 { GCTracer::Scope sweep_scope(tracer_, GCTracer::Scope::MC_SWEEP_OLDSPACE); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4506 while (buffer != NULL) { | 4499 while (buffer != NULL) { |
4507 SlotsBuffer* next_buffer = buffer->next(); | 4500 SlotsBuffer* next_buffer = buffer->next(); |
4508 DeallocateBuffer(buffer); | 4501 DeallocateBuffer(buffer); |
4509 buffer = next_buffer; | 4502 buffer = next_buffer; |
4510 } | 4503 } |
4511 *buffer_address = NULL; | 4504 *buffer_address = NULL; |
4512 } | 4505 } |
4513 | 4506 |
4514 | 4507 |
4515 } } // namespace v8::internal | 4508 } } // namespace v8::internal |
OLD | NEW |