From 68103cee8eef44ac47d6f939bc173a42402473a9 Mon Sep 17 00:00:00 2001 From: "kasperl@chromium.org" Date: Wed, 1 Oct 2008 10:57:37 +0000 Subject: [PATCH] Get rid of the local variable we use to keep the state 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 | 11 +---------- src/codegen-arm.cc | 33 +++++++++------------------------ src/codegen-ia32.cc | 34 +++++++++------------------------- src/parser.cc | 6 ++---- src/usage-analyzer.cc | 5 ----- 5 files changed, 21 insertions(+), 68 deletions(-) diff --git a/src/ast.h b/src/ast.h index 7cde61a..0194623 100644 --- 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_; }; diff --git a/src/codegen-arm.cc b/src/codegen-arm.cc index 5192bb2..0df6907 100644 --- a/src/codegen-arm.cc +++ b/src/codegen-arm.cc @@ -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 diff --git a/src/codegen-ia32.cc b/src/codegen-ia32.cc index f3ae4cf..95c2da7 100644 --- a/src/codegen-ia32.cc +++ b/src/codegen-ia32.cc @@ -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 diff --git a/src/parser.cc b/src/parser.cc index c39b4b6..d310979 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -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)); diff --git a/src/usage-analyzer.cc b/src/usage-analyzer.cc index 2910fc6..43f29a1 100644 --- a/src/usage-analyzer.cc +++ b/src/usage-analyzer.cc @@ -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()); } -- 2.7.4