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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 codegen_->RecordSafepoint(pointers_, deoptimization_index_); | 47 codegen_->RecordSafepoint(pointers_, deoptimization_index_); |
48 } | 48 } |
49 | 49 |
50 private: | 50 private: |
51 LCodeGen* codegen_; | 51 LCodeGen* codegen_; |
52 LPointerMap* pointers_; | 52 LPointerMap* pointers_; |
53 int deoptimization_index_; | 53 int deoptimization_index_; |
54 }; | 54 }; |
55 | 55 |
56 | 56 |
| 57 class LGapNode: public ZoneObject { |
| 58 public: |
| 59 explicit LGapNode(LOperand* operand) |
| 60 : operand_(operand), resolved_(false), visited_id_(-1) { } |
| 61 |
| 62 LOperand* operand() const { return operand_; } |
| 63 bool IsResolved() const { return !IsAssigned() || resolved_; } |
| 64 void MarkResolved() { |
| 65 ASSERT(!IsResolved()); |
| 66 resolved_ = true; |
| 67 } |
| 68 int visited_id() const { return visited_id_; } |
| 69 void set_visited_id(int id) { |
| 70 ASSERT(id > visited_id_); |
| 71 visited_id_ = id; |
| 72 } |
| 73 |
| 74 bool IsAssigned() const { return assigned_from_.is_set(); } |
| 75 LGapNode* assigned_from() const { return assigned_from_.get(); } |
| 76 void set_assigned_from(LGapNode* n) { assigned_from_.set(n); } |
| 77 |
| 78 private: |
| 79 LOperand* operand_; |
| 80 SetOncePointer<LGapNode> assigned_from_; |
| 81 bool resolved_; |
| 82 int visited_id_; |
| 83 }; |
| 84 |
| 85 |
| 86 LGapResolver::LGapResolver() |
| 87 : nodes_(32), |
| 88 identified_cycles_(4), |
| 89 result_(16), |
| 90 next_visited_id_(0) { |
| 91 } |
| 92 |
| 93 |
| 94 const ZoneList<LMoveOperands>* LGapResolver::Resolve( |
| 95 const ZoneList<LMoveOperands>* moves, |
| 96 LOperand* marker_operand) { |
| 97 nodes_.Rewind(0); |
| 98 identified_cycles_.Rewind(0); |
| 99 result_.Rewind(0); |
| 100 next_visited_id_ = 0; |
| 101 |
| 102 for (int i = 0; i < moves->length(); ++i) { |
| 103 LMoveOperands move = moves->at(i); |
| 104 if (!move.IsRedundant()) RegisterMove(move); |
| 105 } |
| 106 |
| 107 for (int i = 0; i < identified_cycles_.length(); ++i) { |
| 108 ResolveCycle(identified_cycles_[i], marker_operand); |
| 109 } |
| 110 |
| 111 int unresolved_nodes; |
| 112 do { |
| 113 unresolved_nodes = 0; |
| 114 for (int j = 0; j < nodes_.length(); j++) { |
| 115 LGapNode* node = nodes_[j]; |
| 116 if (!node->IsResolved() && node->assigned_from()->IsResolved()) { |
| 117 AddResultMove(node->assigned_from(), node); |
| 118 node->MarkResolved(); |
| 119 } |
| 120 if (!node->IsResolved()) ++unresolved_nodes; |
| 121 } |
| 122 } while (unresolved_nodes > 0); |
| 123 return &result_; |
| 124 } |
| 125 |
| 126 |
| 127 void LGapResolver::AddResultMove(LGapNode* from, LGapNode* to) { |
| 128 AddResultMove(from->operand(), to->operand()); |
| 129 } |
| 130 |
| 131 |
| 132 void LGapResolver::AddResultMove(LOperand* from, LOperand* to) { |
| 133 result_.Add(LMoveOperands(from, to)); |
| 134 } |
| 135 |
| 136 |
| 137 void LGapResolver::ResolveCycle(LGapNode* start, LOperand* marker_operand) { |
| 138 ZoneList<LOperand*> cycle_operands(8); |
| 139 cycle_operands.Add(marker_operand); |
| 140 LGapNode* cur = start; |
| 141 do { |
| 142 cur->MarkResolved(); |
| 143 cycle_operands.Add(cur->operand()); |
| 144 cur = cur->assigned_from(); |
| 145 } while (cur != start); |
| 146 cycle_operands.Add(marker_operand); |
| 147 |
| 148 for (int i = cycle_operands.length() - 1; i > 0; --i) { |
| 149 LOperand* from = cycle_operands[i]; |
| 150 LOperand* to = cycle_operands[i - 1]; |
| 151 AddResultMove(from, to); |
| 152 } |
| 153 } |
| 154 |
| 155 |
| 156 bool LGapResolver::CanReach(LGapNode* a, LGapNode* b, int visited_id) { |
| 157 ASSERT(a != b); |
| 158 LGapNode* cur = a; |
| 159 while (cur != b && cur->visited_id() != visited_id && cur->IsAssigned()) { |
| 160 cur->set_visited_id(visited_id); |
| 161 cur = cur->assigned_from(); |
| 162 } |
| 163 |
| 164 return cur == b; |
| 165 } |
| 166 |
| 167 |
| 168 bool LGapResolver::CanReach(LGapNode* a, LGapNode* b) { |
| 169 ASSERT(a != b); |
| 170 return CanReach(a, b, next_visited_id_++); |
| 171 } |
| 172 |
| 173 |
| 174 void LGapResolver::RegisterMove(LMoveOperands move) { |
| 175 if (move.from()->IsConstantOperand()) { |
| 176 // Constant moves should be last in the machine code. Therefore add them |
| 177 // first to the result set. |
| 178 AddResultMove(move.from(), move.to()); |
| 179 } else { |
| 180 LGapNode* from = LookupNode(move.from()); |
| 181 LGapNode* to = LookupNode(move.to()); |
| 182 if (to->IsAssigned() && to->assigned_from() == from) { |
| 183 move.Eliminate(); |
| 184 return; |
| 185 } |
| 186 ASSERT(!to->IsAssigned()); |
| 187 if (CanReach(from, to)) { |
| 188 // This introduces a cycle. Save. |
| 189 identified_cycles_.Add(from); |
| 190 } |
| 191 to->set_assigned_from(from); |
| 192 } |
| 193 } |
| 194 |
| 195 |
| 196 LGapNode* LGapResolver::LookupNode(LOperand* operand) { |
| 197 for (int i = 0; i < nodes_.length(); ++i) { |
| 198 if (nodes_[i]->operand()->Equals(operand)) return nodes_[i]; |
| 199 } |
| 200 |
| 201 // No node found => create a new one. |
| 202 LGapNode* result = new LGapNode(operand); |
| 203 nodes_.Add(result); |
| 204 return result; |
| 205 } |
| 206 |
| 207 |
57 #define __ masm()-> | 208 #define __ masm()-> |
58 | 209 |
59 bool LCodeGen::GenerateCode() { | 210 bool LCodeGen::GenerateCode() { |
60 HPhase phase("Code generation", chunk()); | 211 HPhase phase("Code generation", chunk()); |
61 ASSERT(is_unused()); | 212 ASSERT(is_unused()); |
62 status_ = GENERATING; | 213 status_ = GENERATING; |
63 CpuFeatures::Scope scope1(VFP3); | 214 CpuFeatures::Scope scope1(VFP3); |
64 CpuFeatures::Scope scope2(ARMv7); | 215 CpuFeatures::Scope scope2(ARMv7); |
65 return GeneratePrologue() && | 216 return GeneratePrologue() && |
66 GenerateBody() && | 217 GenerateBody() && |
(...skipping 2906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2973 | 3124 |
2974 | 3125 |
2975 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 3126 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
2976 Abort("DoOsrEntry unimplemented."); | 3127 Abort("DoOsrEntry unimplemented."); |
2977 } | 3128 } |
2978 | 3129 |
2979 | 3130 |
2980 #undef __ | 3131 #undef __ |
2981 | 3132 |
2982 } } // namespace v8::internal | 3133 } } // namespace v8::internal |
OLD | NEW |