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 "src/types.h" | 5 #include "src/types.h" |
6 | 6 |
7 #include "src/ostreams.h" | 7 #include "src/ostreams.h" |
8 #include "src/types-inl.h" | 8 #include "src/types-inl.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 12 matching lines...) Expand all Loading... |
23 static bool deq(double x, double y) { | 23 static bool deq(double x, double y) { |
24 return dle(x, y) && dle(y, x); | 24 return dle(x, y) && dle(y, x); |
25 } | 25 } |
26 | 26 |
27 | 27 |
28 // ----------------------------------------------------------------------------- | 28 // ----------------------------------------------------------------------------- |
29 // Glb and lub computation. | 29 // Glb and lub computation. |
30 | 30 |
31 // The largest bitset subsumed by this type. | 31 // The largest bitset subsumed by this type. |
32 template<class Config> | 32 template<class Config> |
33 int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { | 33 typename TypeImpl<Config>::bitset |
| 34 TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { |
34 DisallowHeapAllocation no_allocation; | 35 DisallowHeapAllocation no_allocation; |
35 if (type->IsBitset()) { | 36 if (type->IsBitset()) { |
36 return type->AsBitset(); | 37 return type->AsBitset(); |
37 } else if (type->IsUnion()) { | 38 } else if (type->IsUnion()) { |
38 UnionHandle unioned = handle(type->AsUnion()); | 39 UnionHandle unioned = handle(type->AsUnion()); |
39 DCHECK(unioned->Wellformed()); | 40 DCHECK(unioned->Wellformed()); |
40 return unioned->Get(0)->BitsetGlb(); // Other BitsetGlb's are kNone anyway. | 41 return unioned->Get(0)->BitsetGlb(); // Other BitsetGlb's are kNone anyway. |
41 } else { | 42 } else { |
42 return kNone; | 43 return kNone; |
43 } | 44 } |
44 } | 45 } |
45 | 46 |
46 | 47 |
47 // The smallest bitset subsuming this type. | 48 // The smallest bitset subsuming this type. |
48 template<class Config> | 49 template<class Config> |
49 int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { | 50 typename TypeImpl<Config>::bitset |
| 51 TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { |
50 DisallowHeapAllocation no_allocation; | 52 DisallowHeapAllocation no_allocation; |
51 if (type->IsBitset()) { | 53 if (type->IsBitset()) { |
52 return type->AsBitset(); | 54 return type->AsBitset(); |
53 } else if (type->IsUnion()) { | 55 } else if (type->IsUnion()) { |
54 UnionHandle unioned = handle(type->AsUnion()); | 56 UnionHandle unioned = handle(type->AsUnion()); |
55 int bitset = kNone; | 57 bitset result = kNone; |
56 for (int i = 0; i < unioned->Length(); ++i) { | 58 for (int i = 0; i < unioned->Length(); ++i) { |
57 bitset |= unioned->Get(i)->BitsetLub(); | 59 result |= unioned->Get(i)->BitsetLub(); |
58 } | 60 } |
59 return bitset; | 61 return result; |
60 } else if (type->IsClass()) { | 62 } else if (type->IsClass()) { |
61 // Little hack to avoid the need for a region for handlification here... | 63 // Little hack to avoid the need for a region for handlification here... |
62 return Config::is_class(type) ? Lub(*Config::as_class(type)) : | 64 return Config::is_class(type) ? Lub(*Config::as_class(type)) : |
63 type->AsClass()->Bound(NULL)->AsBitset(); | 65 type->AsClass()->Bound(NULL)->AsBitset(); |
64 } else if (type->IsConstant()) { | 66 } else if (type->IsConstant()) { |
65 return type->AsConstant()->Bound()->AsBitset(); | 67 return type->AsConstant()->Bound()->AsBitset(); |
66 } else if (type->IsRange()) { | 68 } else if (type->IsRange()) { |
67 return type->AsRange()->Bound()->AsBitset(); | 69 return type->AsRange()->Bound()->AsBitset(); |
68 } else if (type->IsContext()) { | 70 } else if (type->IsContext()) { |
69 return type->AsContext()->Bound()->AsBitset(); | 71 return type->AsContext()->Bound()->AsBitset(); |
70 } else if (type->IsArray()) { | 72 } else if (type->IsArray()) { |
71 return type->AsArray()->Bound()->AsBitset(); | 73 return type->AsArray()->Bound()->AsBitset(); |
72 } else if (type->IsFunction()) { | 74 } else if (type->IsFunction()) { |
73 return type->AsFunction()->Bound()->AsBitset(); | 75 return type->AsFunction()->Bound()->AsBitset(); |
74 } else { | 76 } else { |
75 UNREACHABLE(); | 77 UNREACHABLE(); |
76 return kNone; | 78 return kNone; |
77 } | 79 } |
78 } | 80 } |
79 | 81 |
80 | 82 |
81 // The smallest bitset subsuming this type, ignoring explicit bounds. | 83 // The smallest bitset subsuming this type, ignoring explicit bounds. |
82 template<class Config> | 84 template<class Config> |
83 int TypeImpl<Config>::BitsetType::InherentLub(TypeImpl* type) { | 85 typename TypeImpl<Config>::bitset |
| 86 TypeImpl<Config>::BitsetType::InherentLub(TypeImpl* type) { |
84 DisallowHeapAllocation no_allocation; | 87 DisallowHeapAllocation no_allocation; |
85 if (type->IsBitset()) { | 88 if (type->IsBitset()) { |
86 return type->AsBitset(); | 89 return type->AsBitset(); |
87 } else if (type->IsUnion()) { | 90 } else if (type->IsUnion()) { |
88 UnionHandle unioned = handle(type->AsUnion()); | 91 UnionHandle unioned = handle(type->AsUnion()); |
89 int bitset = kNone; | 92 bitset result = kNone; |
90 for (int i = 0; i < unioned->Length(); ++i) { | 93 for (int i = 0; i < unioned->Length(); ++i) { |
91 bitset |= unioned->Get(i)->InherentBitsetLub(); | 94 result |= unioned->Get(i)->InherentBitsetLub(); |
92 } | 95 } |
93 return bitset; | 96 return result; |
94 } else if (type->IsClass()) { | 97 } else if (type->IsClass()) { |
95 return Lub(*type->AsClass()->Map()); | 98 return Lub(*type->AsClass()->Map()); |
96 } else if (type->IsConstant()) { | 99 } else if (type->IsConstant()) { |
97 return Lub(*type->AsConstant()->Value()); | 100 return Lub(*type->AsConstant()->Value()); |
98 } else if (type->IsRange()) { | 101 } else if (type->IsRange()) { |
99 return Lub(type->AsRange()->Min(), type->AsRange()->Max()); | 102 return Lub(type->AsRange()->Min(), type->AsRange()->Max()); |
100 } else if (type->IsContext()) { | 103 } else if (type->IsContext()) { |
101 return kInternal & kTaggedPtr; | 104 return kInternal & kTaggedPtr; |
102 } else if (type->IsArray()) { | 105 } else if (type->IsArray()) { |
103 return kArray; | 106 return kArray; |
104 } else if (type->IsFunction()) { | 107 } else if (type->IsFunction()) { |
105 return kFunction; | 108 return kFunction; |
106 } else { | 109 } else { |
107 UNREACHABLE(); | 110 UNREACHABLE(); |
108 return kNone; | 111 return kNone; |
109 } | 112 } |
110 } | 113 } |
111 | 114 |
112 | 115 |
113 template<class Config> | 116 template<class Config> |
114 int TypeImpl<Config>::BitsetType::Lub(i::Object* value) { | 117 typename TypeImpl<Config>::bitset |
| 118 TypeImpl<Config>::BitsetType::Lub(i::Object* value) { |
115 DisallowHeapAllocation no_allocation; | 119 DisallowHeapAllocation no_allocation; |
116 if (value->IsNumber()) { | 120 if (value->IsNumber()) { |
117 return Lub(value->Number()) & (value->IsSmi() ? kTaggedInt : kTaggedPtr); | 121 return Lub(value->Number()) & (value->IsSmi() ? kTaggedInt : kTaggedPtr); |
118 } | 122 } |
119 return Lub(i::HeapObject::cast(value)->map()); | 123 return Lub(i::HeapObject::cast(value)->map()); |
120 } | 124 } |
121 | 125 |
122 | 126 |
123 template<class Config> | 127 template<class Config> |
124 int TypeImpl<Config>::BitsetType::Lub(double value) { | 128 typename TypeImpl<Config>::bitset |
| 129 TypeImpl<Config>::BitsetType::Lub(double value) { |
125 DisallowHeapAllocation no_allocation; | 130 DisallowHeapAllocation no_allocation; |
126 if (i::IsMinusZero(value)) return kMinusZero; | 131 if (i::IsMinusZero(value)) return kMinusZero; |
127 if (std::isnan(value)) return kNaN; | 132 if (std::isnan(value)) return kNaN; |
128 if (IsUint32Double(value)) return Lub(FastD2UI(value)); | 133 if (IsUint32Double(value)) return Lub(FastD2UI(value)); |
129 if (IsInt32Double(value)) return Lub(FastD2I(value)); | 134 if (IsInt32Double(value)) return Lub(FastD2I(value)); |
130 return kOtherNumber; | 135 return kOtherNumber; |
131 } | 136 } |
132 | 137 |
133 | 138 |
134 template<class Config> | 139 template<class Config> |
135 int TypeImpl<Config>::BitsetType::Lub(double min, double max) { | 140 typename TypeImpl<Config>::bitset |
| 141 TypeImpl<Config>::BitsetType::Lub(double min, double max) { |
136 DisallowHeapAllocation no_allocation; | 142 DisallowHeapAllocation no_allocation; |
137 DCHECK(dle(min, max)); | 143 DCHECK(dle(min, max)); |
138 if (deq(min, max)) return BitsetType::Lub(min); // Singleton range. | 144 if (deq(min, max)) return BitsetType::Lub(min); // Singleton range. |
139 int bitset = BitsetType::kNumber ^ SEMANTIC(BitsetType::kNaN); | 145 bitset result = BitsetType::kNumber ^ SEMANTIC(BitsetType::kNaN); |
140 if (dle(0, min) || max < 0) bitset ^= SEMANTIC(BitsetType::kMinusZero); | 146 if (dle(0, min) || max < 0) result ^= SEMANTIC(BitsetType::kMinusZero); |
141 return bitset; | 147 return result; |
142 // TODO(neis): Could refine this further by doing more checks on min/max. | 148 // TODO(neis): Could refine this further by doing more checks on min/max. |
143 } | 149 } |
144 | 150 |
145 | 151 |
146 template<class Config> | 152 template<class Config> |
147 int TypeImpl<Config>::BitsetType::Lub(int32_t value) { | 153 typename TypeImpl<Config>::bitset |
| 154 TypeImpl<Config>::BitsetType::Lub(int32_t value) { |
148 if (value >= 0x40000000) { | 155 if (value >= 0x40000000) { |
149 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; | 156 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; |
150 } | 157 } |
151 if (value >= 0) return kUnsignedSmall; | 158 if (value >= 0) return kUnsignedSmall; |
152 if (value >= -0x40000000) return kOtherSignedSmall; | 159 if (value >= -0x40000000) return kOtherSignedSmall; |
153 return i::SmiValuesAre31Bits() ? kOtherSigned32 : kOtherSignedSmall; | 160 return i::SmiValuesAre31Bits() ? kOtherSigned32 : kOtherSignedSmall; |
154 } | 161 } |
155 | 162 |
156 | 163 |
157 template<class Config> | 164 template<class Config> |
158 int TypeImpl<Config>::BitsetType::Lub(uint32_t value) { | 165 typename TypeImpl<Config>::bitset |
| 166 TypeImpl<Config>::BitsetType::Lub(uint32_t value) { |
159 DisallowHeapAllocation no_allocation; | 167 DisallowHeapAllocation no_allocation; |
160 if (value >= 0x80000000u) return kOtherUnsigned32; | 168 if (value >= 0x80000000u) return kOtherUnsigned32; |
161 if (value >= 0x40000000u) { | 169 if (value >= 0x40000000u) { |
162 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; | 170 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; |
163 } | 171 } |
164 return kUnsignedSmall; | 172 return kUnsignedSmall; |
165 } | 173 } |
166 | 174 |
167 | 175 |
168 template<class Config> | 176 template<class Config> |
169 int TypeImpl<Config>::BitsetType::Lub(i::Map* map) { | 177 typename TypeImpl<Config>::bitset |
| 178 TypeImpl<Config>::BitsetType::Lub(i::Map* map) { |
170 DisallowHeapAllocation no_allocation; | 179 DisallowHeapAllocation no_allocation; |
171 switch (map->instance_type()) { | 180 switch (map->instance_type()) { |
172 case STRING_TYPE: | 181 case STRING_TYPE: |
173 case ONE_BYTE_STRING_TYPE: | 182 case ONE_BYTE_STRING_TYPE: |
174 case CONS_STRING_TYPE: | 183 case CONS_STRING_TYPE: |
175 case CONS_ONE_BYTE_STRING_TYPE: | 184 case CONS_ONE_BYTE_STRING_TYPE: |
176 case SLICED_STRING_TYPE: | 185 case SLICED_STRING_TYPE: |
177 case SLICED_ONE_BYTE_STRING_TYPE: | 186 case SLICED_ONE_BYTE_STRING_TYPE: |
178 case EXTERNAL_STRING_TYPE: | 187 case EXTERNAL_STRING_TYPE: |
179 case EXTERNAL_ONE_BYTE_STRING_TYPE: | 188 case EXTERNAL_ONE_BYTE_STRING_TYPE: |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 } | 459 } |
451 return true; | 460 return true; |
452 } | 461 } |
453 | 462 |
454 | 463 |
455 // ----------------------------------------------------------------------------- | 464 // ----------------------------------------------------------------------------- |
456 // Union and intersection | 465 // Union and intersection |
457 | 466 |
458 template<class Config> | 467 template<class Config> |
459 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound( | 468 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound( |
460 int bitset, Region* region) { | 469 bitset bitset_bound, Region* region) { |
461 TypeHandle bound = BitsetType::New(bitset, region); | 470 TypeHandle bound = BitsetType::New(bitset_bound, region); |
462 if (this->IsClass()) { | 471 if (this->IsClass()) { |
463 return ClassType::New(this->AsClass()->Map(), bound, region); | 472 return ClassType::New(this->AsClass()->Map(), bound, region); |
464 } else if (this->IsConstant()) { | 473 } else if (this->IsConstant()) { |
465 return ConstantType::New(this->AsConstant()->Value(), bound, region); | 474 return ConstantType::New(this->AsConstant()->Value(), bound, region); |
466 } else if (this->IsRange()) { | 475 } else if (this->IsRange()) { |
467 return RangeType::New( | 476 return RangeType::New( |
468 this->AsRange()->Min(), this->AsRange()->Max(), bound, region); | 477 this->AsRange()->Min(), this->AsRange()->Max(), bound, region); |
469 } else if (this->IsContext()) { | 478 } else if (this->IsContext()) { |
470 return ContextType::New(this->AsContext()->Outer(), bound, region); | 479 return ContextType::New(this->AsContext()->Outer(), bound, region); |
471 } else if (this->IsArray()) { | 480 } else if (this->IsArray()) { |
472 return ArrayType::New(this->AsArray()->Element(), bound, region); | 481 return ArrayType::New(this->AsArray()->Element(), bound, region); |
473 } else if (this->IsFunction()) { | 482 } else if (this->IsFunction()) { |
474 FunctionHandle function = Config::handle(this->AsFunction()); | 483 FunctionHandle function = Config::handle(this->AsFunction()); |
475 int arity = function->Arity(); | 484 int arity = function->Arity(); |
476 FunctionHandle type = FunctionType::New( | 485 FunctionHandle type = FunctionType::New( |
477 function->Result(), function->Receiver(), bound, arity, region); | 486 function->Result(), function->Receiver(), bound, arity, region); |
478 for (int i = 0; i < arity; ++i) { | 487 for (int i = 0; i < arity; ++i) { |
479 type->InitParameter(i, function->Parameter(i)); | 488 type->InitParameter(i, function->Parameter(i)); |
480 } | 489 } |
481 return type; | 490 return type; |
482 } | 491 } |
483 UNREACHABLE(); | 492 UNREACHABLE(); |
484 return TypeHandle(); | 493 return TypeHandle(); |
485 } | 494 } |
486 | 495 |
487 | 496 |
488 template<class Config> | 497 template<class Config> |
489 int TypeImpl<Config>::BoundBy(TypeImpl* that) { | 498 typename TypeImpl<Config>::bitset TypeImpl<Config>::BoundBy(TypeImpl* that) { |
490 DCHECK(!this->IsUnion()); | 499 DCHECK(!this->IsUnion()); |
491 if (that->IsUnion()) { | 500 if (that->IsUnion()) { |
492 UnionType* unioned = that->AsUnion(); | 501 UnionType* unioned = that->AsUnion(); |
493 int length = unioned->Length(); | 502 int length = unioned->Length(); |
494 int bitset = BitsetType::kNone; | 503 bitset result = BitsetType::kNone; |
495 for (int i = 0; i < length; ++i) { | 504 for (int i = 0; i < length; ++i) { |
496 bitset |= BoundBy(unioned->Get(i)->unhandle()); | 505 result |= BoundBy(unioned->Get(i)->unhandle()); |
497 } | 506 } |
498 return bitset; | 507 return result; |
499 } else if (that->IsClass() && this->IsClass() && | 508 } else if (that->IsClass() && this->IsClass() && |
500 *this->AsClass()->Map() == *that->AsClass()->Map()) { | 509 *this->AsClass()->Map() == *that->AsClass()->Map()) { |
501 return that->BitsetLub(); | 510 return that->BitsetLub(); |
502 } else if (that->IsConstant() && this->IsConstant() && | 511 } else if (that->IsConstant() && this->IsConstant() && |
503 *this->AsConstant()->Value() == *that->AsConstant()->Value()) { | 512 *this->AsConstant()->Value() == *that->AsConstant()->Value()) { |
504 return that->AsConstant()->Bound()->AsBitset(); | 513 return that->AsConstant()->Bound()->AsBitset(); |
505 } else if (that->IsContext() && this->IsContext() && this->Is(that)) { | 514 } else if (that->IsContext() && this->IsContext() && this->Is(that)) { |
506 return that->AsContext()->Bound()->AsBitset(); | 515 return that->AsContext()->Bound()->AsBitset(); |
507 } else if (that->IsArray() && this->IsArray() && this->Is(that)) { | 516 } else if (that->IsArray() && this->IsArray() && this->Is(that)) { |
508 return that->AsArray()->Bound()->AsBitset(); | 517 return that->AsArray()->Bound()->AsBitset(); |
509 } else if (that->IsFunction() && this->IsFunction() && this->Is(that)) { | 518 } else if (that->IsFunction() && this->IsFunction() && this->Is(that)) { |
510 return that->AsFunction()->Bound()->AsBitset(); | 519 return that->AsFunction()->Bound()->AsBitset(); |
511 } | 520 } |
512 return that->BitsetGlb(); | 521 return that->BitsetGlb(); |
513 } | 522 } |
514 | 523 |
515 | 524 |
516 template<class Config> | 525 template<class Config> |
517 int TypeImpl<Config>::IndexInUnion( | 526 int TypeImpl<Config>::IndexInUnion( |
518 int bound, UnionHandle unioned, int current_size) { | 527 bitset bound, UnionHandle unioned, int current_size) { |
519 DCHECK(!this->IsUnion()); | 528 DCHECK(!this->IsUnion()); |
520 for (int i = 0; i < current_size; ++i) { | 529 for (int i = 0; i < current_size; ++i) { |
521 TypeHandle that = unioned->Get(i); | 530 TypeHandle that = unioned->Get(i); |
522 if (that->IsBitset()) { | 531 if (that->IsBitset()) { |
523 if (BitsetType::Is(bound, that->AsBitset())) return i; | 532 if (BitsetType::Is(bound, that->AsBitset())) return i; |
524 } else if (that->IsClass() && this->IsClass()) { | 533 } else if (that->IsClass() && this->IsClass()) { |
525 if (*this->AsClass()->Map() == *that->AsClass()->Map()) return i; | 534 if (*this->AsClass()->Map() == *that->AsClass()->Map()) return i; |
526 } else if (that->IsConstant() && this->IsConstant()) { | 535 } else if (that->IsConstant() && this->IsConstant()) { |
527 if (*this->AsConstant()->Value() == *that->AsConstant()->Value()) | 536 if (*this->AsConstant()->Value() == *that->AsConstant()->Value()) |
528 return i; | 537 return i; |
529 } else if (that->IsContext() && this->IsContext()) { | 538 } else if (that->IsContext() && this->IsContext()) { |
530 if (this->Is(that)) return i; | 539 if (this->Is(that)) return i; |
531 } else if (that->IsArray() && this->IsArray()) { | 540 } else if (that->IsArray() && this->IsArray()) { |
532 if (this->Is(that)) return i; | 541 if (this->Is(that)) return i; |
533 } else if (that->IsFunction() && this->IsFunction()) { | 542 } else if (that->IsFunction() && this->IsFunction()) { |
534 if (this->Is(that)) return i; | 543 if (this->Is(that)) return i; |
535 } | 544 } |
536 } | 545 } |
537 return -1; | 546 return -1; |
538 } | 547 } |
539 | 548 |
540 | 549 |
541 // Get non-bitsets from type, bounded by upper. | 550 // Get non-bitsets from type, bounded by upper. |
542 // Store at result starting at index. Returns updated index. | 551 // Store at result starting at index. Returns updated index. |
543 template<class Config> | 552 template<class Config> |
544 int TypeImpl<Config>::ExtendUnion( | 553 int TypeImpl<Config>::ExtendUnion( |
545 UnionHandle result, int size, TypeHandle type, | 554 UnionHandle result, int size, TypeHandle type, |
546 TypeHandle other, bool is_intersect, Region* region) { | 555 TypeHandle other, bool is_intersect, Region* region) { |
547 if (type->IsUnion()) { | 556 if (type->IsUnion()) { |
548 UnionHandle unioned = handle(type->AsUnion()); | 557 UnionHandle unioned = Config::template cast<UnionType>(type); |
549 for (int i = 0; i < unioned->Length(); ++i) { | 558 for (int i = 0; i < unioned->Length(); ++i) { |
550 TypeHandle type_i = unioned->Get(i); | 559 TypeHandle type_i = unioned->Get(i); |
551 DCHECK(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0)))); | 560 DCHECK(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0)))); |
552 if (!type_i->IsBitset()) { | 561 if (!type_i->IsBitset()) { |
553 size = ExtendUnion(result, size, type_i, other, is_intersect, region); | 562 size = ExtendUnion(result, size, type_i, other, is_intersect, region); |
554 } | 563 } |
555 } | 564 } |
556 } else if (!type->IsBitset()) { | 565 } else if (!type->IsBitset()) { |
557 DCHECK(type->IsClass() || type->IsConstant() || type->IsRange() || | 566 DCHECK(type->IsClass() || type->IsConstant() || type->IsRange() || |
558 type->IsContext() || type->IsArray() || type->IsFunction()); | 567 type->IsContext() || type->IsArray() || type->IsFunction()); |
559 int inherent_bound = type->InherentBitsetLub(); | 568 bitset inherent_bound = type->InherentBitsetLub(); |
560 int old_bound = type->BitsetLub(); | 569 bitset old_bound = type->BitsetLub(); |
561 int other_bound = type->BoundBy(other->unhandle()) & inherent_bound; | 570 bitset other_bound = type->BoundBy(other->unhandle()) & inherent_bound; |
562 int new_bound = | 571 bitset new_bound = |
563 is_intersect ? (old_bound & other_bound) : (old_bound | other_bound); | 572 is_intersect ? (old_bound & other_bound) : (old_bound | other_bound); |
564 if (new_bound != BitsetType::kNone) { | 573 if (new_bound != BitsetType::kNone) { |
565 int i = type->IndexInUnion(new_bound, result, size); | 574 int i = type->IndexInUnion(new_bound, result, size); |
566 if (i == -1) { | 575 if (i == -1) { |
567 i = size++; | 576 i = size++; |
568 } else if (result->Get(i)->IsBitset()) { | 577 } else if (result->Get(i)->IsBitset()) { |
569 return size; // Already fully subsumed. | 578 return size; // Already fully subsumed. |
570 } else { | 579 } else { |
571 int type_i_bound = result->Get(i)->BitsetLub(); | 580 bitset type_i_bound = result->Get(i)->BitsetLub(); |
572 new_bound |= type_i_bound; | 581 new_bound |= type_i_bound; |
573 if (new_bound == type_i_bound) return size; | 582 if (new_bound == type_i_bound) return size; |
574 } | 583 } |
575 if (new_bound != old_bound) type = type->Rebound(new_bound, region); | 584 if (new_bound != old_bound) type = type->Rebound(new_bound, region); |
576 result->Set(i, type); | 585 result->Set(i, type); |
577 } | 586 } |
578 } | 587 } |
579 return size; | 588 return size; |
580 } | 589 } |
581 | 590 |
(...skipping 18 matching lines...) Expand all Loading... |
600 } | 609 } |
601 | 610 |
602 // Slow case: may need to produce a Unioned object. | 611 // Slow case: may need to produce a Unioned object. |
603 int size = 0; | 612 int size = 0; |
604 if (!type1->IsBitset()) { | 613 if (!type1->IsBitset()) { |
605 size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1); | 614 size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1); |
606 } | 615 } |
607 if (!type2->IsBitset()) { | 616 if (!type2->IsBitset()) { |
608 size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); | 617 size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); |
609 } | 618 } |
610 int bitset = type1->BitsetGlb() | type2->BitsetGlb(); | 619 bitset bits = type1->BitsetGlb() | type2->BitsetGlb(); |
611 if (bitset != BitsetType::kNone) ++size; | 620 if (bits != BitsetType::kNone) ++size; |
612 DCHECK(size >= 1); | 621 DCHECK(size >= 1); |
613 | 622 |
614 UnionHandle unioned = UnionType::New(size, region); | 623 UnionHandle unioned = UnionType::New(size, region); |
615 size = 0; | 624 size = 0; |
616 if (bitset != BitsetType::kNone) { | 625 if (bits != BitsetType::kNone) { |
617 unioned->Set(size++, BitsetType::New(bitset, region)); | 626 unioned->Set(size++, BitsetType::New(bits, region)); |
618 } | 627 } |
619 size = ExtendUnion(unioned, size, type1, type2, false, region); | 628 size = ExtendUnion(unioned, size, type1, type2, false, region); |
620 size = ExtendUnion(unioned, size, type2, type1, false, region); | 629 size = ExtendUnion(unioned, size, type2, type1, false, region); |
621 | 630 |
622 if (size == 1) { | 631 if (size == 1) { |
623 return unioned->Get(0); | 632 return unioned->Get(0); |
624 } else { | 633 } else { |
625 unioned->Shrink(size); | 634 unioned->Shrink(size); |
626 DCHECK(unioned->Wellformed()); | 635 DCHECK(unioned->Wellformed()); |
627 return unioned; | 636 return unioned; |
(...skipping 21 matching lines...) Expand all Loading... |
649 } | 658 } |
650 | 659 |
651 // Slow case: may need to produce a Unioned object. | 660 // Slow case: may need to produce a Unioned object. |
652 int size = 0; | 661 int size = 0; |
653 if (!type1->IsBitset()) { | 662 if (!type1->IsBitset()) { |
654 size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1); | 663 size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1); |
655 } | 664 } |
656 if (!type2->IsBitset()) { | 665 if (!type2->IsBitset()) { |
657 size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); | 666 size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); |
658 } | 667 } |
659 int bitset = type1->BitsetGlb() & type2->BitsetGlb(); | 668 bitset bits = type1->BitsetGlb() & type2->BitsetGlb(); |
660 if (bitset != BitsetType::kNone) ++size; | 669 if (bits != BitsetType::kNone) ++size; |
661 DCHECK(size >= 1); | 670 DCHECK(size >= 1); |
662 | 671 |
663 UnionHandle unioned = UnionType::New(size, region); | 672 UnionHandle unioned = UnionType::New(size, region); |
664 size = 0; | 673 size = 0; |
665 if (bitset != BitsetType::kNone) { | 674 if (bits != BitsetType::kNone) { |
666 unioned->Set(size++, BitsetType::New(bitset, region)); | 675 unioned->Set(size++, BitsetType::New(bits, region)); |
667 } | 676 } |
668 size = ExtendUnion(unioned, size, type1, type2, true, region); | 677 size = ExtendUnion(unioned, size, type1, type2, true, region); |
669 size = ExtendUnion(unioned, size, type2, type1, true, region); | 678 size = ExtendUnion(unioned, size, type2, type1, true, region); |
670 | 679 |
671 if (size == 0) { | 680 if (size == 0) { |
672 return None(region); | 681 return None(region); |
673 } else if (size == 1) { | 682 } else if (size == 1) { |
674 return unioned->Get(0); | 683 return unioned->Get(0); |
675 } else { | 684 } else { |
676 unioned->Shrink(size); | 685 unioned->Shrink(size); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() { | 774 i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() { |
766 return TypeImplIteratorAux<Config, T>::current(get_type()); | 775 return TypeImplIteratorAux<Config, T>::current(get_type()); |
767 } | 776 } |
768 | 777 |
769 | 778 |
770 template<class Config> template<class T> | 779 template<class Config> template<class T> |
771 void TypeImpl<Config>::Iterator<T>::Advance() { | 780 void TypeImpl<Config>::Iterator<T>::Advance() { |
772 DisallowHeapAllocation no_allocation; | 781 DisallowHeapAllocation no_allocation; |
773 ++index_; | 782 ++index_; |
774 if (type_->IsUnion()) { | 783 if (type_->IsUnion()) { |
775 UnionHandle unioned = handle(type_->AsUnion()); | 784 UnionHandle unioned = Config::template cast<UnionType>(type_); |
776 for (; index_ < unioned->Length(); ++index_) { | 785 for (; index_ < unioned->Length(); ++index_) { |
777 if (matches(unioned->Get(index_))) return; | 786 if (matches(unioned->Get(index_))) return; |
778 } | 787 } |
779 } else if (index_ == 0 && matches(type_)) { | 788 } else if (index_ == 0 && matches(type_)) { |
780 return; | 789 return; |
781 } | 790 } |
782 index_ = -1; | 791 index_ = -1; |
783 } | 792 } |
784 | 793 |
785 | 794 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 UNREACHABLE(); | 843 UNREACHABLE(); |
835 return None(region); | 844 return None(region); |
836 } | 845 } |
837 } | 846 } |
838 | 847 |
839 | 848 |
840 // ----------------------------------------------------------------------------- | 849 // ----------------------------------------------------------------------------- |
841 // Printing. | 850 // Printing. |
842 | 851 |
843 template<class Config> | 852 template<class Config> |
844 const char* TypeImpl<Config>::BitsetType::Name(int bitset) { | 853 const char* TypeImpl<Config>::BitsetType::Name(bitset bits) { |
845 switch (bitset) { | 854 switch (bits) { |
846 case REPRESENTATION(kAny): return "Any"; | 855 case REPRESENTATION(kAny): return "Any"; |
847 #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ | 856 #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ |
848 case REPRESENTATION(k##type): return #type; | 857 case REPRESENTATION(k##type): return #type; |
849 REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE) | 858 REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE) |
850 #undef RETURN_NAMED_REPRESENTATION_TYPE | 859 #undef RETURN_NAMED_REPRESENTATION_TYPE |
851 | 860 |
852 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ | 861 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ |
853 case SEMANTIC(k##type): return #type; | 862 case SEMANTIC(k##type): return #type; |
854 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 863 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
855 #undef RETURN_NAMED_SEMANTIC_TYPE | 864 #undef RETURN_NAMED_SEMANTIC_TYPE |
856 | 865 |
857 default: | 866 default: |
858 return NULL; | 867 return NULL; |
859 } | 868 } |
860 } | 869 } |
861 | 870 |
862 | 871 |
863 template <class Config> | 872 template <class Config> |
864 void TypeImpl<Config>::BitsetType::Print(OStream& os, // NOLINT | 873 void TypeImpl<Config>::BitsetType::Print(OStream& os, // NOLINT |
865 int bitset) { | 874 bitset bits) { |
866 DisallowHeapAllocation no_allocation; | 875 DisallowHeapAllocation no_allocation; |
867 const char* name = Name(bitset); | 876 const char* name = Name(bits); |
868 if (name != NULL) { | 877 if (name != NULL) { |
869 os << name; | 878 os << name; |
870 return; | 879 return; |
871 } | 880 } |
872 | 881 |
873 static const int named_bitsets[] = { | 882 static const bitset named_bitsets[] = { |
874 #define BITSET_CONSTANT(type, value) REPRESENTATION(k##type), | 883 #define BITSET_CONSTANT(type, value) REPRESENTATION(k##type), |
875 REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) | 884 REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) |
876 #undef BITSET_CONSTANT | 885 #undef BITSET_CONSTANT |
877 | 886 |
878 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type), | 887 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type), |
879 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) | 888 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) |
880 #undef BITSET_CONSTANT | 889 #undef BITSET_CONSTANT |
881 }; | 890 }; |
882 | 891 |
883 bool is_first = true; | 892 bool is_first = true; |
884 os << "("; | 893 os << "("; |
885 for (int i(arraysize(named_bitsets) - 1); bitset != 0 && i >= 0; --i) { | 894 for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) { |
886 int subset = named_bitsets[i]; | 895 bitset subset = named_bitsets[i]; |
887 if ((bitset & subset) == subset) { | 896 if ((bits & subset) == subset) { |
888 if (!is_first) os << " | "; | 897 if (!is_first) os << " | "; |
889 is_first = false; | 898 is_first = false; |
890 os << Name(subset); | 899 os << Name(subset); |
891 bitset -= subset; | 900 bits -= subset; |
892 } | 901 } |
893 } | 902 } |
894 DCHECK(bitset == 0); | 903 DCHECK(bits == 0); |
895 os << ")"; | 904 os << ")"; |
896 } | 905 } |
897 | 906 |
898 | 907 |
899 template <class Config> | 908 template <class Config> |
900 void TypeImpl<Config>::PrintTo(OStream& os, PrintDimension dim) { // NOLINT | 909 void TypeImpl<Config>::PrintTo(OStream& os, PrintDimension dim) { // NOLINT |
901 DisallowHeapAllocation no_allocation; | 910 DisallowHeapAllocation no_allocation; |
902 if (dim != REPRESENTATION_DIM) { | 911 if (dim != REPRESENTATION_DIM) { |
903 if (this->IsBitset()) { | 912 if (this->IsBitset()) { |
904 BitsetType::Print(os, SEMANTIC(this->AsBitset())); | 913 BitsetType::Print(os, SEMANTIC(this->AsBitset())); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; | 987 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; |
979 | 988 |
980 template TypeImpl<ZoneTypeConfig>::TypeHandle | 989 template TypeImpl<ZoneTypeConfig>::TypeHandle |
981 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 990 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
982 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 991 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
983 template TypeImpl<HeapTypeConfig>::TypeHandle | 992 template TypeImpl<HeapTypeConfig>::TypeHandle |
984 TypeImpl<HeapTypeConfig>::Convert<Type>( | 993 TypeImpl<HeapTypeConfig>::Convert<Type>( |
985 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 994 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
986 | 995 |
987 } } // namespace v8::internal | 996 } } // namespace v8::internal |
OLD | NEW |