| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 // TODO(rossberg): Should we use object sets somehow? Is it worth it? | 417 // TODO(rossberg): Should we use object sets somehow? Is it worth it? |
| 418 template<class Config> | 418 template<class Config> |
| 419 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( | 419 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( |
| 420 TypeHandle type1, TypeHandle type2, Region* region) { | 420 TypeHandle type1, TypeHandle type2, Region* region) { |
| 421 // Fast case: bit sets. | 421 // Fast case: bit sets. |
| 422 if (type1->IsBitset() && type2->IsBitset()) { | 422 if (type1->IsBitset() && type2->IsBitset()) { |
| 423 return Config::from_bitset(type1->AsBitset() | type2->AsBitset(), region); | 423 return Config::from_bitset(type1->AsBitset() | type2->AsBitset(), region); |
| 424 } | 424 } |
| 425 | 425 |
| 426 // Fast case: top or bottom types. | 426 // Fast case: top or bottom types. |
| 427 if (type1->IsAny()) return type1; | 427 if (type1->IsAny() || type2->IsNone()) return type1; |
| 428 if (type2->IsAny()) return type2; | 428 if (type2->IsAny() || type1->IsNone()) return type2; |
| 429 if (type1->IsNone()) return type2; | |
| 430 if (type2->IsNone()) return type1; | |
| 431 | 429 |
| 432 // Semi-fast case: Unioned objects are neither involved nor produced. | 430 // Semi-fast case: Unioned objects are neither involved nor produced. |
| 433 if (!(type1->IsUnion() || type2->IsUnion())) { | 431 if (!(type1->IsUnion() || type2->IsUnion())) { |
| 434 if (type1->Is(type2)) return type2; | 432 if (type1->Is(type2)) return type2; |
| 435 if (type2->Is(type1)) return type1; | 433 if (type2->Is(type1)) return type1; |
| 436 } | 434 } |
| 437 | 435 |
| 438 // Slow case: may need to produce a Unioned object. | 436 // Slow case: may need to produce a Unioned object. |
| 439 int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0; | 437 int size = 0; |
| 440 if (!type1->IsBitset()) { | 438 if (!type1->IsBitset()) { |
| 441 size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1); | 439 size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1); |
| 442 } | 440 } |
| 443 if (!type2->IsBitset()) { | 441 if (!type2->IsBitset()) { |
| 444 size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1); | 442 size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1); |
| 445 } | 443 } |
| 446 ASSERT(size >= 2); | 444 int bitset = type1->GlbBitset() | type2->GlbBitset(); |
| 445 if (IsInhabited(bitset)) ++size; |
| 446 ASSERT(size >= 1); |
| 447 UnionedHandle unioned = Config::union_create(size, region); | 447 UnionedHandle unioned = Config::union_create(size, region); |
| 448 |
| 448 size = 0; | 449 size = 0; |
| 449 | 450 if (IsInhabited(bitset)) { |
| 450 int bitset = type1->GlbBitset() | type2->GlbBitset(); | |
| 451 if (bitset != kNone) { | |
| 452 Config::union_set(unioned, size++, Config::from_bitset(bitset, region)); | 451 Config::union_set(unioned, size++, Config::from_bitset(bitset, region)); |
| 453 } | 452 } |
| 454 size = ExtendUnion(unioned, type1, size); | 453 size = ExtendUnion(unioned, type1, size); |
| 455 size = ExtendUnion(unioned, type2, size); | 454 size = ExtendUnion(unioned, type2, size); |
| 456 | 455 |
| 457 if (size == 1) { | 456 if (size == 1) { |
| 458 return Config::union_get(unioned, 0); | 457 return Config::union_get(unioned, 0); |
| 459 } else { | 458 } else { |
| 460 Config::union_shrink(unioned, size); | 459 Config::union_shrink(unioned, size); |
| 461 return Config::from_union(unioned); | 460 return Config::from_union(unioned); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 // TODO(rossberg): Should we use object sets somehow? Is it worth it? | 492 // TODO(rossberg): Should we use object sets somehow? Is it worth it? |
| 494 template<class Config> | 493 template<class Config> |
| 495 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect( | 494 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect( |
| 496 TypeHandle type1, TypeHandle type2, Region* region) { | 495 TypeHandle type1, TypeHandle type2, Region* region) { |
| 497 // Fast case: bit sets. | 496 // Fast case: bit sets. |
| 498 if (type1->IsBitset() && type2->IsBitset()) { | 497 if (type1->IsBitset() && type2->IsBitset()) { |
| 499 return Config::from_bitset(type1->AsBitset() & type2->AsBitset(), region); | 498 return Config::from_bitset(type1->AsBitset() & type2->AsBitset(), region); |
| 500 } | 499 } |
| 501 | 500 |
| 502 // Fast case: top or bottom types. | 501 // Fast case: top or bottom types. |
| 503 if (type1->IsNone()) return type1; | 502 if (type1->IsNone() || type2->IsAny()) return type1; |
| 504 if (type2->IsNone()) return type2; | 503 if (type2->IsNone() || type1->IsAny()) return type2; |
| 505 if (type1->IsAny()) return type2; | |
| 506 if (type2->IsAny()) return type1; | |
| 507 | 504 |
| 508 // Semi-fast case: Unioned objects are neither involved nor produced. | 505 // Semi-fast case: Unioned objects are neither involved nor produced. |
| 509 if (!(type1->IsUnion() || type2->IsUnion())) { | 506 if (!(type1->IsUnion() || type2->IsUnion())) { |
| 510 if (type1->Is(type2)) return type1; | 507 if (type1->Is(type2)) return type1; |
| 511 if (type2->Is(type1)) return type2; | 508 if (type2->Is(type1)) return type2; |
| 512 } | 509 } |
| 513 | 510 |
| 514 // Slow case: may need to produce a Unioned object. | 511 // Slow case: may need to produce a Unioned object. |
| 515 int size = 0; | 512 int size = INT_MAX; |
| 516 if (!type1->IsBitset()) { | 513 if (!type1->IsBitset()) { |
| 517 size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 2); | 514 size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1); |
| 518 } | 515 } |
| 519 if (!type2->IsBitset()) { | 516 if (!type2->IsBitset()) { |
| 520 int size2 = (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 2); | 517 size = Min(size, |
| 521 size = (size == 0 ? size2 : Min(size, size2)); | 518 type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1); |
| 522 } | 519 } |
| 523 ASSERT(size >= 2); | 520 int bitset = type1->GlbBitset() & type2->GlbBitset(); |
| 521 if (IsInhabited(bitset)) ++size; |
| 522 ASSERT(size >= 1); |
| 524 UnionedHandle unioned = Config::union_create(size, region); | 523 UnionedHandle unioned = Config::union_create(size, region); |
| 524 |
| 525 size = 0; | 525 size = 0; |
| 526 | 526 if (IsInhabited(bitset)) { |
| 527 int bitset = type1->GlbBitset() & type2->GlbBitset(); | |
| 528 if (bitset != kNone) { | |
| 529 Config::union_set(unioned, size++, Config::from_bitset(bitset, region)); | 527 Config::union_set(unioned, size++, Config::from_bitset(bitset, region)); |
| 530 } | 528 } |
| 531 size = ExtendIntersection(unioned, type1, type2, size); | 529 size = ExtendIntersection(unioned, type1, type2, size); |
| 532 size = ExtendIntersection(unioned, type2, type1, size); | 530 size = ExtendIntersection(unioned, type2, type1, size); |
| 533 | 531 |
| 534 if (size == 0) { | 532 if (size == 0) { |
| 535 return None(region); | 533 return None(region); |
| 536 } else if (size == 1) { | 534 } else if (size == 1) { |
| 537 return Config::union_get(unioned, 0); | 535 return Config::union_get(unioned, 0); |
| 538 } else { | 536 } else { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 } | 636 } |
| 639 | 637 |
| 640 | 638 |
| 641 template<class Config> | 639 template<class Config> |
| 642 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) { | 640 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) { |
| 643 if (this->IsBitset()) { | 641 if (this->IsBitset()) { |
| 644 int bitset = this->AsBitset(); | 642 int bitset = this->AsBitset(); |
| 645 switch (dim) { | 643 switch (dim) { |
| 646 case BOTH_DIMS: | 644 case BOTH_DIMS: |
| 647 BitsetTypePrint(out, bitset & kSemantic); | 645 BitsetTypePrint(out, bitset & kSemantic); |
| 648 PrintF("/"); | 646 PrintF(out, "/"); |
| 649 BitsetTypePrint(out, bitset & kRepresentation); | 647 BitsetTypePrint(out, bitset & kRepresentation); |
| 650 break; | 648 break; |
| 651 case SEMANTIC_DIM: | 649 case SEMANTIC_DIM: |
| 652 BitsetTypePrint(out, bitset & kSemantic); | 650 BitsetTypePrint(out, bitset & kSemantic); |
| 653 break; | 651 break; |
| 654 case REPRESENTATION_DIM: | 652 case REPRESENTATION_DIM: |
| 655 BitsetTypePrint(out, bitset & kRepresentation); | 653 BitsetTypePrint(out, bitset & kRepresentation); |
| 656 break; | 654 break; |
| 657 } | 655 } |
| 658 } else if (this->IsConstant()) { | 656 } else if (this->IsConstant()) { |
| 659 PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant())); | 657 PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant())); |
| 660 Config::from_bitset(this->LubBitset())->TypePrint(out); | 658 Config::from_bitset(this->LubBitset())->TypePrint(out); |
| 661 PrintF(")"); | 659 PrintF(out, ")"); |
| 662 } else if (this->IsClass()) { | 660 } else if (this->IsClass()) { |
| 663 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass())); | 661 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass())); |
| 664 Config::from_bitset(this->LubBitset())->TypePrint(out); | 662 Config::from_bitset(this->LubBitset())->TypePrint(out); |
| 665 PrintF(")"); | 663 PrintF(out, ")"); |
| 666 } else if (this->IsUnion()) { | 664 } else if (this->IsUnion()) { |
| 667 PrintF(out, "("); | 665 PrintF(out, "("); |
| 668 UnionedHandle unioned = this->AsUnion(); | 666 UnionedHandle unioned = this->AsUnion(); |
| 669 for (int i = 0; i < Config::union_length(unioned); ++i) { | 667 for (int i = 0; i < Config::union_length(unioned); ++i) { |
| 670 TypeHandle type_i = Config::union_get(unioned, i); | 668 TypeHandle type_i = Config::union_get(unioned, i); |
| 671 if (i > 0) PrintF(out, " | "); | 669 if (i > 0) PrintF(out, " | "); |
| 672 type_i->TypePrint(out); | 670 type_i->TypePrint(out, dim); |
| 673 } | 671 } |
| 674 PrintF(out, ")"); | 672 PrintF(out, ")"); |
| 675 } | 673 } |
| 676 } | 674 } |
| 677 #endif | 675 #endif |
| 678 | 676 |
| 679 | 677 |
| 680 template class TypeImpl<ZoneTypeConfig>; | 678 template class TypeImpl<ZoneTypeConfig>; |
| 681 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>; | 679 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>; |
| 682 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>; | 680 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>; |
| 683 | 681 |
| 684 template class TypeImpl<HeapTypeConfig>; | 682 template class TypeImpl<HeapTypeConfig>; |
| 685 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>; | 683 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>; |
| 686 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; | 684 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; |
| 687 | 685 |
| 688 template TypeImpl<ZoneTypeConfig>::TypeHandle | 686 template TypeImpl<ZoneTypeConfig>::TypeHandle |
| 689 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 687 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
| 690 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 688 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
| 691 template TypeImpl<HeapTypeConfig>::TypeHandle | 689 template TypeImpl<HeapTypeConfig>::TypeHandle |
| 692 TypeImpl<HeapTypeConfig>::Convert<Type>( | 690 TypeImpl<HeapTypeConfig>::Convert<Type>( |
| 693 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 691 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
| 694 | 692 |
| 695 | 693 |
| 696 } } // namespace v8::internal | 694 } } // namespace v8::internal |
| OLD | NEW |