| 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 27 matching lines...) Expand all Loading... |
| 38 #include "arm/register-allocator-arm.h" | 38 #include "arm/register-allocator-arm.h" |
| 39 #else | 39 #else |
| 40 #error Unsupported target architecture. | 40 #error Unsupported target architecture. |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 namespace v8 { | 43 namespace v8 { |
| 44 namespace internal { | 44 namespace internal { |
| 45 | 45 |
| 46 | 46 |
| 47 // ------------------------------------------------------------------------- | 47 // ------------------------------------------------------------------------- |
| 48 // StaticType | |
| 49 // | |
| 50 // StaticType represent the type of an expression or a word at runtime. | |
| 51 // The types are ordered by knowledge, so that if a value can come about | |
| 52 // in more than one way, and there are different static types inferred | |
| 53 // for the different ways, the types can be combined to a type that we | |
| 54 // are still certain of (possibly just "unknown"). | |
| 55 | |
| 56 class StaticType BASE_EMBEDDED { | |
| 57 public: | |
| 58 StaticType() : static_type_(UNKNOWN_TYPE) {} | |
| 59 | |
| 60 static StaticType unknown() { return StaticType(); } | |
| 61 static StaticType smi() { return StaticType(SMI_TYPE); } | |
| 62 static StaticType jsstring() { return StaticType(STRING_TYPE); } | |
| 63 static StaticType heap_object() { return StaticType(HEAP_OBJECT_TYPE); } | |
| 64 | |
| 65 // Accessors | |
| 66 bool is_unknown() { return static_type_ == UNKNOWN_TYPE; } | |
| 67 bool is_smi() { return static_type_ == SMI_TYPE; } | |
| 68 bool is_heap_object() { return (static_type_ & HEAP_OBJECT_TYPE) != 0; } | |
| 69 bool is_jsstring() { return static_type_ == STRING_TYPE; } | |
| 70 | |
| 71 bool operator==(StaticType other) const { | |
| 72 return static_type_ == other.static_type_; | |
| 73 } | |
| 74 | |
| 75 // Find the best approximating type for a value. | |
| 76 // The argument must not be NULL. | |
| 77 static StaticType TypeOf(Object* object) { | |
| 78 // Remember to make the most specific tests first. A string is also a heap | |
| 79 // object, so test for string-ness first. | |
| 80 if (object->IsSmi()) return smi(); | |
| 81 if (object->IsString()) return jsstring(); | |
| 82 if (object->IsHeapObject()) return heap_object(); | |
| 83 return unknown(); | |
| 84 } | |
| 85 | |
| 86 // Merges two static types to a type that combines the knowledge | |
| 87 // of both. If there is no way to combine (e.g., being a string *and* | |
| 88 // being a smi), the resulting type is unknown. | |
| 89 StaticType merge(StaticType other) { | |
| 90 StaticType x( | |
| 91 static_cast<StaticTypeEnum>(static_type_ & other.static_type_)); | |
| 92 return x; | |
| 93 } | |
| 94 | |
| 95 private: | |
| 96 enum StaticTypeEnum { | |
| 97 // Numbers are chosen so that least upper bound of the following | |
| 98 // partial order is implemented by bitwise "and": | |
| 99 // | |
| 100 // string | |
| 101 // | | |
| 102 // heap-object smi | |
| 103 // \ / | |
| 104 // unknown | |
| 105 // | |
| 106 UNKNOWN_TYPE = 0x00, | |
| 107 SMI_TYPE = 0x01, | |
| 108 HEAP_OBJECT_TYPE = 0x02, | |
| 109 STRING_TYPE = 0x04 | HEAP_OBJECT_TYPE | |
| 110 }; | |
| 111 explicit StaticType(StaticTypeEnum static_type) : static_type_(static_type) {} | |
| 112 | |
| 113 // StaticTypeEnum static_type_; | |
| 114 StaticTypeEnum static_type_; | |
| 115 | |
| 116 friend class FrameElement; | |
| 117 friend class Result; | |
| 118 }; | |
| 119 | |
| 120 | |
| 121 // ------------------------------------------------------------------------- | |
| 122 // Results | 48 // Results |
| 123 // | 49 // |
| 124 // Results encapsulate the compile-time values manipulated by the code | 50 // Results encapsulate the compile-time values manipulated by the code |
| 125 // generator. They can represent registers or constants. | 51 // generator. They can represent registers or constants. |
| 126 | 52 |
| 127 class Result BASE_EMBEDDED { | 53 class Result BASE_EMBEDDED { |
| 128 public: | 54 public: |
| 129 enum Type { | 55 enum Type { |
| 130 INVALID, | 56 INVALID, |
| 131 REGISTER, | 57 REGISTER, |
| 132 CONSTANT | 58 CONSTANT |
| 133 }; | 59 }; |
| 134 | 60 |
| 135 // Construct an invalid result. | 61 // Construct an invalid result. |
| 136 Result() { invalidate(); } | 62 Result() { invalidate(); } |
| 137 | 63 |
| 138 // Construct a register Result. | 64 // Construct a register Result. |
| 139 explicit Result(Register reg); | 65 explicit Result(Register reg); |
| 140 | 66 |
| 141 // Construct a register Result with a known static type. | |
| 142 Result(Register reg, StaticType static_type); | |
| 143 | |
| 144 // Construct a Result whose value is a compile-time constant. | 67 // Construct a Result whose value is a compile-time constant. |
| 145 explicit Result(Handle<Object> value) { | 68 explicit Result(Handle<Object> value) { |
| 146 value_ = StaticTypeField::encode(StaticType::TypeOf(*value).static_type_) | 69 value_ = TypeField::encode(CONSTANT) |
| 147 | TypeField::encode(CONSTANT) | |
| 148 | DataField::encode(ConstantList()->length()); | 70 | DataField::encode(ConstantList()->length()); |
| 149 ConstantList()->Add(value); | 71 ConstantList()->Add(value); |
| 150 } | 72 } |
| 151 | 73 |
| 152 // The copy constructor and assignment operators could each create a new | 74 // The copy constructor and assignment operators could each create a new |
| 153 // register reference. | 75 // register reference. |
| 154 Result(const Result& other) { | 76 Result(const Result& other) { |
| 155 other.CopyTo(this); | 77 other.CopyTo(this); |
| 156 } | 78 } |
| 157 | 79 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 175 return &list; | 97 return &list; |
| 176 } | 98 } |
| 177 | 99 |
| 178 // Clear the constants indirection table. | 100 // Clear the constants indirection table. |
| 179 static void ClearConstantList() { | 101 static void ClearConstantList() { |
| 180 ConstantList()->Clear(); | 102 ConstantList()->Clear(); |
| 181 } | 103 } |
| 182 | 104 |
| 183 inline void Unuse(); | 105 inline void Unuse(); |
| 184 | 106 |
| 185 StaticType static_type() const { | |
| 186 return StaticType(StaticTypeField::decode(value_)); | |
| 187 } | |
| 188 | |
| 189 void set_static_type(StaticType type) { | |
| 190 value_ = value_ & ~StaticTypeField::mask(); | |
| 191 value_ = value_ | StaticTypeField::encode(type.static_type_); | |
| 192 } | |
| 193 | |
| 194 Type type() const { return TypeField::decode(value_); } | 107 Type type() const { return TypeField::decode(value_); } |
| 195 | 108 |
| 196 void invalidate() { value_ = TypeField::encode(INVALID); } | 109 void invalidate() { value_ = TypeField::encode(INVALID); } |
| 197 | 110 |
| 198 bool is_valid() const { return type() != INVALID; } | 111 bool is_valid() const { return type() != INVALID; } |
| 199 bool is_register() const { return type() == REGISTER; } | 112 bool is_register() const { return type() == REGISTER; } |
| 200 bool is_constant() const { return type() == CONSTANT; } | 113 bool is_constant() const { return type() == CONSTANT; } |
| 201 | 114 |
| 202 Register reg() const { | 115 Register reg() const { |
| 203 ASSERT(is_register()); | 116 ASSERT(is_register()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 218 void ToRegister(); | 131 void ToRegister(); |
| 219 | 132 |
| 220 // Move this result to a specified register. The register is spilled from | 133 // Move this result to a specified register. The register is spilled from |
| 221 // the frame, and the register is singly-referenced (by this result) | 134 // the frame, and the register is singly-referenced (by this result) |
| 222 // outside the frame. | 135 // outside the frame. |
| 223 void ToRegister(Register reg); | 136 void ToRegister(Register reg); |
| 224 | 137 |
| 225 private: | 138 private: |
| 226 uint32_t value_; | 139 uint32_t value_; |
| 227 | 140 |
| 228 class StaticTypeField: public BitField<StaticType::StaticTypeEnum, 0, 3> {}; | 141 class TypeField: public BitField<Type, 0, 2> {}; |
| 229 class TypeField: public BitField<Type, 3, 2> {}; | 142 class DataField: public BitField<uint32_t, 2, 32 - 3> {}; |
| 230 class DataField: public BitField<uint32_t, 5, 32 - 6> {}; | |
| 231 | 143 |
| 232 inline void CopyTo(Result* destination) const; | 144 inline void CopyTo(Result* destination) const; |
| 233 | 145 |
| 234 friend class CodeGeneratorScope; | 146 friend class CodeGeneratorScope; |
| 235 }; | 147 }; |
| 236 | 148 |
| 237 | 149 |
| 238 // ------------------------------------------------------------------------- | 150 // ------------------------------------------------------------------------- |
| 239 // Register file | 151 // Register file |
| 240 // | 152 // |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 } | 289 } |
| 378 | 290 |
| 379 private: | 291 private: |
| 380 CodeGenerator* cgen_; | 292 CodeGenerator* cgen_; |
| 381 RegisterFile registers_; | 293 RegisterFile registers_; |
| 382 }; | 294 }; |
| 383 | 295 |
| 384 } } // namespace v8::internal | 296 } } // namespace v8::internal |
| 385 | 297 |
| 386 #endif // V8_REGISTER_ALLOCATOR_H_ | 298 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |