Commit dde47c04 authored by Wiktor Garbacz's avatar Wiktor Garbacz Committed by Commit Bot

[parser] Simplify preparse decision logic.

BUG=v8:6093

Change-Id: I7fa591c70a0db3ce158b9a9aa798ee7cdbaf0ae1
Reviewed-on: https://chromium-review.googlesource.com/485679
Commit-Queue: Wiktor Garbacz <wiktorg@google.com>
Reviewed-by: 's avatarDaniel Vogelheim <vogelheim@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44839}
parent e8df147f
...@@ -2621,11 +2621,13 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2621,11 +2621,13 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
DCHECK_IMPLIES(parse_lazily(), allow_lazy_); DCHECK_IMPLIES(parse_lazily(), allow_lazy_);
DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr); DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
bool can_preparse = parse_lazily() && const bool is_lazy =
eager_compile_hint == FunctionLiteral::kShouldLazyCompile; eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
const bool is_top_level =
bool is_lazy_top_level_function = impl()->AllowsLazyParsingWithoutUnresolvedVariables();
can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); const bool is_lazy_top_level_function = is_lazy && is_top_level;
const bool is_lazy_inner_function = is_lazy && !is_top_level;
const bool is_declaration = function_type == FunctionLiteral::kDeclaration;
RuntimeCallTimerScope runtime_timer( RuntimeCallTimerScope runtime_timer(
runtime_call_stats_, runtime_call_stats_,
...@@ -2649,22 +2651,14 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2649,22 +2651,14 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// Inner functions will be parsed using a temporary Zone. After parsing, we // Inner functions will be parsed using a temporary Zone. After parsing, we
// will migrate unresolved variable into a Scope in the main Zone. // will migrate unresolved variable into a Scope in the main Zone.
// TODO(marja): Refactor parsing modes: simplify this.
bool use_temp_zone = const bool should_preparse_inner =
(FLAG_aggressive_lazy_inner_functions parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function &&
? can_preparse (is_declaration || FLAG_aggressive_lazy_inner_functions);
: (is_lazy_top_level_function ||
(parse_lazily() && // This may be modified later to reflect preparsing decision taken
function_type == FunctionLiteral::kDeclaration && bool should_preparse =
eager_compile_hint == FunctionLiteral::kShouldLazyCompile))); (parse_lazily() && is_lazy_top_level_function) || should_preparse_inner;
DCHECK_IMPLIES(
(is_lazy_top_level_function ||
(parse_lazily() && function_type == FunctionLiteral::kDeclaration &&
eager_compile_hint == FunctionLiteral::kShouldLazyCompile)),
can_preparse);
bool is_lazy_inner_function =
use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function;
ZoneList<Statement*>* body = nullptr; ZoneList<Statement*>* body = nullptr;
int expected_property_count = -1; int expected_property_count = -1;
...@@ -2689,7 +2683,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2689,7 +2683,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// to do scope analysis correctly after full parsing, we migrate needed // to do scope analysis correctly after full parsing, we migrate needed
// information when the function is parsed. // information when the function is parsed.
Zone temp_zone(zone()->allocator(), ZONE_NAME); Zone temp_zone(zone()->allocator(), ZONE_NAME);
DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); DiscardableZoneScope zone_scope(this, &temp_zone, should_preparse);
// This Scope lives in the main zone. We'll migrate data into that zone // This Scope lives in the main zone. We'll migrate data into that zone
// later. // later.
...@@ -2697,7 +2691,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2697,7 +2691,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
SetLanguageMode(scope, language_mode); SetLanguageMode(scope, language_mode);
#ifdef DEBUG #ifdef DEBUG
scope->SetScopeName(function_name); scope->SetScopeName(function_name);
if (use_temp_zone) scope->set_needs_migration(); if (should_preparse) scope->set_needs_migration();
#endif #endif
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN, CHECK_OK);
...@@ -2708,7 +2702,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2708,7 +2702,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// abort lazy parsing if it suspects that wasn't a good idea. If so (in // abort lazy parsing if it suspects that wasn't a good idea. If so (in
// which case the parser is expected to have backtracked), or if we didn't // which case the parser is expected to have backtracked), or if we didn't
// try to lazy parse in the first place, we'll have to parse eagerly. // try to lazy parse in the first place, we'll have to parse eagerly.
if (is_lazy_top_level_function || is_lazy_inner_function) { if (should_preparse) {
DCHECK(parse_lazily());
DCHECK(is_lazy_top_level_function || is_lazy_inner_function);
Scanner::BookmarkScope bookmark(scanner()); Scanner::BookmarkScope bookmark(scanner());
bookmark.Set(); bookmark.Set();
LazyParsingResult result = LazyParsingResult result =
...@@ -2718,9 +2714,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2718,9 +2714,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (result == kLazyParsingAborted) { if (result == kLazyParsingAborted) {
DCHECK(is_lazy_top_level_function); DCHECK(is_lazy_top_level_function);
bookmark.Apply(); bookmark.Apply();
// Trigger eager (re-)parsing, just below this block.
is_lazy_top_level_function = false;
// This is probably an initialization function. Inform the compiler it // This is probably an initialization function. Inform the compiler it
// should also eager-compile this function, and that we expect it to be // should also eager-compile this function, and that we expect it to be
// used once. // used once.
...@@ -2728,48 +2721,44 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2728,48 +2721,44 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
should_be_used_once_hint = true; should_be_used_once_hint = true;
scope->ResetAfterPreparsing(ast_value_factory(), true); scope->ResetAfterPreparsing(ast_value_factory(), true);
zone_scope.Reset(); zone_scope.Reset();
use_temp_zone = false; // Trigger eager (re-)parsing, just below this block.
should_preparse = false;
} }
} }
if (!is_lazy_top_level_function && !is_lazy_inner_function) { if (should_preparse) {
scope->AnalyzePartially(&previous_zone_ast_node_factory,
preparsed_scope_data_);
} else {
body = ParseFunction(function_name, pos, kind, function_type, scope, body = ParseFunction(function_name, pos, kind, function_type, scope,
&num_parameters, &function_length, &num_parameters, &function_length,
&has_duplicate_parameters, &expected_property_count, &has_duplicate_parameters, &expected_property_count,
CHECK_OK); CHECK_OK);
} }
DCHECK(use_temp_zone || !is_lazy_top_level_function); DCHECK_EQ(should_preparse, temp_zoned_);
if (use_temp_zone) { if (V8_UNLIKELY(FLAG_trace_preparse)) {
// If the preconditions are correct the function body should never be
// accessed, but do this anyway for better behaviour if they're wrong.
body = nullptr;
scope->AnalyzePartially(&previous_zone_ast_node_factory,
preparsed_scope_data_);
}
DCHECK_IMPLIES(use_temp_zone, temp_zoned_);
if (FLAG_trace_preparse) {
PrintF(" [%s]: %i-%i %.*s\n", PrintF(" [%s]: %i-%i %.*s\n",
is_lazy_top_level_function should_preparse ? (is_top_level ? "Preparse no-resolution"
? "Preparse no-resolution" : "Preparse resolution")
: (temp_zoned_ ? "Preparse resolution" : "Full parse"), : "Full parse",
scope->start_position(), scope->end_position(), scope->start_position(), scope->end_position(),
function_name->byte_length(), function_name->raw_data()); function_name->byte_length(), function_name->raw_data());
} }
if (V8_UNLIKELY(FLAG_runtime_stats)) { if (V8_UNLIKELY(FLAG_runtime_stats)) {
if (is_lazy_top_level_function) { if (should_preparse) {
RuntimeCallStats::CorrectCurrentCounterId( RuntimeCallStats::CounterId counter_id =
runtime_call_stats_,
parsing_on_main_thread_
? &RuntimeCallStats::PreParseNoVariableResolution
: &RuntimeCallStats::PreParseBackgroundNoVariableResolution);
} else if (temp_zoned_) {
RuntimeCallStats::CorrectCurrentCounterId(
runtime_call_stats_,
parsing_on_main_thread_ parsing_on_main_thread_
? &RuntimeCallStats::PreParseWithVariableResolution ? &RuntimeCallStats::PreParseWithVariableResolution
: &RuntimeCallStats::PreParseBackgroundWithVariableResolution); : &RuntimeCallStats::PreParseBackgroundWithVariableResolution;
if (is_top_level) {
counter_id =
parsing_on_main_thread_
? &RuntimeCallStats::PreParseNoVariableResolution
: &RuntimeCallStats::PreParseBackgroundNoVariableResolution;
}
RuntimeCallStats::CorrectCurrentCounterId(runtime_call_stats_,
counter_id);
} }
} }
......
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