| 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 | 
|---|