Chromium Code Reviews| 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 |