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 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 ReportMessage(MessageTemplate::kNotDefined, name); | 574 ReportMessage(MessageTemplate::kNotDefined, name); |
575 *ok = false; | 575 *ok = false; |
576 return nullptr; | 576 return nullptr; |
577 } | 577 } |
578 | 578 |
579 return factory()->NewCallRuntime(context_index, args, pos); | 579 return factory()->NewCallRuntime(context_index, args, pos); |
580 } | 580 } |
581 | 581 |
582 Parser::Parser(ParseInfo* info) | 582 Parser::Parser(ParseInfo* info) |
583 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), | 583 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), |
584 info->extension(), info->ast_value_factory()), | 584 info->extension(), info->ast_value_factory(), |
| 585 info->isolate()->counters()->runtime_call_stats()), |
585 scanner_(info->unicode_cache()), | 586 scanner_(info->unicode_cache()), |
586 reusable_preparser_(nullptr), | 587 reusable_preparser_(nullptr), |
587 original_scope_(nullptr), | 588 original_scope_(nullptr), |
588 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 589 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
589 target_stack_(nullptr), | 590 target_stack_(nullptr), |
590 compile_options_(info->compile_options()), | 591 compile_options_(info->compile_options()), |
591 cached_parse_data_(nullptr), | 592 cached_parse_data_(nullptr), |
592 total_preparse_skipped_(0), | 593 total_preparse_skipped_(0), |
593 parsing_on_main_thread_(true), | 594 parsing_on_main_thread_(true), |
594 log_(nullptr) { | 595 log_(nullptr) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 } | 659 } |
659 | 660 |
660 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { | 661 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { |
661 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 662 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
662 // see comment for HistogramTimerScope class. | 663 // see comment for HistogramTimerScope class. |
663 | 664 |
664 // It's OK to use the Isolate & counters here, since this function is only | 665 // It's OK to use the Isolate & counters here, since this function is only |
665 // called in the main thread. | 666 // called in the main thread. |
666 DCHECK(parsing_on_main_thread_); | 667 DCHECK(parsing_on_main_thread_); |
667 | 668 |
668 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseProgram); | 669 RuntimeCallTimerScope runtime_timer( |
| 670 runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval |
| 671 : &RuntimeCallStats::ParseProgram); |
669 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram"); | 672 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram"); |
670 Handle<String> source(String::cast(info->script()->source())); | 673 Handle<String> source(String::cast(info->script()->source())); |
671 isolate->counters()->total_parse_size()->Increment(source->length()); | 674 isolate->counters()->total_parse_size()->Increment(source->length()); |
672 base::ElapsedTimer timer; | 675 base::ElapsedTimer timer; |
673 if (FLAG_trace_parse) { | 676 if (FLAG_trace_parse) { |
674 timer.Start(); | 677 timer.Start(); |
675 } | 678 } |
676 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 679 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
677 | 680 |
678 // Initialize parser state. | 681 // Initialize parser state. |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 // Make sure the target stack is empty. | 824 // Make sure the target stack is empty. |
822 DCHECK(target_stack_ == NULL); | 825 DCHECK(target_stack_ == NULL); |
823 | 826 |
824 return result; | 827 return result; |
825 } | 828 } |
826 | 829 |
827 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) { | 830 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) { |
828 // It's OK to use the Isolate & counters here, since this function is only | 831 // It's OK to use the Isolate & counters here, since this function is only |
829 // called in the main thread. | 832 // called in the main thread. |
830 DCHECK(parsing_on_main_thread_); | 833 DCHECK(parsing_on_main_thread_); |
831 RuntimeCallTimerScope runtime_timer(isolate, | 834 RuntimeCallTimerScope runtime_timer(runtime_call_stats_, |
832 &RuntimeCallStats::ParseFunction); | 835 &RuntimeCallStats::ParseFunction); |
833 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction"); | 836 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction"); |
834 Handle<String> source(String::cast(info->script()->source())); | 837 Handle<String> source(String::cast(info->script()->source())); |
835 isolate->counters()->total_parse_size()->Increment(source->length()); | 838 isolate->counters()->total_parse_size()->Increment(source->length()); |
836 base::ElapsedTimer timer; | 839 base::ElapsedTimer timer; |
837 if (FLAG_trace_parse) { | 840 if (FLAG_trace_parse) { |
838 timer.Start(); | 841 timer.Start(); |
839 } | 842 } |
840 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 843 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
841 DeserializeScopeChain(info, info->maybe_outer_scope_info()); | 844 DeserializeScopeChain(info, info->maybe_outer_scope_info()); |
(...skipping 1726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2568 DCHECK_IMPLIES(parse_lazily(), FLAG_lazy); | 2571 DCHECK_IMPLIES(parse_lazily(), FLAG_lazy); |
2569 DCHECK_IMPLIES(parse_lazily(), allow_lazy()); | 2572 DCHECK_IMPLIES(parse_lazily(), allow_lazy()); |
2570 DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr); | 2573 DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr); |
2571 | 2574 |
2572 bool can_preparse = parse_lazily() && | 2575 bool can_preparse = parse_lazily() && |
2573 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; | 2576 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; |
2574 | 2577 |
2575 bool is_lazy_top_level_function = | 2578 bool is_lazy_top_level_function = |
2576 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); | 2579 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); |
2577 | 2580 |
| 2581 RuntimeCallTimerScope runtime_timer(runtime_call_stats_, |
| 2582 &RuntimeCallStats::ParseFunctionLiteral); |
| 2583 |
2578 // Determine whether we can still lazy parse the inner function. | 2584 // Determine whether we can still lazy parse the inner function. |
2579 // The preconditions are: | 2585 // The preconditions are: |
2580 // - Lazy compilation has to be enabled. | 2586 // - Lazy compilation has to be enabled. |
2581 // - Neither V8 natives nor native function declarations can be allowed, | 2587 // - Neither V8 natives nor native function declarations can be allowed, |
2582 // since parsing one would retroactively force the function to be | 2588 // since parsing one would retroactively force the function to be |
2583 // eagerly compiled. | 2589 // eagerly compiled. |
2584 // - The invoker of this parser can't depend on the AST being eagerly | 2590 // - The invoker of this parser can't depend on the AST being eagerly |
2585 // built (either because the function is about to be compiled, or | 2591 // built (either because the function is about to be compiled, or |
2586 // because the AST is going to be inspected for some reason). | 2592 // because the AST is going to be inspected for some reason). |
2587 // - Because of the above, we can't be attempting to parse a | 2593 // - Because of the above, we can't be attempting to parse a |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2685 scope->AnalyzePartially(&previous_zone_ast_node_factory); | 2691 scope->AnalyzePartially(&previous_zone_ast_node_factory); |
2686 } | 2692 } |
2687 | 2693 |
2688 if (FLAG_trace_preparse) { | 2694 if (FLAG_trace_preparse) { |
2689 PrintF(" [%s]: %i-%i %.*s\n", | 2695 PrintF(" [%s]: %i-%i %.*s\n", |
2690 is_lazy_top_level_function | 2696 is_lazy_top_level_function |
2691 ? "Preparse no-resolution" | 2697 ? "Preparse no-resolution" |
2692 : (use_temp_zone ? "Preparse resolution" : "Full parse"), | 2698 : (use_temp_zone ? "Preparse resolution" : "Full parse"), |
2693 scope->start_position(), scope->end_position(), | 2699 scope->start_position(), scope->end_position(), |
2694 function_name->byte_length(), function_name->raw_data()); | 2700 function_name->byte_length(), function_name->raw_data()); |
| 2701 if (is_lazy_top_level_function) { |
| 2702 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_, |
| 2703 PreParseNoVariableResolution); |
| 2704 } else if (use_temp_zone) { |
| 2705 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_, |
| 2706 PreParseWithVariableResolution); |
| 2707 } |
2695 } | 2708 } |
2696 | 2709 |
2697 // Validate function name. We can do this only after parsing the function, | 2710 // Validate function name. We can do this only after parsing the function, |
2698 // since the function can declare itself strict. | 2711 // since the function can declare itself strict. |
2699 language_mode = scope->language_mode(); | 2712 language_mode = scope->language_mode(); |
2700 CheckFunctionName(language_mode, function_name, function_name_validity, | 2713 CheckFunctionName(language_mode, function_name, function_name_validity, |
2701 function_name_location, CHECK_OK); | 2714 function_name_location, CHECK_OK); |
2702 | 2715 |
2703 if (is_strict(language_mode)) { | 2716 if (is_strict(language_mode)) { |
2704 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 2717 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3277 return result; | 3290 return result; |
3278 } | 3291 } |
3279 | 3292 |
3280 PreParser::PreParseResult Parser::ParseFunctionWithPreParser( | 3293 PreParser::PreParseResult Parser::ParseFunctionWithPreParser( |
3281 FunctionKind kind, DeclarationScope* function_scope, bool is_inner_function, | 3294 FunctionKind kind, DeclarationScope* function_scope, bool is_inner_function, |
3282 bool may_abort) { | 3295 bool may_abort) { |
3283 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); | 3296 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); |
3284 | 3297 |
3285 if (reusable_preparser_ == NULL) { | 3298 if (reusable_preparser_ == NULL) { |
3286 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), | 3299 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), |
3287 &pending_error_handler_, stack_limit_); | 3300 &pending_error_handler_, |
| 3301 runtime_call_stats_, stack_limit_); |
3288 reusable_preparser_->set_allow_lazy(true); | 3302 reusable_preparser_->set_allow_lazy(true); |
3289 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 3303 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
3290 SET_ALLOW(natives); | 3304 SET_ALLOW(natives); |
3291 SET_ALLOW(harmony_do_expressions); | 3305 SET_ALLOW(harmony_do_expressions); |
3292 SET_ALLOW(harmony_function_sent); | 3306 SET_ALLOW(harmony_function_sent); |
3293 SET_ALLOW(harmony_async_await); | 3307 SET_ALLOW(harmony_async_await); |
3294 SET_ALLOW(harmony_trailing_commas); | 3308 SET_ALLOW(harmony_trailing_commas); |
3295 SET_ALLOW(harmony_class_fields); | 3309 SET_ALLOW(harmony_class_fields); |
3296 #undef SET_ALLOW | 3310 #undef SET_ALLOW |
3297 } | 3311 } |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3751 } | 3765 } |
3752 } | 3766 } |
3753 if (scanner_.FoundHtmlComment()) { | 3767 if (scanner_.FoundHtmlComment()) { |
3754 isolate->CountUsage(v8::Isolate::kHtmlComment); | 3768 isolate->CountUsage(v8::Isolate::kHtmlComment); |
3755 if (script->line_offset() == 0 && script->column_offset() == 0) { | 3769 if (script->line_offset() == 0 && script->column_offset() == 0) { |
3756 isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript); | 3770 isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript); |
3757 } | 3771 } |
3758 } | 3772 } |
3759 isolate->counters()->total_preparse_skipped()->Increment( | 3773 isolate->counters()->total_preparse_skipped()->Increment( |
3760 total_preparse_skipped_); | 3774 total_preparse_skipped_); |
| 3775 if (!parsing_on_main_thread_ && |
| 3776 FLAG_runtime_stats == |
| 3777 v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE) { |
| 3778 // Copy over the counters from the background thread to the main counters on |
| 3779 // the isolate. |
| 3780 // TODO(cbruni,lpy): properly attach the runtime stats to the trace for |
| 3781 // background parsing. |
| 3782 isolate->counters()->runtime_call_stats()->Add(runtime_call_stats_); |
| 3783 } |
3761 } | 3784 } |
3762 | 3785 |
3763 | 3786 |
3764 // ---------------------------------------------------------------------------- | 3787 // ---------------------------------------------------------------------------- |
3765 // The Parser interface. | 3788 // The Parser interface. |
3766 | 3789 |
3767 | 3790 |
3768 bool Parser::ParseStatic(ParseInfo* info) { | 3791 bool Parser::ParseStatic(ParseInfo* info) { |
3769 Parser parser(info); | 3792 Parser parser(info); |
3770 if (parser.Parse(info)) { | 3793 if (parser.Parse(info)) { |
(...skipping 25 matching lines...) Expand all Loading... |
3796 | 3819 |
3797 | 3820 |
3798 void Parser::ParseOnBackground(ParseInfo* info) { | 3821 void Parser::ParseOnBackground(ParseInfo* info) { |
3799 parsing_on_main_thread_ = false; | 3822 parsing_on_main_thread_ = false; |
3800 | 3823 |
3801 DCHECK(info->literal() == NULL); | 3824 DCHECK(info->literal() == NULL); |
3802 FunctionLiteral* result = NULL; | 3825 FunctionLiteral* result = NULL; |
3803 | 3826 |
3804 ParserLogger logger; | 3827 ParserLogger logger; |
3805 if (produce_cached_parse_data()) log_ = &logger; | 3828 if (produce_cached_parse_data()) log_ = &logger; |
| 3829 if (FLAG_runtime_stats) { |
| 3830 // Create separate runtime stats for background parsing. |
| 3831 runtime_call_stats_ = new (zone()) RuntimeCallStats(); |
| 3832 } |
3806 | 3833 |
3807 std::unique_ptr<Utf16CharacterStream> stream; | 3834 std::unique_ptr<Utf16CharacterStream> stream; |
3808 Utf16CharacterStream* stream_ptr; | 3835 Utf16CharacterStream* stream_ptr; |
3809 if (info->character_stream()) { | 3836 if (info->character_stream()) { |
3810 DCHECK(info->source_stream() == nullptr); | 3837 DCHECK(info->source_stream() == nullptr); |
3811 stream_ptr = info->character_stream(); | 3838 stream_ptr = info->character_stream(); |
3812 } else { | 3839 } else { |
3813 DCHECK(info->character_stream() == nullptr); | 3840 DCHECK(info->character_stream() == nullptr); |
3814 stream.reset(ScannerStream::For(info->source_stream(), | 3841 stream.reset(ScannerStream::For(info->source_stream(), |
3815 info->source_stream_encoding())); | 3842 info->source_stream_encoding())); |
(...skipping 19 matching lines...) Expand all Loading... |
3835 | 3862 |
3836 info->set_literal(result); | 3863 info->set_literal(result); |
3837 | 3864 |
3838 // We cannot internalize on a background thread; a foreground task will take | 3865 // We cannot internalize on a background thread; a foreground task will take |
3839 // care of calling Parser::Internalize just before compilation. | 3866 // care of calling Parser::Internalize just before compilation. |
3840 | 3867 |
3841 if (produce_cached_parse_data()) { | 3868 if (produce_cached_parse_data()) { |
3842 if (result != NULL) *info->cached_data() = logger.GetScriptData(); | 3869 if (result != NULL) *info->cached_data() = logger.GetScriptData(); |
3843 log_ = NULL; | 3870 log_ = NULL; |
3844 } | 3871 } |
| 3872 if (FLAG_runtime_stats) { |
| 3873 // TODO(cbruni,lpy): properly attach the runtime stats to the trace for |
| 3874 // background parsing. |
| 3875 } |
3845 } | 3876 } |
3846 | 3877 |
3847 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { | 3878 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { |
3848 return new (zone()) TemplateLiteral(zone(), pos); | 3879 return new (zone()) TemplateLiteral(zone(), pos); |
3849 } | 3880 } |
3850 | 3881 |
3851 | 3882 |
3852 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) { | 3883 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) { |
3853 int pos = scanner()->location().beg_pos; | 3884 int pos = scanner()->location().beg_pos; |
3854 int end = scanner()->location().end_pos - (tail ? 1 : 2); | 3885 int end = scanner()->location().end_pos - (tail ? 1 : 2); |
(...skipping 1557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5412 | 5443 |
5413 return final_loop; | 5444 return final_loop; |
5414 } | 5445 } |
5415 | 5446 |
5416 #undef CHECK_OK | 5447 #undef CHECK_OK |
5417 #undef CHECK_OK_VOID | 5448 #undef CHECK_OK_VOID |
5418 #undef CHECK_FAILED | 5449 #undef CHECK_FAILED |
5419 | 5450 |
5420 } // namespace internal | 5451 } // namespace internal |
5421 } // namespace v8 | 5452 } // namespace v8 |
OLD | NEW |