Chromium Code Reviews

Side by Side Diff: src/types.h

Issue 558193003: Redesign of the internal type system. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
« no previous file with comments | « no previous file | src/types.cc » ('j') | src/types.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/factory.h" 9 #include "src/factory.h"
9 #include "src/handles.h" 10 #include "src/handles.h"
10 #include "src/ostreams.h" 11 #include "src/ostreams.h"
11 12
12 namespace v8 { 13 namespace v8 {
13 namespace internal { 14 namespace internal {
14 15
15 // SUMMARY 16 // SUMMARY
16 // 17 //
17 // A simple type system for compiler-internal use. It is based entirely on 18 // A simple type system for compiler-internal use. It is based entirely on
(...skipping 87 matching lines...)
105 // existing assumptions or tests. 106 // existing assumptions or tests.
106 // Consequently, do not normally use Equals for type tests, always use Is! 107 // Consequently, do not normally use Equals for type tests, always use Is!
107 // 108 //
108 // The NowIs operator implements state-sensitive subtying, as described above. 109 // The NowIs operator implements state-sensitive subtying, as described above.
109 // Any compilation decision based on such temporary properties requires runtime 110 // Any compilation decision based on such temporary properties requires runtime
110 // guarding! 111 // guarding!
111 // 112 //
112 // PROPERTIES 113 // PROPERTIES
113 // 114 //
114 // Various formal properties hold for constructors, operators, and predicates 115 // Various formal properties hold for constructors, operators, and predicates
115 // over types. For example, constructors are injective, subtyping is a complete 116 // over types. For example, constructors are injective and subtyping is a
116 // partial order, union and intersection satisfy the usual algebraic properties. 117 // complete partial order.
117 // 118 //
118 // See test/cctest/test-types.cc for a comprehensive executable specification, 119 // See test/cctest/test-types.cc for a comprehensive executable specification,
119 // especially with respect to the properties of the more exotic 'temporal' 120 // especially with respect to the properties of the more exotic 'temporal'
120 // constructors and predicates (those prefixed 'Now'). 121 // constructors and predicates (those prefixed 'Now').
121 // 122 //
122 // IMPLEMENTATION 123 // IMPLEMENTATION
123 // 124 //
124 // Internally, all 'primitive' types, and their unions, are represented as 125 // Internally, all 'primitive' types, and their unions, are represented as
125 // bitsets. Class is a heap pointer to the respective map. Only Constant's, or 126 // bitsets. Class is a heap pointer to the respective map. Only Constant's, or
126 // unions containing Class'es or Constant's, currently require allocation. 127 // unions containing Class'es or Constant's, currently require allocation.
(...skipping 74 matching lines...)
201 V(Primitive, kNumber | kName | kBoolean | kNull | kUndefined) \ 202 V(Primitive, kNumber | kName | kBoolean | kNull | kUndefined) \
202 V(DetectableObject, kArray | kFunction | kRegExp | kOtherObject) \ 203 V(DetectableObject, kArray | kFunction | kRegExp | kOtherObject) \
203 V(DetectableReceiver, kDetectableObject | kProxy) \ 204 V(DetectableReceiver, kDetectableObject | kProxy) \
204 V(Detectable, kDetectableReceiver | kNumber | kName) \ 205 V(Detectable, kDetectableReceiver | kNumber | kName) \
205 V(Object, kDetectableObject | kUndetectable) \ 206 V(Object, kDetectableObject | kUndetectable) \
206 V(Receiver, kObject | kProxy) \ 207 V(Receiver, kObject | kProxy) \
207 V(NonNumber, kBoolean | kName | kNull | kReceiver | \ 208 V(NonNumber, kBoolean | kName | kNull | kReceiver | \
208 kUndefined | kInternal) \ 209 kUndefined | kInternal) \
209 V(Any, -1) 210 V(Any, -1)
210 211
212 /*
213 * The following diagrams show how integers (in the mathematical sense) are
214 * divided among the different atomic numerical types.
215 *
216 * If SmiValuesAre31Bits():
217 *
218 * ON OS32 OSS US OU31 OU32 ON
219 * ______[_______[_______[_______[_______[_______[_______
220 * -2^31 -2^30 0 2^30 2^31 2^32
221 *
222 * Otherwise:
rossberg 2014/09/10 15:44:15 Nit: indentation off
neis1 2014/09/11 12:58:12 Done.
223 *
224 * ON OSS US OU32 ON
225 * ______[_______________[_______________[_______[_______
226 * -2^31 0 2^31 2^32
227 *
228 *
229 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
230 *
231 */
232
233 #define PROPER_BITSET_TYPE_LIST(V) \
234 REPRESENTATION_BITSET_TYPE_LIST(V) \
235 SEMANTIC_BITSET_TYPE_LIST(V)
236
211 #define BITSET_TYPE_LIST(V) \ 237 #define BITSET_TYPE_LIST(V) \
212 MASK_BITSET_TYPE_LIST(V) \ 238 MASK_BITSET_TYPE_LIST(V) \
213 REPRESENTATION_BITSET_TYPE_LIST(V) \ 239 PROPER_BITSET_TYPE_LIST(V)
214 SEMANTIC_BITSET_TYPE_LIST(V)
215 240
216 241
217 // ----------------------------------------------------------------------------- 242 // -----------------------------------------------------------------------------
218 // The abstract Type class, parameterized over the low-level representation. 243 // The abstract Type class, parameterized over the low-level representation.
219 244
220 // struct Config { 245 // struct Config {
221 // typedef TypeImpl<Config> Type; 246 // typedef TypeImpl<Config> Type;
222 // typedef Base; 247 // typedef Base;
223 // typedef Struct; 248 // typedef Struct;
224 // typedef Region; 249 // typedef Region;
(...skipping 47 matching lines...)
272 typedef typename Config::template Handle<UnionType>::type UnionHandle; 297 typedef typename Config::template Handle<UnionType>::type UnionHandle;
273 typedef typename Config::Region Region; 298 typedef typename Config::Region Region;
274 299
275 // Constructors. 300 // Constructors.
276 301
277 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ 302 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
278 static TypeImpl* type() { return BitsetType::New(BitsetType::k##type); } \ 303 static TypeImpl* type() { return BitsetType::New(BitsetType::k##type); } \
279 static TypeHandle type(Region* region) { \ 304 static TypeHandle type(Region* region) { \
280 return BitsetType::New(BitsetType::k##type, region); \ 305 return BitsetType::New(BitsetType::k##type, region); \
281 } 306 }
282 BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) 307 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
283 #undef DEFINE_TYPE_CONSTRUCTOR 308 #undef DEFINE_TYPE_CONSTRUCTOR
284 309
285 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { 310 static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
286 return ClassType::New(map, region); 311 return ClassType::New(map, region);
287 } 312 }
288 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { 313 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
289 // TODO(neis): Return RangeType for numerical values.
290 return ConstantType::New(value, region); 314 return ConstantType::New(value, region);
291 } 315 }
292 static TypeHandle Range(double min, double max, Region* region) { 316 static TypeHandle Range(
317 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
293 return RangeType::New(min, max, region); 318 return RangeType::New(min, max, region);
294 } 319 }
295 static TypeHandle Context(TypeHandle outer, Region* region) { 320 static TypeHandle Context(TypeHandle outer, Region* region) {
296 return ContextType::New(outer, region); 321 return ContextType::New(outer, region);
297 } 322 }
298 static TypeHandle Array(TypeHandle element, Region* region) { 323 static TypeHandle Array(TypeHandle element, Region* region) {
299 return ArrayType::New(element, region); 324 return ArrayType::New(element, region);
300 } 325 }
301 static FunctionHandle Function( 326 static FunctionHandle Function(
302 TypeHandle result, TypeHandle receiver, int arity, Region* region) { 327 TypeHandle result, TypeHandle receiver, int arity, Region* region) {
(...skipping 47 matching lines...)
350 bool Is(TypeHandle that) { return this->Is(*that); } 375 bool Is(TypeHandle that) { return this->Is(*that); }
351 376
352 bool Maybe(TypeImpl* that); 377 bool Maybe(TypeImpl* that);
353 template<class TypeHandle> 378 template<class TypeHandle>
354 bool Maybe(TypeHandle that) { return this->Maybe(*that); } 379 bool Maybe(TypeHandle that) { return this->Maybe(*that); }
355 380
356 bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); } 381 bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); }
357 template<class TypeHandle> 382 template<class TypeHandle>
358 bool Equals(TypeHandle that) { return this->Equals(*that); } 383 bool Equals(TypeHandle that) { return this->Equals(*that); }
359 384
360 // Equivalent to Constant(value)->Is(this), but avoiding allocation. 385 // Equivalent to Constant(val)->Is(this), but avoiding allocation.
361 bool Contains(i::Object* val); 386 bool Contains(i::Object* val);
362 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); } 387 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
363 388
364 // State-dependent versions of the above that consider subtyping between 389 // State-dependent versions of the above that consider subtyping between
365 // a constant and its map class. 390 // a constant and its map class.
366 inline static TypeHandle NowOf(i::Object* value, Region* region); 391 inline static TypeHandle NowOf(i::Object* value, Region* region);
367 static TypeHandle NowOf(i::Handle<i::Object> value, Region* region) { 392 static TypeHandle NowOf(i::Handle<i::Object> value, Region* region) {
368 return NowOf(*value, region); 393 return NowOf(*value, region);
369 } 394 }
370 bool NowIs(TypeImpl* that); 395 bool NowIs(TypeImpl* that);
(...skipping 88 matching lines...)
459 int AsBitset() { 484 int AsBitset() {
460 DCHECK(this->IsBitset()); 485 DCHECK(this->IsBitset());
461 return static_cast<BitsetType*>(this)->Bitset(); 486 return static_cast<BitsetType*>(this)->Bitset();
462 } 487 }
463 UnionType* AsUnion() { return UnionType::cast(this); } 488 UnionType* AsUnion() { return UnionType::cast(this); }
464 489
465 // Auxiliary functions. 490 // Auxiliary functions.
466 491
467 int BitsetGlb() { return BitsetType::Glb(this); } 492 int BitsetGlb() { return BitsetType::Glb(this); }
468 int BitsetLub() { return BitsetType::Lub(this); } 493 int BitsetLub() { return BitsetType::Lub(this); }
469 int InherentBitsetLub() { return BitsetType::InherentLub(this); }
470 494
471 bool SlowIs(TypeImpl* that); 495 bool SlowIs(TypeImpl* that);
472 496
473 TypeHandle Rebound(int bitset, Region* region); 497 static bool IsInteger(double x) {
474 int BoundBy(TypeImpl* that); 498 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
475 int IndexInUnion(int bound, UnionHandle unioned, int current_size); 499 }
476 static int ExtendUnion( 500 static bool IsInteger(i::Object* x) {
477 UnionHandle unioned, int current_size, TypeHandle t, 501 return x->IsNumber() && IsInteger(x->Number());
478 TypeHandle other, bool is_intersect, Region* region); 502 }
503
504 struct Limits {
505 i::Handle<i::Object> min;
506 i::Handle<i::Object> max;
507 Limits(i::Handle<i::Object> min, i::Handle<i::Object> max) :
508 min(min), max(max) {}
509 explicit Limits(RangeType* range) :
510 min(range->MinV()), max(range->MaxV()) {}
511 };
512
513 static Limits intersect(Limits lhs, Limits rhs);
514 static Limits union_(Limits lhs, Limits rhs);
515 static bool overlap(RangeType* lhs, RangeType* rhs);
516 static bool contains(RangeType* lhs, RangeType* rhs);
517 static bool contains(RangeType* range, i::Object* val);
518
519 RangeType* GetRange();
520 static int UpdateRange(
521 RangeHandle type, UnionHandle result, int size, Region* region);
522
523 bool SimplyEquals(TypeImpl* that);
524 static int AddToUnion(
525 TypeHandle type, UnionHandle result, int size, Region* region);
526 static int IntersectAux(
527 TypeHandle type, TypeHandle other,
528 UnionHandle result, int size, Region* region);
529 static TypeHandle NormalizeUnion(UnionHandle unioned, int size);
479 }; 530 };
480 531
481 532
482 // ----------------------------------------------------------------------------- 533 // -----------------------------------------------------------------------------
483 // Bitset types (internal). 534 // Bitset types (internal).
484 535
485 template<class Config> 536 template<class Config>
486 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { 537 class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
487 protected: 538 protected:
488 friend class TypeImpl<Config>; 539 friend class TypeImpl<Config>;
489 540
490 enum { 541 enum {
491 #define DECLARE_TYPE(type, value) k##type = (value), 542 #define DECLARE_TYPE(type, value) k##type = (value),
492 BITSET_TYPE_LIST(DECLARE_TYPE) 543 BITSET_TYPE_LIST(DECLARE_TYPE)
493 #undef DECLARE_TYPE 544 #undef DECLARE_TYPE
494 kUnusedEOL = 0 545 kUnusedEOL = 0
495 }; 546 };
496 547
497 int Bitset() { return Config::as_bitset(this); } 548 int Bitset() { return Config::as_bitset(this); }
498 549
499 static TypeImpl* New(int bitset) { 550 static TypeImpl* New(int bitset) {
551 DCHECK(bitset == kNone || IsInhabited(bitset));
500 return static_cast<BitsetType*>(Config::from_bitset(bitset)); 552 return static_cast<BitsetType*>(Config::from_bitset(bitset));
501 } 553 }
502 static TypeHandle New(int bitset, Region* region) { 554 static TypeHandle New(int bitset, Region* region) {
555 DCHECK(bitset == kNone || IsInhabited(bitset));
503 return Config::from_bitset(bitset, region); 556 return Config::from_bitset(bitset, region);
504 } 557 }
505 558
506 static bool IsInhabited(int bitset) { 559 static bool IsInhabited(int bitset) {
507 return (bitset & kRepresentation) && (bitset & kSemantic); 560 return (bitset & kRepresentation) && (bitset & kSemantic);
508 } 561 }
509 562
510 static bool Is(int bitset1, int bitset2) { 563 static bool Is(int bitset1, int bitset2) {
511 return (bitset1 | bitset2) == bitset2; 564 return (bitset1 | bitset2) == bitset2;
512 } 565 }
513 566
514 static int Glb(TypeImpl* type); // greatest lower bound that's a bitset 567 static int Glb(TypeImpl* type); // greatest lower bound that's a bitset
515 static int Lub(TypeImpl* type); // least upper bound that's a bitset 568 static int Lub(TypeImpl* type); // least upper bound that's a bitset
516 static int Lub(i::Object* value); 569 static int Lub(i::Object* value);
517 static int Lub(double value); 570 static int Lub(double value);
518 static int Lub(int32_t value); 571 static int Lub(int32_t value);
519 static int Lub(uint32_t value); 572 static int Lub(uint32_t value);
520 static int Lub(i::Map* map); 573 static int Lub(i::Map* map);
521 static int Lub(double min, double max); 574 static int Lub(Limits lim);
522 static int InherentLub(TypeImpl* type); 575 static double Min(int bitset);
523 576
524 static const char* Name(int bitset); 577 static const char* Name(int bitset);
525 static void Print(OStream& os, int bitset); // NOLINT 578 static void Print(OStream& os, int bitset); // NOLINT
526 using TypeImpl::PrintTo; 579 #ifdef DEBUG
580 static void Print(int bitset);
581 #endif
527 }; 582 };
528 583
529 584
530 // ----------------------------------------------------------------------------- 585 // -----------------------------------------------------------------------------
531 // Superclass for non-bitset types (internal). 586 // Superclass for non-bitset types (internal).
532 // Contains a tag and a variable number of type or value fields. 587 // Contains a tag and a variable number of type or value fields.
533 588
534 template<class Config> 589 template<class Config>
535 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { 590 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> {
536 protected: 591 protected:
(...skipping 65 matching lines...)
602 bool Wellformed(); 657 bool Wellformed();
603 }; 658 };
604 659
605 660
606 // ----------------------------------------------------------------------------- 661 // -----------------------------------------------------------------------------
607 // Class types. 662 // Class types.
608 663
609 template<class Config> 664 template<class Config>
610 class TypeImpl<Config>::ClassType : public StructuralType { 665 class TypeImpl<Config>::ClassType : public StructuralType {
611 public: 666 public:
612 TypeHandle Bound(Region* region) {
613 return Config::is_class(this)
614 ? BitsetType::New(BitsetType::Lub(*Config::as_class(this)), region)
615 : this->Get(0);
616 }
617 i::Handle<i::Map> Map() { 667 i::Handle<i::Map> Map() {
618 return Config::is_class(this) 668 return Config::is_class(this)
619 ? Config::as_class(this) 669 ? Config::as_class(this)
620 : this->template GetValue<i::Map>(1); 670 : this->template GetValue<i::Map>(0);
621 }
622
623 static ClassHandle New(
624 i::Handle<i::Map> map, TypeHandle bound, Region* region) {
625 DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(*map)));
626 ClassHandle type = Config::template cast<ClassType>(
627 StructuralType::New(StructuralType::kClassTag, 2, region));
628 type->Set(0, bound);
629 type->SetValue(1, map);
630 return type;
631 } 671 }
632 672
633 static ClassHandle New(i::Handle<i::Map> map, Region* region) { 673 static ClassHandle New(i::Handle<i::Map> map, Region* region) {
634 ClassHandle type = 674 ClassHandle type =
635 Config::template cast<ClassType>(Config::from_class(map, region)); 675 Config::template cast<ClassType>(Config::from_class(map, region));
636 if (type->IsClass()) { 676 if (!type->IsClass()) {
637 return type; 677 type = Config::template cast<ClassType>(
638 } else { 678 StructuralType::New(StructuralType::kClassTag, 1, region));
rossberg 2014/09/10 15:44:15 Nit: style guide wants +4 indentation for line con
neis1 2014/09/11 12:58:12 Done.
639 TypeHandle bound = BitsetType::New(BitsetType::Lub(*map), region); 679 type->SetValue(0, map);
640 return New(map, bound, region);
641 } 680 }
681 return type;
642 } 682 }
643 683
644 static ClassType* cast(TypeImpl* type) { 684 static ClassType* cast(TypeImpl* type) {
645 DCHECK(type->IsClass()); 685 DCHECK(type->IsClass());
646 return static_cast<ClassType*>(type); 686 return static_cast<ClassType*>(type);
647 } 687 }
648 }; 688 };
649 689
650 690
651 // ----------------------------------------------------------------------------- 691 // -----------------------------------------------------------------------------
652 // Constant types. 692 // Constant types.
653 693
654 template<class Config> 694 template<class Config>
655 class TypeImpl<Config>::ConstantType : public StructuralType { 695 class TypeImpl<Config>::ConstantType : public StructuralType {
656 public: 696 public:
657 TypeHandle Bound() { return this->Get(0); } 697 i::Handle<i::Object> Value() {
658 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); } 698 return this->template GetValue<i::Object>(0);
rossberg 2014/09/10 15:44:15 Nit: probably fits on previous line
neis1 2014/09/11 12:58:12 Done.
699 }
659 700
660 static ConstantHandle New( 701 static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
661 i::Handle<i::Object> value, TypeHandle bound, Region* region) {
662 DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(*value)));
663 ConstantHandle type = Config::template cast<ConstantType>( 702 ConstantHandle type = Config::template cast<ConstantType>(
664 StructuralType::New(StructuralType::kConstantTag, 2, region)); 703 StructuralType::New(StructuralType::kConstantTag, 1, region));
665 type->Set(0, bound); 704 type->SetValue(0, value);
666 type->SetValue(1, value);
667 return type; 705 return type;
668 } 706 }
669 707
670 static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
671 TypeHandle bound = BitsetType::New(BitsetType::Lub(*value), region);
672 return New(value, bound, region);
673 }
674
675 static ConstantType* cast(TypeImpl* type) { 708 static ConstantType* cast(TypeImpl* type) {
676 DCHECK(type->IsConstant()); 709 DCHECK(type->IsConstant());
677 return static_cast<ConstantType*>(type); 710 return static_cast<ConstantType*>(type);
678 } 711 }
679 }; 712 };
680 713
681 714
682 // ----------------------------------------------------------------------------- 715 // -----------------------------------------------------------------------------
683 // Range types. 716 // Range types.
717 // They represent continuous integer intervals in the form of a minimum
rossberg 2014/09/10 15:44:15 This should go to the top, along with the other ex
neis1 2014/09/11 12:58:12 Done.
718 // and a maximum value. Either value might be an infinity.
719 //
720 // Constant(v) is considered a subtype of Range(x..y) if v happens to be an
721 // integer between x and y.
684 722
685 template<class Config> 723 template<class Config>
686 class TypeImpl<Config>::RangeType : public StructuralType { 724 class TypeImpl<Config>::RangeType : public StructuralType {
687 public: 725 public:
688 TypeHandle Bound() { return this->Get(0); } 726 i::Handle<i::Object> MinV() { return this->template GetValue<i::Object>(0); }
689 double Min() { return this->template GetValue<i::HeapNumber>(1)->value(); } 727 i::Handle<i::Object> MaxV() { return this->template GetValue<i::Object>(1); }
690 double Max() { return this->template GetValue<i::HeapNumber>(2)->value(); } 728 double Min() { return MinV()->Number(); }
729 double Max() { return MaxV()->Number(); }
rossberg 2014/09/10 15:44:15 Since we call the method to get a numeric value fr
neis1 2014/09/11 12:58:12 Not sure I'm following. Are you suggesting to exp
rossberg 2014/09/15 15:58:29 The latter. It's more consistent with our naming e
neis1 2014/09/16 10:03:59 But less consistent with the naming here, such as
rossberg 2014/09/16 14:04:40 OK, fair enough. Actually, I'd say, just remove th
neis1 2014/09/18 13:05:18 Done.
691 730
692 static RangeHandle New( 731 static RangeHandle New(
693 double min, double max, TypeHandle bound, Region* region) { 732 i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
694 DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(min, max))); 733 DCHECK(min->Number() <= max->Number());
695 RangeHandle type = Config::template cast<RangeType>( 734 RangeHandle type = Config::template cast<RangeType>(
696 StructuralType::New(StructuralType::kRangeTag, 3, region)); 735 StructuralType::New(StructuralType::kRangeTag, 2, region));
697 type->Set(0, bound); 736 type->SetValue(0, min);
698 Factory* factory = Config::isolate(region)->factory(); 737 type->SetValue(1, max);
699 Handle<HeapNumber> minV = factory->NewHeapNumber(min); 738 #ifdef DEBUG
rossberg 2014/09/10 15:44:15 Debugging left-overs?
neis1 2014/09/11 12:58:12 Done.
700 Handle<HeapNumber> maxV = factory->NewHeapNumber(max); 739 type->Print();
701 type->SetValue(1, minV); 740 #endif
702 type->SetValue(2, maxV);
703 return type; 741 return type;
704 } 742 }
705 743
706 static RangeHandle New(double min, double max, Region* region) { 744 static RangeHandle New(Limits lim, Region* region) {
707 TypeHandle bound = BitsetType::New(BitsetType::Lub(min, max), region); 745 return New(lim.min, lim.max, region);
708 return New(min, max, bound, region);
709 } 746 }
710 747
711 static RangeType* cast(TypeImpl* type) { 748 static RangeType* cast(TypeImpl* type) {
712 DCHECK(type->IsRange()); 749 DCHECK(type->IsRange());
713 return static_cast<RangeType*>(type); 750 return static_cast<RangeType*>(type);
714 } 751 }
715 }; 752 };
716 753
717 754
718 // ----------------------------------------------------------------------------- 755 // -----------------------------------------------------------------------------
719 // Context types. 756 // Context types.
720 757
721 template<class Config> 758 template<class Config>
722 class TypeImpl<Config>::ContextType : public StructuralType { 759 class TypeImpl<Config>::ContextType : public StructuralType {
723 public: 760 public:
724 TypeHandle Bound() { return this->Get(0); } 761 TypeHandle Outer() { return this->Get(0); }
725 TypeHandle Outer() { return this->Get(1); }
726
727 static ContextHandle New(TypeHandle outer, TypeHandle bound, Region* region) {
728 DCHECK(BitsetType::Is(
729 bound->AsBitset(), BitsetType::kInternal & BitsetType::kTaggedPtr));
730 ContextHandle type = Config::template cast<ContextType>(
731 StructuralType::New(StructuralType::kContextTag, 2, region));
732 type->Set(0, bound);
733 type->Set(1, outer);
734 return type;
735 }
736 762
737 static ContextHandle New(TypeHandle outer, Region* region) { 763 static ContextHandle New(TypeHandle outer, Region* region) {
738 TypeHandle bound = BitsetType::New( 764 ContextHandle type = Config::template cast<ContextType>(
739 BitsetType::kInternal & BitsetType::kTaggedPtr, region); 765 StructuralType::New(StructuralType::kContextTag, 1, region));
740 return New(outer, bound, region); 766 type->Set(0, outer);
767 return type;
741 } 768 }
742 769
743 static ContextType* cast(TypeImpl* type) { 770 static ContextType* cast(TypeImpl* type) {
744 DCHECK(type->IsContext()); 771 DCHECK(type->IsContext());
745 return static_cast<ContextType*>(type); 772 return static_cast<ContextType*>(type);
746 } 773 }
747 }; 774 };
748 775
749 776
750 // ----------------------------------------------------------------------------- 777 // -----------------------------------------------------------------------------
751 // Array types. 778 // Array types.
752 779
753 template<class Config> 780 template<class Config>
754 class TypeImpl<Config>::ArrayType : public StructuralType { 781 class TypeImpl<Config>::ArrayType : public StructuralType {
755 public: 782 public:
756 TypeHandle Bound() { return this->Get(0); } 783 TypeHandle Element() { return this->Get(0); }
757 TypeHandle Element() { return this->Get(1); }
758
759 static ArrayHandle New(TypeHandle element, TypeHandle bound, Region* region) {
760 DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::kArray));
761 ArrayHandle type = Config::template cast<ArrayType>(
762 StructuralType::New(StructuralType::kArrayTag, 2, region));
763 type->Set(0, bound);
764 type->Set(1, element);
765 return type;
766 }
767 784
768 static ArrayHandle New(TypeHandle element, Region* region) { 785 static ArrayHandle New(TypeHandle element, Region* region) {
769 TypeHandle bound = BitsetType::New(BitsetType::kArray, region); 786 ArrayHandle type = Config::template cast<ArrayType>(
770 return New(element, bound, region); 787 StructuralType::New(StructuralType::kArrayTag, 1, region));
788 type->Set(0, element);
789 return type;
771 } 790 }
772 791
773 static ArrayType* cast(TypeImpl* type) { 792 static ArrayType* cast(TypeImpl* type) {
774 DCHECK(type->IsArray()); 793 DCHECK(type->IsArray());
775 return static_cast<ArrayType*>(type); 794 return static_cast<ArrayType*>(type);
776 } 795 }
777 }; 796 };
778 797
779 798
780 // ----------------------------------------------------------------------------- 799 // -----------------------------------------------------------------------------
781 // Function types. 800 // Function types.
782 801
783 template<class Config> 802 template<class Config>
784 class TypeImpl<Config>::FunctionType : public StructuralType { 803 class TypeImpl<Config>::FunctionType : public StructuralType {
785 public: 804 public:
786 int Arity() { return this->Length() - 3; } 805 int Arity() { return this->Length() - 2; }
787 TypeHandle Bound() { return this->Get(0); } 806 TypeHandle Result() { return this->Get(0); }
788 TypeHandle Result() { return this->Get(1); } 807 TypeHandle Receiver() { return this->Get(1); }
789 TypeHandle Receiver() { return this->Get(2); } 808 TypeHandle Parameter(int i) { return this->Get(2 + i); }
790 TypeHandle Parameter(int i) { return this->Get(3 + i); }
791 809
792 void InitParameter(int i, TypeHandle type) { this->Set(3 + i, type); } 810 void InitParameter(int i, TypeHandle type) { this->Set(2 + i, type); }
793
794 static FunctionHandle New(
795 TypeHandle result, TypeHandle receiver, TypeHandle bound,
796 int arity, Region* region) {
797 DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::kFunction));
798 FunctionHandle type = Config::template cast<FunctionType>(
799 StructuralType::New(StructuralType::kFunctionTag, 3 + arity, region));
800 type->Set(0, bound);
801 type->Set(1, result);
802 type->Set(2, receiver);
803 return type;
804 }
805 811
806 static FunctionHandle New( 812 static FunctionHandle New(
807 TypeHandle result, TypeHandle receiver, int arity, Region* region) { 813 TypeHandle result, TypeHandle receiver, int arity, Region* region) {
808 TypeHandle bound = BitsetType::New(BitsetType::kFunction, region); 814 FunctionHandle type = Config::template cast<FunctionType>(
809 return New(result, receiver, bound, arity, region); 815 StructuralType::New(StructuralType::kFunctionTag, 2 + arity, region));
816 type->Set(0, result);
817 type->Set(1, receiver);
818 return type;
810 } 819 }
811 820
812 static FunctionType* cast(TypeImpl* type) { 821 static FunctionType* cast(TypeImpl* type) {
813 DCHECK(type->IsFunction()); 822 DCHECK(type->IsFunction());
814 return static_cast<FunctionType*>(type); 823 return static_cast<FunctionType*>(type);
815 } 824 }
816 }; 825 };
817 826
818 827
819 // ----------------------------------------------------------------------------- 828 // -----------------------------------------------------------------------------
(...skipping 26 matching lines...)
846 // Zone-allocated types; they are either (odd) integers to represent bitsets, or 855 // Zone-allocated types; they are either (odd) integers to represent bitsets, or
847 // (even) pointers to structures for everything else. 856 // (even) pointers to structures for everything else.
848 857
849 struct ZoneTypeConfig { 858 struct ZoneTypeConfig {
850 typedef TypeImpl<ZoneTypeConfig> Type; 859 typedef TypeImpl<ZoneTypeConfig> Type;
851 class Base {}; 860 class Base {};
852 typedef void* Struct; 861 typedef void* Struct;
853 typedef i::Zone Region; 862 typedef i::Zone Region;
854 template<class T> struct Handle { typedef T* type; }; 863 template<class T> struct Handle { typedef T* type; };
855 864
856 // TODO(neis): This will be removed again once we have struct_get_double().
857 static inline i::Isolate* isolate(Region* region) {
858 return region->isolate();
859 }
860
861 template<class T> static inline T* handle(T* type); 865 template<class T> static inline T* handle(T* type);
862 template<class T> static inline T* cast(Type* type); 866 template<class T> static inline T* cast(Type* type);
863 867
864 static inline bool is_bitset(Type* type); 868 static inline bool is_bitset(Type* type);
865 static inline bool is_class(Type* type); 869 static inline bool is_class(Type* type);
866 static inline bool is_struct(Type* type, int tag); 870 static inline bool is_struct(Type* type, int tag);
867 871
868 static inline int as_bitset(Type* type); 872 static inline int as_bitset(Type* type);
869 static inline i::Handle<i::Map> as_class(Type* type); 873 static inline i::Handle<i::Map> as_class(Type* type);
870 static inline Struct* as_struct(Type* type); 874 static inline Struct* as_struct(Type* type);
(...skipping 22 matching lines...)
893 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for 897 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for
894 // constants, or fixed arrays for unions. 898 // constants, or fixed arrays for unions.
895 899
896 struct HeapTypeConfig { 900 struct HeapTypeConfig {
897 typedef TypeImpl<HeapTypeConfig> Type; 901 typedef TypeImpl<HeapTypeConfig> Type;
898 typedef i::Object Base; 902 typedef i::Object Base;
899 typedef i::FixedArray Struct; 903 typedef i::FixedArray Struct;
900 typedef i::Isolate Region; 904 typedef i::Isolate Region;
901 template<class T> struct Handle { typedef i::Handle<T> type; }; 905 template<class T> struct Handle { typedef i::Handle<T> type; };
902 906
903 // TODO(neis): This will be removed again once we have struct_get_double().
904 static inline i::Isolate* isolate(Region* region) {
905 return region;
906 }
907
908 template<class T> static inline i::Handle<T> handle(T* type); 907 template<class T> static inline i::Handle<T> handle(T* type);
909 template<class T> static inline i::Handle<T> cast(i::Handle<Type> type); 908 template<class T> static inline i::Handle<T> cast(i::Handle<Type> type);
910 909
911 static inline bool is_bitset(Type* type); 910 static inline bool is_bitset(Type* type);
912 static inline bool is_class(Type* type); 911 static inline bool is_class(Type* type);
913 static inline bool is_struct(Type* type, int tag); 912 static inline bool is_struct(Type* type, int tag);
914 913
915 static inline int as_bitset(Type* type); 914 static inline int as_bitset(Type* type);
916 static inline i::Handle<i::Map> as_class(Type* type); 915 static inline i::Handle<i::Map> as_class(Type* type);
917 static inline i::Handle<Struct> as_struct(Type* type); 916 static inline i::Handle<Struct> as_struct(Type* type);
(...skipping 77 matching lines...)
995 bool Narrows(BoundsImpl that) { 994 bool Narrows(BoundsImpl that) {
996 return that.lower->Is(this->lower) && this->upper->Is(that.upper); 995 return that.lower->Is(this->lower) && this->upper->Is(that.upper);
997 } 996 }
998 }; 997 };
999 998
1000 typedef BoundsImpl<ZoneTypeConfig> Bounds; 999 typedef BoundsImpl<ZoneTypeConfig> Bounds;
1001 1000
1002 } } // namespace v8::internal 1001 } } // namespace v8::internal
1003 1002
1004 #endif // V8_TYPES_H_ 1003 #endif // V8_TYPES_H_
OLDNEW
« no previous file with comments | « no previous file | src/types.cc » ('j') | src/types.cc » ('J')

Powered by Google App Engine