Author: [email protected]
Date: Thu Mar 19 04:57:18 2009
New Revision: 1546

Modified:
    branches/bleeding_edge/src/disassembler.cc
    branches/bleeding_edge/src/jump-target.cc
    branches/bleeding_edge/src/virtual-frame-ia32.cc
    branches/bleeding_edge/src/virtual-frame.cc
    branches/bleeding_edge/src/virtual-frame.h

Log:
Add a copied flag to virtual frame elements that tells if a copy has
been made of the element.  Set it when copying an element, clear it
when writing to an element marked copied and discovering that it is
not copied.

The copied flags on entry frames are exact.  Preparing a frame for
merging set the copied flags to be exact (to increase the likelihood
of matching the entry frame or another frame).
Review URL: http://codereview.chromium.org/50005

Modified: branches/bleeding_edge/src/disassembler.cc
==============================================================================
--- branches/bleeding_edge/src/disassembler.cc  (original)
+++ branches/bleeding_edge/src/disassembler.cc  Thu Mar 19 04:57:18 2009
@@ -99,7 +99,7 @@
    }
  }

-static const int kOutBufferSize = 1024 + String::kMaxShortPrintLength;
+static const int kOutBufferSize = 2048 + String::kMaxShortPrintLength;
  static const int kRelocInfoPosition = 57;

  static int DecodeIt(FILE* f,

Modified: branches/bleeding_edge/src/jump-target.cc
==============================================================================
--- branches/bleeding_edge/src/jump-target.cc   (original)
+++ branches/bleeding_edge/src/jump-target.cc   Thu Mar 19 04:57:18 2009
@@ -270,6 +270,16 @@
      }
    }

+  // Set the copied flags in the frame to be exact.  This assumes that
+  // the backing store of copies is always lower in the frame.
+  for (int i = 0; i < length; i++) {
+    entry_frame_->elements_[i].clear_copied();
+    if (entry_frame_->elements_[i].is_copy()) {
+      int index = entry_frame_->elements_[i].index();
+      entry_frame_->elements_[index].set_copied();
+    }
+  }
+
    // Fill in the other fields of the entry frame.
    entry_frame_->local_count_ = initial_frame->local_count_;
    entry_frame_->frame_pointer_ = initial_frame->frame_pointer_;

Modified: branches/bleeding_edge/src/virtual-frame-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/virtual-frame-ia32.cc    (original)
+++ branches/bleeding_edge/src/virtual-frame-ia32.cc    Thu Mar 19 04:57:18  
2009
@@ -171,11 +171,10 @@
    MergeMoveRegistersToRegisters(expected);
    MergeMoveMemoryToRegisters(expected);

-  // Fix any sync bit problems from the bottom-up, stopping when we
-  // hit the stack pointer or the top of the frame if the stack
-  // pointer is floating above the frame.
-  int limit = Min(stack_pointer_, elements_.length() - 1);
-  for (int i = 0; i <= limit; i++) {
+  // Fix any sync flag problems from the bottom-up and make the copied
+  // flags exact.  This assumes that the backing store of copies is
+  // always lower in the frame.
+  for (int i = 0; i < elements_.length(); i++) {
      FrameElement source = elements_[i];
      FrameElement target = expected->elements_[i];
      if (source.is_synced() && !target.is_synced()) {
@@ -183,6 +182,10 @@
      } else if (!source.is_synced() && target.is_synced()) {
        SyncElementAt(i);
      }
+    elements_[i].clear_copied();
+    if (elements_[i].is_copy()) {
+      elements_[elements_[i].index()].set_copied();
+    }
    }

    // Adjust the stack point downard if necessary.
@@ -550,6 +553,7 @@
      return copy;
    }

+  elements_[index].clear_copied();
    return FrameElement::InvalidElement();
  }

@@ -569,7 +573,9 @@
        // push that register on top of the frame.  If it is copied,
        // make the first copy the backing store and push a fresh copy
        // on top of the frame.
-      FrameElement copy = AdjustCopies(index);
+      FrameElement copy = original.is_copied()
+                          ? AdjustCopies(index)
+                          : FrameElement::InvalidElement();
        if (copy.is_valid()) {
          // The original element was a copy.  Push the copy of the new
          // backing store.
@@ -593,7 +599,9 @@
        // If the element is not copied, push it on top of the frame.
        // If it is copied, make the first copy be the new backing store
        // and push a fresh copy on top of the frame.
-      FrameElement copy = AdjustCopies(index);
+      FrameElement copy = original.is_copied()
+                          ? AdjustCopies(index)
+                          : FrameElement::InvalidElement();
        if (copy.is_valid()) {
          // The original element was a copy.  Push the copy of the new
          // backing store.
@@ -634,7 +642,8 @@
    FrameElement original = elements_[index];
    // If the stored-to slot may be copied, adjust to preserve the
    // copy-on-write semantics of copied elements.
-  if (original.is_register() || original.is_memory()) {
+  if (original.is_copied() &&
+      (original.is_register() || original.is_memory())) {
      FrameElement ignored = AdjustCopies(index);
    }


Modified: branches/bleeding_edge/src/virtual-frame.cc
==============================================================================
--- branches/bleeding_edge/src/virtual-frame.cc (original)
+++ branches/bleeding_edge/src/virtual-frame.cc Thu Mar 19 04:57:18 2009
@@ -93,9 +93,11 @@
      case FrameElement::REGISTER:
        // All copies are backed by memory or register locations.
        result.type_ =
-          FrameElement::TypeField::encode(FrameElement::COPY) |
-          FrameElement::SyncField::encode(FrameElement::NOT_SYNCED);
+          FrameElement::TypeField::encode(FrameElement::COPY)
+          | FrameElement::IsCopiedField::encode(false)
+          | FrameElement::SyncField::encode(FrameElement::NOT_SYNCED);
        result.data_.index_ = index;
+      elements_[index].set_copied();
        break;

      case FrameElement::INVALID:
@@ -208,11 +210,15 @@
    if (!elements_[index].is_valid()) return;

    SyncElementAt(index);
+  // The element is now in memory.  Its copied flag is preserved.
+  FrameElement new_element = FrameElement::MemoryElement();
+  if (elements_[index].is_copied()) {
+    new_element.set_copied();
+  }
    if (elements_[index].is_register()) {
      Unuse(elements_[index].reg());
    }
-  // The element is now in memory.
-  elements_[index] = FrameElement::MemoryElement();
+  elements_[index] = new_element;
  }


@@ -276,6 +282,11 @@
        ASSERT(source.is_valid());
        elements_[i].clear_sync();
      }
+
+    elements_[i].clear_copied();
+    if (elements_[i].is_copy()) {
+      elements_[elements_[i].index()].set_copied();
+    }
    }
  }

@@ -367,7 +378,8 @@

    // If the original may be a copy, adjust to preserve the copy-on-write
    // semantics of copied elements.
-  if (original.is_register() || original.is_memory()) {
+  if (original.is_copied() &&
+      (original.is_register() || original.is_memory())) {
      FrameElement ignored = AdjustCopies(frame_index);
    }

@@ -523,8 +535,7 @@


  bool FrameElement::Equals(FrameElement other) {
-  if (type() != other.type()) return false;
-  if (is_synced() != other.is_synced()) return false;
+  if (type_ != other.type_) return false;

    if (is_register()) {
      if (!reg().is(other.reg())) return false;
@@ -539,23 +550,25 @@


  bool VirtualFrame::Equals(VirtualFrame* other) {
+#ifdef DEBUG
+  // These are sanity checks in debug builds, but we do not need to
+  // use them to distinguish frames at merge points.
    if (cgen_ != other->cgen_) return false;
    if (masm_ != other->masm_) return false;
-  if (elements_.length() != other->elements_.length()) return false;
-
-  for (int i = 0; i < elements_.length(); i++) {
-    if (!elements_[i].Equals(other->elements_[i])) return false;
-  }
-
    if (parameter_count_ != other->parameter_count_) return false;
    if (local_count_ != other->local_count_) return false;
-  if (stack_pointer_ != other->stack_pointer_) return false;
    if (frame_pointer_ != other->frame_pointer_) return false;

    for (int i = 0; i < kNumRegisters; i++) {
      if (frame_registers_.count(i) != other->frame_registers_.count(i)) {
        return false;
      }
+  }
+  if (elements_.length() != other->elements_.length()) return false;
+#endif
+  if (stack_pointer_ != other->stack_pointer_) return false;
+  for (int i = 0; i < elements_.length(); i++) {
+    if (!elements_[i].Equals(other->elements_[i])) return false;
    }

    return true;

Modified: branches/bleeding_edge/src/virtual-frame.h
==============================================================================
--- branches/bleeding_edge/src/virtual-frame.h  (original)
+++ branches/bleeding_edge/src/virtual-frame.h  Thu Mar 19 04:57:18 2009
@@ -101,6 +101,16 @@
    bool is_constant() const { return type() == CONSTANT; }
    bool is_copy() const { return type() == COPY; }

+  bool is_copied() const { return IsCopiedField::decode(type_); }
+
+  void set_copied() {
+    type_ = (type_ & ~IsCopiedField::mask()) | IsCopiedField::encode(true);
+  }
+
+  void clear_copied() {
+    type_ = (type_ & ~IsCopiedField::mask()) |  
IsCopiedField::encode(false);
+  }
+
    Register reg() const {
      ASSERT(is_register());
      return data_.reg_;
@@ -129,7 +139,8 @@

    // BitField is <type, shift, size>.
    class SyncField : public BitField<SyncFlag, 0, 1> {};
-  class TypeField : public BitField<Type, 1, 32 - 1> {};
+  class IsCopiedField : public BitField<bool, 1, 1> {};
+  class TypeField : public BitField<Type, 2, 32 - 2> {};

    Type type() const { return TypeField::decode(type_); }

@@ -144,10 +155,6 @@
      int index_;
    } data_;

-  // The index of the next element in a list of copies, or the frame's
-  // illegal index if there is no next element.
-  int next_;
-
    // Used to construct memory and register elements.
    FrameElement(Type type, Register reg, SyncFlag is_synced) {
      Initialize(type, reg, is_synced);
@@ -175,16 +182,18 @@
  namespace v8 { namespace internal {

  FrameElement::FrameElement(Handle<Object> value, SyncFlag is_synced) {
-  type_ = TypeField::encode(CONSTANT) | SyncField::encode(is_synced);
+  type_ = TypeField::encode(CONSTANT)
+          | IsCopiedField::encode(false)
+          | SyncField::encode(is_synced);
    data_.handle_ = value.location();
-  next_ = VirtualFrame::kIllegalIndex;
  }


  void FrameElement::Initialize(Type type, Register reg, SyncFlag is_synced)  
{
-  type_ = TypeField::encode(type) | SyncField::encode(is_synced);
+  type_ = TypeField::encode(type)
+          | IsCopiedField::encode(false)
+          | SyncField::encode(is_synced);
    data_.reg_ = reg;
-  next_ = VirtualFrame::kIllegalIndex;
  }



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

Reply via email to