Chromium Code Reviews| Index: src/preparser.cc |
| diff --git a/src/preparser.cc b/src/preparser.cc |
| index 950f7b50ec35ca6a255788dac4b1aecccdef9086..8544517b70aa553437446de851018a393fc17907 100644 |
| --- a/src/preparser.cc |
| +++ b/src/preparser.cc |
| @@ -99,7 +99,8 @@ PreParserExpression PreParserTraits::ParseFunctionLiteral( |
| PreParser::PreParseResult PreParser::PreParseLazyFunction( |
| - LanguageMode language_mode, FunctionKind kind, ParserRecorder* log) { |
| + LanguageMode language_mode, FunctionKind kind, ParserRecorder* log, |
| + Scanner::BookmarkScope* bookmark) { |
| log_ = log; |
| // Lazy functions always have trivial outer scopes (no with/catch scopes). |
| Scope* top_scope = NewScope(scope_, SCRIPT_SCOPE); |
| @@ -114,9 +115,12 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction( |
| DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
| bool ok = true; |
| int start_position = peek_position(); |
| - ParseLazyFunctionLiteralBody(&ok); |
| - if (stack_overflow()) return kPreParseStackOverflow; |
| - if (!ok) { |
| + ParseLazyFunctionLiteralBody(&ok, bookmark); |
| + if (bookmark && bookmark->HasBeenReset()) { |
| + ; // Do nothing, as we've just aborted scanning this function. |
| + } else if (stack_overflow()) { |
| + return kPreParseStackOverflow; |
| + } else if (!ok) { |
| ReportUnexpectedToken(scanner()->current_token()); |
| } else { |
| DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
| @@ -196,15 +200,22 @@ PreParser::Statement PreParser::ParseStatementListItem(bool* ok) { |
| } |
| -void PreParser::ParseStatementList(int end_token, bool* ok) { |
| +void PreParser::ParseStatementList(int end_token, bool* ok, |
| + Scanner::BookmarkScope* bookmark) { |
| // SourceElements :: |
| // (Statement)* <end_token> |
| + // Bookkeeping for trial parse if bookmark is set: |
| + DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); |
| + bool maybe_reset = bookmark != nullptr; |
| + int count_lines = 0; |
|
marja
2015/04/24 12:08:13
Nit: Not really lines, but statements
|
| + |
| bool directive_prologue = true; |
| while (peek() != end_token) { |
| if (directive_prologue && peek() != Token::STRING) { |
| directive_prologue = false; |
| } |
| + bool starts_with_identifier = peek() == Token::IDENTIFIER; |
| Scanner::Location token_loc = scanner()->peek_location(); |
| Scanner::Location old_this_loc = function_state_->this_location(); |
| Scanner::Location old_super_loc = function_state_->super_location(); |
| @@ -241,6 +252,19 @@ void PreParser::ParseStatementList(int end_token, bool* ok) { |
| directive_prologue = false; |
| } |
| } |
| + |
| + // If we're allowed to reset to a bookmark, we will do so when we see a long |
| + // and trivial function. |
| + // Our current definition of 'long and trivial) is: |
|
marja
2015/04/24 12:08:13
Nit: ) -> '
|
| + // - over 200 statements |
| + // - all starting with an identifier (i.e., no if, for, while, etc.) |
| + if (maybe_reset && (!starts_with_identifier || ++count_lines > 200)) { |
|
marja
2015/04/24 12:08:13
IMO clearer:
if (!starts_with_identifier) maybe_r
|
| + if (count_lines > 200) { |
| + bookmark->Reset(); |
| + return; |
| + } |
| + maybe_reset = false; |
| + } |
| } |
| } |
| @@ -1044,10 +1068,12 @@ PreParser::Expression PreParser::ParseFunctionLiteral( |
| } |
| -void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { |
| +void PreParser::ParseLazyFunctionLiteralBody(bool* ok, |
| + Scanner::BookmarkScope* bookmark) { |
| int body_start = position(); |
| - ParseStatementList(Token::RBRACE, ok); |
| + ParseStatementList(Token::RBRACE, ok, bookmark); |
| if (!*ok) return; |
| + if (bookmark && bookmark->HasBeenReset()) return; |
| // Position right after terminal '}'. |
| DCHECK_EQ(Token::RBRACE, scanner()->peek()); |