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 { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 for (int i = 0; i < unioned->Length(); ++i) { | 58 for (int i = 0; i < unioned->Length(); ++i) { |
59 bitset |= unioned->Get(i)->BitsetLub(); | 59 bitset |= unioned->Get(i)->BitsetLub(); |
60 } | 60 } |
61 return bitset; | 61 return bitset; |
62 } else if (type->IsClass()) { | 62 } else if (type->IsClass()) { |
63 // Little hack to avoid the need for a region for handlification here... | 63 // Little hack to avoid the need for a region for handlification here... |
64 return Config::is_class(type) ? Lub(*Config::as_class(type)) : | 64 return Config::is_class(type) ? Lub(*Config::as_class(type)) : |
65 type->AsClass()->Bound(NULL)->AsBitset(); | 65 type->AsClass()->Bound(NULL)->AsBitset(); |
66 } else if (type->IsConstant()) { | 66 } else if (type->IsConstant()) { |
67 return type->AsConstant()->Bound()->AsBitset(); | 67 return type->AsConstant()->Bound()->AsBitset(); |
68 } else if (type->IsRange()) { | |
69 return type->AsRange()->Bound()->AsBitset(); | |
68 } else if (type->IsContext()) { | 70 } else if (type->IsContext()) { |
69 return type->AsContext()->Bound()->AsBitset(); | 71 return type->AsContext()->Bound()->AsBitset(); |
70 } else if (type->IsArray()) { | 72 } else if (type->IsArray()) { |
71 return type->AsArray()->Bound()->AsBitset(); | 73 return type->AsArray()->Bound()->AsBitset(); |
72 } else if (type->IsFunction()) { | 74 } else if (type->IsFunction()) { |
73 return type->AsFunction()->Bound()->AsBitset(); | 75 return type->AsFunction()->Bound()->AsBitset(); |
74 } else { | 76 } else { |
75 UNREACHABLE(); | 77 UNREACHABLE(); |
76 return kNone; | 78 return kNone; |
77 } | 79 } |
(...skipping 10 matching lines...) Expand all Loading... | |
88 UnionHandle unioned = handle(type->AsUnion()); | 90 UnionHandle unioned = handle(type->AsUnion()); |
89 int bitset = kNone; | 91 int bitset = kNone; |
90 for (int i = 0; i < unioned->Length(); ++i) { | 92 for (int i = 0; i < unioned->Length(); ++i) { |
91 bitset |= unioned->Get(i)->InherentBitsetLub(); | 93 bitset |= unioned->Get(i)->InherentBitsetLub(); |
92 } | 94 } |
93 return bitset; | 95 return bitset; |
94 } else if (type->IsClass()) { | 96 } else if (type->IsClass()) { |
95 return Lub(*type->AsClass()->Map()); | 97 return Lub(*type->AsClass()->Map()); |
96 } else if (type->IsConstant()) { | 98 } else if (type->IsConstant()) { |
97 return Lub(*type->AsConstant()->Value()); | 99 return Lub(*type->AsConstant()->Value()); |
100 } else if (type->IsRange()) { | |
101 return RangeType::InherentLub( | |
102 type->AsRange()->Min(), type->AsRange()->Max()); | |
98 } else if (type->IsContext()) { | 103 } else if (type->IsContext()) { |
99 return kInternal & kTaggedPtr; | 104 return kInternal & kTaggedPtr; |
100 } else if (type->IsArray()) { | 105 } else if (type->IsArray()) { |
101 return kArray; | 106 return kArray; |
102 } else if (type->IsFunction()) { | 107 } else if (type->IsFunction()) { |
103 return kFunction; | 108 return kFunction; |
104 } else { | 109 } else { |
105 UNREACHABLE(); | 110 UNREACHABLE(); |
106 return kNone; | 111 return kNone; |
107 } | 112 } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
267 | 272 |
268 if (that->IsClass()) { | 273 if (that->IsClass()) { |
269 return this->IsClass() | 274 return this->IsClass() |
270 && *this->AsClass()->Map() == *that->AsClass()->Map() | 275 && *this->AsClass()->Map() == *that->AsClass()->Map() |
271 && ((Config::is_class(that) && Config::is_class(this)) || | 276 && ((Config::is_class(that) && Config::is_class(this)) || |
272 BitsetType::New(this->BitsetLub())->Is( | 277 BitsetType::New(this->BitsetLub())->Is( |
273 BitsetType::New(that->BitsetLub()))); | 278 BitsetType::New(that->BitsetLub()))); |
274 } | 279 } |
275 if (that->IsConstant()) { | 280 if (that->IsConstant()) { |
276 return this->IsConstant() | 281 return this->IsConstant() |
277 && *this->AsConstant()->Value() == *that->AsConstant()->Value() | 282 && this->AsConstant()->Bound()->Is(that->AsConstant()->Bound()) |
278 && this->AsConstant()->Bound()->Is(that->AsConstant()->Bound()); | 283 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); |
rossberg
2014/08/05 14:49:15
Check value first, since that is faster.
neis
2014/08/06 13:15:01
Done.
| |
284 } | |
285 if (that->IsRange()) { | |
286 return this->IsRange() | |
287 && this->AsRange()->Bound()->Is(that->AsRange()->Bound()) | |
288 && RangeType::le(that->AsRange()->Min(), this->AsRange()->Min()) | |
289 && RangeType::le(this->AsRange()->Max(), that->AsRange()->Max()); | |
279 } | 290 } |
280 if (that->IsContext()) { | 291 if (that->IsContext()) { |
281 return this->IsContext() | 292 return this->IsContext() |
282 && this->AsContext()->Outer()->Equals(that->AsContext()->Outer()); | 293 && this->AsContext()->Outer()->Equals(that->AsContext()->Outer()); |
283 } | 294 } |
284 if (that->IsArray()) { | 295 if (that->IsArray()) { |
285 return this->IsArray() | 296 return this->IsArray() |
286 && this->AsArray()->Element()->Equals(that->AsArray()->Element()); | 297 && this->AsArray()->Element()->Equals(that->AsArray()->Element()); |
287 } | 298 } |
288 if (that->IsFunction()) { | 299 if (that->IsFunction()) { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 } | 413 } |
403 | 414 |
404 return false; | 415 return false; |
405 } | 416 } |
406 | 417 |
407 | 418 |
408 // Check if value is contained in (inhabits) type. | 419 // Check if value is contained in (inhabits) type. |
409 template<class Config> | 420 template<class Config> |
410 bool TypeImpl<Config>::Contains(i::Object* value) { | 421 bool TypeImpl<Config>::Contains(i::Object* value) { |
411 DisallowHeapAllocation no_allocation; | 422 DisallowHeapAllocation no_allocation; |
423 if (this->IsRange()) { | |
424 return value->IsNumber() && | |
425 RangeType::le(this->AsRange()->Min(), value->Number()) && | |
426 RangeType::le(value->Number(), this->AsRange()->Max()) && | |
427 BitsetType::Is(BitsetType::Lub(value), this->BitsetLub()); | |
428 } | |
412 for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) { | 429 for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) { |
413 if (*it.Current() == value) return true; | 430 if (*it.Current() == value) return true; |
414 } | 431 } |
415 return BitsetType::New(BitsetType::Lub(value))->Is(this); | 432 return BitsetType::New(BitsetType::Lub(value))->Is(this); |
416 } | 433 } |
417 | 434 |
418 | 435 |
419 template<class Config> | 436 template<class Config> |
420 bool TypeImpl<Config>::UnionType::Wellformed() { | 437 bool TypeImpl<Config>::UnionType::Wellformed() { |
421 DCHECK(this->Length() >= 2); | 438 DCHECK(this->Length() >= 2); |
(...skipping 12 matching lines...) Expand all Loading... | |
434 // Union and intersection | 451 // Union and intersection |
435 | 452 |
436 template<class Config> | 453 template<class Config> |
437 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound( | 454 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound( |
438 int bitset, Region* region) { | 455 int bitset, Region* region) { |
439 TypeHandle bound = BitsetType::New(bitset, region); | 456 TypeHandle bound = BitsetType::New(bitset, region); |
440 if (this->IsClass()) { | 457 if (this->IsClass()) { |
441 return ClassType::New(this->AsClass()->Map(), bound, region); | 458 return ClassType::New(this->AsClass()->Map(), bound, region); |
442 } else if (this->IsConstant()) { | 459 } else if (this->IsConstant()) { |
443 return ConstantType::New(this->AsConstant()->Value(), bound, region); | 460 return ConstantType::New(this->AsConstant()->Value(), bound, region); |
461 } else if (this->IsRange()) { | |
462 return RangeType::New( | |
463 this->AsRange()->Min(), this->AsRange()->Max(), bound, region); | |
444 } else if (this->IsContext()) { | 464 } else if (this->IsContext()) { |
445 return ContextType::New(this->AsContext()->Outer(), bound, region); | 465 return ContextType::New(this->AsContext()->Outer(), bound, region); |
446 } else if (this->IsArray()) { | 466 } else if (this->IsArray()) { |
447 return ArrayType::New(this->AsArray()->Element(), bound, region); | 467 return ArrayType::New(this->AsArray()->Element(), bound, region); |
448 } else if (this->IsFunction()) { | 468 } else if (this->IsFunction()) { |
449 FunctionType* function = this->AsFunction(); | 469 FunctionType* function = this->AsFunction(); |
450 int arity = function->Arity(); | 470 int arity = function->Arity(); |
451 FunctionHandle type = FunctionType::New( | 471 FunctionHandle type = FunctionType::New( |
452 function->Result(), function->Receiver(), bound, arity, region); | 472 function->Result(), function->Receiver(), bound, arity, region); |
453 for (int i = 0; i < arity; ++i) { | 473 for (int i = 0; i < arity; ++i) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
522 if (type->IsUnion()) { | 542 if (type->IsUnion()) { |
523 UnionHandle unioned = handle(type->AsUnion()); | 543 UnionHandle unioned = handle(type->AsUnion()); |
524 for (int i = 0; i < unioned->Length(); ++i) { | 544 for (int i = 0; i < unioned->Length(); ++i) { |
525 TypeHandle type_i = unioned->Get(i); | 545 TypeHandle type_i = unioned->Get(i); |
526 DCHECK(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0)))); | 546 DCHECK(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0)))); |
527 if (!type_i->IsBitset()) { | 547 if (!type_i->IsBitset()) { |
528 size = ExtendUnion(result, size, type_i, other, is_intersect, region); | 548 size = ExtendUnion(result, size, type_i, other, is_intersect, region); |
529 } | 549 } |
530 } | 550 } |
531 } else if (!type->IsBitset()) { | 551 } else if (!type->IsBitset()) { |
532 DCHECK(type->IsClass() || type->IsConstant() || | 552 DCHECK(type->IsClass() || type->IsConstant() || type->IsRange() || |
533 type->IsArray() || type->IsFunction() || type->IsContext()); | 553 type->IsContext() || type->IsArray() || type->IsFunction()); |
534 int inherent_bound = type->InherentBitsetLub(); | 554 int inherent_bound = type->InherentBitsetLub(); |
535 int old_bound = type->BitsetLub(); | 555 int old_bound = type->BitsetLub(); |
536 int other_bound = type->BoundBy(other->unhandle()) & inherent_bound; | 556 int other_bound = type->BoundBy(other->unhandle()) & inherent_bound; |
537 int new_bound = | 557 int new_bound = |
538 is_intersect ? (old_bound & other_bound) : (old_bound | other_bound); | 558 is_intersect ? (old_bound & other_bound) : (old_bound | other_bound); |
539 if (new_bound != BitsetType::kNone) { | 559 if (new_bound != BitsetType::kNone) { |
540 int i = type->IndexInUnion(new_bound, result, size); | 560 int i = type->IndexInUnion(new_bound, result, size); |
541 if (i == -1) { | 561 if (i == -1) { |
542 i = size++; | 562 i = size++; |
543 } else if (result->Get(i)->IsBitset()) { | 563 } else if (result->Get(i)->IsBitset()) { |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
790 if (type->IsBitset()) { | 810 if (type->IsBitset()) { |
791 return BitsetType::New(type->AsBitset(), region); | 811 return BitsetType::New(type->AsBitset(), region); |
792 } else if (type->IsClass()) { | 812 } else if (type->IsClass()) { |
793 return ClassType::New( | 813 return ClassType::New( |
794 type->AsClass()->Map(), | 814 type->AsClass()->Map(), |
795 BitsetType::New(type->BitsetLub(), region), region); | 815 BitsetType::New(type->BitsetLub(), region), region); |
796 } else if (type->IsConstant()) { | 816 } else if (type->IsConstant()) { |
797 return ConstantType::New( | 817 return ConstantType::New( |
798 type->AsConstant()->Value(), | 818 type->AsConstant()->Value(), |
799 Convert<OtherType>(type->AsConstant()->Bound(), region), region); | 819 Convert<OtherType>(type->AsConstant()->Bound(), region), region); |
820 } else if (type->IsRange()) { | |
821 return RangeType::New( | |
822 type->AsRange()->Min(), type->AsRange()->Max(), | |
823 Convert<OtherType>(type->AsRange()->Bound(), region), region); | |
800 } else if (type->IsContext()) { | 824 } else if (type->IsContext()) { |
801 TypeHandle outer = Convert<OtherType>(type->AsContext()->Outer(), region); | 825 TypeHandle outer = Convert<OtherType>(type->AsContext()->Outer(), region); |
802 return ContextType::New(outer, region); | 826 return ContextType::New(outer, region); |
803 } else if (type->IsUnion()) { | 827 } else if (type->IsUnion()) { |
804 int length = type->AsUnion()->Length(); | 828 int length = type->AsUnion()->Length(); |
805 UnionHandle unioned = UnionType::New(length, region); | 829 UnionHandle unioned = UnionType::New(length, region); |
806 for (int i = 0; i < length; ++i) { | 830 for (int i = 0; i < length; ++i) { |
807 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region)); | 831 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region)); |
808 } | 832 } |
809 return unioned; | 833 return unioned; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
960 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; | 984 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; |
961 | 985 |
962 template TypeImpl<ZoneTypeConfig>::TypeHandle | 986 template TypeImpl<ZoneTypeConfig>::TypeHandle |
963 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 987 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
964 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 988 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
965 template TypeImpl<HeapTypeConfig>::TypeHandle | 989 template TypeImpl<HeapTypeConfig>::TypeHandle |
966 TypeImpl<HeapTypeConfig>::Convert<Type>( | 990 TypeImpl<HeapTypeConfig>::Convert<Type>( |
967 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 991 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
968 | 992 |
969 } } // namespace v8::internal | 993 } } // namespace v8::internal |
OLD | NEW |