diff options
author | Anna Henningsen <anna@addaleax.net> | 2019-07-20 19:35:24 +0200 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2019-07-22 11:55:25 -0700 |
commit | 89e4b36e62978f54b2e33b4bce8197072dbe8af1 (patch) | |
tree | dc43dc3491aac3ddc3977612d4fb8f772e7a9592 /src/node_contextify.cc | |
parent | 31178994140676417a4ee7d30e7f7e57e73c6873 (diff) | |
download | android-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.cc | 37 |
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 |