diff --git a/common.gypi b/common.gypi index d3c17d47bc141b..ba554d4eb0748a 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.26', + 'v8_embedder_string': '-node.27', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/snapshot/code-serializer.cc b/deps/v8/src/snapshot/code-serializer.cc index d5c05b28e7edfa..6d4714127e35bb 100644 --- a/deps/v8/src/snapshot/code-serializer.cc +++ b/deps/v8/src/snapshot/code-serializer.cc @@ -71,9 +71,16 @@ ScriptCompiler::CachedData* CodeSerializer::Serialize( // Serialize code object. Handle source(String::cast(script->source()), isolate); + Handle wrapped_arguments; + if (script->is_wrapped()) { + wrapped_arguments = + Handle(script->wrapped_arguments(), isolate); + } + HandleScope scope(isolate); - CodeSerializer cs(isolate, SerializedCodeData::SourceHash( - source, script->origin_options())); + CodeSerializer cs(isolate, + SerializedCodeData::SourceHash(source, wrapped_arguments, + script->origin_options())); DisallowGarbageCollection no_gc; cs.reference_map()->AddAttachedReference(*source); AlignedCachedData* cached_data = cs.SerializeSharedFunctionInfo(info); @@ -429,11 +436,17 @@ MaybeHandle CodeSerializer::Deserialize( HandleScope scope(isolate); + Handle wrapped_arguments; + if (!script_details.wrapped_arguments.is_null()) { + wrapped_arguments = script_details.wrapped_arguments.ToHandleChecked(); + } + SerializedCodeSanityCheckResult sanity_check_result = SerializedCodeSanityCheckResult::kSuccess; const SerializedCodeData scd = SerializedCodeData::FromCachedData( cached_data, - SerializedCodeData::SourceHash(source, script_details.origin_options), + SerializedCodeData::SourceHash(source, wrapped_arguments, + script_details.origin_options), &sanity_check_result); if (sanity_check_result != SerializedCodeSanityCheckResult::kSuccess) { if (v8_flags.profile_deserialization) @@ -542,6 +555,11 @@ MaybeHandle CodeSerializer::FinishOffThreadDeserialize( HandleScope scope(isolate); + Handle wrapped_arguments; + if (!script_details.wrapped_arguments.is_null()) { + wrapped_arguments = script_details.wrapped_arguments.ToHandleChecked(); + } + // Do a source sanity check now that we have the source. It's important for // FromPartiallySanityCheckedCachedData call that the sanity_check_result // holds the result of the off-thread sanity check. @@ -550,7 +568,8 @@ MaybeHandle CodeSerializer::FinishOffThreadDeserialize( const SerializedCodeData scd = SerializedCodeData::FromPartiallySanityCheckedCachedData( cached_data, - SerializedCodeData::SourceHash(source, script_details.origin_options), + SerializedCodeData::SourceHash(source, wrapped_arguments, + script_details.origin_options), &sanity_check_result); if (sanity_check_result != SerializedCodeSanityCheckResult::kSuccess) { // The only case where the deserialization result could exist despite a @@ -708,15 +727,17 @@ SerializedCodeSanityCheckResult SerializedCodeData::SanityCheckWithoutSource() return SerializedCodeSanityCheckResult::kSuccess; } -uint32_t SerializedCodeData::SourceHash(Handle source, - ScriptOriginOptions origin_options) { +uint32_t SerializedCodeData::SourceHash( + Handle source, Handle wrapped_arguments, + ScriptOriginOptions origin_options) { const uint32_t source_length = source->length(); + const uint32_t has_wrapped_arguments = !wrapped_arguments.is_null(); static constexpr uint32_t kModuleFlagMask = (1 << 31); const uint32_t is_module = origin_options.IsModule() ? kModuleFlagMask : 0; DCHECK_EQ(0, source_length & kModuleFlagMask); - return source_length | is_module; + return source_length | is_module | has_wrapped_arguments << 1; } // Return ScriptData object and relinquish ownership over it to the caller. diff --git a/deps/v8/src/snapshot/code-serializer.h b/deps/v8/src/snapshot/code-serializer.h index 248fc0824afc14..f0894aa47abcef 100644 --- a/deps/v8/src/snapshot/code-serializer.h +++ b/deps/v8/src/snapshot/code-serializer.h @@ -161,6 +161,7 @@ class SerializedCodeData : public SerializedData { base::Vector Payload() const; static uint32_t SourceHash(Handle source, + Handle wrapped_arguments, ScriptOriginOptions origin_options); private: diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 35b8a9496839b9..056a1bda7166c9 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -5442,6 +5442,71 @@ TEST(CachedCompileFunction) { } } +TEST(InvalidCachedCompileFunction) { + DisableAlwaysOpt(); + LocalContext env; + Isolate* isolate = CcTest::i_isolate(); + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. + + v8::HandleScope scope(CcTest::isolate()); + + v8::Local source = v8_str(""); + ScriptCompiler::CachedData* script_cache; + { + v8::ScriptCompiler::Source script_source(source); + v8::Local script = + v8::ScriptCompiler::CompileUnboundScript( + reinterpret_cast(isolate), &script_source, + v8::ScriptCompiler::kEagerCompile) + .ToLocalChecked(); + script_cache = v8::ScriptCompiler::CreateCodeCache(script); + } + + ScriptCompiler::CachedData* fun_cache; + { + v8::ScriptCompiler::Source script_source(source, script_cache); + v8::Local fun = + v8::ScriptCompiler::CompileFunction( + env.local(), &script_source, 0, nullptr, 0, nullptr, + v8::ScriptCompiler::kConsumeCodeCache) + .ToLocalChecked(); + // Check that the cached data can be re-created. + fun_cache = v8::ScriptCompiler::CreateCodeCacheForFunction(fun); + // Check that the cached data without wrapped arguments is rejected. + CHECK(script_source.GetCachedData()->rejected); + } + + { + DisallowCompilation no_compile_expected(isolate); + v8::ScriptCompiler::Source script_source(source, fun_cache); + v8::Local fun = + v8::ScriptCompiler::CompileFunction( + env.local(), &script_source, 0, nullptr, 0, nullptr, + v8::ScriptCompiler::kConsumeCodeCache) + .ToLocalChecked(); + v8::Local result = + fun->Call(env.local(), v8::Undefined(CcTest::isolate()), 0, nullptr) + .ToLocalChecked(); + CHECK(result->IsUndefined()); + fun_cache = v8::ScriptCompiler::CreateCodeCacheForFunction(fun); + } + + { + v8::ScriptCompiler::Source script_source(source, fun_cache); + v8::Local script = + v8::ScriptCompiler::CompileUnboundScript( + reinterpret_cast(isolate), &script_source, + v8::ScriptCompiler::kConsumeCodeCache) + .ToLocalChecked(); + // Check that the cached data can be re-created. + script_cache = v8::ScriptCompiler::CreateCodeCache(script); + // Check that the cached data with wrapped arguments is rejected. + CHECK(script_source.GetCachedData()->rejected); + delete script_cache; + } +} + TEST(CachedCompileFunctionRespectsEager) { DisableAlwaysOpt(); LocalContext env;