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 |
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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ | 328 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ |
339 static TypeImpl* type() { \ | 329 static TypeImpl* type() { \ |
340 return BitsetType::New(BitsetType::k##type); \ | 330 return BitsetType::New(BitsetType::k##type); \ |
341 } \ | 331 } \ |
342 static TypeHandle type(Region* region) { \ | 332 static TypeHandle type(Region* region) { \ |
343 return BitsetType::New(BitsetType::k##type, region); \ | 333 return BitsetType::New(BitsetType::k##type, region); \ |
344 } | 334 } |
345 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) | 335 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) |
346 #undef DEFINE_TYPE_CONSTRUCTOR | 336 #undef DEFINE_TYPE_CONSTRUCTOR |
347 | 337 |
| 338 static TypeImpl* SignedSmall() { |
| 339 return BitsetType::New(BitsetType::SignedSmall()); |
| 340 } |
| 341 static TypeHandle SignedSmall(Region* region) { |
| 342 return BitsetType::New(BitsetType::SignedSmall(), region); |
| 343 } |
| 344 static TypeImpl* UnsignedSmall() { |
| 345 return BitsetType::New(BitsetType::UnsignedSmall()); |
| 346 } |
| 347 static TypeHandle UnsignedSmall(Region* region) { |
| 348 return BitsetType::New(BitsetType::UnsignedSmall(), region); |
| 349 } |
| 350 |
348 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { | 351 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { |
349 return ClassType::New(map, region); | 352 return ClassType::New(map, region); |
350 } | 353 } |
351 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { | 354 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { |
352 return ConstantType::New(value, region); | 355 return ConstantType::New(value, region); |
353 } | 356 } |
354 static TypeHandle Range( | 357 static TypeHandle Range( |
355 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { | 358 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) { |
356 return RangeType::New(min, max, region); | 359 return RangeType::New( |
| 360 min, max, BitsetType::New(REPRESENTATION(BitsetType::kTagged | |
| 361 BitsetType::kUntaggedNumber), |
| 362 region), |
| 363 region); |
357 } | 364 } |
358 static TypeHandle Context(TypeHandle outer, Region* region) { | 365 static TypeHandle Context(TypeHandle outer, Region* region) { |
359 return ContextType::New(outer, region); | 366 return ContextType::New(outer, region); |
360 } | 367 } |
361 static TypeHandle Array(TypeHandle element, Region* region) { | 368 static TypeHandle Array(TypeHandle element, Region* region) { |
362 return ArrayType::New(element, region); | 369 return ArrayType::New(element, region); |
363 } | 370 } |
364 static FunctionHandle Function( | 371 static FunctionHandle Function( |
365 TypeHandle result, TypeHandle receiver, int arity, Region* region) { | 372 TypeHandle result, TypeHandle receiver, int arity, Region* region) { |
366 return FunctionType::New(result, receiver, arity, region); | 373 return FunctionType::New(result, receiver, arity, region); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 static bool IsInteger(double x) { | 560 static bool IsInteger(double x) { |
554 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. | 561 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. |
555 } | 562 } |
556 static bool IsInteger(i::Object* x) { | 563 static bool IsInteger(i::Object* x) { |
557 return x->IsNumber() && IsInteger(x->Number()); | 564 return x->IsNumber() && IsInteger(x->Number()); |
558 } | 565 } |
559 | 566 |
560 struct Limits { | 567 struct Limits { |
561 i::Handle<i::Object> min; | 568 i::Handle<i::Object> min; |
562 i::Handle<i::Object> max; | 569 i::Handle<i::Object> max; |
563 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max) : | 570 bitset representation; |
564 min(min), max(max) {} | 571 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max, |
565 explicit Limits(RangeType* range) : | 572 bitset representation) |
566 min(range->Min()), max(range->Max()) {} | 573 : min(min), max(max), representation(representation) {} |
| 574 explicit Limits(RangeType* range) |
| 575 : min(range->Min()), |
| 576 max(range->Max()), |
| 577 representation(REPRESENTATION(range->Bound()->AsBitset())) {} |
| 578 static Limits Empty(Region* region) { |
| 579 // TODO(jarin) Get rid of the heap numbers. |
| 580 i::Factory* f = i::Isolate::Current()->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 } |
567 }; | 585 }; |
568 | 586 |
| 587 static bool IsEmpty(Limits lim); |
569 static Limits Intersect(Limits lhs, Limits rhs); | 588 static Limits Intersect(Limits lhs, Limits rhs); |
570 static Limits Union(Limits lhs, Limits rhs); | 589 static Limits Union(Limits lhs, Limits rhs); |
571 static bool Overlap(RangeType* lhs, RangeType* rhs); | 590 static bool Overlap(RangeType* lhs, RangeType* rhs); |
572 static bool Contains(RangeType* lhs, RangeType* rhs); | 591 static bool Contains(RangeType* lhs, RangeType* rhs); |
| 592 static bool Contains(RangeType* range, ConstantType* constant); |
573 static bool Contains(RangeType* range, i::Object* val); | 593 static bool Contains(RangeType* range, i::Object* val); |
574 | 594 |
575 static int UpdateRange( | 595 static int UpdateRange( |
576 RangeHandle type, UnionHandle result, int size, Region* region); | 596 RangeHandle type, UnionHandle result, int size, Region* region); |
577 | 597 |
| 598 static Limits IntersectRangeAndBitset(TypeHandle range, TypeHandle bits, |
| 599 Region* region); |
| 600 static Limits ToLimits(bitset bits, Region* region); |
| 601 |
578 bool SimplyEquals(TypeImpl* that); | 602 bool SimplyEquals(TypeImpl* that); |
579 template<class TypeHandle> | 603 template<class TypeHandle> |
580 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } | 604 bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } |
581 | 605 |
582 static int AddToUnion( | 606 static int AddToUnion( |
583 TypeHandle type, UnionHandle result, int size, Region* region); | 607 TypeHandle type, UnionHandle result, int size, Region* region); |
584 static int IntersectAux( | 608 static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result, |
585 TypeHandle type, TypeHandle other, | 609 int size, Limits* limits, Region* region); |
586 UnionHandle result, int size, Region* region); | |
587 static TypeHandle NormalizeUnion(UnionHandle unioned, int size); | 610 static TypeHandle NormalizeUnion(UnionHandle unioned, int size); |
| 611 static TypeHandle NormalizeRangeAndBitset(RangeHandle range, bitset* bits, |
| 612 Region* region); |
588 }; | 613 }; |
589 | 614 |
590 | 615 |
591 // ----------------------------------------------------------------------------- | 616 // ----------------------------------------------------------------------------- |
592 // Bitset types (internal). | 617 // Bitset types (internal). |
593 | 618 |
594 template<class Config> | 619 template<class Config> |
595 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { | 620 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { |
596 protected: | 621 protected: |
597 friend class TypeImpl<Config>; | 622 friend class TypeImpl<Config>; |
598 | 623 |
599 enum { | 624 enum { |
600 #define DECLARE_TYPE(type, value) k##type = (value), | 625 #define DECLARE_TYPE(type, value) k##type = (value), |
601 BITSET_TYPE_LIST(DECLARE_TYPE) | 626 BITSET_TYPE_LIST(DECLARE_TYPE) |
602 #undef DECLARE_TYPE | 627 #undef DECLARE_TYPE |
603 kUnusedEOL = 0 | 628 kUnusedEOL = 0 |
604 }; | 629 }; |
605 | 630 |
| 631 static bitset SignedSmall(); |
| 632 static bitset UnsignedSmall(); |
| 633 |
606 bitset Bitset() { return Config::as_bitset(this); } | 634 bitset Bitset() { return Config::as_bitset(this); } |
607 | 635 |
608 static TypeImpl* New(bitset bits) { | 636 static TypeImpl* New(bitset bits) { |
609 DCHECK(bits == kNone || IsInhabited(bits)); | 637 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); | 638 return Config::from_bitset(bits); |
625 } | 639 } |
626 static TypeHandle New(bitset bits, Region* region) { | 640 static TypeHandle New(bitset bits, Region* region) { |
627 DCHECK(bits == kNone || IsInhabited(bits)); | 641 if (FLAG_enable_slow_asserts) CheckNumberBits(bits); |
628 return Config::from_bitset(bits, region); | 642 return Config::from_bitset(bits, region); |
629 } | 643 } |
630 // TODO(neis): Eventually allow again for types with empty semantics | 644 // TODO(neis): Eventually allow again for types with empty semantics |
631 // part and modify intersection and possibly subtyping accordingly. | 645 // part and modify intersection and possibly subtyping accordingly. |
632 | 646 |
633 static bool IsInhabited(bitset bits) { | 647 static bool IsInhabited(bitset bits) { |
634 return bits & kSemantic; | 648 return bits & kSemantic; |
635 } | 649 } |
636 | 650 |
637 static bool Is(bitset bits1, bitset bits2) { | 651 static bool Is(bitset bits1, bitset bits2) { |
638 return (bits1 | bits2) == bits2; | 652 return (bits1 | bits2) == bits2; |
639 } | 653 } |
640 | 654 |
641 static double Min(bitset); | 655 static double Min(bitset); |
642 static double Max(bitset); | 656 static double Max(bitset); |
643 | 657 |
644 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset | 658 static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset |
| 659 static bitset Glb(double min, double max); |
645 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset | 660 static bitset Lub(TypeImpl* type); // least upper bound that's a bitset |
646 static bitset Lub(i::Map* map); | 661 static bitset Lub(i::Map* map); |
647 static bitset Lub(i::Object* value); | 662 static bitset Lub(i::Object* value); |
648 static bitset Lub(double value); | 663 static bitset Lub(double value); |
649 static bitset Lub(double min, double max); | 664 static bitset Lub(double min, double max); |
650 | 665 |
651 static const char* Name(bitset); | 666 static const char* Name(bitset); |
652 static void Print(std::ostream& os, bitset); // NOLINT | 667 static void Print(std::ostream& os, bitset); // NOLINT |
653 #ifdef DEBUG | 668 #ifdef DEBUG |
654 static void Print(bitset); | 669 static void Print(bitset); |
655 #endif | 670 #endif |
656 | 671 |
| 672 static bitset NumberBits(bitset bits); |
| 673 |
657 private: | 674 private: |
658 struct BitsetMin{ | 675 struct Boundary { |
659 bitset bits; | 676 bitset bits; |
660 double min; | 677 double min; |
661 }; | 678 }; |
662 static const BitsetMin BitsetMins31[]; | 679 static const Boundary BoundariesArray[]; |
663 static const BitsetMin BitsetMins32[]; | 680 static inline const Boundary* Boundaries(); |
664 static const BitsetMin* BitsetMins() { | 681 static inline size_t BoundariesSize(); |
665 return i::SmiValuesAre31Bits() ? BitsetMins31 : BitsetMins32; | 682 |
666 } | 683 static void CheckNumberBits(bitset bits); |
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 } | |
672 }; | 684 }; |
673 | 685 |
674 | 686 |
675 // ----------------------------------------------------------------------------- | 687 // ----------------------------------------------------------------------------- |
676 // Superclass for non-bitset types (internal). | 688 // Superclass for non-bitset types (internal). |
677 // Contains a tag and a variable number of type or value fields. | 689 // Contains a tag and a variable number of type or value fields. |
678 | 690 |
679 template<class Config> | 691 template<class Config> |
680 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { | 692 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { |
681 protected: | 693 protected: |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 // TODO(neis): Also cache value if numerical. | 820 // TODO(neis): Also cache value if numerical. |
809 // TODO(neis): Allow restricting the representation. | 821 // TODO(neis): Allow restricting the representation. |
810 | 822 |
811 | 823 |
812 // ----------------------------------------------------------------------------- | 824 // ----------------------------------------------------------------------------- |
813 // Range types. | 825 // Range types. |
814 | 826 |
815 template<class Config> | 827 template<class Config> |
816 class TypeImpl<Config>::RangeType : public StructuralType { | 828 class TypeImpl<Config>::RangeType : public StructuralType { |
817 public: | 829 public: |
818 int BitsetLub() { return this->Get(0)->AsBitset(); } | 830 TypeHandle Bound() { return this->Get(0); } |
819 i::Handle<i::Object> Min() { return this->template GetValue<i::Object>(1); } | 831 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); } | 832 i::Handle<i::Object> Max() { return this->template GetValue<i::Object>(2); } |
821 | 833 |
822 static RangeHandle New( | 834 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) { | 835 TypeHandle representation, Region* region) { |
824 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); | 836 DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); |
825 DCHECK(min->Number() <= max->Number()); | 837 DCHECK(min->Number() <= max->Number()); |
| 838 bitset representation_bits = representation->AsBitset(); |
| 839 DCHECK(REPRESENTATION(representation_bits) == representation_bits); |
| 840 |
826 RangeHandle type = Config::template cast<RangeType>( | 841 RangeHandle type = Config::template cast<RangeType>( |
827 StructuralType::New(StructuralType::kRangeTag, 3, region)); | 842 StructuralType::New(StructuralType::kRangeTag, 3, region)); |
828 type->Set(0, BitsetType::New( | 843 |
829 BitsetType::Lub(min->Number(), max->Number()), region)); | 844 bitset bits = SEMANTIC(BitsetType::Lub(min->Number(), max->Number())) | |
| 845 representation_bits; |
| 846 type->Set(0, BitsetType::New(bits, region)); |
830 type->SetValue(1, min); | 847 type->SetValue(1, min); |
831 type->SetValue(2, max); | 848 type->SetValue(2, max); |
832 return type; | 849 return type; |
833 } | 850 } |
834 | 851 |
835 static RangeHandle New(Limits lim, Region* region) { | 852 static RangeHandle New(Limits lim, Region* region) { |
836 return New(lim.min, lim.max, region); | 853 return New(lim.min, lim.max, BitsetType::New(lim.representation, region), |
| 854 region); |
837 } | 855 } |
838 | 856 |
839 static RangeType* cast(TypeImpl* type) { | 857 static RangeType* cast(TypeImpl* type) { |
840 DCHECK(type->IsRange()); | 858 DCHECK(type->IsRange()); |
841 return static_cast<RangeType*>(type); | 859 return static_cast<RangeType*>(type); |
842 } | 860 } |
843 }; | 861 }; |
844 // TODO(neis): Also cache min and max values. | 862 // TODO(neis): Also cache min and max values. |
845 // TODO(neis): Allow restricting the representation. | 863 // TODO(neis): Allow restricting the representation. |
846 | 864 |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1093 bool Narrows(BoundsImpl that) { | 1111 bool Narrows(BoundsImpl that) { |
1094 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 1112 return that.lower->Is(this->lower) && this->upper->Is(that.upper); |
1095 } | 1113 } |
1096 }; | 1114 }; |
1097 | 1115 |
1098 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 1116 typedef BoundsImpl<ZoneTypeConfig> Bounds; |
1099 | 1117 |
1100 } } // namespace v8::internal | 1118 } } // namespace v8::internal |
1101 | 1119 |
1102 #endif // V8_TYPES_H_ | 1120 #endif // V8_TYPES_H_ |
OLD | NEW |