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 19 matching lines...) Expand all Loading... |
30 #if defined(V8_TARGET_ARCH_X64) | 30 #if defined(V8_TARGET_ARCH_X64) |
31 | 31 |
32 #include "x64/lithium-codegen-x64.h" | 32 #include "x64/lithium-codegen-x64.h" |
33 #include "code-stubs.h" | 33 #include "code-stubs.h" |
34 #include "stub-cache.h" | 34 #include "stub-cache.h" |
35 | 35 |
36 namespace v8 { | 36 namespace v8 { |
37 namespace internal { | 37 namespace internal { |
38 | 38 |
39 | 39 |
| 40 class LGapNode: public ZoneObject { |
| 41 public: |
| 42 explicit LGapNode(LOperand* operand) |
| 43 : operand_(operand), resolved_(false), visited_id_(-1) { } |
| 44 |
| 45 LOperand* operand() const { return operand_; } |
| 46 bool IsResolved() const { return !IsAssigned() || resolved_; } |
| 47 void MarkResolved() { |
| 48 ASSERT(!IsResolved()); |
| 49 resolved_ = true; |
| 50 } |
| 51 int visited_id() const { return visited_id_; } |
| 52 void set_visited_id(int id) { |
| 53 ASSERT(id > visited_id_); |
| 54 visited_id_ = id; |
| 55 } |
| 56 |
| 57 bool IsAssigned() const { return assigned_from_.is_set(); } |
| 58 LGapNode* assigned_from() const { return assigned_from_.get(); } |
| 59 void set_assigned_from(LGapNode* n) { assigned_from_.set(n); } |
| 60 |
| 61 private: |
| 62 LOperand* operand_; |
| 63 SetOncePointer<LGapNode> assigned_from_; |
| 64 bool resolved_; |
| 65 int visited_id_; |
| 66 }; |
| 67 |
| 68 |
| 69 LGapResolver::LGapResolver() |
| 70 : nodes_(32), |
| 71 identified_cycles_(4), |
| 72 result_(16), |
| 73 next_visited_id_(0) { |
| 74 } |
| 75 |
| 76 |
| 77 const ZoneList<LMoveOperands>* LGapResolver::Resolve( |
| 78 const ZoneList<LMoveOperands>* moves, |
| 79 LOperand* marker_operand) { |
| 80 nodes_.Rewind(0); |
| 81 identified_cycles_.Rewind(0); |
| 82 result_.Rewind(0); |
| 83 next_visited_id_ = 0; |
| 84 |
| 85 for (int i = 0; i < moves->length(); ++i) { |
| 86 LMoveOperands move = moves->at(i); |
| 87 if (!move.IsRedundant()) RegisterMove(move); |
| 88 } |
| 89 |
| 90 for (int i = 0; i < identified_cycles_.length(); ++i) { |
| 91 ResolveCycle(identified_cycles_[i], marker_operand); |
| 92 } |
| 93 |
| 94 int unresolved_nodes; |
| 95 do { |
| 96 unresolved_nodes = 0; |
| 97 for (int j = 0; j < nodes_.length(); j++) { |
| 98 LGapNode* node = nodes_[j]; |
| 99 if (!node->IsResolved() && node->assigned_from()->IsResolved()) { |
| 100 AddResultMove(node->assigned_from(), node); |
| 101 node->MarkResolved(); |
| 102 } |
| 103 if (!node->IsResolved()) ++unresolved_nodes; |
| 104 } |
| 105 } while (unresolved_nodes > 0); |
| 106 return &result_; |
| 107 } |
| 108 |
| 109 |
| 110 void LGapResolver::AddResultMove(LGapNode* from, LGapNode* to) { |
| 111 AddResultMove(from->operand(), to->operand()); |
| 112 } |
| 113 |
| 114 |
| 115 void LGapResolver::AddResultMove(LOperand* from, LOperand* to) { |
| 116 result_.Add(LMoveOperands(from, to)); |
| 117 } |
| 118 |
| 119 |
| 120 void LGapResolver::ResolveCycle(LGapNode* start, LOperand* marker_operand) { |
| 121 ZoneList<LOperand*> cycle_operands(8); |
| 122 cycle_operands.Add(marker_operand); |
| 123 LGapNode* cur = start; |
| 124 do { |
| 125 cur->MarkResolved(); |
| 126 cycle_operands.Add(cur->operand()); |
| 127 cur = cur->assigned_from(); |
| 128 } while (cur != start); |
| 129 cycle_operands.Add(marker_operand); |
| 130 |
| 131 for (int i = cycle_operands.length() - 1; i > 0; --i) { |
| 132 LOperand* from = cycle_operands[i]; |
| 133 LOperand* to = cycle_operands[i - 1]; |
| 134 AddResultMove(from, to); |
| 135 } |
| 136 } |
| 137 |
| 138 |
| 139 bool LGapResolver::CanReach(LGapNode* a, LGapNode* b, int visited_id) { |
| 140 ASSERT(a != b); |
| 141 LGapNode* cur = a; |
| 142 while (cur != b && cur->visited_id() != visited_id && cur->IsAssigned()) { |
| 143 cur->set_visited_id(visited_id); |
| 144 cur = cur->assigned_from(); |
| 145 } |
| 146 |
| 147 return cur == b; |
| 148 } |
| 149 |
| 150 |
| 151 bool LGapResolver::CanReach(LGapNode* a, LGapNode* b) { |
| 152 ASSERT(a != b); |
| 153 return CanReach(a, b, next_visited_id_++); |
| 154 } |
| 155 |
| 156 |
| 157 void LGapResolver::RegisterMove(LMoveOperands move) { |
| 158 if (move.from()->IsConstantOperand()) { |
| 159 // Constant moves should be last in the machine code. Therefore add them |
| 160 // first to the result set. |
| 161 AddResultMove(move.from(), move.to()); |
| 162 } else { |
| 163 LGapNode* from = LookupNode(move.from()); |
| 164 LGapNode* to = LookupNode(move.to()); |
| 165 if (to->IsAssigned() && to->assigned_from() == from) { |
| 166 move.Eliminate(); |
| 167 return; |
| 168 } |
| 169 ASSERT(!to->IsAssigned()); |
| 170 if (CanReach(from, to)) { |
| 171 // This introduces a cycle. Save. |
| 172 identified_cycles_.Add(from); |
| 173 } |
| 174 to->set_assigned_from(from); |
| 175 } |
| 176 } |
| 177 |
| 178 |
| 179 LGapNode* LGapResolver::LookupNode(LOperand* operand) { |
| 180 for (int i = 0; i < nodes_.length(); ++i) { |
| 181 if (nodes_[i]->operand()->Equals(operand)) return nodes_[i]; |
| 182 } |
| 183 |
| 184 // No node found => create a new one. |
| 185 LGapNode* result = new LGapNode(operand); |
| 186 nodes_.Add(result); |
| 187 return result; |
| 188 } |
| 189 |
| 190 |
40 #define __ masm()-> | 191 #define __ masm()-> |
41 | 192 |
42 bool LCodeGen::GenerateCode() { | 193 bool LCodeGen::GenerateCode() { |
43 HPhase phase("Code generation", chunk()); | 194 HPhase phase("Code generation", chunk()); |
44 ASSERT(is_unused()); | 195 ASSERT(is_unused()); |
45 status_ = GENERATING; | 196 status_ = GENERATING; |
46 return GeneratePrologue() && | 197 return GeneratePrologue() && |
47 GenerateBody() && | 198 GenerateBody() && |
48 GenerateDeferredCode() && | 199 GenerateDeferredCode() && |
49 GenerateSafepointTable(); | 200 GenerateSafepointTable(); |
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1159 | 1310 |
1160 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 1311 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
1161 Abort("Unimplemented: %s", "DoOsrEntry"); | 1312 Abort("Unimplemented: %s", "DoOsrEntry"); |
1162 } | 1313 } |
1163 | 1314 |
1164 #undef __ | 1315 #undef __ |
1165 | 1316 |
1166 } } // namespace v8::internal | 1317 } } // namespace v8::internal |
1167 | 1318 |
1168 #endif // V8_TARGET_ARCH_X64 | 1319 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |