Commit 7f9de3dc authored by Yang Guo's avatar Yang Guo Committed by Commit Bot

[snapshot] add kProduceExhaustiveCodeCache option.

- Add kProduceExhaustiveCodeCache to v8::ScriptCompiler::CompileOptions
  to request eager compilation to add as much as possible to the code
  cache for the script.
- Repurpose ParseInfo::kLazy flag.
- Remove ParseInfo::kDebug flag.
- Remove --serialize-toplevel as it has become obsolete.

R=marja@chromium.org

Bug: chromium:768705
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: Ife14f7a1d1c02e525f0b9dbfd2452013d67c7167
Reviewed-on: https://chromium-review.googlesource.com/684019
Commit-Queue: Yang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48160}
parent 2c8ec6b5
......@@ -1436,6 +1436,7 @@ class V8_EXPORT ScriptCompiler {
kProduceParserCache,
kConsumeParserCache,
kProduceCodeCache,
kProduceFullCodeCache,
kConsumeCodeCache
};
......
......@@ -2274,10 +2274,12 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
ENTER_V8_NO_SCRIPT(isolate, v8_isolate->GetCurrentContext(), ScriptCompiler,
CompileUnbound, MaybeLocal<UnboundScript>(),
InternalEscapableScope);
bool produce_cache = options == kProduceParserCache ||
options == kProduceCodeCache ||
options == kProduceFullCodeCache;
// Don't try to produce any kind of cache when the debugger is loaded.
if (isolate->debug()->is_loaded() &&
(options == kProduceParserCache || options == kProduceCodeCache)) {
if (isolate->debug()->is_loaded() && produce_cache) {
options = kNoCompileOptions;
}
......@@ -2330,8 +2332,7 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
}
RETURN_ON_FAILED_EXECUTION(UnboundScript);
if ((options == kProduceParserCache || options == kProduceCodeCache) &&
script_data != NULL) {
if (produce_cache && script_data != NULL) {
// script_data now contains the data that was generated. source will
// take the ownership.
source->cached_data = new CachedData(
......
......@@ -26,6 +26,7 @@ BackgroundParsingTask::BackgroundParsingTask(
// on the foreground thread.
DCHECK(options == ScriptCompiler::kProduceParserCache ||
options == ScriptCompiler::kProduceCodeCache ||
options == ScriptCompiler::kProduceFullCodeCache ||
options == ScriptCompiler::kNoCompileOptions);
VMState<PARSER> state(isolate);
......
......@@ -1006,7 +1006,7 @@ MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) {
// Start a compilation.
ParseInfo parse_info(script);
parse_info.set_is_debug();
parse_info.set_eager();
// TODO(635): support extensions.
Handle<JSArray> infos;
......@@ -1159,6 +1159,11 @@ bool ContainsAsmModule(Handle<Script> script) {
return false;
}
bool ShouldProduceCodeCache(ScriptCompiler::CompileOptions options) {
return options == ScriptCompiler::kProduceCodeCache ||
options == ScriptCompiler::kProduceFullCodeCache;
}
} // namespace
bool Compiler::CodeGenerationFromStringsAllowed(Isolate* isolate,
......@@ -1215,7 +1220,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
if (compile_options == ScriptCompiler::kNoCompileOptions) {
cached_data = NULL;
} else if (compile_options == ScriptCompiler::kProduceParserCache ||
compile_options == ScriptCompiler::kProduceCodeCache) {
ShouldProduceCodeCache(compile_options)) {
DCHECK(cached_data && !*cached_data);
DCHECK(extension == NULL);
DCHECK(!isolate->debug()->is_loaded());
......@@ -1240,7 +1245,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
InfoVectorPair pair = compilation_cache->LookupScript(
source, script_name, line_offset, column_offset, resource_options,
context, language_mode);
if (!pair.has_shared() && FLAG_serialize_toplevel &&
if (!pair.has_shared() &&
compile_options == ScriptCompiler::kConsumeCodeCache &&
!isolate->debug()->is_loaded()) {
// Then check cached code provided by embedder.
......@@ -1275,14 +1280,11 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
}
base::ElapsedTimer timer;
if (FLAG_profile_deserialization && FLAG_serialize_toplevel &&
compile_options == ScriptCompiler::kProduceCodeCache) {
if (FLAG_profile_deserialization && ShouldProduceCodeCache(compile_options)) {
timer.Start();
}
if (result.is_null() ||
(FLAG_serialize_toplevel &&
compile_options == ScriptCompiler::kProduceCodeCache)) {
if (result.is_null() || ShouldProduceCodeCache(compile_options)) {
// No cache entry found, or embedder wants a code cache. Compile the script.
// Create a script object describing the script to be compiled.
......@@ -1322,9 +1324,10 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
if (!context->IsNativeContext()) {
parse_info.set_outer_scope_info(handle(context->scope_info()));
}
if (FLAG_serialize_toplevel &&
compile_options == ScriptCompiler::kProduceCodeCache) {
if (ShouldProduceCodeCache(compile_options)) {
parse_info.set_will_serialize();
parse_info.set_eager(compile_options ==
ScriptCompiler::kProduceFullCodeCache);
}
parse_info.set_language_mode(
......@@ -1338,8 +1341,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
vector = isolate->factory()->NewCell(feedback_vector);
compilation_cache->PutScript(source, context, language_mode, result,
vector);
if (FLAG_serialize_toplevel &&
compile_options == ScriptCompiler::kProduceCodeCache &&
if (ShouldProduceCodeCache(compile_options) &&
!ContainsAsmModule(script)) {
HistogramTimerScope histogram_timer(
isolate->counters()->compile_serialize());
......
......@@ -772,7 +772,6 @@ DEFINE_BOOL(always_opt, false, "always try to optimize functions")
DEFINE_BOOL(always_osr, false, "always try to OSR functions")
DEFINE_BOOL(prepare_always_opt, false, "prepare for turning on always opt")
DEFINE_BOOL(serialize_toplevel, true, "enable caching of toplevel scripts")
DEFINE_BOOL(serialize_eager, false, "compile eagerly when caching scripts")
DEFINE_BOOL(trace_serializer, false, "print code serializer trace")
#ifdef DEBUG
......
......@@ -65,6 +65,7 @@ class V8_EXPORT_PRIVATE ParseInfo {
void setter(bool val) { SetFlag(flag, val); }
FLAG_ACCESSOR(kToplevel, is_toplevel, set_toplevel)
FLAG_ACCESSOR(kEager, is_eager, set_eager)
FLAG_ACCESSOR(kEval, is_eval, set_eval)
FLAG_ACCESSOR(kStrictMode, is_strict_mode, set_strict_mode)
FLAG_ACCESSOR(kNative, is_native, set_native)
......@@ -72,7 +73,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
FLAG_ACCESSOR(kAllowLazyParsing, allow_lazy_parsing, set_allow_lazy_parsing)
FLAG_ACCESSOR(kIsNamedExpression, is_named_expression,
set_is_named_expression)
FLAG_ACCESSOR(kDebug, is_debug, set_is_debug)
FLAG_ACCESSOR(kSerializing, will_serialize, set_will_serialize)
FLAG_ACCESSOR(kLazyCompile, lazy_compile, set_lazy_compile)
FLAG_ACCESSOR(kCollectTypeProfile, collect_type_profile,
......@@ -236,7 +236,7 @@ class V8_EXPORT_PRIVATE ParseInfo {
enum Flag {
// ---------- Input flags ---------------------------
kToplevel = 1 << 0,
kLazy = 1 << 1,
kEager = 1 << 1,
kEval = 1 << 2,
kStrictMode = 1 << 3,
kNative = 1 << 4,
......@@ -244,12 +244,11 @@ class V8_EXPORT_PRIVATE ParseInfo {
kModule = 1 << 6,
kAllowLazyParsing = 1 << 7,
kIsNamedExpression = 1 << 8,
kDebug = 1 << 9,
kSerializing = 1 << 10,
kLazyCompile = 1 << 11,
kCollectTypeProfile = 1 << 12,
kBlockCoverageEnabled = 1 << 13,
kIsAsmWasmBroken = 1 << 14,
kSerializing = 1 << 9,
kLazyCompile = 1 << 10,
kCollectTypeProfile = 1 << 11,
kBlockCoverageEnabled = 1 << 12,
kIsAsmWasmBroken = 1 << 13,
};
//------------- Inputs to parsing and scope analysis -----------------------
......
......@@ -489,10 +489,8 @@ Parser::Parser(ParseInfo* info)
// aggressive about lazy compilation, because it might trigger compilation
// of functions without an outer context when setting a breakpoint through
// Debug::FindSharedFunctionInfoInScript
bool can_compile_lazily = FLAG_lazy && !info->is_debug();
// Consider compiling eagerly when targeting the code cache.
can_compile_lazily &= !(FLAG_serialize_eager && info->will_serialize());
// We also compile eagerly for kProduceExhaustiveCodeCache.
bool can_compile_lazily = FLAG_lazy && !info->is_eager();
set_default_eager_compile_hint(can_compile_lazily
? FunctionLiteral::kShouldLazyCompile
......
......@@ -1206,7 +1206,6 @@ static Handle<SharedFunctionInfo> CompileScript(
}
TEST(CodeSerializerOnePlusOne) {
FLAG_serialize_toplevel = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
......@@ -1256,7 +1255,6 @@ TEST(CodeSerializerOnePlusOne) {
}
TEST(CodeSerializerPromotedToCompilationCache) {
FLAG_serialize_toplevel = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
......@@ -1286,7 +1284,6 @@ TEST(CodeSerializerPromotedToCompilationCache) {
}
TEST(CodeSerializerInternalizedString) {
FLAG_serialize_toplevel = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
......@@ -1345,7 +1342,6 @@ TEST(CodeSerializerInternalizedString) {
}
TEST(CodeSerializerLargeCodeObject) {
FLAG_serialize_toplevel = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
......@@ -1398,7 +1394,6 @@ TEST(CodeSerializerLargeCodeObject) {
TEST(CodeSerializerLargeCodeObjectWithIncrementalMarking) {
if (FLAG_never_compact) return;
ManualGCScope manual_gc_scope;
FLAG_serialize_toplevel = true;
FLAG_always_opt = false;
const char* filter_flag = "--turbo-filter=NOTHING";
FlagList::SetFlagsFromString(filter_flag, StrLength(filter_flag));
......@@ -1475,7 +1470,6 @@ TEST(CodeSerializerLargeCodeObjectWithIncrementalMarking) {
source.Dispose();
}
TEST(CodeSerializerLargeStrings) {
FLAG_serialize_toplevel = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
Factory* f = isolate->factory();
......@@ -1532,7 +1526,6 @@ TEST(CodeSerializerLargeStrings) {
}
TEST(CodeSerializerThreeBigStrings) {
FLAG_serialize_toplevel = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
Factory* f = isolate->factory();
......@@ -1642,7 +1635,6 @@ class SerializerTwoByteResource : public v8::String::ExternalStringResource {
};
TEST(CodeSerializerExternalString) {
FLAG_serialize_toplevel = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
......@@ -1704,7 +1696,6 @@ TEST(CodeSerializerExternalString) {
}
TEST(CodeSerializerLargeExternalString) {
FLAG_serialize_toplevel = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
......@@ -1762,7 +1753,6 @@ TEST(CodeSerializerLargeExternalString) {
}
TEST(CodeSerializerExternalScriptName) {
FLAG_serialize_toplevel = true;
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
......@@ -1821,8 +1811,8 @@ static void SerializerCodeEventListener(const v8::JitCodeEvent* event) {
}
}
v8::ScriptCompiler::CachedData* ProduceCache(const char* source) {
v8::ScriptCompiler::CachedData* ProduceCache(const char* source,
bool eager = false) {
v8::ScriptCompiler::CachedData* cache;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
......@@ -1836,9 +1826,11 @@ v8::ScriptCompiler::CachedData* ProduceCache(const char* source) {
v8::Local<v8::String> source_str = v8_str(source);
v8::ScriptOrigin origin(v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin);
v8::ScriptCompiler::CompileOptions options =
eager ? v8::ScriptCompiler::kProduceFullCodeCache
: v8::ScriptCompiler::kProduceCodeCache;
v8::Local<v8::UnboundScript> script =
v8::ScriptCompiler::CompileUnboundScript(
isolate1, &source, v8::ScriptCompiler::kProduceCodeCache)
v8::ScriptCompiler::CompileUnboundScript(isolate1, &source, options)
.ToLocalChecked();
const v8::ScriptCompiler::CachedData* data = source.GetCachedData();
CHECK(data);
......@@ -1861,8 +1853,6 @@ v8::ScriptCompiler::CachedData* ProduceCache(const char* source) {
}
TEST(CodeSerializerIsolates) {
FLAG_serialize_toplevel = true;
const char* source = "function f() { return 'abc'; }; f() + 'def'";
v8::ScriptCompiler::CachedData* cache = ProduceCache(source);
......@@ -1901,9 +1891,52 @@ TEST(CodeSerializerIsolates) {
isolate2->Dispose();
}
TEST(CodeSerializerFlagChange) {
FLAG_serialize_toplevel = true;
TEST(CodeSerializerIsolatesEager) {
const char* source =
"function f() {"
" return function g() {"
" return 'abc';"
" }"
"}"
"f()() + 'def'";
v8::ScriptCompiler::CachedData* cache = ProduceCache(source, true);
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
isolate2->SetJitCodeEventHandler(v8::kJitCodeEventDefault,
SerializerCodeEventListener);
toplevel_test_code_event_found = false;
{
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(isolate2);
v8::Local<v8::Context> context = v8::Context::New(isolate2);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(source);
v8::ScriptOrigin origin(v8_str("test"));
v8::ScriptCompiler::Source source(source_str, origin, cache);
v8::Local<v8::UnboundScript> script;
{
DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2));
script = v8::ScriptCompiler::CompileUnboundScript(
isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
}
CHECK(!cache->rejected);
v8::Local<v8::Value> result = script->BindToCurrentContext()
->Run(isolate2->GetCurrentContext())
.ToLocalChecked();
CHECK(result->ToString(isolate2->GetCurrentContext())
.ToLocalChecked()
->Equals(isolate2->GetCurrentContext(), v8_str("abcdef"))
.FromJust());
}
CHECK(toplevel_test_code_event_found);
isolate2->Dispose();
}
TEST(CodeSerializerFlagChange) {
const char* source = "function f() { return 'abc'; }; f() + 'def'";
v8::ScriptCompiler::CachedData* cache = ProduceCache(source);
......@@ -1931,8 +1964,6 @@ TEST(CodeSerializerFlagChange) {
}
TEST(CodeSerializerBitFlip) {
FLAG_serialize_toplevel = true;
const char* source = "function f() { return 'abc'; }; f() + 'def'";
v8::ScriptCompiler::CachedData* cache = ProduceCache(source);
......@@ -1960,8 +1991,6 @@ TEST(CodeSerializerBitFlip) {
}
TEST(CodeSerializerWithHarmonyScoping) {
FLAG_serialize_toplevel = true;
const char* source1 = "'use strict'; let x = 'X'";
const char* source2 = "'use strict'; let y = 'Y'";
const char* source3 = "'use strict'; x + y";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment