diff options
Diffstat (limited to 'deps/v8/src/heap/incremental-marking.cc')
-rw-r--r-- | deps/v8/src/heap/incremental-marking.cc | 126 |
1 files changed, 71 insertions, 55 deletions
diff --git a/deps/v8/src/heap/incremental-marking.cc b/deps/v8/src/heap/incremental-marking.cc index 4b1d7712a7..b0418686bf 100644 --- a/deps/v8/src/heap/incremental-marking.cc +++ b/deps/v8/src/heap/incremental-marking.cc @@ -32,6 +32,7 @@ IncrementalMarking::IncrementalMarking(Heap* heap) was_activated_(false), black_allocation_(false), finalize_marking_completed_(false), + trace_wrappers_toggle_(false), request_type_(NONE), new_generation_observer_(*this, kAllocatedThreshold), old_generation_observer_(*this, kAllocatedThreshold) {} @@ -129,27 +130,27 @@ static void MarkObjectGreyDoNotEnqueue(Object* obj) { HeapObject* heap_obj = HeapObject::cast(obj); MarkBit mark_bit = ObjectMarking::MarkBitFrom(HeapObject::cast(obj)); if (Marking::IsBlack(mark_bit)) { - MemoryChunk::IncrementLiveBytesFromGC(heap_obj, -heap_obj->Size()); + MemoryChunk::IncrementLiveBytes(heap_obj, -heap_obj->Size()); } Marking::AnyToGrey(mark_bit); } } -void IncrementalMarking::TransferMark(Heap* heap, Address old_start, - Address new_start) { +void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from, + HeapObject* to) { // This is only used when resizing an object. - DCHECK(MemoryChunk::FromAddress(old_start) == - MemoryChunk::FromAddress(new_start)); + DCHECK(MemoryChunk::FromAddress(from->address()) == + MemoryChunk::FromAddress(to->address())); if (!heap->incremental_marking()->IsMarking()) return; // If the mark doesn't move, we don't check the color of the object. // It doesn't matter whether the object is black, since it hasn't changed // size, so the adjustment to the live data count will be zero anyway. - if (old_start == new_start) return; + if (from == to) return; - MarkBit new_mark_bit = ObjectMarking::MarkBitFrom(new_start); - MarkBit old_mark_bit = ObjectMarking::MarkBitFrom(old_start); + MarkBit new_mark_bit = ObjectMarking::MarkBitFrom(to); + MarkBit old_mark_bit = ObjectMarking::MarkBitFrom(from); #ifdef DEBUG Marking::ObjectColor old_color = Marking::Color(old_mark_bit); @@ -161,8 +162,7 @@ void IncrementalMarking::TransferMark(Heap* heap, Address old_start, return; } else if (Marking::IsGrey(old_mark_bit)) { Marking::GreyToWhite(old_mark_bit); - heap->incremental_marking()->WhiteToGreyAndPush( - HeapObject::FromAddress(new_start), new_mark_bit); + heap->incremental_marking()->WhiteToGreyAndPush(to, new_mark_bit); heap->incremental_marking()->RestartIfNotMarking(); } @@ -268,7 +268,7 @@ class IncrementalMarkingMarkingVisitor MarkBit mark_bit = ObjectMarking::MarkBitFrom(heap_object); if (Marking::IsWhite(mark_bit)) { Marking::MarkBlack(mark_bit); - MemoryChunk::IncrementLiveBytesFromGC(heap_object, heap_object->Size()); + MemoryChunk::IncrementLiveBytes(heap_object, heap_object->Size()); return true; } return false; @@ -524,10 +524,10 @@ void IncrementalMarking::StartMarking() { state_ = MARKING; - if (heap_->UsingEmbedderHeapTracer()) { + { TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_INCREMENTAL_WRAPPER_PROLOGUE); - heap_->embedder_heap_tracer()->TracePrologue(); + heap_->local_embedder_heap_tracer()->TracePrologue(); } RecordWriteStub::Mode mode = is_compacting_ @@ -603,7 +603,7 @@ void IncrementalMarking::MarkObjectGroups() { TRACE_GC(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL_FINALIZE_OBJECT_GROUPING); - DCHECK(!heap_->UsingEmbedderHeapTracer()); + DCHECK(!heap_->local_embedder_heap_tracer()->InUse()); DCHECK(!finalize_marking_completed_); DCHECK(IsMarking()); @@ -736,7 +736,8 @@ void IncrementalMarking::FinalizeIncrementally() { // 4) Remove weak cell with live values from the list of weak cells, they // do not need processing during GC. MarkRoots(); - if (!heap_->UsingEmbedderHeapTracer()) { + if (!heap_->local_embedder_heap_tracer()->InUse() && + FLAG_object_grouping_in_incremental_finalization) { MarkObjectGroups(); } if (incremental_marking_finalization_rounds_ == 0) { @@ -750,7 +751,8 @@ void IncrementalMarking::FinalizeIncrementally() { abs(old_marking_deque_top - heap_->mark_compact_collector()->marking_deque()->top()); - marking_progress += static_cast<int>(heap_->wrappers_to_trace()); + marking_progress += static_cast<int>( + heap_->local_embedder_heap_tracer()->NumberOfCachedWrappersToTrace()); double end = heap_->MonotonicallyIncreasingTimeInMs(); double delta = end - start; @@ -806,8 +808,7 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { // them. if (map_word.IsForwardingAddress()) { HeapObject* dest = map_word.ToForwardingAddress(); - if (Marking::IsBlack(ObjectMarking::MarkBitFrom(dest->address()))) - continue; + if (Marking::IsBlack(ObjectMarking::MarkBitFrom(dest))) continue; array[new_top] = dest; new_top = ((new_top + 1) & mask); DCHECK(new_top != marking_deque->bottom()); @@ -864,7 +865,7 @@ void IncrementalMarking::MarkBlack(HeapObject* obj, int size) { MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); if (Marking::IsBlack(mark_bit)) return; Marking::GreyToBlack(mark_bit); - MemoryChunk::IncrementLiveBytesFromGC(obj, size); + MemoryChunk::IncrementLiveBytes(obj, size); } intptr_t IncrementalMarking::ProcessMarkingDeque( @@ -890,6 +891,11 @@ intptr_t IncrementalMarking::ProcessMarkingDeque( VisitObject(map, obj, size); bytes_processed += size - unscanned_bytes_of_large_object_; } + // Report all found wrappers to the embedder. This is necessary as the + // embedder could potentially invalidate wrappers as soon as V8 is done + // with its incremental marking processing. Any cached wrappers could + // result in broken pointers at this point. + heap_->local_embedder_heap_tracer()->RegisterWrappersWithRemoteTracer(); return bytes_processed; } @@ -933,7 +939,7 @@ void IncrementalMarking::Hurry() { MarkBit mark_bit = ObjectMarking::MarkBitFrom(cache); if (Marking::IsGrey(mark_bit)) { Marking::GreyToBlack(mark_bit); - MemoryChunk::IncrementLiveBytesFromGC(cache, cache->Size()); + MemoryChunk::IncrementLiveBytes(cache, cache->Size()); } } context = Context::cast(context)->next_context_link(); @@ -1026,15 +1032,40 @@ void IncrementalMarking::Epilogue() { double IncrementalMarking::AdvanceIncrementalMarking( double deadline_in_ms, CompletionAction completion_action, ForceCompletionAction force_completion, StepOrigin step_origin) { + HistogramTimerScope incremental_marking_scope( + heap_->isolate()->counters()->gc_incremental_marking()); + TRACE_EVENT0("v8", "V8.GCIncrementalMarking"); + TRACE_GC(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL); DCHECK(!IsStopped()); + DCHECK_EQ( + 0, heap_->local_embedder_heap_tracer()->NumberOfCachedWrappersToTrace()); double remaining_time_in_ms = 0.0; intptr_t step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( kStepSizeInMs, heap()->tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); + const bool incremental_wrapper_tracing = + state_ == MARKING && FLAG_incremental_marking_wrappers && + heap_->local_embedder_heap_tracer()->InUse(); do { - Step(step_size_in_bytes, completion_action, force_completion, step_origin); + if (incremental_wrapper_tracing && trace_wrappers_toggle_) { + TRACE_GC(heap()->tracer(), + GCTracer::Scope::MC_INCREMENTAL_WRAPPER_TRACING); + const double wrapper_deadline = + heap_->MonotonicallyIncreasingTimeInMs() + kStepSizeInMs; + if (!heap_->local_embedder_heap_tracer() + ->ShouldFinalizeIncrementalMarking()) { + heap_->local_embedder_heap_tracer()->Trace( + wrapper_deadline, EmbedderHeapTracer::AdvanceTracingActions( + EmbedderHeapTracer::ForceCompletionAction:: + DO_NOT_FORCE_COMPLETION)); + } + } else { + Step(step_size_in_bytes, completion_action, force_completion, + step_origin); + } + trace_wrappers_toggle_ = !trace_wrappers_toggle_; remaining_time_in_ms = deadline_in_ms - heap()->MonotonicallyIncreasingTimeInMs(); } while (remaining_time_in_ms >= kStepSizeInMs && !IsComplete() && @@ -1109,6 +1140,10 @@ void IncrementalMarking::AdvanceIncrementalMarkingOnAllocation() { bytes_marked_ahead_of_schedule_ -= bytes_to_process; bytes_processed = bytes_to_process; } else { + HistogramTimerScope incremental_marking_scope( + heap_->isolate()->counters()->gc_incremental_marking()); + TRACE_EVENT0("v8", "V8.GCIncrementalMarking"); + TRACE_GC(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL); bytes_processed = Step(bytes_to_process, GC_VIA_STACK_GUARD, FORCE_COMPLETION, StepOrigin::kV8); } @@ -1120,10 +1155,6 @@ size_t IncrementalMarking::Step(size_t bytes_to_process, CompletionAction action, ForceCompletionAction completion, StepOrigin step_origin) { - HistogramTimerScope incremental_marking_scope( - heap_->isolate()->counters()->gc_incremental_marking()); - TRACE_EVENT0("v8", "V8.GCIncrementalMarking"); - TRACE_GC(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL); double start = heap_->MonotonicallyIncreasingTimeInMs(); if (state_ == SWEEPING) { @@ -1133,41 +1164,26 @@ size_t IncrementalMarking::Step(size_t bytes_to_process, size_t bytes_processed = 0; if (state_ == MARKING) { - const bool incremental_wrapper_tracing = - FLAG_incremental_marking_wrappers && heap_->UsingEmbedderHeapTracer(); - const bool process_wrappers = - incremental_wrapper_tracing && - (heap_->RequiresImmediateWrapperProcessing() || - heap_->mark_compact_collector()->marking_deque()->IsEmpty()); - bool wrapper_work_left = incremental_wrapper_tracing; - if (!process_wrappers) { - bytes_processed = ProcessMarkingDeque(bytes_to_process); - if (step_origin == StepOrigin::kTask) { - bytes_marked_ahead_of_schedule_ += bytes_processed; - } - } else { - const double wrapper_deadline = - heap_->MonotonicallyIncreasingTimeInMs() + kStepSizeInMs; - TRACE_GC(heap()->tracer(), - GCTracer::Scope::MC_INCREMENTAL_WRAPPER_TRACING); - heap_->RegisterWrappersWithEmbedderHeapTracer(); - wrapper_work_left = heap_->embedder_heap_tracer()->AdvanceTracing( - wrapper_deadline, EmbedderHeapTracer::AdvanceTracingActions( - EmbedderHeapTracer::ForceCompletionAction:: - DO_NOT_FORCE_COMPLETION)); + bytes_processed = ProcessMarkingDeque(bytes_to_process); + if (step_origin == StepOrigin::kTask) { + bytes_marked_ahead_of_schedule_ += bytes_processed; } - if (heap_->mark_compact_collector()->marking_deque()->IsEmpty() && - !wrapper_work_left) { - if (completion == FORCE_COMPLETION || - IsIdleMarkingDelayCounterLimitReached()) { - if (!finalize_marking_completed_) { - FinalizeMarking(action); + if (heap_->mark_compact_collector()->marking_deque()->IsEmpty()) { + if (heap_->local_embedder_heap_tracer() + ->ShouldFinalizeIncrementalMarking()) { + if (completion == FORCE_COMPLETION || + IsIdleMarkingDelayCounterLimitReached()) { + if (!finalize_marking_completed_) { + FinalizeMarking(action); + } else { + MarkingComplete(action); + } } else { - MarkingComplete(action); + IncrementIdleMarkingDelayCounter(); } } else { - IncrementIdleMarkingDelayCounter(); + heap_->local_embedder_heap_tracer()->NotifyV8MarkingDequeWasEmpty(); } } } |