Index: src/arm/lithium-arm.cc |
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc |
index 87efc92c8de37a6c5b3a08e20636a1af7b5175c2..e53e96daa040d0b8caa610142cbc7fcd0dfe9651 100644 |
--- a/src/arm/lithium-arm.cc |
+++ b/src/arm/lithium-arm.cc |
@@ -1,4 +1,4 @@ |
-// Copyright 2010 the V8 project authors. All rights reserved. |
+// Copyright 2011 the V8 project authors. All rights reserved. |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are |
// met: |
@@ -472,151 +472,6 @@ void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) { |
} |
-class LGapNode: public ZoneObject { |
- public: |
- explicit LGapNode(LOperand* operand) |
- : operand_(operand), resolved_(false), visited_id_(-1) { } |
- |
- LOperand* operand() const { return operand_; } |
- bool IsResolved() const { return !IsAssigned() || resolved_; } |
- void MarkResolved() { |
- ASSERT(!IsResolved()); |
- resolved_ = true; |
- } |
- int visited_id() const { return visited_id_; } |
- void set_visited_id(int id) { |
- ASSERT(id > visited_id_); |
- visited_id_ = id; |
- } |
- |
- bool IsAssigned() const { return assigned_from_.is_set(); } |
- LGapNode* assigned_from() const { return assigned_from_.get(); } |
- void set_assigned_from(LGapNode* n) { assigned_from_.set(n); } |
- |
- private: |
- LOperand* operand_; |
- SetOncePointer<LGapNode> assigned_from_; |
- bool resolved_; |
- int visited_id_; |
-}; |
- |
- |
-LGapResolver::LGapResolver(const ZoneList<LMoveOperands>* moves, |
- LOperand* marker_operand) |
- : nodes_(4), |
- identified_cycles_(4), |
- result_(4), |
- marker_operand_(marker_operand), |
- next_visited_id_(0) { |
- for (int i = 0; i < moves->length(); ++i) { |
- LMoveOperands move = moves->at(i); |
- if (!move.IsRedundant()) RegisterMove(move); |
- } |
-} |
- |
- |
-const ZoneList<LMoveOperands>* LGapResolver::ResolveInReverseOrder() { |
- for (int i = 0; i < identified_cycles_.length(); ++i) { |
- ResolveCycle(identified_cycles_[i]); |
- } |
- |
- int unresolved_nodes; |
- do { |
- unresolved_nodes = 0; |
- for (int j = 0; j < nodes_.length(); j++) { |
- LGapNode* node = nodes_[j]; |
- if (!node->IsResolved() && node->assigned_from()->IsResolved()) { |
- AddResultMove(node->assigned_from(), node); |
- node->MarkResolved(); |
- } |
- if (!node->IsResolved()) ++unresolved_nodes; |
- } |
- } while (unresolved_nodes > 0); |
- return &result_; |
-} |
- |
- |
-void LGapResolver::AddResultMove(LGapNode* from, LGapNode* to) { |
- AddResultMove(from->operand(), to->operand()); |
-} |
- |
- |
-void LGapResolver::AddResultMove(LOperand* from, LOperand* to) { |
- result_.Add(LMoveOperands(from, to)); |
-} |
- |
- |
-void LGapResolver::ResolveCycle(LGapNode* start) { |
- ZoneList<LOperand*> circle_operands(8); |
- circle_operands.Add(marker_operand_); |
- LGapNode* cur = start; |
- do { |
- cur->MarkResolved(); |
- circle_operands.Add(cur->operand()); |
- cur = cur->assigned_from(); |
- } while (cur != start); |
- circle_operands.Add(marker_operand_); |
- |
- for (int i = circle_operands.length() - 1; i > 0; --i) { |
- LOperand* from = circle_operands[i]; |
- LOperand* to = circle_operands[i - 1]; |
- AddResultMove(from, to); |
- } |
-} |
- |
- |
-bool LGapResolver::CanReach(LGapNode* a, LGapNode* b, int visited_id) { |
- ASSERT(a != b); |
- LGapNode* cur = a; |
- while (cur != b && cur->visited_id() != visited_id && cur->IsAssigned()) { |
- cur->set_visited_id(visited_id); |
- cur = cur->assigned_from(); |
- } |
- |
- return cur == b; |
-} |
- |
- |
-bool LGapResolver::CanReach(LGapNode* a, LGapNode* b) { |
- ASSERT(a != b); |
- return CanReach(a, b, next_visited_id_++); |
-} |
- |
- |
-void LGapResolver::RegisterMove(LMoveOperands move) { |
- if (move.from()->IsConstantOperand()) { |
- // Constant moves should be last in the machine code. Therefore add them |
- // first to the result set. |
- AddResultMove(move.from(), move.to()); |
- } else { |
- LGapNode* from = LookupNode(move.from()); |
- LGapNode* to = LookupNode(move.to()); |
- if (to->IsAssigned() && to->assigned_from() == from) { |
- move.Eliminate(); |
- return; |
- } |
- ASSERT(!to->IsAssigned()); |
- if (CanReach(from, to)) { |
- // This introduces a circle. Save. |
- identified_cycles_.Add(from); |
- } |
- to->set_assigned_from(from); |
- } |
-} |
- |
- |
-LGapNode* LGapResolver::LookupNode(LOperand* operand) { |
- for (int i = 0; i < nodes_.length(); ++i) { |
- if (nodes_[i]->operand()->Equals(operand)) return nodes_[i]; |
- } |
- |
- // No node found => create a new one. |
- LGapNode* result = new LGapNode(operand); |
- nodes_.Add(result); |
- return result; |
-} |
- |
- |
Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const { |
return HConstant::cast(graph_->LookupValue(operand->index()))->handle(); |
} |
@@ -1289,7 +1144,7 @@ LInstruction* LChunkBuilder::DoCompareMapAndBranch( |
LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
- return DefineAsRegister(new LArgumentsLength(Use(length->value()))); |
+ return DefineAsRegister(new LArgumentsLength(UseRegister(length->value()))); |
} |
@@ -1306,6 +1161,14 @@ LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { |
} |
+LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( |
+ HInstanceOfKnownGlobal* instr) { |
+ LInstruction* result = |
+ new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0)); |
+ return MarkAsCall(DefineFixed(result, r0), instr); |
+} |
+ |
+ |
LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { |
LOperand* function = UseFixed(instr->function(), r1); |
LOperand* receiver = UseFixed(instr->receiver(), r0); |
@@ -1674,7 +1537,7 @@ LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), |
- Use(instr->length()))); |
+ UseRegister(instr->length()))); |
} |
@@ -1754,8 +1617,7 @@ LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { |
LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
LOperand* value = UseRegisterAtStart(instr->value()); |
- LOperand* temp = TempRegister(); |
- LInstruction* result = new LCheckInstanceType(value, temp); |
+ LInstruction* result = new LCheckInstanceType(value); |
return AssignEnvironment(result); |
} |
@@ -1917,7 +1779,7 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
- bool needs_write_barrier = !instr->value()->type().IsSmi(); |
+ bool needs_write_barrier = instr->NeedsWriteBarrier(); |
LOperand* obj = needs_write_barrier |
? UseTempRegister(instr->object()) |
@@ -1927,17 +1789,11 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
? UseTempRegister(instr->value()) |
: UseRegister(instr->value()); |
- // We only need a scratch register if we have a write barrier or we |
- // have a store into the properties array (not in-object-property). |
- LOperand* temp = (!instr->is_in_object() || needs_write_barrier) |
- ? TempRegister() : NULL; |
- |
return new LStoreNamedField(obj, |
instr->name(), |
val, |
instr->is_in_object(), |
instr->offset(), |
- temp, |
needs_write_barrier, |
instr->transition()); |
} |
@@ -2014,14 +1870,14 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
LOperand* arguments = UseRegister(instr->arguments()); |
LOperand* length = UseTempRegister(instr->length()); |
- LOperand* index = Use(instr->index()); |
+ LOperand* index = UseRegister(instr->index()); |
LInstruction* result = new LAccessArgumentsAt(arguments, length, index); |
return DefineAsRegister(AssignEnvironment(result)); |
} |
LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
- LInstruction* result = new LTypeof(Use(instr->value())); |
+ LInstruction* result = new LTypeof(UseRegisterAtStart(instr->value())); |
return MarkAsCall(DefineFixed(result, r0), instr); |
} |