Commit 14bf19af authored by verwaest's avatar verwaest Committed by Commit bot

Allow lazy parsing of functions nested in eager compiled functions

This is blocked on https://bugs.chromium.org/p/v8/issues/detail?id=5484

BUG=v8:5501

Review-Url: https://codereview.chromium.org/2405813002
Cr-Commit-Position: refs/heads/master@{#40167}
parent 91a3517e
......@@ -1119,9 +1119,7 @@ bool Scope::AllowsLazyParsingWithoutUnresolvedVariables() const {
// inner scopes to find out how to allocate variables on the block scope. At
// this point, declarations may not have yet been parsed.
for (const Scope* s = this; s != nullptr; s = s->outer_scope_) {
if (s->is_block_scope()) return false;
// TODO(marja): Refactor parsing modes: also add s->is_function_scope()
// here.
if (s->is_block_scope() || s->is_function_scope()) return false;
}
return true;
}
......
......@@ -1055,17 +1055,9 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
// non-NULL). If compiling for debugging, we may eagerly compile inner
// functions, so do not parse lazily in that case.
ScriptCompiler::CompileOptions options = parse_info->compile_options();
bool parse_allow_lazy = (options == ScriptCompiler::kConsumeParserCache ||
String::cast(script->source())->length() >
FLAG_min_preparse_length) &&
!info->is_debug();
// Consider parsing eagerly when targeting the code cache.
parse_allow_lazy &= !(FLAG_serialize_eager && info->will_serialize());
// Consider parsing eagerly when targeting Ignition.
parse_allow_lazy &= !(FLAG_ignition && FLAG_ignition_eager &&
!isolate->serializer_enabled());
bool parse_allow_lazy =
options == ScriptCompiler::kConsumeParserCache ||
String::cast(script->source())->length() > FLAG_min_preparse_length;
parse_info->set_allow_lazy_parsing(parse_allow_lazy);
if (!parse_allow_lazy &&
......@@ -1084,8 +1076,6 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
}
}
DCHECK(!info->is_debug() || !parse_info->allow_lazy_parsing());
FunctionLiteral* lit = parse_info->literal();
// Measure how long it takes to do the compilation; only take the
......
......@@ -38,6 +38,7 @@ ParseInfo::ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared)
: ParseInfo(zone) {
isolate_ = shared->GetIsolate();
set_allow_lazy_parsing(FLAG_lazy_inner_functions);
set_hash_seed(isolate_->heap()->HashSeed());
set_is_named_expression(shared->is_named_expression());
set_calls_eval(shared->scope_info()->CallsEval());
......
......@@ -3922,6 +3922,12 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
FunctionKind kind = formal_parameters.scope->function_kind();
FunctionLiteral::EagerCompileHint eager_compile_hint =
default_eager_compile_hint_;
bool can_preparse = mode() == PARSE_LAZILY &&
eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
// TODO(marja): consider lazy-parsing inner arrow functions too. is_this
// handling in Scope::ResolveVariable needs to change.
bool is_lazy_top_level_function =
can_preparse && scope()->AllowsLazyParsingWithoutUnresolvedVariables();
bool should_be_used_once_hint = false;
{
FunctionState function_state(&function_state_, &scope_state_,
......@@ -3938,14 +3944,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
// Multiple statement body
Consume(Token::LBRACE);
DCHECK_EQ(scope(), formal_parameters.scope);
bool is_lazily_parsed =
(mode() == PARSE_LAZILY &&
formal_parameters.scope
->AllowsLazyParsingWithoutUnresolvedVariables() &&
eager_compile_hint == FunctionLiteral::kShouldLazyCompile);
// TODO(marja): consider lazy-parsing inner arrow functions too. is_this
// handling in Scope::ResolveVariable needs to change.
if (is_lazily_parsed) {
if (is_lazy_top_level_function) {
Scanner::BookmarkScope bookmark(scanner());
bookmark.Set();
LazyParsingResult result = impl()->SkipLazyFunctionBody(
......@@ -3962,7 +3961,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
if (result == kLazyParsingAborted) {
bookmark.Apply();
// Trigger eager (re-)parsing, just below this block.
is_lazily_parsed = false;
is_lazy_top_level_function = false;
// This is probably an initialization function. Inform the compiler it
// should also eager-compile this function, and that we expect it to
......@@ -3971,7 +3970,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
should_be_used_once_hint = true;
}
}
if (!is_lazily_parsed) {
if (!is_lazy_top_level_function) {
body = impl()->ParseEagerFunctionBody(
impl()->EmptyIdentifier(), kNoSourcePosition, formal_parameters,
kind, FunctionLiteral::kAnonymousExpression, CHECK_OK);
......
......@@ -2626,10 +2626,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
DCHECK_IMPLIES(mode() == PARSE_LAZILY, allow_lazy());
DCHECK_IMPLIES(mode() == PARSE_LAZILY, extension_ == nullptr);
bool can_preparse = mode() == PARSE_LAZILY &&
eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
bool is_lazy_top_level_function =
mode() == PARSE_LAZILY &&
eager_compile_hint == FunctionLiteral::kShouldLazyCompile &&
scope()->AllowsLazyParsingWithoutUnresolvedVariables();
can_preparse && scope()->AllowsLazyParsingWithoutUnresolvedVariables();
// Determine whether we can still lazy parse the inner function.
// The preconditions are:
......@@ -2651,8 +2652,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// will migrate unresolved variable into a Scope in the main Zone.
// TODO(marja): Refactor parsing modes: simplify this.
bool use_temp_zone =
allow_lazy() && function_type == FunctionLiteral::kDeclaration &&
eager_compile_hint != FunctionLiteral::kShouldEagerCompile &&
(FLAG_lazy_inner_functions
? can_preparse
: (allow_lazy() &&
eager_compile_hint == FunctionLiteral::kShouldLazyCompile)) &&
!(FLAG_validate_asm && scope()->IsAsmModule());
bool is_lazy_inner_function =
use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function;
......@@ -3152,11 +3155,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
const AstRawString* function_name, int pos,
const ParserFormalParameters& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, bool* ok) {
// Everything inside an eagerly parsed function will be parsed eagerly (see
// comment above). Lazy inner functions are handled separately and they won't
// require the mode to be PARSE_LAZILY (see ParseFunctionLiteral).
// TODO(marja): Refactor parsing modes: remove this.
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY);
ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
static const int kFunctionNameAssignmentIndex = 0;
......
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