Commit b125c943 authored by Michael Lippautz's avatar Michael Lippautz Committed by V8 LUCI CQ

Reland "Reland "heap: Fix initial GC configuration for C++-only heaps""

This is a reland of 1f0b0ed0

No actual code has changed in the relands.

The change was reverted due to triggering flaky failures in
WebMediaPlayerImplTest which was not set up properly. The test setup
has been fixed in https://crrev.com/c/3025796.

Original change's description:
> Reland "heap: Fix initial GC configuration for C++-only heaps"
>
> This is a reland of 7ef67b2e
>
> Manually checked that the CL was not the culprit breaking
>   media_blink_unittests --gtest_filter=WebMediaPlayerImplTest.MemDumpReporting
>
> Original change's description:
> > heap: Fix initial GC configuration for C++-only heaps
> >
> > Heaps in V8 start with a large limit that is shrunk upon young
> > generation GCs, based on some liveness estimate. This provides best
> > throughput during startup while at the same time finding a reasonable
> > first limit.
> >
> > For C++ (embedder memory) there is no estimate which is why it was
> > piggy-backing on V8. This breaks in scenarios where no JS memory is
> > allocated.
> >
> > In this fix we start a memory reducer after embedder memory has hit
> > the activation threshold if no GC happened so far. As soon as a single
> > Scavenger has happened, we leave it up to the JS estimate to figure
> > out a limit. Memory reducing GCs will then find a regular limit based
> > on the initial live size.
> >
> > Drive-by: Give embedders the same activiation threshold of 8MB as JS.
> >
> > Bug: chromium:1217076
> > Change-Id: I8469696002ac2af8d75d6b47def062d2608387a1
> > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2944935
> > Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
> > Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#75012}
>
> Bug: chromium:1217076
> Change-Id: I482d8525379e33095834d5b41be8bb49bdd8a5d4
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2949094
> Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
> Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
> Auto-Submit: Michael Lippautz <mlippautz@chromium.org>
> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#75048}

Bug: chromium:1217076
Change-Id: If920d6b2c54a0c9d67e55e276421e4694eb1414e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2960218Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75894}
parent 8439314d
......@@ -1941,16 +1941,28 @@ void Heap::CompleteSweepingFull() {
void Heap::StartIncrementalMarkingIfAllocationLimitIsReached(
int gc_flags, const GCCallbackFlags gc_callback_flags) {
if (incremental_marking()->IsStopped()) {
IncrementalMarkingLimit reached_limit = IncrementalMarkingLimitReached();
if (reached_limit == IncrementalMarkingLimit::kSoftLimit) {
incremental_marking()->incremental_marking_job()->ScheduleTask(this);
} else if (reached_limit == IncrementalMarkingLimit::kHardLimit) {
StartIncrementalMarking(
gc_flags,
OldGenerationSpaceAvailable() <= NewSpaceCapacity()
? GarbageCollectionReason::kAllocationLimit
: GarbageCollectionReason::kGlobalAllocationLimit,
gc_callback_flags);
switch (IncrementalMarkingLimitReached()) {
case IncrementalMarkingLimit::kHardLimit:
StartIncrementalMarking(
gc_flags,
OldGenerationSpaceAvailable() <= NewSpaceCapacity()
? GarbageCollectionReason::kAllocationLimit
: GarbageCollectionReason::kGlobalAllocationLimit,
gc_callback_flags);
break;
case IncrementalMarkingLimit::kSoftLimit:
incremental_marking()->incremental_marking_job()->ScheduleTask(this);
break;
case IncrementalMarkingLimit::kFallbackForEmbedderLimit:
// This is a fallback case where no appropriate limits have been
// configured yet.
MemoryReducer::Event event;
event.type = MemoryReducer::kPossibleGarbage;
event.time_ms = MonotonicallyIncreasingTimeInMs();
memory_reducer()->NotifyPossibleGarbage(event);
break;
case IncrementalMarkingLimit::kNoLimit:
break;
}
}
}
......@@ -5148,12 +5160,14 @@ size_t Heap::OldGenerationSizeOfObjects() {
return total + lo_space_->SizeOfObjects() + code_lo_space_->SizeOfObjects();
}
size_t Heap::EmbedderSizeOfObjects() const {
return local_embedder_heap_tracer()
? local_embedder_heap_tracer()->used_size()
: 0;
}
size_t Heap::GlobalSizeOfObjects() {
const size_t on_heap_size = OldGenerationSizeOfObjects();
const size_t embedder_size = local_embedder_heap_tracer()
? local_embedder_heap_tracer()->used_size()
: 0;
return on_heap_size + embedder_size;
return OldGenerationSizeOfObjects() + EmbedderSizeOfObjects();
}
uint64_t Heap::AllocatedExternalMemorySinceMarkCompact() {
......@@ -5295,11 +5309,13 @@ double Heap::PercentToGlobalMemoryLimit() {
return total_bytes > 0 ? (current_bytes / total_bytes) * 100.0 : 0;
}
// This function returns either kNoLimit, kSoftLimit, or kHardLimit.
// The kNoLimit means that either incremental marking is disabled or it is too
// - kNoLimit means that either incremental marking is disabled or it is too
// early to start incremental marking.
// The kSoftLimit means that incremental marking should be started soon.
// The kHardLimit means that incremental marking should be started immediately.
// - kSoftLimit means that incremental marking should be started soon.
// - kHardLimit means that incremental marking should be started immediately.
// - kFallbackForEmbedderLimit means that incremental marking should be
// started as soon as the embedder does not allocate with high throughput
// anymore.
Heap::IncrementalMarkingLimit Heap::IncrementalMarkingLimitReached() {
// Code using an AlwaysAllocateScope assumes that the GC state does not
// change; that implies that no marking steps must be performed.
......@@ -5364,6 +5380,15 @@ Heap::IncrementalMarkingLimit Heap::IncrementalMarkingLimitReached() {
if (old_generation_space_available > NewSpaceCapacity() &&
(!global_memory_available ||
global_memory_available > NewSpaceCapacity())) {
if (local_embedder_heap_tracer()->InUse() &&
!old_generation_size_configured_ && gc_count_ == 0) {
// At this point the embedder memory is above the activation
// threshold. No GC happened so far and it's thus unlikely to get a
// configured heap any time soon. Start a memory reducer in this case
// which will wait until the allocation rate is low to trigger garbage
// collection.
return IncrementalMarkingLimit::kFallbackForEmbedderLimit;
}
return IncrementalMarkingLimit::kNoLimit;
}
if (ShouldOptimizeForMemoryUsage()) {
......
......@@ -1471,6 +1471,10 @@ class Heap {
// Excludes external memory held by those objects.
V8_EXPORT_PRIVATE size_t OldGenerationSizeOfObjects();
// Returns the size of objects held by the EmbedderHeapTracer.
V8_EXPORT_PRIVATE size_t EmbedderSizeOfObjects() const;
// Returns the global size of objects (embedder + V8 non-new spaces).
V8_EXPORT_PRIVATE size_t GlobalSizeOfObjects();
// We allow incremental marking to overshoot the V8 and global allocation
......@@ -2052,7 +2056,12 @@ class Heap {
double PercentToOldGenerationLimit();
double PercentToGlobalMemoryLimit();
enum class IncrementalMarkingLimit { kNoLimit, kSoftLimit, kHardLimit };
enum class IncrementalMarkingLimit {
kNoLimit,
kSoftLimit,
kHardLimit,
kFallbackForEmbedderLimit
};
IncrementalMarkingLimit IncrementalMarkingLimitReached();
bool ShouldStressCompaction() const;
......
......@@ -159,7 +159,7 @@ bool IncrementalMarking::CanBeActivated() {
bool IncrementalMarking::IsBelowActivationThresholds() const {
return heap_->OldGenerationSizeOfObjects() <= kV8ActivationThreshold &&
heap_->GlobalSizeOfObjects() <= kGlobalActivationThreshold;
heap_->EmbedderSizeOfObjects() <= kEmbedderActivationThreshold;
}
void IncrementalMarking::Start(GarbageCollectionReason gc_reason) {
......
......@@ -75,10 +75,10 @@ class V8_EXPORT_PRIVATE IncrementalMarking final {
#ifndef DEBUG
static constexpr size_t kV8ActivationThreshold = 8 * MB;
static constexpr size_t kGlobalActivationThreshold = 16 * MB;
static constexpr size_t kEmbedderActivationThreshold = 8 * MB;
#else
static constexpr size_t kV8ActivationThreshold = 0;
static constexpr size_t kGlobalActivationThreshold = 0;
static constexpr size_t kEmbedderActivationThreshold = 0;
#endif
#ifdef V8_ATOMIC_MARKING_STATE
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment