Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(406)

Side by Side Diff: src/types.cc

Issue 219333003: Fix Type::Intersect to skip uninhabited bitsets (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-crbug-357330.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-crbug-357330.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698