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