Author: [email protected]
Date: Wed Mar 11 03:25:48 2009
New Revision: 1486

Modified:
    branches/bleeding_edge/src/codegen-arm.cc
    branches/bleeding_edge/src/codegen-arm.h
    branches/bleeding_edge/src/codegen-ia32.cc
    branches/bleeding_edge/src/codegen-ia32.h
    branches/bleeding_edge/src/codegen.cc
    branches/bleeding_edge/src/codegen.h

Log:
Fix issue 268 by explicitly calling Unuse (to deallocate all contained
virtual frames) on zone-allocated jump targets.  These include jump
targets in AST nodes and the entry and exit targets of deferred code.

See http://code.google.com/p/v8/issues/detail?id=268

Review URL: http://codereview.chromium.org/42067

Modified: branches/bleeding_edge/src/codegen-arm.cc
==============================================================================
--- branches/bleeding_edge/src/codegen-arm.cc   (original)
+++ branches/bleeding_edge/src/codegen-arm.cc   Wed Mar 11 03:25:48 2009
@@ -284,7 +284,11 @@
    DeleteFrame();

    // Process any deferred code using the register allocator.
-  ProcessDeferred();
+  if (HasStackOverflow()) {
+    ClearDeferred();
+  } else {
+    ProcessDeferred();
+  }

    allocator_ = NULL;
    scope_ = NULL;
@@ -1133,6 +1137,7 @@
    if (node->break_target()->is_linked()) {
      node->break_target()->Bind();
    }
+  node->break_target()->Unuse();
    ASSERT(!has_valid_frame() || frame_->height() == original_height);
  }

@@ -1594,6 +1599,7 @@
    if (node->break_target()->is_linked()) {
      node->break_target()->Bind();
    }
+  node->break_target()->Unuse();
    ASSERT(!has_valid_frame() || frame_->height() == original_height);
  }

@@ -1781,6 +1787,8 @@
    if (node->break_target()->is_linked()) {
      node->break_target()->Bind();
    }
+  node->continue_target()->Unuse();
+  node->break_target()->Unuse();
    ASSERT(!has_valid_frame() || frame_->height() == original_height);
  }

@@ -1971,6 +1979,8 @@

    // Exit.
    exit.Bind();
+  node->continue_target()->Unuse();
+  node->break_target()->Unuse();
    ASSERT(frame_->height() == original_height);
  }


Modified: branches/bleeding_edge/src/codegen-arm.h
==============================================================================
--- branches/bleeding_edge/src/codegen-arm.h    (original)
+++ branches/bleeding_edge/src/codegen-arm.h    Wed Mar 11 03:25:48 2009
@@ -195,6 +195,8 @@
    // Accessors
    Scope* scope() const { return scope_; }

+  // Clearing and generating deferred code.
+  void ClearDeferred();
    void ProcessDeferred();

    bool is_eval() { return is_eval_; }

Modified: branches/bleeding_edge/src/codegen-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/codegen-ia32.cc  (original)
+++ branches/bleeding_edge/src/codegen-ia32.cc  Wed Mar 11 03:25:48 2009
@@ -307,7 +307,11 @@
    DeleteFrame();

    // Process any deferred code using the register allocator.
-  ProcessDeferred();
+  if (HasStackOverflow()) {
+    ClearDeferred();
+  } else {
+    ProcessDeferred();
+  }

    // There is no need to delete the register allocator, it is a
    // stack-allocated local.
@@ -1567,6 +1571,7 @@
    if (node->break_target()->is_linked()) {
      node->break_target()->Bind();
    }
+  node->break_target()->Unuse();
  }


@@ -2094,37 +2099,39 @@

      // There are two ways to reach the body: from the corresponding
      // test or as the fall through of the previous body.
-    if (!clause->body_target()->is_linked() && !has_valid_frame()) {
-      // If we have neither, skip this body.
-      continue;
-    } else if (clause->body_target()->is_linked() && has_valid_frame()) {
-      // If we have both, put a jump on the fall through path to avoid
-      // the dropping of the switch value on the test path.  The
-      // exception is the default which has already had the switch
-      // value dropped.
-      if (clause->is_default()) {
-        clause->body_target()->Bind();
+    if (clause->body_target()->is_linked() || has_valid_frame()) {
+      if (clause->body_target()->is_linked()) {
+        if (has_valid_frame()) {
+          // If we have both a jump to the test and a fall through, put
+          // a jump on the fall through path to avoid the dropping of
+          // the switch value on the test path.  The exception is the
+          // default which has already had the switch value dropped.
+          if (clause->is_default()) {
+            clause->body_target()->Bind();
+          } else {
+            JumpTarget body(this);
+            body.Jump();
+            clause->body_target()->Bind();
+            frame_->Drop();
+            body.Bind();
+          }
+        } else {
+          // No fall through to worry about.
+          clause->body_target()->Bind();
+          if (!clause->is_default()) {
+            frame_->Drop();
+          }
+        }
        } else {
-        JumpTarget body(this);
-        body.Jump();
-        clause->body_target()->Bind();
-        frame_->Drop();
-        body.Bind();
-      }
-    } else if (clause->body_target()->is_linked()) {
-      // No fall through to worry about.
-      clause->body_target()->Bind();
-      if (!clause->is_default()) {
-        frame_->Drop();
+        // Otherwise, we have only fall through.
+        ASSERT(has_valid_frame());
        }
-    } else {
-      // Otherwise, we have only fall through.
-      ASSERT(has_valid_frame());
-    }

-    // We are now prepared to compile the body.
-    Comment cmnt(masm_, "[ Case body");
-    VisitStatements(clause->statements());
+      // We are now prepared to compile the body.
+      Comment cmnt(masm_, "[ Case body");
+      VisitStatements(clause->statements());
+    }
+    clause->body_target()->Unuse();
    }

    // We may not have a valid frame here so bind the break target only
@@ -2132,6 +2139,7 @@
    if (node->break_target()->is_linked()) {
      node->break_target()->Bind();
    }
+  node->break_target()->Unuse();
  }


@@ -2452,6 +2460,8 @@
    }

    DecrementLoopNesting();
+  node->continue_target()->Unuse();
+  node->break_target()->Unuse();
  }


@@ -2636,6 +2646,9 @@

    // Exit.
    exit.Bind();
+
+  node->continue_target()->Unuse();
+  node->break_target()->Unuse();
  }



Modified: branches/bleeding_edge/src/codegen-ia32.h
==============================================================================
--- branches/bleeding_edge/src/codegen-ia32.h   (original)
+++ branches/bleeding_edge/src/codegen-ia32.h   Wed Mar 11 03:25:48 2009
@@ -340,6 +340,8 @@
    // Accessors
    Scope* scope() const { return scope_; }

+  // Clearing and generating deferred code.
+  void ClearDeferred();
    void ProcessDeferred();

    bool is_eval() { return is_eval_; }

Modified: branches/bleeding_edge/src/codegen.cc
==============================================================================
--- branches/bleeding_edge/src/codegen.cc       (original)
+++ branches/bleeding_edge/src/codegen.cc       Wed Mar 11 03:25:48 2009
@@ -53,6 +53,13 @@
  }


+void CodeGenerator::ClearDeferred() {
+  for (int i = 0; i < deferred_.length(); i++) {
+    deferred_[i]->Clear();
+  }
+}
+
+
  void CodeGenerator::ProcessDeferred() {
    while (!deferred_.is_empty()) {
      DeferredCode* code = deferred_.RemoveLast();
@@ -66,6 +73,7 @@
      Comment cmnt(masm, code->comment());
      code->Generate();
      ASSERT(code->enter()->is_bound());
+    code->Clear();
    }
  }


Modified: branches/bleeding_edge/src/codegen.h
==============================================================================
--- branches/bleeding_edge/src/codegen.h        (original)
+++ branches/bleeding_edge/src/codegen.h        Wed Mar 11 03:25:48 2009
@@ -52,6 +52,7 @@
  // CodeGenerator::CodeGenerator
  // CodeGenerator::~CodeGenerator
  // CodeGenerator::ProcessDeferred
+// CodeGenerator::ClearDeferred
  // CodeGenerator::GenCode
  // CodeGenerator::BuildBoilerplate
  // CodeGenerator::ComputeCallInitialize
@@ -91,6 +92,14 @@
    virtual ~DeferredCode() { }

    virtual void Generate() = 0;
+
+  // Unuse the entry and exit targets, deallocating all virtual frames
+  // held by them.  It will be impossible to emit a (correct) jump
+  // into or out of the deferred code after clearing.
+  void Clear() {
+    enter_.Unuse();
+    exit_.Unuse();
+  }

    MacroAssembler* masm() const { return masm_; }
    CodeGenerator* generator() const { return generator_; }

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to