Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_TYPES_H_ | 5 #ifndef V8_TYPES_H_ |
| 6 #define V8_TYPES_H_ | 6 #define V8_TYPES_H_ |
| 7 | 7 |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/factory.h" | 9 #include "src/factory.h" |
| 10 #include "src/handles.h" | 10 #include "src/handles.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 // Subtyping relates the two dimensions, for example: | 81 // Subtyping relates the two dimensions, for example: |
| 82 // | 82 // |
| 83 // Number <= Tagged \/ UntaggedNumber | 83 // Number <= Tagged \/ UntaggedNumber |
| 84 // Object <= TaggedPtr \/ UntaggedPtr | 84 // Object <= TaggedPtr \/ UntaggedPtr |
| 85 // | 85 // |
| 86 // That holds because the semantic type constructors defined by the API create | 86 // That holds because the semantic type constructors defined by the API create |
| 87 // types that allow for all possible representations, and dually, the ones for | 87 // types that allow for all possible representations, and dually, the ones for |
| 88 // representation types initially include all semantic ranges. Representations | 88 // representation types initially include all semantic ranges. Representations |
| 89 // can then e.g. be narrowed for a given semantic type using intersection: | 89 // can then e.g. be narrowed for a given semantic type using intersection: |
| 90 // | 90 // |
| 91 // SignedSmall /\ TaggedInt (a 'smi') | 91 // Signed31 /\ TaggedInt (a 'smi') |
| 92 // Number /\ TaggedPtr (a heap number) | 92 // Number /\ TaggedPtr (a heap number) |
| 93 // | 93 // |
| 94 // | 94 // |
| 95 // RANGE TYPES | 95 // RANGE TYPES |
| 96 // | 96 // |
| 97 // A range type represents a continuous integer interval by its minimum and | 97 // A range type represents a continuous integer interval by its minimum and |
| 98 // maximum value. Either value might be an infinity. | 98 // maximum value. Either value might be an infinity. |
| 99 // | 99 // |
| 100 // Constant(v) is considered a subtype of Range(x..y) if v happens to be an | 100 // Constant(v) is considered a subtype of Range(x..y) if v happens to be an |
| 101 // integer between x and y. | 101 // integer between x and y. |
| 102 // | 102 // |
| 103 // | 103 // |
| 104 // PREDICATES | 104 // PREDICATES |
| 105 // | 105 // |
| 106 // There are two main functions for testing types: | 106 // There are two main functions for testing types: |
| 107 // | 107 // |
| 108 // T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2) | 108 // T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2) |
| 109 // T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0) | 109 // T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0) |
| 110 // | 110 // |
| 111 // Typically, the former is to be used to select representations (e.g., via | 111 // Typically, the former is to be used to select representations (e.g., via |
| 112 // T->Is(SignedSmall())), and the latter to check whether a specific case needs | 112 // T->Is(Signed31())), and the latter to check whether a specific case needs |
| 113 // handling (e.g., via T->Maybe(Number())). | 113 // handling (e.g., via T->Maybe(Number())). |
| 114 // | 114 // |
| 115 // There is no functionality to discover whether a type is a leaf in the | 115 // There is no functionality to discover whether a type is a leaf in the |
| 116 // lattice. That is intentional. It should always be possible to refine the | 116 // lattice. That is intentional. It should always be possible to refine the |
| 117 // lattice (e.g., splitting up number types further) without invalidating any | 117 // lattice (e.g., splitting up number types further) without invalidating any |
| 118 // existing assumptions or tests. | 118 // existing assumptions or tests. |
| 119 // Consequently, do not normally use Equals for type tests, always use Is! | 119 // Consequently, do not normally use Equals for type tests, always use Is! |
| 120 // | 120 // |
| 121 // The NowIs operator implements state-sensitive subtying, as described above. | 121 // The NowIs operator implements state-sensitive subtying, as described above. |
| 122 // Any compilation decision based on such temporary properties requires runtime | 122 // Any compilation decision based on such temporary properties requires runtime |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 146 // - class Type (zone-allocated, for compiler and concurrent compilation) | 146 // - class Type (zone-allocated, for compiler and concurrent compilation) |
| 147 // - class HeapType (heap-allocated, for persistent types) | 147 // - class HeapType (heap-allocated, for persistent types) |
| 148 // | 148 // |
| 149 // Both provide the same API, and the Convert method can be used to interconvert | 149 // Both provide the same API, and the Convert method can be used to interconvert |
| 150 // them. For zone types, no query method touches the heap, only constructors do. | 150 // them. For zone types, no query method touches the heap, only constructors do. |
| 151 | 151 |
| 152 | 152 |
| 153 // ----------------------------------------------------------------------------- | 153 // ----------------------------------------------------------------------------- |
| 154 // Values for bitset types | 154 // Values for bitset types |
| 155 | 155 |
| 156 // clang-format off | |
| 157 | |
| 156 #define MASK_BITSET_TYPE_LIST(V) \ | 158 #define MASK_BITSET_TYPE_LIST(V) \ |
| 157 V(Representation, 0xfff00000u) \ | 159 V(Representation, 0xfff00000u) \ |
| 158 V(Semantic, 0x000ffffeu) | 160 V(Semantic, 0x000ffffeu) |
| 159 | 161 |
| 160 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation) | 162 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation) |
| 161 #define SEMANTIC(k) ((k) & BitsetType::kSemantic) | 163 #define SEMANTIC(k) ((k) & BitsetType::kSemantic) |
| 162 | 164 |
| 163 #define REPRESENTATION_BITSET_TYPE_LIST(V) \ | 165 #define REPRESENTATION_BITSET_TYPE_LIST(V) \ |
| 164 V(None, 0) \ | 166 V(None, 0) \ |
| 165 V(UntaggedBit, 1u << 20 | kSemantic) \ | 167 V(UntaggedBit, 1u << 20 | kSemantic) \ |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 188 V(Untagged, kUntaggedNumber | kUntaggedPointer) \ | 190 V(Untagged, kUntaggedNumber | kUntaggedPointer) \ |
| 189 V(Tagged, kTaggedSigned | kTaggedPointer) | 191 V(Tagged, kTaggedSigned | kTaggedPointer) |
| 190 | 192 |
| 191 #define INTERNAL_BITSET_TYPE_LIST(V) \ | 193 #define INTERNAL_BITSET_TYPE_LIST(V) \ |
| 192 V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 194 V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 193 V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 195 V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 194 V(OtherSigned32, 1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 196 V(OtherSigned32, 1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 195 V(OtherNumber, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) | 197 V(OtherNumber, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) |
| 196 | 198 |
| 197 #define SEMANTIC_BITSET_TYPE_LIST(V) \ | 199 #define SEMANTIC_BITSET_TYPE_LIST(V) \ |
| 198 V(NegativeSignedSmall, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 200 V(Negative31, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
|
rossberg
2014/12/12 13:57:51
Hm, I'd really prefer to make any bits referring t
Jarin
2015/01/08 14:30:27
I am not entirely sure why are these types bad. Ev
rossberg
2015/01/15 15:15:12
Mainly to prevent misuse --- for portability, nobo
Jarin
2015/01/16 16:28:39
I changed the tests back (where it made sense).
| |
| 199 V(Null, 1u << 6 | REPRESENTATION(kTaggedPointer)) \ | 201 V(Null, 1u << 6 | REPRESENTATION(kTaggedPointer)) \ |
| 200 V(Undefined, 1u << 7 | REPRESENTATION(kTaggedPointer)) \ | 202 V(Undefined, 1u << 7 | REPRESENTATION(kTaggedPointer)) \ |
| 201 V(Boolean, 1u << 8 | REPRESENTATION(kTaggedPointer)) \ | 203 V(Boolean, 1u << 8 | REPRESENTATION(kTaggedPointer)) \ |
| 202 V(UnsignedSmall, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 204 V(Unsigned30, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 203 V(MinusZero, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 205 V(MinusZero, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 204 V(NaN, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 206 V(NaN, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 205 V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \ | 207 V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \ |
| 206 V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \ | 208 V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \ |
| 207 V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \ | 209 V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \ |
| 208 V(Undetectable, 1u << 15 | REPRESENTATION(kTaggedPointer)) \ | 210 V(Undetectable, 1u << 15 | REPRESENTATION(kTaggedPointer)) \ |
| 209 V(Array, 1u << 16 | REPRESENTATION(kTaggedPointer)) \ | 211 V(Array, 1u << 16 | REPRESENTATION(kTaggedPointer)) \ |
| 210 V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \ | 212 V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \ |
| 211 V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \ | 213 V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \ |
| 212 V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \ | 214 V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \ |
| 213 \ | 215 \ |
| 214 V(SignedSmall, kUnsignedSmall | kNegativeSignedSmall) \ | 216 V(Signed31, kUnsigned30 | kNegative31) \ |
| 215 V(Signed32, kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \ | 217 V(Signed32, kSigned31 | kOtherUnsigned31 | kOtherSigned32) \ |
| 216 V(NegativeSigned32, kNegativeSignedSmall | kOtherSigned32) \ | 218 V(Negative32, kNegative31 | kOtherSigned32) \ |
| 217 V(NonNegativeSigned32, kUnsignedSmall | kOtherUnsigned31) \ | 219 V(Unsigned31, kUnsigned30 | kOtherUnsigned31) \ |
| 218 V(Unsigned32, kUnsignedSmall | kOtherUnsigned31 | kOtherUnsigned32) \ | 220 V(Unsigned32, kUnsigned30 | kOtherUnsigned31 | kOtherUnsigned32) \ |
| 219 V(Integral32, kSigned32 | kUnsigned32) \ | 221 V(Integral32, kSigned32 | kUnsigned32) \ |
| 220 V(PlainNumber, kIntegral32 | kOtherNumber) \ | 222 V(PlainNumber, kIntegral32 | kOtherNumber) \ |
| 221 V(OrderedNumber, kPlainNumber | kMinusZero) \ | 223 V(OrderedNumber, kPlainNumber | kMinusZero) \ |
| 222 V(Number, kOrderedNumber | kNaN) \ | 224 V(Number, kOrderedNumber | kNaN) \ |
| 223 V(String, kInternalizedString | kOtherString) \ | 225 V(String, kInternalizedString | kOtherString) \ |
| 224 V(UniqueName, kSymbol | kInternalizedString) \ | 226 V(UniqueName, kSymbol | kInternalizedString) \ |
| 225 V(Name, kSymbol | kString) \ | 227 V(Name, kSymbol | kString) \ |
| 226 V(NumberOrString, kNumber | kString) \ | 228 V(NumberOrString, kNumber | kString) \ |
| 227 V(PlainPrimitive, kNumberOrString | kBoolean | kNull | kUndefined) \ | 229 V(PlainPrimitive, kNumberOrString | kBoolean | kNull | kUndefined) \ |
| 228 V(Primitive, kSymbol | kPlainPrimitive) \ | 230 V(Primitive, kSymbol | kPlainPrimitive) \ |
| 229 V(DetectableObject, kArray | kOtherObject) \ | 231 V(DetectableObject, kArray | kOtherObject) \ |
| 230 V(DetectableReceiver, kDetectableObject | kProxy) \ | 232 V(DetectableReceiver, kDetectableObject | kProxy) \ |
| 231 V(Detectable, kDetectableReceiver | kNumber | kName) \ | 233 V(Detectable, kDetectableReceiver | kNumber | kName) \ |
| 232 V(Object, kDetectableObject | kUndetectable) \ | 234 V(Object, kDetectableObject | kUndetectable) \ |
| 233 V(Receiver, kObject | kProxy) \ | 235 V(Receiver, kObject | kProxy) \ |
| 234 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \ | 236 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \ |
| 235 kReceiver) \ | 237 kReceiver) \ |
| 236 V(NonNumber, kUnique | kString | kInternal) \ | 238 V(NonNumber, kUnique | kString | kInternal) \ |
| 237 V(Any, 0xfffffffeu) | 239 V(Any, 0xfffffffeu) |
| 238 | 240 |
| 241 // clang-format on | |
| 239 | 242 |
| 240 /* | 243 /* |
| 241 * The following diagrams show how integers (in the mathematical sense) are | 244 * The following diagrams show how integers (in the mathematical sense) are |
| 242 * divided among the different atomic numerical types. | 245 * divided among the different atomic numerical types. |
| 243 * | 246 * |
| 244 * If SmiValuesAre31Bits(): | 247 * ON OS32 N31 U30 OU31 OU32 ON |
| 245 * | |
| 246 * ON OS32 OSS US OU31 OU32 ON | |
| 247 * ______[_______[_______[_______[_______[_______[_______ | 248 * ______[_______[_______[_______[_______[_______[_______ |
| 248 * -2^31 -2^30 0 2^30 2^31 2^32 | 249 * -2^31 -2^30 0 2^30 2^31 2^32 |
| 249 * | 250 * |
| 250 * Otherwise: | |
| 251 * | |
| 252 * ON OSS US OU32 ON | |
| 253 * ______[_______________[_______________[_______[_______ | |
| 254 * -2^31 0 2^31 2^32 | |
| 255 * | |
| 256 * | |
| 257 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. | 251 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. |
| 258 * | |
| 259 * NOTE: OtherSigned32 (OS32) and OU31 (OtherUnsigned31) are empty if Smis are | |
| 260 * 32-bit wide. They should thus never be used directly, only indirectly | |
| 261 * via e.g. Number. | |
| 262 */ | 252 */ |
| 263 | 253 |
| 264 #define PROPER_BITSET_TYPE_LIST(V) \ | 254 #define PROPER_BITSET_TYPE_LIST(V) \ |
| 265 REPRESENTATION_BITSET_TYPE_LIST(V) \ | 255 REPRESENTATION_BITSET_TYPE_LIST(V) \ |
| 266 SEMANTIC_BITSET_TYPE_LIST(V) | 256 SEMANTIC_BITSET_TYPE_LIST(V) |
| 267 | 257 |
| 268 #define BITSET_TYPE_LIST(V) \ | 258 #define BITSET_TYPE_LIST(V) \ |
| 269 MASK_BITSET_TYPE_LIST(V) \ | 259 MASK_BITSET_TYPE_LIST(V) \ |
| 270 REPRESENTATION_BITSET_TYPE_LIST(V) \ | 260 REPRESENTATION_BITSET_TYPE_LIST(V) \ |
| 271 INTERNAL_BITSET_TYPE_LIST(V) \ | 261 INTERNAL_BITSET_TYPE_LIST(V) \ |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 297 // static Handle<Struct>::type struct_create(int tag, int length, Region*); | 287 // static Handle<Struct>::type struct_create(int tag, int length, Region*); |
| 298 // static void struct_shrink(Handle<Struct>::type, int length); | 288 // static void struct_shrink(Handle<Struct>::type, int length); |
| 299 // static int struct_tag(Handle<Struct>::type); | 289 // static int struct_tag(Handle<Struct>::type); |
| 300 // static int struct_length(Handle<Struct>::type); | 290 // static int struct_length(Handle<Struct>::type); |
| 301 // static Handle<Type>::type struct_get(Handle<Struct>::type, int); | 291 // static Handle<Type>::type struct_get(Handle<Struct>::type, int); |
| 302 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type); | 292 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type); |
| 303 // template<class V> | 293 // template<class V> |
| 304 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int); | 294 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int); |
| 305 // template<class V> | 295 // template<class V> |
| 306 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>); | 296 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>); |
| 297 // static i::Isolate* get_isolate(Region* region); | |
|
rossberg
2014/12/12 13:57:51
Nit: remove the get_ prefix
Jarin
2015/01/08 14:30:27
Done.
| |
| 307 // } | 298 // } |
| 308 template<class Config> | 299 template<class Config> |
| 309 class TypeImpl : public Config::Base { | 300 class TypeImpl : public Config::Base { |
| 310 public: | 301 public: |
| 311 // Auxiliary types. | 302 // Auxiliary types. |
| 312 | 303 |
| 313 typedef uint32_t bitset; // Internal | 304 typedef uint32_t bitset; // Internal |
| 314 class BitsetType; // Internal | 305 class BitsetType; // Internal |
| 315 class StructuralType; // Internal | 306 class StructuralType; // Internal |
| 316 class UnionType; // Internal | 307 class UnionType; // Internal |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 337 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ | 328 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ |
| 338 static TypeImpl* type() { \ | 329 static TypeImpl* type() { \ |
| 339 return BitsetType::New(BitsetType::k##type); \ | 330 return BitsetType::New(BitsetType::k##type); \ |
| 340 } \ | 331 } \ |
| 341 static TypeHandle type(Region* region) { \ | 332 static TypeHandle type(Region* region) { \ |
| 342 return BitsetType::New(BitsetType::k##type, region); \ | 333 return BitsetType::New(BitsetType::k##type, region); \ |
| 343 } | 334 } |
| 344 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) | 335 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) |
| 345 #undef DEFINE_TYPE_CONSTRUCTOR | 336 #undef DEFINE_TYPE_CONSTRUCTOR |
| 346 | 337 |
| 338 static TypeImpl* SignedSmall() { return BitsetType::New(SignedSmallBits()); } | |
| 339 static TypeHandle SignedSmall(Region* region) { | |
| 340 return BitsetType::New(SignedSmallBits(), region); | |
| 341 } | |
| 342 static TypeImpl* UnsignedSmall() { | |
| 343 return BitsetType::New(UnsignedSmallBits()); | |
| 344 } | |
| 345 static TypeHandle UnsignedSmall(Region* region) { | |
| 346 return BitsetType::New(UnsignedSmallBits(), region); | |
| 347 } | |
| 348 | |
| 347 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { | 349 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { |
| 348 return ClassType::New(map, region); | 350 return ClassType::New(map, region); |
| 349 } | 351 } |
| 350 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { | 352 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { |
| 351 return ConstantType::New(value, region); | 353 return ConstantType::New(value, region); |
| 352 } | 354 } |
| 353 static TypeHandle Range( | 355 static TypeHandle Range( |
| 354 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { | 356 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { |
| 355 return RangeType::New(min, max, region); | 357 return RangeType::New(min, max, REPRESENTATION(BitsetType::kTagged | |
| 358 BitsetType::kUntaggedNumber), | |
| 359 region); | |
| 356 } | 360 } |
| 357 static TypeHandle Context(TypeHandle outer, Region* region) { | 361 static TypeHandle Context(TypeHandle outer, Region* region) { |
| 358 return ContextType::New(outer, region); | 362 return ContextType::New(outer, region); |
| 359 } | 363 } |
| 360 static TypeHandle Array(TypeHandle element, Region* region) { | 364 static TypeHandle Array(TypeHandle element, Region* region) { |
| 361 return ArrayType::New(element, region); | 365 return ArrayType::New(element, region); |
| 362 } | 366 } |
| 363 static FunctionHandle Function( | 367 static FunctionHandle Function( |
| 364 TypeHandle result, TypeHandle receiver, int arity, Region* region) { | 368 TypeHandle result, TypeHandle receiver, int arity, Region* region) { |
| 365 return FunctionType::New(result, receiver, arity, region); | 369 return FunctionType::New(result, receiver, arity, region); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 540 DCHECK(this->IsBitset()); | 544 DCHECK(this->IsBitset()); |
| 541 return static_cast<BitsetType*>(this)->Bitset(); | 545 return static_cast<BitsetType*>(this)->Bitset(); |
| 542 } | 546 } |
| 543 UnionType* AsUnion() { return UnionType::cast(this); } | 547 UnionType* AsUnion() { return UnionType::cast(this); } |
| 544 | 548 |
| 545 // Auxiliary functions. | 549 // Auxiliary functions. |
| 546 | 550 |
| 547 bitset BitsetGlb() { return BitsetType::Glb(this); } | 551 bitset BitsetGlb() { return BitsetType::Glb(this); } |
| 548 bitset BitsetLub() { return BitsetType::Lub(this); } | 552 bitset BitsetLub() { return BitsetType::Lub(this); } |
| 549 | 553 |
| 554 static bitset SignedSmallBits(); | |
| 555 static bitset UnsignedSmallBits(); | |
| 556 | |
| 550 bool SlowIs(TypeImpl* that); | 557 bool SlowIs(TypeImpl* that); |
| 551 | 558 |
| 552 static bool IsInteger(double x) { | 559 static bool IsInteger(double x) { |
| 553 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. | 560 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. |
| 554 } | 561 } |
| 555 static bool IsInteger(i::Object* x) { | 562 static bool IsInteger(i::Object* x) { |
| 556 return x->IsNumber() && IsInteger(x->Number()); | 563 return x->IsNumber() && IsInteger(x->Number()); |
| 557 } | 564 } |
| 558 | 565 |
| 559 struct Limits { | 566 struct Limits { |
| 560 i::Handle<i::Object> min; | 567 i::Handle<i::Object> min; |
| 561 i::Handle<i::Object> max; | 568 i::Handle<i::Object> max; |
| 562 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max) : | 569 bitset representation; |
| 563 min(min), max(max) {} | 570 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max, |
| 564 explicit Limits(RangeType* range) : | 571 bitset representation) |
| 565 min(range->Min()), max(range->Max()) {} | 572 : min(min), max(max), representation(representation) {} |
| 573 explicit Limits(RangeType* range) | |
| 574 : min(range->Min()), | |
| 575 max(range->Max()), | |
| 576 representation(range->Representation()) {} | |
| 577 static Limits Empty(Region* region) { | |
| 578 i::Factory* f = Config::get_isolate(region)->factory(); | |
| 579 i::Handle<i::Object> min = f->NewNumber(1); | |
| 580 i::Handle<i::Object> max = f->NewNumber(0); | |
| 581 return Limits(min, max, BitsetType::kNone); | |
| 582 } | |
| 566 }; | 583 }; |
| 567 | 584 |
| 585 static bool IsEmpty(Limits lim); | |
| 568 static Limits Intersect(Limits lhs, Limits rhs); | 586 static Limits Intersect(Limits lhs, Limits rhs); |
| 569 static Limits Union(Limits lhs, Limits rhs); | 587 static Limits Union(Limits lhs, Limits rhs); |
| 570 static bool Overlap(RangeType* lhs, RangeType* rhs); | 588 static bool Overlap(RangeType* lhs, RangeType* rhs); |
| 571 static bool Contains(RangeType* lhs, RangeType* rhs); | 589 static bool Contains(RangeType* lhs, RangeType* rhs); |
| 590 static bool Contains(RangeType* range, ConstantType* constant); | |
| 572 static bool Contains(RangeType* range, i::Object* val); | 591 static bool Contains(RangeType* range, i::Object* val); |
| 573 | 592 |
| 574 static int UpdateRange( | 593 static int UpdateRange( |
| 575 RangeHandle type, UnionHandle result, int size, Region* region); | 594 RangeHandle type, UnionHandle result, int size, Region* region); |
| 576 | 595 |
| 596 static Limits IntersectRangeAndBitset(TypeHandle range, TypeHandle bits, | |
| 597 Region* region); | |
| 598 static Limits NumberBitsetToLimits(bitset bits, Region* region); | |
|
rossberg
2014/12/12 13:57:51
Nit: ToLimits would seem good enough a name
Jarin
2015/01/08 14:30:27
Done.
| |
| 599 | |
| 577 bool SimplyEquals(TypeImpl* that); | 600 bool SimplyEquals(TypeImpl* that); |
| 578 template<class TypeHandle> | 601 template<class TypeHandle> |
| 579 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } | 602 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } |
| 580 | 603 |
| 581 static int AddToUnion( | 604 static int AddToUnion( |
| 582 TypeHandle type, UnionHandle result, int size, Region* region); | 605 TypeHandle type, UnionHandle result, int size, Region* region); |
| 583 static int IntersectAux( | 606 static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result, |
| 584 TypeHandle type, TypeHandle other, | 607 int size, Limits* limits, Region* region); |
| 585 UnionHandle result, int size, Region* region); | |
| 586 static TypeHandle NormalizeUnion(UnionHandle unioned, int size); | 608 static TypeHandle NormalizeUnion(UnionHandle unioned, int size); |
| 609 static TypeHandle NormalizeRangeAndBitset(RangeHandle range, bitset* bits, | |
| 610 Region* region); | |
| 587 }; | 611 }; |
| 588 | 612 |
| 589 | 613 |
| 590 // ----------------------------------------------------------------------------- | 614 // ----------------------------------------------------------------------------- |
| 591 // Bitset types (internal). | 615 // Bitset types (internal). |
| 592 | 616 |
| 593 template<class Config> | 617 template<class Config> |
| 594 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { | 618 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { |
| 595 protected: | 619 protected: |
| 596 friend class TypeImpl<Config>; | 620 friend class TypeImpl<Config>; |
| 597 | 621 |
| 598 enum { | 622 enum { |
| 599 #define DECLARE_TYPE(type, value) k##type = (value), | 623 #define DECLARE_TYPE(type, value) k##type = (value), |
| 600 BITSET_TYPE_LIST(DECLARE_TYPE) | 624 BITSET_TYPE_LIST(DECLARE_TYPE) |
| 601 #undef DECLARE_TYPE | 625 #undef DECLARE_TYPE |
| 602 kUnusedEOL = 0 | 626 kUnusedEOL = 0 |
| 603 }; | 627 }; |
| 604 | 628 |
| 605 bitset Bitset() { return Config::as_bitset(this); } | 629 bitset Bitset() { return Config::as_bitset(this); } |
| 606 | 630 |
| 607 static TypeImpl* New(bitset bits) { | 631 static TypeImpl* New(bitset bits) { |
| 608 DCHECK(bits == kNone || IsInhabited(bits)); | 632 DCHECK(bits == kNone || IsInhabited(bits)); |
| 609 | 633 |
| 610 if (FLAG_enable_slow_asserts) { | 634 if (FLAG_enable_slow_asserts) { |
| 611 // Check that the bitset does not contain any holes in number ranges. | 635 // Check that the bitset does not contain any holes in number ranges. |
| 612 bitset mask = kSemantic; | 636 bitset number_bits = NumberBits(bits); |
| 613 if (!i::SmiValuesAre31Bits()) { | |
| 614 mask &= ~(kOtherUnsigned31 | kOtherSigned32); | |
| 615 } | |
| 616 bitset number_bits = bits & kPlainNumber & mask; | |
| 617 if (number_bits != 0) { | 637 if (number_bits != 0) { |
| 618 bitset lub = Lub(Min(number_bits), Max(number_bits)) & mask; | 638 bitset lub = SEMANTIC(Lub(Min(number_bits), Max(number_bits))); |
| 619 CHECK(lub == number_bits); | 639 CHECK(lub == number_bits); |
| 620 } | 640 } |
| 621 } | 641 } |
| 622 | 642 |
| 623 return Config::from_bitset(bits); | 643 return Config::from_bitset(bits); |
| 624 } | 644 } |
| 625 static TypeHandle New(bitset bits, Region* region) { | 645 static TypeHandle New(bitset bits, Region* region) { |
| 626 DCHECK(bits == kNone || IsInhabited(bits)); | 646 DCHECK(bits == kNone || IsInhabited(bits)); |
| 627 return Config::from_bitset(bits, region); | 647 return Config::from_bitset(bits, region); |
| 628 } | 648 } |
| 629 // TODO(neis): Eventually allow again for types with empty semantics | 649 // TODO(neis): Eventually allow again for types with empty semantics |
| 630 // part and modify intersection and possibly subtyping accordingly. | 650 // part and modify intersection and possibly subtyping accordingly. |
| 631 | 651 |
| 632 static bool IsInhabited(bitset bits) { | 652 static bool IsInhabited(bitset bits) { |
| 633 return bits & kSemantic; | 653 return bits & kSemantic; |
| 634 } | 654 } |
| 635 | 655 |
| 656 static bitset NumberBits(bitset bits) { | |
|
rossberg
2014/12/12 13:57:51
Move to same place as (Un)signedSmallBits.
Jarin
2015/01/08 14:30:28
Done.
| |
| 657 return bits & kPlainNumber & kSemantic; | |
| 658 } | |
| 659 | |
| 636 static bool Is(bitset bits1, bitset bits2) { | 660 static bool Is(bitset bits1, bitset bits2) { |
| 637 return (bits1 | bits2) == bits2; | 661 return (bits1 | bits2) == bits2; |
| 638 } | 662 } |
| 639 | 663 |
| 640 static double Min(bitset); | 664 static double Min(bitset); |
| 641 static double Max(bitset); | 665 static double Max(bitset); |
| 642 | 666 |
| 643 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset | 667 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset |
| 668 static bitset Glb(double min, double max); | |
| 644 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset | 669 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset |
| 645 static bitset Lub(i::Map* map); | 670 static bitset Lub(i::Map* map); |
| 646 static bitset Lub(i::Object* value); | 671 static bitset Lub(i::Object* value); |
| 647 static bitset Lub(double value); | 672 static bitset Lub(double value); |
| 648 static bitset Lub(double min, double max); | 673 static bitset Lub(double min, double max); |
| 649 | 674 |
| 650 static const char* Name(bitset); | 675 static const char* Name(bitset); |
| 651 static void Print(std::ostream& os, bitset); // NOLINT | 676 static void Print(std::ostream& os, bitset); // NOLINT |
| 652 #ifdef DEBUG | 677 #ifdef DEBUG |
| 653 static void Print(bitset); | 678 static void Print(bitset); |
| 654 #endif | 679 #endif |
| 655 | 680 |
| 656 private: | 681 private: |
| 657 struct BitsetMin{ | 682 struct BitsetMin{ |
| 658 bitset bits; | 683 bitset bits; |
| 659 double min; | 684 double min; |
| 660 }; | 685 }; |
| 661 static const BitsetMin BitsetMins31[]; | 686 static const BitsetMin BitsetMinsArray[]; |
| 662 static const BitsetMin BitsetMins32[]; | 687 static const BitsetMin* BitsetMins() { return BitsetMinsArray; } |
| 663 static const BitsetMin* BitsetMins() { | |
| 664 return i::SmiValuesAre31Bits() ? BitsetMins31 : BitsetMins32; | |
| 665 } | |
| 666 static size_t BitsetMinsSize() { | 688 static size_t BitsetMinsSize() { |
| 667 return i::SmiValuesAre31Bits() ? 7 : 5; | 689 return 7; |
| 668 /* arraysize(BitsetMins31) : arraysize(BitsetMins32); */ | 690 /* arraysize(BitsetMinsArray); */ |
| 669 // Using arraysize here doesn't compile on Windows. | 691 // Using arraysize here doesn't compile on Windows. |
| 670 } | 692 } |
| 671 }; | 693 }; |
| 672 | 694 |
| 673 | 695 |
| 674 // ----------------------------------------------------------------------------- | 696 // ----------------------------------------------------------------------------- |
| 675 // Superclass for non-bitset types (internal). | 697 // Superclass for non-bitset types (internal). |
| 676 // Contains a tag and a variable number of type or value fields. | 698 // Contains a tag and a variable number of type or value fields. |
| 677 | 699 |
| 678 template<class Config> | 700 template<class Config> |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 782 }; | 804 }; |
| 783 | 805 |
| 784 | 806 |
| 785 // ----------------------------------------------------------------------------- | 807 // ----------------------------------------------------------------------------- |
| 786 // Constant types. | 808 // Constant types. |
| 787 | 809 |
| 788 template<class Config> | 810 template<class Config> |
| 789 class TypeImpl<Config>::ConstantType : public StructuralType { | 811 class TypeImpl<Config>::ConstantType : public StructuralType { |
| 790 public: | 812 public: |
| 791 TypeHandle Bound() { return this->Get(0); } | 813 TypeHandle Bound() { return this->Get(0); } |
| 814 bitset Representation() { return REPRESENTATION(this->Get(0)->AsBitset()); } | |
|
rossberg
2014/12/12 13:57:51
Please don't expose bitset functionality in this i
rossberg
2014/12/12 15:30:41
s/in this interfaces/in these public interfaces/
Jarin
2015/01/08 14:30:27
Done.
| |
| 792 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); } | 815 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); } |
| 793 | 816 |
| 794 static ConstantHandle New(i::Handle<i::Object> value, Region* region) { | 817 static ConstantHandle New(i::Handle<i::Object> value, Region* region) { |
| 795 ConstantHandle type = Config::template cast<ConstantType>( | 818 ConstantHandle type = Config::template cast<ConstantType>( |
| 796 StructuralType::New(StructuralType::kConstantTag, 2, region)); | 819 StructuralType::New(StructuralType::kConstantTag, 2, region)); |
| 797 type->Set(0, BitsetType::New(BitsetType::Lub(*value), region)); | 820 type->Set(0, BitsetType::New(BitsetType::Lub(*value), region)); |
| 798 type->SetValue(1, value); | 821 type->SetValue(1, value); |
| 799 return type; | 822 return type; |
| 800 } | 823 } |
| 801 | 824 |
| 802 static ConstantType* cast(TypeImpl* type) { | 825 static ConstantType* cast(TypeImpl* type) { |
| 803 DCHECK(type->IsConstant()); | 826 DCHECK(type->IsConstant()); |
| 804 return static_cast<ConstantType*>(type); | 827 return static_cast<ConstantType*>(type); |
| 805 } | 828 } |
| 806 }; | 829 }; |
| 807 // TODO(neis): Also cache value if numerical. | 830 // TODO(neis): Also cache value if numerical. |
| 808 // TODO(neis): Allow restricting the representation. | 831 // TODO(neis): Allow restricting the representation. |
| 809 | 832 |
| 810 | 833 |
| 811 // ----------------------------------------------------------------------------- | 834 // ----------------------------------------------------------------------------- |
| 812 // Range types. | 835 // Range types. |
| 813 | 836 |
| 814 template<class Config> | 837 template<class Config> |
| 815 class TypeImpl<Config>::RangeType : public StructuralType { | 838 class TypeImpl<Config>::RangeType : public StructuralType { |
| 816 public: | 839 public: |
| 817 int BitsetLub() { return this->Get(0)->AsBitset(); } | 840 int BitsetLub() { return this->Get(0)->AsBitset(); } |
| 841 bitset Representation() { return REPRESENTATION(BitsetLub()); } | |
|
rossberg
2014/12/12 13:57:51
Same here.
Jarin
2015/01/08 14:30:27
Done.
| |
| 818 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); } | 842 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); } |
| 819 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); } | 843 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); } |
| 820 | 844 |
| 821 static RangeHandle New( | 845 static RangeHandle New(i::Handle<i::Object> min, i::Handle<i::Object> max, |
| 822 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { | 846 bitset representation, Region* region) { |
|
rossberg
2014/12/12 13:57:51
For the same reason, make representation a Type he
Jarin
2015/01/08 14:30:27
Done.
| |
| 823 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); | 847 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); |
| 824 DCHECK(min->Number() <= max->Number()); | 848 DCHECK(min->Number() <= max->Number()); |
| 849 DCHECK(REPRESENTATION(representation) == representation); | |
| 850 | |
| 851 // Make sure the representation does not contain non-number stuff. | |
|
rossberg
2014/12/12 13:57:51
Shouldn't this better be an assertion?
Jarin
2015/01/08 14:30:27
Removed this code. (If we want the point-wise repr
| |
| 852 representation &= | |
| 853 REPRESENTATION(BitsetType::kTagged | BitsetType::kUntaggedNumber); | |
| 854 | |
| 825 RangeHandle type = Config::template cast<RangeType>( | 855 RangeHandle type = Config::template cast<RangeType>( |
| 826 StructuralType::New(StructuralType::kRangeTag, 3, region)); | 856 StructuralType::New(StructuralType::kRangeTag, 3, region)); |
| 827 type->Set(0, BitsetType::New( | 857 |
| 828 BitsetType::Lub(min->Number(), max->Number()), region)); | 858 bitset bits = SEMANTIC(BitsetType::Lub(min->Number(), max->Number())) | |
| 859 representation; | |
| 860 type->Set(0, BitsetType::New(bits, region)); | |
| 829 type->SetValue(1, min); | 861 type->SetValue(1, min); |
| 830 type->SetValue(2, max); | 862 type->SetValue(2, max); |
| 831 return type; | 863 return type; |
| 832 } | 864 } |
| 833 | 865 |
| 834 static RangeHandle New(Limits lim, Region* region) { | 866 static RangeHandle New(Limits lim, Region* region) { |
| 835 return New(lim.min, lim.max, region); | 867 return New(lim.min, lim.max, lim.representation, region); |
| 836 } | 868 } |
| 837 | 869 |
| 838 static RangeType* cast(TypeImpl* type) { | 870 static RangeType* cast(TypeImpl* type) { |
| 839 DCHECK(type->IsRange()); | 871 DCHECK(type->IsRange()); |
| 840 return static_cast<RangeType*>(type); | 872 return static_cast<RangeType*>(type); |
| 841 } | 873 } |
| 842 }; | 874 }; |
| 843 // TODO(neis): Also cache min and max values. | 875 // TODO(neis): Also cache min and max values. |
| 844 // TODO(neis): Allow restricting the representation. | 876 // TODO(neis): Allow restricting the representation. |
| 845 | 877 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 974 static inline Struct* struct_create(int tag, int length, Zone* zone); | 1006 static inline Struct* struct_create(int tag, int length, Zone* zone); |
| 975 static inline void struct_shrink(Struct* structure, int length); | 1007 static inline void struct_shrink(Struct* structure, int length); |
| 976 static inline int struct_tag(Struct* structure); | 1008 static inline int struct_tag(Struct* structure); |
| 977 static inline int struct_length(Struct* structure); | 1009 static inline int struct_length(Struct* structure); |
| 978 static inline Type* struct_get(Struct* structure, int i); | 1010 static inline Type* struct_get(Struct* structure, int i); |
| 979 static inline void struct_set(Struct* structure, int i, Type* type); | 1011 static inline void struct_set(Struct* structure, int i, Type* type); |
| 980 template<class V> | 1012 template<class V> |
| 981 static inline i::Handle<V> struct_get_value(Struct* structure, int i); | 1013 static inline i::Handle<V> struct_get_value(Struct* structure, int i); |
| 982 template<class V> static inline void struct_set_value( | 1014 template<class V> static inline void struct_set_value( |
| 983 Struct* structure, int i, i::Handle<V> x); | 1015 Struct* structure, int i, i::Handle<V> x); |
| 1016 static inline i::Isolate* get_isolate(Zone* zone); | |
| 984 }; | 1017 }; |
| 985 | 1018 |
| 986 typedef TypeImpl<ZoneTypeConfig> Type; | 1019 typedef TypeImpl<ZoneTypeConfig> Type; |
| 987 | 1020 |
| 988 | 1021 |
| 989 // ----------------------------------------------------------------------------- | 1022 // ----------------------------------------------------------------------------- |
| 990 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for | 1023 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for |
| 991 // constants, or fixed arrays for unions. | 1024 // constants, or fixed arrays for unions. |
| 992 | 1025 |
| 993 struct HeapTypeConfig { | 1026 struct HeapTypeConfig { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1022 static inline int struct_length(i::Handle<Struct> structure); | 1055 static inline int struct_length(i::Handle<Struct> structure); |
| 1023 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i); | 1056 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i); |
| 1024 static inline void struct_set( | 1057 static inline void struct_set( |
| 1025 i::Handle<Struct> structure, int i, i::Handle<Type> type); | 1058 i::Handle<Struct> structure, int i, i::Handle<Type> type); |
| 1026 template<class V> | 1059 template<class V> |
| 1027 static inline i::Handle<V> struct_get_value( | 1060 static inline i::Handle<V> struct_get_value( |
| 1028 i::Handle<Struct> structure, int i); | 1061 i::Handle<Struct> structure, int i); |
| 1029 template<class V> | 1062 template<class V> |
| 1030 static inline void struct_set_value( | 1063 static inline void struct_set_value( |
| 1031 i::Handle<Struct> structure, int i, i::Handle<V> x); | 1064 i::Handle<Struct> structure, int i, i::Handle<V> x); |
| 1065 static inline i::Isolate* get_isolate(Isolate* isolate); | |
| 1032 }; | 1066 }; |
| 1033 | 1067 |
| 1034 typedef TypeImpl<HeapTypeConfig> HeapType; | 1068 typedef TypeImpl<HeapTypeConfig> HeapType; |
| 1035 | 1069 |
| 1036 | 1070 |
| 1037 // ----------------------------------------------------------------------------- | 1071 // ----------------------------------------------------------------------------- |
| 1038 // Type bounds. A simple struct to represent a pair of lower/upper types. | 1072 // Type bounds. A simple struct to represent a pair of lower/upper types. |
| 1039 | 1073 |
| 1040 template<class Config> | 1074 template<class Config> |
| 1041 struct BoundsImpl { | 1075 struct BoundsImpl { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1092 bool Narrows(BoundsImpl that) { | 1126 bool Narrows(BoundsImpl that) { |
| 1093 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 1127 return that.lower->Is(this->lower) && this->upper->Is(that.upper); |
| 1094 } | 1128 } |
| 1095 }; | 1129 }; |
| 1096 | 1130 |
| 1097 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 1131 typedef BoundsImpl<ZoneTypeConfig> Bounds; |
| 1098 | 1132 |
| 1099 } } // namespace v8::internal | 1133 } } // namespace v8::internal |
| 1100 | 1134 |
| 1101 #endif // V8_TYPES_H_ | 1135 #endif // V8_TYPES_H_ |
| OLD | NEW |