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

Side by Side Diff: src/types.cc

Issue 251753005: Establish distributivity for type union & intersection (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Accurate representation glb & intersection; renaming Created 6 years, 7 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
OLDNEW
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 "types.h" 5 #include "types.h"
6 6
7 #include "string-stream.h" 7 #include "string-stream.h"
8 #include "types-inl.h" 8 #include "types-inl.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 } 110 }
111 111
112 112
113 // Get the largest bitset subsumed by this type. 113 // Get the largest bitset subsumed by this type.
114 template<class Config> 114 template<class Config>
115 int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { 115 int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
116 DisallowHeapAllocation no_allocation; 116 DisallowHeapAllocation no_allocation;
117 if (type->IsBitset()) { 117 if (type->IsBitset()) {
118 return type->AsBitset(); 118 return type->AsBitset();
119 } else if (type->IsUnion()) { 119 } else if (type->IsUnion()) {
120 // All but the first are non-bitsets and thus would yield kNone anyway. 120 UnionHandle unioned = handle(type->AsUnion());
121 return type->AsUnion()->Get(0)->BitsetGlb(); 121 int bitset = kNone;
122 for (int i = 0; i < unioned->Length(); ++i) {
123 bitset |= unioned->Get(i)->BitsetGlb();
124 }
125 return bitset;
126 } else if (type->IsClass()) {
127 // Little hack to avoid the need for a region for handlification here...
128 return REPRESENTATION(Config::is_class(type)
129 ? Lub(*Config::as_class(type))
130 : type->AsClass()->Bound(NULL)->AsBitset());
131 } else if (type->IsConstant()) {
132 return REPRESENTATION(type->AsConstant()->Bound()->AsBitset());
133 } else if (type->IsArray()) {
134 return REPRESENTATION(type->AsArray()->Bound()->AsBitset());
135 } else if (type->IsFunction()) {
136 return REPRESENTATION(type->AsFunction()->Bound()->AsBitset());
122 } else { 137 } else {
138 UNREACHABLE();
123 return kNone; 139 return kNone;
124 } 140 }
125 } 141 }
126 142
127 143
128 // Get the smallest bitset subsuming this type. 144 // Get the smallest bitset subsuming this type.
129 template<class Config> 145 template<class Config>
130 int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { 146 int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
131 DisallowHeapAllocation no_allocation; 147 DisallowHeapAllocation no_allocation;
132 if (type->IsBitset()) { 148 if (type->IsBitset()) {
133 return type->AsBitset(); 149 return type->AsBitset();
134 } else if (type->IsUnion()) { 150 } else if (type->IsUnion()) {
135 UnionHandle unioned = handle(type->AsUnion()); 151 UnionHandle unioned = handle(type->AsUnion());
136 int bitset = kNone; 152 int bitset = kNone;
137 for (int i = 0; i < unioned->Length(); ++i) { 153 for (int i = 0; i < unioned->Length(); ++i) {
138 bitset |= unioned->Get(i)->BitsetLub(); 154 bitset |= unioned->Get(i)->BitsetLub();
139 } 155 }
140 return bitset; 156 return bitset;
141 } else if (type->IsClass()) { 157 } else if (type->IsClass()) {
142 int bitset = Config::lub_bitset(type); 158 // Little hack to avoid the need for a region for handlification here...
143 return bitset ? bitset : Lub(*type->AsClass()->Map()); 159 return Config::is_class(type) ? Lub(*Config::as_class(type)) :
160 type->AsClass()->Bound(NULL)->AsBitset();
144 } else if (type->IsConstant()) { 161 } else if (type->IsConstant()) {
145 int bitset = Config::lub_bitset(type); 162 return type->AsConstant()->Bound()->AsBitset();
146 return bitset ? bitset : Lub(*type->AsConstant()->Value()); 163 } else if (type->IsArray()) {
164 return type->AsArray()->Bound()->AsBitset();
165 } else if (type->IsFunction()) {
166 return type->AsFunction()->Bound()->AsBitset();
167 } else {
168 UNREACHABLE();
169 return kNone;
170 }
171 }
172
173
174 // Get the smallest bitset subsuming this type, ignoring current bounds.
175 template<class Config>
176 int TypeImpl<Config>::BitsetType::InherentLub(TypeImpl* type) {
177 DisallowHeapAllocation no_allocation;
178 if (type->IsBitset()) {
179 return type->AsBitset();
180 } else if (type->IsUnion()) {
181 UnionHandle unioned = handle(type->AsUnion());
182 int bitset = kNone;
183 for (int i = 0; i < unioned->Length(); ++i) {
184 bitset |= unioned->Get(i)->InherentBitsetLub();
185 }
186 return bitset;
187 } else if (type->IsClass()) {
188 return Lub(*type->AsClass()->Map());
189 } else if (type->IsConstant()) {
190 return Lub(*type->AsConstant()->Value());
147 } else if (type->IsArray()) { 191 } else if (type->IsArray()) {
148 return kArray; 192 return kArray;
149 } else if (type->IsFunction()) { 193 } else if (type->IsFunction()) {
150 return kFunction; 194 return kFunction;
151 } else { 195 } else {
152 UNREACHABLE(); 196 UNREACHABLE();
153 return kNone; 197 return kNone;
154 } 198 }
155 } 199 }
156 200
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 // Check this <= that. 321 // Check this <= that.
278 template<class Config> 322 template<class Config>
279 bool TypeImpl<Config>::SlowIs(TypeImpl* that) { 323 bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
280 DisallowHeapAllocation no_allocation; 324 DisallowHeapAllocation no_allocation;
281 325
282 // Fast path for bitsets. 326 // Fast path for bitsets.
283 if (this->IsNone()) return true; 327 if (this->IsNone()) return true;
284 if (that->IsBitset()) { 328 if (that->IsBitset()) {
285 return (BitsetType::Lub(this) | that->AsBitset()) == that->AsBitset(); 329 return (BitsetType::Lub(this) | that->AsBitset()) == that->AsBitset();
286 } 330 }
331 if (this->IsBitset() && SEMANTIC(this->AsBitset()) == BitsetType::kNone) {
332 // Bitsets only have non-bitset supertypes along the representation axis.
333 int that_bitset = that->BitsetGlb();
334 return (this->AsBitset() | that_bitset) == that_bitset;
335 }
287 336
288 if (that->IsClass()) { 337 if (that->IsClass()) {
289 return this->IsClass() 338 return this->IsClass()
290 && *this->AsClass()->Map() == *that->AsClass()->Map(); 339 && *this->AsClass()->Map() == *that->AsClass()->Map()
340 && ((Config::is_class(that) && Config::is_class(this)) ||
341 BitsetType::New(this->BitsetLub())->Is(
342 BitsetType::New(that->BitsetLub())));
291 } 343 }
292 if (that->IsConstant()) { 344 if (that->IsConstant()) {
293 return this->IsConstant() 345 return this->IsConstant()
294 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); 346 && *this->AsConstant()->Value() == *that->AsConstant()->Value()
347 && this->AsConstant()->Bound()->Is(that->AsConstant()->Bound());
295 } 348 }
296 if (that->IsArray()) { 349 if (that->IsArray()) {
297 return this->IsArray() 350 return this->IsArray()
298 && this->AsArray()->Element()->Equals(that->AsArray()->Element()); 351 && this->AsArray()->Element()->Equals(that->AsArray()->Element());
299 } 352 }
300 if (that->IsFunction()) { 353 if (that->IsFunction()) {
301 // We currently do not allow for any variance here, in order to keep 354 // We currently do not allow for any variance here, in order to keep
302 // Union and Intersect operations simple. 355 // Union and Intersect operations simple.
303 if (!this->IsFunction()) return false; 356 if (!this->IsFunction()) return false;
304 FunctionType* this_fun = this->AsFunction(); 357 FunctionType* this_fun = this->AsFunction();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 return this->Equals(that); 470 return this->Equals(that);
418 } 471 }
419 472
420 return false; 473 return false;
421 } 474 }
422 475
423 476
424 template<class Config> 477 template<class Config>
425 bool TypeImpl<Config>::Contains(i::Object* value) { 478 bool TypeImpl<Config>::Contains(i::Object* value) {
426 DisallowHeapAllocation no_allocation; 479 DisallowHeapAllocation no_allocation;
427
428 for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) { 480 for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) {
429 if (*it.Current() == value) return true; 481 if (*it.Current() == value) return true;
430 } 482 }
431 return BitsetType::New(BitsetType::Lub(value))->Is(this); 483 return BitsetType::New(BitsetType::Lub(value))->Is(this);
432 } 484 }
433 485
434 486
435 template<class Config> 487 template<class Config>
436 bool TypeImpl<Config>::InUnion(UnionHandle unioned, int current_size) { 488 bool TypeImpl<Config>::UnionType::Wellformed() {
437 ASSERT(!this->IsUnion()); 489 ASSERT(this->Length() >= 2);
438 for (int i = 0; i < current_size; ++i) { 490 for (int i = 0; i < this->Length(); ++i) {
439 if (this->Is(unioned->Get(i))) return true; 491 ASSERT(!this->Get(i)->IsUnion());
492 if (i > 0) ASSERT(!this->Get(i)->IsBitset());
493 for (int j = 0; j < this->Length(); ++j) {
494 if (i != j) ASSERT(!this->Get(i)->Is(this->Get(j)));
495 }
440 } 496 }
441 return false; 497 return true;
442 } 498 }
443 499
444 500
445 // Get non-bitsets from this which are not subsumed by union, store at result, 501 template<class Config>
446 // starting at index. Returns updated index. 502 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Narrow(
503 int bitset, Region* region) {
504 TypeHandle bound = BitsetType::New(bitset, region);
505 if (this->IsClass()) {
506 return ClassType::New(this->AsClass()->Map(), bound, region);
507 } else if (this->IsConstant()) {
508 return ConstantType::New(this->AsConstant()->Value(), bound, region);
509 } else if (this->IsArray()) {
510 return ArrayType::New(this->AsArray()->Element(), bound, region);
511 } else if (this->IsFunction()) {
512 FunctionType* function = this->AsFunction();
513 int arity = function->Arity();
514 FunctionHandle type = FunctionType::New(
515 function->Result(), function->Receiver(), bound, arity, region);
516 for (int i = 0; i < arity; ++i) {
517 type->InitParameter(i, function->Parameter(i));
518 }
519 return type;
520 }
521 UNREACHABLE();
522 return TypeHandle();
523 }
524
525
526 template<class Config>
527 int TypeImpl<Config>::BoundBy(TypeImpl* that) {
528 ASSERT(!this->IsUnion());
529 if (that->IsUnion()) {
530 UnionType* unioned = that->AsUnion();
531 int length = unioned->Length();
532 int bitset = BitsetType::kNone;
533 for (int i = 0; i < length; ++i) {
534 bitset |= BoundBy(unioned->Get(i)->unhandle());
535 }
536 return bitset;
537 } else if (that->IsClass() && this->IsClass() &&
538 *this->AsClass()->Map() == *that->AsClass()->Map()) {
539 return that->BitsetLub();
540 } else if (that->IsConstant() && this->IsConstant() &&
541 *this->AsConstant()->Value() == *that->AsConstant()->Value()) {
542 return that->AsConstant()->Bound()->AsBitset();
543 } else if (that->IsArray() && this->IsArray() && this->Is(that)) {
544 return that->AsArray()->Bound()->AsBitset();
545 } else if (that->IsFunction() && this->IsFunction() && this->Is(that)) {
546 return that->AsFunction()->Bound()->AsBitset();
547 }
548 return that->BitsetGlb();
549 }
550
551
552 template<class Config>
553 int TypeImpl<Config>::IndexInUnion(
554 int bound, UnionHandle unioned, int current_size) {
555 ASSERT(!this->IsUnion());
556 for (int i = 0; i < current_size; ++i) {
557 TypeHandle that = unioned->Get(i);
558 if (that->IsBitset()) {
559 if ((bound | that->AsBitset()) == that->AsBitset()) return i;
560 } else if (that->IsClass() && this->IsClass()) {
561 if (*this->AsClass()->Map() == *that->AsClass()->Map()) return i;
562 } else if (that->IsConstant() && this->IsConstant()) {
563 if (*this->AsConstant()->Value() == *that->AsConstant()->Value())
564 return i;
565 } else if (that->IsArray() && this->IsArray()) {
566 if (this->Is(that)) return i;
567 } else if (that->IsFunction() && this->IsFunction()) {
568 if (this->Is(that)) return i;
569 }
570 }
571 return -1;
572 }
573
574
575 // Get non-bitsets from type, bounded by upper.
576 // Store at result starting at index. Returns updated index.
447 template<class Config> 577 template<class Config>
448 int TypeImpl<Config>::ExtendUnion( 578 int TypeImpl<Config>::ExtendUnion(
449 UnionHandle result, TypeHandle type, int current_size) { 579 UnionHandle result, int size, TypeHandle type,
450 int old_size = current_size; 580 TypeHandle other, bool is_intersect, Region* region) {
581 int old_size = size;
451 if (type->IsUnion()) { 582 if (type->IsUnion()) {
452 UnionHandle unioned = handle(type->AsUnion()); 583 UnionHandle unioned = handle(type->AsUnion());
453 for (int i = 0; i < unioned->Length(); ++i) { 584 for (int i = 0; i < unioned->Length(); ++i) {
454 TypeHandle type = unioned->Get(i); 585 TypeHandle type_i = unioned->Get(i);
455 ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0)))); 586 ASSERT(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0))));
456 if (!type->IsBitset() && !type->InUnion(result, old_size)) { 587 if (!type_i->IsBitset()) {
457 result->Set(current_size++, type); 588 size = ExtendUnion(result, size, type_i, other, is_intersect, region);
458 } 589 }
459 } 590 }
460 } else if (!type->IsBitset()) { 591 } else if (!type->IsBitset()) {
461 // For all structural types, subtyping implies equivalence.
462 ASSERT(type->IsClass() || type->IsConstant() || 592 ASSERT(type->IsClass() || type->IsConstant() ||
463 type->IsArray() || type->IsFunction()); 593 type->IsArray() || type->IsFunction());
464 if (!type->InUnion(result, old_size)) { 594 int inherent_bound = type->InherentBitsetLub();
465 result->Set(current_size++, type); 595 int old_bound = type->BitsetLub();
596 int other_bound = type->BoundBy(other->unhandle()) & inherent_bound;
597 int new_bound =
598 is_intersect ? (old_bound & other_bound) : (old_bound | other_bound);
599 if (new_bound != BitsetType::kNone) {
600 int i = type->IndexInUnion(new_bound, result, old_size);
601 if (i == -1) {
602 i = size++;
603 } else if (result->Get(i)->IsBitset()) {
604 return size; // Already fully subsumed.
605 } else {
606 int type_i_bound = result->Get(i)->BitsetLub();
607 new_bound |= type_i_bound;
608 if (new_bound == type_i_bound) return size;
609 }
610 if (new_bound != old_bound) type = type->Narrow(new_bound, region);
611 result->Set(i, type);
466 } 612 }
467 } 613 }
468 return current_size; 614 return size;
469 } 615 }
470 616
471 617
472 // Union is O(1) on simple bit unions, but O(n*m) on structured unions. 618 // If bitset is subsumed by another entry in the result, remove it.
619 // (Only bitsets with empty semantic axis can be subtypes of non-bitsets.)
620 template<class Config>
621 int TypeImpl<Config>::NormalizeUnion(UnionHandle result, int size, int bitset) {
622 if (bitset != BitsetType::kNone && SEMANTIC(bitset) == BitsetType::kNone) {
623 for (int i = 1; i < size; ++i) {
624 int glb = result->Get(i)->BitsetGlb();
625 if ((bitset | glb) == glb) {
626 for (int j = 1; j < size; ++j) {
627 result->Set(j - 1, result->Get(j));
628 }
629 --size;
630 break;
631 }
632 }
633 }
634 return size;
635 }
636
637
638 // Union is O(1) on simple bitsets, but O(n*m) on structured unions.
473 template<class Config> 639 template<class Config>
474 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( 640 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
475 TypeHandle type1, TypeHandle type2, Region* region) { 641 TypeHandle type1, TypeHandle type2, Region* region) {
476 // Fast case: bit sets. 642 // Fast case: bit sets.
477 if (type1->IsBitset() && type2->IsBitset()) { 643 if (type1->IsBitset() && type2->IsBitset()) {
478 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region); 644 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region);
479 } 645 }
480 646
481 // Fast case: top or bottom types. 647 // Fast case: top or bottom types.
482 if (type1->IsAny() || type2->IsNone()) return type1; 648 if (type1->IsAny() || type2->IsNone()) return type1;
(...skipping 15 matching lines...) Expand all
498 } 664 }
499 int bitset = type1->BitsetGlb() | type2->BitsetGlb(); 665 int bitset = type1->BitsetGlb() | type2->BitsetGlb();
500 if (bitset != BitsetType::kNone) ++size; 666 if (bitset != BitsetType::kNone) ++size;
501 ASSERT(size >= 1); 667 ASSERT(size >= 1);
502 668
503 UnionHandle unioned = UnionType::New(size, region); 669 UnionHandle unioned = UnionType::New(size, region);
504 size = 0; 670 size = 0;
505 if (bitset != BitsetType::kNone) { 671 if (bitset != BitsetType::kNone) {
506 unioned->Set(size++, BitsetType::New(bitset, region)); 672 unioned->Set(size++, BitsetType::New(bitset, region));
507 } 673 }
508 size = ExtendUnion(unioned, type1, size); 674 size = ExtendUnion(unioned, size, type1, type2, false, region);
509 size = ExtendUnion(unioned, type2, size); 675 size = ExtendUnion(unioned, size, type2, type1, false, region);
676 size = NormalizeUnion(unioned, size, bitset);
510 677
511 if (size == 1) { 678 if (size == 1) {
512 return unioned->Get(0); 679 return unioned->Get(0);
513 } else { 680 } else {
514 unioned->Shrink(size); 681 unioned->Shrink(size);
682 ASSERT(unioned->Wellformed());
515 return unioned; 683 return unioned;
516 } 684 }
517 } 685 }
518 686
519 687
520 // Get non-bitsets from type which are also in other, store at result, 688 // Intersection is O(1) on simple bitsets, but O(n*m) on structured unions.
521 // starting at index. Returns updated index.
522 template<class Config>
523 int TypeImpl<Config>::ExtendIntersection(
524 UnionHandle result, TypeHandle type, TypeHandle other, int current_size) {
525 int old_size = current_size;
526 if (type->IsUnion()) {
527 UnionHandle unioned = handle(type->AsUnion());
528 for (int i = 0; i < unioned->Length(); ++i) {
529 TypeHandle type = unioned->Get(i);
530 ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0))));
531 if (!type->IsBitset() && type->Is(other) &&
532 !type->InUnion(result, old_size)) {
533 result->Set(current_size++, type);
534 }
535 }
536 } else if (!type->IsBitset()) {
537 // For all structural types, subtyping implies equivalence.
538 ASSERT(type->IsClass() || type->IsConstant() ||
539 type->IsArray() || type->IsFunction());
540 if (type->Is(other) && !type->InUnion(result, old_size)) {
541 result->Set(current_size++, type);
542 }
543 }
544 return current_size;
545 }
546
547
548 // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions.
549 template<class Config> 689 template<class Config>
550 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect( 690 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
551 TypeHandle type1, TypeHandle type2, Region* region) { 691 TypeHandle type1, TypeHandle type2, Region* region) {
552 // Fast case: bit sets. 692 // Fast case: bit sets.
553 if (type1->IsBitset() && type2->IsBitset()) { 693 if (type1->IsBitset() && type2->IsBitset()) {
554 return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region); 694 return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region);
555 } 695 }
556 696
557 // Fast case: top or bottom types. 697 // Fast case: top or bottom types.
558 if (type1->IsNone() || type2->IsAny()) return type1; 698 if (type1->IsNone() || type2->IsAny()) return type1;
(...skipping 15 matching lines...) Expand all
574 } 714 }
575 int bitset = type1->BitsetGlb() & type2->BitsetGlb(); 715 int bitset = type1->BitsetGlb() & type2->BitsetGlb();
576 if (bitset != BitsetType::kNone) ++size; 716 if (bitset != BitsetType::kNone) ++size;
577 ASSERT(size >= 1); 717 ASSERT(size >= 1);
578 718
579 UnionHandle unioned = UnionType::New(size, region); 719 UnionHandle unioned = UnionType::New(size, region);
580 size = 0; 720 size = 0;
581 if (bitset != BitsetType::kNone) { 721 if (bitset != BitsetType::kNone) {
582 unioned->Set(size++, BitsetType::New(bitset, region)); 722 unioned->Set(size++, BitsetType::New(bitset, region));
583 } 723 }
584 size = ExtendIntersection(unioned, type1, type2, size); 724 size = ExtendUnion(unioned, size, type1, type2, true, region);
585 size = ExtendIntersection(unioned, type2, type1, size); 725 size = ExtendUnion(unioned, size, type2, type1, true, region);
726 size = NormalizeUnion(unioned, size, bitset);
586 727
587 if (size == 0) { 728 if (size == 0) {
588 return None(region); 729 return None(region);
589 } else if (size == 1) { 730 } else if (size == 1) {
590 return unioned->Get(0); 731 return unioned->Get(0);
591 } else { 732 } else {
592 unioned->Shrink(size); 733 unioned->Shrink(size);
734 ASSERT(unioned->Wellformed());
593 return unioned; 735 return unioned;
594 } 736 }
595 } 737 }
596 738
597 739
598 template<class Config> 740 template<class Config>
599 template<class OtherType> 741 template<class OtherType>
600 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert( 742 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert(
601 typename OtherType::TypeHandle type, Region* region) { 743 typename OtherType::TypeHandle type, Region* region) {
602 if (type->IsBitset()) { 744 if (type->IsBitset()) {
603 return BitsetType::New(type->AsBitset(), region); 745 return BitsetType::New(type->AsBitset(), region);
604 } else if (type->IsClass()) { 746 } else if (type->IsClass()) {
605 return ClassType::New(type->AsClass()->Map(), region); 747 return ClassType::New(
748 type->AsClass()->Map(),
749 BitsetType::New(type->BitsetLub(), region), region);
606 } else if (type->IsConstant()) { 750 } else if (type->IsConstant()) {
607 return ConstantType::New(type->AsConstant()->Value(), region); 751 return ConstantType::New(
752 type->AsConstant()->Value(),
753 Convert<OtherType>(type->AsConstant()->Bound(), region), region);
608 } else if (type->IsUnion()) { 754 } else if (type->IsUnion()) {
609 int length = type->AsUnion()->Length(); 755 int length = type->AsUnion()->Length();
610 UnionHandle unioned = UnionType::New(length, region); 756 UnionHandle unioned = UnionType::New(length, region);
611 for (int i = 0; i < length; ++i) { 757 for (int i = 0; i < length; ++i) {
612 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region)); 758 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region));
613 } 759 }
614 return unioned; 760 return unioned;
615 } else if (type->IsArray()) { 761 } else if (type->IsArray()) {
616 return ArrayType::New( 762 return ArrayType::New(
617 Convert<OtherType>(type->AsArray()->Element(), region), region); 763 Convert<OtherType>(type->AsArray()->Element(), region),
764 Convert<OtherType>(type->AsArray()->Bound(), region), region);
618 } else if (type->IsFunction()) { 765 } else if (type->IsFunction()) {
619 FunctionHandle function = FunctionType::New( 766 FunctionHandle function = FunctionType::New(
620 Convert<OtherType>(type->AsFunction()->Result(), region), 767 Convert<OtherType>(type->AsFunction()->Result(), region),
621 Convert<OtherType>(type->AsFunction()->Receiver(), region), 768 Convert<OtherType>(type->AsFunction()->Receiver(), region),
769 Convert<OtherType>(type->AsFunction()->Bound(), region),
622 type->AsFunction()->Arity(), region); 770 type->AsFunction()->Arity(), region);
623 for (int i = 0; i < function->Arity(); ++i) { 771 for (int i = 0; i < function->Arity(); ++i) {
624 function->InitParameter(i, 772 function->InitParameter(i,
625 Convert<OtherType>(type->AsFunction()->Parameter(i), region)); 773 Convert<OtherType>(type->AsFunction()->Parameter(i), region));
626 } 774 }
627 return function; 775 return function;
628 } else { 776 } else {
629 UNREACHABLE(); 777 UNREACHABLE();
630 return None(region); 778 return None(region);
631 } 779 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 } 849 }
702 ASSERT(bitset == 0); 850 ASSERT(bitset == 0);
703 PrintF(out, ")"); 851 PrintF(out, ")");
704 } 852 }
705 } 853 }
706 854
707 855
708 template<class Config> 856 template<class Config>
709 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) { 857 void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
710 DisallowHeapAllocation no_allocation; 858 DisallowHeapAllocation no_allocation;
711 if (this->IsBitset()) { 859 if (dim != REPRESENTATION_DIM) {
712 int bitset = this->AsBitset(); 860 if (this->IsBitset()) {
713 switch (dim) { 861 BitsetType::BitsetTypePrint(out, SEMANTIC(this->AsBitset()));
714 case BOTH_DIMS: 862 } else if (this->IsConstant()) {
715 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic); 863 PrintF(out, "Constant(%p : ",
716 PrintF(out, "/"); 864 static_cast<void*>(*this->AsConstant()->Value()));
717 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation); 865 BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim);
718 break; 866 PrintF(out, ")");
719 case SEMANTIC_DIM: 867 return;
720 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic); 868 } else if (this->IsClass()) {
721 break; 869 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()->Map()));
722 case REPRESENTATION_DIM: 870 BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim);
723 BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation); 871 PrintF(out, ")");
724 break; 872 return;
873 } else if (this->IsUnion()) {
874 PrintF(out, "(");
875 UnionHandle unioned = handle(this->AsUnion());
876 for (int i = 0; i < unioned->Length(); ++i) {
877 TypeHandle type_i = unioned->Get(i);
878 if (i > 0) PrintF(out, " | ");
879 type_i->TypePrint(out, dim);
880 }
881 PrintF(out, ")");
882 return;
883 } else if (this->IsArray()) {
884 PrintF(out, "Array(");
885 AsArray()->Element()->TypePrint(out, dim);
886 PrintF(out, ")");
887 } else if (this->IsFunction()) {
888 if (!this->AsFunction()->Receiver()->IsAny()) {
889 this->AsFunction()->Receiver()->TypePrint(out, dim);
890 PrintF(out, ".");
891 }
892 PrintF(out, "(");
893 for (int i = 0; i < this->AsFunction()->Arity(); ++i) {
894 if (i > 0) PrintF(out, ", ");
895 this->AsFunction()->Parameter(i)->TypePrint(out, dim);
896 }
897 PrintF(out, ")->");
898 this->AsFunction()->Result()->TypePrint(out, dim);
899 } else {
900 UNREACHABLE();
725 } 901 }
726 } else if (this->IsConstant()) { 902 }
727 PrintF(out, "Constant(%p : ", 903 if (dim == BOTH_DIMS) {
728 static_cast<void*>(*this->AsConstant()->Value())); 904 PrintF(out, "/");
729 BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim); 905 }
730 PrintF(out, ")"); 906 if (dim != SEMANTIC_DIM) {
731 } else if (this->IsClass()) { 907 BitsetType::BitsetTypePrint(out, REPRESENTATION(this->BitsetLub()));
732 PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()->Map()));
733 BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim);
734 PrintF(out, ")");
735 } else if (this->IsUnion()) {
736 PrintF(out, "(");
737 UnionHandle unioned = handle(this->AsUnion());
738 for (int i = 0; i < unioned->Length(); ++i) {
739 TypeHandle type_i = unioned->Get(i);
740 if (i > 0) PrintF(out, " | ");
741 type_i->TypePrint(out, dim);
742 }
743 PrintF(out, ")");
744 } else if (this->IsArray()) {
745 PrintF(out, "[");
746 AsArray()->Element()->TypePrint(out, dim);
747 PrintF(out, "]");
748 } else if (this->IsFunction()) {
749 if (!this->AsFunction()->Receiver()->IsAny()) {
750 this->AsFunction()->Receiver()->TypePrint(out, dim);
751 PrintF(out, ".");
752 }
753 PrintF(out, "(");
754 for (int i = 0; i < this->AsFunction()->Arity(); ++i) {
755 if (i > 0) PrintF(out, ", ");
756 this->AsFunction()->Parameter(i)->TypePrint(out, dim);
757 }
758 PrintF(out, ")->");
759 this->AsFunction()->Result()->TypePrint(out, dim);
760 } else {
761 UNREACHABLE();
762 } 908 }
763 } 909 }
764 910
765 911
766 template class TypeImpl<ZoneTypeConfig>; 912 template class TypeImpl<ZoneTypeConfig>;
767 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>; 913 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>;
768 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>; 914 template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>;
769 915
770 template class TypeImpl<HeapTypeConfig>; 916 template class TypeImpl<HeapTypeConfig>;
771 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>; 917 template class TypeImpl<HeapTypeConfig>::Iterator<i::Map>;
772 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; 918 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
773 919
774 template TypeImpl<ZoneTypeConfig>::TypeHandle 920 template TypeImpl<ZoneTypeConfig>::TypeHandle
775 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( 921 TypeImpl<ZoneTypeConfig>::Convert<HeapType>(
776 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); 922 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*);
777 template TypeImpl<HeapTypeConfig>::TypeHandle 923 template TypeImpl<HeapTypeConfig>::TypeHandle
778 TypeImpl<HeapTypeConfig>::Convert<Type>( 924 TypeImpl<HeapTypeConfig>::Convert<Type>(
779 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); 925 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
780 926
781 } } // namespace v8::internal 927 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/types.h ('k') | src/types-inl.h » ('j') | test/cctest/test-types.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698