Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(382)

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

Issue 2375013002: Revert of Preparse top-level functions in discardable zones (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ast/scopes.cc ('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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 prev_fni_(parser->fni_), 120 prev_fni_(parser->fni_),
121 prev_zone_(parser->zone_) { 121 prev_zone_(parser->zone_) {
122 if (use_temp_zone) { 122 if (use_temp_zone) {
123 parser_->fni_ = &fni_; 123 parser_->fni_ = &fni_;
124 parser_->zone_ = temp_zone; 124 parser_->zone_ = temp_zone;
125 if (parser_->reusable_preparser_ != nullptr) { 125 if (parser_->reusable_preparser_ != nullptr) {
126 parser_->reusable_preparser_->zone_ = temp_zone; 126 parser_->reusable_preparser_->zone_ = temp_zone;
127 } 127 }
128 } 128 }
129 } 129 }
130 void Reset() { 130 ~DiscardableZoneScope() {
131 parser_->fni_ = prev_fni_; 131 parser_->fni_ = prev_fni_;
132 parser_->zone_ = prev_zone_; 132 parser_->zone_ = prev_zone_;
133 if (parser_->reusable_preparser_ != nullptr) { 133 if (parser_->reusable_preparser_ != nullptr) {
134 parser_->reusable_preparser_->zone_ = prev_zone_; 134 parser_->reusable_preparser_->zone_ = prev_zone_;
135 } 135 }
136 ast_node_factory_scope_.Reset();
137 } 136 }
138 ~DiscardableZoneScope() { Reset(); }
139 137
140 private: 138 private:
141 AstNodeFactory::BodyScope ast_node_factory_scope_; 139 AstNodeFactory::BodyScope ast_node_factory_scope_;
142 FuncNameInferrer fni_; 140 FuncNameInferrer fni_;
143 Parser* parser_; 141 Parser* parser_;
144 FuncNameInferrer* prev_fni_; 142 FuncNameInferrer* prev_fni_;
145 Zone* prev_zone_; 143 Zone* prev_zone_;
146 144
147 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope); 145 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope);
148 }; 146 };
(...skipping 2526 matching lines...) Expand 10 before | Expand all | Expand 10 after
2675 // FunctionExpression; even without enclosing parentheses it might be 2673 // FunctionExpression; even without enclosing parentheses it might be
2676 // immediately invoked. 2674 // immediately invoked.
2677 // - The function literal shouldn't be hinted to eagerly compile. 2675 // - The function literal shouldn't be hinted to eagerly compile.
2678 // - For asm.js functions the body needs to be available when module 2676 // - For asm.js functions the body needs to be available when module
2679 // validation is active, because we examine the entire module at once. 2677 // validation is active, because we examine the entire module at once.
2680 2678
2681 // Inner functions will be parsed using a temporary Zone. After parsing, we 2679 // Inner functions will be parsed using a temporary Zone. After parsing, we
2682 // will migrate unresolved variable into a Scope in the main Zone. 2680 // will migrate unresolved variable into a Scope in the main Zone.
2683 // TODO(marja): Refactor parsing modes: simplify this. 2681 // TODO(marja): Refactor parsing modes: simplify this.
2684 bool use_temp_zone = 2682 bool use_temp_zone =
2685 allow_lazy() && function_type == FunctionLiteral::kDeclaration && 2683 !is_lazy_top_level_function && allow_lazy() &&
2684 function_type == FunctionLiteral::kDeclaration &&
2686 eager_compile_hint != FunctionLiteral::kShouldEagerCompile && 2685 eager_compile_hint != FunctionLiteral::kShouldEagerCompile &&
2687 !(FLAG_validate_asm && scope()->IsAsmModule()); 2686 !(FLAG_validate_asm && scope()->IsAsmModule());
2688 bool is_lazy_inner_function = 2687 bool is_lazy_inner_function = use_temp_zone && FLAG_lazy_inner_functions;
2689 use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function;
2690 2688
2691 // This Scope lives in the main zone. We'll migrate data into that zone later. 2689 // This Scope lives in the main zone. We'll migrate data into that zone later.
2692 DeclarationScope* scope = NewFunctionScope(kind); 2690 DeclarationScope* scope = NewFunctionScope(kind);
2693 SetLanguageMode(scope, language_mode); 2691 SetLanguageMode(scope, language_mode);
2694 2692
2695 ZoneList<Statement*>* body = nullptr; 2693 ZoneList<Statement*>* body = nullptr;
2696 int arity = -1; 2694 int arity = -1;
2697 int materialized_literal_count = -1; 2695 int materialized_literal_count = -1;
2698 int expected_property_count = -1; 2696 int expected_property_count = -1;
2699 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 2697 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
2700 bool should_be_used_once_hint = false; 2698 bool should_be_used_once_hint = false;
2701 bool has_duplicate_parameters; 2699 bool has_duplicate_parameters;
2702 2700
2703 FunctionState function_state(&function_state_, &scope_state_, scope);
2704 #ifdef DEBUG
2705 scope->SetScopeName(function_name);
2706 #endif
2707
2708 ExpressionClassifier formals_classifier(this, &duplicate_finder);
2709
2710 if (is_generator) {
2711 // For generators, allocating variables in contexts is currently a win
2712 // because it minimizes the work needed to suspend and resume an
2713 // activation. The machine code produced for generators (by full-codegen)
2714 // relies on this forced context allocation, but not in an essential way.
2715 this->scope()->ForceContextAllocation();
2716
2717 // Calling a generator returns a generator object. That object is stored
2718 // in a temporary variable, a definition that is used by "yield"
2719 // expressions. This also marks the FunctionState as a generator.
2720 Variable* temp =
2721 NewTemporary(ast_value_factory()->dot_generator_object_string());
2722 function_state.set_generator_object_variable(temp);
2723 }
2724
2725 Expect(Token::LPAREN, CHECK_OK);
2726 int start_position = scanner()->location().beg_pos;
2727 this->scope()->set_start_position(start_position);
2728 ParserFormalParameters formals(scope);
2729 ParseFormalParameterList(&formals, CHECK_OK);
2730 arity = formals.Arity();
2731 Expect(Token::RPAREN, CHECK_OK);
2732 int formals_end_position = scanner()->location().end_pos;
2733
2734 CheckArityRestrictions(arity, kind, formals.has_rest, start_position,
2735 formals_end_position, CHECK_OK);
2736 Expect(Token::LBRACE, CHECK_OK);
2737 // Don't include the rest parameter into the function's formal parameter
2738 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
2739 // which says whether we need to create an arguments adaptor frame).
2740 if (formals.has_rest) arity--;
2741
2742 { 2701 {
2743 // Temporary zones can nest. When we migrate free variables (see below), we 2702 // Temporary zones can nest. When we migrate free variables (see below), we
2744 // need to recreate them in the previous Zone. 2703 // need to recreate them in the previous Zone.
2745 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); 2704 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
2746 previous_zone_ast_node_factory.set_zone(zone()); 2705 previous_zone_ast_node_factory.set_zone(zone());
2747 2706
2748 // Open a new zone scope, which sets our AstNodeFactory to allocate in the 2707 // Open a new zone scope, which sets our AstNodeFactory to allocate in the
2749 // new temporary zone if the preconditions are satisfied, and ensures that 2708 // new temporary zone if the preconditions are satisfied, and ensures that
2750 // the previous zone is always restored after parsing the body. To be able 2709 // the previous zone is always restored after parsing the body. To be able
2751 // to do scope analysis correctly after full parsing, we migrate needed 2710 // to do scope analysis correctly after full parsing, we migrate needed
2752 // information when the function is parsed. 2711 // information when the function is parsed.
2753 Zone temp_zone(zone()->allocator()); 2712 Zone temp_zone(zone()->allocator());
2754 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); 2713 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone);
2714
2715 FunctionState function_state(&function_state_, &scope_state_, scope);
2755 #ifdef DEBUG 2716 #ifdef DEBUG
2717 scope->SetScopeName(function_name);
2756 if (use_temp_zone) scope->set_needs_migration(); 2718 if (use_temp_zone) scope->set_needs_migration();
2757 #endif 2719 #endif
2720 ExpressionClassifier formals_classifier(this, &duplicate_finder);
2721
2722 if (is_generator) {
2723 // For generators, allocating variables in contexts is currently a win
2724 // because it minimizes the work needed to suspend and resume an
2725 // activation. The machine code produced for generators (by full-codegen)
2726 // relies on this forced context allocation, but not in an essential way.
2727 this->scope()->ForceContextAllocation();
2728
2729 // Calling a generator returns a generator object. That object is stored
2730 // in a temporary variable, a definition that is used by "yield"
2731 // expressions. This also marks the FunctionState as a generator.
2732 Variable* temp =
2733 NewTemporary(ast_value_factory()->dot_generator_object_string());
2734 function_state.set_generator_object_variable(temp);
2735 }
2736
2737 Expect(Token::LPAREN, CHECK_OK);
2738 int start_position = scanner()->location().beg_pos;
2739 this->scope()->set_start_position(start_position);
2740 ParserFormalParameters formals(scope);
2741 ParseFormalParameterList(&formals, CHECK_OK);
2742 arity = formals.Arity();
2743 Expect(Token::RPAREN, CHECK_OK);
2744 int formals_end_position = scanner()->location().end_pos;
2745
2746 CheckArityRestrictions(arity, kind, formals.has_rest, start_position,
2747 formals_end_position, CHECK_OK);
2748 Expect(Token::LBRACE, CHECK_OK);
2749 // Don't include the rest parameter into the function's formal parameter
2750 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
2751 // which says whether we need to create an arguments adaptor frame).
2752 if (formals.has_rest) arity--;
2758 2753
2759 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse 2754 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2760 // lazily. We'll call SkipLazyFunctionBody, which may decide to abort lazy 2755 // lazily. We'll call SkipLazyFunctionBody, which may decide to abort lazy
2761 // parsing if it suspects that wasn't a good idea. If so (in which case the 2756 // parsing if it suspects that wasn't a good idea. If so (in which case the
2762 // parser is expected to have backtracked), or if we didn't try to lazy 2757 // parser is expected to have backtracked), or if we didn't try to lazy
2763 // parse in the first place, we'll have to parse eagerly. 2758 // parse in the first place, we'll have to parse eagerly.
2764 if (is_lazy_top_level_function || is_lazy_inner_function) { 2759 if (is_lazy_top_level_function || is_lazy_inner_function) {
2765 Scanner::BookmarkScope bookmark(scanner()); 2760 Scanner::BookmarkScope bookmark(scanner());
2766 bookmark.Set(); 2761 bookmark.Set();
2767 LazyParsingResult result = SkipLazyFunctionBody( 2762 LazyParsingResult result = SkipLazyFunctionBody(
2768 &materialized_literal_count, &expected_property_count, 2763 &materialized_literal_count, &expected_property_count,
2769 is_lazy_inner_function, is_lazy_top_level_function, CHECK_OK); 2764 is_lazy_inner_function, is_lazy_top_level_function, CHECK_OK);
2770 2765
2771 materialized_literal_count += formals.materialized_literals_count + 2766 materialized_literal_count += formals.materialized_literals_count +
2772 function_state.materialized_literal_count(); 2767 function_state.materialized_literal_count();
2773 2768
2774 if (result == kLazyParsingAborted) { 2769 if (result == kLazyParsingAborted) {
2775 DCHECK(is_lazy_top_level_function); 2770 DCHECK(is_lazy_top_level_function);
2776 bookmark.Apply(); 2771 bookmark.Apply();
2777 // Trigger eager (re-)parsing, just below this block. 2772 // Trigger eager (re-)parsing, just below this block.
2778 is_lazy_top_level_function = false; 2773 is_lazy_top_level_function = false;
2779 2774
2780 // This is probably an initialization function. Inform the compiler it 2775 // This is probably an initialization function. Inform the compiler it
2781 // should also eager-compile this function, and that we expect it to be 2776 // should also eager-compile this function, and that we expect it to be
2782 // used once. 2777 // used once.
2783 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 2778 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2784 should_be_used_once_hint = true; 2779 should_be_used_once_hint = true;
2785 scope->ResetAfterPreparsing(true); 2780 scope->ResetAfterPreparsing(true);
2786 zone_scope.Reset();
2787 use_temp_zone = false;
2788 } 2781 }
2789 } 2782 }
2790 2783
2791 if (!is_lazy_top_level_function && !is_lazy_inner_function) { 2784 if (!is_lazy_top_level_function && !is_lazy_inner_function) {
2792 body = ParseEagerFunctionBody(function_name, pos, formals, kind, 2785 body = ParseEagerFunctionBody(function_name, pos, formals, kind,
2793 function_type, CHECK_OK); 2786 function_type, CHECK_OK);
2794 2787
2795 materialized_literal_count = function_state.materialized_literal_count(); 2788 materialized_literal_count = function_state.materialized_literal_count();
2796 expected_property_count = function_state.expected_property_count(); 2789 expected_property_count = function_state.expected_property_count();
2797 } 2790 }
(...skipping 2751 matching lines...) Expand 10 before | Expand all | Expand 10 after
5549 5542
5550 return final_loop; 5543 return final_loop;
5551 } 5544 }
5552 5545
5553 #undef CHECK_OK 5546 #undef CHECK_OK
5554 #undef CHECK_OK_VOID 5547 #undef CHECK_OK_VOID
5555 #undef CHECK_FAILED 5548 #undef CHECK_FAILED
5556 5549
5557 } // namespace internal 5550 } // namespace internal
5558 } // namespace v8 5551 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698