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

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

Issue 2368313002: Don't use different function scopes when parsing with temp 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
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 2723 matching lines...) Expand 10 before | Expand all | Expand 10 after
2734 // Inner functions will be parsed using a temporary Zone. After parsing, we 2734 // Inner functions will be parsed using a temporary Zone. After parsing, we
2735 // will migrate unresolved variable into a Scope in the main Zone. 2735 // will migrate unresolved variable into a Scope in the main Zone.
2736 // TODO(marja): Refactor parsing modes: simplify this. 2736 // TODO(marja): Refactor parsing modes: simplify this.
2737 bool use_temp_zone = 2737 bool use_temp_zone =
2738 !is_lazy_top_level_function && allow_lazy() && 2738 !is_lazy_top_level_function && allow_lazy() &&
2739 function_type == FunctionLiteral::kDeclaration && 2739 function_type == FunctionLiteral::kDeclaration &&
2740 eager_compile_hint != FunctionLiteral::kShouldEagerCompile && 2740 eager_compile_hint != FunctionLiteral::kShouldEagerCompile &&
2741 !(FLAG_validate_asm && scope()->IsAsmModule()); 2741 !(FLAG_validate_asm && scope()->IsAsmModule());
2742 bool is_lazy_inner_function = use_temp_zone && FLAG_lazy_inner_functions; 2742 bool is_lazy_inner_function = use_temp_zone && FLAG_lazy_inner_functions;
2743 2743
2744 DeclarationScope* main_scope = nullptr; 2744 // This Scope lives in the main zone. We'll migrate data into that zone later.
2745 if (use_temp_zone) { 2745 DeclarationScope* scope = NewFunctionScope(kind);
2746 // This Scope lives in the main Zone; we'll migrate data into it later. 2746 SetLanguageMode(scope, language_mode);
2747 main_scope = NewFunctionScope(kind);
2748 }
2749 2747
2750 ZoneList<Statement*>* body = nullptr; 2748 ZoneList<Statement*>* body = nullptr;
2751 int arity = -1; 2749 int arity = -1;
2752 int materialized_literal_count = -1; 2750 int materialized_literal_count = -1;
2753 int expected_property_count = -1; 2751 int expected_property_count = -1;
2754 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 2752 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
2755 bool should_be_used_once_hint = false; 2753 bool should_be_used_once_hint = false;
2756 bool has_duplicate_parameters; 2754 bool has_duplicate_parameters;
2757 2755
2758 { 2756 {
2759 // Temporary zones can nest. When we migrate free variables (see below), we 2757 // Temporary zones can nest. When we migrate free variables (see below), we
2760 // need to recreate them in the previous Zone. 2758 // need to recreate them in the previous Zone.
2761 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); 2759 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
2762 previous_zone_ast_node_factory.set_zone(zone()); 2760 previous_zone_ast_node_factory.set_zone(zone());
2763 2761
2764 // Open a new zone scope, which sets our AstNodeFactory to allocate in the 2762 // Open a new zone scope, which sets our AstNodeFactory to allocate in the
2765 // new temporary zone if the preconditions are satisfied, and ensures that 2763 // new temporary zone if the preconditions are satisfied, and ensures that
2766 // the previous zone is always restored after parsing the body. To be able 2764 // the previous zone is always restored after parsing the body. To be able
2767 // to do scope analysis correctly after full parsing, we migrate needed 2765 // to do scope analysis correctly after full parsing, we migrate needed
2768 // information from scope into main_scope when the function has been parsed. 2766 // information when the function is parsed.
2769 Zone temp_zone(zone()->allocator()); 2767 Zone temp_zone(zone()->allocator());
2770 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); 2768 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone);
2771 2769
2772 DeclarationScope* scope = NewFunctionScope(kind);
2773 SetLanguageMode(scope, language_mode);
2774 if (!use_temp_zone) {
2775 main_scope = scope;
2776 } else {
2777 DCHECK(main_scope->zone() != scope->zone());
2778 }
2779
2780 FunctionState function_state(&function_state_, &scope_state_, scope); 2770 FunctionState function_state(&function_state_, &scope_state_, scope);
2781 #ifdef DEBUG 2771 #ifdef DEBUG
2782 scope->SetScopeName(function_name); 2772 scope->SetScopeName(function_name);
2783 #endif 2773 #endif
2784 ExpressionClassifier formals_classifier(this, &duplicate_finder); 2774 ExpressionClassifier formals_classifier(this, &duplicate_finder);
2785 2775
2786 if (is_generator) { 2776 if (is_generator) {
2787 // For generators, allocating variables in contexts is currently a win 2777 // For generators, allocating variables in contexts is currently a win
2788 // because it minimizes the work needed to suspend and resume an 2778 // because it minimizes the work needed to suspend and resume an
2789 // activation. The machine code produced for generators (by full-codegen) 2779 // activation. The machine code produced for generators (by full-codegen)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2834 DCHECK(is_lazy_top_level_function); 2824 DCHECK(is_lazy_top_level_function);
2835 bookmark.Apply(); 2825 bookmark.Apply();
2836 // Trigger eager (re-)parsing, just below this block. 2826 // Trigger eager (re-)parsing, just below this block.
2837 is_lazy_top_level_function = false; 2827 is_lazy_top_level_function = false;
2838 2828
2839 // This is probably an initialization function. Inform the compiler it 2829 // This is probably an initialization function. Inform the compiler it
2840 // should also eager-compile this function, and that we expect it to be 2830 // should also eager-compile this function, and that we expect it to be
2841 // used once. 2831 // used once.
2842 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 2832 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2843 should_be_used_once_hint = true; 2833 should_be_used_once_hint = true;
2844 } else if (is_lazy_inner_function) { 2834 scope->ResetAfterPreparsing();
2845 DCHECK(main_scope != scope);
2846 scope->AnalyzePartially(main_scope, &previous_zone_ast_node_factory);
2847 } 2835 }
2848 } 2836 }
2837
2849 if (!is_lazy_top_level_function && !is_lazy_inner_function) { 2838 if (!is_lazy_top_level_function && !is_lazy_inner_function) {
2850 body = ParseEagerFunctionBody(function_name, pos, formals, kind, 2839 body = ParseEagerFunctionBody(function_name, pos, formals, kind,
2851 function_type, CHECK_OK); 2840 function_type, CHECK_OK);
2852 2841
2853 materialized_literal_count = function_state.materialized_literal_count(); 2842 materialized_literal_count = function_state.materialized_literal_count();
2854 expected_property_count = function_state.expected_property_count(); 2843 expected_property_count = function_state.expected_property_count();
2855 if (use_temp_zone) { 2844 }
2856 // If the preconditions are correct the function body should never be 2845
2857 // accessed, but do this anyway for better behaviour if they're wrong. 2846 if (use_temp_zone || is_lazy_top_level_function) {
marja 2016/09/27 07:14:03 This sounds wrong... is_lazy_inner_function maybe?
marja 2016/09/27 11:17:34 .... and I was confused; use_temp_zone contains th
2858 body = nullptr; 2847 // If the preconditions are correct the function body should never be
2859 DCHECK(main_scope != scope); 2848 // accessed, but do this anyway for better behaviour if they're wrong.
2860 scope->AnalyzePartially(main_scope, &previous_zone_ast_node_factory); 2849 body = nullptr;
2861 } 2850 scope->AnalyzePartially(&previous_zone_ast_node_factory);
2862 } 2851 }
2863 2852
2864 // Parsing the body may change the language mode in our scope. 2853 // Parsing the body may change the language mode in our scope.
2865 language_mode = scope->language_mode(); 2854 language_mode = scope->language_mode();
2866 2855
2867 // Validate name and parameter names. We can do this only after parsing the 2856 // Validate name and parameter names. We can do this only after parsing the
2868 // function, since the function can declare itself strict. 2857 // function, since the function can declare itself strict.
2869 CheckFunctionName(language_mode, function_name, function_name_validity, 2858 CheckFunctionName(language_mode, function_name, function_name_validity,
2870 function_name_location, CHECK_OK); 2859 function_name_location, CHECK_OK);
2871 const bool allow_duplicate_parameters = 2860 const bool allow_duplicate_parameters =
(...skipping 16 matching lines...) Expand all
2888 has_duplicate_parameters = 2877 has_duplicate_parameters =
2889 !classifier()->is_valid_formal_parameter_list_without_duplicates(); 2878 !classifier()->is_valid_formal_parameter_list_without_duplicates();
2890 } // DiscardableZoneScope goes out of scope. 2879 } // DiscardableZoneScope goes out of scope.
2891 2880
2892 FunctionLiteral::ParameterFlag duplicate_parameters = 2881 FunctionLiteral::ParameterFlag duplicate_parameters =
2893 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 2882 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2894 : FunctionLiteral::kNoDuplicateParameters; 2883 : FunctionLiteral::kNoDuplicateParameters;
2895 2884
2896 // Note that the FunctionLiteral needs to be created in the main Zone again. 2885 // Note that the FunctionLiteral needs to be created in the main Zone again.
2897 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 2886 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2898 function_name, main_scope, body, materialized_literal_count, 2887 function_name, scope, body, materialized_literal_count,
2899 expected_property_count, arity, duplicate_parameters, function_type, 2888 expected_property_count, arity, duplicate_parameters, function_type,
2900 eager_compile_hint, kind, pos); 2889 eager_compile_hint, kind, pos);
2901 function_literal->set_function_token_position(function_token_pos); 2890 function_literal->set_function_token_position(function_token_pos);
2902 if (should_be_used_once_hint) 2891 if (should_be_used_once_hint)
2903 function_literal->set_should_be_used_once_hint(); 2892 function_literal->set_should_be_used_once_hint();
2904 2893
2905 if (should_infer_name) { 2894 if (should_infer_name) {
2906 DCHECK_NOT_NULL(fni_); 2895 DCHECK_NOT_NULL(fni_);
2907 fni_->AddFunction(function_literal); 2896 fni_->AddFunction(function_literal);
2908 } 2897 }
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
3473 #undef SET_ALLOW 3462 #undef SET_ALLOW
3474 } 3463 }
3475 // Aborting inner function preparsing would leave scopes in an inconsistent 3464 // Aborting inner function preparsing would leave scopes in an inconsistent
3476 // state; we don't parse inner functions in the abortable mode anyway. 3465 // state; we don't parse inner functions in the abortable mode anyway.
3477 DCHECK(!is_inner_function || !may_abort); 3466 DCHECK(!is_inner_function || !may_abort);
3478 3467
3479 DeclarationScope* function_scope = function_state_->scope(); 3468 DeclarationScope* function_scope = function_state_->scope();
3480 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( 3469 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
3481 function_scope, parsing_module_, logger, is_inner_function, may_abort, 3470 function_scope, parsing_module_, logger, is_inner_function, may_abort,
3482 use_counts_); 3471 use_counts_);
3483 // Detaching the scopes created by PreParser from the Scope chain must be done
3484 // above (see ParseFunctionLiteral & AnalyzePartially).
3485 if (!is_inner_function) function_scope->ResetAfterPreparsing();
3486 if (pre_parse_timer_ != NULL) { 3472 if (pre_parse_timer_ != NULL) {
3487 pre_parse_timer_->Stop(); 3473 pre_parse_timer_->Stop();
3488 } 3474 }
3489 return result; 3475 return result;
3490 } 3476 }
3491 3477
3492 Expression* Parser::InstallHomeObject(Expression* function_literal, 3478 Expression* Parser::InstallHomeObject(Expression* function_literal,
3493 Expression* home_object) { 3479 Expression* home_object) {
3494 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 3480 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
3495 Variable* result_var = 3481 Variable* result_var =
(...skipping 2103 matching lines...) Expand 10 before | Expand all | Expand 10 after
5599 5585
5600 return final_loop; 5586 return final_loop;
5601 } 5587 }
5602 5588
5603 #undef CHECK_OK 5589 #undef CHECK_OK
5604 #undef CHECK_OK_VOID 5590 #undef CHECK_OK_VOID
5605 #undef CHECK_FAILED 5591 #undef CHECK_FAILED
5606 5592
5607 } // namespace internal 5593 } // namespace internal
5608 } // namespace v8 5594 } // namespace v8
OLDNEW
« src/ast/scopes.cc ('K') | « src/ast/scopes.cc ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698