OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 codegen_->RecordSafepoint(pointers_, deoptimization_index_); | 51 codegen_->RecordSafepoint(pointers_, deoptimization_index_); |
52 } | 52 } |
53 | 53 |
54 private: | 54 private: |
55 LCodeGen* codegen_; | 55 LCodeGen* codegen_; |
56 LPointerMap* pointers_; | 56 LPointerMap* pointers_; |
57 int deoptimization_index_; | 57 int deoptimization_index_; |
58 }; | 58 }; |
59 | 59 |
60 | 60 |
| 61 class LGapNode: public ZoneObject { |
| 62 public: |
| 63 explicit LGapNode(LOperand* operand) |
| 64 : operand_(operand), resolved_(false), visited_id_(-1) { } |
| 65 |
| 66 LOperand* operand() const { return operand_; } |
| 67 bool IsResolved() const { return !IsAssigned() || resolved_; } |
| 68 void MarkResolved() { |
| 69 ASSERT(!IsResolved()); |
| 70 resolved_ = true; |
| 71 } |
| 72 int visited_id() const { return visited_id_; } |
| 73 void set_visited_id(int id) { |
| 74 ASSERT(id > visited_id_); |
| 75 visited_id_ = id; |
| 76 } |
| 77 |
| 78 bool IsAssigned() const { return assigned_from_.is_set(); } |
| 79 LGapNode* assigned_from() const { return assigned_from_.get(); } |
| 80 void set_assigned_from(LGapNode* n) { assigned_from_.set(n); } |
| 81 |
| 82 private: |
| 83 LOperand* operand_; |
| 84 SetOncePointer<LGapNode> assigned_from_; |
| 85 bool resolved_; |
| 86 int visited_id_; |
| 87 }; |
| 88 |
| 89 |
| 90 LGapResolver::LGapResolver() |
| 91 : nodes_(32), |
| 92 identified_cycles_(4), |
| 93 result_(16), |
| 94 next_visited_id_(0) { |
| 95 } |
| 96 |
| 97 |
| 98 const ZoneList<LMoveOperands>* LGapResolver::Resolve( |
| 99 const ZoneList<LMoveOperands>* moves, |
| 100 LOperand* marker_operand) { |
| 101 nodes_.Rewind(0); |
| 102 identified_cycles_.Rewind(0); |
| 103 result_.Rewind(0); |
| 104 next_visited_id_ = 0; |
| 105 |
| 106 for (int i = 0; i < moves->length(); ++i) { |
| 107 LMoveOperands move = moves->at(i); |
| 108 if (!move.IsRedundant()) RegisterMove(move); |
| 109 } |
| 110 |
| 111 for (int i = 0; i < identified_cycles_.length(); ++i) { |
| 112 ResolveCycle(identified_cycles_[i], marker_operand); |
| 113 } |
| 114 |
| 115 int unresolved_nodes; |
| 116 do { |
| 117 unresolved_nodes = 0; |
| 118 for (int j = 0; j < nodes_.length(); j++) { |
| 119 LGapNode* node = nodes_[j]; |
| 120 if (!node->IsResolved() && node->assigned_from()->IsResolved()) { |
| 121 AddResultMove(node->assigned_from(), node); |
| 122 node->MarkResolved(); |
| 123 } |
| 124 if (!node->IsResolved()) ++unresolved_nodes; |
| 125 } |
| 126 } while (unresolved_nodes > 0); |
| 127 return &result_; |
| 128 } |
| 129 |
| 130 |
| 131 void LGapResolver::AddResultMove(LGapNode* from, LGapNode* to) { |
| 132 AddResultMove(from->operand(), to->operand()); |
| 133 } |
| 134 |
| 135 |
| 136 void LGapResolver::AddResultMove(LOperand* from, LOperand* to) { |
| 137 result_.Add(LMoveOperands(from, to)); |
| 138 } |
| 139 |
| 140 |
| 141 void LGapResolver::ResolveCycle(LGapNode* start, LOperand* marker_operand) { |
| 142 ZoneList<LOperand*> cycle_operands(8); |
| 143 cycle_operands.Add(marker_operand); |
| 144 LGapNode* cur = start; |
| 145 do { |
| 146 cur->MarkResolved(); |
| 147 cycle_operands.Add(cur->operand()); |
| 148 cur = cur->assigned_from(); |
| 149 } while (cur != start); |
| 150 cycle_operands.Add(marker_operand); |
| 151 |
| 152 for (int i = cycle_operands.length() - 1; i > 0; --i) { |
| 153 LOperand* from = cycle_operands[i]; |
| 154 LOperand* to = cycle_operands[i - 1]; |
| 155 AddResultMove(from, to); |
| 156 } |
| 157 } |
| 158 |
| 159 |
| 160 bool LGapResolver::CanReach(LGapNode* a, LGapNode* b, int visited_id) { |
| 161 ASSERT(a != b); |
| 162 LGapNode* cur = a; |
| 163 while (cur != b && cur->visited_id() != visited_id && cur->IsAssigned()) { |
| 164 cur->set_visited_id(visited_id); |
| 165 cur = cur->assigned_from(); |
| 166 } |
| 167 |
| 168 return cur == b; |
| 169 } |
| 170 |
| 171 |
| 172 bool LGapResolver::CanReach(LGapNode* a, LGapNode* b) { |
| 173 ASSERT(a != b); |
| 174 return CanReach(a, b, next_visited_id_++); |
| 175 } |
| 176 |
| 177 |
| 178 void LGapResolver::RegisterMove(LMoveOperands move) { |
| 179 if (move.from()->IsConstantOperand()) { |
| 180 // Constant moves should be last in the machine code. Therefore add them |
| 181 // first to the result set. |
| 182 AddResultMove(move.from(), move.to()); |
| 183 } else { |
| 184 LGapNode* from = LookupNode(move.from()); |
| 185 LGapNode* to = LookupNode(move.to()); |
| 186 if (to->IsAssigned() && to->assigned_from() == from) { |
| 187 move.Eliminate(); |
| 188 return; |
| 189 } |
| 190 ASSERT(!to->IsAssigned()); |
| 191 if (CanReach(from, to)) { |
| 192 // This introduces a cycle. Save. |
| 193 identified_cycles_.Add(from); |
| 194 } |
| 195 to->set_assigned_from(from); |
| 196 } |
| 197 } |
| 198 |
| 199 |
| 200 LGapNode* LGapResolver::LookupNode(LOperand* operand) { |
| 201 for (int i = 0; i < nodes_.length(); ++i) { |
| 202 if (nodes_[i]->operand()->Equals(operand)) return nodes_[i]; |
| 203 } |
| 204 |
| 205 // No node found => create a new one. |
| 206 LGapNode* result = new LGapNode(operand); |
| 207 nodes_.Add(result); |
| 208 return result; |
| 209 } |
| 210 |
| 211 |
61 #define __ masm()-> | 212 #define __ masm()-> |
62 | 213 |
63 bool LCodeGen::GenerateCode() { | 214 bool LCodeGen::GenerateCode() { |
64 HPhase phase("Code generation", chunk()); | 215 HPhase phase("Code generation", chunk()); |
65 ASSERT(is_unused()); | 216 ASSERT(is_unused()); |
66 status_ = GENERATING; | 217 status_ = GENERATING; |
67 CpuFeatures::Scope scope(SSE2); | 218 CpuFeatures::Scope scope(SSE2); |
68 return GeneratePrologue() && | 219 return GeneratePrologue() && |
69 GenerateBody() && | 220 GenerateBody() && |
70 GenerateDeferredCode() && | 221 GenerateDeferredCode() && |
(...skipping 3410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3481 ASSERT(osr_pc_offset_ == -1); | 3632 ASSERT(osr_pc_offset_ == -1); |
3482 osr_pc_offset_ = masm()->pc_offset(); | 3633 osr_pc_offset_ = masm()->pc_offset(); |
3483 } | 3634 } |
3484 | 3635 |
3485 | 3636 |
3486 #undef __ | 3637 #undef __ |
3487 | 3638 |
3488 } } // namespace v8::internal | 3639 } } // namespace v8::internal |
3489 | 3640 |
3490 #endif // V8_TARGET_ARCH_IA32 | 3641 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |