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 |