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

Side by Side Diff: src/types.cc

Issue 218403002: Fix Type::Intersect to allocate large enough union. 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 | « src/types.h ('k') | 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 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 if (type1->IsNone()) return type2; 429 if (type1->IsNone()) return type2;
430 if (type2->IsNone()) return type1; 430 if (type2->IsNone()) return type1;
431 431
432 // Semi-fast case: Unioned objects are neither involved nor produced. 432 // Semi-fast case: Unioned objects are neither involved nor produced.
433 if (!(type1->IsUnion() || type2->IsUnion())) { 433 if (!(type1->IsUnion() || type2->IsUnion())) {
434 if (type1->Is(type2)) return type2; 434 if (type1->Is(type2)) return type2;
435 if (type2->Is(type1)) return type1; 435 if (type2->Is(type1)) return type1;
436 } 436 }
437 437
438 // Slow case: may need to produce a Unioned object. 438 // Slow case: may need to produce a Unioned object.
439 int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0; 439 int bitset = type1->GlbBitset() | type2->GlbBitset();
440 int allocated_size = bitset != kNone ? 1 : 0;
440 if (!type1->IsBitset()) { 441 if (!type1->IsBitset()) {
441 size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1); 442 allocated_size += type1->IsUnion() ? Config::union_length(type1->AsUnion())
443 : 1;
442 } 444 }
443 if (!type2->IsBitset()) { 445 if (!type2->IsBitset()) {
444 size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1); 446 allocated_size += type2->IsUnion() ? Config::union_length(type2->AsUnion())
447 : 1;
445 } 448 }
446 ASSERT(size >= 2); 449 UnionedHandle unioned = Config::union_create(allocated_size, region);
447 UnionedHandle unioned = Config::union_create(size, region); 450 int used_size = 0;
448 size = 0;
449 451
450 int bitset = type1->GlbBitset() | type2->GlbBitset();
451 if (bitset != kNone) { 452 if (bitset != kNone) {
452 Config::union_set(unioned, size++, Config::from_bitset(bitset, region)); 453 Config::union_set(unioned, used_size++,
454 Config::from_bitset(bitset, region));
453 } 455 }
454 size = ExtendUnion(unioned, type1, size); 456 used_size = ExtendUnion(unioned, type1, used_size);
455 size = ExtendUnion(unioned, type2, size); 457 used_size = ExtendUnion(unioned, type2, used_size);
458 ASSERT(used_size <= allocated_size);
456 459
457 if (size == 1) { 460 if (used_size == 1) {
458 return Config::union_get(unioned, 0); 461 return Config::union_get(unioned, 0);
459 } else { 462 } else {
460 Config::union_shrink(unioned, size); 463 Config::union_shrink(unioned, used_size);
461 return Config::from_union(unioned); 464 return Config::from_union(unioned);
462 } 465 }
463 } 466 }
464 467
465 468
466 // Get non-bitsets from type which are also in other, store at unioned, 469 // Get non-bitsets from type which are also in other, store at unioned,
467 // starting at index. Returns updated index. 470 // starting at index. Returns updated index.
468 template<class Config> 471 template<class Config>
469 int TypeImpl<Config>::ExtendIntersection( 472 int TypeImpl<Config>::ExtendIntersection(
470 UnionedHandle result, TypeHandle type, TypeHandle other, int current_size) { 473 UnionedHandle result, TypeHandle type, TypeHandle other, int current_size) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 if (type1->IsAny()) return type2; 508 if (type1->IsAny()) return type2;
506 if (type2->IsAny()) return type1; 509 if (type2->IsAny()) return type1;
507 510
508 // Semi-fast case: Unioned objects are neither involved nor produced. 511 // Semi-fast case: Unioned objects are neither involved nor produced.
509 if (!(type1->IsUnion() || type2->IsUnion())) { 512 if (!(type1->IsUnion() || type2->IsUnion())) {
510 if (type1->Is(type2)) return type1; 513 if (type1->Is(type2)) return type1;
511 if (type2->Is(type1)) return type2; 514 if (type2->Is(type1)) return type2;
512 } 515 }
513 516
514 // Slow case: may need to produce a Unioned object. 517 // Slow case: may need to produce a Unioned object.
515 int size = 0; 518 int allocated_size = 0;
516 if (!type1->IsBitset()) { 519 if (!type1->IsBitset()) {
517 size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 2); 520 allocated_size = type1->IsUnion() ? Config::union_length(type1->AsUnion())
521 : 1;
518 } 522 }
519 if (!type2->IsBitset()) { 523 if (!type2->IsBitset()) {
520 int size2 = (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 2); 524 int size2 = type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1;
521 size = (size == 0 ? size2 : Min(size, size2)); 525 allocated_size = allocated_size == 0 ? size2 : Min(allocated_size, size2);
522 } 526 }
523 ASSERT(size >= 2); 527 int bitset = type1->GlbBitset() & type2->GlbBitset();
524 UnionedHandle unioned = Config::union_create(size, region); 528 if (bitset != kNone) allocated_size++;
525 size = 0; 529 UnionedHandle unioned = Config::union_create(allocated_size, region);
530 int used_size = 0;
526 531
527 int bitset = type1->GlbBitset() & type2->GlbBitset();
528 if (bitset != kNone) { 532 if (bitset != kNone) {
529 Config::union_set(unioned, size++, Config::from_bitset(bitset, region)); 533 Config::union_set(unioned, used_size++,
534 Config::from_bitset(bitset, region));
530 } 535 }
531 size = ExtendIntersection(unioned, type1, type2, size); 536 used_size = ExtendIntersection(unioned, type1, type2, used_size);
532 size = ExtendIntersection(unioned, type2, type1, size); 537 used_size = ExtendIntersection(unioned, type2, type1, used_size);
538 ASSERT(used_size <= allocated_size);
533 539
534 if (size == 0) { 540 if (used_size == 0) {
535 return None(region); 541 return None(region);
536 } else if (size == 1) { 542 } else if (used_size == 1) {
537 return Config::union_get(unioned, 0); 543 return Config::union_get(unioned, 0);
538 } else { 544 } else {
539 Config::union_shrink(unioned, size); 545 Config::union_shrink(unioned, used_size);
540 return Config::from_union(unioned); 546 return Config::from_union(unioned);
541 } 547 }
542 } 548 }
543 549
544 550
545 template<class Config> 551 template<class Config>
546 template<class OtherType> 552 template<class OtherType>
547 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert( 553 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert(
548 typename OtherType::TypeHandle type, Region* region) { 554 typename OtherType::TypeHandle type, Region* region) {
549 if (type->IsBitset()) { 555 if (type->IsBitset()) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 } 644 }
639 645
640 646
641 template<class Config> 647 template<class Config>
642 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) { 648 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
643 if (this->IsBitset()) { 649 if (this->IsBitset()) {
644 int bitset = this->AsBitset(); 650 int bitset = this->AsBitset();
645 switch (dim) { 651 switch (dim) {
646 case BOTH_DIMS: 652 case BOTH_DIMS:
647 BitsetTypePrint(out, bitset & kSemantic); 653 BitsetTypePrint(out, bitset & kSemantic);
648 PrintF("/"); 654 PrintF(out, "/");
649 BitsetTypePrint(out, bitset & kRepresentation); 655 BitsetTypePrint(out, bitset & kRepresentation);
650 break; 656 break;
651 case SEMANTIC_DIM: 657 case SEMANTIC_DIM:
652 BitsetTypePrint(out, bitset & kSemantic); 658 BitsetTypePrint(out, bitset & kSemantic);
653 break; 659 break;
654 case REPRESENTATION_DIM: 660 case REPRESENTATION_DIM:
655 BitsetTypePrint(out, bitset & kRepresentation); 661 BitsetTypePrint(out, bitset & kRepresentation);
656 break; 662 break;
657 } 663 }
658 } else if (this->IsConstant()) { 664 } else if (this->IsConstant()) {
659 PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant())); 665 PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant()));
660 Config::from_bitset(this->LubBitset())->TypePrint(out); 666 Config::from_bitset(this->LubBitset())->TypePrint(out);
661 PrintF(")"); 667 PrintF(out, ")");
662 } else if (this->IsClass()) { 668 } else if (this->IsClass()) {
663 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass())); 669 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()));
664 Config::from_bitset(this->LubBitset())->TypePrint(out); 670 Config::from_bitset(this->LubBitset())->TypePrint(out);
665 PrintF(")"); 671 PrintF(out, ")");
666 } else if (this->IsUnion()) { 672 } else if (this->IsUnion()) {
667 PrintF(out, "("); 673 PrintF(out, "(");
668 UnionedHandle unioned = this->AsUnion(); 674 UnionedHandle unioned = this->AsUnion();
669 for (int i = 0; i < Config::union_length(unioned); ++i) { 675 for (int i = 0; i < Config::union_length(unioned); ++i) {
670 TypeHandle type_i = Config::union_get(unioned, i); 676 TypeHandle type_i = Config::union_get(unioned, i);
671 if (i > 0) PrintF(out, " | "); 677 if (i > 0) PrintF(out, " | ");
672 type_i->TypePrint(out); 678 type_i->TypePrint(out, dim);
673 } 679 }
674 PrintF(out, ")"); 680 PrintF(out, ")");
675 } 681 }
676 } 682 }
677 #endif 683 #endif
678 684
679 685
680 template class TypeImpl<ZoneTypeConfig>; 686 template class TypeImpl<ZoneTypeConfig>;
681 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>; 687 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>;
682 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>; 688 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>;
683 689
684 template class TypeImpl<HeapTypeConfig>; 690 template class TypeImpl<HeapTypeConfig>;
685 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>; 691 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>;
686 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; 692 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
687 693
688 template TypeImpl<ZoneTypeConfig>::TypeHandle 694 template TypeImpl<ZoneTypeConfig>::TypeHandle
689 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( 695 TypeImpl<ZoneTypeConfig>::Convert<HeapType>(
690 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); 696 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*);
691 template TypeImpl<HeapTypeConfig>::TypeHandle 697 template TypeImpl<HeapTypeConfig>::TypeHandle
692 TypeImpl<HeapTypeConfig>::Convert<Type>( 698 TypeImpl<HeapTypeConfig>::Convert<Type>(
693 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); 699 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
694 700
695 701
696 } } // namespace v8::internal 702 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/types.h ('k') | test/mjsunit/regress/regress-crbug-357330.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698