Chromium Code Reviews

Side by Side Diff: src/parsing/parser.cc

Issue 2514353002: [parser] Keep track of whether we are in a temp-zone in the parser, and don't lazy parse anymore on… (Closed)
Patch Set: Move ParsingModeScope to ParseFunction and drop mode from DiscardableZoneScope Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « src/parsing/parser.h ('k') | no next file » | no next file with comments »
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/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 94 matching lines...)
105 105
106 // Helper for putting parts of the parse results into a temporary zone when 106 // Helper for putting parts of the parse results into a temporary zone when
107 // parsing inner function bodies. 107 // parsing inner function bodies.
108 class DiscardableZoneScope { 108 class DiscardableZoneScope {
109 public: 109 public:
110 DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone) 110 DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone)
111 : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone), 111 : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone),
112 fni_(parser->ast_value_factory_, temp_zone), 112 fni_(parser->ast_value_factory_, temp_zone),
113 parser_(parser), 113 parser_(parser),
114 prev_fni_(parser->fni_), 114 prev_fni_(parser->fni_),
115 prev_zone_(parser->zone_) { 115 prev_zone_(parser->zone_),
116 prev_allow_lazy_(parser->allow_lazy_),
117 prev_temp_zoned_(parser->temp_zoned_) {
116 if (use_temp_zone) { 118 if (use_temp_zone) {
119 DCHECK(!parser_->temp_zoned_);
120 parser_->allow_lazy_ = false;
121 parser_->temp_zoned_ = true;
117 parser_->fni_ = &fni_; 122 parser_->fni_ = &fni_;
118 parser_->zone_ = temp_zone; 123 parser_->zone_ = temp_zone;
119 if (parser_->reusable_preparser_ != nullptr) { 124 if (parser_->reusable_preparser_ != nullptr) {
120 parser_->reusable_preparser_->zone_ = temp_zone; 125 parser_->reusable_preparser_->zone_ = temp_zone;
121 parser_->reusable_preparser_->factory()->set_zone(temp_zone); 126 parser_->reusable_preparser_->factory()->set_zone(temp_zone);
122 } 127 }
123 } 128 }
124 } 129 }
125 void Reset() { 130 void Reset() {
126 parser_->fni_ = prev_fni_; 131 parser_->fni_ = prev_fni_;
127 parser_->zone_ = prev_zone_; 132 parser_->zone_ = prev_zone_;
133 parser_->allow_lazy_ = prev_allow_lazy_;
134 parser_->temp_zoned_ = prev_temp_zoned_;
128 if (parser_->reusable_preparser_ != nullptr) { 135 if (parser_->reusable_preparser_ != nullptr) {
129 parser_->reusable_preparser_->zone_ = prev_zone_; 136 parser_->reusable_preparser_->zone_ = prev_zone_;
130 parser_->reusable_preparser_->factory()->set_zone(prev_zone_); 137 parser_->reusable_preparser_->factory()->set_zone(prev_zone_);
131 } 138 }
132 ast_node_factory_scope_.Reset(); 139 ast_node_factory_scope_.Reset();
133 } 140 }
134 ~DiscardableZoneScope() { Reset(); } 141 ~DiscardableZoneScope() { Reset(); }
135 142
136 private: 143 private:
137 AstNodeFactory::BodyScope ast_node_factory_scope_; 144 AstNodeFactory::BodyScope ast_node_factory_scope_;
138 FuncNameInferrer fni_; 145 FuncNameInferrer fni_;
139 Parser* parser_; 146 Parser* parser_;
140 FuncNameInferrer* prev_fni_; 147 FuncNameInferrer* prev_fni_;
141 Zone* prev_zone_; 148 Zone* prev_zone_;
149 bool prev_allow_lazy_;
150 bool prev_temp_zoned_;
142 151
143 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope); 152 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope);
144 }; 153 };
145 154
146 void Parser::SetCachedData(ParseInfo* info) { 155 void Parser::SetCachedData(ParseInfo* info) {
147 DCHECK_NULL(cached_parse_data_); 156 DCHECK_NULL(cached_parse_data_);
148 if (consume_cached_parse_data()) { 157 if (consume_cached_parse_data()) {
149 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data()); 158 if (allow_lazy_) {
150 if (cached_parse_data_ == nullptr) { 159 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
151 compile_options_ = ScriptCompiler::kNoCompileOptions; 160 if (cached_parse_data_ != nullptr) return;
152 } 161 }
162 compile_options_ = ScriptCompiler::kNoCompileOptions;
153 } 163 }
154 } 164 }
155 165
156 Expression* Parser::CallClassFieldInitializer(Scope* scope, 166 Expression* Parser::CallClassFieldInitializer(Scope* scope,
157 Expression* this_expr) { 167 Expression* this_expr) {
158 // This produces the expression 168 // This produces the expression
159 // `.class_field_intializer(this_expr)`, where '.class_field_intializer' is 169 // `.class_field_intializer(this_expr)`, where '.class_field_intializer' is
160 // the name 170 // the name
161 // of a synthetic variable. 171 // of a synthetic variable.
162 // 'this_expr' will be 'this' in a base constructor and the result of calling 172 // 'this_expr' will be 'this' in a base constructor and the result of calling
(...skipping 422 matching lines...)
585 info->isolate()->counters()->runtime_call_stats(), 595 info->isolate()->counters()->runtime_call_stats(),
586 true), 596 true),
587 scanner_(info->unicode_cache()), 597 scanner_(info->unicode_cache()),
588 reusable_preparser_(nullptr), 598 reusable_preparser_(nullptr),
589 original_scope_(nullptr), 599 original_scope_(nullptr),
590 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 600 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
591 target_stack_(nullptr), 601 target_stack_(nullptr),
592 compile_options_(info->compile_options()), 602 compile_options_(info->compile_options()),
593 cached_parse_data_(nullptr), 603 cached_parse_data_(nullptr),
594 total_preparse_skipped_(0), 604 total_preparse_skipped_(0),
605 temp_zoned_(false),
595 log_(nullptr) { 606 log_(nullptr) {
596 // Even though we were passed ParseInfo, we should not store it in 607 // Even though we were passed ParseInfo, we should not store it in
597 // Parser - this makes sure that Isolate is not accidentally accessed via 608 // Parser - this makes sure that Isolate is not accidentally accessed via
598 // ParseInfo during background parsing. 609 // ParseInfo during background parsing.
599 DCHECK(!info->script().is_null() || info->source_stream() != nullptr || 610 DCHECK(!info->script().is_null() || info->source_stream() != nullptr ||
600 info->character_stream() != nullptr); 611 info->character_stream() != nullptr);
601 // Determine if functions can be lazily compiled. This is necessary to 612 // Determine if functions can be lazily compiled. This is necessary to
602 // allow some of our builtin JS files to be lazily compiled. These 613 // allow some of our builtin JS files to be lazily compiled. These
603 // builtins cannot be handled lazily by the parser, since we have to know 614 // builtins cannot be handled lazily by the parser, since we have to know
604 // if a function uses the special natives syntax, which is something the 615 // if a function uses the special natives syntax, which is something the
(...skipping 68 matching lines...)
673 base::ElapsedTimer timer; 684 base::ElapsedTimer timer;
674 if (FLAG_trace_parse) { 685 if (FLAG_trace_parse) {
675 timer.Start(); 686 timer.Start();
676 } 687 }
677 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 688 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
678 689
679 // Initialize parser state. 690 // Initialize parser state.
680 ParserLogger logger; 691 ParserLogger logger;
681 692
682 if (produce_cached_parse_data()) { 693 if (produce_cached_parse_data()) {
683 log_ = &logger; 694 if (allow_lazy_) {
695 log_ = &logger;
696 } else {
697 compile_options_ = ScriptCompiler::kNoCompileOptions;
698 }
684 } else if (consume_cached_parse_data()) { 699 } else if (consume_cached_parse_data()) {
685 cached_parse_data_->Initialize(); 700 cached_parse_data_->Initialize();
686 } 701 }
687 702
688 DeserializeScopeChain(info, info->maybe_outer_scope_info()); 703 DeserializeScopeChain(info, info->maybe_outer_scope_info());
689 704
690 source = String::Flatten(source); 705 source = String::Flatten(source);
691 FunctionLiteral* result; 706 FunctionLiteral* result;
692 707
693 { 708 {
(...skipping 1991 matching lines...)
2685 } 2700 }
2686 2701
2687 DCHECK(use_temp_zone || !is_lazy_top_level_function); 2702 DCHECK(use_temp_zone || !is_lazy_top_level_function);
2688 if (use_temp_zone) { 2703 if (use_temp_zone) {
2689 // If the preconditions are correct the function body should never be 2704 // If the preconditions are correct the function body should never be
2690 // accessed, but do this anyway for better behaviour if they're wrong. 2705 // accessed, but do this anyway for better behaviour if they're wrong.
2691 body = nullptr; 2706 body = nullptr;
2692 scope->AnalyzePartially(&previous_zone_ast_node_factory); 2707 scope->AnalyzePartially(&previous_zone_ast_node_factory);
2693 } 2708 }
2694 2709
2710 DCHECK_IMPLIES(use_temp_zone, temp_zoned_);
2695 if (FLAG_trace_preparse) { 2711 if (FLAG_trace_preparse) {
2696 PrintF(" [%s]: %i-%i %.*s\n", 2712 PrintF(" [%s]: %i-%i %.*s\n",
2697 is_lazy_top_level_function 2713 is_lazy_top_level_function
2698 ? "Preparse no-resolution" 2714 ? "Preparse no-resolution"
2699 : (use_temp_zone ? "Preparse resolution" : "Full parse"), 2715 : (temp_zoned_ ? "Preparse resolution" : "Full parse"),
2700 scope->start_position(), scope->end_position(), 2716 scope->start_position(), scope->end_position(),
2701 function_name->byte_length(), function_name->raw_data()); 2717 function_name->byte_length(), function_name->raw_data());
2702 } 2718 }
2703 if (is_lazy_top_level_function) { 2719 if (is_lazy_top_level_function) {
2704 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_, 2720 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_,
2705 PreParseNoVariableResolution); 2721 PreParseNoVariableResolution);
2706 } else if (use_temp_zone) { 2722 } else if (temp_zoned_) {
2707 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_, 2723 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_,
2708 PreParseWithVariableResolution); 2724 PreParseWithVariableResolution);
2709 } 2725 }
2710 2726
2711 // Validate function name. We can do this only after parsing the function, 2727 // Validate function name. We can do this only after parsing the function,
2712 // since the function can declare itself strict. 2728 // since the function can declare itself strict.
2713 language_mode = scope->language_mode(); 2729 language_mode = scope->language_mode();
2714 CheckFunctionName(language_mode, function_name, function_name_validity, 2730 CheckFunctionName(language_mode, function_name, function_name_validity,
2715 function_name_location, CHECK_OK); 2731 function_name_location, CHECK_OK);
2716 2732
(...skipping 392 matching lines...)
3109 return factory()->NewYield(get_proxy, assignment, scope()->start_position(), 3125 return factory()->NewYield(get_proxy, assignment, scope()->start_position(),
3110 Yield::kOnExceptionThrow); 3126 Yield::kOnExceptionThrow);
3111 } 3127 }
3112 3128
3113 ZoneList<Statement*>* Parser::ParseFunction( 3129 ZoneList<Statement*>* Parser::ParseFunction(
3114 const AstRawString* function_name, int pos, FunctionKind kind, 3130 const AstRawString* function_name, int pos, FunctionKind kind,
3115 FunctionLiteral::FunctionType function_type, 3131 FunctionLiteral::FunctionType function_type,
3116 DeclarationScope* function_scope, int* num_parameters, int* function_length, 3132 DeclarationScope* function_scope, int* num_parameters, int* function_length,
3117 bool* has_duplicate_parameters, int* materialized_literal_count, 3133 bool* has_duplicate_parameters, int* materialized_literal_count,
3118 int* expected_property_count, bool* ok) { 3134 int* expected_property_count, bool* ok) {
3135 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
3136
3119 FunctionState function_state(&function_state_, &scope_state_, function_scope); 3137 FunctionState function_state(&function_state_, &scope_state_, function_scope);
3120 3138
3121 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 3139 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
3122 ExpressionClassifier formals_classifier(this, &duplicate_finder); 3140 ExpressionClassifier formals_classifier(this, &duplicate_finder);
3123 3141
3124 if (IsGeneratorFunction(kind)) PrepareGeneratorVariables(&function_state); 3142 if (IsGeneratorFunction(kind)) PrepareGeneratorVariables(&function_state);
3125 3143
3126 ParserFormalParameters formals(function_scope); 3144 ParserFormalParameters formals(function_scope);
3127 ParseFormalParameterList(&formals, CHECK_OK); 3145 ParseFormalParameterList(&formals, CHECK_OK);
3128 Expect(Token::RPAREN, CHECK_OK); 3146 Expect(Token::RPAREN, CHECK_OK);
(...skipping 24 matching lines...)
3153 3171
3154 *materialized_literal_count = function_state.materialized_literal_count(); 3172 *materialized_literal_count = function_state.materialized_literal_count();
3155 *expected_property_count = function_state.expected_property_count(); 3173 *expected_property_count = function_state.expected_property_count();
3156 return body; 3174 return body;
3157 } 3175 }
3158 3176
3159 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 3177 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3160 const AstRawString* function_name, int pos, 3178 const AstRawString* function_name, int pos,
3161 const ParserFormalParameters& parameters, FunctionKind kind, 3179 const ParserFormalParameters& parameters, FunctionKind kind,
3162 FunctionLiteral::FunctionType function_type, bool* ok) { 3180 FunctionLiteral::FunctionType function_type, bool* ok) {
3163 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
3164 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 3181 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
3165 3182
3166 static const int kFunctionNameAssignmentIndex = 0; 3183 static const int kFunctionNameAssignmentIndex = 0;
3167 if (function_type == FunctionLiteral::kNamedExpression) { 3184 if (function_type == FunctionLiteral::kNamedExpression) {
3168 DCHECK(function_name != NULL); 3185 DCHECK(function_name != NULL);
3169 // If we have a named function expression, we add a local variable 3186 // If we have a named function expression, we add a local variable
3170 // declaration to the body of the function with the name of the 3187 // declaration to the body of the function with the name of the
3171 // function and let it refer to the function itself (closure). 3188 // function and let it refer to the function itself (closure).
3172 // Not having parsed the function body, the language mode may still change, 3189 // Not having parsed the function body, the language mode may still change,
3173 // so we reserve a spot and create the actual const assignment later. 3190 // so we reserve a spot and create the actual const assignment later.
(...skipping 638 matching lines...)
3812 } 3829 }
3813 3830
3814 3831
3815 void Parser::ParseOnBackground(ParseInfo* info) { 3832 void Parser::ParseOnBackground(ParseInfo* info) {
3816 parsing_on_main_thread_ = false; 3833 parsing_on_main_thread_ = false;
3817 3834
3818 DCHECK(info->literal() == NULL); 3835 DCHECK(info->literal() == NULL);
3819 FunctionLiteral* result = NULL; 3836 FunctionLiteral* result = NULL;
3820 3837
3821 ParserLogger logger; 3838 ParserLogger logger;
3822 if (produce_cached_parse_data()) log_ = &logger; 3839 if (produce_cached_parse_data()) {
3840 if (allow_lazy_) {
3841 log_ = &logger;
3842 } else {
3843 compile_options_ = ScriptCompiler::kNoCompileOptions;
3844 }
3845 }
3823 if (FLAG_runtime_stats) { 3846 if (FLAG_runtime_stats) {
3824 // Create separate runtime stats for background parsing. 3847 // Create separate runtime stats for background parsing.
3825 runtime_call_stats_ = new (zone()) RuntimeCallStats(); 3848 runtime_call_stats_ = new (zone()) RuntimeCallStats();
3826 } 3849 }
3827 3850
3828 std::unique_ptr<Utf16CharacterStream> stream; 3851 std::unique_ptr<Utf16CharacterStream> stream;
3829 Utf16CharacterStream* stream_ptr; 3852 Utf16CharacterStream* stream_ptr;
3830 if (info->character_stream()) { 3853 if (info->character_stream()) {
3831 DCHECK(info->source_stream() == nullptr); 3854 DCHECK(info->source_stream() == nullptr);
3832 stream_ptr = info->character_stream(); 3855 stream_ptr = info->character_stream();
(...skipping 1604 matching lines...)
5437 5460
5438 return final_loop; 5461 return final_loop;
5439 } 5462 }
5440 5463
5441 #undef CHECK_OK 5464 #undef CHECK_OK
5442 #undef CHECK_OK_VOID 5465 #undef CHECK_OK_VOID
5443 #undef CHECK_FAILED 5466 #undef CHECK_FAILED
5444 5467
5445 } // namespace internal 5468 } // namespace internal
5446 } // namespace v8 5469 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine