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 #include <iomanip> | 5 #include <iomanip> |
6 | 6 |
7 #include "src/types.h" | 7 #include "src/types.h" |
8 | 8 |
9 #include "src/ostreams.h" | 9 #include "src/ostreams.h" |
10 #include "src/types-inl.h" | 10 #include "src/types-inl.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 // Range-related helper functions. | 21 // Range-related helper functions. |
22 | 22 |
23 // The result may be invalid (max < min). | 23 // The result may be invalid (max < min). |
24 template<class Config> | 24 template<class Config> |
25 typename TypeImpl<Config>::Limits TypeImpl<Config>::Intersect( | 25 typename TypeImpl<Config>::Limits TypeImpl<Config>::Intersect( |
26 Limits lhs, Limits rhs) { | 26 Limits lhs, Limits rhs) { |
27 DisallowHeapAllocation no_allocation; | 27 DisallowHeapAllocation no_allocation; |
28 Limits result(lhs); | 28 Limits result(lhs); |
29 if (lhs.min < rhs.min) result.min = rhs.min; | 29 if (lhs.min < rhs.min) result.min = rhs.min; |
30 if (lhs.max > rhs.max) result.max = rhs.max; | 30 if (lhs.max > rhs.max) result.max = rhs.max; |
31 result.representation = lhs.representation & rhs.representation; | |
32 return result; | 31 return result; |
33 } | 32 } |
34 | 33 |
35 | 34 |
36 template <class Config> | 35 template <class Config> |
37 bool TypeImpl<Config>::IsEmpty(Limits lim) { | 36 bool TypeImpl<Config>::IsEmpty(Limits lim) { |
38 return lim.min > lim.max; | 37 return lim.min > lim.max; |
39 } | 38 } |
40 | 39 |
41 | 40 |
42 template <class Config> | 41 template <class Config> |
43 typename TypeImpl<Config>::Limits TypeImpl<Config>::Union(Limits lhs, | 42 typename TypeImpl<Config>::Limits TypeImpl<Config>::Union(Limits lhs, |
44 Limits rhs) { | 43 Limits rhs) { |
45 DisallowHeapAllocation no_allocation; | 44 DisallowHeapAllocation no_allocation; |
| 45 if (IsEmpty(lhs)) return rhs; |
| 46 if (IsEmpty(rhs)) return lhs; |
46 Limits result(lhs); | 47 Limits result(lhs); |
47 if (lhs.min > rhs.min) result.min = rhs.min; | 48 if (lhs.min > rhs.min) result.min = rhs.min; |
48 if (lhs.max < rhs.max) result.max = rhs.max; | 49 if (lhs.max < rhs.max) result.max = rhs.max; |
49 result.representation = lhs.representation | rhs.representation; | |
50 return result; | 50 return result; |
51 } | 51 } |
52 | 52 |
53 | 53 |
54 template<class Config> | 54 template<class Config> |
55 bool TypeImpl<Config>::Overlap( | 55 bool TypeImpl<Config>::Overlap( |
56 typename TypeImpl<Config>::RangeType* lhs, | 56 typename TypeImpl<Config>::RangeType* lhs, |
57 typename TypeImpl<Config>::RangeType* rhs) { | 57 typename TypeImpl<Config>::RangeType* rhs) { |
58 DisallowHeapAllocation no_allocation; | 58 DisallowHeapAllocation no_allocation; |
59 typename TypeImpl<Config>::Limits lim = Intersect(Limits(lhs), Limits(rhs)); | 59 typename TypeImpl<Config>::Limits lim = Intersect(Limits(lhs), Limits(rhs)); |
60 return lim.min <= lim.max; | 60 return lim.min <= lim.max; |
61 } | 61 } |
62 | 62 |
63 | 63 |
64 template<class Config> | 64 template<class Config> |
65 bool TypeImpl<Config>::Contains( | 65 bool TypeImpl<Config>::Contains( |
66 typename TypeImpl<Config>::RangeType* lhs, | 66 typename TypeImpl<Config>::RangeType* lhs, |
67 typename TypeImpl<Config>::RangeType* rhs) { | 67 typename TypeImpl<Config>::RangeType* rhs) { |
68 DisallowHeapAllocation no_allocation; | 68 DisallowHeapAllocation no_allocation; |
69 return BitsetType::Is(rhs->Bound(), lhs->Bound()) && | 69 return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max(); |
70 lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max(); | |
71 } | 70 } |
72 | 71 |
73 | 72 |
74 template <class Config> | 73 template <class Config> |
75 bool TypeImpl<Config>::Contains(typename TypeImpl<Config>::RangeType* lhs, | 74 bool TypeImpl<Config>::Contains(typename TypeImpl<Config>::RangeType* lhs, |
76 typename TypeImpl<Config>::ConstantType* rhs) { | 75 typename TypeImpl<Config>::ConstantType* rhs) { |
77 DisallowHeapAllocation no_allocation; | 76 DisallowHeapAllocation no_allocation; |
78 return IsInteger(*rhs->Value()) && | 77 return IsInteger(*rhs->Value()) && |
79 BitsetType::Is(rhs->Bound()->AsBitset(), lhs->Bound()) && | |
80 lhs->Min() <= rhs->Value()->Number() && | 78 lhs->Min() <= rhs->Value()->Number() && |
81 rhs->Value()->Number() <= lhs->Max(); | 79 rhs->Value()->Number() <= lhs->Max(); |
82 } | 80 } |
83 | 81 |
84 | 82 |
85 template<class Config> | 83 template<class Config> |
86 bool TypeImpl<Config>::Contains( | 84 bool TypeImpl<Config>::Contains( |
87 typename TypeImpl<Config>::RangeType* range, i::Object* val) { | 85 typename TypeImpl<Config>::RangeType* range, i::Object* val) { |
88 DisallowHeapAllocation no_allocation; | 86 DisallowHeapAllocation no_allocation; |
89 return IsInteger(val) && | 87 return IsInteger(val) && |
90 BitsetType::Is(BitsetType::Lub(val), range->Bound()) && | |
91 range->Min() <= val->Number() && val->Number() <= range->Max(); | 88 range->Min() <= val->Number() && val->Number() <= range->Max(); |
92 } | 89 } |
93 | 90 |
94 | 91 |
95 // ----------------------------------------------------------------------------- | 92 // ----------------------------------------------------------------------------- |
96 // Min and Max computation. | 93 // Min and Max computation. |
97 | 94 |
98 template<class Config> | 95 template<class Config> |
99 double TypeImpl<Config>::Min() { | 96 double TypeImpl<Config>::Min() { |
100 DCHECK(this->Is(Number())); | 97 DCHECK(this->SemanticIs(Number())); |
101 if (this->IsBitset()) return BitsetType::Min(this->AsBitset()); | 98 if (this->IsBitset()) return BitsetType::Min(this->AsBitset()); |
102 if (this->IsUnion()) { | 99 if (this->IsUnion()) { |
103 double min = +V8_INFINITY; | 100 double min = +V8_INFINITY; |
104 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 101 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
105 min = std::min(min, this->AsUnion()->Get(i)->Min()); | 102 min = std::min(min, this->AsUnion()->Get(i)->Min()); |
106 } | 103 } |
107 return min; | 104 return min; |
108 } | 105 } |
109 if (this->IsRange()) return this->AsRange()->Min(); | 106 if (this->IsRange()) return this->AsRange()->Min(); |
110 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); | 107 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); |
111 UNREACHABLE(); | 108 UNREACHABLE(); |
112 return 0; | 109 return 0; |
113 } | 110 } |
114 | 111 |
115 | 112 |
116 template<class Config> | 113 template<class Config> |
117 double TypeImpl<Config>::Max() { | 114 double TypeImpl<Config>::Max() { |
118 DCHECK(this->Is(Number())); | 115 DCHECK(this->SemanticIs(Number())); |
119 if (this->IsBitset()) return BitsetType::Max(this->AsBitset()); | 116 if (this->IsBitset()) return BitsetType::Max(this->AsBitset()); |
120 if (this->IsUnion()) { | 117 if (this->IsUnion()) { |
121 double max = -V8_INFINITY; | 118 double max = -V8_INFINITY; |
122 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 119 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
123 max = std::max(max, this->AsUnion()->Get(i)->Max()); | 120 max = std::max(max, this->AsUnion()->Get(i)->Max()); |
124 } | 121 } |
125 return max; | 122 return max; |
126 } | 123 } |
127 if (this->IsRange()) return this->AsRange()->Max(); | 124 if (this->IsRange()) return this->AsRange()->Max(); |
128 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); | 125 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); |
129 UNREACHABLE(); | 126 UNREACHABLE(); |
130 return 0; | 127 return 0; |
131 } | 128 } |
132 | 129 |
133 | 130 |
134 // ----------------------------------------------------------------------------- | 131 // ----------------------------------------------------------------------------- |
135 // Glb and lub computation. | 132 // Glb and lub computation. |
136 | 133 |
137 | 134 |
138 // The largest bitset subsumed by this type. | 135 // The largest bitset subsumed by this type. |
139 template<class Config> | 136 template<class Config> |
140 typename TypeImpl<Config>::bitset | 137 typename TypeImpl<Config>::bitset |
141 TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { | 138 TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { |
142 DisallowHeapAllocation no_allocation; | 139 DisallowHeapAllocation no_allocation; |
| 140 // Fast case. |
143 if (type->IsBitset()) { | 141 if (type->IsBitset()) { |
144 return type->AsBitset(); | 142 return type->AsBitset(); |
145 } else if (type->IsUnion()) { | 143 } else if (type->IsUnion()) { |
146 SLOW_DCHECK(type->AsUnion()->Wellformed()); | 144 SLOW_DCHECK(type->AsUnion()->Wellformed()); |
147 return type->AsUnion()->Get(0)->BitsetGlb() | | 145 return type->AsUnion()->Get(0)->BitsetGlb() | |
148 type->AsUnion()->Get(1)->BitsetGlb(); // Shortcut. | 146 SEMANTIC(type->AsUnion()->Get(1)->BitsetGlb()); // Shortcut. |
149 } else if (type->IsRange()) { | 147 } else if (type->IsRange()) { |
150 bitset glb = SEMANTIC( | 148 bitset glb = SEMANTIC( |
151 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max())); | 149 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max())); |
152 if (glb == 0) { | 150 return glb | REPRESENTATION(type->BitsetLub()); |
153 return kNone; | |
154 } else { | |
155 return glb | REPRESENTATION(type->BitsetLub()); | |
156 } | |
157 } else { | 151 } else { |
158 // (The remaining BitsetGlb's are None anyway). | 152 return type->Representation(); |
159 return kNone; | |
160 } | 153 } |
161 } | 154 } |
162 | 155 |
163 | 156 |
164 // The smallest bitset subsuming this type. | 157 // The smallest bitset subsuming this type. |
165 template<class Config> | 158 template<class Config> |
166 typename TypeImpl<Config>::bitset | 159 typename TypeImpl<Config>::bitset |
167 TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { | 160 TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { |
168 DisallowHeapAllocation no_allocation; | 161 DisallowHeapAllocation no_allocation; |
169 if (type->IsBitset()) return type->AsBitset(); | 162 if (type->IsBitset()) return type->AsBitset(); |
170 if (type->IsUnion()) { | 163 if (type->IsUnion()) { |
171 int bitset = kNone; | 164 // Take the representation from the first element, which is always |
| 165 // a bitset. |
| 166 int bitset = type->AsUnion()->Get(0)->BitsetLub(); |
172 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { | 167 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { |
173 bitset |= type->AsUnion()->Get(i)->BitsetLub(); | 168 // Other elements only contribute their semantic part. |
| 169 bitset |= SEMANTIC(type->AsUnion()->Get(i)->BitsetLub()); |
174 } | 170 } |
175 return bitset; | 171 return bitset; |
176 } | 172 } |
177 if (type->IsClass()) { | 173 if (type->IsClass()) { |
178 // Little hack to avoid the need for a region for handlification here... | 174 // Little hack to avoid the need for a region for handlification here... |
179 return Config::is_class(type) ? Lub(*Config::as_class(type)) : | 175 return Config::is_class(type) ? Lub(*Config::as_class(type)) : |
180 type->AsClass()->Bound(NULL)->AsBitset(); | 176 type->AsClass()->Bound(NULL)->AsBitset(); |
181 } | 177 } |
182 if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset(); | 178 if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset(); |
183 if (type->IsRange()) return type->AsRange()->Bound(); | 179 if (type->IsRange()) return type->AsRange()->Bound(); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 // in the greatest lower bound. (There is also the small trouble | 396 // in the greatest lower bound. (There is also the small trouble |
401 // of kOtherNumber having a range hole, which we can conveniently | 397 // of kOtherNumber having a range hole, which we can conveniently |
402 // ignore here.) | 398 // ignore here.) |
403 return glb & ~(SEMANTIC(kOtherNumber)); | 399 return glb & ~(SEMANTIC(kOtherNumber)); |
404 } | 400 } |
405 | 401 |
406 | 402 |
407 template <class Config> | 403 template <class Config> |
408 double TypeImpl<Config>::BitsetType::Min(bitset bits) { | 404 double TypeImpl<Config>::BitsetType::Min(bitset bits) { |
409 DisallowHeapAllocation no_allocation; | 405 DisallowHeapAllocation no_allocation; |
410 DCHECK(Is(bits, kNumber)); | 406 DCHECK(Is(SEMANTIC(bits), kNumber)); |
411 const Boundary* mins = Boundaries(); | 407 const Boundary* mins = Boundaries(); |
412 bool mz = SEMANTIC(bits & kMinusZero); | 408 bool mz = SEMANTIC(bits & kMinusZero); |
413 for (size_t i = 0; i < BoundariesSize(); ++i) { | 409 for (size_t i = 0; i < BoundariesSize(); ++i) { |
414 if (Is(SEMANTIC(mins[i].bits), bits)) { | 410 if (Is(SEMANTIC(mins[i].bits), bits)) { |
415 return mz ? std::min(0.0, mins[i].min) : mins[i].min; | 411 return mz ? std::min(0.0, mins[i].min) : mins[i].min; |
416 } | 412 } |
417 } | 413 } |
418 if (mz) return 0; | 414 if (mz) return 0; |
419 return std::numeric_limits<double>::quiet_NaN(); | 415 return std::numeric_limits<double>::quiet_NaN(); |
420 } | 416 } |
421 | 417 |
422 | 418 |
423 template<class Config> | 419 template<class Config> |
424 double TypeImpl<Config>::BitsetType::Max(bitset bits) { | 420 double TypeImpl<Config>::BitsetType::Max(bitset bits) { |
425 DisallowHeapAllocation no_allocation; | 421 DisallowHeapAllocation no_allocation; |
426 DCHECK(Is(bits, kNumber)); | 422 DCHECK(Is(SEMANTIC(bits), kNumber)); |
427 const Boundary* mins = Boundaries(); | 423 const Boundary* mins = Boundaries(); |
428 bool mz = SEMANTIC(bits & kMinusZero); | 424 bool mz = SEMANTIC(bits & kMinusZero); |
429 if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].bits), bits)) { | 425 if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].bits), bits)) { |
430 return +V8_INFINITY; | 426 return +V8_INFINITY; |
431 } | 427 } |
432 for (size_t i = BoundariesSize() - 1; i-- > 0;) { | 428 for (size_t i = BoundariesSize() - 1; i-- > 0;) { |
433 if (Is(SEMANTIC(mins[i].bits), bits)) { | 429 if (Is(SEMANTIC(mins[i].bits), bits)) { |
434 return mz ? | 430 return mz ? |
435 std::max(0.0, mins[i+1].min - 1) : mins[i+1].min - 1; | 431 std::max(0.0, mins[i+1].min - 1) : mins[i+1].min - 1; |
436 } | 432 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 for (int i = 0, n = this_fun->Arity(); i < n; ++i) { | 471 for (int i = 0, n = this_fun->Arity(); i < n; ++i) { |
476 if (!this_fun->Parameter(i)->Equals(that_fun->Parameter(i))) return false; | 472 if (!this_fun->Parameter(i)->Equals(that_fun->Parameter(i))) return false; |
477 } | 473 } |
478 return true; | 474 return true; |
479 } | 475 } |
480 UNREACHABLE(); | 476 UNREACHABLE(); |
481 return false; | 477 return false; |
482 } | 478 } |
483 | 479 |
484 | 480 |
| 481 template <class Config> |
| 482 typename TypeImpl<Config>::bitset TypeImpl<Config>::Representation() { |
| 483 return REPRESENTATION(this->BitsetLub()); |
| 484 } |
| 485 |
| 486 |
485 // Check if [this] <= [that]. | 487 // Check if [this] <= [that]. |
486 template<class Config> | 488 template<class Config> |
487 bool TypeImpl<Config>::SlowIs(TypeImpl* that) { | 489 bool TypeImpl<Config>::SlowIs(TypeImpl* that) { |
488 DisallowHeapAllocation no_allocation; | 490 DisallowHeapAllocation no_allocation; |
489 | 491 |
| 492 // Fast bitset cases |
490 if (that->IsBitset()) { | 493 if (that->IsBitset()) { |
491 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); | 494 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); |
492 } | 495 } |
| 496 |
493 if (this->IsBitset()) { | 497 if (this->IsBitset()) { |
494 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); | 498 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); |
495 } | 499 } |
496 | 500 |
| 501 // Check the representations. |
| 502 if (!BitsetType::Is(Representation(), that->Representation())) { |
| 503 return false; |
| 504 } |
| 505 |
| 506 // Check the semantic part. |
| 507 return SemanticIs(that); |
| 508 } |
| 509 |
| 510 |
| 511 // Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method |
| 512 // should be independent of the representation axis of the types. |
| 513 template <class Config> |
| 514 bool TypeImpl<Config>::SemanticIs(TypeImpl* that) { |
| 515 DisallowHeapAllocation no_allocation; |
| 516 |
| 517 if (this == that) return true; |
| 518 |
| 519 if (that->IsBitset()) { |
| 520 return BitsetType::Is(SEMANTIC(this->BitsetLub()), that->AsBitset()); |
| 521 } |
| 522 if (this->IsBitset()) { |
| 523 return BitsetType::Is(SEMANTIC(this->AsBitset()), that->BitsetGlb()); |
| 524 } |
| 525 |
497 // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T) | 526 // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T) |
498 if (this->IsUnion()) { | 527 if (this->IsUnion()) { |
499 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 528 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
500 if (!this->AsUnion()->Get(i)->Is(that)) return false; | 529 if (!this->AsUnion()->Get(i)->SemanticIs(that)) return false; |
501 } | 530 } |
502 return true; | 531 return true; |
503 } | 532 } |
504 | 533 |
505 // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn) | 534 // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn) |
506 if (that->IsUnion()) { | 535 if (that->IsUnion()) { |
507 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) { | 536 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) { |
508 if (this->Is(that->AsUnion()->Get(i))) return true; | 537 if (this->SemanticIs(that->AsUnion()->Get(i)->unhandle())) return true; |
509 if (i > 1 && this->IsRange()) return false; // Shortcut. | 538 if (i > 1 && this->IsRange()) return false; // Shortcut. |
510 } | 539 } |
511 return false; | 540 return false; |
512 } | 541 } |
513 | 542 |
514 if (that->IsRange()) { | 543 if (that->IsRange()) { |
515 return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || | 544 return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || |
516 (this->IsConstant() && | 545 (this->IsConstant() && |
517 Contains(that->AsRange(), this->AsConstant())); | 546 Contains(that->AsRange(), this->AsConstant())); |
518 } | 547 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 } | 580 } |
552 return true; | 581 return true; |
553 } | 582 } |
554 | 583 |
555 | 584 |
556 // Check if [this] and [that] overlap. | 585 // Check if [this] and [that] overlap. |
557 template<class Config> | 586 template<class Config> |
558 bool TypeImpl<Config>::Maybe(TypeImpl* that) { | 587 bool TypeImpl<Config>::Maybe(TypeImpl* that) { |
559 DisallowHeapAllocation no_allocation; | 588 DisallowHeapAllocation no_allocation; |
560 | 589 |
| 590 // Take care of the representation part (and also approximate |
| 591 // the semantic part). |
| 592 if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub())) |
| 593 return false; |
| 594 |
| 595 return SemanticMaybe(that); |
| 596 } |
| 597 |
| 598 template <class Config> |
| 599 bool TypeImpl<Config>::SemanticMaybe(TypeImpl* that) { |
| 600 DisallowHeapAllocation no_allocation; |
| 601 |
561 // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T) | 602 // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T) |
562 if (this->IsUnion()) { | 603 if (this->IsUnion()) { |
563 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 604 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
564 if (this->AsUnion()->Get(i)->Maybe(that)) return true; | 605 if (this->AsUnion()->Get(i)->SemanticMaybe(that)) return true; |
565 } | 606 } |
566 return false; | 607 return false; |
567 } | 608 } |
568 | 609 |
569 // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn) | 610 // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn) |
570 if (that->IsUnion()) { | 611 if (that->IsUnion()) { |
571 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) { | 612 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) { |
572 if (this->Maybe(that->AsUnion()->Get(i))) return true; | 613 if (this->SemanticMaybe(that->AsUnion()->Get(i)->unhandle())) return true; |
573 } | 614 } |
574 return false; | 615 return false; |
575 } | 616 } |
576 | 617 |
577 if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub())) | 618 if (!BitsetType::SemanticIsInhabited(this->BitsetLub() & that->BitsetLub())) |
578 return false; | 619 return false; |
579 | 620 |
580 if (this->IsBitset() && that->IsBitset()) return true; | 621 if (this->IsBitset() && that->IsBitset()) return true; |
581 | 622 |
582 if (this->IsClass() != that->IsClass()) return true; | 623 if (this->IsClass() != that->IsClass()) return true; |
583 | 624 |
584 if (this->IsRange()) { | 625 if (this->IsRange()) { |
585 if (that->IsConstant()) { | 626 if (that->IsConstant()) { |
586 return Contains(this->AsRange(), that->AsConstant()); | 627 return Contains(this->AsRange(), that->AsConstant()); |
587 } | 628 } |
588 if (that->IsRange()) { | 629 if (that->IsRange()) { |
589 return Overlap(this->AsRange(), that->AsRange()); | 630 return Overlap(this->AsRange(), that->AsRange()); |
590 } | 631 } |
591 if (that->IsBitset()) { | 632 if (that->IsBitset()) { |
592 bitset number_bits = BitsetType::NumberBits(that->AsBitset()); | 633 bitset number_bits = BitsetType::NumberBits(that->AsBitset()); |
593 if (number_bits == BitsetType::kNone) { | 634 if (number_bits == BitsetType::kNone) { |
594 return false; | 635 return false; |
595 } | 636 } |
596 double min = std::max(BitsetType::Min(number_bits), this->Min()); | 637 double min = std::max(BitsetType::Min(number_bits), this->Min()); |
597 double max = std::min(BitsetType::Max(number_bits), this->Max()); | 638 double max = std::min(BitsetType::Max(number_bits), this->Max()); |
598 return min <= max; | 639 return min <= max; |
599 } | 640 } |
600 } | 641 } |
601 if (that->IsRange()) { | 642 if (that->IsRange()) { |
602 return that->Maybe(this); // This case is handled above. | 643 return that->SemanticMaybe(this); // This case is handled above. |
603 } | 644 } |
604 | 645 |
605 if (this->IsBitset() || that->IsBitset()) return true; | 646 if (this->IsBitset() || that->IsBitset()) return true; |
606 | 647 |
607 return this->SimplyEquals(that); | 648 return this->SimplyEquals(that); |
608 } | 649 } |
609 | 650 |
610 | 651 |
611 // Return the range in [this], or [NULL]. | 652 // Return the range in [this], or [NULL]. |
612 template<class Config> | 653 template<class Config> |
(...skipping 19 matching lines...) Expand all Loading... |
632 } | 673 } |
633 return BitsetType::New(BitsetType::Lub(value))->Is(this); | 674 return BitsetType::New(BitsetType::Lub(value))->Is(this); |
634 } | 675 } |
635 | 676 |
636 | 677 |
637 template<class Config> | 678 template<class Config> |
638 bool TypeImpl<Config>::UnionType::Wellformed() { | 679 bool TypeImpl<Config>::UnionType::Wellformed() { |
639 DisallowHeapAllocation no_allocation; | 680 DisallowHeapAllocation no_allocation; |
640 // This checks the invariants of the union representation: | 681 // This checks the invariants of the union representation: |
641 // 1. There are at least two elements. | 682 // 1. There are at least two elements. |
642 // 2. At most one element is a bitset, and it must be the first one. | 683 // 2. The first element is a bitset, no other element is a bitset. |
643 // 3. At most one element is a range, and it must be the second one | 684 // 3. At most one element is a range, and it must be the second one. |
644 // (even when the first element is not a bitset). | |
645 // 4. No element is itself a union. | 685 // 4. No element is itself a union. |
646 // 5. No element is a subtype of any other. | 686 // 5. No element (except the bitset) is a subtype of any other. |
647 // 6. If there is a range, then the bitset type does not contain | 687 // 6. If there is a range, then the bitset type does not contain |
648 // plain number bits. | 688 // plain number bits. |
649 DCHECK(this->Length() >= 2); // (1) | 689 DCHECK(this->Length() >= 2); // (1) |
650 | 690 DCHECK(this->Get(0)->IsBitset()); // (2a) |
651 bitset number_bits = this->Get(0)->IsBitset() | |
652 ? BitsetType::NumberBits(this->Get(0)->AsBitset()) : 0; | |
653 USE(number_bits); | |
654 | 691 |
655 for (int i = 0; i < this->Length(); ++i) { | 692 for (int i = 0; i < this->Length(); ++i) { |
656 if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2) | 693 if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2b) |
657 if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3) | 694 if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3) |
658 DCHECK(!this->Get(i)->IsUnion()); // (4) | 695 DCHECK(!this->Get(i)->IsUnion()); // (4) |
659 for (int j = 0; j < this->Length(); ++j) { | 696 for (int j = 0; j < this->Length(); ++j) { |
660 if (i != j) DCHECK(!this->Get(i)->Is(this->Get(j))); // (5) | 697 if (i != j && i != 0) |
| 698 DCHECK(!this->Get(i)->SemanticIs(this->Get(j)->unhandle())); // (5) |
661 } | 699 } |
662 } | 700 } |
663 DCHECK(!this->Get(1)->IsRange() || (number_bits == 0)); // (6) | 701 DCHECK(!this->Get(1)->IsRange() || |
| 702 (BitsetType::NumberBits(this->Get(0)->AsBitset()) == |
| 703 BitsetType::kNone)); // (6) |
664 return true; | 704 return true; |
665 } | 705 } |
666 | 706 |
667 | 707 |
668 // ----------------------------------------------------------------------------- | 708 // ----------------------------------------------------------------------------- |
669 // Union and intersection | 709 // Union and intersection |
670 | 710 |
671 | 711 |
672 static bool AddIsSafe(int x, int y) { | 712 static bool AddIsSafe(int x, int y) { |
673 return x >= 0 ? | 713 return x >= 0 ? |
674 y <= std::numeric_limits<int>::max() - x : | 714 y <= std::numeric_limits<int>::max() - x : |
675 y >= std::numeric_limits<int>::min() - x; | 715 y >= std::numeric_limits<int>::min() - x; |
676 } | 716 } |
677 | 717 |
678 | 718 |
679 template<class Config> | 719 template<class Config> |
680 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect( | 720 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect( |
681 TypeHandle type1, TypeHandle type2, Region* region) { | 721 TypeHandle type1, TypeHandle type2, Region* region) { |
682 bitset bits = type1->BitsetGlb() & type2->BitsetGlb(); | |
683 if (!BitsetType::IsInhabited(bits)) bits = BitsetType::kNone; | |
684 | 722 |
685 // Fast case: bit sets. | 723 // Fast case: bit sets. |
686 if (type1->IsBitset() && type2->IsBitset()) { | 724 if (type1->IsBitset() && type2->IsBitset()) { |
687 return BitsetType::New(bits, region); | 725 return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region); |
688 } | 726 } |
689 | 727 |
690 // Fast case: top or bottom types. | 728 // Fast case: top or bottom types. |
691 if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut. | 729 if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut. |
692 if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut. | 730 if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut. |
693 | 731 |
694 // Semi-fast case. | 732 // Semi-fast case. |
695 if (type1->Is(type2)) return type1; | 733 if (type1->Is(type2)) return type1; |
696 if (type2->Is(type1)) return type2; | 734 if (type2->Is(type1)) return type2; |
697 | 735 |
698 // Slow case: create union. | 736 // Slow case: create union. |
| 737 |
| 738 // Figure out the representation of the result first. |
| 739 // The rest of the method should not change this representation and |
| 740 // it should not make any decisions based on representations (i.e., |
| 741 // it should only use the semantic part of types). |
| 742 const bitset representation = |
| 743 type1->Representation() & type2->Representation(); |
| 744 |
| 745 // Semantic subtyping check - this is needed for consistency with the |
| 746 // semi-fast case above - we should behave the same way regardless of |
| 747 // representations. Intersection with a universal bitset should only update |
| 748 // the representations. |
| 749 if (type1->SemanticIs(type2->unhandle())) { |
| 750 type2 = Any(region); |
| 751 } else if (type2->SemanticIs(type1->unhandle())) { |
| 752 type1 = Any(region); |
| 753 } |
| 754 |
| 755 bitset bits = |
| 756 SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()) | representation; |
699 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; | 757 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; |
700 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; | 758 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; |
701 if (!AddIsSafe(size1, size2)) return Any(region); | 759 if (!AddIsSafe(size1, size2)) return Any(region); |
702 int size = size1 + size2; | 760 int size = size1 + size2; |
703 if (!AddIsSafe(size, 2)) return Any(region); | 761 if (!AddIsSafe(size, 2)) return Any(region); |
704 size += 2; | 762 size += 2; |
705 UnionHandle result = UnionType::New(size, region); | 763 UnionHandle result = UnionType::New(size, region); |
706 size = 0; | 764 size = 0; |
707 | 765 |
708 // Deal with bitsets. | 766 // Deal with bitsets. |
709 result->Set(size++, BitsetType::New(bits, region)); | 767 result->Set(size++, BitsetType::New(bits, region)); |
710 // Insert a placeholder for the range. | |
711 result->Set(size++, None(region)); | |
712 | 768 |
713 Limits lims = Limits::Empty(region); | 769 Limits lims = Limits::Empty(region); |
714 size = IntersectAux(type1, type2, result, size, &lims, region); | 770 size = IntersectAux(type1, type2, result, size, &lims, region); |
715 | 771 |
716 // If the range is not empty, then insert it into the union and | 772 // If the range is not empty, then insert it into the union and |
717 // remove the number bits from the bitset. | 773 // remove the number bits from the bitset. |
718 if (!IsEmpty(lims)) { | 774 if (!IsEmpty(lims)) { |
719 size = UpdateRange(RangeType::New(lims, region), result, size, region); | 775 size = UpdateRange(RangeType::New(lims, representation, region), result, |
| 776 size, region); |
720 | 777 |
721 // Remove the number bits. | 778 // Remove the number bits. |
722 bitset number_bits = BitsetType::NumberBits(bits); | 779 bitset number_bits = BitsetType::NumberBits(bits); |
723 bits &= ~number_bits; | 780 bits &= ~number_bits; |
724 if (SEMANTIC(bits) == BitsetType::kNone) { | |
725 bits = BitsetType::kNone; | |
726 } | |
727 result->Set(0, BitsetType::New(bits, region)); | 781 result->Set(0, BitsetType::New(bits, region)); |
728 } | 782 } |
729 return NormalizeUnion(result, size); | 783 return NormalizeUnion(result, size); |
730 } | 784 } |
731 | 785 |
732 | 786 |
733 template<class Config> | 787 template<class Config> |
734 int TypeImpl<Config>::UpdateRange( | 788 int TypeImpl<Config>::UpdateRange( |
735 RangeHandle range, UnionHandle result, int size, Region* region) { | 789 RangeHandle range, UnionHandle result, int size, Region* region) { |
736 TypeHandle old_range = result->Get(1); | 790 if (size == 1) { |
737 DCHECK(old_range->IsRange() || old_range->IsNone()); | 791 result->Set(size++, range); |
738 if (range->Is(old_range)) return size; | 792 } else { |
739 if (!old_range->Is(range->unhandle())) { | 793 // Make space for the range. |
740 range = RangeType::New( | 794 result->Set(size++, result->Get(1)); |
741 Union(Limits(range->AsRange()), Limits(old_range->AsRange())), region); | 795 result->Set(1, range); |
742 } | 796 } |
743 result->Set(1, range); | |
744 | 797 |
745 // Remove any components that just got subsumed. | 798 // Remove any components that just got subsumed. |
746 for (int i = 2; i < size; ) { | 799 for (int i = 2; i < size; ) { |
747 if (result->Get(i)->Is(range->unhandle())) { | 800 if (result->Get(i)->SemanticIs(range->unhandle())) { |
748 result->Set(i, result->Get(--size)); | 801 result->Set(i, result->Get(--size)); |
749 } else { | 802 } else { |
750 ++i; | 803 ++i; |
751 } | 804 } |
752 } | 805 } |
753 return size; | 806 return size; |
754 } | 807 } |
755 | 808 |
756 | 809 |
757 template <class Config> | 810 template <class Config> |
758 typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits, | 811 typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits, |
759 Region* region) { | 812 Region* region) { |
760 bitset representation = REPRESENTATION(bits); | |
761 bitset number_bits = BitsetType::NumberBits(bits); | 813 bitset number_bits = BitsetType::NumberBits(bits); |
762 | 814 |
763 if (representation == BitsetType::kNone && number_bits == BitsetType::kNone) { | 815 if (number_bits == BitsetType::kNone) { |
764 return Limits::Empty(region); | 816 return Limits::Empty(region); |
765 } | 817 } |
766 | 818 |
767 return Limits(BitsetType::Min(number_bits), BitsetType::Max(number_bits), | 819 return Limits(BitsetType::Min(number_bits), BitsetType::Max(number_bits)); |
768 representation); | |
769 } | 820 } |
770 | 821 |
771 | 822 |
772 template <class Config> | 823 template <class Config> |
773 typename TypeImpl<Config>::Limits TypeImpl<Config>::IntersectRangeAndBitset( | 824 typename TypeImpl<Config>::Limits TypeImpl<Config>::IntersectRangeAndBitset( |
774 TypeHandle range, TypeHandle bitset, Region* region) { | 825 TypeHandle range, TypeHandle bitset, Region* region) { |
775 Limits range_lims(range->AsRange()); | 826 Limits range_lims(range->AsRange()); |
776 Limits bitset_lims = ToLimits(bitset->AsBitset(), region); | 827 Limits bitset_lims = ToLimits(bitset->AsBitset(), region); |
777 return Intersect(range_lims, bitset_lims); | 828 return Intersect(range_lims, bitset_lims); |
778 } | 829 } |
(...skipping 11 matching lines...) Expand all Loading... |
790 return size; | 841 return size; |
791 } | 842 } |
792 if (rhs->IsUnion()) { | 843 if (rhs->IsUnion()) { |
793 for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) { | 844 for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) { |
794 size = | 845 size = |
795 IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, region); | 846 IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, region); |
796 } | 847 } |
797 return size; | 848 return size; |
798 } | 849 } |
799 | 850 |
800 if (!BitsetType::IsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) { | 851 if (!BitsetType::SemanticIsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) { |
801 return size; | 852 return size; |
802 } | 853 } |
803 | 854 |
804 if (lhs->IsRange()) { | 855 if (lhs->IsRange()) { |
805 if (rhs->IsBitset()) { | 856 if (rhs->IsBitset()) { |
806 Limits lim = IntersectRangeAndBitset(lhs, rhs, region); | 857 Limits lim = IntersectRangeAndBitset(lhs, rhs, region); |
807 | 858 |
808 if (!IsEmpty(lim)) { | 859 if (!IsEmpty(lim)) { |
809 *lims = Union(lim, *lims); | 860 *lims = Union(lim, *lims); |
810 } | 861 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 RangeHandle range, bitset* bits, Region* region) { | 901 RangeHandle range, bitset* bits, Region* region) { |
851 // Fast path: If the bitset does not mention numbers, we can just keep the | 902 // Fast path: If the bitset does not mention numbers, we can just keep the |
852 // range. | 903 // range. |
853 bitset number_bits = BitsetType::NumberBits(*bits); | 904 bitset number_bits = BitsetType::NumberBits(*bits); |
854 if (number_bits == 0) { | 905 if (number_bits == 0) { |
855 return range; | 906 return range; |
856 } | 907 } |
857 | 908 |
858 // If the range is contained within the bitset, return an empty range | 909 // If the range is contained within the bitset, return an empty range |
859 // (but make sure we take the representation). | 910 // (but make sure we take the representation). |
860 bitset range_lub = range->BitsetLub(); | 911 bitset range_lub = SEMANTIC(range->BitsetLub()); |
861 if (BitsetType::Is(BitsetType::NumberBits(range_lub), *bits)) { | 912 if (BitsetType::Is(BitsetType::NumberBits(range_lub), *bits)) { |
862 *bits |= range_lub; | |
863 return None(region); | 913 return None(region); |
864 } | 914 } |
865 | 915 |
866 // Slow path: reconcile the bitset range and the range. | 916 // Slow path: reconcile the bitset range and the range. |
867 double bitset_min = BitsetType::Min(number_bits); | 917 double bitset_min = BitsetType::Min(number_bits); |
868 double bitset_max = BitsetType::Max(number_bits); | 918 double bitset_max = BitsetType::Max(number_bits); |
869 | 919 |
870 double range_min = range->Min(); | 920 double range_min = range->Min(); |
871 double range_max = range->Max(); | 921 double range_max = range->Max(); |
872 | 922 |
873 bitset range_representation = REPRESENTATION(range->BitsetLub()); | |
874 bitset bits_representation = REPRESENTATION(*bits); | |
875 bitset representation = | |
876 (bits_representation | range_representation) & BitsetType::kNumber; | |
877 | |
878 // Remove the number bits from the bitset, they would just confuse us now. | 923 // Remove the number bits from the bitset, they would just confuse us now. |
879 *bits &= ~number_bits; | 924 *bits &= ~number_bits; |
880 if (bits_representation == *bits) { | |
881 *bits = BitsetType::kNone; | |
882 } | |
883 | 925 |
884 if (representation == range_representation && range_min <= bitset_min && | 926 if (range_min <= bitset_min && range_max >= bitset_max) { |
885 range_max >= bitset_max) { | |
886 // Bitset is contained within the range, just return the range. | 927 // Bitset is contained within the range, just return the range. |
887 return range; | 928 return range; |
888 } | 929 } |
889 | 930 |
890 if (bitset_min < range_min) { | 931 if (bitset_min < range_min) { |
891 range_min = bitset_min; | 932 range_min = bitset_min; |
892 } | 933 } |
893 if (bitset_max > range_max) { | 934 if (bitset_max > range_max) { |
894 range_max = bitset_max; | 935 range_max = bitset_max; |
895 } | 936 } |
896 return RangeType::New(range_min, range_max, | 937 return RangeType::New(range_min, range_max, |
897 BitsetType::New(representation, region), region); | 938 BitsetType::New(BitsetType::kNone, region), region); |
898 } | 939 } |
899 | 940 |
900 | 941 |
901 template<class Config> | 942 template<class Config> |
902 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( | 943 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( |
903 TypeHandle type1, TypeHandle type2, Region* region) { | 944 TypeHandle type1, TypeHandle type2, Region* region) { |
904 | |
905 // Fast case: bit sets. | 945 // Fast case: bit sets. |
906 if (type1->IsBitset() && type2->IsBitset()) { | 946 if (type1->IsBitset() && type2->IsBitset()) { |
907 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region); | 947 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region); |
908 } | 948 } |
909 | 949 |
910 // Fast case: top or bottom types. | 950 // Fast case: top or bottom types. |
911 if (type1->IsAny() || type2->IsNone()) return type1; | 951 if (type1->IsAny() || type2->IsNone()) return type1; |
912 if (type2->IsAny() || type1->IsNone()) return type2; | 952 if (type2->IsAny() || type1->IsNone()) return type2; |
913 | 953 |
914 // Semi-fast case. | 954 // Semi-fast case. |
915 if (type1->Is(type2)) return type2; | 955 if (type1->Is(type2)) return type2; |
916 if (type2->Is(type1)) return type1; | 956 if (type2->Is(type1)) return type1; |
917 | 957 |
| 958 // Figure out the representation of the result. |
| 959 // The rest of the method should not change this representation and |
| 960 // it should make any decisions based on representations (i.e., |
| 961 // it should only use the semantic part of types). |
| 962 const bitset representation = |
| 963 type1->Representation() | type2->Representation(); |
| 964 |
918 // Slow case: create union. | 965 // Slow case: create union. |
919 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; | 966 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; |
920 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; | 967 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; |
921 if (!AddIsSafe(size1, size2)) return Any(region); | 968 if (!AddIsSafe(size1, size2)) return Any(region); |
922 int size = size1 + size2; | 969 int size = size1 + size2; |
923 if (!AddIsSafe(size, 2)) return Any(region); | 970 if (!AddIsSafe(size, 2)) return Any(region); |
924 size += 2; | 971 size += 2; |
925 UnionHandle result = UnionType::New(size, region); | 972 UnionHandle result = UnionType::New(size, region); |
926 size = 0; | 973 size = 0; |
927 | 974 |
928 // Compute the new bitset. | 975 // Compute the new bitset. |
929 bitset new_bitset = type1->BitsetGlb() | type2->BitsetGlb(); | 976 bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb()); |
930 | 977 |
931 // Deal with ranges. | 978 // Deal with ranges. |
932 TypeHandle range = None(region); | 979 TypeHandle range = None(region); |
933 RangeType* range1 = type1->GetRange(); | 980 RangeType* range1 = type1->GetRange(); |
934 RangeType* range2 = type2->GetRange(); | 981 RangeType* range2 = type2->GetRange(); |
935 if (range1 != NULL && range2 != NULL) { | 982 if (range1 != NULL && range2 != NULL) { |
936 Limits lims = Union(Limits(range1), Limits(range2)); | 983 Limits lims = Union(Limits(range1), Limits(range2)); |
937 RangeHandle union_range = RangeType::New(lims, region); | 984 RangeHandle union_range = RangeType::New(lims, representation, region); |
938 range = NormalizeRangeAndBitset(union_range, &new_bitset, region); | 985 range = NormalizeRangeAndBitset(union_range, &new_bitset, region); |
939 } else if (range1 != NULL) { | 986 } else if (range1 != NULL) { |
940 range = NormalizeRangeAndBitset(handle(range1), &new_bitset, region); | 987 range = NormalizeRangeAndBitset(handle(range1), &new_bitset, region); |
941 } else if (range2 != NULL) { | 988 } else if (range2 != NULL) { |
942 range = NormalizeRangeAndBitset(handle(range2), &new_bitset, region); | 989 range = NormalizeRangeAndBitset(handle(range2), &new_bitset, region); |
943 } | 990 } |
| 991 new_bitset = SEMANTIC(new_bitset) | representation; |
944 TypeHandle bits = BitsetType::New(new_bitset, region); | 992 TypeHandle bits = BitsetType::New(new_bitset, region); |
945 result->Set(size++, bits); | 993 result->Set(size++, bits); |
946 result->Set(size++, range); | 994 if (!range->IsNone()) result->Set(size++, range); |
947 | 995 |
948 size = AddToUnion(type1, result, size, region); | 996 size = AddToUnion(type1, result, size, region); |
949 size = AddToUnion(type2, result, size, region); | 997 size = AddToUnion(type2, result, size, region); |
950 return NormalizeUnion(result, size); | 998 return NormalizeUnion(result, size); |
951 } | 999 } |
952 | 1000 |
953 | 1001 |
954 // Add [type] to [result] unless [type] is bitset, range, or already subsumed. | 1002 // Add [type] to [result] unless [type] is bitset, range, or already subsumed. |
955 // Return new size of [result]. | 1003 // Return new size of [result]. |
956 template<class Config> | 1004 template<class Config> |
957 int TypeImpl<Config>::AddToUnion( | 1005 int TypeImpl<Config>::AddToUnion( |
958 TypeHandle type, UnionHandle result, int size, Region* region) { | 1006 TypeHandle type, UnionHandle result, int size, Region* region) { |
959 if (type->IsBitset() || type->IsRange()) return size; | 1007 if (type->IsBitset() || type->IsRange()) return size; |
960 if (type->IsUnion()) { | 1008 if (type->IsUnion()) { |
961 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { | 1009 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { |
962 size = AddToUnion(type->AsUnion()->Get(i), result, size, region); | 1010 size = AddToUnion(type->AsUnion()->Get(i), result, size, region); |
963 } | 1011 } |
964 return size; | 1012 return size; |
965 } | 1013 } |
966 for (int i = 0; i < size; ++i) { | 1014 for (int i = 0; i < size; ++i) { |
967 if (type->Is(result->Get(i))) return size; | 1015 if (type->SemanticIs(result->Get(i)->unhandle())) return size; |
968 } | 1016 } |
969 result->Set(size++, type); | 1017 result->Set(size++, type); |
970 return size; | 1018 return size; |
971 } | 1019 } |
972 | 1020 |
973 | 1021 |
974 template<class Config> | 1022 template<class Config> |
975 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeUnion( | 1023 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeUnion( |
976 UnionHandle unioned, int size) { | 1024 UnionHandle unioned, int size) { |
977 DCHECK(size >= 2); | 1025 DCHECK(size >= 1); |
978 // If range is subsumed by bitset, use its place for a different type. | 1026 DCHECK(unioned->Get(0)->IsBitset()); |
979 if (unioned->Get(1)->Is(unioned->Get(0))) { | 1027 // If the union has just one element, return it. |
980 unioned->Set(1, unioned->Get(--size)); | 1028 if (size == 1) { |
| 1029 return unioned->Get(0); |
981 } | 1030 } |
982 // If bitset is None, use its place for a different type. | 1031 bitset bits = unioned->Get(0)->AsBitset(); |
983 if (size >= 2 && unioned->Get(0)->IsNone()) { | 1032 // If the union only consists of a range, we can get rid of the union. |
984 unioned->Set(0, unioned->Get(--size)); | 1033 if (size == 2 && SEMANTIC(bits) == BitsetType::kNone) { |
| 1034 bitset representation = REPRESENTATION(bits); |
| 1035 if (representation == unioned->Get(1)->Representation()) { |
| 1036 return unioned->Get(1); |
| 1037 } |
| 1038 // TODO(jarin) If the element at 1 is range of constant, slap |
| 1039 // the representation on it and return that. |
985 } | 1040 } |
986 if (size == 1) return unioned->Get(0); | |
987 unioned->Shrink(size); | 1041 unioned->Shrink(size); |
988 SLOW_DCHECK(unioned->Wellformed()); | 1042 SLOW_DCHECK(unioned->Wellformed()); |
989 return unioned; | 1043 return unioned; |
990 } | 1044 } |
991 | 1045 |
992 | 1046 |
993 // ----------------------------------------------------------------------------- | 1047 // ----------------------------------------------------------------------------- |
| 1048 // Component extraction |
| 1049 |
| 1050 // static |
| 1051 template <class Config> |
| 1052 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Representation( |
| 1053 TypeHandle t, Region* region) { |
| 1054 return BitsetType::New(t->Representation(), region); |
| 1055 } |
| 1056 |
| 1057 |
| 1058 // static |
| 1059 template <class Config> |
| 1060 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Semantic( |
| 1061 TypeHandle t, Region* region) { |
| 1062 return Intersect(t, BitsetType::New(BitsetType::kSemantic, region), region); |
| 1063 } |
| 1064 |
| 1065 |
| 1066 // ----------------------------------------------------------------------------- |
994 // Iteration. | 1067 // Iteration. |
995 | 1068 |
996 template<class Config> | 1069 template<class Config> |
997 int TypeImpl<Config>::NumClasses() { | 1070 int TypeImpl<Config>::NumClasses() { |
998 DisallowHeapAllocation no_allocation; | 1071 DisallowHeapAllocation no_allocation; |
999 if (this->IsClass()) { | 1072 if (this->IsClass()) { |
1000 return 1; | 1073 return 1; |
1001 } else if (this->IsUnion()) { | 1074 } else if (this->IsUnion()) { |
1002 int result = 0; | 1075 int result = 0; |
1003 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 1076 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1287 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; | 1360 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; |
1288 | 1361 |
1289 template TypeImpl<ZoneTypeConfig>::TypeHandle | 1362 template TypeImpl<ZoneTypeConfig>::TypeHandle |
1290 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 1363 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
1291 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 1364 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
1292 template TypeImpl<HeapTypeConfig>::TypeHandle | 1365 template TypeImpl<HeapTypeConfig>::TypeHandle |
1293 TypeImpl<HeapTypeConfig>::Convert<Type>( | 1366 TypeImpl<HeapTypeConfig>::Convert<Type>( |
1294 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 1367 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
1295 | 1368 |
1296 } } // namespace v8::internal | 1369 } } // namespace v8::internal |
OLD | NEW |