| 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 | |
| 158 #define MASK_BITSET_TYPE_LIST(V) \ | 156 #define MASK_BITSET_TYPE_LIST(V) \ |
| 159 V(Representation, 0xfff00000u) \ | 157 V(Representation, 0xfff00000u) \ |
| 160 V(Semantic, 0x000ffffeu) | 158 V(Semantic, 0x000ffffeu) |
| 161 | 159 |
| 162 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation) | 160 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation) |
| 163 #define SEMANTIC(k) ((k) & BitsetType::kSemantic) | 161 #define SEMANTIC(k) ((k) & BitsetType::kSemantic) |
| 164 | 162 |
| 165 #define REPRESENTATION_BITSET_TYPE_LIST(V) \ | 163 #define REPRESENTATION_BITSET_TYPE_LIST(V) \ |
| 166 V(None, 0) \ | 164 V(None, 0) \ |
| 167 V(UntaggedBit, 1u << 20 | kSemantic) \ | 165 V(UntaggedBit, 1u << 20 | kSemantic) \ |
| (...skipping 22 matching lines...) Expand all Loading... |
| 190 V(Untagged, kUntaggedNumber | kUntaggedPointer) \ | 188 V(Untagged, kUntaggedNumber | kUntaggedPointer) \ |
| 191 V(Tagged, kTaggedSigned | kTaggedPointer) | 189 V(Tagged, kTaggedSigned | kTaggedPointer) |
| 192 | 190 |
| 193 #define INTERNAL_BITSET_TYPE_LIST(V) \ | 191 #define INTERNAL_BITSET_TYPE_LIST(V) \ |
| 194 V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 192 V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 195 V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 193 V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 196 V(OtherSigned32, 1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 194 V(OtherSigned32, 1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 197 V(OtherNumber, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) | 195 V(OtherNumber, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) |
| 198 | 196 |
| 199 #define SEMANTIC_BITSET_TYPE_LIST(V) \ | 197 #define SEMANTIC_BITSET_TYPE_LIST(V) \ |
| 200 V(Negative31, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 198 V(NegativeSignedSmall, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 201 V(Null, 1u << 6 | REPRESENTATION(kTaggedPointer)) \ | 199 V(Null, 1u << 6 | REPRESENTATION(kTaggedPointer)) \ |
| 202 V(Undefined, 1u << 7 | REPRESENTATION(kTaggedPointer)) \ | 200 V(Undefined, 1u << 7 | REPRESENTATION(kTaggedPointer)) \ |
| 203 V(Boolean, 1u << 8 | REPRESENTATION(kTaggedPointer)) \ | 201 V(Boolean, 1u << 8 | REPRESENTATION(kTaggedPointer)) \ |
| 204 V(Unsigned30, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 202 V(UnsignedSmall, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 205 V(MinusZero, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 203 V(MinusZero, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 206 V(NaN, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \ | 204 V(NaN, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \ |
| 207 V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \ | 205 V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \ |
| 208 V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \ | 206 V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \ |
| 209 V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \ | 207 V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \ |
| 210 V(Undetectable, 1u << 15 | REPRESENTATION(kTaggedPointer)) \ | 208 V(Undetectable, 1u << 15 | REPRESENTATION(kTaggedPointer)) \ |
| 211 V(Array, 1u << 16 | REPRESENTATION(kTaggedPointer)) \ | 209 V(Array, 1u << 16 | REPRESENTATION(kTaggedPointer)) \ |
| 212 V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \ | 210 V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \ |
| 213 V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \ | 211 V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \ |
| 214 V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \ | 212 V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \ |
| 215 \ | 213 \ |
| 216 V(Signed31, kUnsigned30 | kNegative31) \ | 214 V(SignedSmall, kUnsignedSmall | kNegativeSignedSmall) \ |
| 217 V(Signed32, kSigned31 | kOtherUnsigned31 | kOtherSigned32) \ | 215 V(Signed32, kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \ |
| 218 V(Negative32, kNegative31 | kOtherSigned32) \ | 216 V(NegativeSigned32, kNegativeSignedSmall | kOtherSigned32) \ |
| 219 V(Unsigned31, kUnsigned30 | kOtherUnsigned31) \ | 217 V(NonNegativeSigned32, kUnsignedSmall | kOtherUnsigned31) \ |
| 220 V(Unsigned32, kUnsigned30 | kOtherUnsigned31 | kOtherUnsigned32) \ | 218 V(Unsigned32, kUnsignedSmall | kOtherUnsigned31 | kOtherUnsigned32) \ |
| 221 V(Integral32, kSigned32 | kUnsigned32) \ | 219 V(Integral32, kSigned32 | kUnsigned32) \ |
| 222 V(PlainNumber, kIntegral32 | kOtherNumber) \ | 220 V(PlainNumber, kIntegral32 | kOtherNumber) \ |
| 223 V(OrderedNumber, kPlainNumber | kMinusZero) \ | 221 V(OrderedNumber, kPlainNumber | kMinusZero) \ |
| 224 V(Number, kOrderedNumber | kNaN) \ | 222 V(Number, kOrderedNumber | kNaN) \ |
| 225 V(String, kInternalizedString | kOtherString) \ | 223 V(String, kInternalizedString | kOtherString) \ |
| 226 V(UniqueName, kSymbol | kInternalizedString) \ | 224 V(UniqueName, kSymbol | kInternalizedString) \ |
| 227 V(Name, kSymbol | kString) \ | 225 V(Name, kSymbol | kString) \ |
| 228 V(NumberOrString, kNumber | kString) \ | 226 V(NumberOrString, kNumber | kString) \ |
| 229 V(PlainPrimitive, kNumberOrString | kBoolean | kNull | kUndefined) \ | 227 V(PlainPrimitive, kNumberOrString | kBoolean | kNull | kUndefined) \ |
| 230 V(Primitive, kSymbol | kPlainPrimitive) \ | 228 V(Primitive, kSymbol | kPlainPrimitive) \ |
| 231 V(DetectableObject, kArray | kOtherObject) \ | 229 V(DetectableObject, kArray | kOtherObject) \ |
| 232 V(DetectableReceiver, kDetectableObject | kProxy) \ | 230 V(DetectableReceiver, kDetectableObject | kProxy) \ |
| 233 V(Detectable, kDetectableReceiver | kNumber | kName) \ | 231 V(Detectable, kDetectableReceiver | kNumber | kName) \ |
| 234 V(Object, kDetectableObject | kUndetectable) \ | 232 V(Object, kDetectableObject | kUndetectable) \ |
| 235 V(Receiver, kObject | kProxy) \ | 233 V(Receiver, kObject | kProxy) \ |
| 236 V(StringOrReceiver, kString | kReceiver) \ | 234 V(StringOrReceiver, kString | kReceiver) \ |
| 237 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \ | 235 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \ |
| 238 kReceiver) \ | 236 kReceiver) \ |
| 239 V(NonNumber, kUnique | kString | kInternal) \ | 237 V(NonNumber, kUnique | kString | kInternal) \ |
| 240 V(Any, 0xfffffffeu) | 238 V(Any, 0xfffffffeu) |
| 241 | 239 |
| 242 // clang-format on | |
| 243 | 240 |
| 244 /* | 241 /* |
| 245 * The following diagrams show how integers (in the mathematical sense) are | 242 * The following diagrams show how integers (in the mathematical sense) are |
| 246 * divided among the different atomic numerical types. | 243 * divided among the different atomic numerical types. |
| 247 * | 244 * |
| 248 * ON OS32 N31 U30 OU31 OU32 ON | 245 * If SmiValuesAre31Bits(): |
| 246 * |
| 247 * ON OS32 OSS US OU31 OU32 ON |
| 249 * ______[_______[_______[_______[_______[_______[_______ | 248 * ______[_______[_______[_______[_______[_______[_______ |
| 250 * -2^31 -2^30 0 2^30 2^31 2^32 | 249 * -2^31 -2^30 0 2^30 2^31 2^32 |
| 251 * | 250 * |
| 251 * Otherwise: |
| 252 * |
| 253 * ON OSS US OU32 ON |
| 254 * ______[_______________[_______________[_______[_______ |
| 255 * -2^31 0 2^31 2^32 |
| 256 * |
| 257 * |
| 252 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. | 258 * 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. |
| 253 */ | 263 */ |
| 254 | 264 |
| 255 #define PROPER_BITSET_TYPE_LIST(V) \ | 265 #define PROPER_BITSET_TYPE_LIST(V) \ |
| 256 REPRESENTATION_BITSET_TYPE_LIST(V) \ | 266 REPRESENTATION_BITSET_TYPE_LIST(V) \ |
| 257 SEMANTIC_BITSET_TYPE_LIST(V) | 267 SEMANTIC_BITSET_TYPE_LIST(V) |
| 258 | 268 |
| 259 #define BITSET_TYPE_LIST(V) \ | 269 #define BITSET_TYPE_LIST(V) \ |
| 260 MASK_BITSET_TYPE_LIST(V) \ | 270 MASK_BITSET_TYPE_LIST(V) \ |
| 261 REPRESENTATION_BITSET_TYPE_LIST(V) \ | 271 REPRESENTATION_BITSET_TYPE_LIST(V) \ |
| 262 INTERNAL_BITSET_TYPE_LIST(V) \ | 272 INTERNAL_BITSET_TYPE_LIST(V) \ |
| (...skipping 25 matching lines...) Expand all Loading... |
| 288 // static Handle<Struct>::type struct_create(int tag, int length, Region*); | 298 // static Handle<Struct>::type struct_create(int tag, int length, Region*); |
| 289 // static void struct_shrink(Handle<Struct>::type, int length); | 299 // static void struct_shrink(Handle<Struct>::type, int length); |
| 290 // static int struct_tag(Handle<Struct>::type); | 300 // static int struct_tag(Handle<Struct>::type); |
| 291 // static int struct_length(Handle<Struct>::type); | 301 // static int struct_length(Handle<Struct>::type); |
| 292 // static Handle<Type>::type struct_get(Handle<Struct>::type, int); | 302 // static Handle<Type>::type struct_get(Handle<Struct>::type, int); |
| 293 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type); | 303 // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type); |
| 294 // template<class V> | 304 // template<class V> |
| 295 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int); | 305 // static i::Handle<V> struct_get_value(Handle<Struct>::type, int); |
| 296 // template<class V> | 306 // template<class V> |
| 297 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>); | 307 // static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>); |
| 298 // static i::Isolate* isolate(Region* region); | |
| 299 // } | 308 // } |
| 300 template<class Config> | 309 template<class Config> |
| 301 class TypeImpl : public Config::Base { | 310 class TypeImpl : public Config::Base { |
| 302 public: | 311 public: |
| 303 // Auxiliary types. | 312 // Auxiliary types. |
| 304 | 313 |
| 305 typedef uint32_t bitset; // Internal | 314 typedef uint32_t bitset; // Internal |
| 306 class BitsetType; // Internal | 315 class BitsetType; // Internal |
| 307 class StructuralType; // Internal | 316 class StructuralType; // Internal |
| 308 class UnionType; // Internal | 317 class UnionType; // Internal |
| (...skipping 20 matching lines...) Expand all Loading... |
| 329 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ | 338 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ |
| 330 static TypeImpl* type() { \ | 339 static TypeImpl* type() { \ |
| 331 return BitsetType::New(BitsetType::k##type); \ | 340 return BitsetType::New(BitsetType::k##type); \ |
| 332 } \ | 341 } \ |
| 333 static TypeHandle type(Region* region) { \ | 342 static TypeHandle type(Region* region) { \ |
| 334 return BitsetType::New(BitsetType::k##type, region); \ | 343 return BitsetType::New(BitsetType::k##type, region); \ |
| 335 } | 344 } |
| 336 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) | 345 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) |
| 337 #undef DEFINE_TYPE_CONSTRUCTOR | 346 #undef DEFINE_TYPE_CONSTRUCTOR |
| 338 | 347 |
| 339 static TypeImpl* SignedSmall() { | |
| 340 return BitsetType::New(BitsetType::SignedSmall()); | |
| 341 } | |
| 342 static TypeHandle SignedSmall(Region* region) { | |
| 343 return BitsetType::New(BitsetType::SignedSmall(), region); | |
| 344 } | |
| 345 static TypeImpl* UnsignedSmall() { | |
| 346 return BitsetType::New(BitsetType::UnsignedSmall()); | |
| 347 } | |
| 348 static TypeHandle UnsignedSmall(Region* region) { | |
| 349 return BitsetType::New(BitsetType::UnsignedSmall(), region); | |
| 350 } | |
| 351 | |
| 352 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { | 348 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { |
| 353 return ClassType::New(map, region); | 349 return ClassType::New(map, region); |
| 354 } | 350 } |
| 355 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { | 351 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { |
| 356 return ConstantType::New(value, region); | 352 return ConstantType::New(value, region); |
| 357 } | 353 } |
| 358 static TypeHandle Range( | 354 static TypeHandle Range( |
| 359 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { | 355 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { |
| 360 return RangeType::New( | 356 return RangeType::New(min, max, region); |
| 361 min, max, BitsetType::New(REPRESENTATION(BitsetType::kTagged | | |
| 362 BitsetType::kUntaggedNumber), | |
| 363 region), | |
| 364 region); | |
| 365 } | 357 } |
| 366 static TypeHandle Context(TypeHandle outer, Region* region) { | 358 static TypeHandle Context(TypeHandle outer, Region* region) { |
| 367 return ContextType::New(outer, region); | 359 return ContextType::New(outer, region); |
| 368 } | 360 } |
| 369 static TypeHandle Array(TypeHandle element, Region* region) { | 361 static TypeHandle Array(TypeHandle element, Region* region) { |
| 370 return ArrayType::New(element, region); | 362 return ArrayType::New(element, region); |
| 371 } | 363 } |
| 372 static FunctionHandle Function( | 364 static FunctionHandle Function( |
| 373 TypeHandle result, TypeHandle receiver, int arity, Region* region) { | 365 TypeHandle result, TypeHandle receiver, int arity, Region* region) { |
| 374 return FunctionType::New(result, receiver, arity, region); | 366 return FunctionType::New(result, receiver, arity, region); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 static bool IsInteger(double x) { | 553 static bool IsInteger(double x) { |
| 562 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. | 554 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. |
| 563 } | 555 } |
| 564 static bool IsInteger(i::Object* x) { | 556 static bool IsInteger(i::Object* x) { |
| 565 return x->IsNumber() && IsInteger(x->Number()); | 557 return x->IsNumber() && IsInteger(x->Number()); |
| 566 } | 558 } |
| 567 | 559 |
| 568 struct Limits { | 560 struct Limits { |
| 569 i::Handle<i::Object> min; | 561 i::Handle<i::Object> min; |
| 570 i::Handle<i::Object> max; | 562 i::Handle<i::Object> max; |
| 571 bitset representation; | 563 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max) : |
| 572 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max, | 564 min(min), max(max) {} |
| 573 bitset representation) | 565 explicit Limits(RangeType* range) : |
| 574 : min(min), max(max), representation(representation) {} | 566 min(range->Min()), max(range->Max()) {} |
| 575 explicit Limits(RangeType* range) | |
| 576 : min(range->Min()), | |
| 577 max(range->Max()), | |
| 578 representation(REPRESENTATION(range->Bound()->AsBitset())) {} | |
| 579 static Limits Empty(Region* region) { | |
| 580 i::Factory* f = Config::isolate(region)->factory(); | |
| 581 i::Handle<i::Object> min = f->NewNumber(1); | |
| 582 i::Handle<i::Object> max = f->NewNumber(0); | |
| 583 return Limits(min, max, BitsetType::kNone); | |
| 584 } | |
| 585 }; | 567 }; |
| 586 | 568 |
| 587 static bool IsEmpty(Limits lim); | |
| 588 static Limits Intersect(Limits lhs, Limits rhs); | 569 static Limits Intersect(Limits lhs, Limits rhs); |
| 589 static Limits Union(Limits lhs, Limits rhs); | 570 static Limits Union(Limits lhs, Limits rhs); |
| 590 static bool Overlap(RangeType* lhs, RangeType* rhs); | 571 static bool Overlap(RangeType* lhs, RangeType* rhs); |
| 591 static bool Contains(RangeType* lhs, RangeType* rhs); | 572 static bool Contains(RangeType* lhs, RangeType* rhs); |
| 592 static bool Contains(RangeType* range, ConstantType* constant); | |
| 593 static bool Contains(RangeType* range, i::Object* val); | 573 static bool Contains(RangeType* range, i::Object* val); |
| 594 | 574 |
| 595 static int UpdateRange( | 575 static int UpdateRange( |
| 596 RangeHandle type, UnionHandle result, int size, Region* region); | 576 RangeHandle type, UnionHandle result, int size, Region* region); |
| 597 | 577 |
| 598 static Limits IntersectRangeAndBitset(TypeHandle range, TypeHandle bits, | |
| 599 Region* region); | |
| 600 static Limits ToLimits(bitset bits, Region* region); | |
| 601 | |
| 602 bool SimplyEquals(TypeImpl* that); | 578 bool SimplyEquals(TypeImpl* that); |
| 603 template<class TypeHandle> | 579 template<class TypeHandle> |
| 604 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } | 580 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } |
| 605 | 581 |
| 606 static int AddToUnion( | 582 static int AddToUnion( |
| 607 TypeHandle type, UnionHandle result, int size, Region* region); | 583 TypeHandle type, UnionHandle result, int size, Region* region); |
| 608 static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result, | 584 static int IntersectAux( |
| 609 int size, Limits* limits, Region* region); | 585 TypeHandle type, TypeHandle other, |
| 586 UnionHandle result, int size, Region* region); |
| 610 static TypeHandle NormalizeUnion(UnionHandle unioned, int size); | 587 static TypeHandle NormalizeUnion(UnionHandle unioned, int size); |
| 611 static TypeHandle NormalizeRangeAndBitset(RangeHandle range, bitset* bits, | |
| 612 Region* region); | |
| 613 }; | 588 }; |
| 614 | 589 |
| 615 | 590 |
| 616 // ----------------------------------------------------------------------------- | 591 // ----------------------------------------------------------------------------- |
| 617 // Bitset types (internal). | 592 // Bitset types (internal). |
| 618 | 593 |
| 619 template<class Config> | 594 template<class Config> |
| 620 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { | 595 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { |
| 621 protected: | 596 protected: |
| 622 friend class TypeImpl<Config>; | 597 friend class TypeImpl<Config>; |
| 623 | 598 |
| 624 enum { | 599 enum { |
| 625 #define DECLARE_TYPE(type, value) k##type = (value), | 600 #define DECLARE_TYPE(type, value) k##type = (value), |
| 626 BITSET_TYPE_LIST(DECLARE_TYPE) | 601 BITSET_TYPE_LIST(DECLARE_TYPE) |
| 627 #undef DECLARE_TYPE | 602 #undef DECLARE_TYPE |
| 628 kUnusedEOL = 0 | 603 kUnusedEOL = 0 |
| 629 }; | 604 }; |
| 630 | 605 |
| 631 static bitset SignedSmall(); | |
| 632 static bitset UnsignedSmall(); | |
| 633 | |
| 634 bitset Bitset() { return Config::as_bitset(this); } | 606 bitset Bitset() { return Config::as_bitset(this); } |
| 635 | 607 |
| 636 static TypeImpl* New(bitset bits) { | 608 static TypeImpl* New(bitset bits) { |
| 637 if (FLAG_enable_slow_asserts) CheckNumberBits(bits); | 609 DCHECK(bits == kNone || IsInhabited(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 |
| 638 return Config::from_bitset(bits); | 624 return Config::from_bitset(bits); |
| 639 } | 625 } |
| 640 static TypeHandle New(bitset bits, Region* region) { | 626 static TypeHandle New(bitset bits, Region* region) { |
| 641 if (FLAG_enable_slow_asserts) CheckNumberBits(bits); | 627 DCHECK(bits == kNone || IsInhabited(bits)); |
| 642 return Config::from_bitset(bits, region); | 628 return Config::from_bitset(bits, region); |
| 643 } | 629 } |
| 644 // TODO(neis): Eventually allow again for types with empty semantics | 630 // TODO(neis): Eventually allow again for types with empty semantics |
| 645 // part and modify intersection and possibly subtyping accordingly. | 631 // part and modify intersection and possibly subtyping accordingly. |
| 646 | 632 |
| 647 static bool IsInhabited(bitset bits) { | 633 static bool IsInhabited(bitset bits) { |
| 648 return bits & kSemantic; | 634 return bits & kSemantic; |
| 649 } | 635 } |
| 650 | 636 |
| 651 static bool Is(bitset bits1, bitset bits2) { | 637 static bool Is(bitset bits1, bitset bits2) { |
| 652 return (bits1 | bits2) == bits2; | 638 return (bits1 | bits2) == bits2; |
| 653 } | 639 } |
| 654 | 640 |
| 655 static double Min(bitset); | 641 static double Min(bitset); |
| 656 static double Max(bitset); | 642 static double Max(bitset); |
| 657 | 643 |
| 658 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset | 644 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset |
| 659 static bitset Glb(double min, double max); | |
| 660 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset | 645 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset |
| 661 static bitset Lub(i::Map* map); | 646 static bitset Lub(i::Map* map); |
| 662 static bitset Lub(i::Object* value); | 647 static bitset Lub(i::Object* value); |
| 663 static bitset Lub(double value); | 648 static bitset Lub(double value); |
| 664 static bitset Lub(double min, double max); | 649 static bitset Lub(double min, double max); |
| 665 | 650 |
| 666 static const char* Name(bitset); | 651 static const char* Name(bitset); |
| 667 static void Print(std::ostream& os, bitset); // NOLINT | 652 static void Print(std::ostream& os, bitset); // NOLINT |
| 668 #ifdef DEBUG | 653 #ifdef DEBUG |
| 669 static void Print(bitset); | 654 static void Print(bitset); |
| 670 #endif | 655 #endif |
| 671 | 656 |
| 672 static bitset NumberBits(bitset bits); | |
| 673 | |
| 674 private: | 657 private: |
| 675 struct Boundary { | 658 struct BitsetMin{ |
| 676 bitset bits; | 659 bitset bits; |
| 677 double min; | 660 double min; |
| 678 }; | 661 }; |
| 679 static const Boundary BoundariesArray[]; | 662 static const BitsetMin BitsetMins31[]; |
| 680 static inline const Boundary* Boundaries(); | 663 static const BitsetMin BitsetMins32[]; |
| 681 static inline size_t BoundariesSize(); | 664 static const BitsetMin* BitsetMins() { |
| 682 | 665 return i::SmiValuesAre31Bits() ? BitsetMins31 : BitsetMins32; |
| 683 static void CheckNumberBits(bitset bits); | 666 } |
| 667 static size_t BitsetMinsSize() { |
| 668 return i::SmiValuesAre31Bits() ? 7 : 5; |
| 669 /* arraysize(BitsetMins31) : arraysize(BitsetMins32); */ |
| 670 // Using arraysize here doesn't compile on Windows. |
| 671 } |
| 684 }; | 672 }; |
| 685 | 673 |
| 686 | 674 |
| 687 // ----------------------------------------------------------------------------- | 675 // ----------------------------------------------------------------------------- |
| 688 // Superclass for non-bitset types (internal). | 676 // Superclass for non-bitset types (internal). |
| 689 // Contains a tag and a variable number of type or value fields. | 677 // Contains a tag and a variable number of type or value fields. |
| 690 | 678 |
| 691 template<class Config> | 679 template<class Config> |
| 692 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { | 680 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { |
| 693 protected: | 681 protected: |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 // TODO(neis): Also cache value if numerical. | 808 // TODO(neis): Also cache value if numerical. |
| 821 // TODO(neis): Allow restricting the representation. | 809 // TODO(neis): Allow restricting the representation. |
| 822 | 810 |
| 823 | 811 |
| 824 // ----------------------------------------------------------------------------- | 812 // ----------------------------------------------------------------------------- |
| 825 // Range types. | 813 // Range types. |
| 826 | 814 |
| 827 template<class Config> | 815 template<class Config> |
| 828 class TypeImpl<Config>::RangeType : public StructuralType { | 816 class TypeImpl<Config>::RangeType : public StructuralType { |
| 829 public: | 817 public: |
| 830 TypeHandle Bound() { return this->Get(0); } | 818 int BitsetLub() { return this->Get(0)->AsBitset(); } |
| 831 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); } | 819 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); } |
| 832 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); } | 820 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); } |
| 833 | 821 |
| 834 static RangeHandle New(i::Handle<i::Object> min, i::Handle<i::Object> max, | 822 static RangeHandle New( |
| 835 TypeHandle representation, Region* region) { | 823 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { |
| 836 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); | 824 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); |
| 837 DCHECK(min->Number() <= max->Number()); | 825 DCHECK(min->Number() <= max->Number()); |
| 838 bitset representation_bits = representation->AsBitset(); | |
| 839 DCHECK(REPRESENTATION(representation_bits) == representation_bits); | |
| 840 | |
| 841 RangeHandle type = Config::template cast<RangeType>( | 826 RangeHandle type = Config::template cast<RangeType>( |
| 842 StructuralType::New(StructuralType::kRangeTag, 3, region)); | 827 StructuralType::New(StructuralType::kRangeTag, 3, region)); |
| 843 | 828 type->Set(0, BitsetType::New( |
| 844 bitset bits = SEMANTIC(BitsetType::Lub(min->Number(), max->Number())) | | 829 BitsetType::Lub(min->Number(), max->Number()), region)); |
| 845 representation_bits; | |
| 846 type->Set(0, BitsetType::New(bits, region)); | |
| 847 type->SetValue(1, min); | 830 type->SetValue(1, min); |
| 848 type->SetValue(2, max); | 831 type->SetValue(2, max); |
| 849 return type; | 832 return type; |
| 850 } | 833 } |
| 851 | 834 |
| 852 static RangeHandle New(Limits lim, Region* region) { | 835 static RangeHandle New(Limits lim, Region* region) { |
| 853 return New(lim.min, lim.max, BitsetType::New(lim.representation, region), | 836 return New(lim.min, lim.max, region); |
| 854 region); | |
| 855 } | 837 } |
| 856 | 838 |
| 857 static RangeType* cast(TypeImpl* type) { | 839 static RangeType* cast(TypeImpl* type) { |
| 858 DCHECK(type->IsRange()); | 840 DCHECK(type->IsRange()); |
| 859 return static_cast<RangeType*>(type); | 841 return static_cast<RangeType*>(type); |
| 860 } | 842 } |
| 861 }; | 843 }; |
| 862 // TODO(neis): Also cache min and max values. | 844 // TODO(neis): Also cache min and max values. |
| 863 // TODO(neis): Allow restricting the representation. | 845 // TODO(neis): Allow restricting the representation. |
| 864 | 846 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 static inline Struct* struct_create(int tag, int length, Zone* zone); | 975 static inline Struct* struct_create(int tag, int length, Zone* zone); |
| 994 static inline void struct_shrink(Struct* structure, int length); | 976 static inline void struct_shrink(Struct* structure, int length); |
| 995 static inline int struct_tag(Struct* structure); | 977 static inline int struct_tag(Struct* structure); |
| 996 static inline int struct_length(Struct* structure); | 978 static inline int struct_length(Struct* structure); |
| 997 static inline Type* struct_get(Struct* structure, int i); | 979 static inline Type* struct_get(Struct* structure, int i); |
| 998 static inline void struct_set(Struct* structure, int i, Type* type); | 980 static inline void struct_set(Struct* structure, int i, Type* type); |
| 999 template<class V> | 981 template<class V> |
| 1000 static inline i::Handle<V> struct_get_value(Struct* structure, int i); | 982 static inline i::Handle<V> struct_get_value(Struct* structure, int i); |
| 1001 template<class V> static inline void struct_set_value( | 983 template<class V> static inline void struct_set_value( |
| 1002 Struct* structure, int i, i::Handle<V> x); | 984 Struct* structure, int i, i::Handle<V> x); |
| 1003 static inline i::Isolate* isolate(Zone* zone); | |
| 1004 }; | 985 }; |
| 1005 | 986 |
| 1006 typedef TypeImpl<ZoneTypeConfig> Type; | 987 typedef TypeImpl<ZoneTypeConfig> Type; |
| 1007 | 988 |
| 1008 | 989 |
| 1009 // ----------------------------------------------------------------------------- | 990 // ----------------------------------------------------------------------------- |
| 1010 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for | 991 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for |
| 1011 // constants, or fixed arrays for unions. | 992 // constants, or fixed arrays for unions. |
| 1012 | 993 |
| 1013 struct HeapTypeConfig { | 994 struct HeapTypeConfig { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1042 static inline int struct_length(i::Handle<Struct> structure); | 1023 static inline int struct_length(i::Handle<Struct> structure); |
| 1043 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i); | 1024 static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i); |
| 1044 static inline void struct_set( | 1025 static inline void struct_set( |
| 1045 i::Handle<Struct> structure, int i, i::Handle<Type> type); | 1026 i::Handle<Struct> structure, int i, i::Handle<Type> type); |
| 1046 template<class V> | 1027 template<class V> |
| 1047 static inline i::Handle<V> struct_get_value( | 1028 static inline i::Handle<V> struct_get_value( |
| 1048 i::Handle<Struct> structure, int i); | 1029 i::Handle<Struct> structure, int i); |
| 1049 template<class V> | 1030 template<class V> |
| 1050 static inline void struct_set_value( | 1031 static inline void struct_set_value( |
| 1051 i::Handle<Struct> structure, int i, i::Handle<V> x); | 1032 i::Handle<Struct> structure, int i, i::Handle<V> x); |
| 1052 static inline i::Isolate* isolate(Isolate* isolate); | |
| 1053 }; | 1033 }; |
| 1054 | 1034 |
| 1055 typedef TypeImpl<HeapTypeConfig> HeapType; | 1035 typedef TypeImpl<HeapTypeConfig> HeapType; |
| 1056 | 1036 |
| 1057 | 1037 |
| 1058 // ----------------------------------------------------------------------------- | 1038 // ----------------------------------------------------------------------------- |
| 1059 // Type bounds. A simple struct to represent a pair of lower/upper types. | 1039 // Type bounds. A simple struct to represent a pair of lower/upper types. |
| 1060 | 1040 |
| 1061 template<class Config> | 1041 template<class Config> |
| 1062 struct BoundsImpl { | 1042 struct BoundsImpl { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1113 bool Narrows(BoundsImpl that) { | 1093 bool Narrows(BoundsImpl that) { |
| 1114 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 1094 return that.lower->Is(this->lower) && this->upper->Is(that.upper); |
| 1115 } | 1095 } |
| 1116 }; | 1096 }; |
| 1117 | 1097 |
| 1118 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 1098 typedef BoundsImpl<ZoneTypeConfig> Bounds; |
| 1119 | 1099 |
| 1120 } } // namespace v8::internal | 1100 } } // namespace v8::internal |
| 1121 | 1101 |
| 1122 #endif // V8_TYPES_H_ | 1102 #endif // V8_TYPES_H_ |
| OLD | NEW |