OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 // | 88 // |
89 // Internally, all 'primitive' types, and their unions, are represented as | 89 // Internally, all 'primitive' types, and their unions, are represented as |
90 // bitsets via smis. Class is a heap pointer to the respective map. Only | 90 // bitsets via smis. Class is a heap pointer to the respective map. Only |
91 // Constant's, or unions containing Class'es or Constant's, require allocation. | 91 // Constant's, or unions containing Class'es or Constant's, require allocation. |
92 // Note that the bitset representation is closed under both Union and Intersect. | 92 // Note that the bitset representation is closed under both Union and Intersect. |
93 // | 93 // |
94 // The type representation is heap-allocated, so cannot (currently) be used in | 94 // The type representation is heap-allocated, so cannot (currently) be used in |
95 // a concurrent compilation context. | 95 // a concurrent compilation context. |
96 | 96 |
97 | 97 |
98 #define PRIMITIVE_TYPE_LIST(V) \ | 98 #define BITSET_TYPE_LIST(V) \ |
99 V(None, 0) \ | 99 V(None, 0) \ |
100 V(Null, 1 << 0) \ | 100 V(Null, 1 << 0) \ |
101 V(Undefined, 1 << 1) \ | 101 V(Undefined, 1 << 1) \ |
102 V(Boolean, 1 << 2) \ | 102 V(Boolean, 1 << 2) \ |
103 V(Smi, 1 << 3) \ | 103 V(Smi, 1 << 3) \ |
104 V(OtherSigned32, 1 << 4) \ | 104 V(OtherSigned32, 1 << 4) \ |
105 V(Unsigned32, 1 << 5) \ | 105 V(Unsigned32, 1 << 5) \ |
106 V(Double, 1 << 6) \ | 106 V(Double, 1 << 6) \ |
107 V(Symbol, 1 << 7) \ | 107 V(Symbol, 1 << 7) \ |
108 V(InternalizedString, 1 << 8) \ | 108 V(InternalizedString, 1 << 8) \ |
109 V(OtherString, 1 << 9) \ | 109 V(OtherString, 1 << 9) \ |
110 V(Undetectable, 1 << 10) \ | 110 V(Undetectable, 1 << 10) \ |
111 V(Array, 1 << 11) \ | 111 V(Array, 1 << 11) \ |
112 V(Function, 1 << 12) \ | 112 V(Function, 1 << 12) \ |
113 V(RegExp, 1 << 13) \ | 113 V(RegExp, 1 << 13) \ |
114 V(OtherObject, 1 << 14) \ | 114 V(OtherObject, 1 << 14) \ |
115 V(Proxy, 1 << 15) \ | 115 V(Proxy, 1 << 15) \ |
116 V(Internal, 1 << 16) | 116 V(Internal, 1 << 16) \ |
117 | 117 \ |
118 #define COMPOSED_TYPE_LIST(V) \ | |
119 V(Oddball, kBoolean | kNull | kUndefined) \ | 118 V(Oddball, kBoolean | kNull | kUndefined) \ |
120 V(Signed32, kSmi | kOtherSigned32) \ | 119 V(Signed32, kSmi | kOtherSigned32) \ |
121 V(Number, kSigned32 | kUnsigned32 | kDouble) \ | 120 V(Number, kSigned32 | kUnsigned32 | kDouble) \ |
122 V(String, kInternalizedString | kOtherString) \ | 121 V(String, kInternalizedString | kOtherString) \ |
123 V(UniqueName, kSymbol | kInternalizedString) \ | 122 V(UniqueName, kSymbol | kInternalizedString) \ |
124 V(Name, kSymbol | kString) \ | 123 V(Name, kSymbol | kString) \ |
125 V(NumberOrString, kNumber | kString) \ | 124 V(NumberOrString, kNumber | kString) \ |
126 V(Object, kUndetectable | kArray | kFunction | \ | 125 V(Object, kUndetectable | kArray | kFunction | \ |
127 kRegExp | kOtherObject) \ | 126 kRegExp | kOtherObject) \ |
128 V(Receiver, kObject | kProxy) \ | 127 V(Receiver, kObject | kProxy) \ |
129 V(Allocated, kDouble | kName | kReceiver) \ | 128 V(Allocated, kDouble | kName | kReceiver) \ |
130 V(Any, kOddball | kNumber | kAllocated | kInternal) \ | 129 V(Any, kOddball | kNumber | kAllocated | kInternal) \ |
131 V(NonNumber, kAny - kNumber) \ | 130 V(NonNumber, kAny - kNumber) \ |
132 V(Detectable, kAllocated - kUndetectable) | 131 V(Detectable, kAllocated - kUndetectable) |
133 | 132 |
134 #define TYPE_LIST(V) \ | |
135 PRIMITIVE_TYPE_LIST(V) \ | |
136 COMPOSED_TYPE_LIST(V) | |
137 | |
138 | |
139 | 133 |
140 class Type : public Object { | 134 class Type : public Object { |
141 public: | 135 public: |
142 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ | 136 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ |
143 static Type* type() { return from_bitset(k##type); } | 137 static Type* type() { return from_bitset(k##type); } |
144 TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) | 138 BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) |
145 #undef DEFINE_TYPE_CONSTRUCTOR | 139 #undef DEFINE_TYPE_CONSTRUCTOR |
146 | 140 |
147 static Type* Class(Handle<i::Map> map) { return from_handle(map); } | 141 static Type* Class(Handle<i::Map> map) { return from_handle(map); } |
148 static Type* Constant(Handle<i::HeapObject> value) { | 142 static Type* Constant(Handle<i::HeapObject> value) { |
149 return Constant(value, value->GetIsolate()); | 143 return Constant(value, value->GetIsolate()); |
150 } | 144 } |
151 static Type* Constant(Handle<i::Object> value, Isolate* isolate) { | 145 static Type* Constant(Handle<i::Object> value, Isolate* isolate) { |
152 return from_handle(isolate->factory()->NewBox(value)); | 146 return from_handle(isolate->factory()->NewBox(value)); |
153 } | 147 } |
154 | 148 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 | 213 |
220 private: | 214 private: |
221 // A union is a fixed array containing types. Invariants: | 215 // A union is a fixed array containing types. Invariants: |
222 // - its length is at least 2 | 216 // - its length is at least 2 |
223 // - at most one field is a bitset, and it must go into index 0 | 217 // - at most one field is a bitset, and it must go into index 0 |
224 // - no field is a union | 218 // - no field is a union |
225 typedef FixedArray Unioned; | 219 typedef FixedArray Unioned; |
226 | 220 |
227 enum { | 221 enum { |
228 #define DECLARE_TYPE(type, value) k##type = (value), | 222 #define DECLARE_TYPE(type, value) k##type = (value), |
229 TYPE_LIST(DECLARE_TYPE) | 223 BITSET_TYPE_LIST(DECLARE_TYPE) |
230 #undef DECLARE_TYPE | 224 #undef DECLARE_TYPE |
231 kUnusedEOL = 0 | 225 kUnusedEOL = 0 |
232 }; | 226 }; |
233 | 227 |
234 bool is_none() { return this == None(); } | 228 bool is_none() { return this == None(); } |
235 bool is_bitset() { return this->IsSmi(); } | 229 bool is_bitset() { return this->IsSmi(); } |
236 bool is_class() { return this->IsMap(); } | 230 bool is_class() { return this->IsMap(); } |
237 bool is_constant() { return this->IsBox(); } | 231 bool is_constant() { return this->IsBox(); } |
238 bool is_union() { return this->IsFixedArray(); } | 232 bool is_union() { return this->IsFixedArray(); } |
239 | 233 |
(...skipping 30 matching lines...) Expand all Loading... |
270 int GlbBitset(); // greatest lower bound that's a bitset | 264 int GlbBitset(); // greatest lower bound that's a bitset |
271 | 265 |
272 static int LubBitset(i::Object* value); | 266 static int LubBitset(i::Object* value); |
273 static int LubBitset(i::Map* map); | 267 static int LubBitset(i::Map* map); |
274 | 268 |
275 bool InUnion(Handle<Unioned> unioned, int current_size); | 269 bool InUnion(Handle<Unioned> unioned, int current_size); |
276 int ExtendUnion(Handle<Unioned> unioned, int current_size); | 270 int ExtendUnion(Handle<Unioned> unioned, int current_size); |
277 int ExtendIntersection( | 271 int ExtendIntersection( |
278 Handle<Unioned> unioned, Handle<Type> type, int current_size); | 272 Handle<Unioned> unioned, Handle<Type> type, int current_size); |
279 | 273 |
280 static const char* GetComposedName(int type) { | 274 static const char* bitset_name(int bitset); |
281 switch (type) { | |
282 #define PRINT_COMPOSED_TYPE(type, value) \ | |
283 case k##type: \ | |
284 return # type; | |
285 COMPOSED_TYPE_LIST(PRINT_COMPOSED_TYPE) | |
286 #undef PRINT_COMPOSED_TYPE | |
287 } | |
288 return NULL; | |
289 } | |
290 | |
291 static const char* GetPrimitiveName(int type) { | |
292 switch (type) { | |
293 #define PRINT_PRIMITIVE_TYPE(type, value) \ | |
294 case k##type: \ | |
295 return # type; | |
296 PRIMITIVE_TYPE_LIST(PRINT_PRIMITIVE_TYPE) | |
297 #undef PRINT_PRIMITIVE_TYPE | |
298 default: | |
299 UNREACHABLE(); | |
300 return "InvalidType"; | |
301 } | |
302 } | |
303 }; | 275 }; |
304 | 276 |
305 | 277 |
306 // A simple struct to represent a pair of lower/upper type bounds. | 278 // A simple struct to represent a pair of lower/upper type bounds. |
307 struct Bounds { | 279 struct Bounds { |
308 Handle<Type> lower; | 280 Handle<Type> lower; |
309 Handle<Type> upper; | 281 Handle<Type> upper; |
310 | 282 |
311 Bounds() {} | 283 Bounds() {} |
312 Bounds(Handle<Type> l, Handle<Type> u) : lower(l), upper(u) { | 284 Bounds(Handle<Type> l, Handle<Type> u) : lower(l), upper(u) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 static Bounds NarrowUpper(Bounds b, Handle<Type> t, Isolate* isl) { | 323 static Bounds NarrowUpper(Bounds b, Handle<Type> t, Isolate* isl) { |
352 return Bounds( | 324 return Bounds( |
353 handle(Type::Intersect(b.lower, t), isl), | 325 handle(Type::Intersect(b.lower, t), isl), |
354 handle(Type::Intersect(b.upper, t), isl)); | 326 handle(Type::Intersect(b.upper, t), isl)); |
355 } | 327 } |
356 }; | 328 }; |
357 | 329 |
358 } } // namespace v8::internal | 330 } } // namespace v8::internal |
359 | 331 |
360 #endif // V8_TYPES_H_ | 332 #endif // V8_TYPES_H_ |
OLD | NEW |