Index: src/parser.cc |
=================================================================== |
--- src/parser.cc (revision 4136) |
+++ src/parser.cc (working copy) |
@@ -148,6 +148,7 @@ |
ParserLog* log_; |
bool is_pre_parsing_; |
ScriptDataImpl* pre_data_; |
+ bool seen_loop_stmt_; // Used for inner loop detection. |
bool inside_with() const { return with_nesting_level_ > 0; } |
ParserFactory* factory() const { return factory_; } |
@@ -1205,7 +1206,8 @@ |
factory_(factory), |
log_(log), |
is_pre_parsing_(is_pre_parsing == PREPARSE), |
- pre_data_(pre_data) { |
+ pre_data_(pre_data), |
+ seen_loop_stmt_(false) { |
} |
@@ -2651,6 +2653,9 @@ |
if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
if (loop != NULL) loop->Initialize(cond, body); |
+ |
+ seen_loop_stmt_ = true; |
+ |
return loop; |
} |
@@ -2669,6 +2674,9 @@ |
Statement* body = ParseStatement(NULL, CHECK_OK); |
if (loop != NULL) loop->Initialize(cond, body); |
+ |
+ seen_loop_stmt_ = true; |
+ |
return loop; |
} |
@@ -2702,6 +2710,9 @@ |
Block* result = NEW(Block(NULL, 2, false)); |
result->AddStatement(variable_statement); |
result->AddStatement(loop); |
+ |
+ seen_loop_stmt_ = true; |
+ |
// Parsed for-in loop w/ variable/const declaration. |
return result; |
} |
@@ -2731,6 +2742,8 @@ |
Statement* body = ParseStatement(NULL, CHECK_OK); |
if (loop) loop->Initialize(expression, enumerable, body); |
+ seen_loop_stmt_ = true; |
+ |
// Parsed for-in loop. |
return loop; |
@@ -2763,9 +2776,17 @@ |
} |
Expect(Token::RPAREN, CHECK_OK); |
+ seen_loop_stmt_ = false; |
+ |
Statement* body = ParseStatement(NULL, CHECK_OK); |
+ // Mark this loop if it is an inner loop. |
+ if (loop && !seen_loop_stmt_) loop->set_peel_this_loop(true); |
+ |
if (loop) loop->Initialize(init, cond, next, body); |
+ |
+ seen_loop_stmt_ = true; |
+ |
return loop; |
} |
@@ -3710,6 +3731,9 @@ |
// Function :: |
// '(' FormalParameterList? ')' '{' FunctionBody '}' |
+ // Reset flag used for inner loop detection. |
+ seen_loop_stmt_ = false; |
+ |
bool is_named = !var_name.is_null(); |
// The name associated with this function. If it's a function expression, |
@@ -3820,6 +3844,12 @@ |
if (!is_pre_parsing_) { |
function_literal->set_function_token_position(function_token_position); |
} |
+ |
+ // Set flag for inner loop detection. We treat loops that contain a function |
+ // literal not as inner loops because we avoid duplicating function literals |
+ // when peeling or unrolling such a loop. |
+ seen_loop_stmt_ = true; |
+ |
return function_literal; |
} |
} |