diff --git a/src/node_builtins.cc b/src/node_builtins.cc index d78ad3dd811432..84815969b6d1fa 100644 --- a/src/node_builtins.cc +++ b/src/node_builtins.cc @@ -254,7 +254,7 @@ MaybeLocal BuiltinLoader::LookupAndCompileInternal( Local context, const char* id, std::vector>* parameters, - BuiltinLoader::Result* result) { + Realm* optional_realm) { Isolate* isolate = context->GetIsolate(); EscapableHandleScope scope(isolate); @@ -320,9 +320,13 @@ MaybeLocal BuiltinLoader::LookupAndCompileInternal( // will never be in any of these two sets, but the two sets are only for // testing anyway. - *result = (has_cache && !script_source.GetCachedData()->rejected) - ? Result::kWithCache - : Result::kWithoutCache; + Result result = (has_cache && !script_source.GetCachedData()->rejected) + ? Result::kWithCache + : Result::kWithoutCache; + if (optional_realm != nullptr) { + DCHECK_EQ(this, optional_realm->env()->builtin_loader()); + RecordResult(id, result, optional_realm); + } if (has_cache) { per_process::Debug(DebugCategory::CODE_CACHE, @@ -336,28 +340,35 @@ MaybeLocal BuiltinLoader::LookupAndCompileInternal( : "is accepted"); } - if (*result == Result::kWithoutCache) { + if (result == Result::kWithoutCache && optional_realm != nullptr && + !optional_realm->env()->isolate_data()->is_building_snapshot()) { // We failed to accept this cache, maybe because it was rejected, maybe // because it wasn't present. Either way, we'll attempt to replace this // code cache info with a new one. - std::shared_ptr new_cached_data( - ScriptCompiler::CreateCodeCacheForFunction(fun)); - CHECK_NOT_NULL(new_cached_data); - - { - RwLock::ScopedLock lock(code_cache_->mutex); - code_cache_->map.insert_or_assign( - id, BuiltinCodeCacheData(std::move(new_cached_data))); - } + // This is only done when the isolate is not being serialized because + // V8 does not support serializing code cache with an unfinalized read-only + // space (which is what isolates pending to be serialized have). + SaveCodeCache(id, fun); } return scope.Escape(fun); } +void BuiltinLoader::SaveCodeCache(const char* id, Local fun) { + std::shared_ptr new_cached_data( + ScriptCompiler::CreateCodeCacheForFunction(fun)); + CHECK_NOT_NULL(new_cached_data); + + { + RwLock::ScopedLock lock(code_cache_->mutex); + code_cache_->map.insert_or_assign( + id, BuiltinCodeCacheData(std::move(new_cached_data))); + } +} + MaybeLocal BuiltinLoader::LookupAndCompile(Local context, const char* id, Realm* optional_realm) { - Result result; std::vector> parameters; Isolate* isolate = context->GetIsolate(); // Detects parameters of the scripts based on module ids. @@ -403,11 +414,7 @@ MaybeLocal BuiltinLoader::LookupAndCompile(Local context, } MaybeLocal maybe = - LookupAndCompileInternal(context, id, ¶meters, &result); - if (optional_realm != nullptr) { - DCHECK_EQ(this, optional_realm->env()->builtin_loader()); - RecordResult(id, result, optional_realm); - } + LookupAndCompileInternal(context, id, ¶meters, optional_realm); return maybe; } @@ -483,13 +490,17 @@ bool BuiltinLoader::CompileAllBuiltins(Local context) { continue; } v8::TryCatch bootstrapCatch(context->GetIsolate()); - USE(LookupAndCompile(context, id.data(), nullptr)); + auto fn = LookupAndCompile(context, id.data(), nullptr); if (bootstrapCatch.HasCaught()) { per_process::Debug(DebugCategory::CODE_CACHE, "Failed to compile code cache for %s\n", id.data()); all_succeeded = false; PrintCaughtException(context->GetIsolate(), context, bootstrapCatch); + } else { + // This is used by the snapshot builder, so save the code cache + // unconditionally. + SaveCodeCache(id.data(), fn.ToLocalChecked()); } } return all_succeeded; diff --git a/src/node_builtins.h b/src/node_builtins.h index f91c2a8105bfe5..9f2fbc1e539374 100644 --- a/src/node_builtins.h +++ b/src/node_builtins.h @@ -147,7 +147,8 @@ class NODE_EXTERN_PRIVATE BuiltinLoader { v8::Local context, const char* id, std::vector>* parameters, - Result* result); + Realm* optional_realm); + void SaveCodeCache(const char* id, v8::Local fn); static void RecordResult(const char* id, BuiltinLoader::Result result,