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 |