Skip to content

Commit 90d14df

Browse files
addaleaxjasnell
authored andcommitted
src: minor c++ refactors to module_wrap
- Move `module_map` to `Environment` instead of having it be global state - `std::map` → `std::unordered_map` - Remove one level of indirection for the map values - Clean up empty vectors in `module_map` - Call `Reset()` on all persistent handles in `resolve_cache_` - Add a missing `HandleScope` to `ModuleWrap::~ModuleWrap()` PR-URL: #15515 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com>
1 parent 17d8dfe commit 90d14df

File tree

3 files changed

+31
-32
lines changed

3 files changed

+31
-32
lines changed

src/env.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ namespace performance {
5252
struct performance_state;
5353
}
5454

55+
namespace loader {
56+
class ModuleWrap;
57+
}
58+
5559
// Pick an index that's hopefully out of the way when we're embedded inside
5660
// another application. Performance-wise or memory-wise it doesn't matter:
5761
// Context::SetAlignedPointerInEmbedderData() is backed by a FixedArray,
@@ -586,6 +590,8 @@ class Environment {
586590
// List of id's that have been destroyed and need the destroy() cb called.
587591
inline std::vector<double>* destroy_ids_list();
588592

593+
std::unordered_multimap<int, loader::ModuleWrap*> module_map;
594+
589595
inline double* heap_statistics_buffer() const;
590596
inline void set_heap_statistics_buffer(double* pointer);
591597

src/module_wrap.cc

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ using v8::EscapableHandleScope;
1818
using v8::Function;
1919
using v8::FunctionCallbackInfo;
2020
using v8::FunctionTemplate;
21+
using v8::HandleScope;
2122
using v8::Integer;
2223
using v8::IntegrityLevel;
2324
using v8::Isolate;
@@ -26,32 +27,31 @@ using v8::Local;
2627
using v8::MaybeLocal;
2728
using v8::Module;
2829
using v8::Object;
29-
using v8::Persistent;
3030
using v8::Promise;
3131
using v8::ScriptCompiler;
3232
using v8::ScriptOrigin;
3333
using v8::String;
3434
using v8::Value;
3535

36-
static const char* EXTENSIONS[] = {".mjs", ".js", ".json", ".node"};
37-
std::map<int, std::vector<ModuleWrap*>*> ModuleWrap::module_map_;
36+
static const char* const EXTENSIONS[] = {".mjs", ".js", ".json", ".node"};
3837

3938
ModuleWrap::ModuleWrap(Environment* env,
4039
Local<Object> object,
4140
Local<Module> module,
4241
Local<String> url) : BaseObject(env, object) {
43-
Isolate* iso = Isolate::GetCurrent();
44-
module_.Reset(iso, module);
45-
url_.Reset(iso, url);
42+
module_.Reset(env->isolate(), module);
43+
url_.Reset(env->isolate(), url);
4644
}
4745

4846
ModuleWrap::~ModuleWrap() {
49-
Local<Module> module = module_.Get(Isolate::GetCurrent());
50-
std::vector<ModuleWrap*>* same_hash = module_map_[module->GetIdentityHash()];
51-
auto it = std::find(same_hash->begin(), same_hash->end(), this);
52-
53-
if (it != same_hash->end()) {
54-
same_hash->erase(it);
47+
HandleScope scope(env()->isolate());
48+
Local<Module> module = module_.Get(env()->isolate());
49+
auto range = env()->module_map.equal_range(module->GetIdentityHash());
50+
for (auto it = range.first; it != range.second; ++it) {
51+
if (it->second == this) {
52+
env()->module_map.erase(it);
53+
break;
54+
}
5555
}
5656

5757
module_.Reset();
@@ -119,12 +119,7 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
119119
ModuleWrap* obj =
120120
new ModuleWrap(Environment::GetCurrent(ctx), that, mod, url);
121121

122-
if (ModuleWrap::module_map_.count(mod->GetIdentityHash()) == 0) {
123-
ModuleWrap::module_map_[mod->GetIdentityHash()] =
124-
new std::vector<ModuleWrap*>();
125-
}
126-
127-
ModuleWrap::module_map_[mod->GetIdentityHash()]->push_back(obj);
122+
env->module_map.emplace(mod->GetIdentityHash(), obj);
128123
Wrap(that, obj);
129124

130125
that->SetIntegrityLevel(ctx, IntegrityLevel::kFrozen);
@@ -170,8 +165,7 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
170165
env->ThrowError("linking error, expected resolver to return a promise");
171166
}
172167
Local<Promise> resolve_promise = resolve_return_value.As<Promise>();
173-
obj->resolve_cache_[specifier_std] = new Persistent<Promise>();
174-
obj->resolve_cache_[specifier_std]->Reset(iso, resolve_promise);
168+
obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
175169
}
176170

177171
args.GetReturnValue().Set(handle_scope.Escape(that));
@@ -187,6 +181,8 @@ void ModuleWrap::Instantiate(const FunctionCallbackInfo<Value>& args) {
187181
bool ok = mod->Instantiate(ctx, ModuleWrap::ResolveCallback);
188182

189183
// clear resolve cache on instantiate
184+
for (auto& entry : obj->resolve_cache_)
185+
entry.second.Reset();
190186
obj->resolve_cache_.clear();
191187

192188
if (!ok) {
@@ -214,18 +210,17 @@ MaybeLocal<Module> ModuleWrap::ResolveCallback(Local<Context> context,
214210
Local<Module> referrer) {
215211
Environment* env = Environment::GetCurrent(context);
216212
Isolate* iso = Isolate::GetCurrent();
217-
if (ModuleWrap::module_map_.count(referrer->GetIdentityHash()) == 0) {
213+
if (env->module_map.count(referrer->GetIdentityHash()) == 0) {
218214
env->ThrowError("linking error, unknown module");
219215
return MaybeLocal<Module>();
220216
}
221217

222-
std::vector<ModuleWrap*>* possible_deps =
223-
ModuleWrap::module_map_[referrer->GetIdentityHash()];
224218
ModuleWrap* dependent = nullptr;
225-
226-
for (auto possible_dep : *possible_deps) {
227-
if (possible_dep->module_ == referrer) {
228-
dependent = possible_dep;
219+
auto range = env->module_map.equal_range(referrer->GetIdentityHash());
220+
for (auto it = range.first; it != range.second; ++it) {
221+
if (it->second->module_ == referrer) {
222+
dependent = it->second;
223+
break;
229224
}
230225
}
231226

@@ -243,7 +238,7 @@ MaybeLocal<Module> ModuleWrap::ResolveCallback(Local<Context> context,
243238
}
244239

245240
Local<Promise> resolve_promise =
246-
dependent->resolve_cache_[specifier_std]->Get(iso);
241+
dependent->resolve_cache_[specifier_std].Get(iso);
247242

248243
if (resolve_promise->State() != Promise::kFulfilled) {
249244
env->ThrowError("linking error, dependency promises must be resolved on "

src/module_wrap.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55

6-
#include <map>
6+
#include <unordered_map>
77
#include <string>
88
#include <vector>
99
#include "node_url.h"
@@ -45,9 +45,7 @@ class ModuleWrap : public BaseObject {
4545
v8::Persistent<v8::Module> module_;
4646
v8::Persistent<v8::String> url_;
4747
bool linked_ = false;
48-
std::map<std::string, v8::Persistent<v8::Promise>*> resolve_cache_;
49-
50-
static std::map<int, std::vector<ModuleWrap*>*> module_map_;
48+
std::unordered_map<std::string, v8::Persistent<v8::Promise>> resolve_cache_;
5149
};
5250

5351
} // namespace loader

0 commit comments

Comments
 (0)