Reviewers: fschneider, Sven Panne, Vyacheslav Egorov,

Message:
Please review this patch. Thanks.

Zheng Liu
[email protected]

Description:
Fix potential operand pointer aliasing in LGap after live range split.

BUG=v8:2124

Please review this at http://codereview.chromium.org/10332107/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/

Affected files:
  M     src/lithium-allocator.h
  M     src/lithium-allocator.cc
  M     src/lithium.h


Index: src/lithium-allocator.cc
===================================================================
--- src/lithium-allocator.cc    (revision 11534)
+++ src/lithium-allocator.cc    (working copy)
@@ -271,7 +271,7 @@
 }


-void LiveRange::SplitAt(LifetimePosition position,
+UsePosition* LiveRange::SplitAt(LifetimePosition position,
                         LiveRange* result,
                         Zone* zone) {
   ASSERT(Start().Value() < position.Value());
@@ -354,6 +354,8 @@
   Verify();
   result->Verify();
 #endif
+
+  return use_before;
 }


@@ -1993,7 +1995,26 @@

   LiveRange* result = LiveRangeFor(GetVirtualRegister());
   if (!AllocationOk()) return NULL;
-  range->SplitAt(pos, result, zone_);
+
+  UsePosition* prev_use_pos = range->SplitAt(pos, result, zone_);
+  UsePosition* use_pos = result->first_pos();
+  int index = pos.InstructionIndex();
+  if (prev_use_pos != NULL && use_pos != NULL &&
+          prev_use_pos->operand() == use_pos->operand()) {
+    ASSERT(prev_use_pos->pos().InstructionIndex() == index - 1);
+    LOperand* op = use_pos->operand();
+    LOperand* copy_op = new(zone_) LOperand();
+    copy_op->ConvertTo(op->kind(), op->index());
+
+    /* clone operand, update the operand at LGap */
+    ASSERT(!IsGapAt(index));
+    LParallelMove* move = GapAt(index - 1)->
+        GetOrCreateParallelMove(LGap::START);
+    ASSERT(move->IsOperandUsed(op, LParallelMove::DESTINATION));
+    move->UpdateOperand(op, copy_op, LParallelMove::DESTINATION);
+    prev_use_pos->set_operand(copy_op);
+  }
+
   return result;
 }

Index: src/lithium-allocator.h
===================================================================
--- src/lithium-allocator.h     (revision 11534)
+++ src/lithium-allocator.h     (working copy)
@@ -248,6 +248,7 @@

   LOperand* operand() const { return operand_; }
   bool HasOperand() const { return operand_ != NULL; }
+  void set_operand(LOperand* new_op) { operand_ = new_op; }

   LOperand* hint() const { return hint_; }
   void set_hint(LOperand* hint) { hint_ = hint; }
@@ -318,7 +319,7 @@
   // the range.
   // All uses following the given position will be moved from this
   // live range to the result live range.
-  void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone);
+ UsePosition* SplitAt(LifetimePosition position, LiveRange* result, Zone* zone);

   bool IsDouble() const { return is_double_; }
   bool HasRegisterAssigned() const {
Index: src/lithium.h
===================================================================
--- src/lithium.h       (revision 11534)
+++ src/lithium.h       (working copy)
@@ -404,6 +404,39 @@

   bool IsRedundant() const;

+  enum OperandPosition {
+    SOURCE,
+    DESTINATION
+  };
+
+  bool IsOperandUsed(LOperand* op, OperandPosition dest_or_source) {
+    for (int i = 0; i < move_operands_.length(); i ++) {
+      if (dest_or_source == DESTINATION &&
+              move_operands_[i].destination() == op) {
+        return true;
+      }
+      if (dest_or_source == SOURCE &&
+              move_operands_[i].source() == op) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void UpdateOperand(LOperand* old_op, LOperand* new_op,
+          OperandPosition dest_or_source) {
+    for (int i = 0; i < move_operands_.length(); i ++) {
+      if (dest_or_source == DESTINATION &&
+            move_operands_[i].destination() == old_op) {
+        move_operands_[i].set_destination(new_op);
+      }
+      if (dest_or_source == SOURCE &&
+            move_operands_[i].source() == old_op) {
+        move_operands_[i].set_source(new_op);
+      }
+    }
+  }
+
   const ZoneList<LMoveOperands>* move_operands() const {
     return &move_operands_;
   }


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

Reply via email to