summaryrefslogtreecommitdiff
path: root/deps/v8/src/heap/incremental-marking.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/heap/incremental-marking.cc')
-rw-r--r--deps/v8/src/heap/incremental-marking.cc126
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();
}
}
}