Commit a6a81318 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

heap: Add GC trigger when overshooting global limit

Adds global allocation limit to the general overshoot safety net for triggering
GC. Adds a check to the interrupt that is triggered by the embedder to catch
cases where there's no on-heap allocation.

Bug: chromium:985641, chromium:948807
Change-Id: I3bc0c30f9344b57096db7ebbd8ad8c76808548ba
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1709414Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62827}
parent 224ca74a
......@@ -118,6 +118,10 @@ void LocalEmbedderHeapTracer::StartIncrementalMarkingIfNeeded() {
heap->StartIncrementalMarkingIfAllocationLimitIsReached(
heap->GCFlagsForIncrementalMarking(),
kGCCallbackScheduleIdleGarbageCollection);
if (heap->AllocationLimitOvershotByLargeMargin()) {
heap->FinalizeIncrementalMarkingAtomically(
i::GarbageCollectionReason::kExternalFinalize);
}
}
} // namespace internal
......
......@@ -4654,6 +4654,40 @@ uint64_t Heap::PromotedExternalMemorySize() {
isolate_data->external_memory_at_last_mark_compact_);
}
bool Heap::AllocationLimitOvershotByLargeMargin() {
// This guards against too eager finalization in small heaps.
// The number is chosen based on v8.browsing_mobile on Nexus 7v2.
constexpr size_t kMarginForSmallHeaps = 32u * MB;
const size_t v8_overshoot =
old_generation_allocation_limit_ <
OldGenerationObjectsAndPromotedExternalMemorySize()
? OldGenerationObjectsAndPromotedExternalMemorySize() -
old_generation_allocation_limit_
: 0;
const size_t global_overshoot =
global_allocation_limit_ < GlobalSizeOfObjects()
? GlobalSizeOfObjects() - global_allocation_limit_
: 0;
// Bail out if the V8 and global sizes are still below their respective
// limits.
if (v8_overshoot == 0 && global_overshoot == 0) {
return false;
}
// Overshoot margin is 50% of allocation limit or half-way to the max heap
// with special handling of small heaps.
const size_t v8_margin =
Min(Max(old_generation_allocation_limit_ / 2, kMarginForSmallHeaps),
(max_old_generation_size_ - old_generation_allocation_limit_) / 2);
const size_t global_margin =
Min(Max(global_allocation_limit_ / 2, kMarginForSmallHeaps),
(max_global_memory_size_ - global_allocation_limit_) / 2);
return v8_overshoot >= v8_margin || global_overshoot >= global_margin;
}
bool Heap::ShouldOptimizeForLoadTime() {
return isolate()->rail_mode() == PERFORMANCE_LOAD &&
!AllocationLimitOvershotByLargeMargin() &&
......
......@@ -1177,6 +1177,11 @@ class Heap {
V8_EXPORT_PRIVATE size_t GlobalSizeOfObjects();
// We allow incremental marking to overshoot the V8 and global allocation
// limit for performace reasons. If the overshoot is too large then we are
// more eager to finalize incremental marking.
bool AllocationLimitOvershotByLargeMargin();
// ===========================================================================
// Prologue/epilogue callback methods.========================================
// ===========================================================================
......@@ -1647,26 +1652,6 @@ class Heap {
OldGenerationObjectsAndPromotedExternalMemorySize());
}
// We allow incremental marking to overshoot the allocation limit for
// performace reasons. If the overshoot is too large then we are more
// eager to finalize incremental marking.
inline bool AllocationLimitOvershotByLargeMargin() {
// This guards against too eager finalization in small heaps.
// The number is chosen based on v8.browsing_mobile on Nexus 7v2.
size_t kMarginForSmallHeaps = 32u * MB;
if (old_generation_allocation_limit_ >=
OldGenerationObjectsAndPromotedExternalMemorySize())
return false;
uint64_t overshoot = OldGenerationObjectsAndPromotedExternalMemorySize() -
old_generation_allocation_limit_;
// Overshoot margin is 50% of allocation limit or half-way to the max heap
// with special handling of small heaps.
uint64_t margin =
Min(Max(old_generation_allocation_limit_ / 2, kMarginForSmallHeaps),
(max_old_generation_size_ - old_generation_allocation_limit_) / 2);
return overshoot >= margin;
}
void UpdateTotalGCTime(double duration);
bool MaximumSizeScavenge() { return maximum_size_scavenges_ > 0; }
......
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