[wasm] Run GC if page allocation fails, then retry

This adds another instance of the "if allocation fails, run GC then
retry" pattern, this time for making the actual memory reservation for
wasm memory.

R=mlippautz@chromium.org

Bug: chromium:883639, v8:7872, v8:8158
Change-Id: I40ed020ed2bbc253c4bbcbe51e3e9f5a0278d7a1
Reviewed-on: https://chromium-review.googlesource.com/1227117
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55936}
This commit is contained in:
Clemens Hammacher 2018-09-17 09:28:56 +02:00 committed by Commit Bot
parent b8e554d53c
commit 7784603687

View File

@ -893,27 +893,37 @@ std::unique_ptr<NativeModule> WasmCodeManager::NewNativeModule(
->MemoryPressureNotification(MemoryPressureLevel::kCritical); ->MemoryPressureNotification(MemoryPressureLevel::kCritical);
} }
VirtualMemory mem;
// If the code must be contiguous, reserve enough address space up front. // If the code must be contiguous, reserve enough address space up front.
size_t vmem_size = kRequiresCodeRange ? kMaxWasmCodeMemory : memory_estimate; size_t vmem_size = kRequiresCodeRange ? kMaxWasmCodeMemory : memory_estimate;
TryAllocate(vmem_size, &mem); // Try up to three times; getting rid of dead JSArrayBuffer allocations might
if (mem.IsReserved()) { // require two GCs because the first GC maybe incremental and may have
Address start = mem.address(); // floating garbage.
size_t size = mem.size(); static constexpr int kAllocationRetries = 2;
Address end = mem.end(); VirtualMemory mem;
std::unique_ptr<NativeModule> ret( for (int retries = 0;; ++retries) {
new NativeModule(isolate, enabled, can_request_more, std::move(mem), TryAllocate(vmem_size, &mem);
this, std::move(module), env)); if (mem.IsReserved()) break;
TRACE_HEAP("New NativeModule %p: Mem: %" PRIuPTR ",+%zu\n", this, start, if (retries == kAllocationRetries) {
size); V8::FatalProcessOutOfMemory(isolate, "WasmCodeManager::NewNativeModule");
base::LockGuard<base::Mutex> lock(&native_modules_mutex_); return nullptr;
AssignRanges(start, end, ret.get()); }
native_modules_.emplace(ret.get()); // Run one GC, then try the allocation again.
return ret; isolate->heap()->MemoryPressureNotification(MemoryPressureLevel::kCritical,
true);
} }
V8::FatalProcessOutOfMemory(isolate, "WasmCodeManager::NewNativeModule"); Address start = mem.address();
return nullptr; size_t size = mem.size();
Address end = mem.end();
std::unique_ptr<NativeModule> ret(
new NativeModule(isolate, enabled, can_request_more, std::move(mem), this,
std::move(module), env));
TRACE_HEAP("New NativeModule %p: Mem: %" PRIuPTR ",+%zu\n", this, start,
size);
base::LockGuard<base::Mutex> lock(&native_modules_mutex_);
AssignRanges(start, end, ret.get());
native_modules_.emplace(ret.get());
return ret;
} }
bool NativeModule::SetExecutable(bool executable) { bool NativeModule::SetExecutable(bool executable) {