Author: whessev8
Date: Wed Dec 17 05:24:43 2008
New Revision: 991

Modified:
    branches/experimental/toiger/src/virtual-frame-ia32.cc
    branches/experimental/toiger/src/virtual-frame-ia32.h

Log:
Factor VirtualFrame::MergeTo() into three functions, for
ease of reading and debugging.

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

Modified: branches/experimental/toiger/src/virtual-frame-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.cc      (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.cc      Wed Dec 17  
05:24:43 2008
@@ -166,42 +166,6 @@
  }


-// Clear the dirty bit for the element at a given index.  This requires
-// writing dirty elements to the actual frame.  We can only allocate space
-// in the actual frame for the virtual element immediately above the stack
-// pointer.
-void VirtualFrame::SyncElementAt(int index) {
-  FrameElement element = elements_[index];
-
-  if (!element.is_synced()) {
-    if (index <= stack_pointer_) {
-      // Write elements below the stack pointer to their (already  
allocated)
-      // actual frame location.
-      if (element.is_constant()) {
-        __ Set(Operand(ebp, fp_relative(index)),  
Immediate(element.handle()));
-      } else {
-        ASSERT(element.is_register());
-        __ mov(Operand(ebp, fp_relative(index)), element.reg());
-      }
-    } else {
-      // Push elements above the stack pointer to allocate space and sync
-      // them.  Space should have already been allocated in the actual  
frame
-      // for all the elements below this one.
-      ASSERT(index == stack_pointer_ + 1);
-      stack_pointer_++;
-      if (element.is_constant()) {
-        __ push(Immediate(element.handle()));
-      } else {
-        ASSERT(element.is_register());
-        __ push(element.reg());
-      }
-    }
-
-    elements_[index].set_sync();
-  }
-}
-
-
  // Spill any register if possible, making its reference count zero.
  Register VirtualFrame::SpillAnyRegister() {
    // Find the leftmost (ordered by register code), least
@@ -243,21 +207,16 @@
  }


-// Spill an element, making its type be MEMORY.  If it is a register the
-// reference count is not decremented, so it must be done externally.
+// Spill an element, making its type be MEMORY.
+// Does not decrement usage counts, if element is a register.
  void VirtualFrame::RawSpillElementAt(int index) {
-  if (index > stack_pointer_ + 1) {
-    SyncRange(stack_pointer_ + 1, index);
-  }
    SyncElementAt(index);
    // The element is now in memory.
    elements_[index] = FrameElement::MemoryElement();
  }


-// Make the type of the element at a given index be MEMORY.  We can only
-// allocate space in the actual frame for the virtual element immediately
-// above the stack pointer.
+// Make the type of the element at a given index be MEMORY.
  void VirtualFrame::SpillElementAt(int index) {
    if (elements_[index].is_register()) {
      Unuse(elements_[index].reg());
@@ -266,16 +225,60 @@
  }


+// Clear the dirty bit for the element at a given index.
+// The element must be on the physical stack, or the first
+// element below the stack pointer (created by a single push).
+void VirtualFrame::RawSyncElementAt(int index) {
+  FrameElement element = elements_[index];
+
+  if (!element.is_synced()) {
+    if (index <= stack_pointer_) {
+      // Write elements below the stack pointer to their (already  
allocated)
+      // actual frame location.
+      if (element.is_constant()) {
+        __ Set(Operand(ebp, fp_relative(index)),  
Immediate(element.handle()));
+      } else {
+        ASSERT(element.is_register());
+        __ mov(Operand(ebp, fp_relative(index)), element.reg());
+      }
+    } else {
+      // Push elements above the stack pointer to allocate space and sync
+      // them.  Space should have already been allocated in the actual  
frame
+      // for all the elements below this one.
+      ASSERT(index == stack_pointer_ + 1);
+      stack_pointer_++;
+      if (element.is_constant()) {
+        __ push(Immediate(element.handle()));
+      } else {
+        ASSERT(element.is_register());
+        __ push(element.reg());
+      }
+    }
+
+    elements_[index].set_sync();
+  }
+}
+
+
  // Clear the dirty bits for the range of elements in [begin, end).
  void VirtualFrame::SyncRange(int begin, int end) {
    ASSERT(begin >= 0);
    ASSERT(end <= elements_.length());
    for (int i = begin; i < end; i++) {
-    SyncElementAt(i);
+    RawSyncElementAt(i);
    }
  }


+// Clear the dirty bit for the element at a given index.
+void VirtualFrame::SyncElementAt(int index) {
+  if (index > stack_pointer_ + 1) {
+    SyncRange(stack_pointer_ + 1, index);
+  }
+  RawSyncElementAt(index);
+}
+
+
  // Make the type of all elements be MEMORY.
  void VirtualFrame::SpillAll() {
    for (int i = 0; i < elements_.length(); i++) {
@@ -453,62 +456,9 @@
    // First perform all to-memory moves, register-to-memory moves because
    // they can free registers and constant-to-memory moves because they do
    // not use registers.
-  for (int i = 0; i < elements_.length(); i++) {
-    FrameElement source = elements_[i];
-    FrameElement target = expected->elements_[i];
-    if (target.is_memory() && !source.is_memory()) {
-      ASSERT(source.is_register() || source.is_constant());
-      SpillElementAt(i);
-    }
-  }
-
+  MergeMoveRegistersToMemory(expected);
    MergeMoveRegistersToRegisters(expected);
-
-  // Finally, constant-to-register and memory-to-register.  We do these  
from
-  // the top down so we can use pop for memory-to-register moves above the
-  // expected stack pointer.
-  for (int i = elements_.length() - 1; i >= 0; i--) {
-    FrameElement source = elements_[i];
-    FrameElement target = expected->elements_[i];
-    if (target.is_register() && !source.is_register()) {
-      ASSERT(source.is_constant() || source.is_memory());
-      if (source.is_memory()) {
-        ASSERT(i <= stack_pointer_);
-        if (i <= expected->stack_pointer_) {
-          // Elements below both stack pointers can just be moved.
-          __ mov(target.reg(), Operand(ebp, fp_relative(i)));
-        } else {
-          // Elements below the current stack pointer but above the  
expected
-          // one can be popped, bet first we may have to adjust the stack
-          // pointer downward.
-          if (stack_pointer_ > i + 1) {
-#ifdef DEBUG
-            // In debug builds check to ensure this is safe.
-            for (int j = stack_pointer_; j > i; j--) {
-              ASSERT(!elements_[j].is_memory());
-            }
-#endif
-            stack_pointer_ = i + 1;
-            __ add(Operand(esp),
-                   Immediate((stack_pointer_ - i) * kPointerSize));
-          }
-          stack_pointer_--;
-          __ pop(target.reg());
-        }
-      } else {
-        // Source is constant.
-        __ Set(target.reg(), Immediate(source.handle()));
-        if (target.is_synced()) {
-          if (i > stack_pointer_) {
-            SyncRange(stack_pointer_ + 1, i);
-          }
-          SyncElementAt(i);
-        }
-      }
-      Use(target.reg());
-      elements_[i] = target;
-    }
-  }
+  MergeMoveMemoryToRegisters(expected);

    // At this point, the frames should be identical.
    ASSERT(stack_pointer_ == expected->stack_pointer_);
@@ -534,12 +484,24 @@
  }


+void VirtualFrame::MergeMoveRegistersToMemory(VirtualFrame *expected) {
+  for (int i = 0; i < elements_.length(); i++) {
+    FrameElement source = elements_[i];
+    FrameElement target = expected->elements_[i];
+    if (target.is_memory() && !source.is_memory()) {
+      ASSERT(source.is_register() || source.is_constant());
+      SpillElementAt(i);
+    }
+  }
+}
+
+
  void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame *expected) {
    int start = 0;
    int end = elements_.length() - 1;
-  bool any_moves_blocked; // Did we fail to make some moves this iteration?
+  bool any_moves_blocked;  // Did we fail to make some moves this  
iteration?
    bool should_break_cycles = false;
-  bool any_moves_made; // Did we make any progress this iteration?
+  bool any_moves_made;  // Did we make any progress this iteration?
    do {
      any_moves_blocked = false;
      any_moves_made = false;
@@ -592,6 +554,54 @@
        end = last_move_blocked;
      }
    } while (any_moves_blocked);
+}
+
+
+void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame *expected) {
+  // Finally, constant-to-register and memory-to-register.  We do these  
from
+  // the top down so we can use pop for memory-to-register moves above the
+  // expected stack pointer.
+  for (int i = elements_.length() - 1; i >= 0; i--) {
+    FrameElement source = elements_[i];
+    FrameElement target = expected->elements_[i];
+    if (target.is_register() && !source.is_register()) {
+      ASSERT(source.is_constant() || source.is_memory());
+      if (source.is_memory()) {
+        ASSERT(i <= stack_pointer_);
+        if (i <= expected->stack_pointer_) {
+          // Elements below both stack pointers can just be moved.
+          __ mov(target.reg(), Operand(ebp, fp_relative(i)));
+        } else {
+          // Elements below the current stack pointer but above the  
expected
+          // one can be popped, but first we may have to adjust the stack
+          // pointer downward.
+          if (stack_pointer_ > i) {
+            // Sync elements between i and stack pointer, and bring
+            // stack pointer down to i.
+#ifdef DEBUG
+            // In debug builds check to ensure this is safe.
+            for (int j = stack_pointer_; j > i; j--) {
+              ASSERT(!elements_[j].is_memory());
+            }
+#endif
+            __ add(Operand(esp),
+                   Immediate((stack_pointer_ - i) * kPointerSize));
+            stack_pointer_ = i;
+            }
+          stack_pointer_--;
+          __ pop(target.reg());
+        }
+      } else {
+        // Source is constant.
+        __ Set(target.reg(), Immediate(source.handle()));
+        if (target.is_synced()) {
+          SyncElementAt(i);
+        }
+      }
+      Use(target.reg());
+      elements_[i] = target;
+    }
+  }
  }



Modified: branches/experimental/toiger/src/virtual-frame-ia32.h
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.h       (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.h       Wed Dec 17  
05:24:43 2008
@@ -478,12 +478,6 @@
    // decrements both the register's internal and external reference counts.
    void Unuse(Register reg);

-  // Sync the element at a particular index---write it to memory if
-  // necessary, but do not free any associated register or forget its value
-  // if constant.  Space should have already been allocated in the actual
-  // frame for all the elements below this one (at least).
-  void SyncElementAt(int index);
-
    // Spill the element at a particular index---write it to memory if
    // necessary, free any associated register, and forget its value if
    // constant.
@@ -493,9 +487,18 @@
    // it was in a register).
    void RawSpillElementAt(int index);

+  // Sync the element at a particular index.  If it is a register or
+  // constant that disagrees with the value on the stack, write it to  
memory.
+  // Keep the element type as register or constant, and clear the dirty  
bit.
+  void SyncElementAt(int index);
+
    // Sync the range of elements in [begin, end).
    void SyncRange(int begin, int end);

+  // Sync a single element, assuming that its index is less than
+  // or equal to stack pointer + 1.
+  void RawSyncElementAt(int index);
+
    // Push a copy of a frame slot (typically a local or parameter) on top of
    // the frame.
    void LoadFrameSlotAt(int index);
@@ -508,6 +511,10 @@
    // arguments to a call) and all registers.
    void PrepareForCall(int count);

+  // Move frame elements currently in registers or constants, that
+  // should be in memory in the expected frame, to memory.
+  void MergeMoveRegistersToMemory(VirtualFrame *expected);
+
    // Make the register-to-register moves necessary to
    // merge this frame with the expected frame.
    // Register to memory moves must already have been made,
@@ -516,6 +523,13 @@
    // created in order to break cycles of register moves.
    // Used in the implementation of MergeTo().
    void MergeMoveRegistersToRegisters(VirtualFrame *expected);
+
+  // Make the memory-to-register and constant-to-register moves
+  // needed to make this frame equal the expected frame.
+  // Called after all register-to-memory and register-to-register
+  // moves have been made.  After this function returns, the frames
+  // should be equal.
+  void MergeMoveMemoryToRegisters(VirtualFrame *expected);
  };



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

Reply via email to