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 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 ReportMessage(MessageTemplate::kNotDefined, name); | 580 ReportMessage(MessageTemplate::kNotDefined, name); |
581 *ok = false; | 581 *ok = false; |
582 return nullptr; | 582 return nullptr; |
583 } | 583 } |
584 | 584 |
585 return factory()->NewCallRuntime(context_index, args, pos); | 585 return factory()->NewCallRuntime(context_index, args, pos); |
586 } | 586 } |
587 | 587 |
588 Parser::Parser(ParseInfo* info) | 588 Parser::Parser(ParseInfo* info) |
589 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), | 589 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), |
590 info->extension(), info->ast_value_factory()), | 590 info->extension(), info->ast_value_factory(), |
| 591 info->isolate()->counters()->runtime_call_stats()), |
591 scanner_(info->unicode_cache()), | 592 scanner_(info->unicode_cache()), |
592 reusable_preparser_(nullptr), | 593 reusable_preparser_(nullptr), |
593 original_scope_(nullptr), | 594 original_scope_(nullptr), |
594 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 595 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
595 target_stack_(nullptr), | 596 target_stack_(nullptr), |
596 compile_options_(info->compile_options()), | 597 compile_options_(info->compile_options()), |
597 cached_parse_data_(nullptr), | 598 cached_parse_data_(nullptr), |
598 total_preparse_skipped_(0), | 599 total_preparse_skipped_(0), |
599 parsing_on_main_thread_(true), | 600 parsing_on_main_thread_(true), |
600 log_(nullptr) { | 601 log_(nullptr) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 } | 665 } |
665 | 666 |
666 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { | 667 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { |
667 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 668 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
668 // see comment for HistogramTimerScope class. | 669 // see comment for HistogramTimerScope class. |
669 | 670 |
670 // It's OK to use the Isolate & counters here, since this function is only | 671 // It's OK to use the Isolate & counters here, since this function is only |
671 // called in the main thread. | 672 // called in the main thread. |
672 DCHECK(parsing_on_main_thread_); | 673 DCHECK(parsing_on_main_thread_); |
673 | 674 |
674 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseProgram); | 675 RuntimeCallTimerScope runtime_timer( |
| 676 runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval |
| 677 : &RuntimeCallStats::ParseProgram); |
675 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram"); | 678 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram"); |
676 Handle<String> source(String::cast(info->script()->source())); | 679 Handle<String> source(String::cast(info->script()->source())); |
677 isolate->counters()->total_parse_size()->Increment(source->length()); | 680 isolate->counters()->total_parse_size()->Increment(source->length()); |
678 base::ElapsedTimer timer; | 681 base::ElapsedTimer timer; |
679 if (FLAG_trace_parse) { | 682 if (FLAG_trace_parse) { |
680 timer.Start(); | 683 timer.Start(); |
681 } | 684 } |
682 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 685 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
683 | 686 |
684 // Initialize parser state. | 687 // Initialize parser state. |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 // Make sure the target stack is empty. | 830 // Make sure the target stack is empty. |
828 DCHECK(target_stack_ == NULL); | 831 DCHECK(target_stack_ == NULL); |
829 | 832 |
830 return result; | 833 return result; |
831 } | 834 } |
832 | 835 |
833 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) { | 836 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) { |
834 // It's OK to use the Isolate & counters here, since this function is only | 837 // It's OK to use the Isolate & counters here, since this function is only |
835 // called in the main thread. | 838 // called in the main thread. |
836 DCHECK(parsing_on_main_thread_); | 839 DCHECK(parsing_on_main_thread_); |
837 RuntimeCallTimerScope runtime_timer(isolate, | 840 RuntimeCallTimerScope runtime_timer(runtime_call_stats_, |
838 &RuntimeCallStats::ParseFunction); | 841 &RuntimeCallStats::ParseFunction); |
839 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction"); | 842 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction"); |
840 Handle<String> source(String::cast(info->script()->source())); | 843 Handle<String> source(String::cast(info->script()->source())); |
841 isolate->counters()->total_parse_size()->Increment(source->length()); | 844 isolate->counters()->total_parse_size()->Increment(source->length()); |
842 base::ElapsedTimer timer; | 845 base::ElapsedTimer timer; |
843 if (FLAG_trace_parse) { | 846 if (FLAG_trace_parse) { |
844 timer.Start(); | 847 timer.Start(); |
845 } | 848 } |
846 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 849 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
847 DeserializeScopeChain(info, info->maybe_outer_scope_info()); | 850 DeserializeScopeChain(info, info->maybe_outer_scope_info()); |
(...skipping 1726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2574 DCHECK_IMPLIES(parse_lazily(), FLAG_lazy); | 2577 DCHECK_IMPLIES(parse_lazily(), FLAG_lazy); |
2575 DCHECK_IMPLIES(parse_lazily(), allow_lazy()); | 2578 DCHECK_IMPLIES(parse_lazily(), allow_lazy()); |
2576 DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr); | 2579 DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr); |
2577 | 2580 |
2578 bool can_preparse = parse_lazily() && | 2581 bool can_preparse = parse_lazily() && |
2579 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; | 2582 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; |
2580 | 2583 |
2581 bool is_lazy_top_level_function = | 2584 bool is_lazy_top_level_function = |
2582 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); | 2585 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); |
2583 | 2586 |
| 2587 RuntimeCallTimerScope runtime_timer(runtime_call_stats_, |
| 2588 &RuntimeCallStats::ParseFunctionLiteral); |
| 2589 |
2584 // Determine whether we can still lazy parse the inner function. | 2590 // Determine whether we can still lazy parse the inner function. |
2585 // The preconditions are: | 2591 // The preconditions are: |
2586 // - Lazy compilation has to be enabled. | 2592 // - Lazy compilation has to be enabled. |
2587 // - Neither V8 natives nor native function declarations can be allowed, | 2593 // - Neither V8 natives nor native function declarations can be allowed, |
2588 // since parsing one would retroactively force the function to be | 2594 // since parsing one would retroactively force the function to be |
2589 // eagerly compiled. | 2595 // eagerly compiled. |
2590 // - The invoker of this parser can't depend on the AST being eagerly | 2596 // - The invoker of this parser can't depend on the AST being eagerly |
2591 // built (either because the function is about to be compiled, or | 2597 // built (either because the function is about to be compiled, or |
2592 // because the AST is going to be inspected for some reason). | 2598 // because the AST is going to be inspected for some reason). |
2593 // - Because of the above, we can't be attempting to parse a | 2599 // - 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... |
2691 scope->AnalyzePartially(&previous_zone_ast_node_factory); | 2697 scope->AnalyzePartially(&previous_zone_ast_node_factory); |
2692 } | 2698 } |
2693 | 2699 |
2694 if (FLAG_trace_preparse) { | 2700 if (FLAG_trace_preparse) { |
2695 PrintF(" [%s]: %i-%i %.*s\n", | 2701 PrintF(" [%s]: %i-%i %.*s\n", |
2696 is_lazy_top_level_function | 2702 is_lazy_top_level_function |
2697 ? "Preparse no-resolution" | 2703 ? "Preparse no-resolution" |
2698 : (use_temp_zone ? "Preparse resolution" : "Full parse"), | 2704 : (use_temp_zone ? "Preparse resolution" : "Full parse"), |
2699 scope->start_position(), scope->end_position(), | 2705 scope->start_position(), scope->end_position(), |
2700 function_name->byte_length(), function_name->raw_data()); | 2706 function_name->byte_length(), function_name->raw_data()); |
| 2707 if (is_lazy_top_level_function) { |
| 2708 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_, |
| 2709 PreParseNoVariableResolution); |
| 2710 } else if (use_temp_zone) { |
| 2711 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_, |
| 2712 PreParseWithVariableResolution); |
| 2713 } |
2701 } | 2714 } |
2702 | 2715 |
2703 // Validate function name. We can do this only after parsing the function, | 2716 // Validate function name. We can do this only after parsing the function, |
2704 // since the function can declare itself strict. | 2717 // since the function can declare itself strict. |
2705 language_mode = scope->language_mode(); | 2718 language_mode = scope->language_mode(); |
2706 CheckFunctionName(language_mode, function_name, function_name_validity, | 2719 CheckFunctionName(language_mode, function_name, function_name_validity, |
2707 function_name_location, CHECK_OK); | 2720 function_name_location, CHECK_OK); |
2708 | 2721 |
2709 if (is_strict(language_mode)) { | 2722 if (is_strict(language_mode)) { |
2710 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 2723 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3285 MarkCollectedTailCallExpressions(); | 3298 MarkCollectedTailCallExpressions(); |
3286 return result; | 3299 return result; |
3287 } | 3300 } |
3288 | 3301 |
3289 PreParser::PreParseResult Parser::ParseFunctionWithPreParser( | 3302 PreParser::PreParseResult Parser::ParseFunctionWithPreParser( |
3290 FunctionKind kind, DeclarationScope* function_scope, bool is_inner_function, | 3303 FunctionKind kind, DeclarationScope* function_scope, bool is_inner_function, |
3291 bool may_abort) { | 3304 bool may_abort) { |
3292 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); | 3305 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); |
3293 | 3306 |
3294 if (reusable_preparser_ == NULL) { | 3307 if (reusable_preparser_ == NULL) { |
3295 reusable_preparser_ = | 3308 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), |
3296 new PreParser(zone(), &scanner_, ast_value_factory(), stack_limit_); | 3309 runtime_call_stats_, stack_limit_); |
3297 reusable_preparser_->set_allow_lazy(true); | 3310 reusable_preparser_->set_allow_lazy(true); |
3298 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 3311 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
3299 SET_ALLOW(natives); | 3312 SET_ALLOW(natives); |
3300 SET_ALLOW(harmony_do_expressions); | 3313 SET_ALLOW(harmony_do_expressions); |
3301 SET_ALLOW(harmony_function_sent); | 3314 SET_ALLOW(harmony_function_sent); |
3302 SET_ALLOW(harmony_async_await); | 3315 SET_ALLOW(harmony_async_await); |
3303 SET_ALLOW(harmony_trailing_commas); | 3316 SET_ALLOW(harmony_trailing_commas); |
3304 SET_ALLOW(harmony_class_fields); | 3317 SET_ALLOW(harmony_class_fields); |
3305 #undef SET_ALLOW | 3318 #undef SET_ALLOW |
3306 } | 3319 } |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3760 } | 3773 } |
3761 } | 3774 } |
3762 if (scanner_.FoundHtmlComment()) { | 3775 if (scanner_.FoundHtmlComment()) { |
3763 isolate->CountUsage(v8::Isolate::kHtmlComment); | 3776 isolate->CountUsage(v8::Isolate::kHtmlComment); |
3764 if (script->line_offset() == 0 && script->column_offset() == 0) { | 3777 if (script->line_offset() == 0 && script->column_offset() == 0) { |
3765 isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript); | 3778 isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript); |
3766 } | 3779 } |
3767 } | 3780 } |
3768 isolate->counters()->total_preparse_skipped()->Increment( | 3781 isolate->counters()->total_preparse_skipped()->Increment( |
3769 total_preparse_skipped_); | 3782 total_preparse_skipped_); |
| 3783 if (!parsing_on_main_thread_ && |
| 3784 FLAG_runtime_stats == |
| 3785 v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE) { |
| 3786 // Copy over the counters from the background thread to the main counters on |
| 3787 // the isolate. |
| 3788 // TODO(cbruni,lpy): properly attach the runtime stats to the trace for |
| 3789 // background parsing. |
| 3790 isolate->counters()->runtime_call_stats()->Add(runtime_call_stats_); |
| 3791 } |
3770 } | 3792 } |
3771 | 3793 |
3772 | 3794 |
3773 // ---------------------------------------------------------------------------- | 3795 // ---------------------------------------------------------------------------- |
3774 // The Parser interface. | 3796 // The Parser interface. |
3775 | 3797 |
3776 | 3798 |
3777 bool Parser::ParseStatic(ParseInfo* info) { | 3799 bool Parser::ParseStatic(ParseInfo* info) { |
3778 Parser parser(info); | 3800 Parser parser(info); |
3779 if (parser.Parse(info)) { | 3801 if (parser.Parse(info)) { |
(...skipping 25 matching lines...) Expand all Loading... |
3805 | 3827 |
3806 | 3828 |
3807 void Parser::ParseOnBackground(ParseInfo* info) { | 3829 void Parser::ParseOnBackground(ParseInfo* info) { |
3808 parsing_on_main_thread_ = false; | 3830 parsing_on_main_thread_ = false; |
3809 | 3831 |
3810 DCHECK(info->literal() == NULL); | 3832 DCHECK(info->literal() == NULL); |
3811 FunctionLiteral* result = NULL; | 3833 FunctionLiteral* result = NULL; |
3812 | 3834 |
3813 ParserLogger logger; | 3835 ParserLogger logger; |
3814 if (produce_cached_parse_data()) log_ = &logger; | 3836 if (produce_cached_parse_data()) log_ = &logger; |
| 3837 if (FLAG_runtime_stats) { |
| 3838 // Create separate runtime stats for background parsing. |
| 3839 runtime_call_stats_ = new (zone()) RuntimeCallStats(); |
| 3840 } |
3815 | 3841 |
3816 std::unique_ptr<Utf16CharacterStream> stream; | 3842 std::unique_ptr<Utf16CharacterStream> stream; |
3817 Utf16CharacterStream* stream_ptr; | 3843 Utf16CharacterStream* stream_ptr; |
3818 if (info->character_stream()) { | 3844 if (info->character_stream()) { |
3819 DCHECK(info->source_stream() == nullptr); | 3845 DCHECK(info->source_stream() == nullptr); |
3820 stream_ptr = info->character_stream(); | 3846 stream_ptr = info->character_stream(); |
3821 } else { | 3847 } else { |
3822 DCHECK(info->character_stream() == nullptr); | 3848 DCHECK(info->character_stream() == nullptr); |
3823 stream.reset(ScannerStream::For(info->source_stream(), | 3849 stream.reset(ScannerStream::For(info->source_stream(), |
3824 info->source_stream_encoding())); | 3850 info->source_stream_encoding())); |
(...skipping 19 matching lines...) Expand all Loading... |
3844 | 3870 |
3845 info->set_literal(result); | 3871 info->set_literal(result); |
3846 | 3872 |
3847 // We cannot internalize on a background thread; a foreground task will take | 3873 // We cannot internalize on a background thread; a foreground task will take |
3848 // care of calling Parser::Internalize just before compilation. | 3874 // care of calling Parser::Internalize just before compilation. |
3849 | 3875 |
3850 if (produce_cached_parse_data()) { | 3876 if (produce_cached_parse_data()) { |
3851 if (result != NULL) *info->cached_data() = logger.GetScriptData(); | 3877 if (result != NULL) *info->cached_data() = logger.GetScriptData(); |
3852 log_ = NULL; | 3878 log_ = NULL; |
3853 } | 3879 } |
| 3880 if (FLAG_runtime_stats) { |
| 3881 // TODO(cbruni,lpy): properly attach the runtime stats to the trace for |
| 3882 // background parsing. |
| 3883 } |
3854 } | 3884 } |
3855 | 3885 |
3856 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { | 3886 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { |
3857 return new (zone()) TemplateLiteral(zone(), pos); | 3887 return new (zone()) TemplateLiteral(zone(), pos); |
3858 } | 3888 } |
3859 | 3889 |
3860 | 3890 |
3861 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) { | 3891 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) { |
3862 int pos = scanner()->location().beg_pos; | 3892 int pos = scanner()->location().beg_pos; |
3863 int end = scanner()->location().end_pos - (tail ? 1 : 2); | 3893 int end = scanner()->location().end_pos - (tail ? 1 : 2); |
(...skipping 1557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5421 | 5451 |
5422 return final_loop; | 5452 return final_loop; |
5423 } | 5453 } |
5424 | 5454 |
5425 #undef CHECK_OK | 5455 #undef CHECK_OK |
5426 #undef CHECK_OK_VOID | 5456 #undef CHECK_OK_VOID |
5427 #undef CHECK_FAILED | 5457 #undef CHECK_FAILED |
5428 | 5458 |
5429 } // namespace internal | 5459 } // namespace internal |
5430 } // namespace v8 | 5460 } // namespace v8 |
OLD | NEW |