Skip to content

Commit 9238afb

Browse files
kbabbittV8 LUCI CQ
authored andcommitted
Allow embedder to set global OOM handler
Embedders can currently specify a callback for OOM errors during Isolate initialization. However, there are cases where an OOM error can be thrown in a context where we don't have access to an Isolate, for example on a task posted to a worker thread. This CL introduces an initialization API to allow the embedder to specify a process-wide OOM callback. Bug: chromium:614440 Change-Id: I326753d80767679f677e85104d9edeef92e19086 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3561916 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Kevin Babbitt <kbabbitt@microsoft.com> Cr-Commit-Position: refs/heads/main@{#79832}
1 parent 89f8435 commit 9238afb

2 files changed

Lines changed: 24 additions & 6 deletions

File tree

‎include/v8-initialization.h‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
#include <stddef.h>
99
#include <stdint.h>
1010

11-
#include "v8-internal.h" // NOLINT(build/include_directory)
12-
#include "v8-isolate.h" // NOLINT(build/include_directory)
13-
#include "v8-platform.h" // NOLINT(build/include_directory)
14-
#include "v8config.h" // NOLINT(build/include_directory)
11+
#include "v8-callbacks.h" // NOLINT(build/include_directory)
12+
#include "v8-internal.h" // NOLINT(build/include_directory)
13+
#include "v8-isolate.h" // NOLINT(build/include_directory)
14+
#include "v8-platform.h" // NOLINT(build/include_directory)
15+
#include "v8config.h" // NOLINT(build/include_directory)
1516

1617
// We reserve the V8_* prefix for macros defined in V8 public API and
1718
// assume there are no name conflicts with the embedder's code.
@@ -275,6 +276,14 @@ class V8_EXPORT V8 {
275276
UnhandledExceptionCallback unhandled_exception_callback);
276277
#endif
277278

279+
/**
280+
* Allows the host application to provide a callback that will be called when
281+
* v8 has encountered a fatal failure to allocate memory and is about to
282+
* terminate.
283+
*/
284+
285+
static void SetFatalMemoryErrorCallback(OOMErrorCallback oom_error_callback);
286+
278287
/**
279288
* Get statistics about the shared memory usage.
280289
*/

‎src/api/api.cc‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@
172172

173173
namespace v8 {
174174

175+
static OOMErrorCallback g_oom_error_callback = nullptr;
176+
175177
static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
176178
i::Handle<i::Script> script) {
177179
i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate);
@@ -228,8 +230,9 @@ void i::V8::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location,
228230
memset(last_few_messages, 0x0BADC0DE, Heap::kTraceRingBufferSize + 1);
229231
memset(js_stacktrace, 0x0BADC0DE, Heap::kStacktraceBufferSize + 1);
230232
memset(&heap_stats, 0xBADC0DE, sizeof(heap_stats));
231-
// Note that the embedder's oom handler is also not available and therefore
232-
// won't be called in this case. We just crash.
233+
// Give the embedder a chance to handle the condition. If it doesn't,
234+
// just crash.
235+
if (g_oom_error_callback) g_oom_error_callback(location, is_heap_oom);
233236
FATAL("Fatal process out of memory: %s", location);
234237
UNREACHABLE();
235238
}
@@ -304,6 +307,7 @@ void i::V8::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location,
304307
}
305308
}
306309
Utils::ReportOOMFailure(isolate, location, is_heap_oom);
310+
if (g_oom_error_callback) g_oom_error_callback(location, is_heap_oom);
307311
// If the fatal error handler returns, we stop execution.
308312
FATAL("API fatal error handler returned after process out of memory");
309313
}
@@ -6106,6 +6110,11 @@ void V8::SetUnhandledExceptionCallback(
61066110
}
61076111
#endif // V8_OS_WIN
61086112

6113+
void v8::V8::SetFatalMemoryErrorCallback(
6114+
v8::OOMErrorCallback oom_error_callback) {
6115+
g_oom_error_callback = oom_error_callback;
6116+
}
6117+
61096118
void v8::V8::SetEntropySource(EntropySource entropy_source) {
61106119
base::RandomNumberGenerator::SetEntropySource(entropy_source);
61116120
}

0 commit comments

Comments
 (0)