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 { |
11 namespace internal { | 11 namespace internal { |
12 | 12 |
13 // ----------------------------------------------------------------------------- | 13 // ----------------------------------------------------------------------------- |
14 // Glb and lub computation. | 14 // Glb and lub computation. |
15 | 15 |
16 // The largest bitset subsumed by this type. | 16 // The largest bitset subsumed by this type. |
17 template<class Config> | 17 template<class Config> |
18 int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { | 18 int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { |
19 DisallowHeapAllocation no_allocation; | 19 DisallowHeapAllocation no_allocation; |
20 if (type->IsBitset()) { | 20 if (type->IsBitset()) { |
21 return type->AsBitset(); | 21 return type->AsBitset(); |
22 } else if (type->IsUnion()) { | 22 } else if (type->IsUnion()) { |
23 UnionHandle unioned = handle(type->AsUnion()); | 23 UnionHandle unioned = handle(type->AsUnion()); |
24 int bitset = kNone; | 24 DCHECK(unioned->Wellformed()); |
25 for (int i = 0; i < unioned->Length(); ++i) { | 25 return unioned->Get(0)->BitsetGlb(); // Other BitsetGlb's are kNone anyway. |
26 bitset |= unioned->Get(i)->BitsetGlb(); | |
27 } | |
28 return bitset; | |
29 } else if (type->IsClass()) { | |
30 // Little hack to avoid the need for a region for handlification here... | |
31 return REPRESENTATION(Config::is_class(type) | |
32 ? Lub(*Config::as_class(type)) | |
33 : type->AsClass()->Bound(NULL)->AsBitset()); | |
34 } else if (type->IsConstant()) { | |
35 return REPRESENTATION(type->AsConstant()->Bound()->AsBitset()); | |
36 } else if (type->IsContext()) { | |
37 return REPRESENTATION(type->AsContext()->Bound()->AsBitset()); | |
38 } else if (type->IsArray()) { | |
39 return REPRESENTATION(type->AsArray()->Bound()->AsBitset()); | |
40 } else if (type->IsFunction()) { | |
41 return REPRESENTATION(type->AsFunction()->Bound()->AsBitset()); | |
42 } else { | 26 } else { |
43 UNREACHABLE(); | |
44 return kNone; | 27 return kNone; |
45 } | 28 } |
46 } | 29 } |
47 | 30 |
48 | 31 |
49 // The smallest bitset subsuming this type. | 32 // The smallest bitset subsuming this type. |
50 template<class Config> | 33 template<class Config> |
51 int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { | 34 int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { |
52 DisallowHeapAllocation no_allocation; | 35 DisallowHeapAllocation no_allocation; |
53 if (type->IsBitset()) { | 36 if (type->IsBitset()) { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 // Check this <= that. | 236 // Check this <= that. |
254 template<class Config> | 237 template<class Config> |
255 bool TypeImpl<Config>::SlowIs(TypeImpl* that) { | 238 bool TypeImpl<Config>::SlowIs(TypeImpl* that) { |
256 DisallowHeapAllocation no_allocation; | 239 DisallowHeapAllocation no_allocation; |
257 | 240 |
258 // Fast path for bitsets. | 241 // Fast path for bitsets. |
259 if (this->IsNone()) return true; | 242 if (this->IsNone()) return true; |
260 if (that->IsBitset()) { | 243 if (that->IsBitset()) { |
261 return BitsetType::Is(BitsetType::Lub(this), that->AsBitset()); | 244 return BitsetType::Is(BitsetType::Lub(this), that->AsBitset()); |
262 } | 245 } |
263 if (this->IsBitset() && SEMANTIC(this->AsBitset()) == BitsetType::kNone) { | |
264 // Bitsets only have non-bitset supertypes along the representation axis. | |
265 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); | |
266 } | |
267 | 246 |
268 if (that->IsClass()) { | 247 if (that->IsClass()) { |
269 return this->IsClass() | 248 return this->IsClass() |
270 && *this->AsClass()->Map() == *that->AsClass()->Map() | 249 && *this->AsClass()->Map() == *that->AsClass()->Map() |
271 && ((Config::is_class(that) && Config::is_class(this)) || | 250 && ((Config::is_class(that) && Config::is_class(this)) || |
272 BitsetType::New(this->BitsetLub())->Is( | 251 BitsetType::New(this->BitsetLub())->Is( |
273 BitsetType::New(that->BitsetLub()))); | 252 BitsetType::New(that->BitsetLub()))); |
274 } | 253 } |
275 if (that->IsConstant()) { | 254 if (that->IsConstant()) { |
276 return this->IsConstant() | 255 return this->IsConstant() |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 if (new_bound == type_i_bound) return size; | 527 if (new_bound == type_i_bound) return size; |
549 } | 528 } |
550 if (new_bound != old_bound) type = type->Rebound(new_bound, region); | 529 if (new_bound != old_bound) type = type->Rebound(new_bound, region); |
551 result->Set(i, type); | 530 result->Set(i, type); |
552 } | 531 } |
553 } | 532 } |
554 return size; | 533 return size; |
555 } | 534 } |
556 | 535 |
557 | 536 |
558 // If bitset is subsumed by another entry in the result, remove it. | |
559 // (Only bitsets with empty semantic axis can be subtypes of non-bitsets.) | |
560 template<class Config> | |
561 int TypeImpl<Config>::NormalizeUnion(UnionHandle result, int size, int bitset) { | |
562 if (bitset != BitsetType::kNone && SEMANTIC(bitset) == BitsetType::kNone) { | |
563 for (int i = 1; i < size; ++i) { | |
564 int glb = result->Get(i)->BitsetGlb(); | |
565 if (BitsetType::Is(bitset, glb)) { | |
566 for (int j = 1; j < size; ++j) { | |
567 result->Set(j - 1, result->Get(j)); | |
568 } | |
569 --size; | |
570 break; | |
571 } | |
572 } | |
573 } | |
574 return size; | |
575 } | |
576 | |
577 | |
578 // Union is O(1) on simple bitsets, but O(n*m) on structured unions. | 537 // Union is O(1) on simple bitsets, but O(n*m) on structured unions. |
579 template<class Config> | 538 template<class Config> |
580 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( | 539 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( |
581 TypeHandle type1, TypeHandle type2, Region* region) { | 540 TypeHandle type1, TypeHandle type2, Region* region) { |
582 // Fast case: bit sets. | 541 // Fast case: bit sets. |
583 if (type1->IsBitset() && type2->IsBitset()) { | 542 if (type1->IsBitset() && type2->IsBitset()) { |
584 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region); | 543 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region); |
585 } | 544 } |
586 | 545 |
587 // Fast case: top or bottom types. | 546 // Fast case: top or bottom types. |
(...skipping 18 matching lines...) Expand all Loading... |
606 if (bitset != BitsetType::kNone) ++size; | 565 if (bitset != BitsetType::kNone) ++size; |
607 DCHECK(size >= 1); | 566 DCHECK(size >= 1); |
608 | 567 |
609 UnionHandle unioned = UnionType::New(size, region); | 568 UnionHandle unioned = UnionType::New(size, region); |
610 size = 0; | 569 size = 0; |
611 if (bitset != BitsetType::kNone) { | 570 if (bitset != BitsetType::kNone) { |
612 unioned->Set(size++, BitsetType::New(bitset, region)); | 571 unioned->Set(size++, BitsetType::New(bitset, region)); |
613 } | 572 } |
614 size = ExtendUnion(unioned, size, type1, type2, false, region); | 573 size = ExtendUnion(unioned, size, type1, type2, false, region); |
615 size = ExtendUnion(unioned, size, type2, type1, false, region); | 574 size = ExtendUnion(unioned, size, type2, type1, false, region); |
616 size = NormalizeUnion(unioned, size, bitset); | |
617 | 575 |
618 if (size == 1) { | 576 if (size == 1) { |
619 return unioned->Get(0); | 577 return unioned->Get(0); |
620 } else { | 578 } else { |
621 unioned->Shrink(size); | 579 unioned->Shrink(size); |
622 DCHECK(unioned->Wellformed()); | 580 DCHECK(unioned->Wellformed()); |
623 return unioned; | 581 return unioned; |
624 } | 582 } |
625 } | 583 } |
626 | 584 |
(...skipping 29 matching lines...) Expand all Loading... |
656 if (bitset != BitsetType::kNone) ++size; | 614 if (bitset != BitsetType::kNone) ++size; |
657 DCHECK(size >= 1); | 615 DCHECK(size >= 1); |
658 | 616 |
659 UnionHandle unioned = UnionType::New(size, region); | 617 UnionHandle unioned = UnionType::New(size, region); |
660 size = 0; | 618 size = 0; |
661 if (bitset != BitsetType::kNone) { | 619 if (bitset != BitsetType::kNone) { |
662 unioned->Set(size++, BitsetType::New(bitset, region)); | 620 unioned->Set(size++, BitsetType::New(bitset, region)); |
663 } | 621 } |
664 size = ExtendUnion(unioned, size, type1, type2, true, region); | 622 size = ExtendUnion(unioned, size, type1, type2, true, region); |
665 size = ExtendUnion(unioned, size, type2, type1, true, region); | 623 size = ExtendUnion(unioned, size, type2, type1, true, region); |
666 size = NormalizeUnion(unioned, size, bitset); | |
667 | 624 |
668 if (size == 0) { | 625 if (size == 0) { |
669 return None(region); | 626 return None(region); |
670 } else if (size == 1) { | 627 } else if (size == 1) { |
671 return unioned->Get(0); | 628 return unioned->Get(0); |
672 } else { | 629 } else { |
673 unioned->Shrink(size); | 630 unioned->Shrink(size); |
674 DCHECK(unioned->Wellformed()); | 631 DCHECK(unioned->Wellformed()); |
675 return unioned; | 632 return unioned; |
676 } | 633 } |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
960 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; | 917 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; |
961 | 918 |
962 template TypeImpl<ZoneTypeConfig>::TypeHandle | 919 template TypeImpl<ZoneTypeConfig>::TypeHandle |
963 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 920 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
964 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 921 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
965 template TypeImpl<HeapTypeConfig>::TypeHandle | 922 template TypeImpl<HeapTypeConfig>::TypeHandle |
966 TypeImpl<HeapTypeConfig>::Convert<Type>( | 923 TypeImpl<HeapTypeConfig>::Convert<Type>( |
967 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 924 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
968 | 925 |
969 } } // namespace v8::internal | 926 } } // namespace v8::internal |
OLD | NEW |