@@ -254,7 +254,7 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompileInternal(
254
254
Local<Context> context,
255
255
const char * id,
256
256
std::vector<Local<String>>* parameters,
257
- BuiltinLoader::Result* result ) {
257
+ Realm* optional_realm ) {
258
258
Isolate* isolate = context->GetIsolate ();
259
259
EscapableHandleScope scope (isolate);
260
260
@@ -320,9 +320,13 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompileInternal(
320
320
// will never be in any of these two sets, but the two sets are only for
321
321
// testing anyway.
322
322
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
+ }
326
330
327
331
if (has_cache) {
328
332
per_process::Debug (DebugCategory::CODE_CACHE,
@@ -336,28 +340,35 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompileInternal(
336
340
: " is accepted" );
337
341
}
338
342
339
- if (*result == Result::kWithoutCache ) {
343
+ if (result == Result::kWithoutCache && optional_realm != nullptr &&
344
+ !optional_realm->env ()->isolate_data ()->is_building_snapshot ()) {
340
345
// We failed to accept this cache, maybe because it was rejected, maybe
341
346
// because it wasn't present. Either way, we'll attempt to replace this
342
347
// 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);
352
352
}
353
353
354
354
return scope.Escape (fun);
355
355
}
356
356
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
+
357
369
MaybeLocal<Function> BuiltinLoader::LookupAndCompile (Local<Context> context,
358
370
const char * id,
359
371
Realm* optional_realm) {
360
- Result result;
361
372
std::vector<Local<String>> parameters;
362
373
Isolate* isolate = context->GetIsolate ();
363
374
// Detects parameters of the scripts based on module ids.
@@ -403,11 +414,7 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(Local<Context> context,
403
414
}
404
415
405
416
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);
411
418
return maybe;
412
419
}
413
420
@@ -483,13 +490,17 @@ bool BuiltinLoader::CompileAllBuiltins(Local<Context> context) {
483
490
continue ;
484
491
}
485
492
v8::TryCatch bootstrapCatch (context->GetIsolate ());
486
- USE ( LookupAndCompile (context, id.data (), nullptr ) );
493
+ auto fn = LookupAndCompile (context, id.data (), nullptr );
487
494
if (bootstrapCatch.HasCaught ()) {
488
495
per_process::Debug (DebugCategory::CODE_CACHE,
489
496
" Failed to compile code cache for %s\n " ,
490
497
id.data ());
491
498
all_succeeded = false ;
492
499
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 ());
493
504
}
494
505
}
495
506
return all_succeeded;
0 commit comments