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 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 } | 661 } |
662 | 662 |
663 | 663 |
664 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { | 664 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { |
665 DCHECK(space->identity() == OLD_SPACE || space->identity() == CODE_SPACE); | 665 DCHECK(space->identity() == OLD_SPACE || space->identity() == CODE_SPACE); |
666 | 666 |
667 int number_of_pages = space->CountTotalPages(); | 667 int number_of_pages = space->CountTotalPages(); |
668 int area_size = space->AreaSize(); | 668 int area_size = space->AreaSize(); |
669 | 669 |
670 // Pairs of (live_bytes_in_page, page). | 670 // Pairs of (live_bytes_in_page, page). |
671 std::vector<std::pair<int, Page*> > pages; | 671 typedef std::pair<int, Page*> LiveBytesPagePair; |
| 672 std::vector<LiveBytesPagePair> pages; |
672 pages.reserve(number_of_pages); | 673 pages.reserve(number_of_pages); |
673 | 674 |
674 PageIterator it(space); | 675 PageIterator it(space); |
675 while (it.has_next()) { | 676 while (it.has_next()) { |
676 Page* p = it.next(); | 677 Page* p = it.next(); |
677 if (p->NeverEvacuate()) continue; | 678 if (p->NeverEvacuate()) continue; |
678 if (p->IsFlagSet(Page::POPULAR_PAGE)) { | 679 if (p->IsFlagSet(Page::POPULAR_PAGE)) { |
679 // This page had slots buffer overflow on previous GC, skip it. | 680 // This page had slots buffer overflow on previous GC, skip it. |
680 p->ClearFlag(Page::POPULAR_PAGE); | 681 p->ClearFlag(Page::POPULAR_PAGE); |
681 continue; | 682 continue; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 max_evacuated_bytes = kMaxEvacuatedBytes; | 733 max_evacuated_bytes = kMaxEvacuatedBytes; |
733 } | 734 } |
734 intptr_t free_bytes_threshold = | 735 intptr_t free_bytes_threshold = |
735 target_fragmentation_percent * (area_size / 100); | 736 target_fragmentation_percent * (area_size / 100); |
736 | 737 |
737 // Sort pages from the most free to the least free, then select | 738 // Sort pages from the most free to the least free, then select |
738 // the first n pages for evacuation such that: | 739 // the first n pages for evacuation such that: |
739 // - the total size of evacuated objects does not exceed the specified | 740 // - the total size of evacuated objects does not exceed the specified |
740 // limit. | 741 // limit. |
741 // - fragmentation of (n+1)-th page does not exceed the specified limit. | 742 // - fragmentation of (n+1)-th page does not exceed the specified limit. |
742 std::sort(pages.begin(), pages.end()); | 743 std::sort(pages.begin(), pages.end(), |
| 744 [](const LiveBytesPagePair& a, const LiveBytesPagePair& b) { |
| 745 return a.first < b.first; |
| 746 }); |
743 for (size_t i = 0; i < pages.size(); i++) { | 747 for (size_t i = 0; i < pages.size(); i++) { |
744 int live_bytes = pages[i].first; | 748 int live_bytes = pages[i].first; |
745 int free_bytes = area_size - live_bytes; | 749 int free_bytes = area_size - live_bytes; |
746 if (FLAG_always_compact || | 750 if (FLAG_always_compact || |
747 (free_bytes >= free_bytes_threshold && | 751 (free_bytes >= free_bytes_threshold && |
748 total_live_bytes + live_bytes <= max_evacuated_bytes)) { | 752 total_live_bytes + live_bytes <= max_evacuated_bytes)) { |
749 candidate_count++; | 753 candidate_count++; |
750 total_live_bytes += live_bytes; | 754 total_live_bytes += live_bytes; |
751 } | 755 } |
752 if (FLAG_trace_fragmentation_verbose) { | 756 if (FLAG_trace_fragmentation_verbose) { |
(...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1961 DCHECK(in_use_); | 1965 DCHECK(in_use_); |
1962 top_ = bottom_ = 0xdecbad; | 1966 top_ = bottom_ = 0xdecbad; |
1963 in_use_ = false; | 1967 in_use_ = false; |
1964 } | 1968 } |
1965 | 1969 |
1966 | 1970 |
1967 void MarkCompactCollector::MarkLiveObjects() { | 1971 void MarkCompactCollector::MarkLiveObjects() { |
1968 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK); | 1972 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK); |
1969 double start_time = 0.0; | 1973 double start_time = 0.0; |
1970 if (FLAG_print_cumulative_gc_stat) { | 1974 if (FLAG_print_cumulative_gc_stat) { |
1971 start_time = base::OS::TimeCurrentMillis(); | 1975 start_time = heap_->MonotonicallyIncreasingTimeInMs(); |
1972 } | 1976 } |
1973 // The recursive GC marker detects when it is nearing stack overflow, | 1977 // The recursive GC marker detects when it is nearing stack overflow, |
1974 // and switches to a different marking system. JS interrupts interfere | 1978 // and switches to a different marking system. JS interrupts interfere |
1975 // with the C stack limit check. | 1979 // with the C stack limit check. |
1976 PostponeInterruptsScope postpone(isolate()); | 1980 PostponeInterruptsScope postpone(isolate()); |
1977 | 1981 |
1978 { | 1982 { |
1979 GCTracer::Scope gc_scope(heap()->tracer(), | 1983 GCTracer::Scope gc_scope(heap()->tracer(), |
1980 GCTracer::Scope::MC_MARK_FINISH_INCREMENTAL); | 1984 GCTracer::Scope::MC_MARK_FINISH_INCREMENTAL); |
1981 IncrementalMarking* incremental_marking = heap_->incremental_marking(); | 1985 IncrementalMarking* incremental_marking = heap_->incremental_marking(); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2051 // the weak roots we just marked as pending destruction. | 2055 // the weak roots we just marked as pending destruction. |
2052 // | 2056 // |
2053 // We only process harmony collections, as all object groups have been fully | 2057 // We only process harmony collections, as all object groups have been fully |
2054 // processed and no weakly reachable node can discover new objects groups. | 2058 // processed and no weakly reachable node can discover new objects groups. |
2055 ProcessEphemeralMarking(&root_visitor, true); | 2059 ProcessEphemeralMarking(&root_visitor, true); |
2056 } | 2060 } |
2057 | 2061 |
2058 AfterMarking(); | 2062 AfterMarking(); |
2059 | 2063 |
2060 if (FLAG_print_cumulative_gc_stat) { | 2064 if (FLAG_print_cumulative_gc_stat) { |
2061 heap_->tracer()->AddMarkingTime(base::OS::TimeCurrentMillis() - start_time); | 2065 heap_->tracer()->AddMarkingTime(heap_->MonotonicallyIncreasingTimeInMs() - |
| 2066 start_time); |
2062 } | 2067 } |
2063 } | 2068 } |
2064 | 2069 |
2065 | 2070 |
2066 void MarkCompactCollector::AfterMarking() { | 2071 void MarkCompactCollector::AfterMarking() { |
2067 { | 2072 { |
2068 GCTracer::Scope gc_scope(heap()->tracer(), | 2073 GCTracer::Scope gc_scope(heap()->tracer(), |
2069 GCTracer::Scope::MC_MARK_STRING_TABLE); | 2074 GCTracer::Scope::MC_MARK_STRING_TABLE); |
2070 | 2075 |
2071 // Prune the string table removing all strings only pointed to by the | 2076 // Prune the string table removing all strings only pointed to by the |
(...skipping 2325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4397 PrintF("SweepSpace: %s (%d pages swept)\n", | 4402 PrintF("SweepSpace: %s (%d pages swept)\n", |
4398 AllocationSpaceName(space->identity()), pages_swept); | 4403 AllocationSpaceName(space->identity()), pages_swept); |
4399 } | 4404 } |
4400 } | 4405 } |
4401 | 4406 |
4402 | 4407 |
4403 void MarkCompactCollector::SweepSpaces() { | 4408 void MarkCompactCollector::SweepSpaces() { |
4404 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_SWEEP); | 4409 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_SWEEP); |
4405 double start_time = 0.0; | 4410 double start_time = 0.0; |
4406 if (FLAG_print_cumulative_gc_stat) { | 4411 if (FLAG_print_cumulative_gc_stat) { |
4407 start_time = base::OS::TimeCurrentMillis(); | 4412 start_time = heap_->MonotonicallyIncreasingTimeInMs(); |
4408 } | 4413 } |
4409 | 4414 |
4410 #ifdef DEBUG | 4415 #ifdef DEBUG |
4411 state_ = SWEEP_SPACES; | 4416 state_ = SWEEP_SPACES; |
4412 #endif | 4417 #endif |
4413 | 4418 |
4414 MoveEvacuationCandidatesToEndOfPagesList(); | 4419 MoveEvacuationCandidatesToEndOfPagesList(); |
4415 | 4420 |
4416 { | 4421 { |
4417 { | 4422 { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4449 // needed to properly free them. | 4454 // needed to properly free them. |
4450 heap()->array_buffer_tracker()->FreeDead(false); | 4455 heap()->array_buffer_tracker()->FreeDead(false); |
4451 | 4456 |
4452 // Clear the marking state of live large objects. | 4457 // Clear the marking state of live large objects. |
4453 heap_->lo_space()->ClearMarkingStateOfLiveObjects(); | 4458 heap_->lo_space()->ClearMarkingStateOfLiveObjects(); |
4454 | 4459 |
4455 // Deallocate evacuated candidate pages. | 4460 // Deallocate evacuated candidate pages. |
4456 ReleaseEvacuationCandidates(); | 4461 ReleaseEvacuationCandidates(); |
4457 | 4462 |
4458 if (FLAG_print_cumulative_gc_stat) { | 4463 if (FLAG_print_cumulative_gc_stat) { |
4459 heap_->tracer()->AddSweepingTime(base::OS::TimeCurrentMillis() - | 4464 heap_->tracer()->AddSweepingTime(heap_->MonotonicallyIncreasingTimeInMs() - |
4460 start_time); | 4465 start_time); |
4461 } | 4466 } |
4462 | 4467 |
4463 #ifdef VERIFY_HEAP | 4468 #ifdef VERIFY_HEAP |
4464 if (FLAG_verify_heap && !sweeping_in_progress_) { | 4469 if (FLAG_verify_heap && !sweeping_in_progress_) { |
4465 VerifyEvacuation(heap()); | 4470 VerifyEvacuation(heap()); |
4466 } | 4471 } |
4467 #endif | 4472 #endif |
4468 } | 4473 } |
4469 | 4474 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4575 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4580 MarkBit mark_bit = Marking::MarkBitFrom(host); |
4576 if (Marking::IsBlack(mark_bit)) { | 4581 if (Marking::IsBlack(mark_bit)) { |
4577 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); | 4582 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); |
4578 RecordRelocSlot(&rinfo, target); | 4583 RecordRelocSlot(&rinfo, target); |
4579 } | 4584 } |
4580 } | 4585 } |
4581 } | 4586 } |
4582 | 4587 |
4583 } // namespace internal | 4588 } // namespace internal |
4584 } // namespace v8 | 4589 } // namespace v8 |
OLD | NEW |