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

Side by Side Diff: src/parser.cc

Issue 998001: Loop peeling for inner loops.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/flag-definitions.h ('k') | src/variables.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 TemporaryScope* temp_scope_; 141 TemporaryScope* temp_scope_;
142 Mode mode_; 142 Mode mode_;
143 143
144 Target* target_stack_; // for break, continue statements 144 Target* target_stack_; // for break, continue statements
145 bool allow_natives_syntax_; 145 bool allow_natives_syntax_;
146 v8::Extension* extension_; 146 v8::Extension* extension_;
147 ParserFactory* factory_; 147 ParserFactory* factory_;
148 ParserLog* log_; 148 ParserLog* log_;
149 bool is_pre_parsing_; 149 bool is_pre_parsing_;
150 ScriptDataImpl* pre_data_; 150 ScriptDataImpl* pre_data_;
151 bool seen_loop_stmt_; // Used for inner loop detection.
151 152
152 bool inside_with() const { return with_nesting_level_ > 0; } 153 bool inside_with() const { return with_nesting_level_ > 0; }
153 ParserFactory* factory() const { return factory_; } 154 ParserFactory* factory() const { return factory_; }
154 ParserLog* log() const { return log_; } 155 ParserLog* log() const { return log_; }
155 Scanner& scanner() { return scanner_; } 156 Scanner& scanner() { return scanner_; }
156 Mode mode() const { return mode_; } 157 Mode mode() const { return mode_; }
157 ScriptDataImpl* pre_data() const { return pre_data_; } 158 ScriptDataImpl* pre_data() const { return pre_data_; }
158 159
159 // All ParseXXX functions take as the last argument an *ok parameter 160 // All ParseXXX functions take as the last argument an *ok parameter
160 // which is set to false if parsing failed; it is unchanged otherwise. 161 // which is set to false if parsing failed; it is unchanged otherwise.
(...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 scanner_(is_pre_parsing), 1199 scanner_(is_pre_parsing),
1199 top_scope_(NULL), 1200 top_scope_(NULL),
1200 with_nesting_level_(0), 1201 with_nesting_level_(0),
1201 temp_scope_(NULL), 1202 temp_scope_(NULL),
1202 target_stack_(NULL), 1203 target_stack_(NULL),
1203 allow_natives_syntax_(allow_natives_syntax), 1204 allow_natives_syntax_(allow_natives_syntax),
1204 extension_(extension), 1205 extension_(extension),
1205 factory_(factory), 1206 factory_(factory),
1206 log_(log), 1207 log_(log),
1207 is_pre_parsing_(is_pre_parsing == PREPARSE), 1208 is_pre_parsing_(is_pre_parsing == PREPARSE),
1208 pre_data_(pre_data) { 1209 pre_data_(pre_data),
1210 seen_loop_stmt_(false) {
1209 } 1211 }
1210 1212
1211 1213
1212 bool Parser::PreParseProgram(Handle<String> source, 1214 bool Parser::PreParseProgram(Handle<String> source,
1213 unibrow::CharacterStream* stream) { 1215 unibrow::CharacterStream* stream) {
1214 HistogramTimerScope timer(&Counters::pre_parse); 1216 HistogramTimerScope timer(&Counters::pre_parse);
1215 AssertNoZoneAllocation assert_no_zone_allocation; 1217 AssertNoZoneAllocation assert_no_zone_allocation;
1216 AssertNoAllocation assert_no_allocation; 1218 AssertNoAllocation assert_no_allocation;
1217 NoHandleAllocation no_handle_allocation; 1219 NoHandleAllocation no_handle_allocation;
1218 scanner_.Initialize(source, stream, JAVASCRIPT); 1220 scanner_.Initialize(source, stream, JAVASCRIPT);
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 Expression* cond = ParseExpression(true, CHECK_OK); 2646 Expression* cond = ParseExpression(true, CHECK_OK);
2645 Expect(Token::RPAREN, CHECK_OK); 2647 Expect(Token::RPAREN, CHECK_OK);
2646 2648
2647 // Allow do-statements to be terminated with and without 2649 // Allow do-statements to be terminated with and without
2648 // semi-colons. This allows code such as 'do;while(0)return' to 2650 // semi-colons. This allows code such as 'do;while(0)return' to
2649 // parse, which would not be the case if we had used the 2651 // parse, which would not be the case if we had used the
2650 // ExpectSemicolon() functionality here. 2652 // ExpectSemicolon() functionality here.
2651 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 2653 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2652 2654
2653 if (loop != NULL) loop->Initialize(cond, body); 2655 if (loop != NULL) loop->Initialize(cond, body);
2656
2657 seen_loop_stmt_ = true;
2658
2654 return loop; 2659 return loop;
2655 } 2660 }
2656 2661
2657 2662
2658 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { 2663 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
2659 // WhileStatement :: 2664 // WhileStatement ::
2660 // 'while' '(' Expression ')' Statement 2665 // 'while' '(' Expression ')' Statement
2661 2666
2662 WhileStatement* loop = NEW(WhileStatement(labels)); 2667 WhileStatement* loop = NEW(WhileStatement(labels));
2663 Target target(this, loop); 2668 Target target(this, loop);
2664 2669
2665 Expect(Token::WHILE, CHECK_OK); 2670 Expect(Token::WHILE, CHECK_OK);
2666 Expect(Token::LPAREN, CHECK_OK); 2671 Expect(Token::LPAREN, CHECK_OK);
2667 Expression* cond = ParseExpression(true, CHECK_OK); 2672 Expression* cond = ParseExpression(true, CHECK_OK);
2668 Expect(Token::RPAREN, CHECK_OK); 2673 Expect(Token::RPAREN, CHECK_OK);
2669 Statement* body = ParseStatement(NULL, CHECK_OK); 2674 Statement* body = ParseStatement(NULL, CHECK_OK);
2670 2675
2671 if (loop != NULL) loop->Initialize(cond, body); 2676 if (loop != NULL) loop->Initialize(cond, body);
2677
2678 seen_loop_stmt_ = true;
2679
2672 return loop; 2680 return loop;
2673 } 2681 }
2674 2682
2675 2683
2676 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { 2684 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
2677 // ForStatement :: 2685 // ForStatement ::
2678 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 2686 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2679 2687
2680 Statement* init = NULL; 2688 Statement* init = NULL;
2681 2689
(...skipping 13 matching lines...) Expand all
2695 Expect(Token::RPAREN, CHECK_OK); 2703 Expect(Token::RPAREN, CHECK_OK);
2696 2704
2697 Statement* body = ParseStatement(NULL, CHECK_OK); 2705 Statement* body = ParseStatement(NULL, CHECK_OK);
2698 if (is_pre_parsing_) { 2706 if (is_pre_parsing_) {
2699 return NULL; 2707 return NULL;
2700 } else { 2708 } else {
2701 loop->Initialize(each, enumerable, body); 2709 loop->Initialize(each, enumerable, body);
2702 Block* result = NEW(Block(NULL, 2, false)); 2710 Block* result = NEW(Block(NULL, 2, false));
2703 result->AddStatement(variable_statement); 2711 result->AddStatement(variable_statement);
2704 result->AddStatement(loop); 2712 result->AddStatement(loop);
2713
2714 seen_loop_stmt_ = true;
2715
2705 // Parsed for-in loop w/ variable/const declaration. 2716 // Parsed for-in loop w/ variable/const declaration.
2706 return result; 2717 return result;
2707 } 2718 }
2708 2719
2709 } else { 2720 } else {
2710 init = variable_statement; 2721 init = variable_statement;
2711 } 2722 }
2712 2723
2713 } else { 2724 } else {
2714 Expression* expression = ParseExpression(false, CHECK_OK); 2725 Expression* expression = ParseExpression(false, CHECK_OK);
2715 if (peek() == Token::IN) { 2726 if (peek() == Token::IN) {
2716 // Signal a reference error if the expression is an invalid 2727 // Signal a reference error if the expression is an invalid
2717 // left-hand side expression. We could report this as a syntax 2728 // left-hand side expression. We could report this as a syntax
2718 // error here but for compatibility with JSC we choose to report 2729 // error here but for compatibility with JSC we choose to report
2719 // the error at runtime. 2730 // the error at runtime.
2720 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2731 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2721 Handle<String> type = Factory::invalid_lhs_in_for_in_symbol(); 2732 Handle<String> type = Factory::invalid_lhs_in_for_in_symbol();
2722 expression = NewThrowReferenceError(type); 2733 expression = NewThrowReferenceError(type);
2723 } 2734 }
2724 ForInStatement* loop = NEW(ForInStatement(labels)); 2735 ForInStatement* loop = NEW(ForInStatement(labels));
2725 Target target(this, loop); 2736 Target target(this, loop);
2726 2737
2727 Expect(Token::IN, CHECK_OK); 2738 Expect(Token::IN, CHECK_OK);
2728 Expression* enumerable = ParseExpression(true, CHECK_OK); 2739 Expression* enumerable = ParseExpression(true, CHECK_OK);
2729 Expect(Token::RPAREN, CHECK_OK); 2740 Expect(Token::RPAREN, CHECK_OK);
2730 2741
2731 Statement* body = ParseStatement(NULL, CHECK_OK); 2742 Statement* body = ParseStatement(NULL, CHECK_OK);
2732 if (loop) loop->Initialize(expression, enumerable, body); 2743 if (loop) loop->Initialize(expression, enumerable, body);
2733 2744
2745 seen_loop_stmt_ = true;
2746
2734 // Parsed for-in loop. 2747 // Parsed for-in loop.
2735 return loop; 2748 return loop;
2736 2749
2737 } else { 2750 } else {
2738 init = NEW(ExpressionStatement(expression)); 2751 init = NEW(ExpressionStatement(expression));
2739 } 2752 }
2740 } 2753 }
2741 } 2754 }
2742 2755
2743 // Standard 'for' loop 2756 // Standard 'for' loop
(...skipping 12 matching lines...) Expand all
2756 } 2769 }
2757 Expect(Token::SEMICOLON, CHECK_OK); 2770 Expect(Token::SEMICOLON, CHECK_OK);
2758 2771
2759 Statement* next = NULL; 2772 Statement* next = NULL;
2760 if (peek() != Token::RPAREN) { 2773 if (peek() != Token::RPAREN) {
2761 Expression* exp = ParseExpression(true, CHECK_OK); 2774 Expression* exp = ParseExpression(true, CHECK_OK);
2762 next = NEW(ExpressionStatement(exp)); 2775 next = NEW(ExpressionStatement(exp));
2763 } 2776 }
2764 Expect(Token::RPAREN, CHECK_OK); 2777 Expect(Token::RPAREN, CHECK_OK);
2765 2778
2779 seen_loop_stmt_ = false;
2780
2766 Statement* body = ParseStatement(NULL, CHECK_OK); 2781 Statement* body = ParseStatement(NULL, CHECK_OK);
2767 2782
2783 // Mark this loop if it is an inner loop.
2784 if (loop && !seen_loop_stmt_) loop->set_peel_this_loop(true);
2785
2768 if (loop) loop->Initialize(init, cond, next, body); 2786 if (loop) loop->Initialize(init, cond, next, body);
2787
2788 seen_loop_stmt_ = true;
2789
2769 return loop; 2790 return loop;
2770 } 2791 }
2771 2792
2772 2793
2773 // Precedence = 1 2794 // Precedence = 1
2774 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { 2795 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
2775 // Expression :: 2796 // Expression ::
2776 // AssignmentExpression 2797 // AssignmentExpression
2777 // Expression ',' AssignmentExpression 2798 // Expression ',' AssignmentExpression
2778 2799
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after
3703 } 3724 }
3704 3725
3705 3726
3706 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, 3727 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
3707 int function_token_position, 3728 int function_token_position,
3708 FunctionLiteralType type, 3729 FunctionLiteralType type,
3709 bool* ok) { 3730 bool* ok) {
3710 // Function :: 3731 // Function ::
3711 // '(' FormalParameterList? ')' '{' FunctionBody '}' 3732 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3712 3733
3734 // Reset flag used for inner loop detection.
3735 seen_loop_stmt_ = false;
3736
3713 bool is_named = !var_name.is_null(); 3737 bool is_named = !var_name.is_null();
3714 3738
3715 // The name associated with this function. If it's a function expression, 3739 // The name associated with this function. If it's a function expression,
3716 // this is the actual function name, otherwise this is the name of the 3740 // this is the actual function name, otherwise this is the name of the
3717 // variable declared and initialized with the function (expression). In 3741 // variable declared and initialized with the function (expression). In
3718 // that case, we don't have a function name (it's empty). 3742 // that case, we don't have a function name (it's empty).
3719 Handle<String> name = is_named ? var_name : factory()->EmptySymbol(); 3743 Handle<String> name = is_named ? var_name : factory()->EmptySymbol();
3720 // The function name, if any. 3744 // The function name, if any.
3721 Handle<String> function_name = factory()->EmptySymbol(); 3745 Handle<String> function_name = factory()->EmptySymbol();
3722 if (is_named && (type == EXPRESSION || type == NESTED)) { 3746 if (is_named && (type == EXPRESSION || type == NESTED)) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3813 expected_property_count, 3837 expected_property_count,
3814 only_simple_this_property_assignments, 3838 only_simple_this_property_assignments,
3815 this_property_assignments, 3839 this_property_assignments,
3816 num_parameters, 3840 num_parameters,
3817 start_pos, 3841 start_pos,
3818 end_pos, 3842 end_pos,
3819 function_name->length() > 0)); 3843 function_name->length() > 0));
3820 if (!is_pre_parsing_) { 3844 if (!is_pre_parsing_) {
3821 function_literal->set_function_token_position(function_token_position); 3845 function_literal->set_function_token_position(function_token_position);
3822 } 3846 }
3847
3848 // Set flag for inner loop detection. We treat loops that contain a function
3849 // literal not as inner loops because we avoid duplicating function literals
3850 // when peeling or unrolling such a loop.
3851 seen_loop_stmt_ = true;
3852
3823 return function_literal; 3853 return function_literal;
3824 } 3854 }
3825 } 3855 }
3826 3856
3827 3857
3828 Expression* Parser::ParseV8Intrinsic(bool* ok) { 3858 Expression* Parser::ParseV8Intrinsic(bool* ok) {
3829 // CallRuntime :: 3859 // CallRuntime ::
3830 // '%' Identifier Arguments 3860 // '%' Identifier Arguments
3831 3861
3832 Expect(Token::MOD, CHECK_OK); 3862 Expect(Token::MOD, CHECK_OK);
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after
5142 parser.ParseLazy(script_source, name, 5172 parser.ParseLazy(script_source, name,
5143 start_position, end_position, is_expression); 5173 start_position, end_position, is_expression);
5144 return result; 5174 return result;
5145 } 5175 }
5146 5176
5147 5177
5148 #undef NEW 5178 #undef NEW
5149 5179
5150 5180
5151 } } // namespace v8::internal 5181 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/flag-definitions.h ('k') | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698