| OLD | NEW |
| 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/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 Parser::Parser(ParseInfo* info) | 589 Parser::Parser(ParseInfo* info) |
| 590 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), | 590 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), |
| 591 info->extension(), info->ast_value_factory(), NULL), | 591 info->extension(), info->ast_value_factory(), NULL), |
| 592 scanner_(info->unicode_cache()), | 592 scanner_(info->unicode_cache()), |
| 593 reusable_preparser_(NULL), | 593 reusable_preparser_(NULL), |
| 594 original_scope_(NULL), | 594 original_scope_(NULL), |
| 595 target_stack_(NULL), | 595 target_stack_(NULL), |
| 596 compile_options_(info->compile_options()), | 596 compile_options_(info->compile_options()), |
| 597 cached_parse_data_(nullptr), | 597 cached_parse_data_(nullptr), |
| 598 total_preparse_skipped_(0), | 598 total_preparse_skipped_(0), |
| 599 pre_parse_timer_(NULL), | |
| 600 parsing_on_main_thread_(true) { | 599 parsing_on_main_thread_(true) { |
| 601 // Even though we were passed ParseInfo, we should not store it in | 600 // Even though we were passed ParseInfo, we should not store it in |
| 602 // Parser - this makes sure that Isolate is not accidentally accessed via | 601 // Parser - this makes sure that Isolate is not accidentally accessed via |
| 603 // ParseInfo during background parsing. | 602 // ParseInfo during background parsing. |
| 604 DCHECK(!info->script().is_null() || info->source_stream() != nullptr || | 603 DCHECK(!info->script().is_null() || info->source_stream() != nullptr || |
| 605 info->character_stream() != nullptr); | 604 info->character_stream() != nullptr); |
| 606 // Determine if functions can be lazily compiled. This is necessary to | 605 // Determine if functions can be lazily compiled. This is necessary to |
| 607 // allow some of our builtin JS files to be lazily compiled. These | 606 // allow some of our builtin JS files to be lazily compiled. These |
| 608 // builtins cannot be handled lazily by the parser, since we have to know | 607 // builtins cannot be handled lazily by the parser, since we have to know |
| 609 // if a function uses the special natives syntax, which is something the | 608 // if a function uses the special natives syntax, which is something the |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 } | 669 } |
| 671 | 670 |
| 672 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { | 671 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { |
| 673 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 672 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
| 674 // see comment for HistogramTimerScope class. | 673 // see comment for HistogramTimerScope class. |
| 675 | 674 |
| 676 // It's OK to use the Isolate & counters here, since this function is only | 675 // It's OK to use the Isolate & counters here, since this function is only |
| 677 // called in the main thread. | 676 // called in the main thread. |
| 678 DCHECK(parsing_on_main_thread_); | 677 DCHECK(parsing_on_main_thread_); |
| 679 | 678 |
| 680 HistogramTimerScope timer_scope(isolate->counters()->parse(), true); | |
| 681 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseProgram); | 679 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseProgram); |
| 682 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram"); | 680 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram"); |
| 683 Handle<String> source(String::cast(info->script()->source())); | 681 Handle<String> source(String::cast(info->script()->source())); |
| 684 isolate->counters()->total_parse_size()->Increment(source->length()); | 682 isolate->counters()->total_parse_size()->Increment(source->length()); |
| 685 base::ElapsedTimer timer; | 683 base::ElapsedTimer timer; |
| 686 if (FLAG_trace_parse) { | 684 if (FLAG_trace_parse) { |
| 687 timer.Start(); | 685 timer.Start(); |
| 688 } | 686 } |
| 689 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 687 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
| 690 | 688 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 | 834 |
| 837 return result; | 835 return result; |
| 838 } | 836 } |
| 839 | 837 |
| 840 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) { | 838 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) { |
| 841 // It's OK to use the Isolate & counters here, since this function is only | 839 // It's OK to use the Isolate & counters here, since this function is only |
| 842 // called in the main thread. | 840 // called in the main thread. |
| 843 DCHECK(parsing_on_main_thread_); | 841 DCHECK(parsing_on_main_thread_); |
| 844 RuntimeCallTimerScope runtime_timer(isolate, | 842 RuntimeCallTimerScope runtime_timer(isolate, |
| 845 &RuntimeCallStats::ParseFunction); | 843 &RuntimeCallStats::ParseFunction); |
| 846 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy()); | |
| 847 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction"); | 844 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction"); |
| 848 Handle<String> source(String::cast(info->script()->source())); | 845 Handle<String> source(String::cast(info->script()->source())); |
| 849 isolate->counters()->total_parse_size()->Increment(source->length()); | 846 isolate->counters()->total_parse_size()->Increment(source->length()); |
| 850 base::ElapsedTimer timer; | 847 base::ElapsedTimer timer; |
| 851 if (FLAG_trace_parse) { | 848 if (FLAG_trace_parse) { |
| 852 timer.Start(); | 849 timer.Start(); |
| 853 } | 850 } |
| 854 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 851 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
| 855 DeserializeScopeChain(info, info->maybe_outer_scope_info()); | 852 DeserializeScopeChain(info, info->maybe_outer_scope_info()); |
| 856 | 853 |
| (...skipping 2397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3254 } | 3251 } |
| 3255 result->Set(kFunctionNameAssignmentIndex, statement); | 3252 result->Set(kFunctionNameAssignmentIndex, statement); |
| 3256 } | 3253 } |
| 3257 | 3254 |
| 3258 MarkCollectedTailCallExpressions(); | 3255 MarkCollectedTailCallExpressions(); |
| 3259 return result; | 3256 return result; |
| 3260 } | 3257 } |
| 3261 | 3258 |
| 3262 PreParser::PreParseResult Parser::ParseFunctionBodyWithPreParser( | 3259 PreParser::PreParseResult Parser::ParseFunctionBodyWithPreParser( |
| 3263 SingletonLogger* logger, bool is_inner_function, bool may_abort) { | 3260 SingletonLogger* logger, bool is_inner_function, bool may_abort) { |
| 3264 // This function may be called on a background thread too; record only the | |
| 3265 // main thread preparse times. | |
| 3266 if (pre_parse_timer_ != NULL) { | |
| 3267 pre_parse_timer_->Start(); | |
| 3268 } | |
| 3269 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); | 3261 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); |
| 3270 | 3262 |
| 3271 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 3263 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
| 3272 | 3264 |
| 3273 if (reusable_preparser_ == NULL) { | 3265 if (reusable_preparser_ == NULL) { |
| 3274 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), | 3266 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), |
| 3275 NULL, stack_limit_); | 3267 NULL, stack_limit_); |
| 3276 reusable_preparser_->set_allow_lazy(true); | 3268 reusable_preparser_->set_allow_lazy(true); |
| 3277 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 3269 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
| 3278 SET_ALLOW(natives); | 3270 SET_ALLOW(natives); |
| 3279 SET_ALLOW(harmony_do_expressions); | 3271 SET_ALLOW(harmony_do_expressions); |
| 3280 SET_ALLOW(harmony_function_sent); | 3272 SET_ALLOW(harmony_function_sent); |
| 3281 SET_ALLOW(harmony_restrictive_declarations); | 3273 SET_ALLOW(harmony_restrictive_declarations); |
| 3282 SET_ALLOW(harmony_async_await); | 3274 SET_ALLOW(harmony_async_await); |
| 3283 SET_ALLOW(harmony_trailing_commas); | 3275 SET_ALLOW(harmony_trailing_commas); |
| 3284 SET_ALLOW(harmony_class_fields); | 3276 SET_ALLOW(harmony_class_fields); |
| 3285 #undef SET_ALLOW | 3277 #undef SET_ALLOW |
| 3286 } | 3278 } |
| 3287 // Aborting inner function preparsing would leave scopes in an inconsistent | 3279 // Aborting inner function preparsing would leave scopes in an inconsistent |
| 3288 // state; we don't parse inner functions in the abortable mode anyway. | 3280 // state; we don't parse inner functions in the abortable mode anyway. |
| 3289 DCHECK(!is_inner_function || !may_abort); | 3281 DCHECK(!is_inner_function || !may_abort); |
| 3290 | 3282 |
| 3291 DeclarationScope* function_scope = function_state_->scope(); | 3283 DeclarationScope* function_scope = function_state_->scope(); |
| 3292 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( | 3284 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( |
| 3293 function_scope, parsing_module_, logger, is_inner_function, may_abort, | 3285 function_scope, parsing_module_, logger, is_inner_function, may_abort, |
| 3294 use_counts_); | 3286 use_counts_); |
| 3295 if (pre_parse_timer_ != NULL) { | |
| 3296 pre_parse_timer_->Stop(); | |
| 3297 } | |
| 3298 return result; | 3287 return result; |
| 3299 } | 3288 } |
| 3300 | 3289 |
| 3301 Expression* Parser::InstallHomeObject(Expression* function_literal, | 3290 Expression* Parser::InstallHomeObject(Expression* function_literal, |
| 3302 Expression* home_object) { | 3291 Expression* home_object) { |
| 3303 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 3292 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); |
| 3304 Variable* result_var = | 3293 Variable* result_var = |
| 3305 scope()->NewTemporary(ast_value_factory()->empty_string()); | 3294 scope()->NewTemporary(ast_value_factory()->empty_string()); |
| 3306 DoExpression* do_expr = | 3295 DoExpression* do_expr = |
| 3307 factory()->NewDoExpression(do_block, result_var, kNoSourcePosition); | 3296 factory()->NewDoExpression(do_block, result_var, kNoSourcePosition); |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3768 return false; | 3757 return false; |
| 3769 } | 3758 } |
| 3770 | 3759 |
| 3771 | 3760 |
| 3772 bool Parser::Parse(ParseInfo* info) { | 3761 bool Parser::Parse(ParseInfo* info) { |
| 3773 DCHECK(info->literal() == NULL); | 3762 DCHECK(info->literal() == NULL); |
| 3774 FunctionLiteral* result = NULL; | 3763 FunctionLiteral* result = NULL; |
| 3775 // Ok to use Isolate here; this function is only called in the main thread. | 3764 // Ok to use Isolate here; this function is only called in the main thread. |
| 3776 DCHECK(parsing_on_main_thread_); | 3765 DCHECK(parsing_on_main_thread_); |
| 3777 Isolate* isolate = info->isolate(); | 3766 Isolate* isolate = info->isolate(); |
| 3778 pre_parse_timer_ = isolate->counters()->pre_parse(); | |
| 3779 | 3767 |
| 3780 if (info->is_toplevel()) { | 3768 if (info->is_toplevel()) { |
| 3781 SetCachedData(info); | 3769 SetCachedData(info); |
| 3782 result = ParseProgram(isolate, info); | 3770 result = ParseProgram(isolate, info); |
| 3783 } else { | 3771 } else { |
| 3784 result = ParseFunction(isolate, info); | 3772 result = ParseFunction(isolate, info); |
| 3785 } | 3773 } |
| 3786 info->set_literal(result); | 3774 info->set_literal(result); |
| 3787 | 3775 |
| 3788 Internalize(isolate, info->script(), result == NULL); | 3776 Internalize(isolate, info->script(), result == NULL); |
| (...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5408 | 5396 |
| 5409 return final_loop; | 5397 return final_loop; |
| 5410 } | 5398 } |
| 5411 | 5399 |
| 5412 #undef CHECK_OK | 5400 #undef CHECK_OK |
| 5413 #undef CHECK_OK_VOID | 5401 #undef CHECK_OK_VOID |
| 5414 #undef CHECK_FAILED | 5402 #undef CHECK_FAILED |
| 5415 | 5403 |
| 5416 } // namespace internal | 5404 } // namespace internal |
| 5417 } // namespace v8 | 5405 } // namespace v8 |
| OLD | NEW |