Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Unified Diff: src/d8.cc

Issue 2405313002: [modules] Store Module metadata in per-Context EmbedderData (Closed)
Patch Set: Formatting Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/d8.h ('k') | src/factory.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index 920a6f488f203a9a871fd0db0b364677187dbace..938448936dd23aab906a29f44aac8f26c88536a2 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -9,7 +9,7 @@
#include <algorithm>
#include <fstream>
-#include <map>
+#include <unordered_map>
#include <utility>
#include <vector>
@@ -572,29 +572,74 @@ std::string NormalizePath(const std::string& path,
return result;
}
+// Per-context Module data, allowing sharing of module maps
+// across top-level module loads.
+class ModuleEmbedderData {
+ private:
+ class ModuleGlobalHash {
+ public:
+ explicit ModuleGlobalHash(Isolate* isolate) : isolate_(isolate) {}
+ size_t operator()(const Global<Module>& module) const {
+ return module.Get(isolate_)->GetIdentityHash();
+ }
+
+ private:
+ Isolate* isolate_;
+ };
+
+ public:
+ explicit ModuleEmbedderData(Isolate* isolate)
+ : module_to_directory_map(10, ModuleGlobalHash(isolate)) {}
+
+ // Map from normalized module specifier to Module.
+ std::unordered_map<std::string, Global<Module>> specifier_to_module_map;
+ // Map from Module to the directory that Module was loaded from.
+ std::unordered_map<Global<Module>, std::string, ModuleGlobalHash>
+ module_to_directory_map;
+};
+
+enum {
+ // The debugger reserves the first slot in the Context embedder data.
+ kDebugIdIndex = Context::kDebugIdIndex,
+ kModuleEmbedderDataIndex
+};
+
+void InitializeModuleEmbedderData(Local<Context> context) {
+ context->SetAlignedPointerInEmbedderData(
+ kModuleEmbedderDataIndex, new ModuleEmbedderData(context->GetIsolate()));
+}
+
+ModuleEmbedderData* GetModuleDataFromContext(Local<Context> context) {
+ return static_cast<ModuleEmbedderData*>(
+ context->GetAlignedPointerFromEmbedderData(kModuleEmbedderDataIndex));
+}
+
+void DisposeModuleEmbedderData(Local<Context> context) {
+ delete GetModuleDataFromContext(context);
+ context->SetAlignedPointerInEmbedderData(kModuleEmbedderDataIndex, nullptr);
+}
+
MaybeLocal<Module> ResolveModuleCallback(Local<Context> context,
Local<String> specifier,
- Local<Module> referrer,
- Local<Value> data) {
+ Local<Module> referrer) {
Isolate* isolate = context->GetIsolate();
- auto module_map = static_cast<std::map<std::string, Global<Module>>*>(
- External::Cast(*data)->Value());
- Local<String> dir_name = Local<String>::Cast(referrer->GetEmbedderData());
+ ModuleEmbedderData* d = GetModuleDataFromContext(context);
+ auto dir_name_it =
+ d->module_to_directory_map.find(Global<Module>(isolate, referrer));
+ CHECK(dir_name_it != d->module_to_directory_map.end());
std::string absolute_path =
- NormalizePath(ToSTLString(specifier), ToSTLString(dir_name));
- auto it = module_map->find(absolute_path);
- if (it != module_map->end()) {
- return it->second.Get(isolate);
- }
- return MaybeLocal<Module>();
+ NormalizePath(ToSTLString(specifier), dir_name_it->second);
+ auto module_it = d->specifier_to_module_map.find(absolute_path);
+ CHECK(module_it != d->specifier_to_module_map.end());
+ return module_it->second.Get(isolate);
}
} // anonymous namespace
-MaybeLocal<Module> Shell::FetchModuleTree(
- Isolate* isolate, const std::string& file_name,
- std::map<std::string, Global<Module>>* module_map) {
+MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context,
+ const std::string& file_name) {
DCHECK(IsAbsolutePath(file_name));
+ Isolate* isolate = context->GetIsolate();
TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
Local<String> source_text = ReadFile(isolate, file_name.c_str());
@@ -611,19 +656,22 @@ MaybeLocal<Module> Shell::FetchModuleTree(
ReportException(isolate, &try_catch);
return MaybeLocal<Module>();
}
- module_map->insert(
- std::make_pair(file_name, Global<Module>(isolate, module)));
+
+ ModuleEmbedderData* d = GetModuleDataFromContext(context);
+ CHECK(d->specifier_to_module_map
+ .insert(std::make_pair(file_name, Global<Module>(isolate, module)))
+ .second);
std::string dir_name = DirName(file_name);
- module->SetEmbedderData(
- String::NewFromUtf8(isolate, dir_name.c_str(), NewStringType::kNormal)
- .ToLocalChecked());
+ CHECK(d->module_to_directory_map
+ .insert(std::make_pair(Global<Module>(isolate, module), dir_name))
+ .second);
for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) {
Local<String> name = module->GetModuleRequest(i);
std::string absolute_path = NormalizePath(ToSTLString(name), dir_name);
- if (!module_map->count(absolute_path)) {
- if (FetchModuleTree(isolate, absolute_path, module_map).IsEmpty()) {
+ if (!d->specifier_to_module_map.count(absolute_path)) {
+ if (FetchModuleTree(context, absolute_path).IsEmpty()) {
return MaybeLocal<Module>();
}
}
@@ -635,12 +683,14 @@ MaybeLocal<Module> Shell::FetchModuleTree(
bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
HandleScope handle_scope(isolate);
+ PerIsolateData* data = PerIsolateData::Get(isolate);
+ Local<Context> realm = data->realms_[data->realm_current_].Get(isolate);
+ Context::Scope context_scope(realm);
+
std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory());
Local<Module> root_module;
- std::map<std::string, Global<Module>> module_map;
- if (!FetchModuleTree(isolate, absolute_path, &module_map)
- .ToLocal(&root_module)) {
+ if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) {
return false;
}
@@ -648,16 +698,9 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
try_catch.SetVerbose(true);
MaybeLocal<Value> maybe_result;
- {
- PerIsolateData* data = PerIsolateData::Get(isolate);
- Local<Context> realm = data->realms_[data->realm_current_].Get(isolate);
- Context::Scope context_scope(realm);
-
- if (root_module->Instantiate(realm, ResolveModuleCallback,
- External::New(isolate, &module_map))) {
- maybe_result = root_module->Evaluate(realm);
- EmptyMessageQueues(isolate);
- }
+ if (root_module->Instantiate(realm, ResolveModuleCallback)) {
+ maybe_result = root_module->Evaluate(realm);
+ EmptyMessageQueues(isolate);
}
Local<Value> result;
if (!maybe_result.ToLocal(&result)) {
@@ -682,9 +725,15 @@ PerIsolateData::RealmScope::RealmScope(PerIsolateData* data) : data_(data) {
PerIsolateData::RealmScope::~RealmScope() {
// Drop realms to avoid keeping them alive.
- for (int i = 0; i < data_->realm_count_; ++i)
- data_->realms_[i].Reset();
+ for (int i = 0; i < data_->realm_count_; ++i) {
+ Global<Context>& realm = data_->realms_[i];
+ if (realm.IsEmpty()) continue;
+ DisposeModuleEmbedderData(realm.Get(data_->isolate_));
+ // TODO(adamk): No need to reset manually, Globals reset when destructed.
+ realm.Reset();
+ }
delete[] data_->realms_;
+ // TODO(adamk): No need to reset manually, Globals reset when destructed.
if (!data_->realm_shared_.IsEmpty())
data_->realm_shared_.Reset();
}
@@ -787,6 +836,7 @@ MaybeLocal<Context> Shell::CreateRealm(
try_catch.ReThrow();
return MaybeLocal<Context>();
}
+ InitializeModuleEmbedderData(context);
data->realms_[index].Reset(isolate, context);
args.GetReturnValue().Set(index);
return context;
@@ -820,6 +870,7 @@ void Shell::RealmDispose(const v8::FunctionCallbackInfo<v8::Value>& args) {
Throw(args.GetIsolate(), "Invalid realm index");
return;
}
+ DisposeModuleEmbedderData(data->realms_[index].Get(isolate));
data->realms_[index].Reset();
isolate->ContextDisposedNotification();
isolate->IdleNotificationDeadline(g_platform->MonotonicallyIncreasingTime());
@@ -1488,6 +1539,7 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
EscapableHandleScope handle_scope(isolate);
Local<Context> context = Context::New(isolate, NULL, global_template);
DCHECK(!context.IsEmpty());
+ InitializeModuleEmbedderData(context);
Context::Scope scope(context);
i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory();
@@ -1813,6 +1865,7 @@ void SourceGroup::ExecuteInThread() {
PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
Execute(isolate);
}
+ DisposeModuleEmbedderData(context);
}
Shell::CollectGarbage(isolate);
}
@@ -2072,6 +2125,7 @@ void Worker::ExecuteInThread() {
}
}
}
+ DisposeModuleEmbedderData(context);
}
Shell::CollectGarbage(isolate);
}
@@ -2255,6 +2309,7 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) {
PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
options.isolate_sources[0].Execute(isolate);
}
+ DisposeModuleEmbedderData(context);
}
CollectGarbage(isolate);
for (int i = 1; i < options.num_isolates; ++i) {
« no previous file with comments | « src/d8.h ('k') | src/factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698