Use outer language mode when storing streamed script in isolate cache
Currently, a streamed script which specifies 'use strict' is stored in the isolate script cache with a key indicating that it is strict mode. However, the keys should be based on the context executing the script, not the content of the script, so that the next lookup can find the entry without having to parse the script first. Bug: v8:12668 Change-Id: Iaa76c00c431ad54a86ffd18b61cb4f67dc457b03 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3498220 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/main@{#79331}
This commit is contained in:
parent
6c3d4ddd3e
commit
c2fa5fccb1
@ -1430,8 +1430,7 @@ BackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* streamed_data,
|
||||
timer_(isolate->counters()->compile_script_on_background()),
|
||||
start_position_(0),
|
||||
end_position_(0),
|
||||
function_literal_id_(kFunctionLiteralIdTopLevel),
|
||||
language_mode_(flags_.outer_language_mode()) {
|
||||
function_literal_id_(kFunctionLiteralIdTopLevel) {
|
||||
VMState<PARSER> state(isolate);
|
||||
|
||||
LOG(isolate, ScriptEvent(Logger::ScriptEventType::kStreamingCompile,
|
||||
@ -1455,8 +1454,7 @@ BackgroundCompileTask::BackgroundCompileTask(
|
||||
input_shared_info_(shared_info),
|
||||
start_position_(shared_info->StartPosition()),
|
||||
end_position_(shared_info->EndPosition()),
|
||||
function_literal_id_(shared_info->function_literal_id()),
|
||||
language_mode_(flags_.outer_language_mode()) {
|
||||
function_literal_id_(shared_info->function_literal_id()) {
|
||||
DCHECK(!shared_info->is_toplevel());
|
||||
|
||||
character_stream_->Seek(start_position_);
|
||||
@ -1594,9 +1592,6 @@ void BackgroundCompileTask::Run(
|
||||
function_literal_id_);
|
||||
parser.UpdateStatistics(script_, &use_counts_, &total_preparse_skipped_);
|
||||
|
||||
// Save the language mode.
|
||||
language_mode_ = info.language_mode();
|
||||
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
||||
"V8.CompileCodeBackground");
|
||||
RCS_SCOPE(isolate, RuntimeCallCounterIdForCompile(&info),
|
||||
@ -1628,9 +1623,6 @@ void BackgroundCompileTask::Run(
|
||||
outer_function_sfi_ = isolate->heap()->NewPersistentMaybeHandle(maybe_result);
|
||||
DCHECK(isolate->heap()->ContainsPersistentHandle(script_.location()));
|
||||
persistent_handles_ = isolate->heap()->DetachPersistentHandles();
|
||||
|
||||
// Make sure the language mode didn't change.
|
||||
DCHECK_EQ(language_mode_, info.language_mode());
|
||||
}
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> BackgroundCompileTask::FinalizeScript(
|
||||
@ -3182,8 +3174,8 @@ Compiler::GetSharedFunctionInfoForStreamedScript(
|
||||
{
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
||||
"V8.StreamingFinalization.CheckCache");
|
||||
maybe_result = compilation_cache->LookupScript(source, script_details,
|
||||
task->language_mode());
|
||||
maybe_result = compilation_cache->LookupScript(
|
||||
source, script_details, task->flags().outer_language_mode());
|
||||
if (!maybe_result.is_null()) {
|
||||
compile_timer.set_hit_isolate_cache();
|
||||
}
|
||||
@ -3204,7 +3196,8 @@ Compiler::GetSharedFunctionInfoForStreamedScript(
|
||||
// Add compiled code to the isolate cache.
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
||||
"V8.StreamingFinalization.AddToCache");
|
||||
compilation_cache->PutScript(source, task->language_mode(), result);
|
||||
compilation_cache->PutScript(source, task->flags().outer_language_mode(),
|
||||
result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,7 +529,6 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
|
||||
void AbortFunction();
|
||||
|
||||
UnoptimizedCompileFlags flags() const { return flags_; }
|
||||
LanguageMode language_mode() const { return language_mode_; }
|
||||
|
||||
private:
|
||||
void ReportStatistics(Isolate* isolate);
|
||||
@ -561,8 +560,6 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
|
||||
int start_position_;
|
||||
int end_position_;
|
||||
int function_literal_id_;
|
||||
|
||||
LanguageMode language_mode_;
|
||||
};
|
||||
|
||||
// Contains all data which needs to be transmitted between threads for
|
||||
|
@ -24255,6 +24255,57 @@ TEST(StreamingWithHarmonyScopes) {
|
||||
delete[] full_source;
|
||||
}
|
||||
|
||||
// Regression test for crbug.com/v8/12668. Verifies that after a streamed script
|
||||
// is inserted into the isolate script cache, a non-streamed script with
|
||||
// identical origin can reuse that data.
|
||||
TEST(StreamingWithIsolateScriptCache) {
|
||||
const char* chunks[] = {"'use strict'; (function test() { return 13; })",
|
||||
nullptr};
|
||||
const char* full_source = chunks[0];
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::ScriptOrigin origin(isolate, v8_str("http://foo.com"), 0, 0, false, -1,
|
||||
v8::Local<v8::Value>(), false, false, false);
|
||||
i::Handle<i::JSFunction> first_function;
|
||||
i::Handle<i::JSFunction> second_function;
|
||||
|
||||
// Run the script using streaming.
|
||||
{
|
||||
LocalContext env;
|
||||
|
||||
v8::ScriptCompiler::StreamedSource source(
|
||||
std::make_unique<TestSourceStream>(chunks),
|
||||
v8::ScriptCompiler::StreamedSource::ONE_BYTE);
|
||||
v8::ScriptCompiler::ScriptStreamingTask* task =
|
||||
v8::ScriptCompiler::StartStreaming(isolate, &source,
|
||||
v8::ScriptType::kClassic);
|
||||
StreamerThread::StartThreadForTaskAndJoin(task);
|
||||
delete task;
|
||||
v8::Local<Script> script =
|
||||
v8::ScriptCompiler::Compile(env.local(), &source, v8_str(full_source),
|
||||
origin)
|
||||
.ToLocalChecked();
|
||||
v8::Local<Value> result(script->Run(env.local()).ToLocalChecked());
|
||||
first_function =
|
||||
i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*result));
|
||||
}
|
||||
|
||||
// Run the same script in another Context without streaming.
|
||||
{
|
||||
LocalContext env;
|
||||
v8::ScriptCompiler::Source script_source(v8_str(full_source), origin);
|
||||
Local<Script> script =
|
||||
v8::ScriptCompiler::Compile(env.local(), &script_source)
|
||||
.ToLocalChecked();
|
||||
v8::Local<Value> result(script->Run(env.local()).ToLocalChecked());
|
||||
second_function =
|
||||
i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*result));
|
||||
}
|
||||
|
||||
// The functions created by both copies of the script should refer to the same
|
||||
// SharedFunctionInfo instance due to the isolate script cache.
|
||||
CHECK_EQ(first_function->shared(), second_function->shared());
|
||||
}
|
||||
|
||||
TEST(CodeCache) {
|
||||
v8::Isolate::CreateParams create_params;
|
||||
|
Loading…
Reference in New Issue
Block a user