Skip to content

Commit 2b0315f

Browse files
committed
src: flush V8 interrupts from Environment dtor
This avoids an edge-case memory leak. Refs: nodejs#32523 (comment) PR-URL: nodejs#32523 Reviewed-By: Matheus Marchini <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 83015b0 commit 2b0315f

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

src/env.cc

+24-3
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@ using v8::NewStringType;
4141
using v8::Number;
4242
using v8::Object;
4343
using v8::Private;
44+
using v8::Script;
4445
using v8::SnapshotCreator;
4546
using v8::StackTrace;
4647
using v8::String;
4748
using v8::Symbol;
4849
using v8::TracingController;
50+
using v8::TryCatch;
4951
using v8::Undefined;
5052
using v8::Value;
5153
using worker::Worker;
@@ -412,11 +414,30 @@ Environment::Environment(IsolateData* isolate_data,
412414
}
413415

414416
Environment::~Environment() {
415-
if (Environment** interrupt_data = interrupt_data_.load())
417+
if (Environment** interrupt_data = interrupt_data_.load()) {
418+
// There are pending RequestInterrupt() callbacks. Tell them not to run,
419+
// then force V8 to run interrupts by compiling and running an empty script
420+
// so as not to leak memory.
416421
*interrupt_data = nullptr;
417422

418-
// FreeEnvironment() should have set this.
419-
CHECK(is_stopping());
423+
Isolate::AllowJavascriptExecutionScope allow_js_here(isolate());
424+
HandleScope handle_scope(isolate());
425+
TryCatch try_catch(isolate());
426+
Context::Scope context_scope(context());
427+
428+
#ifdef DEBUG
429+
bool consistency_check = false;
430+
isolate()->RequestInterrupt([](Isolate*, void* data) {
431+
*static_cast<bool*>(data) = true;
432+
}, &consistency_check);
433+
#endif
434+
435+
Local<Script> script;
436+
if (Script::Compile(context(), String::Empty(isolate())).ToLocal(&script))
437+
USE(script->Run(context()));
438+
439+
DCHECK(consistency_check);
440+
}
420441

421442
isolate()->GetHeapProfiler()->RemoveBuildEmbedderGraphCallback(
422443
BuildEmbedderGraph, this);

0 commit comments

Comments
 (0)