From ef1be160d66b7da8bc2da857b1c33c6f680d86f1 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Fri, 15 Jul 2011 17:47:20 -0700 Subject: Upgrade V8 to 3.4.12.1 --- deps/v8/src/parser.cc | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'deps/v8/src/parser.cc') diff --git a/deps/v8/src/parser.cc b/deps/v8/src/parser.cc index 184f0a2a2..3085ef86b 100644 --- a/deps/v8/src/parser.cc +++ b/deps/v8/src/parser.cc @@ -823,14 +823,24 @@ class ParserFinder { // form expr.a = ...; expr.b = ...; etc. class InitializationBlockFinder : public ParserFinder { public: - InitializationBlockFinder() - : first_in_block_(NULL), last_in_block_(NULL), block_size_(0) {} + // We find and mark the initialization blocks in top level + // non-looping code only. This is because the optimization prevents + // reuse of the map transitions, so it should be used only for code + // that will only be run once. + InitializationBlockFinder(Scope* top_scope, Target* target) + : enabled_(top_scope->DeclarationScope()->is_global_scope() && + !IsLoopTarget(target)), + first_in_block_(NULL), + last_in_block_(NULL), + block_size_(0) {} ~InitializationBlockFinder() { + if (!enabled_) return; if (InBlock()) EndBlock(); } void Update(Statement* stat) { + if (!enabled_) return; Assignment* assignment = AsAssignment(stat); if (InBlock()) { if (BlockContinues(assignment)) { @@ -851,6 +861,14 @@ class InitializationBlockFinder : public ParserFinder { // the overhead exceeds the savings below this limit. static const int kMinInitializationBlock = 3; + static bool IsLoopTarget(Target* target) { + while (target != NULL) { + if (target->node()->AsIterationStatement() != NULL) return true; + target = target->previous(); + } + return false; + } + // Returns true if the expressions appear to denote the same object. // In the context of initialization blocks, we only consider expressions // of the form 'expr.x' or expr["x"]. @@ -913,6 +931,7 @@ class InitializationBlockFinder : public ParserFinder { bool InBlock() { return first_in_block_ != NULL; } + const bool enabled_; Assignment* first_in_block_; Assignment* last_in_block_; int block_size_; @@ -1078,7 +1097,7 @@ void* Parser::ParseSourceElements(ZoneList* processor, TargetScope scope(&this->target_stack_); ASSERT(processor != NULL); - InitializationBlockFinder block_finder; + InitializationBlockFinder block_finder(top_scope_, target_stack_); ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate()); bool directive_prologue = true; // Parsing directive prologue. @@ -1133,12 +1152,7 @@ void* Parser::ParseSourceElements(ZoneList* processor, } } - // We find and mark the initialization blocks on top level code only. - // This is because the optimization prevents reuse of the map transitions, - // so it should be used only for code that will only be run once. - if (top_scope_->is_global_scope()) { - block_finder.Update(stat); - } + block_finder.Update(stat); // Find and mark all assignments to named properties in this (this.x =) if (top_scope_->is_function_scope()) { this_property_assignment_finder.Update(top_scope_, stat); @@ -1478,9 +1492,13 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { Block* result = new(zone()) Block(labels, 16, false); Target target(&this->target_stack_, result); Expect(Token::LBRACE, CHECK_OK); + InitializationBlockFinder block_finder(top_scope_, target_stack_); while (peek() != Token::RBRACE) { Statement* stat = ParseStatement(NULL, CHECK_OK); - if (stat && !stat->IsEmpty()) result->AddStatement(stat); + if (stat && !stat->IsEmpty()) { + result->AddStatement(stat); + block_finder.Update(stat); + } } Expect(Token::RBRACE, CHECK_OK); return result; -- cgit v1.2.1