Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: src/parser.cc

Issue 1102523003: Implement a 'trial parse' step, that will abort pre-parsing excessively (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: The Great Rebase Adventure. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/preparser.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 4058 matching lines...) Expand 10 before | Expand all | Expand 10 after
4069 // possible reference to the variable in foo's scope. However, it's possible 4069 // possible reference to the variable in foo's scope. However, it's possible
4070 // that it will be compiled lazily. 4070 // that it will be compiled lazily.
4071 4071
4072 // To make this additional case work, both Parser and PreParser implement a 4072 // To make this additional case work, both Parser and PreParser implement a
4073 // logic where only top-level functions will be parsed lazily. 4073 // logic where only top-level functions will be parsed lazily.
4074 bool is_lazily_parsed = (mode() == PARSE_LAZILY && 4074 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
4075 scope_->AllowsLazyCompilation() && 4075 scope_->AllowsLazyCompilation() &&
4076 !parenthesized_function_); 4076 !parenthesized_function_);
4077 parenthesized_function_ = false; // The bit was set for this function only. 4077 parenthesized_function_ = false; // The bit was set for this function only.
4078 4078
4079 // Eager or lazy parse?
4080 // If is_lazily_parsed, we'll parse lazy. If we can set a bookmark, we'll
4081 // pass it to SkipLazyFunctionBody, which may use it to abort lazy
4082 // parsing if it suspect that wasn't a good idea. If so, or if we didn't
4083 // try to lazy parse in the first place, we'll have to parse eagerly.
4084 Scanner::BookmarkScope bookmark(scanner());
4079 if (is_lazily_parsed) { 4085 if (is_lazily_parsed) {
4080 for (Scope* s = scope_->outer_scope(); 4086 for (Scope* s = scope_->outer_scope();
4081 s != nullptr && (s != s->DeclarationScope()); s = s->outer_scope()) { 4087 s != nullptr && (s != s->DeclarationScope()); s = s->outer_scope()) {
4082 s->ForceContextAllocation(); 4088 s->ForceContextAllocation();
4083 } 4089 }
4090
4091 Scanner::BookmarkScope* maybe_bookmark =
4092 bookmark.Set() ? &bookmark : nullptr;
4084 SkipLazyFunctionBody(&materialized_literal_count, 4093 SkipLazyFunctionBody(&materialized_literal_count,
4085 &expected_property_count, CHECK_OK); 4094 &expected_property_count, /*CHECK_OK*/ ok,
4086 } else { 4095 maybe_bookmark);
4096
4097 if (bookmark.HasBeenReset()) {
4098 // Trigger eager (re-)parsing, just below this block.
4099 is_lazily_parsed = false;
4100
4101 // Inform the compiler it should also eager-compile this function.
4102 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
4103 }
4104 }
4105 if (!is_lazily_parsed) {
4087 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, 4106 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
4088 kind, CHECK_OK); 4107 kind, CHECK_OK);
4089 materialized_literal_count = function_state.materialized_literal_count(); 4108 materialized_literal_count = function_state.materialized_literal_count();
4090 expected_property_count = function_state.expected_property_count(); 4109 expected_property_count = function_state.expected_property_count();
4091 handler_count = function_state.handler_count(); 4110 handler_count = function_state.handler_count();
4092 4111
4093 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { 4112 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
4094 if (!function_state.super_location().IsValid()) { 4113 if (!function_state.super_location().IsValid()) {
4095 ReportMessageAt(function_name_location, 4114 ReportMessageAt(function_name_location,
4096 "strong_super_call_missing", kReferenceError); 4115 "strong_super_call_missing", kReferenceError);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4131 // TODO(caitp): enable optimization of functions with rest params 4150 // TODO(caitp): enable optimization of functions with rest params
4132 function_literal->set_dont_optimize_reason(kRestParameter); 4151 function_literal->set_dont_optimize_reason(kRestParameter);
4133 } 4152 }
4134 4153
4135 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 4154 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4136 return function_literal; 4155 return function_literal;
4137 } 4156 }
4138 4157
4139 4158
4140 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, 4159 void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
4141 int* expected_property_count, 4160 int* expected_property_count, bool* ok,
4142 bool* ok) { 4161 Scanner::BookmarkScope* bookmark) {
4162 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
4143 if (produce_cached_parse_data()) CHECK(log_); 4163 if (produce_cached_parse_data()) CHECK(log_);
4144 4164
4145 int function_block_pos = position(); 4165 int function_block_pos = position();
4146 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) { 4166 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
4147 // If we have cached data, we use it to skip parsing the function body. The 4167 // If we have cached data, we use it to skip parsing the function body. The
4148 // data contains the information we need to construct the lazy function. 4168 // data contains the information we need to construct the lazy function.
4149 FunctionEntry entry = 4169 FunctionEntry entry =
4150 cached_parse_data_->GetFunctionEntry(function_block_pos); 4170 cached_parse_data_->GetFunctionEntry(function_block_pos);
4151 // Check that cached data is valid. If not, mark it as invalid (the embedder 4171 // Check that cached data is valid. If not, mark it as invalid (the embedder
4152 // handles it). Note that end position greater than end of stream is safe, 4172 // handles it). Note that end position greater than end of stream is safe,
(...skipping 12 matching lines...) Expand all
4165 scope_->SetLanguageMode(entry.language_mode()); 4185 scope_->SetLanguageMode(entry.language_mode());
4166 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage(); 4186 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage();
4167 return; 4187 return;
4168 } 4188 }
4169 cached_parse_data_->Reject(); 4189 cached_parse_data_->Reject();
4170 } 4190 }
4171 // With no cached data, we partially parse the function, without building an 4191 // With no cached data, we partially parse the function, without building an
4172 // AST. This gathers the data needed to build a lazy function. 4192 // AST. This gathers the data needed to build a lazy function.
4173 SingletonLogger logger; 4193 SingletonLogger logger;
4174 PreParser::PreParseResult result = 4194 PreParser::PreParseResult result =
4175 ParseLazyFunctionBodyWithPreParser(&logger); 4195 ParseLazyFunctionBodyWithPreParser(&logger, bookmark);
4196 if (bookmark && bookmark->HasBeenReset()) {
4197 return; // Return immediately if pre-parser devided to abort parsing.
4198 }
4176 if (result == PreParser::kPreParseStackOverflow) { 4199 if (result == PreParser::kPreParseStackOverflow) {
4177 // Propagate stack overflow. 4200 // Propagate stack overflow.
4178 set_stack_overflow(); 4201 set_stack_overflow();
4179 *ok = false; 4202 *ok = false;
4180 return; 4203 return;
4181 } 4204 }
4182 if (logger.has_error()) { 4205 if (logger.has_error()) {
4183 ParserTraits::ReportMessageAt( 4206 ParserTraits::ReportMessageAt(
4184 Scanner::Location(logger.start(), logger.end()), logger.message(), 4207 Scanner::Location(logger.start(), logger.end()), logger.message(),
4185 logger.argument_opt(), logger.error_type()); 4208 logger.argument_opt(), logger.error_type());
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
4294 } 4317 }
4295 4318
4296 Expect(Token::RBRACE, CHECK_OK); 4319 Expect(Token::RBRACE, CHECK_OK);
4297 scope_->set_end_position(scanner()->location().end_pos); 4320 scope_->set_end_position(scanner()->location().end_pos);
4298 4321
4299 return body; 4322 return body;
4300 } 4323 }
4301 4324
4302 4325
4303 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( 4326 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
4304 SingletonLogger* logger) { 4327 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) {
4305 // This function may be called on a background thread too; record only the 4328 // This function may be called on a background thread too; record only the
4306 // main thread preparse times. 4329 // main thread preparse times.
4307 if (pre_parse_timer_ != NULL) { 4330 if (pre_parse_timer_ != NULL) {
4308 pre_parse_timer_->Start(); 4331 pre_parse_timer_->Start();
4309 } 4332 }
4310 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); 4333 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
4311 4334
4312 if (reusable_preparser_ == NULL) { 4335 if (reusable_preparser_ == NULL) {
4313 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), 4336 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
4314 NULL, stack_limit_); 4337 NULL, stack_limit_);
4315 reusable_preparser_->set_allow_lazy(true); 4338 reusable_preparser_->set_allow_lazy(true);
4316 reusable_preparser_->set_allow_natives(allow_natives()); 4339 reusable_preparser_->set_allow_natives(allow_natives());
4317 reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules()); 4340 reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules());
4318 reusable_preparser_->set_allow_harmony_arrow_functions( 4341 reusable_preparser_->set_allow_harmony_arrow_functions(
4319 allow_harmony_arrow_functions()); 4342 allow_harmony_arrow_functions());
4320 reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes()); 4343 reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes());
4321 reusable_preparser_->set_allow_harmony_object_literals( 4344 reusable_preparser_->set_allow_harmony_object_literals(
4322 allow_harmony_object_literals()); 4345 allow_harmony_object_literals());
4323 reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy()); 4346 reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy());
4324 reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode()); 4347 reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode());
4325 reusable_preparser_->set_allow_harmony_computed_property_names( 4348 reusable_preparser_->set_allow_harmony_computed_property_names(
4326 allow_harmony_computed_property_names()); 4349 allow_harmony_computed_property_names());
4327 reusable_preparser_->set_allow_harmony_rest_params( 4350 reusable_preparser_->set_allow_harmony_rest_params(
4328 allow_harmony_rest_params()); 4351 allow_harmony_rest_params());
4329 reusable_preparser_->set_allow_harmony_spreadcalls( 4352 reusable_preparser_->set_allow_harmony_spreadcalls(
4330 allow_harmony_spreadcalls()); 4353 allow_harmony_spreadcalls());
4331 reusable_preparser_->set_allow_strong_mode(allow_strong_mode()); 4354 reusable_preparser_->set_allow_strong_mode(allow_strong_mode());
4332 } 4355 }
4333 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( 4356 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4334 language_mode(), function_state_->kind(), logger); 4357 language_mode(), function_state_->kind(), logger, bookmark);
4335 if (pre_parse_timer_ != NULL) { 4358 if (pre_parse_timer_ != NULL) {
4336 pre_parse_timer_->Stop(); 4359 pre_parse_timer_->Stop();
4337 } 4360 }
4338 return result; 4361 return result;
4339 } 4362 }
4340 4363
4341 4364
4342 ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name, 4365 ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
4343 Scanner::Location class_name_location, 4366 Scanner::Location class_name_location,
4344 bool name_is_strict_reserved, int pos, 4367 bool name_is_strict_reserved, int pos,
(...skipping 1487 matching lines...) Expand 10 before | Expand all | Expand 10 after
5832 5855
5833 Expression* Parser::SpreadCallNew(Expression* function, 5856 Expression* Parser::SpreadCallNew(Expression* function,
5834 ZoneList<v8::internal::Expression*>* args, 5857 ZoneList<v8::internal::Expression*>* args,
5835 int pos) { 5858 int pos) {
5836 args->InsertAt(0, function, zone()); 5859 args->InsertAt(0, function, zone());
5837 5860
5838 return factory()->NewCallRuntime( 5861 return factory()->NewCallRuntime(
5839 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5862 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5840 } 5863 }
5841 } } // namespace v8::internal 5864 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/preparser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698