Skip to content

Commit 59cb403

Browse files
committed
deps: V8: backport f4b3f6eb4595
Original commit message: [compiler] support isolate compilation cache in CompileFunction() Previously there was no isolate compilation cache support for scripts compiled Script::CompileFunction() with wrapped arguments. This patch adds support for that. Refs: nodejs#35375 Change-Id: Id1849961ecd1282eb2dac95829157d167a3aa9a1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4962094 Reviewed-by: Camillo Bruni <[email protected]> Commit-Queue: Joyee Cheung <[email protected]> Cr-Commit-Position: refs/heads/main@{#91681} Refs: v8/v8@f4b3f6e
1 parent af48641 commit 59cb403

File tree

11 files changed

+359
-40
lines changed

11 files changed

+359
-40
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737

3838
# Reset this number to 0 on major V8 upgrades.
3939
# Increment by one for each non-official patch applied to deps/v8.
40-
'v8_embedder_string': '-node.15',
40+
'v8_embedder_string': '-node.16',
4141

4242
##### V8 defaults for Node.js #####
4343

deps/npm/lib/npm.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ class Npm {
140140
if (!this.#loadPromise) {
141141
this.#loadPromise = this.time('npm:load', () => this.#load().catch((er) => {
142142
this.loadErr = er
143+
console.log(er);
143144
throw er
144145
}))
145146
}

deps/v8/src/api/api.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2733,6 +2733,7 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInternal(
27332733
i_isolate, source->resource_name, source->resource_line_offset,
27342734
source->resource_column_offset, source->source_map_url,
27352735
source->host_defined_options, source->resource_options);
2736+
script_details.wrapped_arguments = arguments_list;
27362737

27372738
std::unique_ptr<i::AlignedCachedData> cached_data;
27382739
if (options == kConsumeCodeCache) {
@@ -2745,8 +2746,8 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInternal(
27452746
i::Handle<i::JSFunction> scoped_result;
27462747
has_pending_exception =
27472748
!i::Compiler::GetWrappedFunction(
2748-
Utils::OpenHandle(*source->source_string), arguments_list, context,
2749-
script_details, cached_data.get(), options, no_cache_reason)
2749+
Utils::OpenHandle(*source->source_string), context, script_details,
2750+
cached_data.get(), options, no_cache_reason)
27502751
.ToHandle(&scoped_result);
27512752
if (options == kConsumeCodeCache) {
27522753
source->cached_data->rejected = cached_data->rejected();

deps/v8/src/codegen/compilation-cache.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ void CompilationCacheScript::Put(Handle<String> source,
189189
Handle<SharedFunctionInfo> function_info) {
190190
HandleScope scope(isolate());
191191
Handle<CompilationCacheTable> table = GetTable();
192-
table_ = *CompilationCacheTable::PutScript(table, source, function_info,
193-
isolate());
192+
table_ = *CompilationCacheTable::PutScript(table, source, kNullMaybeHandle,
193+
function_info, isolate());
194194
}
195195

196196
InfoCellPair CompilationCacheEval::Lookup(Handle<String> source,

deps/v8/src/codegen/compiler.cc

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3353,14 +3353,13 @@ struct ScriptCompileTimerScope {
33533353
}
33543354
};
33553355

3356-
Handle<Script> NewScript(
3357-
Isolate* isolate, ParseInfo* parse_info, Handle<String> source,
3358-
ScriptDetails script_details, NativesFlag natives,
3359-
MaybeHandle<FixedArray> maybe_wrapped_arguments = kNullMaybeHandle) {
3356+
Handle<Script> NewScript(Isolate* isolate, ParseInfo* parse_info,
3357+
Handle<String> source, ScriptDetails script_details,
3358+
NativesFlag natives) {
33603359
// Create a script object describing the script to be compiled.
3361-
Handle<Script> script =
3362-
parse_info->CreateScript(isolate, source, maybe_wrapped_arguments,
3363-
script_details.origin_options, natives);
3360+
Handle<Script> script = parse_info->CreateScript(
3361+
isolate, source, script_details.wrapped_arguments,
3362+
script_details.origin_options, natives);
33643363
DisallowGarbageCollection no_gc;
33653364
SetScriptFieldsFromDetails(isolate, *script, script_details, &no_gc);
33663365
LOG(isolate, ScriptDetails(*script));
@@ -3742,26 +3741,37 @@ Compiler::GetSharedFunctionInfoForScriptWithCompileHints(
37423741

37433742
// static
37443743
MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
3745-
Handle<String> source, Handle<FixedArray> arguments,
3746-
Handle<Context> context, const ScriptDetails& script_details,
3747-
AlignedCachedData* cached_data,
3744+
Handle<String> source, Handle<Context> context,
3745+
const ScriptDetails& script_details, AlignedCachedData* cached_data,
37483746
v8::ScriptCompiler::CompileOptions compile_options,
37493747
v8::ScriptCompiler::NoCacheReason no_cache_reason) {
37503748
Isolate* isolate = context->GetIsolate();
37513749
ScriptCompileTimerScope compile_timer(isolate, no_cache_reason);
37523750

37533751
if (compile_options == ScriptCompiler::kConsumeCodeCache) {
37543752
DCHECK(cached_data);
3753+
DCHECK_EQ(script_details.repl_mode, REPLMode::kNo);
37553754
} else {
37563755
DCHECK_NULL(cached_data);
37573756
}
37583757

37593758
LanguageMode language_mode = construct_language_mode(v8_flags.use_strict);
3760-
3759+
DCHECK(!script_details.wrapped_arguments.is_null());
37613760
MaybeHandle<SharedFunctionInfo> maybe_result;
3761+
Handle<SharedFunctionInfo> result;
3762+
Handle<Script> script;
3763+
IsCompiledScope is_compiled_scope;
37623764
bool can_consume_code_cache =
37633765
compile_options == ScriptCompiler::kConsumeCodeCache;
3764-
if (can_consume_code_cache) {
3766+
CompilationCache* compilation_cache = isolate->compilation_cache();
3767+
// First check per-isolate compilation cache.
3768+
CompilationCacheScript::LookupResult lookup_result =
3769+
compilation_cache->LookupScript(source, script_details, language_mode);
3770+
maybe_result = lookup_result.toplevel_sfi();
3771+
if (maybe_result.ToHandle(&result)) {
3772+
is_compiled_scope = result->is_compiled_scope(isolate);
3773+
compile_timer.set_hit_isolate_cache();
3774+
} else if (can_consume_code_cache) {
37653775
compile_timer.set_consuming_code_cache();
37663776
// Then check cached code provided by embedder.
37673777
NestedTimedHistogramScope timer(isolate->counters()->compile_deserialize());
@@ -3770,16 +3780,22 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
37703780
"V8.CompileDeserialize");
37713781
maybe_result = CodeSerializer::Deserialize(isolate, cached_data, source,
37723782
script_details.origin_options);
3773-
if (maybe_result.is_null()) {
3783+
bool consuming_code_cache_succeeded = false;
3784+
if (maybe_result.ToHandle(&result)) {
3785+
is_compiled_scope = result->is_compiled_scope(isolate);
3786+
if (is_compiled_scope.is_compiled()) {
3787+
consuming_code_cache_succeeded = true;
3788+
// Promote to per-isolate compilation cache.
3789+
compilation_cache->PutScript(source, language_mode, result);
3790+
}
3791+
}
3792+
if (!consuming_code_cache_succeeded) {
37743793
// Deserializer failed. Fall through to compile.
37753794
compile_timer.set_consuming_code_cache_failed();
37763795
}
37773796
}
37783797

3779-
Handle<SharedFunctionInfo> wrapped;
3780-
Handle<Script> script;
3781-
IsCompiledScope is_compiled_scope;
3782-
if (!maybe_result.ToHandle(&wrapped)) {
3798+
if (maybe_result.is_null()) {
37833799
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForToplevelCompile(
37843800
isolate, true, language_mode, script_details.repl_mode,
37853801
ScriptType::kClassic, v8_flags.lazy);
@@ -3799,9 +3815,8 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
37993815
if (!IsNativeContext(*context)) {
38003816
maybe_outer_scope_info = handle(context->scope_info(), isolate);
38013817
}
3802-
38033818
script = NewScript(isolate, &parse_info, source, script_details,
3804-
NOT_NATIVES_CODE, arguments);
3819+
NOT_NATIVES_CODE);
38053820

38063821
Handle<SharedFunctionInfo> top_level;
38073822
maybe_result = v8::internal::CompileToplevel(&parse_info, script,
@@ -3814,18 +3829,23 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
38143829
for (Tagged<SharedFunctionInfo> info = infos.Next(); !info.is_null();
38153830
info = infos.Next()) {
38163831
if (info->is_wrapped()) {
3817-
wrapped = Handle<SharedFunctionInfo>(info, isolate);
3832+
result = Handle<SharedFunctionInfo>(info, isolate);
38183833
break;
38193834
}
38203835
}
3821-
DCHECK(!wrapped.is_null());
3822-
} else {
3823-
is_compiled_scope = wrapped->is_compiled_scope(isolate);
3824-
script = Handle<Script>(Script::cast(wrapped->script()), isolate);
3836+
DCHECK(!result.is_null());
3837+
3838+
is_compiled_scope = result->is_compiled_scope(isolate);
3839+
script = Handle<Script>(Script::cast(result->script()), isolate);
3840+
// Add the result to the isolate cache if there's no context extension.
3841+
if (maybe_outer_scope_info.is_null()) {
3842+
compilation_cache->PutScript(source, language_mode, result);
3843+
}
38253844
}
3845+
38263846
DCHECK(is_compiled_scope.is_compiled());
38273847

3828-
return Factory::JSFunctionBuilder{isolate, wrapped, context}
3848+
return Factory::JSFunctionBuilder{isolate, result, context}
38293849
.set_allocation_type(AllocationType::kYoung)
38303850
.Build();
38313851
}

deps/v8/src/codegen/compiler.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,8 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
161161
// Create a function that results from wrapping |source| in a function,
162162
// with |arguments| being a list of parameters for that function.
163163
V8_WARN_UNUSED_RESULT static MaybeHandle<JSFunction> GetWrappedFunction(
164-
Handle<String> source, Handle<FixedArray> arguments,
165-
Handle<Context> context, const ScriptDetails& script_details,
166-
AlignedCachedData* cached_data,
164+
Handle<String> source, Handle<Context> context,
165+
const ScriptDetails& script_details, AlignedCachedData* cached_data,
167166
v8::ScriptCompiler::CompileOptions compile_options,
168167
v8::ScriptCompiler::NoCacheReason no_cache_reason);
169168

deps/v8/src/codegen/script-details.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct ScriptDetails {
3030
MaybeHandle<Object> name_obj;
3131
MaybeHandle<Object> source_map_url;
3232
MaybeHandle<Object> host_defined_options;
33+
MaybeHandle<FixedArray> wrapped_arguments;
3334
REPLMode repl_mode;
3435
const ScriptOriginOptions origin_options;
3536
};

deps/v8/src/objects/compilation-cache-table-inl.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ class ScriptCacheKey : public HashTableKey {
6868
ScriptCacheKey(Handle<String> source, MaybeHandle<Object> name,
6969
int line_offset, int column_offset,
7070
v8::ScriptOriginOptions origin_options,
71-
MaybeHandle<Object> host_defined_options, Isolate* isolate);
71+
MaybeHandle<Object> host_defined_options,
72+
MaybeHandle<FixedArray> maybe_wrapped_arguments,
73+
Isolate* isolate);
7274

7375
bool IsMatch(Tagged<Object> other) override;
74-
bool MatchesOrigin(Tagged<Script> script);
76+
bool MatchesScript(Tagged<Script> script);
7577

7678
Handle<Object> AsHandle(Isolate* isolate, Handle<SharedFunctionInfo> shared);
7779

@@ -100,6 +102,7 @@ class ScriptCacheKey : public HashTableKey {
100102
int column_offset_;
101103
v8::ScriptOriginOptions origin_options_;
102104
MaybeHandle<Object> host_defined_options_;
105+
MaybeHandle<FixedArray> wrapped_arguments_;
103106
Isolate* isolate_;
104107
};
105108

deps/v8/src/objects/compilation-cache-table.cc

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ Tagged<Smi> ScriptHash(Tagged<String> source, MaybeHandle<Object> maybe_name,
246246
// We only re-use a cached function for some script source code if the
247247
// script originates from the same place. This is to avoid issues
248248
// when reporting errors, etc.
249-
bool ScriptCacheKey::MatchesOrigin(Tagged<Script> script) {
249+
bool ScriptCacheKey::MatchesScript(Tagged<Script> script) {
250250
DisallowGarbageCollection no_gc;
251251

252252
// If the script name isn't set, the boilerplate script should have
@@ -270,6 +270,30 @@ bool ScriptCacheKey::MatchesOrigin(Tagged<Script> script) {
270270
return false;
271271
}
272272

273+
Handle<FixedArray> wrapped_arguments_handle;
274+
if (wrapped_arguments_.ToHandle(&wrapped_arguments_handle)) {
275+
if (!script->is_wrapped()) {
276+
return false;
277+
}
278+
Tagged<FixedArray> wrapped_arguments = *wrapped_arguments_handle;
279+
Tagged<FixedArray> other_wrapped_arguments = script->wrapped_arguments();
280+
int length = wrapped_arguments->length();
281+
if (length != other_wrapped_arguments->length()) {
282+
return false;
283+
}
284+
for (int i = 0; i < length; i++) {
285+
Tagged<Object> arg = wrapped_arguments->get(i);
286+
Tagged<Object> other_arg = other_wrapped_arguments->get(i);
287+
DCHECK(IsString(arg));
288+
DCHECK(IsString(other_arg));
289+
if (!String::cast(arg)->Equals(String::cast(other_arg))) {
290+
return false;
291+
}
292+
}
293+
} else if (script->is_wrapped()) {
294+
return false;
295+
}
296+
273297
// TODO(cbruni, chromium:1244145): Remove once migrated to the context
274298
Handle<Object> maybe_host_defined_options;
275299
if (!host_defined_options_.ToHandle(&maybe_host_defined_options)) {
@@ -300,12 +324,14 @@ ScriptCacheKey::ScriptCacheKey(Handle<String> source,
300324
: ScriptCacheKey(source, script_details->name_obj,
301325
script_details->line_offset, script_details->column_offset,
302326
script_details->origin_options,
303-
script_details->host_defined_options, isolate) {}
327+
script_details->host_defined_options,
328+
script_details->wrapped_arguments, isolate) {}
304329

305330
ScriptCacheKey::ScriptCacheKey(Handle<String> source, MaybeHandle<Object> name,
306331
int line_offset, int column_offset,
307332
v8::ScriptOriginOptions origin_options,
308333
MaybeHandle<Object> host_defined_options,
334+
MaybeHandle<FixedArray> maybe_wrapped_arguments,
309335
Isolate* isolate)
310336
: HashTableKey(static_cast<uint32_t>(ScriptHash(*source, name, line_offset,
311337
column_offset,
@@ -317,8 +343,19 @@ ScriptCacheKey::ScriptCacheKey(Handle<String> source, MaybeHandle<Object> name,
317343
column_offset_(column_offset),
318344
origin_options_(origin_options),
319345
host_defined_options_(host_defined_options),
346+
wrapped_arguments_(maybe_wrapped_arguments),
320347
isolate_(isolate) {
321348
DCHECK(Smi::IsValid(static_cast<int>(Hash())));
349+
#ifdef DEBUG
350+
Handle<FixedArray> wrapped_arguments;
351+
if (maybe_wrapped_arguments.ToHandle(&wrapped_arguments)) {
352+
int length = wrapped_arguments->length();
353+
for (int i = 0; i < length; i++) {
354+
Tagged<Object> arg = wrapped_arguments->get(i);
355+
DCHECK(IsString(arg));
356+
}
357+
}
358+
#endif
322359
}
323360

324361
bool ScriptCacheKey::IsMatch(Tagged<Object> other) {
@@ -340,7 +377,8 @@ bool ScriptCacheKey::IsMatch(Tagged<Object> other) {
340377
}
341378
Tagged<Script> other_script = Script::cast(other_script_object);
342379
Tagged<String> other_source = String::cast(other_script->source());
343-
return other_source->Equals(*source_) && MatchesOrigin(other_script);
380+
381+
return other_source->Equals(*source_) && MatchesScript(other_script);
344382
}
345383

346384
Handle<Object> ScriptCacheKey::AsHandle(Isolate* isolate,
@@ -467,6 +505,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::EnsureScriptTableCapacity(
467505

468506
Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
469507
Handle<CompilationCacheTable> cache, Handle<String> src,
508+
MaybeHandle<FixedArray> maybe_wrapped_arguments,
470509
Handle<SharedFunctionInfo> value, Isolate* isolate) {
471510
src = String::Flatten(isolate, src);
472511
Handle<Script> script = handle(Script::cast(value->script()), isolate);
@@ -478,7 +517,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
478517
isolate);
479518
ScriptCacheKey key(src, script_name, script->line_offset(),
480519
script->column_offset(), script->origin_options(),
481-
host_defined_options, isolate);
520+
host_defined_options, maybe_wrapped_arguments, isolate);
482521
Handle<Object> k = key.AsHandle(isolate, value);
483522

484523
// Check whether there is already a matching entry. If so, we must overwrite

deps/v8/src/objects/compilation-cache-table.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class CompilationCacheTable
121121
const ScriptDetails& script_details, Isolate* isolate);
122122
static Handle<CompilationCacheTable> PutScript(
123123
Handle<CompilationCacheTable> cache, Handle<String> src,
124+
MaybeHandle<FixedArray> maybe_wrapped_arguments,
124125
Handle<SharedFunctionInfo> value, Isolate* isolate);
125126

126127
// Eval code only gets cached after a second probe for the

0 commit comments

Comments
 (0)