Get rid of the local variable we use to keep the state
authorkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 1 Oct 2008 10:57:37 +0000 (10:57 +0000)
committerkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 1 Oct 2008 10:57:37 +0000 (10:57 +0000)
during the execution of a finally block by just pushing
the state on the execution stack instead.
Review URL: http://codereview.chromium.org/5626

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@402 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/ast.h
src/codegen-arm.cc
src/codegen-ia32.cc
src/parser.cc
src/usage-analyzer.cc

index 7cde61acd42c8af6516d5a67bb3c8486b0dbf79a..0194623c2f611b9dbb0058a06af0e96ba883d392 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -568,24 +568,15 @@ class TryCatch: public TryStatement {
 
 class TryFinally: public TryStatement {
  public:
-  TryFinally(Block* try_block, Expression* finally_var, Block* finally_block)
+  TryFinally(Block* try_block, Block* finally_block)
       : TryStatement(try_block),
-        finally_var_(finally_var),
         finally_block_(finally_block) { }
 
   virtual void Accept(Visitor* v);
 
-  // If the finally block is non-trivial it may be problematic to have
-  // extra stuff on the expression stack while evaluating it. The
-  // finally variable is used to hold the state instead of storing it
-  // on the stack. It may be NULL in which case the state is stored on
-  // the stack.
-  Expression* finally_var() const { return finally_var_; }
-
   Block* finally_block() const { return finally_block_; }
 
  private:
-  Expression* finally_var_;
   Block* finally_block_;
 };
 
index 5192bb266484d32e30a741acc2fbbbb2cfeffa1b..0df690705e4eed72c01e8beeed55fded7bb5fbdb 100644 (file)
@@ -3182,37 +3182,22 @@ void ArmCodeGenerator::VisitTryFinally(TryFinally* node) {
   // --- Finally block ---
   __ bind(&finally_block);
 
-  // We keep a single element on the stack - the (possibly faked)
-  // result - while evaluating the finally block. Record it, so that a
-  // break/continue crossing this statement can restore the stack.
-  const int kFinallyStackSize = 1 * kPointerSize;
-  break_stack_height_ += kFinallyStackSize;
-
-  // Push the state on the stack. If necessary move the state to a
-  // local variable to avoid having extra values on the stack while
-  // evaluating the finally block.
+  // Push the state on the stack.
   __ push(r2);
-  if (node->finally_var() != NULL) {
-    Reference target(this, node->finally_var());
-    SetValue(&target);
-    ASSERT(target.size() == 0);  // no extra stuff on the stack
-    __ pop();  // remove the extra avalue that was pushed above
-  }
+
+  // We keep two elements on the stack - the (possibly faked) result
+  // and the state - while evaluating the finally block. Record it, so
+  // that a break/continue crossing this statement can restore the
+  // stack.
+  const int kFinallyStackSize = 2 * kPointerSize;
+  break_stack_height_ += kFinallyStackSize;
 
   // Generate code for the statements in the finally block.
   VisitStatements(node->finally_block()->statements());
 
-  // Get the state from the stack - or the local variable.
-  if (node->finally_var() != NULL) {
-    Reference target(this, node->finally_var());
-    GetValue(&target);
-  }
+  // Restore state and return value or faked TOS.
   __ pop(r2);
-
-  // Restore return value or faked TOS.
   __ pop(r0);
-
-  // Record the fact that the result has been removed from the stack.
   break_stack_height_ -= kFinallyStackSize;
 
   // Generate code that jumps to the right destination for all used
index f3ae4cf02352476dfd855b6312290d0bd38a7bf1..95c2da77ba9cf1b0788b07a1bac2a0f7b4eb075d 100644 (file)
@@ -3558,38 +3558,22 @@ void Ia32CodeGenerator::VisitTryFinally(TryFinally* node) {
   // --- Finally block ---
   __ bind(&finally_block);
 
-  // We keep a single element on the stack - the (possibly faked)
-  // result - while evaluating the finally block. Record it, so that a
-  // break/continue crossing this statement can restore the stack.
-  const int kFinallyStackSize = 1 * kPointerSize;
-  break_stack_height_ += kFinallyStackSize;
-
-  // Push the state on the stack. If necessary move the state to a
-  // local variable to avoid having extra values on the stack while
-  // evaluating the finally block.
+  // Push the state on the stack.
   __ push(ecx);
-  if (node->finally_var() != NULL) {
-    Reference target(this, node->finally_var());
-    SetValue(&target);
-    ASSERT(target.size() == 0);  // no extra stuff on the stack
-    __ pop(edx);  // remove the extra value that was pushed above
-  }
+
+  // We keep two elements on the stack - the (possibly faked) result
+  // and the state - while evaluating the finally block. Record it, so
+  // that a break/continue crossing this statement can restore the
+  // stack.
+  const int kFinallyStackSize = 2 * kPointerSize;
+  break_stack_height_ += kFinallyStackSize;
 
   // Generate code for the statements in the finally block.
   VisitStatements(node->finally_block()->statements());
 
-  // Get the state from the stack - or the local variable - and
-  // restore the TOS register.
-  if (node->finally_var() != NULL) {
-    Reference target(this, node->finally_var());
-    GetValue(&target);
-  }
+  // Restore state and return value or faked TOS.
   __ pop(ecx);
-
-  // Restore return value or faked TOS.
   __ pop(eax);
-
-  // Record the fact that the result has been removed from the stack.
   break_stack_height_ -= kFinallyStackSize;
 
   // Generate code that jumps to the right destination for all used
index c39b4b6db9ab65c7a4bad9dba4d7e18e34a19843..d310979148bdb2cad74cf215e05138b4d32033c0 100644 (file)
@@ -1598,7 +1598,7 @@ Block* Parser::WithHelper(Expression* obj, ZoneStringList* labels, bool* ok) {
     exit->AddStatement(NEW(WithExitStatement()));
 
     // Return a try-finally statement.
-    TryFinally* wrapper = NEW(TryFinally(body, NULL, exit));
+    TryFinally* wrapper = NEW(TryFinally(body, exit));
     wrapper->set_escaping_labels(collector.labels());
     result->AddStatement(wrapper);
     return result;
@@ -1793,12 +1793,10 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
     tok = peek();
   }
 
-  VariableProxy* finally_var = NULL;
   if (tok == Token::FINALLY || !has_catch) {
     Consume(Token::FINALLY);
     // Declare a variable for holding the finally state while
     // executing the finally block.
-    finally_var = top_scope_->NewTemporary(Factory::finally_state_symbol());
     finally_block = ParseBlock(NULL, CHECK_OK);
   }
 
@@ -1823,7 +1821,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
       result->set_escaping_labels(collector.labels());
     } else {
       ASSERT(finally_block != NULL);
-      result = NEW(TryFinally(try_block, finally_var, finally_block));
+      result = NEW(TryFinally(try_block, finally_block));
       // Add the labels of the try block and the catch block.
       for (int i = 0; i < collector.labels()->length(); i++) {
         catch_collector.labels()->Add(collector.labels()->at(i));
index 2910fc671ba12275c84602f953ec27778d0bd84a..43f29a15ac3fee56a1d97ab38787f0e732ca034a 100644 (file)
@@ -221,11 +221,6 @@ void UsageComputer::VisitTryCatch(TryCatch* node) {
 
 void UsageComputer::VisitTryFinally(TryFinally* node) {
   Visit(node->try_block());
-  Expression* var = node->finally_var();
-  if (var != NULL) {
-    Write(var);
-    Read(var);
-  }
   Visit(node->finally_block());
 }