Skip to content

Commit c5ee93e

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 0a046d0 commit c5ee93e

File tree

10 files changed

+357
-40
lines changed

10 files changed

+357
-40
lines changed

common.gypi

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

3737
# Reset this number to 0 on major V8 upgrades.
3838
# Increment by one for each non-official patch applied to deps/v8.
39-
'v8_embedder_string': '-node.26',
39+
'v8_embedder_string': '-node.27',
4040

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

deps/v8/src/api/api.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2861,6 +2861,7 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInternal(
28612861
i_isolate, source->resource_name, source->resource_line_offset,
28622862
source->resource_column_offset, source->source_map_url,
28632863
source->host_defined_options, source->resource_options);
2864+
script_details.wrapped_arguments = arguments_list;
28642865

28652866
std::unique_ptr<i::AlignedCachedData> cached_data;
28662867
if (options == kConsumeCodeCache) {
@@ -2873,8 +2874,8 @@ MaybeLocal<Function> ScriptCompiler::CompileFunctionInternal(
28732874
i::Handle<i::JSFunction> scoped_result;
28742875
has_pending_exception =
28752876
!i::Compiler::GetWrappedFunction(
2876-
Utils::OpenHandle(*source->source_string), arguments_list, context,
2877-
script_details, cached_data.get(), options, no_cache_reason)
2877+
Utils::OpenHandle(*source->source_string), context, script_details,
2878+
cached_data.get(), options, no_cache_reason)
28782879
.ToHandle(&scoped_result);
28792880
if (options == kConsumeCodeCache) {
28802881
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
@@ -190,8 +190,8 @@ void CompilationCacheScript::Put(Handle<String> source,
190190
Handle<SharedFunctionInfo> function_info) {
191191
HandleScope scope(isolate());
192192
Handle<CompilationCacheTable> table = GetTable();
193-
table_ = *CompilationCacheTable::PutScript(table, source, function_info,
194-
isolate());
193+
table_ = *CompilationCacheTable::PutScript(table, source, kNullMaybeHandle,
194+
function_info, isolate());
195195
}
196196

197197
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
@@ -3255,14 +3255,13 @@ struct ScriptCompileTimerScope {
32553255
}
32563256
};
32573257

3258-
Handle<Script> NewScript(
3259-
Isolate* isolate, ParseInfo* parse_info, Handle<String> source,
3260-
ScriptDetails script_details, NativesFlag natives,
3261-
MaybeHandle<FixedArray> maybe_wrapped_arguments = kNullMaybeHandle) {
3258+
Handle<Script> NewScript(Isolate* isolate, ParseInfo* parse_info,
3259+
Handle<String> source, ScriptDetails script_details,
3260+
NativesFlag natives) {
32623261
// Create a script object describing the script to be compiled.
3263-
Handle<Script> script =
3264-
parse_info->CreateScript(isolate, source, maybe_wrapped_arguments,
3265-
script_details.origin_options, natives);
3262+
Handle<Script> script = parse_info->CreateScript(
3263+
isolate, source, script_details.wrapped_arguments,
3264+
script_details.origin_options, natives);
32663265
DisallowGarbageCollection no_gc;
32673266
SetScriptFieldsFromDetails(isolate, *script, script_details, &no_gc);
32683267
LOG(isolate, ScriptDetails(*script));
@@ -3639,26 +3638,37 @@ Compiler::GetSharedFunctionInfoForScriptWithCompileHints(
36393638

36403639
// static
36413640
MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
3642-
Handle<String> source, Handle<FixedArray> arguments,
3643-
Handle<Context> context, const ScriptDetails& script_details,
3644-
AlignedCachedData* cached_data,
3641+
Handle<String> source, Handle<Context> context,
3642+
const ScriptDetails& script_details, AlignedCachedData* cached_data,
36453643
v8::ScriptCompiler::CompileOptions compile_options,
36463644
v8::ScriptCompiler::NoCacheReason no_cache_reason) {
36473645
Isolate* isolate = context->GetIsolate();
36483646
ScriptCompileTimerScope compile_timer(isolate, no_cache_reason);
36493647

36503648
if (compile_options == ScriptCompiler::kConsumeCodeCache) {
36513649
DCHECK(cached_data);
3650+
DCHECK_EQ(script_details.repl_mode, REPLMode::kNo);
36523651
} else {
36533652
DCHECK_NULL(cached_data);
36543653
}
36553654

36563655
LanguageMode language_mode = construct_language_mode(v8_flags.use_strict);
3657-
3656+
DCHECK(!script_details.wrapped_arguments.is_null());
36583657
MaybeHandle<SharedFunctionInfo> maybe_result;
3658+
Handle<SharedFunctionInfo> result;
3659+
Handle<Script> script;
3660+
IsCompiledScope is_compiled_scope;
36593661
bool can_consume_code_cache =
36603662
compile_options == ScriptCompiler::kConsumeCodeCache;
3661-
if (can_consume_code_cache) {
3663+
CompilationCache* compilation_cache = isolate->compilation_cache();
3664+
// First check per-isolate compilation cache.
3665+
CompilationCacheScript::LookupResult lookup_result =
3666+
compilation_cache->LookupScript(source, script_details, language_mode);
3667+
maybe_result = lookup_result.toplevel_sfi();
3668+
if (maybe_result.ToHandle(&result)) {
3669+
is_compiled_scope = result->is_compiled_scope(isolate);
3670+
compile_timer.set_hit_isolate_cache();
3671+
} else if (can_consume_code_cache) {
36623672
compile_timer.set_consuming_code_cache();
36633673
// Then check cached code provided by embedder.
36643674
NestedTimedHistogramScope timer(isolate->counters()->compile_deserialize());
@@ -3667,16 +3677,22 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
36673677
"V8.CompileDeserialize");
36683678
maybe_result = CodeSerializer::Deserialize(isolate, cached_data, source,
36693679
script_details.origin_options);
3670-
if (maybe_result.is_null()) {
3680+
bool consuming_code_cache_succeeded = false;
3681+
if (maybe_result.ToHandle(&result)) {
3682+
is_compiled_scope = result->is_compiled_scope(isolate);
3683+
if (is_compiled_scope.is_compiled()) {
3684+
consuming_code_cache_succeeded = true;
3685+
// Promote to per-isolate compilation cache.
3686+
compilation_cache->PutScript(source, language_mode, result);
3687+
}
3688+
}
3689+
if (!consuming_code_cache_succeeded) {
36713690
// Deserializer failed. Fall through to compile.
36723691
compile_timer.set_consuming_code_cache_failed();
36733692
}
36743693
}
36753694

3676-
Handle<SharedFunctionInfo> wrapped;
3677-
Handle<Script> script;
3678-
IsCompiledScope is_compiled_scope;
3679-
if (!maybe_result.ToHandle(&wrapped)) {
3695+
if (maybe_result.is_null()) {
36803696
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForToplevelCompile(
36813697
isolate, true, language_mode, script_details.repl_mode,
36823698
ScriptType::kClassic, v8_flags.lazy);
@@ -3696,9 +3712,8 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
36963712
if (!context->IsNativeContext()) {
36973713
maybe_outer_scope_info = handle(context->scope_info(), isolate);
36983714
}
3699-
37003715
script = NewScript(isolate, &parse_info, source, script_details,
3701-
NOT_NATIVES_CODE, arguments);
3716+
NOT_NATIVES_CODE);
37023717

37033718
Handle<SharedFunctionInfo> top_level;
37043719
maybe_result = v8::internal::CompileToplevel(&parse_info, script,
@@ -3711,18 +3726,23 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
37113726
for (SharedFunctionInfo info = infos.Next(); !info.is_null();
37123727
info = infos.Next()) {
37133728
if (info.is_wrapped()) {
3714-
wrapped = Handle<SharedFunctionInfo>(info, isolate);
3729+
result = Handle<SharedFunctionInfo>(info, isolate);
37153730
break;
37163731
}
37173732
}
3718-
DCHECK(!wrapped.is_null());
3719-
} else {
3720-
is_compiled_scope = wrapped->is_compiled_scope(isolate);
3721-
script = Handle<Script>(Script::cast(wrapped->script()), isolate);
3733+
DCHECK(!result.is_null());
3734+
3735+
is_compiled_scope = result->is_compiled_scope(isolate);
3736+
script = Handle<Script>(Script::cast(result->script()), isolate);
3737+
// Add the result to the isolate cache if there's no context extension.
3738+
if (maybe_outer_scope_info.is_null()) {
3739+
compilation_cache->PutScript(source, language_mode, result);
3740+
}
37223741
}
3742+
37233743
DCHECK(is_compiled_scope.is_compiled());
37243744

3725-
return Factory::JSFunctionBuilder{isolate, wrapped, context}
3745+
return Factory::JSFunctionBuilder{isolate, result, context}
37263746
.set_allocation_type(AllocationType::kYoung)
37273747
.Build();
37283748
}

deps/v8/src/codegen/compiler.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,8 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
153153
// Create a function that results from wrapping |source| in a function,
154154
// with |arguments| being a list of parameters for that function.
155155
V8_WARN_UNUSED_RESULT static MaybeHandle<JSFunction> GetWrappedFunction(
156-
Handle<String> source, Handle<FixedArray> arguments,
157-
Handle<Context> context, const ScriptDetails& script_details,
158-
AlignedCachedData* cached_data,
156+
Handle<String> source, Handle<Context> context,
157+
const ScriptDetails& script_details, AlignedCachedData* cached_data,
159158
v8::ScriptCompiler::CompileOptions compile_options,
160159
v8::ScriptCompiler::NoCacheReason no_cache_reason);
161160

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
@@ -67,10 +67,12 @@ class ScriptCacheKey : public HashTableKey {
6767
ScriptCacheKey(Handle<String> source, MaybeHandle<Object> name,
6868
int line_offset, int column_offset,
6969
v8::ScriptOriginOptions origin_options,
70-
MaybeHandle<Object> host_defined_options, Isolate* isolate);
70+
MaybeHandle<Object> host_defined_options,
71+
MaybeHandle<FixedArray> maybe_wrapped_arguments,
72+
Isolate* isolate);
7173

7274
bool IsMatch(Object other) override;
73-
bool MatchesOrigin(Script script);
75+
bool MatchesScript(Script script);
7476

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

@@ -98,6 +100,7 @@ class ScriptCacheKey : public HashTableKey {
98100
int column_offset_;
99101
v8::ScriptOriginOptions origin_options_;
100102
MaybeHandle<Object> host_defined_options_;
103+
MaybeHandle<FixedArray> wrapped_arguments_;
101104
Isolate* isolate_;
102105
};
103106

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

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

250250
// If the script name isn't set, the boilerplate script should have
@@ -268,6 +268,30 @@ bool ScriptCacheKey::MatchesOrigin(Script script) {
268268
return false;
269269
}
270270

271+
Handle<FixedArray> wrapped_arguments_handle;
272+
if (wrapped_arguments_.ToHandle(&wrapped_arguments_handle)) {
273+
if (!script.is_wrapped()) {
274+
return false;
275+
}
276+
FixedArray wrapped_arguments = *wrapped_arguments_handle;
277+
FixedArray other_wrapped_arguments = script.wrapped_arguments();
278+
int length = wrapped_arguments.length();
279+
if (length != other_wrapped_arguments.length()) {
280+
return false;
281+
}
282+
for (int i = 0; i < length; i++) {
283+
Object arg = wrapped_arguments.get(i);
284+
Object other_arg = other_wrapped_arguments.get(i);
285+
DCHECK(arg.IsString());
286+
DCHECK(other_arg.IsString());
287+
if (!String::cast(arg).Equals(String::cast(other_arg))) {
288+
return false;
289+
}
290+
}
291+
} else if (script.is_wrapped()) {
292+
return false;
293+
}
294+
271295
// Don't compare host options if the script was deserialized because we didn't
272296
// serialize host options (see CodeSerializer::SerializeObjectImpl())
273297
if (script.deserialized() &&
@@ -303,12 +327,14 @@ ScriptCacheKey::ScriptCacheKey(Handle<String> source,
303327
: ScriptCacheKey(source, script_details->name_obj,
304328
script_details->line_offset, script_details->column_offset,
305329
script_details->origin_options,
306-
script_details->host_defined_options, isolate) {}
330+
script_details->host_defined_options,
331+
script_details->wrapped_arguments, isolate) {}
307332

308333
ScriptCacheKey::ScriptCacheKey(Handle<String> source, MaybeHandle<Object> name,
309334
int line_offset, int column_offset,
310335
v8::ScriptOriginOptions origin_options,
311336
MaybeHandle<Object> host_defined_options,
337+
MaybeHandle<FixedArray> maybe_wrapped_arguments,
312338
Isolate* isolate)
313339
: HashTableKey(static_cast<uint32_t>(ScriptHash(*source, name, line_offset,
314340
column_offset,
@@ -320,8 +346,19 @@ ScriptCacheKey::ScriptCacheKey(Handle<String> source, MaybeHandle<Object> name,
320346
column_offset_(column_offset),
321347
origin_options_(origin_options),
322348
host_defined_options_(host_defined_options),
349+
wrapped_arguments_(maybe_wrapped_arguments),
323350
isolate_(isolate) {
324351
DCHECK(Smi::IsValid(static_cast<int>(Hash())));
352+
#ifdef DEBUG
353+
Handle<FixedArray> wrapped_arguments;
354+
if (maybe_wrapped_arguments.ToHandle(&wrapped_arguments)) {
355+
int length = wrapped_arguments->length();
356+
for (int i = 0; i < length; i++) {
357+
Object arg = wrapped_arguments->get(i);
358+
DCHECK(arg.IsString());
359+
}
360+
}
361+
#endif
325362
}
326363

327364
bool ScriptCacheKey::IsMatch(Object other) {
@@ -342,7 +379,7 @@ bool ScriptCacheKey::IsMatch(Object other) {
342379
}
343380
Script other_script = Script::cast(other_script_object);
344381
String other_source = String::cast(other_script.source());
345-
return other_source.Equals(*source_) && MatchesOrigin(other_script);
382+
return other_source.Equals(*source_) && MatchesScript(other_script);
346383
}
347384

348385
Handle<Object> ScriptCacheKey::AsHandle(Isolate* isolate,
@@ -469,6 +506,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::EnsureScriptTableCapacity(
469506

470507
Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
471508
Handle<CompilationCacheTable> cache, Handle<String> src,
509+
MaybeHandle<FixedArray> maybe_wrapped_arguments,
472510
Handle<SharedFunctionInfo> value, Isolate* isolate) {
473511
src = String::Flatten(isolate, src);
474512
Handle<Script> script = handle(Script::cast(value->script()), isolate);
@@ -480,7 +518,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
480518
isolate);
481519
ScriptCacheKey key(src, script_name, script->line_offset(),
482520
script->column_offset(), script->origin_options(),
483-
host_defined_options, isolate);
521+
host_defined_options, maybe_wrapped_arguments, isolate);
484522
Handle<Object> k = key.AsHandle(isolate, value);
485523

486524
// 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
@@ -119,6 +119,7 @@ class CompilationCacheTable
119119
const ScriptDetails& script_details, Isolate* isolate);
120120
static Handle<CompilationCacheTable> PutScript(
121121
Handle<CompilationCacheTable> cache, Handle<String> src,
122+
MaybeHandle<FixedArray> maybe_wrapped_arguments,
122123
Handle<SharedFunctionInfo> value, Isolate* isolate);
123124

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

0 commit comments

Comments
 (0)