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/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 27 matching lines...) Expand all Loading... | |
38 MarkCompactCollector::MarkCompactCollector(Heap* heap) | 38 MarkCompactCollector::MarkCompactCollector(Heap* heap) |
39 : // NOLINT | 39 : // NOLINT |
40 #ifdef DEBUG | 40 #ifdef DEBUG |
41 state_(IDLE), | 41 state_(IDLE), |
42 #endif | 42 #endif |
43 reduce_memory_footprint_(false), | 43 reduce_memory_footprint_(false), |
44 abort_incremental_marking_(false), | 44 abort_incremental_marking_(false), |
45 finalize_incremental_marking_(false), | 45 finalize_incremental_marking_(false), |
46 marking_parity_(ODD_MARKING_PARITY), | 46 marking_parity_(ODD_MARKING_PARITY), |
47 compacting_(false), | 47 compacting_(false), |
48 was_marked_incrementally_(false), | |
49 sweeping_in_progress_(false), | 48 sweeping_in_progress_(false), |
50 pending_sweeper_jobs_semaphore_(0), | 49 pending_sweeper_jobs_semaphore_(0), |
51 evacuation_(false), | 50 evacuation_(false), |
52 migration_slots_buffer_(NULL), | 51 migration_slots_buffer_(NULL), |
53 heap_(heap), | 52 heap_(heap), |
54 marking_deque_memory_(NULL), | 53 marking_deque_memory_(NULL), |
55 marking_deque_memory_committed_(0), | 54 marking_deque_memory_committed_(0), |
56 code_flusher_(NULL), | 55 code_flusher_(NULL), |
57 have_code_to_deoptimize_(false) { | 56 have_code_to_deoptimize_(false) { |
58 } | 57 } |
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
780 } | 779 } |
781 compacting_ = false; | 780 compacting_ = false; |
782 evacuation_candidates_.Rewind(0); | 781 evacuation_candidates_.Rewind(0); |
783 invalidated_code_.Rewind(0); | 782 invalidated_code_.Rewind(0); |
784 } | 783 } |
785 DCHECK_EQ(0, evacuation_candidates_.length()); | 784 DCHECK_EQ(0, evacuation_candidates_.length()); |
786 } | 785 } |
787 | 786 |
788 | 787 |
789 void MarkCompactCollector::Prepare() { | 788 void MarkCompactCollector::Prepare() { |
790 was_marked_incrementally_ = heap()->incremental_marking()->IsMarking(); | 789 bool was_marked_incrementally = heap()->incremental_marking()->IsMarking(); |
791 | 790 |
792 #ifdef DEBUG | 791 #ifdef DEBUG |
793 DCHECK(state_ == IDLE); | 792 DCHECK(state_ == IDLE); |
794 state_ = PREPARE_GC; | 793 state_ = PREPARE_GC; |
795 #endif | 794 #endif |
796 | 795 |
797 DCHECK(!FLAG_never_compact || !FLAG_always_compact); | 796 DCHECK(!FLAG_never_compact || !FLAG_always_compact); |
798 | 797 |
799 if (sweeping_in_progress()) { | 798 if (sweeping_in_progress()) { |
800 // Instead of waiting we could also abort the sweeper threads here. | 799 // Instead of waiting we could also abort the sweeper threads here. |
801 EnsureSweepingCompleted(); | 800 EnsureSweepingCompleted(); |
802 } | 801 } |
803 | 802 |
804 // Clear marking bits if incremental marking is aborted. | 803 // Clear marking bits if incremental marking is aborted. |
805 if (was_marked_incrementally_ && abort_incremental_marking_) { | 804 if (was_marked_incrementally && abort_incremental_marking_) { |
806 heap()->incremental_marking()->Stop(); | 805 heap()->incremental_marking()->Stop(); |
807 ClearMarkbits(); | 806 ClearMarkbits(); |
808 AbortWeakCollections(); | 807 AbortWeakCollections(); |
809 AbortWeakCells(); | 808 AbortWeakCells(); |
810 AbortCompaction(); | 809 AbortCompaction(); |
811 was_marked_incrementally_ = false; | 810 was_marked_incrementally = false; |
812 } | 811 } |
813 | 812 |
814 // Don't start compaction if we are in the middle of incremental | 813 // Don't start compaction if we are in the middle of incremental |
815 // marking cycle. We did not collect any slots. | 814 // marking cycle. We did not collect any slots. |
816 if (!FLAG_never_compact && !was_marked_incrementally_) { | 815 if (!FLAG_never_compact && !was_marked_incrementally) { |
817 StartCompaction(NON_INCREMENTAL_COMPACTION); | 816 StartCompaction(NON_INCREMENTAL_COMPACTION); |
818 } | 817 } |
819 | 818 |
820 PagedSpaces spaces(heap()); | 819 PagedSpaces spaces(heap()); |
821 for (PagedSpace* space = spaces.next(); space != NULL; | 820 for (PagedSpace* space = spaces.next(); space != NULL; |
822 space = spaces.next()) { | 821 space = spaces.next()) { |
823 space->PrepareForMarkCompact(); | 822 space->PrepareForMarkCompact(); |
824 } | 823 } |
825 | 824 |
826 #ifdef VERIFY_HEAP | 825 #ifdef VERIFY_HEAP |
827 if (!was_marked_incrementally_ && FLAG_verify_heap) { | 826 if (!was_marked_incrementally && FLAG_verify_heap) { |
828 VerifyMarkbitsAreClean(); | 827 VerifyMarkbitsAreClean(); |
829 } | 828 } |
830 #endif | 829 #endif |
831 } | 830 } |
832 | 831 |
833 | 832 |
834 void MarkCompactCollector::Finish() { | 833 void MarkCompactCollector::Finish() { |
835 #ifdef DEBUG | 834 #ifdef DEBUG |
836 DCHECK(state_ == SWEEP_SPACES || state_ == RELOCATE_OBJECTS); | 835 DCHECK(state_ == SWEEP_SPACES || state_ == RELOCATE_OBJECTS); |
837 state_ = IDLE; | 836 state_ = IDLE; |
(...skipping 1392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2230 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK); | 2229 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK); |
2231 double start_time = 0.0; | 2230 double start_time = 0.0; |
2232 if (FLAG_print_cumulative_gc_stat) { | 2231 if (FLAG_print_cumulative_gc_stat) { |
2233 start_time = base::OS::TimeCurrentMillis(); | 2232 start_time = base::OS::TimeCurrentMillis(); |
2234 } | 2233 } |
2235 // The recursive GC marker detects when it is nearing stack overflow, | 2234 // The recursive GC marker detects when it is nearing stack overflow, |
2236 // and switches to a different marking system. JS interrupts interfere | 2235 // and switches to a different marking system. JS interrupts interfere |
2237 // with the C stack limit check. | 2236 // with the C stack limit check. |
2238 PostponeInterruptsScope postpone(isolate()); | 2237 PostponeInterruptsScope postpone(isolate()); |
2239 | 2238 |
2240 IncrementalMarking* incremental_marking = heap_->incremental_marking(); | 2239 IncrementalMarking* incremental_marking = heap_->incremental_marking(); |
Hannes Payer (out of office)
2015/08/07 09:57:31
It would be nicer to move the chunk of code that d
Michael Starzinger
2015/08/07 10:01:54
Acknowledged. Would you be fine with doing that in
Hannes Payer (out of office)
2015/08/07 10:39:23
let's just do it in this one.
| |
2241 if (was_marked_incrementally_) { | 2240 if (incremental_marking->IsMarking()) { |
2242 incremental_marking->Finalize(); | 2241 incremental_marking->Finalize(); |
2243 } else { | 2242 } else { |
2244 // Abort any pending incremental activities e.g. incremental sweeping. | |
2245 incremental_marking->Stop(); | |
Hannes Payer (out of office)
2015/08/07 09:57:31
stop is now not called for non-aborting GCs. We sh
Michael Starzinger
2015/08/07 10:01:54
Done. Yep, my think-o, the try-jobs caught that.
| |
2246 if (marking_deque_.in_use()) { | 2243 if (marking_deque_.in_use()) { |
2247 marking_deque_.Uninitialize(true); | 2244 marking_deque_.Uninitialize(true); |
2248 } | 2245 } |
2249 } | 2246 } |
2250 | 2247 |
2248 DCHECK(incremental_marking->IsStopped()); | |
2249 | |
2251 #ifdef DEBUG | 2250 #ifdef DEBUG |
2252 DCHECK(state_ == PREPARE_GC); | 2251 DCHECK(state_ == PREPARE_GC); |
2253 state_ = MARK_LIVE_OBJECTS; | 2252 state_ = MARK_LIVE_OBJECTS; |
2254 #endif | 2253 #endif |
2255 | 2254 |
2256 EnsureMarkingDequeIsCommittedAndInitialize( | 2255 EnsureMarkingDequeIsCommittedAndInitialize( |
2257 MarkCompactCollector::kMaxMarkingDequeSize); | 2256 MarkCompactCollector::kMaxMarkingDequeSize); |
2258 | 2257 |
2259 PrepareForCodeFlushing(); | 2258 PrepareForCodeFlushing(); |
2260 | 2259 |
(...skipping 1423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3684 | 3683 |
3685 { | 3684 { |
3686 GCTracer::Scope gc_scope(heap()->tracer(), | 3685 GCTracer::Scope gc_scope(heap()->tracer(), |
3687 GCTracer::Scope::MC_UPDATE_POINTERS_TO_EVACUATED); | 3686 GCTracer::Scope::MC_UPDATE_POINTERS_TO_EVACUATED); |
3688 SlotsBuffer::UpdateSlotsRecordedIn(heap_, migration_slots_buffer_); | 3687 SlotsBuffer::UpdateSlotsRecordedIn(heap_, migration_slots_buffer_); |
3689 if (FLAG_trace_fragmentation_verbose) { | 3688 if (FLAG_trace_fragmentation_verbose) { |
3690 PrintF(" migration slots buffer: %d\n", | 3689 PrintF(" migration slots buffer: %d\n", |
3691 SlotsBuffer::SizeOfChain(migration_slots_buffer_)); | 3690 SlotsBuffer::SizeOfChain(migration_slots_buffer_)); |
3692 } | 3691 } |
3693 | 3692 |
3694 if (compacting_ && was_marked_incrementally_) { | 3693 if (compacting_ && heap()->incremental_marking()->IsMarking()) { |
3695 GCTracer::Scope gc_scope(heap()->tracer(), | 3694 GCTracer::Scope gc_scope(heap()->tracer(), |
3696 GCTracer::Scope::MC_RESCAN_LARGE_OBJECTS); | 3695 GCTracer::Scope::MC_RESCAN_LARGE_OBJECTS); |
3697 // It's difficult to filter out slots recorded for large objects. | 3696 // It's difficult to filter out slots recorded for large objects. |
3698 LargeObjectIterator it(heap_->lo_space()); | 3697 LargeObjectIterator it(heap_->lo_space()); |
3699 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 3698 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
3700 // LargeObjectSpace is not swept yet thus we have to skip | 3699 // LargeObjectSpace is not swept yet thus we have to skip |
3701 // dead objects explicitly. | 3700 // dead objects explicitly. |
3702 if (!IsMarked(obj)) continue; | 3701 if (!IsMarked(obj)) continue; |
3703 | 3702 |
3704 Page* p = Page::FromAddress(obj->address()); | 3703 Page* p = Page::FromAddress(obj->address()); |
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4775 SlotsBuffer* buffer = *buffer_address; | 4774 SlotsBuffer* buffer = *buffer_address; |
4776 while (buffer != NULL) { | 4775 while (buffer != NULL) { |
4777 SlotsBuffer* next_buffer = buffer->next(); | 4776 SlotsBuffer* next_buffer = buffer->next(); |
4778 DeallocateBuffer(buffer); | 4777 DeallocateBuffer(buffer); |
4779 buffer = next_buffer; | 4778 buffer = next_buffer; |
4780 } | 4779 } |
4781 *buffer_address = NULL; | 4780 *buffer_address = NULL; |
4782 } | 4781 } |
4783 } // namespace internal | 4782 } // namespace internal |
4784 } // namespace v8 | 4783 } // namespace v8 |
OLD | NEW |