Commit 9618d095 authored by verwaest's avatar verwaest Committed by Commit bot

Preparse functions in the scope that was created when parsing of the function was started

This reduces the number of scopes for lazily parsed top-level functions from 3 to 1

BUG=v8:5209

Review-Url: https://codereview.chromium.org/2370713003
Cr-Commit-Position: refs/heads/master@{#39725}
parent 0e2155ad
......@@ -808,6 +808,20 @@ class DeclarationScope : public Scope {
void AllocateParameterLocals();
void AllocateReceiver();
void ResetAfterPreparsing() {
// Reset all non-trivial members.
decls_.Clear();
locals_.Clear();
params_.Clear();
sloppy_block_function_map_.Clear();
variables_.Clear();
// Make sure we won't walk the scope tree from here on.
inner_scope_ = nullptr;
// Make sure we won't try to allocate the rest parameter. {params_} was
// cleared above.
has_rest_ = false;
}
private:
void AllocateParameter(Variable* var, int index);
......
......@@ -381,9 +381,14 @@ class ParserBase {
class FunctionState final : public ScopeState {
public:
FunctionState(FunctionState** function_state_stack,
ScopeState** scope_stack, Scope* scope, FunctionKind kind);
ScopeState** scope_stack, DeclarationScope* scope,
FunctionKind kind);
~FunctionState();
DeclarationScope* scope() const {
return ScopeState::scope()->AsDeclarationScope();
}
int NextMaterializedLiteralIndex() {
return next_materialized_literal_index_++;
}
......@@ -1449,7 +1454,7 @@ class ParserBase {
template <typename Impl>
ParserBase<Impl>::FunctionState::FunctionState(
FunctionState** function_state_stack, ScopeState** scope_stack,
Scope* scope, FunctionKind kind)
DeclarationScope* scope, FunctionKind kind)
: ScopeState(scope_stack, scope),
next_materialized_literal_index_(0),
expected_property_count_(0),
......
......@@ -929,9 +929,12 @@ FunctionLiteral* Parser::DoParseLazy(ParseInfo* info,
{
// Parse the function literal.
Scope* outer = original_scope_;
DeclarationScope* outer_function = outer->GetClosureScope();
DCHECK(outer);
FunctionState function_state(&function_state_, &scope_state_, outer,
info->function_kind());
FunctionState function_state(&function_state_, &scope_state_,
outer_function,
outer_function->function_kind());
BlockState block_state(&scope_state_, outer);
DCHECK(is_sloppy(outer->language_mode()) ||
is_strict(info->language_mode()));
FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
......@@ -2940,7 +2943,7 @@ Parser::LazyParsingResult Parser::SkipLazyFunctionBody(
if (produce_cached_parse_data()) CHECK(log_);
int function_block_pos = position();
DeclarationScope* scope = this->scope()->AsDeclarationScope();
DeclarationScope* scope = function_state_->scope();
DCHECK(scope->is_function_scope());
scope->set_is_lazily_parsed(true);
// Inner functions are not part of the cached data.
......@@ -2973,6 +2976,7 @@ Parser::LazyParsingResult Parser::SkipLazyFunctionBody(
SingletonLogger logger;
PreParser::PreParseResult result =
ParseLazyFunctionBodyWithPreParser(&logger, is_inner_function, may_abort);
// Return immediately if pre-parser decided to abort parsing.
if (result == PreParser::kPreParseAbort) {
scope->set_is_lazily_parsed(false);
......@@ -3474,32 +3478,13 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
// state; we don't parse inner functions in the abortable mode anyway.
DCHECK(!is_inner_function || !may_abort);
FunctionKind kind = function_state_->kind();
PreParser::PreParseResult result;
if (!is_inner_function) {
// If we don't need to look at the scope, construct a dummy scope chain
// which is not connected to the real scope chain.
LanguageMode mode = language_mode();
bool has_simple_parameters =
scope()->AsDeclarationScope()->has_simple_parameters();
DeclarationScope* top_scope = NewScriptScope();
top_scope->SetLanguageMode(mode);
FunctionState top_state(&function_state_, &scope_state_, top_scope,
kNormalFunction);
DeclarationScope* function_scope = NewFunctionScope(kind);
if (!has_simple_parameters) {
function_scope->SetHasNonSimpleParameters();
}
result = reusable_preparser_->PreParseLazyFunction(
kind, function_scope, parsing_module_, logger, is_inner_function,
may_abort, use_counts_);
} else {
// Detaching the scopes created by PreParser from the Scope chain must be
// done above (see ParseFunctionLiteral & AnalyzePartially).
result = reusable_preparser_->PreParseLazyFunction(
kind, scope()->AsDeclarationScope(), parsing_module_, logger,
is_inner_function, may_abort, use_counts_);
}
DeclarationScope* function_scope = function_state_->scope();
PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
function_scope, parsing_module_, logger, is_inner_function, may_abort,
use_counts_);
// Detaching the scopes created by PreParser from the Scope chain must be done
// above (see ParseFunctionLiteral & AnalyzePartially).
if (!is_inner_function) function_scope->ResetAfterPreparsing();
if (pre_parse_timer_ != NULL) {
pre_parse_timer_->Stop();
}
......
......@@ -84,9 +84,9 @@ PreParserIdentifier PreParser::GetSymbol() const {
}
PreParser::PreParseResult PreParser::PreParseLazyFunction(
FunctionKind kind, DeclarationScope* function_scope, bool parsing_module,
ParserRecorder* log, bool is_inner_function, bool may_abort,
int* use_counts) {
DeclarationScope* function_scope, bool parsing_module, ParserRecorder* log,
bool is_inner_function, bool may_abort, int* use_counts) {
DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type());
parsing_module_ = parsing_module;
log_ = log;
use_counts_ = use_counts;
......@@ -98,7 +98,7 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
// PreParser.
DCHECK_NULL(scope_state_);
FunctionState function_state(&function_state_, &scope_state_, function_scope,
kind);
function_scope->function_kind());
DCHECK_EQ(Token::LBRACE, scanner()->current_token());
bool ok = true;
int start_position = peek_position();
......@@ -113,7 +113,7 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
ReportUnexpectedToken(scanner()->current_token());
} else {
DCHECK_EQ(Token::RBRACE, scanner()->peek());
if (is_strict(scope()->language_mode())) {
if (is_strict(function_scope->language_mode())) {
int end_pos = scanner()->location().end_pos;
CheckStrictOctalLiteral(start_position, end_pos, &ok);
CheckDecimalLiteralWithLeadingZero(start_position, end_pos);
......
......@@ -823,8 +823,7 @@ class PreParser : public ParserBase<PreParser> {
// keyword and parameters, and have consumed the initial '{'.
// At return, unless an error occurred, the scanner is positioned before the
// the final '}'.
PreParseResult PreParseLazyFunction(FunctionKind kind,
DeclarationScope* function_scope,
PreParseResult PreParseLazyFunction(DeclarationScope* function_scope,
bool parsing_module, ParserRecorder* log,
bool track_unresolved_variables,
bool may_abort, int* use_counts);
......
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