@@ -254,7 +254,7 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompileInternal(
254254 Local<Context> context,
255255 const char * id,
256256 std::vector<Local<String>>* parameters,
257- BuiltinLoader::Result* result ) {
257+ Realm* optional_realm ) {
258258 Isolate* isolate = context->GetIsolate ();
259259 EscapableHandleScope scope (isolate);
260260
@@ -320,9 +320,13 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompileInternal(
320320 // will never be in any of these two sets, but the two sets are only for
321321 // testing anyway.
322322
323- *result = (has_cache && !script_source.GetCachedData ()->rejected )
324- ? Result::kWithCache
325- : Result::kWithoutCache ;
323+ Result result = (has_cache && !script_source.GetCachedData ()->rejected )
324+ ? Result::kWithCache
325+ : Result::kWithoutCache ;
326+ if (optional_realm != nullptr ) {
327+ DCHECK_EQ (this , optional_realm->env ()->builtin_loader ());
328+ RecordResult (id, result, optional_realm);
329+ }
326330
327331 if (has_cache) {
328332 per_process::Debug (DebugCategory::CODE_CACHE,
@@ -336,28 +340,35 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompileInternal(
336340 : " is accepted" );
337341 }
338342
339- if (*result == Result::kWithoutCache ) {
343+ if (result == Result::kWithoutCache && optional_realm != nullptr &&
344+ !optional_realm->env ()->isolate_data ()->is_building_snapshot ()) {
340345 // We failed to accept this cache, maybe because it was rejected, maybe
341346 // because it wasn't present. Either way, we'll attempt to replace this
342347 // code cache info with a new one.
343- std::shared_ptr<ScriptCompiler::CachedData> new_cached_data (
344- ScriptCompiler::CreateCodeCacheForFunction (fun));
345- CHECK_NOT_NULL (new_cached_data);
346-
347- {
348- RwLock::ScopedLock lock (code_cache_->mutex );
349- code_cache_->map .insert_or_assign (
350- id, BuiltinCodeCacheData (std::move (new_cached_data)));
351- }
348+ // This is only done when the isolate is not being serialized because
349+ // V8 does not support serializing code cache with an unfinalized read-only
350+ // space (which is what isolates pending to be serialized have).
351+ SaveCodeCache (id, fun);
352352 }
353353
354354 return scope.Escape (fun);
355355}
356356
357+ void BuiltinLoader::SaveCodeCache (const char * id, Local<Function> fun) {
358+ std::shared_ptr<ScriptCompiler::CachedData> new_cached_data (
359+ ScriptCompiler::CreateCodeCacheForFunction (fun));
360+ CHECK_NOT_NULL (new_cached_data);
361+
362+ {
363+ RwLock::ScopedLock lock (code_cache_->mutex );
364+ code_cache_->map .insert_or_assign (
365+ id, BuiltinCodeCacheData (std::move (new_cached_data)));
366+ }
367+ }
368+
357369MaybeLocal<Function> BuiltinLoader::LookupAndCompile (Local<Context> context,
358370 const char * id,
359371 Realm* optional_realm) {
360- Result result;
361372 std::vector<Local<String>> parameters;
362373 Isolate* isolate = context->GetIsolate ();
363374 // Detects parameters of the scripts based on module ids.
@@ -403,11 +414,7 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(Local<Context> context,
403414 }
404415
405416 MaybeLocal<Function> maybe =
406- LookupAndCompileInternal (context, id, ¶meters, &result);
407- if (optional_realm != nullptr ) {
408- DCHECK_EQ (this , optional_realm->env ()->builtin_loader ());
409- RecordResult (id, result, optional_realm);
410- }
417+ LookupAndCompileInternal (context, id, ¶meters, optional_realm);
411418 return maybe;
412419}
413420
@@ -483,13 +490,17 @@ bool BuiltinLoader::CompileAllBuiltins(Local<Context> context) {
483490 continue ;
484491 }
485492 v8::TryCatch bootstrapCatch (context->GetIsolate ());
486- USE ( LookupAndCompile (context, id.data (), nullptr ) );
493+ auto fn = LookupAndCompile (context, id.data (), nullptr );
487494 if (bootstrapCatch.HasCaught ()) {
488495 per_process::Debug (DebugCategory::CODE_CACHE,
489496 " Failed to compile code cache for %s\n " ,
490497 id.data ());
491498 all_succeeded = false ;
492499 PrintCaughtException (context->GetIsolate (), context, bootstrapCatch);
500+ } else {
501+ // This is used by the snapshot builder, so save the code cache
502+ // unconditionally.
503+ SaveCodeCache (id.data (), fn.ToLocalChecked ());
493504 }
494505 }
495506 return all_succeeded;
0 commit comments