diff options
author | Anna Henningsen <anna@addaleax.net> | 2020-03-28 03:14:06 +0300 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2020-04-10 18:47:16 +0300 |
commit | a173473ba2e76cce679c7d805b091c3a43556983 (patch) | |
tree | a1f1542a52cfdb1892254e768ece61ca43574b40 /src/env.cc | |
parent | 6f9f546406820dc9e233380e061081c9bcd1de0b (diff) |
src: flush V8 interrupts from Environment dtor
This avoids an edge-case memory leak.
Refs: https://github.com/nodejs/node/pull/32523#discussion_r399554491
PR-URL: https://github.com/nodejs/node/pull/32523
Reviewed-By: Matheus Marchini <mat@mmarchini.me>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/env.cc')
-rw-r--r-- | src/env.cc | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/env.cc b/src/env.cc index 5098e8ef0d6..444d9c0368e 100644 --- a/src/env.cc +++ b/src/env.cc @@ -43,11 +43,13 @@ using v8::NewStringType; using v8::Number; using v8::Object; using v8::Private; +using v8::Script; using v8::SnapshotCreator; using v8::StackTrace; using v8::String; using v8::Symbol; using v8::TracingController; +using v8::TryCatch; using v8::Undefined; using v8::Value; using worker::Worker; @@ -435,9 +437,31 @@ Environment::Environment(IsolateData* isolate_data, } Environment::~Environment() { - if (Environment** interrupt_data = interrupt_data_.load()) + if (Environment** interrupt_data = interrupt_data_.load()) { + // There are pending RequestInterrupt() callbacks. Tell them not to run, + // then force V8 to run interrupts by compiling and running an empty script + // so as not to leak memory. *interrupt_data = nullptr; + Isolate::AllowJavascriptExecutionScope allow_js_here(isolate()); + HandleScope handle_scope(isolate()); + TryCatch try_catch(isolate()); + Context::Scope context_scope(context()); + +#ifdef DEBUG + bool consistency_check = false; + isolate()->RequestInterrupt([](Isolate*, void* data) { + *static_cast<bool*>(data) = true; + }, &consistency_check); +#endif + + Local<Script> script; + if (Script::Compile(context(), String::Empty(isolate())).ToLocal(&script)) + USE(script->Run(context())); + + DCHECK(consistency_check); + } + // FreeEnvironment() should have set this. CHECK(is_stopping()); |