 Chromium Code Reviews
 Chromium Code Reviews Issue 795713003:
  Steps towards unification of number bitset and range types.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 795713003:
  Steps towards unification of number bitset and range types.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| 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') | 
| 
rossberg
2015/01/15 15:15:12
This doesn't make sense on 64 bit. The original co
 
Jarin
2015/01/16 16:28:39
Done.
 | |
| 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 | 
| 
rossberg
2015/01/15 15:15:12
Similarly here. Please don't encourage use of Sign
 
Jarin
2015/01/16 16:28:39
Done.
 | |
| 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)) \ | 
| 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(StringOrReceiver, kString | kReceiver) \ | 236 V(StringOrReceiver, kString | kReceiver) \ | 
| 235 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \ | 237 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \ | 
| 236 kReceiver) \ | 238 kReceiver) \ | 
| 237 V(NonNumber, kUnique | kString | kInternal) \ | 239 V(NonNumber, kUnique | kString | kInternal) \ | 
| 238 V(Any, 0xfffffffeu) | 240 V(Any, 0xfffffffeu) | 
| 239 | 241 | 
| 242 // clang-format on | |
| 240 | 243 | 
| 241 /* | 244 /* | 
| 242 * The following diagrams show how integers (in the mathematical sense) are | 245 * The following diagrams show how integers (in the mathematical sense) are | 
| 243 * divided among the different atomic numerical types. | 246 * divided among the different atomic numerical types. | 
| 244 * | 247 * | 
| 245 * If SmiValuesAre31Bits(): | 248 * ON OS32 N31 U30 OU31 OU32 ON | 
| 246 * | |
| 247 * ON OS32 OSS US OU31 OU32 ON | |
| 248 * ______[_______[_______[_______[_______[_______[_______ | 249 * ______[_______[_______[_______[_______[_______[_______ | 
| 249 * -2^31 -2^30 0 2^30 2^31 2^32 | 250 * -2^31 -2^30 0 2^30 2^31 2^32 | 
| 250 * | 251 * | 
| 251 * Otherwise: | |
| 252 * | |
| 253 * ON OSS US OU32 ON | |
| 254 * ______[_______________[_______________[_______[_______ | |
| 255 * -2^31 0 2^31 2^32 | |
| 256 * | |
| 257 * | |
| 258 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. | 252 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. | 
| 259 * | |
| 260 * NOTE: OtherSigned32 (OS32) and OU31 (OtherUnsigned31) are empty if Smis are | |
| 261 * 32-bit wide. They should thus never be used directly, only indirectly | |
| 262 * via e.g. Number. | |
| 263 */ | 253 */ | 
| 264 | 254 | 
| 265 #define PROPER_BITSET_TYPE_LIST(V) \ | 255 #define PROPER_BITSET_TYPE_LIST(V) \ | 
| 266 REPRESENTATION_BITSET_TYPE_LIST(V) \ | 256 REPRESENTATION_BITSET_TYPE_LIST(V) \ | 
| 267 SEMANTIC_BITSET_TYPE_LIST(V) | 257 SEMANTIC_BITSET_TYPE_LIST(V) | 
| 268 | 258 | 
| 269 #define BITSET_TYPE_LIST(V) \ | 259 #define BITSET_TYPE_LIST(V) \ | 
| 270 MASK_BITSET_TYPE_LIST(V) \ | 260 MASK_BITSET_TYPE_LIST(V) \ | 
| 271 REPRESENTATION_BITSET_TYPE_LIST(V) \ | 261 REPRESENTATION_BITSET_TYPE_LIST(V) \ | 
| 272 INTERNAL_BITSET_TYPE_LIST(V) \ | 262 INTERNAL_BITSET_TYPE_LIST(V) \ | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 298 // static Handle<Struct>::type struct_create(int tag, int length, Region*); | 288 // static Handle<Struct>::type struct_create(int tag, int length, Region*); | 
| 299 // static void struct_shrink(Handle<Struct>::type, int length); | 289 // static void struct_shrink(Handle<Struct>::type, int length); | 
| 300 // static int struct_tag(Handle<Struct>::type); | 290 // static int struct_tag(Handle<Struct>::type); | 
| 301 // static int struct_length(Handle<Struct>::type); | 291 // static int struct_length(Handle<Struct>::type); | 
| 302 // static Handle<Type>::type struct_get(Handle<Struct>::type, int); | 292 // static Handle<Type>::type struct_get(Handle<Struct>::type, int); | 
| 303 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type); | 293 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type); | 
| 304 // template<class V> | 294 // template<class V> | 
| 305 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int); | 295 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int); | 
| 306 // template<class V> | 296 // template<class V> | 
| 307 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>); | 297 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>); | 
| 298 // static i::Isolate* isolate(Region* region); | |
| 308 // } | 299 // } | 
| 309 template<class Config> | 300 template<class Config> | 
| 310 class TypeImpl : public Config::Base { | 301 class TypeImpl : public Config::Base { | 
| 311 public: | 302 public: | 
| 312 // Auxiliary types. | 303 // Auxiliary types. | 
| 313 | 304 | 
| 314 typedef uint32_t bitset; // Internal | 305 typedef uint32_t bitset; // Internal | 
| 315 class BitsetType; // Internal | 306 class BitsetType; // Internal | 
| 316 class StructuralType; // Internal | 307 class StructuralType; // Internal | 
| 317 class UnionType; // Internal | 308 class UnionType; // Internal | 
| (...skipping 20 matching lines...) Expand all Loading... | |
| 338 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ | 329 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ | 
| 339 static TypeImpl* type() { \ | 330 static TypeImpl* type() { \ | 
| 340 return BitsetType::New(BitsetType::k##type); \ | 331 return BitsetType::New(BitsetType::k##type); \ | 
| 341 } \ | 332 } \ | 
| 342 static TypeHandle type(Region* region) { \ | 333 static TypeHandle type(Region* region) { \ | 
| 343 return BitsetType::New(BitsetType::k##type, region); \ | 334 return BitsetType::New(BitsetType::k##type, region); \ | 
| 344 } | 335 } | 
| 345 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) | 336 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) | 
| 346 #undef DEFINE_TYPE_CONSTRUCTOR | 337 #undef DEFINE_TYPE_CONSTRUCTOR | 
| 347 | 338 | 
| 339 static TypeImpl* SignedSmall() { return BitsetType::New(SignedSmallBits()); } | |
| 340 static TypeHandle SignedSmall(Region* region) { | |
| 341 return BitsetType::New(SignedSmallBits(), region); | |
| 342 } | |
| 343 static TypeImpl* UnsignedSmall() { | |
| 344 return BitsetType::New(UnsignedSmallBits()); | |
| 345 } | |
| 346 static TypeHandle UnsignedSmall(Region* region) { | |
| 347 return BitsetType::New(UnsignedSmallBits(), region); | |
| 348 } | |
| 349 | |
| 348 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { | 350 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { | 
| 349 return ClassType::New(map, region); | 351 return ClassType::New(map, region); | 
| 350 } | 352 } | 
| 351 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { | 353 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { | 
| 352 return ConstantType::New(value, region); | 354 return ConstantType::New(value, region); | 
| 353 } | 355 } | 
| 354 static TypeHandle Range( | 356 static TypeHandle Range( | 
| 355 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { | 357 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { | 
| 356 return RangeType::New(min, max, region); | 358 return RangeType::New( | 
| 359 min, max, BitsetType::New(REPRESENTATION(BitsetType::kTagged | | |
| 360 BitsetType::kUntaggedNumber), | |
| 361 region), | |
| 362 region); | |
| 357 } | 363 } | 
| 358 static TypeHandle Context(TypeHandle outer, Region* region) { | 364 static TypeHandle Context(TypeHandle outer, Region* region) { | 
| 359 return ContextType::New(outer, region); | 365 return ContextType::New(outer, region); | 
| 360 } | 366 } | 
| 361 static TypeHandle Array(TypeHandle element, Region* region) { | 367 static TypeHandle Array(TypeHandle element, Region* region) { | 
| 362 return ArrayType::New(element, region); | 368 return ArrayType::New(element, region); | 
| 363 } | 369 } | 
| 364 static FunctionHandle Function( | 370 static FunctionHandle Function( | 
| 365 TypeHandle result, TypeHandle receiver, int arity, Region* region) { | 371 TypeHandle result, TypeHandle receiver, int arity, Region* region) { | 
| 366 return FunctionType::New(result, receiver, arity, region); | 372 return FunctionType::New(result, receiver, arity, region); | 
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 541 DCHECK(this->IsBitset()); | 547 DCHECK(this->IsBitset()); | 
| 542 return static_cast<BitsetType*>(this)->Bitset(); | 548 return static_cast<BitsetType*>(this)->Bitset(); | 
| 543 } | 549 } | 
| 544 UnionType* AsUnion() { return UnionType::cast(this); } | 550 UnionType* AsUnion() { return UnionType::cast(this); } | 
| 545 | 551 | 
| 546 // Auxiliary functions. | 552 // Auxiliary functions. | 
| 547 | 553 | 
| 548 bitset BitsetGlb() { return BitsetType::Glb(this); } | 554 bitset BitsetGlb() { return BitsetType::Glb(this); } | 
| 549 bitset BitsetLub() { return BitsetType::Lub(this); } | 555 bitset BitsetLub() { return BitsetType::Lub(this); } | 
| 550 | 556 | 
| 557 static bitset SignedSmallBits(); | |
| 
rossberg
2015/01/15 15:15:12
Nit: I think these belong to the Bitset class as B
 
Jarin
2015/01/16 16:28:39
Done.
 | |
| 558 static bitset UnsignedSmallBits(); | |
| 559 static bitset NumberBits(bitset bits); | |
| 560 | |
| 551 bool SlowIs(TypeImpl* that); | 561 bool SlowIs(TypeImpl* that); | 
| 552 | 562 | 
| 553 static bool IsInteger(double x) { | 563 static bool IsInteger(double x) { | 
| 554 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. | 564 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. | 
| 555 } | 565 } | 
| 556 static bool IsInteger(i::Object* x) { | 566 static bool IsInteger(i::Object* x) { | 
| 557 return x->IsNumber() && IsInteger(x->Number()); | 567 return x->IsNumber() && IsInteger(x->Number()); | 
| 558 } | 568 } | 
| 559 | 569 | 
| 560 struct Limits { | 570 struct Limits { | 
| 561 i::Handle<i::Object> min; | 571 i::Handle<i::Object> min; | 
| 562 i::Handle<i::Object> max; | 572 i::Handle<i::Object> max; | 
| 563 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max) : | 573 bitset representation; | 
| 564 min(min), max(max) {} | 574 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max, | 
| 565 explicit Limits(RangeType* range) : | 575 bitset representation) | 
| 566 min(range->Min()), max(range->Max()) {} | 576 : min(min), max(max), representation(representation) {} | 
| 577 explicit Limits(RangeType* range) | |
| 578 : min(range->Min()), | |
| 579 max(range->Max()), | |
| 580 representation(REPRESENTATION(range->Bound()->AsBitset())) {} | |
| 581 static Limits Empty(Region* region) { | |
| 582 i::Factory* f = Config::isolate(region)->factory(); | |
| 583 i::Handle<i::Object> min = f->NewNumber(1); | |
| 584 i::Handle<i::Object> max = f->NewNumber(0); | |
| 585 return Limits(min, max, BitsetType::kNone); | |
| 586 } | |
| 567 }; | 587 }; | 
| 568 | 588 | 
| 589 static bool IsEmpty(Limits lim); | |
| 569 static Limits Intersect(Limits lhs, Limits rhs); | 590 static Limits Intersect(Limits lhs, Limits rhs); | 
| 570 static Limits Union(Limits lhs, Limits rhs); | 591 static Limits Union(Limits lhs, Limits rhs); | 
| 571 static bool Overlap(RangeType* lhs, RangeType* rhs); | 592 static bool Overlap(RangeType* lhs, RangeType* rhs); | 
| 572 static bool Contains(RangeType* lhs, RangeType* rhs); | 593 static bool Contains(RangeType* lhs, RangeType* rhs); | 
| 594 static bool Contains(RangeType* range, ConstantType* constant); | |
| 573 static bool Contains(RangeType* range, i::Object* val); | 595 static bool Contains(RangeType* range, i::Object* val); | 
| 574 | 596 | 
| 575 static int UpdateRange( | 597 static int UpdateRange( | 
| 576 RangeHandle type, UnionHandle result, int size, Region* region); | 598 RangeHandle type, UnionHandle result, int size, Region* region); | 
| 577 | 599 | 
| 600 static Limits IntersectRangeAndBitset(TypeHandle range, TypeHandle bits, | |
| 601 Region* region); | |
| 602 static Limits ToLimits(bitset bits, Region* region); | |
| 603 | |
| 578 bool SimplyEquals(TypeImpl* that); | 604 bool SimplyEquals(TypeImpl* that); | 
| 579 template<class TypeHandle> | 605 template<class TypeHandle> | 
| 580 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } | 606 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } | 
| 581 | 607 | 
| 582 static int AddToUnion( | 608 static int AddToUnion( | 
| 583 TypeHandle type, UnionHandle result, int size, Region* region); | 609 TypeHandle type, UnionHandle result, int size, Region* region); | 
| 584 static int IntersectAux( | 610 static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result, | 
| 585 TypeHandle type, TypeHandle other, | 611 int size, Limits* limits, Region* region); | 
| 586 UnionHandle result, int size, Region* region); | |
| 587 static TypeHandle NormalizeUnion(UnionHandle unioned, int size); | 612 static TypeHandle NormalizeUnion(UnionHandle unioned, int size); | 
| 613 static TypeHandle NormalizeRangeAndBitset(RangeHandle range, bitset* bits, | |
| 614 Region* region); | |
| 588 }; | 615 }; | 
| 589 | 616 | 
| 590 | 617 | 
| 591 // ----------------------------------------------------------------------------- | 618 // ----------------------------------------------------------------------------- | 
| 592 // Bitset types (internal). | 619 // Bitset types (internal). | 
| 593 | 620 | 
| 594 template<class Config> | 621 template<class Config> | 
| 595 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { | 622 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { | 
| 596 protected: | 623 protected: | 
| 597 friend class TypeImpl<Config>; | 624 friend class TypeImpl<Config>; | 
| 598 | 625 | 
| 599 enum { | 626 enum { | 
| 600 #define DECLARE_TYPE(type, value) k##type = (value), | 627 #define DECLARE_TYPE(type, value) k##type = (value), | 
| 601 BITSET_TYPE_LIST(DECLARE_TYPE) | 628 BITSET_TYPE_LIST(DECLARE_TYPE) | 
| 602 #undef DECLARE_TYPE | 629 #undef DECLARE_TYPE | 
| 603 kUnusedEOL = 0 | 630 kUnusedEOL = 0 | 
| 604 }; | 631 }; | 
| 605 | 632 | 
| 606 bitset Bitset() { return Config::as_bitset(this); } | 633 bitset Bitset() { return Config::as_bitset(this); } | 
| 607 | 634 | 
| 608 static TypeImpl* New(bitset bits) { | 635 static TypeImpl* New(bitset bits) { | 
| 609 DCHECK(bits == kNone || IsInhabited(bits)); | 636 if (FLAG_enable_slow_asserts) CheckNumberBits(bits); | 
| 610 | |
| 611 if (FLAG_enable_slow_asserts) { | |
| 612 // Check that the bitset does not contain any holes in number ranges. | |
| 613 bitset mask = kSemantic; | |
| 614 if (!i::SmiValuesAre31Bits()) { | |
| 615 mask &= ~(kOtherUnsigned31 | kOtherSigned32); | |
| 616 } | |
| 617 bitset number_bits = bits & kPlainNumber & mask; | |
| 618 if (number_bits != 0) { | |
| 619 bitset lub = Lub(Min(number_bits), Max(number_bits)) & mask; | |
| 620 CHECK(lub == number_bits); | |
| 621 } | |
| 622 } | |
| 623 | |
| 624 return Config::from_bitset(bits); | 637 return Config::from_bitset(bits); | 
| 625 } | 638 } | 
| 626 static TypeHandle New(bitset bits, Region* region) { | 639 static TypeHandle New(bitset bits, Region* region) { | 
| 627 DCHECK(bits == kNone || IsInhabited(bits)); | 640 if (FLAG_enable_slow_asserts) CheckNumberBits(bits); | 
| 628 return Config::from_bitset(bits, region); | 641 return Config::from_bitset(bits, region); | 
| 629 } | 642 } | 
| 630 // TODO(neis): Eventually allow again for types with empty semantics | 643 // TODO(neis): Eventually allow again for types with empty semantics | 
| 631 // part and modify intersection and possibly subtyping accordingly. | 644 // part and modify intersection and possibly subtyping accordingly. | 
| 632 | 645 | 
| 633 static bool IsInhabited(bitset bits) { | 646 static bool IsInhabited(bitset bits) { | 
| 634 return bits & kSemantic; | 647 return bits & kSemantic; | 
| 635 } | 648 } | 
| 636 | 649 | 
| 637 static bool Is(bitset bits1, bitset bits2) { | 650 static bool Is(bitset bits1, bitset bits2) { | 
| 638 return (bits1 | bits2) == bits2; | 651 return (bits1 | bits2) == bits2; | 
| 639 } | 652 } | 
| 640 | 653 | 
| 641 static double Min(bitset); | 654 static double Min(bitset); | 
| 642 static double Max(bitset); | 655 static double Max(bitset); | 
| 643 | 656 | 
| 644 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset | 657 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset | 
| 658 static bitset Glb(double min, double max); | |
| 645 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset | 659 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset | 
| 646 static bitset Lub(i::Map* map); | 660 static bitset Lub(i::Map* map); | 
| 647 static bitset Lub(i::Object* value); | 661 static bitset Lub(i::Object* value); | 
| 648 static bitset Lub(double value); | 662 static bitset Lub(double value); | 
| 649 static bitset Lub(double min, double max); | 663 static bitset Lub(double min, double max); | 
| 650 | 664 | 
| 651 static const char* Name(bitset); | 665 static const char* Name(bitset); | 
| 652 static void Print(std::ostream& os, bitset); // NOLINT | 666 static void Print(std::ostream& os, bitset); // NOLINT | 
| 653 #ifdef DEBUG | 667 #ifdef DEBUG | 
| 654 static void Print(bitset); | 668 static void Print(bitset); | 
| 655 #endif | 669 #endif | 
| 656 | 670 | 
| 657 private: | 671 private: | 
| 658 struct BitsetMin{ | 672 struct BitsetBoundary { | 
| 659 bitset bits; | 673 bitset bits; | 
| 660 double min; | 674 double min; | 
| 661 }; | 675 }; | 
| 662 static const BitsetMin BitsetMins31[]; | 676 static const BitsetBoundary BitsetBoundariesArray[]; | 
| 663 static const BitsetMin BitsetMins32[]; | 677 static const BitsetBoundary* BitsetBoundaries() { | 
| 664 static const BitsetMin* BitsetMins() { | 678 return BitsetBoundariesArray; | 
| 665 return i::SmiValuesAre31Bits() ? BitsetMins31 : BitsetMins32; | |
| 666 } | 679 } | 
| 667 static size_t BitsetMinsSize() { | 680 static size_t BitsetBoundariesSize() { | 
| 668 return i::SmiValuesAre31Bits() ? 7 : 5; | 681 return 7; | 
| 
rossberg
2015/01/15 15:15:12
Nit: maybe declare this 'inline' but move it to th
 
Jarin
2015/01/16 16:28:39
Done.
 | |
| 669 /* arraysize(BitsetMins31) : arraysize(BitsetMins32); */ | 682 /* arraysize(BitsetBoundariesArray); */ | 
| 670 // Using arraysize here doesn't compile on Windows. | 683 // Using arraysize here doesn't compile on Windows. | 
| 671 } | 684 } | 
| 685 | |
| 686 static void CheckNumberBits(bitset bits); | |
| 672 }; | 687 }; | 
| 673 | 688 | 
| 674 | 689 | 
| 675 // ----------------------------------------------------------------------------- | 690 // ----------------------------------------------------------------------------- | 
| 676 // Superclass for non-bitset types (internal). | 691 // Superclass for non-bitset types (internal). | 
| 677 // Contains a tag and a variable number of type or value fields. | 692 // Contains a tag and a variable number of type or value fields. | 
| 678 | 693 | 
| 679 template<class Config> | 694 template<class Config> | 
| 680 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { | 695 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { | 
| 681 protected: | 696 protected: | 
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 808 // TODO(neis): Also cache value if numerical. | 823 // TODO(neis): Also cache value if numerical. | 
| 809 // TODO(neis): Allow restricting the representation. | 824 // TODO(neis): Allow restricting the representation. | 
| 810 | 825 | 
| 811 | 826 | 
| 812 // ----------------------------------------------------------------------------- | 827 // ----------------------------------------------------------------------------- | 
| 813 // Range types. | 828 // Range types. | 
| 814 | 829 | 
| 815 template<class Config> | 830 template<class Config> | 
| 816 class TypeImpl<Config>::RangeType : public StructuralType { | 831 class TypeImpl<Config>::RangeType : public StructuralType { | 
| 817 public: | 832 public: | 
| 818 int BitsetLub() { return this->Get(0)->AsBitset(); } | 833 TypeHandle Bound() { return this->Get(0); } | 
| 819 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); } | 834 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); } | 
| 820 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); } | 835 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); } | 
| 821 | 836 | 
| 822 static RangeHandle New( | 837 static RangeHandle New(i::Handle<i::Object> min, i::Handle<i::Object> max, | 
| 823 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { | 838 TypeHandle representation, Region* region) { | 
| 824 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); | 839 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); | 
| 825 DCHECK(min->Number() <= max->Number()); | 840 DCHECK(min->Number() <= max->Number()); | 
| 841 bitset representation_bits = representation->AsBitset(); | |
| 842 DCHECK(REPRESENTATION(representation_bits) == representation_bits); | |
| 843 | |
| 826 RangeHandle type = Config::template cast<RangeType>( | 844 RangeHandle type = Config::template cast<RangeType>( | 
| 827 StructuralType::New(StructuralType::kRangeTag, 3, region)); | 845 StructuralType::New(StructuralType::kRangeTag, 3, region)); | 
| 828 type->Set(0, BitsetType::New( | 846 | 
| 829 BitsetType::Lub(min->Number(), max->Number()), region)); | 847 bitset bits = SEMANTIC(BitsetType::Lub(min->Number(), max->Number())) | | 
| 848 representation_bits; | |
| 849 type->Set(0, BitsetType::New(bits, region)); | |
| 830 type->SetValue(1, min); | 850 type->SetValue(1, min); | 
| 831 type->SetValue(2, max); | 851 type->SetValue(2, max); | 
| 832 return type; | 852 return type; | 
| 833 } | 853 } | 
| 834 | 854 | 
| 835 static RangeHandle New(Limits lim, Region* region) { | 855 static RangeHandle New(Limits lim, Region* region) { | 
| 836 return New(lim.min, lim.max, region); | 856 return New(lim.min, lim.max, BitsetType::New(lim.representation, region), | 
| 857 region); | |
| 837 } | 858 } | 
| 838 | 859 | 
| 839 static RangeType* cast(TypeImpl* type) { | 860 static RangeType* cast(TypeImpl* type) { | 
| 840 DCHECK(type->IsRange()); | 861 DCHECK(type->IsRange()); | 
| 841 return static_cast<RangeType*>(type); | 862 return static_cast<RangeType*>(type); | 
| 842 } | 863 } | 
| 843 }; | 864 }; | 
| 844 // TODO(neis): Also cache min and max values. | 865 // TODO(neis): Also cache min and max values. | 
| 845 // TODO(neis): Allow restricting the representation. | 866 // TODO(neis): Allow restricting the representation. | 
| 846 | 867 | 
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 975 static inline Struct* struct_create(int tag, int length, Zone* zone); | 996 static inline Struct* struct_create(int tag, int length, Zone* zone); | 
| 976 static inline void struct_shrink(Struct* structure, int length); | 997 static inline void struct_shrink(Struct* structure, int length); | 
| 977 static inline int struct_tag(Struct* structure); | 998 static inline int struct_tag(Struct* structure); | 
| 978 static inline int struct_length(Struct* structure); | 999 static inline int struct_length(Struct* structure); | 
| 979 static inline Type* struct_get(Struct* structure, int i); | 1000 static inline Type* struct_get(Struct* structure, int i); | 
| 980 static inline void struct_set(Struct* structure, int i, Type* type); | 1001 static inline void struct_set(Struct* structure, int i, Type* type); | 
| 981 template<class V> | 1002 template<class V> | 
| 982 static inline i::Handle<V> struct_get_value(Struct* structure, int i); | 1003 static inline i::Handle<V> struct_get_value(Struct* structure, int i); | 
| 983 template<class V> static inline void struct_set_value( | 1004 template<class V> static inline void struct_set_value( | 
| 984 Struct* structure, int i, i::Handle<V> x); | 1005 Struct* structure, int i, i::Handle<V> x); | 
| 1006 static inline i::Isolate* isolate(Zone* zone); | |
| 985 }; | 1007 }; | 
| 986 | 1008 | 
| 987 typedef TypeImpl<ZoneTypeConfig> Type; | 1009 typedef TypeImpl<ZoneTypeConfig> Type; | 
| 988 | 1010 | 
| 989 | 1011 | 
| 990 // ----------------------------------------------------------------------------- | 1012 // ----------------------------------------------------------------------------- | 
| 991 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for | 1013 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for | 
| 992 // constants, or fixed arrays for unions. | 1014 // constants, or fixed arrays for unions. | 
| 993 | 1015 | 
| 994 struct HeapTypeConfig { | 1016 struct HeapTypeConfig { | 
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1023 static inline int struct_length(i::Handle<Struct> structure); | 1045 static inline int struct_length(i::Handle<Struct> structure); | 
| 1024 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i); | 1046 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i); | 
| 1025 static inline void struct_set( | 1047 static inline void struct_set( | 
| 1026 i::Handle<Struct> structure, int i, i::Handle<Type> type); | 1048 i::Handle<Struct> structure, int i, i::Handle<Type> type); | 
| 1027 template<class V> | 1049 template<class V> | 
| 1028 static inline i::Handle<V> struct_get_value( | 1050 static inline i::Handle<V> struct_get_value( | 
| 1029 i::Handle<Struct> structure, int i); | 1051 i::Handle<Struct> structure, int i); | 
| 1030 template<class V> | 1052 template<class V> | 
| 1031 static inline void struct_set_value( | 1053 static inline void struct_set_value( | 
| 1032 i::Handle<Struct> structure, int i, i::Handle<V> x); | 1054 i::Handle<Struct> structure, int i, i::Handle<V> x); | 
| 1055 static inline i::Isolate* isolate(Isolate* isolate); | |
| 1033 }; | 1056 }; | 
| 1034 | 1057 | 
| 1035 typedef TypeImpl<HeapTypeConfig> HeapType; | 1058 typedef TypeImpl<HeapTypeConfig> HeapType; | 
| 1036 | 1059 | 
| 1037 | 1060 | 
| 1038 // ----------------------------------------------------------------------------- | 1061 // ----------------------------------------------------------------------------- | 
| 1039 // Type bounds. A simple struct to represent a pair of lower/upper types. | 1062 // Type bounds. A simple struct to represent a pair of lower/upper types. | 
| 1040 | 1063 | 
| 1041 template<class Config> | 1064 template<class Config> | 
| 1042 struct BoundsImpl { | 1065 struct BoundsImpl { | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1093 bool Narrows(BoundsImpl that) { | 1116 bool Narrows(BoundsImpl that) { | 
| 1094 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 1117 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 
| 1095 } | 1118 } | 
| 1096 }; | 1119 }; | 
| 1097 | 1120 | 
| 1098 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 1121 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 
| 1099 | 1122 | 
| 1100 } } // namespace v8::internal | 1123 } } // namespace v8::internal | 
| 1101 | 1124 | 
| 1102 #endif // V8_TYPES_H_ | 1125 #endif // V8_TYPES_H_ | 
| OLD | NEW |