summaryrefslogtreecommitdiff
path: root/src/node_contextify.cc
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2019-07-20 19:35:24 +0200
committerRich Trott <rtrott@gmail.com>2019-07-22 11:55:25 -0700
commit89e4b36e62978f54b2e33b4bce8197072dbe8af1 (patch)
treedc43dc3491aac3ddc3977612d4fb8f772e7a9592 /src/node_contextify.cc
parent31178994140676417a4ee7d30e7f7e57e73c6873 (diff)
downloadandroid-node-v8-89e4b36e62978f54b2e33b4bce8197072dbe8af1.tar.gz
android-node-v8-89e4b36e62978f54b2e33b4bce8197072dbe8af1.tar.bz2
android-node-v8-89e4b36e62978f54b2e33b4bce8197072dbe8af1.zip
src: make `CompiledFnEntry` a `BaseObject`
In particular: - Move the class definition to the relevant header file, i.e. `node_contextify.h`. - Make sure that class instances are destroyed on `Environment` teardown. - Make instances of the key object traceable in heap dumps. This is particularly relevant here because our C++ script → map key mapping could introduce memory leaks when the import function metadata refers back to the script in some way. Refs: https://github.com/nodejs/node/pull/28671 PR-URL: https://github.com/nodejs/node/pull/28782 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'src/node_contextify.cc')
-rw-r--r--src/node_contextify.cc37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/node_contextify.cc b/src/node_contextify.cc
index 6559e813c9..69c110d6be 100644
--- a/src/node_contextify.cc
+++ b/src/node_contextify.cc
@@ -1124,9 +1124,13 @@ void ContextifyContext::CompileFunction(
}
Local<Function> fn = maybe_fn.ToLocalChecked();
- CompiledFnEntry* entry = new CompiledFnEntry(env, id, script);
+ Local<Object> cache_key;
+ if (!env->compiled_fn_entry_template()->NewInstance(
+ context).ToLocal(&cache_key)) {
+ return;
+ }
+ CompiledFnEntry* entry = new CompiledFnEntry(env, cache_key, id, script);
env->id_to_function_map.emplace(id, entry);
- Local<Object> cache_key = entry->cache_key.Get(isolate);
Local<Object> result = Object::New(isolate);
if (result->Set(parsing_context, env->function_string(), fn).IsNothing())
@@ -1162,6 +1166,27 @@ void ContextifyContext::CompileFunction(
args.GetReturnValue().Set(result);
}
+void CompiledFnEntry::WeakCallback(
+ const WeakCallbackInfo<CompiledFnEntry>& data) {
+ CompiledFnEntry* entry = data.GetParameter();
+ delete entry;
+}
+
+CompiledFnEntry::CompiledFnEntry(Environment* env,
+ Local<Object> object,
+ uint32_t id,
+ Local<ScriptOrModule> script)
+ : BaseObject(env, object),
+ id_(id),
+ script_(env->isolate(), script) {
+ script_.SetWeak(this, WeakCallback, v8::WeakCallbackType::kParameter);
+}
+
+CompiledFnEntry::~CompiledFnEntry() {
+ env()->id_to_function_map.erase(id_);
+ script_.ClearWeak();
+}
+
static void StartSigintWatchdog(const FunctionCallbackInfo<Value>& args) {
int ret = SigintWatchdogHelper::GetInstance()->Start();
args.GetReturnValue().Set(ret == 0);
@@ -1190,6 +1215,14 @@ void Initialize(Local<Object> target,
// Used in tests.
env->SetMethodNoSideEffect(
target, "watchdogHasPendingSigint", WatchdogHasPendingSigint);
+
+ {
+ Local<FunctionTemplate> tpl = FunctionTemplate::New(env->isolate());
+ tpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "CompiledFnEntry"));
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
+
+ env->set_compiled_fn_entry_template(tpl->InstanceTemplate());
+ }
}
} // namespace contextify