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 int bitset = kNone; |
25 for (int i = 0; i < unioned->Length(); ++i) { | 25 for (int i = 0; i < unioned->Length(); ++i) { |
rossberg
2014/08/05 15:07:53
You don't need this loop anymore: only the first e
neis
2014/08/05 17:01:10
Good point.
| |
26 bitset |= unioned->Get(i)->BitsetGlb(); | 26 bitset |= unioned->Get(i)->BitsetGlb(); |
27 } | 27 } |
28 return bitset; | 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 { | 29 } else { |
43 UNREACHABLE(); | |
44 return kNone; | 30 return kNone; |
45 } | 31 } |
46 } | 32 } |
47 | 33 |
48 | 34 |
49 // The smallest bitset subsuming this type. | 35 // The smallest bitset subsuming this type. |
50 template<class Config> | 36 template<class Config> |
51 int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { | 37 int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { |
52 DisallowHeapAllocation no_allocation; | 38 DisallowHeapAllocation no_allocation; |
53 if (type->IsBitset()) { | 39 if (type->IsBitset()) { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 // Check this <= that. | 239 // Check this <= that. |
254 template<class Config> | 240 template<class Config> |
255 bool TypeImpl<Config>::SlowIs(TypeImpl* that) { | 241 bool TypeImpl<Config>::SlowIs(TypeImpl* that) { |
256 DisallowHeapAllocation no_allocation; | 242 DisallowHeapAllocation no_allocation; |
257 | 243 |
258 // Fast path for bitsets. | 244 // Fast path for bitsets. |
259 if (this->IsNone()) return true; | 245 if (this->IsNone()) return true; |
260 if (that->IsBitset()) { | 246 if (that->IsBitset()) { |
261 return BitsetType::Is(BitsetType::Lub(this), that->AsBitset()); | 247 return BitsetType::Is(BitsetType::Lub(this), that->AsBitset()); |
262 } | 248 } |
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 | 249 |
268 if (that->IsClass()) { | 250 if (that->IsClass()) { |
269 return this->IsClass() | 251 return this->IsClass() |
270 && *this->AsClass()->Map() == *that->AsClass()->Map() | 252 && *this->AsClass()->Map() == *that->AsClass()->Map() |
271 && ((Config::is_class(that) && Config::is_class(this)) || | 253 && ((Config::is_class(that) && Config::is_class(this)) || |
272 BitsetType::New(this->BitsetLub())->Is( | 254 BitsetType::New(this->BitsetLub())->Is( |
273 BitsetType::New(that->BitsetLub()))); | 255 BitsetType::New(that->BitsetLub()))); |
274 } | 256 } |
275 if (that->IsConstant()) { | 257 if (that->IsConstant()) { |
276 return this->IsConstant() | 258 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; | 530 if (new_bound == type_i_bound) return size; |
549 } | 531 } |
550 if (new_bound != old_bound) type = type->Rebound(new_bound, region); | 532 if (new_bound != old_bound) type = type->Rebound(new_bound, region); |
551 result->Set(i, type); | 533 result->Set(i, type); |
552 } | 534 } |
553 } | 535 } |
554 return size; | 536 return size; |
555 } | 537 } |
556 | 538 |
557 | 539 |
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. | 540 // Union is O(1) on simple bitsets, but O(n*m) on structured unions. |
579 template<class Config> | 541 template<class Config> |
580 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( | 542 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( |
581 TypeHandle type1, TypeHandle type2, Region* region) { | 543 TypeHandle type1, TypeHandle type2, Region* region) { |
582 // Fast case: bit sets. | 544 // Fast case: bit sets. |
583 if (type1->IsBitset() && type2->IsBitset()) { | 545 if (type1->IsBitset() && type2->IsBitset()) { |
584 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region); | 546 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region); |
585 } | 547 } |
586 | 548 |
587 // Fast case: top or bottom types. | 549 // Fast case: top or bottom types. |
(...skipping 18 matching lines...) Expand all Loading... | |
606 if (bitset != BitsetType::kNone) ++size; | 568 if (bitset != BitsetType::kNone) ++size; |
607 DCHECK(size >= 1); | 569 DCHECK(size >= 1); |
608 | 570 |
609 UnionHandle unioned = UnionType::New(size, region); | 571 UnionHandle unioned = UnionType::New(size, region); |
610 size = 0; | 572 size = 0; |
611 if (bitset != BitsetType::kNone) { | 573 if (bitset != BitsetType::kNone) { |
612 unioned->Set(size++, BitsetType::New(bitset, region)); | 574 unioned->Set(size++, BitsetType::New(bitset, region)); |
613 } | 575 } |
614 size = ExtendUnion(unioned, size, type1, type2, false, region); | 576 size = ExtendUnion(unioned, size, type1, type2, false, region); |
615 size = ExtendUnion(unioned, size, type2, type1, false, region); | 577 size = ExtendUnion(unioned, size, type2, type1, false, region); |
616 size = NormalizeUnion(unioned, size, bitset); | |
617 | 578 |
618 if (size == 1) { | 579 if (size == 1) { |
619 return unioned->Get(0); | 580 return unioned->Get(0); |
620 } else { | 581 } else { |
621 unioned->Shrink(size); | 582 unioned->Shrink(size); |
622 DCHECK(unioned->Wellformed()); | 583 DCHECK(unioned->Wellformed()); |
623 return unioned; | 584 return unioned; |
624 } | 585 } |
625 } | 586 } |
626 | 587 |
(...skipping 29 matching lines...) Expand all Loading... | |
656 if (bitset != BitsetType::kNone) ++size; | 617 if (bitset != BitsetType::kNone) ++size; |
657 DCHECK(size >= 1); | 618 DCHECK(size >= 1); |
658 | 619 |
659 UnionHandle unioned = UnionType::New(size, region); | 620 UnionHandle unioned = UnionType::New(size, region); |
660 size = 0; | 621 size = 0; |
661 if (bitset != BitsetType::kNone) { | 622 if (bitset != BitsetType::kNone) { |
662 unioned->Set(size++, BitsetType::New(bitset, region)); | 623 unioned->Set(size++, BitsetType::New(bitset, region)); |
663 } | 624 } |
664 size = ExtendUnion(unioned, size, type1, type2, true, region); | 625 size = ExtendUnion(unioned, size, type1, type2, true, region); |
665 size = ExtendUnion(unioned, size, type2, type1, true, region); | 626 size = ExtendUnion(unioned, size, type2, type1, true, region); |
666 size = NormalizeUnion(unioned, size, bitset); | |
667 | 627 |
668 if (size == 0) { | 628 if (size == 0) { |
669 return None(region); | 629 return None(region); |
670 } else if (size == 1) { | 630 } else if (size == 1) { |
671 return unioned->Get(0); | 631 return unioned->Get(0); |
672 } else { | 632 } else { |
673 unioned->Shrink(size); | 633 unioned->Shrink(size); |
674 DCHECK(unioned->Wellformed()); | 634 DCHECK(unioned->Wellformed()); |
675 return unioned; | 635 return unioned; |
676 } | 636 } |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
960 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; | 920 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; |
961 | 921 |
962 template TypeImpl<ZoneTypeConfig>::TypeHandle | 922 template TypeImpl<ZoneTypeConfig>::TypeHandle |
963 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 923 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
964 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 924 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
965 template TypeImpl<HeapTypeConfig>::TypeHandle | 925 template TypeImpl<HeapTypeConfig>::TypeHandle |
966 TypeImpl<HeapTypeConfig>::Convert<Type>( | 926 TypeImpl<HeapTypeConfig>::Convert<Type>( |
967 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 927 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
968 | 928 |
969 } } // namespace v8::internal | 929 } } // namespace v8::internal |
OLD | NEW |