| OLD | NEW |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 14 matching lines...) Expand all Loading... |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_REGISTER_ALLOCATOR_H_ | 28 #ifndef V8_REGISTER_ALLOCATOR_H_ |
| 29 #define V8_REGISTER_ALLOCATOR_H_ | 29 #define V8_REGISTER_ALLOCATOR_H_ |
| 30 | 30 |
| 31 #include "macro-assembler.h" | 31 #include "macro-assembler.h" |
| 32 | 32 |
| 33 namespace v8 { namespace internal { | 33 namespace v8 { namespace internal { |
| 34 | 34 |
| 35 |
| 36 // ------------------------------------------------------------------------- |
| 37 // StaticType |
| 38 // |
| 39 // StaticType represent the type of an expression or a word at runtime. |
| 40 // The types are ordered by knowledge, so that if a value can come about |
| 41 // in more than one way, and there are different static types inferred |
| 42 // for the different ways, the types can be combined to a type that we |
| 43 // are still certain of (possibly just "unknown"). |
| 44 |
| 45 class StaticType BASE_EMBEDDED { |
| 46 public: |
| 47 StaticType() : static_type_(UNKNOWN_TYPE) {} |
| 48 |
| 49 static StaticType unknown() { return StaticType(); } |
| 50 static StaticType smi() { return StaticType(SMI_TYPE); } |
| 51 static StaticType jsstring() { return StaticType(STRING_TYPE); } |
| 52 static StaticType heap_object() { return StaticType(HEAP_OBJECT_TYPE); } |
| 53 |
| 54 // Accessors |
| 55 bool is_unknown() { return static_type_ == UNKNOWN_TYPE; } |
| 56 bool is_smi() { return static_type_ == SMI_TYPE; } |
| 57 bool is_heap_object() { return (static_type_ & HEAP_OBJECT_TYPE) != 0; } |
| 58 bool is_jsstring() { return static_type_ == STRING_TYPE; } |
| 59 |
| 60 bool operator==(StaticType other) const { |
| 61 return static_type_ == other.static_type_; |
| 62 } |
| 63 |
| 64 // Find the best approximating type for a value. |
| 65 // The argument must not be NULL. |
| 66 static StaticType TypeOf(Object* object) { |
| 67 // Remember to make the most specific tests first. A string is also a heap |
| 68 // object, so test for string-ness first. |
| 69 if (object->IsSmi()) return smi(); |
| 70 if (object->IsString()) return jsstring(); |
| 71 if (object->IsHeapObject()) return heap_object(); |
| 72 return unknown(); |
| 73 } |
| 74 |
| 75 // Merges two static types to a type that combines the knowledge |
| 76 // of both. If there is no way to combine (e.g., being a string *and* |
| 77 // being a smi), the resulting type is unknown. |
| 78 StaticType merge(StaticType other) { |
| 79 StaticType x( |
| 80 static_cast<StaticTypeEnum>(static_type_ & other.static_type_)); |
| 81 return x; |
| 82 } |
| 83 |
| 84 private: |
| 85 enum StaticTypeEnum { |
| 86 // Numbers are chosen so that least upper bound of the following |
| 87 // partial order is implemented by bitwise "and": |
| 88 // |
| 89 // string |
| 90 // | |
| 91 // heap-object smi |
| 92 // \ / |
| 93 // unknown |
| 94 // |
| 95 UNKNOWN_TYPE = 0x00, |
| 96 SMI_TYPE = 0x01, |
| 97 HEAP_OBJECT_TYPE = 0x02, |
| 98 STRING_TYPE = 0x04 | HEAP_OBJECT_TYPE |
| 99 }; |
| 100 explicit StaticType(StaticTypeEnum static_type) : static_type_(static_type) {} |
| 101 |
| 102 // StaticTypeEnum static_type_; |
| 103 byte static_type_; |
| 104 }; |
| 105 |
| 106 |
| 35 // ------------------------------------------------------------------------- | 107 // ------------------------------------------------------------------------- |
| 36 // Results | 108 // Results |
| 37 // | 109 // |
| 38 // Results encapsulate the compile-time values manipulated by the code | 110 // Results encapsulate the compile-time values manipulated by the code |
| 39 // generator. They can represent registers or constants. | 111 // generator. They can represent registers or constants. |
| 40 | 112 |
| 41 class Result BASE_EMBEDDED { | 113 class Result BASE_EMBEDDED { |
| 42 public: | 114 public: |
| 43 enum Type { | 115 enum Type { |
| 44 INVALID, | 116 INVALID, |
| 45 REGISTER, | 117 REGISTER, |
| 46 CONSTANT | 118 CONSTANT |
| 47 }; | 119 }; |
| 48 | 120 |
| 49 // Construct an invalid result. | 121 // Construct an invalid result. |
| 50 explicit Result(CodeGenerator* cgen) : type_(INVALID), cgen_(cgen) {} | 122 explicit Result(CodeGenerator* cgen) |
| 123 : static_type_(), |
| 124 type_(INVALID), |
| 125 cgen_(cgen) {} |
| 51 | 126 |
| 52 // Construct a register Result. | 127 // Construct a register Result. |
| 53 Result(Register reg, CodeGenerator* cgen); | 128 Result(Register reg, |
| 129 CodeGenerator* cgen); |
| 130 |
| 131 // Construct a register Result with a known static type. |
| 132 Result(Register reg, |
| 133 CodeGenerator* cgen, |
| 134 StaticType static_type); |
| 54 | 135 |
| 55 // Construct a Result whose value is a compile-time constant. | 136 // Construct a Result whose value is a compile-time constant. |
| 56 Result(Handle<Object> value, CodeGenerator * cgen) | 137 Result(Handle<Object> value, CodeGenerator * cgen) |
| 57 : type_(CONSTANT), | 138 : static_type_(StaticType::TypeOf(*value)), |
| 139 type_(CONSTANT), |
| 58 cgen_(cgen) { | 140 cgen_(cgen) { |
| 59 data_.handle_ = value.location(); | 141 data_.handle_ = value.location(); |
| 60 } | 142 } |
| 61 | 143 |
| 62 // The copy constructor and assignment operators could each create a new | 144 // The copy constructor and assignment operators could each create a new |
| 63 // register reference. | 145 // register reference. |
| 64 Result(const Result& other) { | 146 Result(const Result& other) { |
| 65 other.CopyTo(this); | 147 other.CopyTo(this); |
| 66 } | 148 } |
| 67 | 149 |
| 68 Result& operator=(const Result& other) { | 150 Result& operator=(const Result& other) { |
| 69 if (this != &other) { | 151 if (this != &other) { |
| 70 Unuse(); | 152 Unuse(); |
| 71 other.CopyTo(this); | 153 other.CopyTo(this); |
| 72 } | 154 } |
| 73 return *this; | 155 return *this; |
| 74 } | 156 } |
| 75 | 157 |
| 76 inline ~Result(); | 158 inline ~Result(); |
| 77 | 159 |
| 78 inline void Unuse(); | 160 inline void Unuse(); |
| 79 | 161 |
| 80 Type type() const { return type_; } | 162 StaticType static_type() const { return static_type_; } |
| 163 void set_static_type(StaticType static_type) { static_type_ = static_type; } |
| 164 |
| 165 Type type() const { return static_cast<Type>(type_); } |
| 81 | 166 |
| 82 bool is_valid() const { return type() != INVALID; } | 167 bool is_valid() const { return type() != INVALID; } |
| 83 bool is_register() const { return type() == REGISTER; } | 168 bool is_register() const { return type() == REGISTER; } |
| 84 bool is_constant() const { return type() == CONSTANT; } | 169 bool is_constant() const { return type() == CONSTANT; } |
| 85 | 170 |
| 86 Register reg() const { | 171 Register reg() const { |
| 87 ASSERT(type() == REGISTER); | 172 ASSERT(type() == REGISTER); |
| 88 return data_.reg_; | 173 return data_.reg_; |
| 89 } | 174 } |
| 90 | 175 |
| 91 Handle<Object> handle() const { | 176 Handle<Object> handle() const { |
| 92 ASSERT(type() == CONSTANT); | 177 ASSERT(type() == CONSTANT); |
| 93 return Handle<Object>(data_.handle_); | 178 return Handle<Object>(data_.handle_); |
| 94 } | 179 } |
| 95 | 180 |
| 96 // Move this result to an arbitrary register. The register is not | 181 // Move this result to an arbitrary register. The register is not |
| 97 // necessarily spilled from the frame or even singly-referenced outside | 182 // necessarily spilled from the frame or even singly-referenced outside |
| 98 // it. | 183 // it. |
| 99 void ToRegister(); | 184 void ToRegister(); |
| 100 | 185 |
| 101 // Move this result to a specified register. The register is spilled from | 186 // Move this result to a specified register. The register is spilled from |
| 102 // the frame, and the register is singly-referenced (by this result) | 187 // the frame, and the register is singly-referenced (by this result) |
| 103 // outside the frame. | 188 // outside the frame. |
| 104 void ToRegister(Register reg); | 189 void ToRegister(Register reg); |
| 105 | 190 |
| 106 private: | 191 private: |
| 107 Type type_; | 192 StaticType static_type_; |
| 193 byte type_; |
| 108 | 194 |
| 109 union { | 195 union { |
| 110 Register reg_; | 196 Register reg_; |
| 111 Object** handle_; | 197 Object** handle_; |
| 112 } data_; | 198 } data_; |
| 113 | 199 |
| 114 CodeGenerator* cgen_; | 200 CodeGenerator* cgen_; |
| 115 | 201 |
| 116 void CopyTo(Result* destination) const; | 202 void CopyTo(Result* destination) const; |
| 117 }; | 203 }; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 } | 324 } |
| 239 | 325 |
| 240 private: | 326 private: |
| 241 CodeGenerator* cgen_; | 327 CodeGenerator* cgen_; |
| 242 RegisterFile registers_; | 328 RegisterFile registers_; |
| 243 }; | 329 }; |
| 244 | 330 |
| 245 } } // namespace v8::internal | 331 } } // namespace v8::internal |
| 246 | 332 |
| 247 #endif // V8_REGISTER_ALLOCATOR_H_ | 333 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |