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