Skip to content

Commit df1513e

Browse files
deps: V8: backport 96ee9bb9e830
Original commit message: [snapshot] Check if a cached data has wrapped arguments Fixes that ScriptCompiler::CreateCodeCacheForFunction aborts on a deserialized shared function info from a cached data accepted with ScriptCompiler::CompileFunction. If the wrapped argument list does not match, the cached data should be rejected. Refs: #56366 Change-Id: I3f0376216791d866fac8eed1ce88dfa05e919b48 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6140933 Commit-Queue: Chengzhong Wu <[email protected]> Reviewed-by: Leszek Swirski <[email protected]> Cr-Commit-Position: refs/heads/main@{#97942} Refs: v8/v8@96ee9bb Co-authored-by: Joyee Cheung <[email protected]>
1 parent d61c869 commit df1513e

File tree

3 files changed

+94
-7
lines changed

3 files changed

+94
-7
lines changed

deps/v8/src/snapshot/code-serializer.cc

+28-7
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,16 @@ ScriptCompiler::CachedData* CodeSerializer::Serialize(
7171

7272
// Serialize code object.
7373
Handle<String> source(String::cast(script->source()), isolate);
74+
Handle<FixedArray> wrapped_arguments;
75+
if (script->is_wrapped()) {
76+
wrapped_arguments =
77+
Handle<FixedArray>(script->wrapped_arguments(), isolate);
78+
}
79+
7480
HandleScope scope(isolate);
75-
CodeSerializer cs(isolate, SerializedCodeData::SourceHash(
76-
source, script->origin_options()));
81+
CodeSerializer cs(isolate,
82+
SerializedCodeData::SourceHash(source, wrapped_arguments,
83+
script->origin_options()));
7784
DisallowGarbageCollection no_gc;
7885
cs.reference_map()->AddAttachedReference(*source);
7986
AlignedCachedData* cached_data = cs.SerializeSharedFunctionInfo(info);
@@ -429,11 +436,17 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
429436

430437
HandleScope scope(isolate);
431438

439+
Handle<FixedArray> wrapped_arguments;
440+
if (!script_details.wrapped_arguments.is_null()) {
441+
wrapped_arguments = script_details.wrapped_arguments.ToHandleChecked();
442+
}
443+
432444
SerializedCodeSanityCheckResult sanity_check_result =
433445
SerializedCodeSanityCheckResult::kSuccess;
434446
const SerializedCodeData scd = SerializedCodeData::FromCachedData(
435447
cached_data,
436-
SerializedCodeData::SourceHash(source, script_details.origin_options),
448+
SerializedCodeData::SourceHash(source, wrapped_arguments,
449+
script_details.origin_options),
437450
&sanity_check_result);
438451
if (sanity_check_result != SerializedCodeSanityCheckResult::kSuccess) {
439452
if (v8_flags.profile_deserialization)
@@ -542,6 +555,11 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::FinishOffThreadDeserialize(
542555

543556
HandleScope scope(isolate);
544557

558+
Handle<FixedArray> wrapped_arguments;
559+
if (!script_details.wrapped_arguments.is_null()) {
560+
wrapped_arguments = script_details.wrapped_arguments.ToHandleChecked();
561+
}
562+
545563
// Do a source sanity check now that we have the source. It's important for
546564
// FromPartiallySanityCheckedCachedData call that the sanity_check_result
547565
// holds the result of the off-thread sanity check.
@@ -550,7 +568,8 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::FinishOffThreadDeserialize(
550568
const SerializedCodeData scd =
551569
SerializedCodeData::FromPartiallySanityCheckedCachedData(
552570
cached_data,
553-
SerializedCodeData::SourceHash(source, script_details.origin_options),
571+
SerializedCodeData::SourceHash(source, wrapped_arguments,
572+
script_details.origin_options),
554573
&sanity_check_result);
555574
if (sanity_check_result != SerializedCodeSanityCheckResult::kSuccess) {
556575
// The only case where the deserialization result could exist despite a
@@ -708,15 +727,17 @@ SerializedCodeSanityCheckResult SerializedCodeData::SanityCheckWithoutSource()
708727
return SerializedCodeSanityCheckResult::kSuccess;
709728
}
710729

711-
uint32_t SerializedCodeData::SourceHash(Handle<String> source,
712-
ScriptOriginOptions origin_options) {
730+
uint32_t SerializedCodeData::SourceHash(
731+
Handle<String> source, Handle<FixedArray> wrapped_arguments,
732+
ScriptOriginOptions origin_options) {
713733
const uint32_t source_length = source->length();
734+
const uint32_t has_wrapped_arguments = !wrapped_arguments.is_null();
714735

715736
static constexpr uint32_t kModuleFlagMask = (1 << 31);
716737
const uint32_t is_module = origin_options.IsModule() ? kModuleFlagMask : 0;
717738
DCHECK_EQ(0, source_length & kModuleFlagMask);
718739

719-
return source_length | is_module;
740+
return source_length | is_module | has_wrapped_arguments << 1;
720741
}
721742

722743
// Return ScriptData object and relinquish ownership over it to the caller.

deps/v8/src/snapshot/code-serializer.h

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ class SerializedCodeData : public SerializedData {
161161
base::Vector<const byte> Payload() const;
162162

163163
static uint32_t SourceHash(Handle<String> source,
164+
Handle<FixedArray> wrapped_arguments,
164165
ScriptOriginOptions origin_options);
165166

166167
private:

deps/v8/test/cctest/test-serialize.cc

+65
Original file line numberDiff line numberDiff line change
@@ -5442,6 +5442,71 @@ TEST(CachedCompileFunction) {
54425442
}
54435443
}
54445444

5445+
TEST(InvalidCachedCompileFunction) {
5446+
DisableAlwaysOpt();
5447+
LocalContext env;
5448+
Isolate* isolate = CcTest::i_isolate();
5449+
isolate->compilation_cache()
5450+
->DisableScriptAndEval(); // Disable same-isolate code cache.
5451+
5452+
v8::HandleScope scope(CcTest::isolate());
5453+
5454+
v8::Local<v8::String> source = v8_str("");
5455+
ScriptCompiler::CachedData* script_cache;
5456+
{
5457+
v8::ScriptCompiler::Source script_source(source);
5458+
v8::Local<v8::UnboundScript> script =
5459+
v8::ScriptCompiler::CompileUnboundScript(
5460+
reinterpret_cast<v8::Isolate*>(isolate), &script_source,
5461+
v8::ScriptCompiler::kEagerCompile)
5462+
.ToLocalChecked();
5463+
script_cache = v8::ScriptCompiler::CreateCodeCache(script);
5464+
}
5465+
5466+
ScriptCompiler::CachedData* fun_cache;
5467+
{
5468+
v8::ScriptCompiler::Source script_source(source, script_cache);
5469+
v8::Local<v8::Function> fun =
5470+
v8::ScriptCompiler::CompileFunction(
5471+
env.local(), &script_source, 0, nullptr, 0, nullptr,
5472+
v8::ScriptCompiler::kConsumeCodeCache)
5473+
.ToLocalChecked();
5474+
// Check that the cached data can be re-created.
5475+
fun_cache = v8::ScriptCompiler::CreateCodeCacheForFunction(fun);
5476+
// Check that the cached data without wrapped arguments is rejected.
5477+
CHECK(script_source.GetCachedData()->rejected);
5478+
}
5479+
5480+
{
5481+
DisallowCompilation no_compile_expected(isolate);
5482+
v8::ScriptCompiler::Source script_source(source, fun_cache);
5483+
v8::Local<v8::Function> fun =
5484+
v8::ScriptCompiler::CompileFunction(
5485+
env.local(), &script_source, 0, nullptr, 0, nullptr,
5486+
v8::ScriptCompiler::kConsumeCodeCache)
5487+
.ToLocalChecked();
5488+
v8::Local<v8::Value> result =
5489+
fun->Call(env.local(), v8::Undefined(CcTest::isolate()), 0, nullptr)
5490+
.ToLocalChecked();
5491+
CHECK(result->IsUndefined());
5492+
fun_cache = v8::ScriptCompiler::CreateCodeCacheForFunction(fun);
5493+
}
5494+
5495+
{
5496+
v8::ScriptCompiler::Source script_source(source, fun_cache);
5497+
v8::Local<v8::UnboundScript> script =
5498+
v8::ScriptCompiler::CompileUnboundScript(
5499+
reinterpret_cast<v8::Isolate*>(isolate), &script_source,
5500+
v8::ScriptCompiler::kConsumeCodeCache)
5501+
.ToLocalChecked();
5502+
// Check that the cached data can be re-created.
5503+
script_cache = v8::ScriptCompiler::CreateCodeCache(script);
5504+
// Check that the cached data with wrapped arguments is rejected.
5505+
CHECK(script_source.GetCachedData()->rejected);
5506+
delete script_cache;
5507+
}
5508+
}
5509+
54455510
TEST(CachedCompileFunctionRespectsEager) {
54465511
DisableAlwaysOpt();
54475512
LocalContext env;

0 commit comments

Comments
 (0)