Commit 79cd9ce7 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Eagerly free external memory on critical memory pressure.

Currently dead ArrayBuffers with external memory are discovered and
freed in sweeper. If sweeping is slow, it can take long time until
the external memory is freed. This is why wasm currently forces
at least two back-to-back GCs on allocaiton failure.

This patch ensures eager finalization of ArrayBuffers on critical
memory pressure notification.

Bug: v8:7621
Change-Id: I96c75922577388cafab049f5cbce01d636a7b400
Reviewed-on: https://chromium-review.googlesource.com/1224328
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55908}
parent a81bd4c0
......@@ -1232,7 +1232,7 @@ void Heap::CollectAllAvailableGarbage(GarbageCollectionReason gc_reason) {
set_current_gc_flags(kNoGCFlags);
new_space_->Shrink();
UncommitFromSpace();
memory_allocator()->unmapper()->EnsureUnmappingCompleted();
EagerlyFreeExternalMemory();
if (FLAG_trace_duplicate_threshold_kb) {
std::map<int, std::vector<HeapObject*>> objects_by_size;
......@@ -3573,6 +3573,7 @@ void Heap::CollectGarbageOnMemoryPressure() {
CollectAllGarbage(kReduceMemoryFootprintMask | kAbortIncrementalMarkingMask,
GarbageCollectionReason::kMemoryPressure,
kGCCallbackFlagCollectAllAvailableGarbage);
EagerlyFreeExternalMemory();
double end = MonotonicallyIncreasingTimeInMs();
// Estimate how much memory we can free.
......@@ -3619,6 +3620,19 @@ void Heap::MemoryPressureNotification(MemoryPressureLevel level,
}
}
void Heap::EagerlyFreeExternalMemory() {
for (Page* page : *old_space()) {
if (!page->SweepingDone()) {
base::LockGuard<base::Mutex> guard(page->mutex());
if (!page->SweepingDone()) {
ArrayBufferTracker::FreeDead(
page, mark_compact_collector()->non_atomic_marking_state());
}
}
}
memory_allocator()->unmapper()->EnsureUnmappingCompleted();
}
void Heap::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
void* data) {
const size_t kMaxCallbacks = 100;
......
......@@ -1739,6 +1739,8 @@ class Heap {
void CollectGarbageOnMemoryPressure();
void EagerlyFreeExternalMemory();
bool InvokeNearHeapLimitCallback();
void ComputeFastPromotionMode();
......
......@@ -52,8 +52,8 @@ void* TryAllocateBackingStore(WasmMemoryTracker* memory_tracker, Heap* heap,
// Let the WasmMemoryTracker know we are going to reserve a bunch of
// address space.
// Try up to three times; getting rid of dead JSArrayBuffer allocations might
// require two GCs.
// TODO(ulan): Fix this to only require one GC (crbug.com/v8/7621).
// require two GCs because the first GC maybe incremental and may have
// floating garbage.
bool did_retry = false;
for (int trial = 0;; ++trial) {
if (memory_tracker->ReserveAddressSpace(*allocation_length)) break;
......
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