| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d6e8d03 commit 90391ff
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -802,6 +802,9 @@ Maybe<bool> InitializePrimordials(Local<Context> context) { | |||
| 802 | 802 | // relatively cheap and all the scripts that we may want to run at | |
| 803 | 803 | // startup are always present in it. | |
| 804 | 804 | thread_local builtins::BuiltinLoader builtin_loader; | |
| 805 | + // Primordials can always be just eagerly compiled. | ||
| 806 | + builtin_loader.SetEagerCompile(); | ||
| 807 | + | ||
| 805 | 808 | for (const char** module = context_files; *module != nullptr; module++) { | |
| 806 | 809 | Local<Value> arguments[] = {exports, primordials}; | |
| 807 | 810 | if (builtin_loader | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -827,6 +827,15 @@ Environment::Environment(IsolateData* isolate_data, | |||
| 827 | 827 | } | |
| 828 | 828 | } | |
| 829 | 829 | ||
| 830 | + // We are supposed to call builtin_loader_.SetEagerCompile() in | ||
| 831 | + // snapshot mode here because it's beneficial to compile built-ins | ||
| 832 | + // loaded in the snapshot eagerly and include the code of inner functions | ||
| 833 | + // that are likely to be used by user since they are part of the core | ||
| 834 | + // startup. But this requires us to start the coverage collections | ||
| 835 | + // before Environment/Context creation which is not currently possible. | ||
| 836 | + // TODO(joyeecheung): refactor V8ProfilerConnection classes to parse | ||
| 837 | + // JSON without v8 and lift this restriction. | ||
| 838 | + | ||
| 830 | 839 | // We'll be creating new objects so make sure we've entered the context. | |
| 831 | 840 | HandleScope handle_scope(isolate); | |
| 832 | 841 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -286,15 +286,24 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompileInternal( | |||
| 286 | 286 | ScriptCompiler::CompileOptions options = | |
| 287 | 287 | has_cache ? ScriptCompiler::kConsumeCodeCache | |
| 288 | 288 | : ScriptCompiler::kNoCompileOptions; | |
| 289 | + if (should_eager_compile_) { | ||
| 290 | + options = ScriptCompiler::kEagerCompile; | ||
| 291 | + } else if (!to_eager_compile_.empty()) { | ||
| 292 | + if (to_eager_compile_.find(id) != to_eager_compile_.end()) { | ||
| 293 | + options = ScriptCompiler::kEagerCompile; | ||
| 294 | + } | ||
| 295 | + } | ||
| 289 | 296 | ScriptCompiler::Source script_source( | |
| 290 | 297 | source, | |
| 291 | 298 | origin, | |
| 292 | 299 | has_cache ? cached_data.AsCachedData().release() : nullptr); | |
| 293 | 300 | ||
| 294 | - per_process::Debug(DebugCategory::CODE_CACHE, | ||
| 295 | - "Compiling %s %s code cache\n", | ||
| 296 | - id, | ||
| 297 | - has_cache ? "with" : "without"); | ||
| 301 | + per_process::Debug( | ||
| 302 | + DebugCategory::CODE_CACHE, | ||
| 303 | + "Compiling %s %s code cache %s\n", | ||
| 304 | + id, | ||
| 305 | + has_cache ? "with" : "without", | ||
| 306 | + options == ScriptCompiler::kEagerCompile ? "eagerly" : "lazily"); | ||
| 298 | 307 | ||
| 299 | 308 | MaybeLocal<Function> maybe_fun = | |
| 300 | 309 | ScriptCompiler::CompileFunction(context, | |
@@ -481,14 +490,33 @@ MaybeLocal<Value> BuiltinLoader::CompileAndCall(Local<Context> context, | |||
| 481 | 490 | return fn->Call(context, undefined, argc, argv); | |
| 482 | 491 | } | |
| 483 | 492 | ||
| 484 | - bool BuiltinLoader::CompileAllBuiltins(Local<Context> context) { | ||
| 493 | + bool BuiltinLoader::CompileAllBuiltinsAndCopyCodeCache( | ||
| 494 | + Local<Context> context, | ||
| 495 | + const std::vector<std::string>& eager_builtins, | ||
| 496 | + std::vector<CodeCacheInfo>* out) { | ||
| 485 | 497 | std::vector<std::string_view> ids = GetBuiltinIds(); | |
| 486 | 498 | bool all_succeeded = true; | |
| 487 | 499 | std::string v8_tools_prefix = "internal/deps/v8/tools/"; | |
| 500 | + std::string primordial_prefix = "internal/per_context/"; | ||
| 501 | + std::string bootstrap_prefix = "internal/bootstrap/"; | ||
| 502 | + std::string main_prefix = "internal/main/"; | ||
| 503 | + to_eager_compile_ = std::unordered_set<std::string>(eager_builtins.begin(), | ||
| 504 | + eager_builtins.end()); | ||
| 505 | + | ||
| 488 | 506 | for (const auto& id : ids) { | |
| 489 | 507 | if (id.compare(0, v8_tools_prefix.size(), v8_tools_prefix) == 0) { | |
| 508 | + // No need to generate code cache for v8 scripts. | ||
| 490 | 509 | continue; | |
| 491 | 510 | } | |
| 511 | + | ||
| 512 | + // Eagerly compile primordials/boostrap/main scripts during code cache | ||
| 513 | + // generation. | ||
| 514 | + if (id.compare(0, primordial_prefix.size(), primordial_prefix) == 0 || | ||
| 515 | + id.compare(0, bootstrap_prefix.size(), bootstrap_prefix) == 0 || | ||
| 516 | + id.compare(0, main_prefix.size(), main_prefix) == 0) { | ||
| 517 | + to_eager_compile_.emplace(id); | ||
| 518 | + } | ||
| 519 | + | ||
| 492 | 520 | v8::TryCatch bootstrapCatch(context->GetIsolate()); | |
| 493 | 521 | auto fn = LookupAndCompile(context, id.data(), nullptr); | |
| 494 | 522 | if (bootstrapCatch.HasCaught()) { | |
@@ -503,14 +531,12 @@ bool BuiltinLoader::CompileAllBuiltins(Local<Context> context) { | |||
| 503 | 531 | SaveCodeCache(id.data(), fn.ToLocalChecked()); | |
| 504 | 532 | } | |
| 505 | 533 | } | |
| 506 | - return all_succeeded; | ||
| 507 | - } | ||
| 508 | 534 | ||
| 509 | - void BuiltinLoader::CopyCodeCache(std::vector<CodeCacheInfo>* out) const { | ||
| 510 | 535 | RwLock::ScopedReadLock lock(code_cache_->mutex); | |
| 511 | 536 | for (auto const& item : code_cache_->map) { | |
| 512 | 537 | out->push_back({item.first, item.second}); | |
| 513 | 538 | } | |
| 539 | + return all_succeeded; | ||
| 514 | 540 | } | |
| 515 | 541 | ||
| 516 | 542 | void BuiltinLoader::RefreshCodeCache(const std::vector<CodeCacheInfo>& in) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,8 +7,8 @@ | |||
| 7 | 7 | #include <map> | |
| 8 | 8 | #include <memory> | |
| 9 | 9 | #include <optional> | |
| 10 | - #include <set> | ||
| 11 | 10 | #include <string> | |
| 11 | + #include <unordered_set> | ||
| 12 | 12 | #include <vector> | |
| 13 | 13 | #include "node_external_reference.h" | |
| 14 | 14 | #include "node_mutex.h" | |
@@ -112,12 +112,18 @@ class NODE_EXTERN_PRIVATE BuiltinLoader { | |||
| 112 | 112 | bool Exists(const char* id); | |
| 113 | 113 | bool Add(const char* id, const UnionBytes& source); | |
| 114 | 114 | ||
| 115 | - bool CompileAllBuiltins(v8::Local<v8::Context> context); | ||
| 115 | + bool CompileAllBuiltinsAndCopyCodeCache( | ||
| 116 | + v8::Local<v8::Context> context, | ||
| 117 | + const std::vector<std::string>& lazy_builtins, | ||
| 118 | + std::vector<CodeCacheInfo>* out); | ||
| 116 | 119 | void RefreshCodeCache(const std::vector<CodeCacheInfo>& in); | |
| 117 | - void CopyCodeCache(std::vector<CodeCacheInfo>* out) const; | ||
| 118 | 120 | ||
| 119 | 121 | void CopySourceAndCodeCacheReferenceFrom(const BuiltinLoader* other); | |
| 120 | 122 | ||
| 123 | + std::vector<std::string_view> GetBuiltinIds() const; | ||
| 124 | + | ||
| 125 | + void SetEagerCompile() { should_eager_compile_ = true; } | ||
| 126 | + | ||
| 121 | 127 | private: | |
| 122 | 128 | // Only allow access from friends. | |
| 123 | 129 | friend class CodeCacheBuilder; | |
@@ -126,8 +132,6 @@ class NODE_EXTERN_PRIVATE BuiltinLoader { | |||
| 126 | 132 | void LoadJavaScriptSource(); // Loads data into source_ | |
| 127 | 133 | UnionBytes GetConfig(); // Return data for config.gypi | |
| 128 | 134 | ||
| 129 | - std::vector<std::string_view> GetBuiltinIds() const; | ||
| 130 | - | ||
| 131 | 135 | struct BuiltinCategories { | |
| 132 | 136 | std::set<std::string> can_be_required; | |
| 133 | 137 | std::set<std::string> cannot_be_required; | |
@@ -179,6 +183,18 @@ class NODE_EXTERN_PRIVATE BuiltinLoader { | |||
| 179 | 183 | ||
| 180 | 184 | const UnionBytes config_; | |
| 181 | 185 | ||
| 186 | + // If any bulitins should be eagerly compiled i.e. with inner functions | ||
| 187 | + // compiled too, either use should_eager_compile_ to compile all builtins | ||
| 188 | + // eagerly, or use to_eager_compile_ to compile specific builtins eagerly. | ||
| 189 | + // Currently we set should_eager_compile_ to true when compiling primordials, | ||
| 190 | + // and use to_eager_compile_ to compile code cache that complements the | ||
| 191 | + // snapshot, where builtins already loaded in the snapshot and a few extras | ||
| 192 | + // are compiled eagerly (other less-essential built-ins are compiled lazily to | ||
| 193 | + // avoid bloating the binary size). At runtime any additional compilation is | ||
| 194 | + // done lazily. | ||
| 195 | + bool should_eager_compile_ = false; | ||
| 196 | + std::unordered_set<std::string> to_eager_compile_; | ||
| 197 | + | ||
| 182 | 198 | struct BuiltinCodeCache { | |
| 183 | 199 | RwLock mutex; | |
| 184 | 200 | BuiltinCodeCacheMap map; | |
@@ -188,6 +204,7 @@ class NODE_EXTERN_PRIVATE BuiltinLoader { | |||
| 188 | 204 | ||
| 189 | 205 | friend class ::PerProcessTest; | |
| 190 | 206 | }; | |
| 207 | + | ||
| 191 | 208 | } // namespace builtins | |
| 192 | 209 | ||
| 193 | 210 | } // namespace node | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1040,10 +1040,12 @@ ExitCode BuildCodeCacheFromSnapshot(SnapshotData* out, | |||
| 1040 | 1040 | Context::Scope context_scope(context); | |
| 1041 | 1041 | builtins::BuiltinLoader builtin_loader; | |
| 1042 | 1042 | // Regenerate all the code cache. | |
| 1043 | - if (!builtin_loader.CompileAllBuiltins(context)) { | ||
| 1043 | + if (!builtin_loader.CompileAllBuiltinsAndCopyCodeCache( | ||
| 1044 | + context, | ||
| 1045 | + out->env_info.principal_realm.builtins, | ||
| 1046 | + &(out->code_cache))) { | ||
| 1044 | 1047 | return ExitCode::kGenericUserError; | |
| 1045 | 1048 | } | |
| 1046 | - builtin_loader.CopyCodeCache(&(out->code_cache)); | ||
| 1047 | 1049 | if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) { | |
| 1048 | 1050 | for (const auto& item : out->code_cache) { | |
| 1049 | 1051 | std::string size_str = FormatSize(item.data.length); | |
@@ -1069,6 +1071,9 @@ ExitCode SnapshotBuilder::Generate( | |||
| 1069 | 1071 | } | |
| 1070 | 1072 | ||
| 1071 | 1073 | if (!WithoutCodeCache(snapshot_config)) { | |
| 1074 | + per_process::Debug( | ||
| 1075 | + DebugCategory::CODE_CACHE, | ||
| 1076 | + "---\nGenerate code cache to complement snapshot\n---\n"); | ||
| 1072 | 1077 | // Deserialize the snapshot to recompile code cache. We need to do this in | |
| 1073 | 1078 | // the second pass because V8 requires the code cache to be compiled with a | |
| 1074 | 1079 | // finalized read-only space. | |
| Back | FazBrowse Home | New Git URL |
0 commit comments