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_COMPILER_TYPES_H_ | 5 #ifndef V8_COMPILER_TYPES_H_ |
6 #define V8_COMPILER_TYPES_H_ | 6 #define V8_COMPILER_TYPES_H_ |
7 | 7 |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/handles.h" | 9 #include "src/handles.h" |
10 #include "src/objects-inl.h" | |
10 #include "src/objects.h" | 11 #include "src/objects.h" |
11 #include "src/ostreams.h" | 12 #include "src/ostreams.h" |
12 | 13 |
13 namespace v8 { | 14 namespace v8 { |
14 namespace internal { | 15 namespace internal { |
15 namespace compiler { | 16 namespace compiler { |
16 | 17 |
17 // SUMMARY | 18 // SUMMARY |
18 // | 19 // |
19 // A simple type system for compiler-internal use. It is based entirely on | 20 // A simple type system for compiler-internal use. It is based entirely on |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 static inline const Boundary* Boundaries(); | 257 static inline const Boundary* Boundaries(); |
257 static inline size_t BoundariesSize(); | 258 static inline size_t BoundariesSize(); |
258 }; | 259 }; |
259 | 260 |
260 // ----------------------------------------------------------------------------- | 261 // ----------------------------------------------------------------------------- |
261 // Superclass for non-bitset types (internal). | 262 // Superclass for non-bitset types (internal). |
262 class TypeBase { | 263 class TypeBase { |
263 protected: | 264 protected: |
264 friend class Type; | 265 friend class Type; |
265 | 266 |
266 enum Kind { kConstant, kTuple, kUnion, kRange }; | 267 enum Kind { kConstant, kOtherNumberConstant, kTuple, kUnion, kRange }; |
267 | 268 |
268 Kind kind() const { return kind_; } | 269 Kind kind() const { return kind_; } |
269 explicit TypeBase(Kind kind) : kind_(kind) {} | 270 explicit TypeBase(Kind kind) : kind_(kind) {} |
270 | 271 |
271 static bool IsKind(Type* type, Kind kind) { | 272 static bool IsKind(Type* type, Kind kind) { |
272 if (BitsetType::IsBitset(type)) return false; | 273 if (BitsetType::IsBitset(type)) return false; |
273 TypeBase* base = reinterpret_cast<TypeBase*>(type); | 274 TypeBase* base = reinterpret_cast<TypeBase*>(type); |
274 return base->kind() == kind; | 275 return base->kind() == kind; |
275 } | 276 } |
276 | 277 |
277 // The hacky conversion to/from Type*. | 278 // The hacky conversion to/from Type*. |
278 static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); } | 279 static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); } |
279 static TypeBase* FromType(Type* type) { | 280 static TypeBase* FromType(Type* type) { |
280 return reinterpret_cast<TypeBase*>(type); | 281 return reinterpret_cast<TypeBase*>(type); |
281 } | 282 } |
282 | 283 |
283 private: | 284 private: |
284 Kind kind_; | 285 Kind kind_; |
285 }; | 286 }; |
286 | 287 |
287 // ----------------------------------------------------------------------------- | 288 // ----------------------------------------------------------------------------- |
288 // Constant types. | 289 // Constant types. |
289 | 290 |
291 class OtherNumberConstantType : public TypeBase { | |
292 public: | |
293 double Value() { return value_; } | |
294 | |
295 static bool IsInteger(double x) { | |
296 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. | |
297 } | |
298 | |
299 static bool IsOtherNumberConstant(double value) { | |
300 // Not an integer, not NaN, and not -0. | |
301 return !std::isnan(value) && !IsInteger(value) && !i::IsMinusZero(value); | |
Jarin
2016/10/04 13:14:55
IsInteger => Type::IsInteger (and remove the IsInt
mvstanton
2016/10/05 13:51:10
Let me keep this for now, I wouldn't be able to in
| |
302 } | |
303 | |
304 static bool IsOtherNumberConstant(Object* value) { | |
305 if (value->IsHeapNumber()) { | |
306 return IsOtherNumberConstant(HeapNumber::cast(value)->value()); | |
Jarin
2016/10/04 13:14:55
Nit:
return value->IsHeapNumber() &&
IsOther
mvstanton
2016/10/05 13:51:10
Done.
| |
307 } | |
308 return false; | |
309 } | |
310 | |
311 private: | |
312 friend class Type; | |
313 friend class BitsetType; | |
314 | |
315 static Type* New(double value, Zone* zone) { | |
316 return AsType(new (zone->New(sizeof(OtherNumberConstantType))) | |
317 OtherNumberConstantType(value)); | |
318 } | |
319 | |
320 static OtherNumberConstantType* cast(Type* type) { | |
321 DCHECK(IsKind(type, kOtherNumberConstant)); | |
322 return static_cast<OtherNumberConstantType*>(FromType(type)); | |
323 } | |
324 | |
325 OtherNumberConstantType(double value) | |
326 : TypeBase(kOtherNumberConstant), value_(value) { | |
327 CHECK(IsOtherNumberConstant(value)); | |
328 } | |
329 | |
330 BitsetType::bitset Lub() { return BitsetType::kOtherNumber; } | |
331 | |
332 double value_; | |
333 }; | |
334 | |
290 class ConstantType : public TypeBase { | 335 class ConstantType : public TypeBase { |
Jarin
2016/10/04 13:14:55
Maybe ConstantType => HeapConstantType?
mvstanton
2016/10/05 13:51:10
Done.
| |
291 public: | 336 public: |
292 i::Handle<i::Object> Value() { return object_; } | 337 i::Handle<i::Object> Value() { return object_; } |
293 | 338 |
294 private: | 339 private: |
295 friend class Type; | 340 friend class Type; |
296 friend class BitsetType; | 341 friend class BitsetType; |
297 | 342 |
298 static Type* New(i::Handle<i::Object> value, Zone* zone) { | 343 static Type* New(i::Handle<i::Object> value, Zone* zone) { |
299 BitsetType::bitset bitset = BitsetType::Lub(*value); | 344 BitsetType::bitset bitset = BitsetType::Lub(*value); |
300 return AsType(new (zone->New(sizeof(ConstantType))) | 345 return AsType(new (zone->New(sizeof(ConstantType))) |
301 ConstantType(bitset, value)); | 346 ConstantType(bitset, value)); |
302 } | 347 } |
303 | 348 |
304 static ConstantType* cast(Type* type) { | 349 static ConstantType* cast(Type* type) { |
305 DCHECK(IsKind(type, kConstant)); | 350 DCHECK(IsKind(type, kConstant)); |
306 return static_cast<ConstantType*>(FromType(type)); | 351 return static_cast<ConstantType*>(FromType(type)); |
307 } | 352 } |
308 | 353 |
309 ConstantType(BitsetType::bitset bitset, i::Handle<i::Object> object) | 354 ConstantType(BitsetType::bitset bitset, i::Handle<i::Object> object) |
310 : TypeBase(kConstant), bitset_(bitset), object_(object) {} | 355 : TypeBase(kConstant), bitset_(bitset), object_(object) { |
356 CHECK(!object->IsSmi()); // Smis should always be RangeTypes. | |
357 CHECK(!OtherNumberConstantType::IsOtherNumberConstant(*object)); | |
358 } | |
311 | 359 |
312 BitsetType::bitset Lub() { return bitset_; } | 360 BitsetType::bitset Lub() { return bitset_; } |
313 | 361 |
314 BitsetType::bitset bitset_; | 362 BitsetType::bitset bitset_; |
315 Handle<i::Object> object_; | 363 Handle<i::Object> object_; |
316 }; | 364 }; |
317 // TODO(neis): Also cache value if numerical. | |
318 | 365 |
319 // ----------------------------------------------------------------------------- | 366 // ----------------------------------------------------------------------------- |
320 // Range types. | 367 // Range types. |
321 | 368 |
322 class RangeType : public TypeBase { | 369 class RangeType : public TypeBase { |
323 public: | 370 public: |
324 struct Limits { | 371 struct Limits { |
325 double min; | 372 double min; |
326 double max; | 373 double max; |
327 Limits(double min, double max) : min(min), max(max) {} | 374 Limits(double min, double max) : min(min), max(max) {} |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) | 514 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) |
468 #undef DEFINE_TYPE_CONSTRUCTOR | 515 #undef DEFINE_TYPE_CONSTRUCTOR |
469 | 516 |
470 static Type* SignedSmall() { | 517 static Type* SignedSmall() { |
471 return BitsetType::New(BitsetType::SignedSmall()); | 518 return BitsetType::New(BitsetType::SignedSmall()); |
472 } | 519 } |
473 static Type* UnsignedSmall() { | 520 static Type* UnsignedSmall() { |
474 return BitsetType::New(BitsetType::UnsignedSmall()); | 521 return BitsetType::New(BitsetType::UnsignedSmall()); |
475 } | 522 } |
476 | 523 |
524 static Type* OtherNumberConstant(double value, Zone* zone) { | |
525 return OtherNumberConstantType::New(value, zone); | |
526 } | |
477 static Type* Constant(i::Handle<i::Object> value, Zone* zone) { | 527 static Type* Constant(i::Handle<i::Object> value, Zone* zone) { |
Jarin
2016/10/04 13:14:55
Maybe Constant => HeapConstant?
mvstanton
2016/10/05 13:51:10
Done.
| |
478 return ConstantType::New(value, zone); | 528 return ConstantType::New(value, zone); |
479 } | 529 } |
480 static Type* Range(double min, double max, Zone* zone) { | 530 static Type* Range(double min, double max, Zone* zone) { |
481 return RangeType::New(min, max, zone); | 531 return RangeType::New(min, max, zone); |
482 } | 532 } |
483 static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) { | 533 static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) { |
484 Type* tuple = TupleType::New(3, zone); | 534 Type* tuple = TupleType::New(3, zone); |
485 tuple->AsTuple()->InitElement(0, first); | 535 tuple->AsTuple()->InitElement(0, first); |
486 tuple->AsTuple()->InitElement(1, second); | 536 tuple->AsTuple()->InitElement(1, second); |
487 tuple->AsTuple()->InitElement(2, third); | 537 tuple->AsTuple()->InitElement(2, third); |
488 return tuple; | 538 return tuple; |
489 } | 539 } |
490 | 540 |
541 // NewConstant is a factory that returns Constant, Range or Number. | |
542 static Type* NewConstant(i::Handle<i::Object> value, Zone* zone); | |
543 | |
491 static Type* Union(Type* type1, Type* type2, Zone* zone); | 544 static Type* Union(Type* type1, Type* type2, Zone* zone); |
492 static Type* Intersect(Type* type1, Type* type2, Zone* zone); | 545 static Type* Intersect(Type* type1, Type* type2, Zone* zone); |
493 | 546 |
494 static Type* Of(double value, Zone* zone) { | 547 static Type* Of(double value, Zone* zone) { |
495 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value))); | 548 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value))); |
496 } | 549 } |
497 static Type* Of(i::Object* value, Zone* zone) { | 550 static Type* Of(i::Object* value, Zone* zone) { |
498 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value))); | 551 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value))); |
499 } | 552 } |
500 static Type* Of(i::Handle<i::Object> value, Zone* zone) { | 553 static Type* Of(i::Handle<i::Object> value, Zone* zone) { |
501 return Of(*value, zone); | 554 return Of(*value, zone); |
502 } | 555 } |
503 | 556 |
504 static Type* For(i::Map* map) { | 557 static Type* For(i::Map* map) { |
505 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map))); | 558 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map))); |
506 } | 559 } |
507 static Type* For(i::Handle<i::Map> map) { return For(*map); } | 560 static Type* For(i::Handle<i::Map> map) { return For(*map); } |
508 | 561 |
509 // Predicates. | 562 // Predicates. |
510 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); } | 563 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); } |
511 | 564 |
512 bool Is(Type* that) { return this == that || this->SlowIs(that); } | 565 bool Is(Type* that) { return this == that || this->SlowIs(that); } |
513 bool Maybe(Type* that); | 566 bool Maybe(Type* that); |
514 bool Equals(Type* that) { return this->Is(that) && that->Is(this); } | 567 bool Equals(Type* that) { return this->Is(that) && that->Is(this); } |
515 | 568 |
516 // Inspection. | 569 // Inspection. |
517 bool IsRange() { return IsKind(TypeBase::kRange); } | 570 bool IsRange() { return IsKind(TypeBase::kRange); } |
518 bool IsConstant() { return IsKind(TypeBase::kConstant); } | 571 bool IsConstant() { return IsKind(TypeBase::kConstant); } |
Jarin
2016/10/04 13:14:55
IsHeapConstant?
mvstanton
2016/10/05 13:51:10
Done.
| |
572 bool IsOtherNumberConstant() { | |
573 return IsKind(TypeBase::kOtherNumberConstant); | |
574 } | |
519 bool IsTuple() { return IsKind(TypeBase::kTuple); } | 575 bool IsTuple() { return IsKind(TypeBase::kTuple); } |
520 | 576 |
521 ConstantType* AsConstant() { return ConstantType::cast(this); } | 577 ConstantType* AsConstant() { return ConstantType::cast(this); } |
578 OtherNumberConstantType* AsOtherNumberConstant() { | |
579 return OtherNumberConstantType::cast(this); | |
580 } | |
522 RangeType* AsRange() { return RangeType::cast(this); } | 581 RangeType* AsRange() { return RangeType::cast(this); } |
523 TupleType* AsTuple() { return TupleType::cast(this); } | 582 TupleType* AsTuple() { return TupleType::cast(this); } |
524 | 583 |
525 // Minimum and maximum of a numeric type. | 584 // Minimum and maximum of a numeric type. |
526 // These functions do not distinguish between -0 and +0. If the type equals | 585 // These functions do not distinguish between -0 and +0. If the type equals |
527 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these | 586 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these |
528 // functions on subtypes of Number. | 587 // functions on subtypes of Number. |
529 double Min(); | 588 double Min(); |
530 double Max(); | 589 double Max(); |
531 | 590 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
598 RangeType::Limits* limits, Zone* zone); | 657 RangeType::Limits* limits, Zone* zone); |
599 static Type* NormalizeUnion(Type* unioned, int size, Zone* zone); | 658 static Type* NormalizeUnion(Type* unioned, int size, Zone* zone); |
600 static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone); | 659 static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone); |
601 }; | 660 }; |
602 | 661 |
603 } // namespace compiler | 662 } // namespace compiler |
604 } // namespace internal | 663 } // namespace internal |
605 } // namespace v8 | 664 } // namespace v8 |
606 | 665 |
607 #endif // V8_COMPILER_TYPES_H_ | 666 #endif // V8_COMPILER_TYPES_H_ |
OLD | NEW |