Skip to content

Commit 7e75cc1

Browse files
committed
src: flush V8 interrupts from Environment dtor
This avoids an edge-case memory leak. Refs: #32523 (comment)
1 parent aeb354d commit 7e75cc1

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

src/env.cc

+25-1
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,13 @@ using v8::NewStringType;
4242
using v8::Number;
4343
using v8::Object;
4444
using v8::Private;
45+
using v8::Script;
4546
using v8::SnapshotCreator;
4647
using v8::StackTrace;
4748
using v8::String;
4849
using v8::Symbol;
4950
using v8::TracingController;
51+
using v8::TryCatch;
5052
using v8::Undefined;
5153
using v8::Value;
5254
using worker::Worker;
@@ -394,9 +396,31 @@ Environment::Environment(IsolateData* isolate_data,
394396
}
395397

396398
Environment::~Environment() {
397-
if (Environment** interrupt_data = interrupt_data_.load())
399+
if (Environment** interrupt_data = interrupt_data_.load()) {
400+
// There are pending RequestInterrupt() callbacks. Tell them not to run,
401+
// then force V8 to run interrupts by compiling and running an empty script
402+
// so as not to leak memory.
398403
*interrupt_data = nullptr;
399404

405+
Isolate::AllowJavascriptExecutionScope allow_js_here(isolate());
406+
HandleScope handle_scope(isolate());
407+
TryCatch try_catch(isolate());
408+
Context::Scope context_scope(context());
409+
410+
#ifdef DEBUG
411+
bool consistency_check = false;
412+
isolate()->RequestInterrupt([](Isolate*, void* data) {
413+
*static_cast<bool*>(data) = true;
414+
}, &consistency_check);
415+
#endif
416+
417+
Local<Script> script;
418+
if (Script::Compile(context(), String::Empty(isolate())).ToLocal(&script))
419+
USE(script->Run(context()));
420+
421+
DCHECK(consistency_check);
422+
}
423+
400424
// FreeEnvironment() should have set this.
401425
CHECK(is_stopping());
402426

0 commit comments

Comments
 (0)