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

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

Issue 2379533003: Revert of 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
« no previous file with comments | « src/ast/scopes.cc ('k') | src/parsing/parser-base.h » ('j') | 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 2727 matching lines...) Expand 10 before | Expand all | Expand 10 after
2738 // Inner functions will be parsed using a temporary Zone. After parsing, we 2738 // Inner functions will be parsed using a temporary Zone. After parsing, we
2739 // will migrate unresolved variable into a Scope in the main Zone. 2739 // will migrate unresolved variable into a Scope in the main Zone.
2740 // TODO(marja): Refactor parsing modes: simplify this. 2740 // TODO(marja): Refactor parsing modes: simplify this.
2741 bool use_temp_zone = 2741 bool use_temp_zone =
2742 !is_lazy_top_level_function && allow_lazy() && 2742 !is_lazy_top_level_function && allow_lazy() &&
2743 function_type == FunctionLiteral::kDeclaration && 2743 function_type == FunctionLiteral::kDeclaration &&
2744 eager_compile_hint != FunctionLiteral::kShouldEagerCompile && 2744 eager_compile_hint != FunctionLiteral::kShouldEagerCompile &&
2745 !(FLAG_validate_asm && scope()->IsAsmModule()); 2745 !(FLAG_validate_asm && scope()->IsAsmModule());
2746 bool is_lazy_inner_function = use_temp_zone && FLAG_lazy_inner_functions; 2746 bool is_lazy_inner_function = use_temp_zone && FLAG_lazy_inner_functions;
2747 2747
2748 // This Scope lives in the main zone. We'll migrate data into that zone later. 2748 DeclarationScope* main_scope = nullptr;
2749 DeclarationScope* scope = NewFunctionScope(kind); 2749 if (use_temp_zone) {
2750 SetLanguageMode(scope, language_mode); 2750 // This Scope lives in the main Zone; we'll migrate data into it later.
2751 main_scope = NewFunctionScope(kind);
2752 }
2751 2753
2752 ZoneList<Statement*>* body = nullptr; 2754 ZoneList<Statement*>* body = nullptr;
2753 int arity = -1; 2755 int arity = -1;
2754 int materialized_literal_count = -1; 2756 int materialized_literal_count = -1;
2755 int expected_property_count = -1; 2757 int expected_property_count = -1;
2756 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 2758 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
2757 bool should_be_used_once_hint = false; 2759 bool should_be_used_once_hint = false;
2758 bool has_duplicate_parameters; 2760 bool has_duplicate_parameters;
2759 2761
2760 { 2762 {
2761 // Temporary zones can nest. When we migrate free variables (see below), we 2763 // Temporary zones can nest. When we migrate free variables (see below), we
2762 // need to recreate them in the previous Zone. 2764 // need to recreate them in the previous Zone.
2763 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); 2765 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
2764 previous_zone_ast_node_factory.set_zone(zone()); 2766 previous_zone_ast_node_factory.set_zone(zone());
2765 2767
2766 // Open a new zone scope, which sets our AstNodeFactory to allocate in the 2768 // Open a new zone scope, which sets our AstNodeFactory to allocate in the
2767 // new temporary zone if the preconditions are satisfied, and ensures that 2769 // new temporary zone if the preconditions are satisfied, and ensures that
2768 // the previous zone is always restored after parsing the body. To be able 2770 // the previous zone is always restored after parsing the body. To be able
2769 // to do scope analysis correctly after full parsing, we migrate needed 2771 // to do scope analysis correctly after full parsing, we migrate needed
2770 // information when the function is parsed. 2772 // information from scope into main_scope when the function has been parsed.
2771 Zone temp_zone(zone()->allocator()); 2773 Zone temp_zone(zone()->allocator());
2772 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); 2774 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone);
2773 2775
2776 DeclarationScope* scope = NewFunctionScope(kind);
2777 SetLanguageMode(scope, language_mode);
2778 if (!use_temp_zone) {
2779 main_scope = scope;
2780 } else {
2781 DCHECK(main_scope->zone() != scope->zone());
2782 }
2783
2774 FunctionState function_state(&function_state_, &scope_state_, scope); 2784 FunctionState function_state(&function_state_, &scope_state_, scope);
2775 #ifdef DEBUG 2785 #ifdef DEBUG
2776 scope->SetScopeName(function_name); 2786 scope->SetScopeName(function_name);
2777 if (use_temp_zone) scope->set_needs_migration();
2778 #endif 2787 #endif
2779 ExpressionClassifier formals_classifier(this, &duplicate_finder); 2788 ExpressionClassifier formals_classifier(this, &duplicate_finder);
2780 2789
2781 if (is_generator) { 2790 if (is_generator) {
2782 // For generators, allocating variables in contexts is currently a win 2791 // For generators, allocating variables in contexts is currently a win
2783 // because it minimizes the work needed to suspend and resume an 2792 // because it minimizes the work needed to suspend and resume an
2784 // activation. The machine code produced for generators (by full-codegen) 2793 // activation. The machine code produced for generators (by full-codegen)
2785 // relies on this forced context allocation, but not in an essential way. 2794 // relies on this forced context allocation, but not in an essential way.
2786 this->scope()->ForceContextAllocation(); 2795 this->scope()->ForceContextAllocation();
2787 2796
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2829 DCHECK(is_lazy_top_level_function); 2838 DCHECK(is_lazy_top_level_function);
2830 bookmark.Apply(); 2839 bookmark.Apply();
2831 // Trigger eager (re-)parsing, just below this block. 2840 // Trigger eager (re-)parsing, just below this block.
2832 is_lazy_top_level_function = false; 2841 is_lazy_top_level_function = false;
2833 2842
2834 // This is probably an initialization function. Inform the compiler it 2843 // This is probably an initialization function. Inform the compiler it
2835 // should also eager-compile this function, and that we expect it to be 2844 // should also eager-compile this function, and that we expect it to be
2836 // used once. 2845 // used once.
2837 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 2846 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2838 should_be_used_once_hint = true; 2847 should_be_used_once_hint = true;
2839 scope->ResetAfterPreparsing(true); 2848 } else if (is_lazy_inner_function) {
2849 DCHECK(main_scope != scope);
2850 scope->AnalyzePartially(main_scope, &previous_zone_ast_node_factory);
2840 } 2851 }
2841 } 2852 }
2842
2843 if (!is_lazy_top_level_function && !is_lazy_inner_function) { 2853 if (!is_lazy_top_level_function && !is_lazy_inner_function) {
2844 body = ParseEagerFunctionBody(function_name, pos, formals, kind, 2854 body = ParseEagerFunctionBody(function_name, pos, formals, kind,
2845 function_type, CHECK_OK); 2855 function_type, CHECK_OK);
2846 2856
2847 materialized_literal_count = function_state.materialized_literal_count(); 2857 materialized_literal_count = function_state.materialized_literal_count();
2848 expected_property_count = function_state.expected_property_count(); 2858 expected_property_count = function_state.expected_property_count();
2849 } 2859 if (use_temp_zone) {
2850 2860 // If the preconditions are correct the function body should never be
2851 if (use_temp_zone || is_lazy_top_level_function) { 2861 // accessed, but do this anyway for better behaviour if they're wrong.
2852 // If the preconditions are correct the function body should never be 2862 body = nullptr;
2853 // accessed, but do this anyway for better behaviour if they're wrong. 2863 DCHECK(main_scope != scope);
2854 body = nullptr; 2864 scope->AnalyzePartially(main_scope, &previous_zone_ast_node_factory);
2855 scope->AnalyzePartially(&previous_zone_ast_node_factory); 2865 }
2856 } 2866 }
2857 2867
2858 // Parsing the body may change the language mode in our scope. 2868 // Parsing the body may change the language mode in our scope.
2859 language_mode = scope->language_mode(); 2869 language_mode = scope->language_mode();
2860 2870
2861 // Validate name and parameter names. We can do this only after parsing the 2871 // Validate name and parameter names. We can do this only after parsing the
2862 // function, since the function can declare itself strict. 2872 // function, since the function can declare itself strict.
2863 CheckFunctionName(language_mode, function_name, function_name_validity, 2873 CheckFunctionName(language_mode, function_name, function_name_validity,
2864 function_name_location, CHECK_OK); 2874 function_name_location, CHECK_OK);
2865 const bool allow_duplicate_parameters = 2875 const bool allow_duplicate_parameters =
(...skipping 16 matching lines...) Expand all
2882 has_duplicate_parameters = 2892 has_duplicate_parameters =
2883 !classifier()->is_valid_formal_parameter_list_without_duplicates(); 2893 !classifier()->is_valid_formal_parameter_list_without_duplicates();
2884 } // DiscardableZoneScope goes out of scope. 2894 } // DiscardableZoneScope goes out of scope.
2885 2895
2886 FunctionLiteral::ParameterFlag duplicate_parameters = 2896 FunctionLiteral::ParameterFlag duplicate_parameters =
2887 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 2897 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2888 : FunctionLiteral::kNoDuplicateParameters; 2898 : FunctionLiteral::kNoDuplicateParameters;
2889 2899
2890 // Note that the FunctionLiteral needs to be created in the main Zone again. 2900 // Note that the FunctionLiteral needs to be created in the main Zone again.
2891 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 2901 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2892 function_name, scope, body, materialized_literal_count, 2902 function_name, main_scope, body, materialized_literal_count,
2893 expected_property_count, arity, duplicate_parameters, function_type, 2903 expected_property_count, arity, duplicate_parameters, function_type,
2894 eager_compile_hint, kind, pos); 2904 eager_compile_hint, kind, pos);
2895 function_literal->set_function_token_position(function_token_pos); 2905 function_literal->set_function_token_position(function_token_pos);
2896 if (should_be_used_once_hint) 2906 if (should_be_used_once_hint)
2897 function_literal->set_should_be_used_once_hint(); 2907 function_literal->set_should_be_used_once_hint();
2898 2908
2899 if (should_infer_name) { 2909 if (should_infer_name) {
2900 DCHECK_NOT_NULL(fni_); 2910 DCHECK_NOT_NULL(fni_);
2901 fni_->AddFunction(function_literal); 2911 fni_->AddFunction(function_literal);
2902 } 2912 }
(...skipping 27 matching lines...) Expand all
2930 } 2940 }
2931 2941
2932 Parser::LazyParsingResult Parser::SkipLazyFunctionBody( 2942 Parser::LazyParsingResult Parser::SkipLazyFunctionBody(
2933 int* materialized_literal_count, int* expected_property_count, 2943 int* materialized_literal_count, int* expected_property_count,
2934 bool is_inner_function, bool may_abort, bool* ok) { 2944 bool is_inner_function, bool may_abort, bool* ok) {
2935 if (produce_cached_parse_data()) CHECK(log_); 2945 if (produce_cached_parse_data()) CHECK(log_);
2936 2946
2937 int function_block_pos = position(); 2947 int function_block_pos = position();
2938 DeclarationScope* scope = function_state_->scope(); 2948 DeclarationScope* scope = function_state_->scope();
2939 DCHECK(scope->is_function_scope()); 2949 DCHECK(scope->is_function_scope());
2950 scope->set_is_lazily_parsed(true);
2940 // Inner functions are not part of the cached data. 2951 // Inner functions are not part of the cached data.
2941 if (!is_inner_function && consume_cached_parse_data() && 2952 if (!is_inner_function && consume_cached_parse_data() &&
2942 !cached_parse_data_->rejected()) { 2953 !cached_parse_data_->rejected()) {
2943 // If we have cached data, we use it to skip parsing the function body. The 2954 // If we have cached data, we use it to skip parsing the function body. The
2944 // data contains the information we need to construct the lazy function. 2955 // data contains the information we need to construct the lazy function.
2945 FunctionEntry entry = 2956 FunctionEntry entry =
2946 cached_parse_data_->GetFunctionEntry(function_block_pos); 2957 cached_parse_data_->GetFunctionEntry(function_block_pos);
2947 // Check that cached data is valid. If not, mark it as invalid (the embedder 2958 // Check that cached data is valid. If not, mark it as invalid (the embedder
2948 // handles it). Note that end position greater than end of stream is safe, 2959 // handles it). Note that end position greater than end of stream is safe,
2949 // and hard to check. 2960 // and hard to check.
(...skipping 12 matching lines...) Expand all
2962 } 2973 }
2963 cached_parse_data_->Reject(); 2974 cached_parse_data_->Reject();
2964 } 2975 }
2965 // With no cached data, we partially parse the function, without building an 2976 // With no cached data, we partially parse the function, without building an
2966 // AST. This gathers the data needed to build a lazy function. 2977 // AST. This gathers the data needed to build a lazy function.
2967 SingletonLogger logger; 2978 SingletonLogger logger;
2968 PreParser::PreParseResult result = 2979 PreParser::PreParseResult result =
2969 ParseLazyFunctionBodyWithPreParser(&logger, is_inner_function, may_abort); 2980 ParseLazyFunctionBodyWithPreParser(&logger, is_inner_function, may_abort);
2970 2981
2971 // Return immediately if pre-parser decided to abort parsing. 2982 // Return immediately if pre-parser decided to abort parsing.
2972 if (result == PreParser::kPreParseAbort) return kLazyParsingAborted; 2983 if (result == PreParser::kPreParseAbort) {
2984 scope->set_is_lazily_parsed(false);
2985 return kLazyParsingAborted;
2986 }
2973 if (result == PreParser::kPreParseStackOverflow) { 2987 if (result == PreParser::kPreParseStackOverflow) {
2974 // Propagate stack overflow. 2988 // Propagate stack overflow.
2975 set_stack_overflow(); 2989 set_stack_overflow();
2976 *ok = false; 2990 *ok = false;
2977 return kLazyParsingComplete; 2991 return kLazyParsingComplete;
2978 } 2992 }
2979 if (logger.has_error()) { 2993 if (logger.has_error()) {
2980 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), 2994 ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
2981 logger.message(), logger.argument_opt(), 2995 logger.message(), logger.argument_opt(),
2982 logger.error_type()); 2996 logger.error_type());
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
3463 #undef SET_ALLOW 3477 #undef SET_ALLOW
3464 } 3478 }
3465 // Aborting inner function preparsing would leave scopes in an inconsistent 3479 // Aborting inner function preparsing would leave scopes in an inconsistent
3466 // state; we don't parse inner functions in the abortable mode anyway. 3480 // state; we don't parse inner functions in the abortable mode anyway.
3467 DCHECK(!is_inner_function || !may_abort); 3481 DCHECK(!is_inner_function || !may_abort);
3468 3482
3469 DeclarationScope* function_scope = function_state_->scope(); 3483 DeclarationScope* function_scope = function_state_->scope();
3470 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( 3484 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
3471 function_scope, parsing_module_, logger, is_inner_function, may_abort, 3485 function_scope, parsing_module_, logger, is_inner_function, may_abort,
3472 use_counts_); 3486 use_counts_);
3487 // Detaching the scopes created by PreParser from the Scope chain must be done
3488 // above (see ParseFunctionLiteral & AnalyzePartially).
3489 if (!is_inner_function) {
3490 function_scope->ResetAfterPreparsing(result == PreParser::kPreParseAbort);
3491 }
3473 if (pre_parse_timer_ != NULL) { 3492 if (pre_parse_timer_ != NULL) {
3474 pre_parse_timer_->Stop(); 3493 pre_parse_timer_->Stop();
3475 } 3494 }
3476 return result; 3495 return result;
3477 } 3496 }
3478 3497
3479 Expression* Parser::InstallHomeObject(Expression* function_literal, 3498 Expression* Parser::InstallHomeObject(Expression* function_literal,
3480 Expression* home_object) { 3499 Expression* home_object) {
3481 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 3500 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
3482 Variable* result_var = 3501 Variable* result_var =
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
3609 MessageTemplate::kUnexpectedStrictReserved); 3628 MessageTemplate::kUnexpectedStrictReserved);
3610 *ok = false; 3629 *ok = false;
3611 return nullptr; 3630 return nullptr;
3612 } 3631 }
3613 if (IsEvalOrArguments(name)) { 3632 if (IsEvalOrArguments(name)) {
3614 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); 3633 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
3615 *ok = false; 3634 *ok = false;
3616 return nullptr; 3635 return nullptr;
3617 } 3636 }
3618 3637
3619 BlockState block_state(zone(), &scope_state_); 3638 BlockState block_state(&scope_state_);
3620 RaiseLanguageMode(STRICT); 3639 RaiseLanguageMode(STRICT);
3621 #ifdef DEBUG 3640 #ifdef DEBUG
3622 scope()->SetScopeName(name); 3641 scope()->SetScopeName(name);
3623 #endif 3642 #endif
3624 3643
3625 VariableProxy* proxy = nullptr; 3644 VariableProxy* proxy = nullptr;
3626 if (name != nullptr) { 3645 if (name != nullptr) {
3627 proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE); 3646 proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3628 // TODO(verwaest): declare via block_state. 3647 // TODO(verwaest): declare via block_state.
3629 Declaration* declaration = 3648 Declaration* declaration =
(...skipping 1956 matching lines...) Expand 10 before | Expand all | Expand 10 after
5586 5605
5587 return final_loop; 5606 return final_loop;
5588 } 5607 }
5589 5608
5590 #undef CHECK_OK 5609 #undef CHECK_OK
5591 #undef CHECK_OK_VOID 5610 #undef CHECK_OK_VOID
5592 #undef CHECK_FAILED 5611 #undef CHECK_FAILED
5593 5612
5594 } // namespace internal 5613 } // namespace internal
5595 } // namespace v8 5614 } // namespace v8
OLDNEW
« no previous file with comments | « 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