Preparse top-level functions in discardable zones

BUG=

Committed: https://crrev.com/ff8cfa9e5e8495165291ddf6e01dba3f8cb5a177
Review-Url: https://codereview.chromium.org/2374963002
Cr-Original-Commit-Position: refs/heads/master@{#39809}
Cr-Commit-Position: refs/heads/master@{#39834}
This commit is contained in:
verwaest 2016-09-28 08:58:22 -07:00 committed by Commit bot
parent a5440d1190
commit 375079b167
3 changed files with 50 additions and 41 deletions

View File

@ -3546,7 +3546,8 @@ class AstNodeFactory final BASE_EMBEDDED {
}
}
~BodyScope() { factory_->zone_ = prev_zone_; }
void Reset() { factory_->zone_ = prev_zone_; }
~BodyScope() { Reset(); }
private:
AstNodeFactory* factory_;

View File

@ -1196,6 +1196,7 @@ void DeclarationScope::ResetAfterPreparsing(bool aborted) {
variables_.Clear();
// Make sure we won't walk the scope tree from here on.
inner_scope_ = nullptr;
unresolved_ = nullptr;
// TODO(verwaest): We should properly preparse the parameters (no declarations
// should be created), and reparse on abort.

View File

@ -127,13 +127,15 @@ class DiscardableZoneScope {
}
}
}
~DiscardableZoneScope() {
void Reset() {
parser_->fni_ = prev_fni_;
parser_->zone_ = prev_zone_;
if (parser_->reusable_preparser_ != nullptr) {
parser_->reusable_preparser_->zone_ = prev_zone_;
}
ast_node_factory_scope_.Reset();
}
~DiscardableZoneScope() { Reset(); }
private:
AstNodeFactory::BodyScope ast_node_factory_scope_;
@ -2626,11 +2628,11 @@ 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 =
!is_lazy_top_level_function && allow_lazy() &&
function_type == FunctionLiteral::kDeclaration &&
allow_lazy() && function_type == FunctionLiteral::kDeclaration &&
eager_compile_hint != FunctionLiteral::kShouldEagerCompile &&
!(FLAG_validate_asm && scope()->IsAsmModule());
bool is_lazy_inner_function = use_temp_zone && FLAG_lazy_inner_functions;
bool is_lazy_inner_function =
use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function;
// This Scope lives in the main zone. We'll migrate data into that zone later.
DeclarationScope* scope = NewFunctionScope(kind);
@ -2644,25 +2646,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
bool should_be_used_once_hint = false;
bool has_duplicate_parameters;
{
// Temporary zones can nest. When we migrate free variables (see below), we
// need to recreate them in the previous Zone.
AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
previous_zone_ast_node_factory.set_zone(zone());
// Open a new zone scope, which sets our AstNodeFactory to allocate in the
// new temporary zone if the preconditions are satisfied, and ensures that
// the previous zone is always restored after parsing the body. To be able
// to do scope analysis correctly after full parsing, we migrate needed
// information when the function is parsed.
Zone temp_zone(zone()->allocator());
DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone);
FunctionState function_state(&function_state_, &scope_state_, scope);
#ifdef DEBUG
scope->SetScopeName(function_name);
if (use_temp_zone) scope->set_needs_migration();
#endif
ExpressionClassifier formals_classifier(this, &duplicate_finder);
if (is_generator) {
@ -2697,6 +2685,23 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// which says whether we need to create an arguments adaptor frame).
if (formals.has_rest) arity--;
{
// Temporary zones can nest. When we migrate free variables (see below), we
// need to recreate them in the previous Zone.
AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
previous_zone_ast_node_factory.set_zone(zone());
// Open a new zone scope, which sets our AstNodeFactory to allocate in the
// new temporary zone if the preconditions are satisfied, and ensures that
// the previous zone is always restored after parsing the body. To be able
// to do scope analysis correctly after full parsing, we migrate needed
// information when the function is parsed.
Zone temp_zone(zone()->allocator());
DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone);
#ifdef DEBUG
if (use_temp_zone) scope->set_needs_migration();
#endif
// Eager or lazy parse? If is_lazy_top_level_function, we'll parse
// lazily. We'll call SkipLazyFunctionBody, which may decide to abort lazy
// parsing if it suspects that wasn't a good idea. If so (in which case the
@ -2724,6 +2729,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
should_be_used_once_hint = true;
scope->ResetAfterPreparsing(true);
zone_scope.Reset();
use_temp_zone = false;
}
}