| 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 12 matching lines...) Expand all Loading... |
| 23 static bool deq(double x, double y) { | 23 static bool deq(double x, double y) { |
| 24 return dle(x, y) && dle(y, x); | 24 return dle(x, y) && dle(y, x); |
| 25 } | 25 } |
| 26 | 26 |
| 27 | 27 |
| 28 // ----------------------------------------------------------------------------- | 28 // ----------------------------------------------------------------------------- |
| 29 // Glb and lub computation. | 29 // Glb and lub computation. |
| 30 | 30 |
| 31 // The largest bitset subsumed by this type. | 31 // The largest bitset subsumed by this type. |
| 32 template<class Config> | 32 template<class Config> |
| 33 typename TypeImpl<Config>::bitset | 33 int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { |
| 34 TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { | |
| 35 DisallowHeapAllocation no_allocation; | 34 DisallowHeapAllocation no_allocation; |
| 36 if (type->IsBitset()) { | 35 if (type->IsBitset()) { |
| 37 return type->AsBitset(); | 36 return type->AsBitset(); |
| 38 } else if (type->IsUnion()) { | 37 } else if (type->IsUnion()) { |
| 39 UnionHandle unioned = handle(type->AsUnion()); | 38 UnionHandle unioned = handle(type->AsUnion()); |
| 40 DCHECK(unioned->Wellformed()); | 39 DCHECK(unioned->Wellformed()); |
| 41 return unioned->Get(0)->BitsetGlb(); // Other BitsetGlb's are kNone anyway. | 40 return unioned->Get(0)->BitsetGlb(); // Other BitsetGlb's are kNone anyway. |
| 42 } else { | 41 } else { |
| 43 return kNone; | 42 return kNone; |
| 44 } | 43 } |
| 45 } | 44 } |
| 46 | 45 |
| 47 | 46 |
| 48 // The smallest bitset subsuming this type. | 47 // The smallest bitset subsuming this type. |
| 49 template<class Config> | 48 template<class Config> |
| 50 typename TypeImpl<Config>::bitset | 49 int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { |
| 51 TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { | |
| 52 DisallowHeapAllocation no_allocation; | 50 DisallowHeapAllocation no_allocation; |
| 53 if (type->IsBitset()) { | 51 if (type->IsBitset()) { |
| 54 return type->AsBitset(); | 52 return type->AsBitset(); |
| 55 } else if (type->IsUnion()) { | 53 } else if (type->IsUnion()) { |
| 56 UnionHandle unioned = handle(type->AsUnion()); | 54 UnionHandle unioned = handle(type->AsUnion()); |
| 57 bitset result = kNone; | 55 int bitset = kNone; |
| 58 for (int i = 0; i < unioned->Length(); ++i) { | 56 for (int i = 0; i < unioned->Length(); ++i) { |
| 59 result |= unioned->Get(i)->BitsetLub(); | 57 bitset |= unioned->Get(i)->BitsetLub(); |
| 60 } | 58 } |
| 61 return result; | 59 return bitset; |
| 62 } else if (type->IsClass()) { | 60 } else if (type->IsClass()) { |
| 63 // Little hack to avoid the need for a region for handlification here... | 61 // Little hack to avoid the need for a region for handlification here... |
| 64 return Config::is_class(type) ? Lub(*Config::as_class(type)) : | 62 return Config::is_class(type) ? Lub(*Config::as_class(type)) : |
| 65 type->AsClass()->Bound(NULL)->AsBitset(); | 63 type->AsClass()->Bound(NULL)->AsBitset(); |
| 66 } else if (type->IsConstant()) { | 64 } else if (type->IsConstant()) { |
| 67 return type->AsConstant()->Bound()->AsBitset(); | 65 return type->AsConstant()->Bound()->AsBitset(); |
| 68 } else if (type->IsRange()) { | 66 } else if (type->IsRange()) { |
| 69 return type->AsRange()->Bound()->AsBitset(); | 67 return type->AsRange()->Bound()->AsBitset(); |
| 70 } else if (type->IsContext()) { | 68 } else if (type->IsContext()) { |
| 71 return type->AsContext()->Bound()->AsBitset(); | 69 return type->AsContext()->Bound()->AsBitset(); |
| 72 } else if (type->IsArray()) { | 70 } else if (type->IsArray()) { |
| 73 return type->AsArray()->Bound()->AsBitset(); | 71 return type->AsArray()->Bound()->AsBitset(); |
| 74 } else if (type->IsFunction()) { | 72 } else if (type->IsFunction()) { |
| 75 return type->AsFunction()->Bound()->AsBitset(); | 73 return type->AsFunction()->Bound()->AsBitset(); |
| 76 } else { | 74 } else { |
| 77 UNREACHABLE(); | 75 UNREACHABLE(); |
| 78 return kNone; | 76 return kNone; |
| 79 } | 77 } |
| 80 } | 78 } |
| 81 | 79 |
| 82 | 80 |
| 83 // The smallest bitset subsuming this type, ignoring explicit bounds. | 81 // The smallest bitset subsuming this type, ignoring explicit bounds. |
| 84 template<class Config> | 82 template<class Config> |
| 85 typename TypeImpl<Config>::bitset | 83 int TypeImpl<Config>::BitsetType::InherentLub(TypeImpl* type) { |
| 86 TypeImpl<Config>::BitsetType::InherentLub(TypeImpl* type) { | |
| 87 DisallowHeapAllocation no_allocation; | 84 DisallowHeapAllocation no_allocation; |
| 88 if (type->IsBitset()) { | 85 if (type->IsBitset()) { |
| 89 return type->AsBitset(); | 86 return type->AsBitset(); |
| 90 } else if (type->IsUnion()) { | 87 } else if (type->IsUnion()) { |
| 91 UnionHandle unioned = handle(type->AsUnion()); | 88 UnionHandle unioned = handle(type->AsUnion()); |
| 92 bitset result = kNone; | 89 int bitset = kNone; |
| 93 for (int i = 0; i < unioned->Length(); ++i) { | 90 for (int i = 0; i < unioned->Length(); ++i) { |
| 94 result |= unioned->Get(i)->InherentBitsetLub(); | 91 bitset |= unioned->Get(i)->InherentBitsetLub(); |
| 95 } | 92 } |
| 96 return result; | 93 return bitset; |
| 97 } else if (type->IsClass()) { | 94 } else if (type->IsClass()) { |
| 98 return Lub(*type->AsClass()->Map()); | 95 return Lub(*type->AsClass()->Map()); |
| 99 } else if (type->IsConstant()) { | 96 } else if (type->IsConstant()) { |
| 100 return Lub(*type->AsConstant()->Value()); | 97 return Lub(*type->AsConstant()->Value()); |
| 101 } else if (type->IsRange()) { | 98 } else if (type->IsRange()) { |
| 102 return Lub(type->AsRange()->Min(), type->AsRange()->Max()); | 99 return Lub(type->AsRange()->Min(), type->AsRange()->Max()); |
| 103 } else if (type->IsContext()) { | 100 } else if (type->IsContext()) { |
| 104 return kInternal & kTaggedPtr; | 101 return kInternal & kTaggedPtr; |
| 105 } else if (type->IsArray()) { | 102 } else if (type->IsArray()) { |
| 106 return kArray; | 103 return kArray; |
| 107 } else if (type->IsFunction()) { | 104 } else if (type->IsFunction()) { |
| 108 return kFunction; | 105 return kFunction; |
| 109 } else { | 106 } else { |
| 110 UNREACHABLE(); | 107 UNREACHABLE(); |
| 111 return kNone; | 108 return kNone; |
| 112 } | 109 } |
| 113 } | 110 } |
| 114 | 111 |
| 115 | 112 |
| 116 template<class Config> | 113 template<class Config> |
| 117 typename TypeImpl<Config>::bitset | 114 int TypeImpl<Config>::BitsetType::Lub(i::Object* value) { |
| 118 TypeImpl<Config>::BitsetType::Lub(i::Object* value) { | |
| 119 DisallowHeapAllocation no_allocation; | 115 DisallowHeapAllocation no_allocation; |
| 120 if (value->IsNumber()) { | 116 if (value->IsNumber()) { |
| 121 return Lub(value->Number()) & (value->IsSmi() ? kTaggedInt : kTaggedPtr); | 117 return Lub(value->Number()) & (value->IsSmi() ? kTaggedInt : kTaggedPtr); |
| 122 } | 118 } |
| 123 return Lub(i::HeapObject::cast(value)->map()); | 119 return Lub(i::HeapObject::cast(value)->map()); |
| 124 } | 120 } |
| 125 | 121 |
| 126 | 122 |
| 127 template<class Config> | 123 template<class Config> |
| 128 typename TypeImpl<Config>::bitset | 124 int TypeImpl<Config>::BitsetType::Lub(double value) { |
| 129 TypeImpl<Config>::BitsetType::Lub(double value) { | |
| 130 DisallowHeapAllocation no_allocation; | 125 DisallowHeapAllocation no_allocation; |
| 131 if (i::IsMinusZero(value)) return kMinusZero; | 126 if (i::IsMinusZero(value)) return kMinusZero; |
| 132 if (std::isnan(value)) return kNaN; | 127 if (std::isnan(value)) return kNaN; |
| 133 if (IsUint32Double(value)) return Lub(FastD2UI(value)); | 128 if (IsUint32Double(value)) return Lub(FastD2UI(value)); |
| 134 if (IsInt32Double(value)) return Lub(FastD2I(value)); | 129 if (IsInt32Double(value)) return Lub(FastD2I(value)); |
| 135 return kOtherNumber; | 130 return kOtherNumber; |
| 136 } | 131 } |
| 137 | 132 |
| 138 | 133 |
| 139 template<class Config> | 134 template<class Config> |
| 140 typename TypeImpl<Config>::bitset | 135 int TypeImpl<Config>::BitsetType::Lub(double min, double max) { |
| 141 TypeImpl<Config>::BitsetType::Lub(double min, double max) { | |
| 142 DisallowHeapAllocation no_allocation; | 136 DisallowHeapAllocation no_allocation; |
| 143 DCHECK(dle(min, max)); | 137 DCHECK(dle(min, max)); |
| 144 if (deq(min, max)) return BitsetType::Lub(min); // Singleton range. | 138 if (deq(min, max)) return BitsetType::Lub(min); // Singleton range. |
| 145 bitset result = BitsetType::kNumber ^ SEMANTIC(BitsetType::kNaN); | 139 int bitset = BitsetType::kNumber ^ SEMANTIC(BitsetType::kNaN); |
| 146 if (dle(0, min) || max < 0) result ^= SEMANTIC(BitsetType::kMinusZero); | 140 if (dle(0, min) || max < 0) bitset ^= SEMANTIC(BitsetType::kMinusZero); |
| 147 return result; | 141 return bitset; |
| 148 // TODO(neis): Could refine this further by doing more checks on min/max. | 142 // TODO(neis): Could refine this further by doing more checks on min/max. |
| 149 } | 143 } |
| 150 | 144 |
| 151 | 145 |
| 152 template<class Config> | 146 template<class Config> |
| 153 typename TypeImpl<Config>::bitset | 147 int TypeImpl<Config>::BitsetType::Lub(int32_t value) { |
| 154 TypeImpl<Config>::BitsetType::Lub(int32_t value) { | |
| 155 if (value >= 0x40000000) { | 148 if (value >= 0x40000000) { |
| 156 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; | 149 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; |
| 157 } | 150 } |
| 158 if (value >= 0) return kUnsignedSmall; | 151 if (value >= 0) return kUnsignedSmall; |
| 159 if (value >= -0x40000000) return kOtherSignedSmall; | 152 if (value >= -0x40000000) return kOtherSignedSmall; |
| 160 return i::SmiValuesAre31Bits() ? kOtherSigned32 : kOtherSignedSmall; | 153 return i::SmiValuesAre31Bits() ? kOtherSigned32 : kOtherSignedSmall; |
| 161 } | 154 } |
| 162 | 155 |
| 163 | 156 |
| 164 template<class Config> | 157 template<class Config> |
| 165 typename TypeImpl<Config>::bitset | 158 int TypeImpl<Config>::BitsetType::Lub(uint32_t value) { |
| 166 TypeImpl<Config>::BitsetType::Lub(uint32_t value) { | |
| 167 DisallowHeapAllocation no_allocation; | 159 DisallowHeapAllocation no_allocation; |
| 168 if (value >= 0x80000000u) return kOtherUnsigned32; | 160 if (value >= 0x80000000u) return kOtherUnsigned32; |
| 169 if (value >= 0x40000000u) { | 161 if (value >= 0x40000000u) { |
| 170 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; | 162 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; |
| 171 } | 163 } |
| 172 return kUnsignedSmall; | 164 return kUnsignedSmall; |
| 173 } | 165 } |
| 174 | 166 |
| 175 | 167 |
| 176 template<class Config> | 168 template<class Config> |
| 177 typename TypeImpl<Config>::bitset | 169 int TypeImpl<Config>::BitsetType::Lub(i::Map* map) { |
| 178 TypeImpl<Config>::BitsetType::Lub(i::Map* map) { | |
| 179 DisallowHeapAllocation no_allocation; | 170 DisallowHeapAllocation no_allocation; |
| 180 switch (map->instance_type()) { | 171 switch (map->instance_type()) { |
| 181 case STRING_TYPE: | 172 case STRING_TYPE: |
| 182 case ONE_BYTE_STRING_TYPE: | 173 case ONE_BYTE_STRING_TYPE: |
| 183 case CONS_STRING_TYPE: | 174 case CONS_STRING_TYPE: |
| 184 case CONS_ONE_BYTE_STRING_TYPE: | 175 case CONS_ONE_BYTE_STRING_TYPE: |
| 185 case SLICED_STRING_TYPE: | 176 case SLICED_STRING_TYPE: |
| 186 case SLICED_ONE_BYTE_STRING_TYPE: | 177 case SLICED_ONE_BYTE_STRING_TYPE: |
| 187 case EXTERNAL_STRING_TYPE: | 178 case EXTERNAL_STRING_TYPE: |
| 188 case EXTERNAL_ONE_BYTE_STRING_TYPE: | 179 case EXTERNAL_ONE_BYTE_STRING_TYPE: |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 } | 450 } |
| 460 return true; | 451 return true; |
| 461 } | 452 } |
| 462 | 453 |
| 463 | 454 |
| 464 // ----------------------------------------------------------------------------- | 455 // ----------------------------------------------------------------------------- |
| 465 // Union and intersection | 456 // Union and intersection |
| 466 | 457 |
| 467 template<class Config> | 458 template<class Config> |
| 468 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound( | 459 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound( |
| 469 bitset bitset_bound, Region* region) { | 460 int bitset, Region* region) { |
| 470 TypeHandle bound = BitsetType::New(bitset_bound, region); | 461 TypeHandle bound = BitsetType::New(bitset, region); |
| 471 if (this->IsClass()) { | 462 if (this->IsClass()) { |
| 472 return ClassType::New(this->AsClass()->Map(), bound, region); | 463 return ClassType::New(this->AsClass()->Map(), bound, region); |
| 473 } else if (this->IsConstant()) { | 464 } else if (this->IsConstant()) { |
| 474 return ConstantType::New(this->AsConstant()->Value(), bound, region); | 465 return ConstantType::New(this->AsConstant()->Value(), bound, region); |
| 475 } else if (this->IsRange()) { | 466 } else if (this->IsRange()) { |
| 476 return RangeType::New( | 467 return RangeType::New( |
| 477 this->AsRange()->Min(), this->AsRange()->Max(), bound, region); | 468 this->AsRange()->Min(), this->AsRange()->Max(), bound, region); |
| 478 } else if (this->IsContext()) { | 469 } else if (this->IsContext()) { |
| 479 return ContextType::New(this->AsContext()->Outer(), bound, region); | 470 return ContextType::New(this->AsContext()->Outer(), bound, region); |
| 480 } else if (this->IsArray()) { | 471 } else if (this->IsArray()) { |
| 481 return ArrayType::New(this->AsArray()->Element(), bound, region); | 472 return ArrayType::New(this->AsArray()->Element(), bound, region); |
| 482 } else if (this->IsFunction()) { | 473 } else if (this->IsFunction()) { |
| 483 FunctionHandle function = Config::handle(this->AsFunction()); | 474 FunctionHandle function = Config::handle(this->AsFunction()); |
| 484 int arity = function->Arity(); | 475 int arity = function->Arity(); |
| 485 FunctionHandle type = FunctionType::New( | 476 FunctionHandle type = FunctionType::New( |
| 486 function->Result(), function->Receiver(), bound, arity, region); | 477 function->Result(), function->Receiver(), bound, arity, region); |
| 487 for (int i = 0; i < arity; ++i) { | 478 for (int i = 0; i < arity; ++i) { |
| 488 type->InitParameter(i, function->Parameter(i)); | 479 type->InitParameter(i, function->Parameter(i)); |
| 489 } | 480 } |
| 490 return type; | 481 return type; |
| 491 } | 482 } |
| 492 UNREACHABLE(); | 483 UNREACHABLE(); |
| 493 return TypeHandle(); | 484 return TypeHandle(); |
| 494 } | 485 } |
| 495 | 486 |
| 496 | 487 |
| 497 template<class Config> | 488 template<class Config> |
| 498 typename TypeImpl<Config>::bitset TypeImpl<Config>::BoundBy(TypeImpl* that) { | 489 int TypeImpl<Config>::BoundBy(TypeImpl* that) { |
| 499 DCHECK(!this->IsUnion()); | 490 DCHECK(!this->IsUnion()); |
| 500 if (that->IsUnion()) { | 491 if (that->IsUnion()) { |
| 501 UnionType* unioned = that->AsUnion(); | 492 UnionType* unioned = that->AsUnion(); |
| 502 int length = unioned->Length(); | 493 int length = unioned->Length(); |
| 503 bitset result = BitsetType::kNone; | 494 int bitset = BitsetType::kNone; |
| 504 for (int i = 0; i < length; ++i) { | 495 for (int i = 0; i < length; ++i) { |
| 505 result |= BoundBy(unioned->Get(i)->unhandle()); | 496 bitset |= BoundBy(unioned->Get(i)->unhandle()); |
| 506 } | 497 } |
| 507 return result; | 498 return bitset; |
| 508 } else if (that->IsClass() && this->IsClass() && | 499 } else if (that->IsClass() && this->IsClass() && |
| 509 *this->AsClass()->Map() == *that->AsClass()->Map()) { | 500 *this->AsClass()->Map() == *that->AsClass()->Map()) { |
| 510 return that->BitsetLub(); | 501 return that->BitsetLub(); |
| 511 } else if (that->IsConstant() && this->IsConstant() && | 502 } else if (that->IsConstant() && this->IsConstant() && |
| 512 *this->AsConstant()->Value() == *that->AsConstant()->Value()) { | 503 *this->AsConstant()->Value() == *that->AsConstant()->Value()) { |
| 513 return that->AsConstant()->Bound()->AsBitset(); | 504 return that->AsConstant()->Bound()->AsBitset(); |
| 514 } else if (that->IsContext() && this->IsContext() && this->Is(that)) { | 505 } else if (that->IsContext() && this->IsContext() && this->Is(that)) { |
| 515 return that->AsContext()->Bound()->AsBitset(); | 506 return that->AsContext()->Bound()->AsBitset(); |
| 516 } else if (that->IsArray() && this->IsArray() && this->Is(that)) { | 507 } else if (that->IsArray() && this->IsArray() && this->Is(that)) { |
| 517 return that->AsArray()->Bound()->AsBitset(); | 508 return that->AsArray()->Bound()->AsBitset(); |
| 518 } else if (that->IsFunction() && this->IsFunction() && this->Is(that)) { | 509 } else if (that->IsFunction() && this->IsFunction() && this->Is(that)) { |
| 519 return that->AsFunction()->Bound()->AsBitset(); | 510 return that->AsFunction()->Bound()->AsBitset(); |
| 520 } | 511 } |
| 521 return that->BitsetGlb(); | 512 return that->BitsetGlb(); |
| 522 } | 513 } |
| 523 | 514 |
| 524 | 515 |
| 525 template<class Config> | 516 template<class Config> |
| 526 int TypeImpl<Config>::IndexInUnion( | 517 int TypeImpl<Config>::IndexInUnion( |
| 527 bitset bound, UnionHandle unioned, int current_size) { | 518 int bound, UnionHandle unioned, int current_size) { |
| 528 DCHECK(!this->IsUnion()); | 519 DCHECK(!this->IsUnion()); |
| 529 for (int i = 0; i < current_size; ++i) { | 520 for (int i = 0; i < current_size; ++i) { |
| 530 TypeHandle that = unioned->Get(i); | 521 TypeHandle that = unioned->Get(i); |
| 531 if (that->IsBitset()) { | 522 if (that->IsBitset()) { |
| 532 if (BitsetType::Is(bound, that->AsBitset())) return i; | 523 if (BitsetType::Is(bound, that->AsBitset())) return i; |
| 533 } else if (that->IsClass() && this->IsClass()) { | 524 } else if (that->IsClass() && this->IsClass()) { |
| 534 if (*this->AsClass()->Map() == *that->AsClass()->Map()) return i; | 525 if (*this->AsClass()->Map() == *that->AsClass()->Map()) return i; |
| 535 } else if (that->IsConstant() && this->IsConstant()) { | 526 } else if (that->IsConstant() && this->IsConstant()) { |
| 536 if (*this->AsConstant()->Value() == *that->AsConstant()->Value()) | 527 if (*this->AsConstant()->Value() == *that->AsConstant()->Value()) |
| 537 return i; | 528 return i; |
| 538 } else if (that->IsContext() && this->IsContext()) { | 529 } else if (that->IsContext() && this->IsContext()) { |
| 539 if (this->Is(that)) return i; | 530 if (this->Is(that)) return i; |
| 540 } else if (that->IsArray() && this->IsArray()) { | 531 } else if (that->IsArray() && this->IsArray()) { |
| 541 if (this->Is(that)) return i; | 532 if (this->Is(that)) return i; |
| 542 } else if (that->IsFunction() && this->IsFunction()) { | 533 } else if (that->IsFunction() && this->IsFunction()) { |
| 543 if (this->Is(that)) return i; | 534 if (this->Is(that)) return i; |
| 544 } | 535 } |
| 545 } | 536 } |
| 546 return -1; | 537 return -1; |
| 547 } | 538 } |
| 548 | 539 |
| 549 | 540 |
| 550 // Get non-bitsets from type, bounded by upper. | 541 // Get non-bitsets from type, bounded by upper. |
| 551 // Store at result starting at index. Returns updated index. | 542 // Store at result starting at index. Returns updated index. |
| 552 template<class Config> | 543 template<class Config> |
| 553 int TypeImpl<Config>::ExtendUnion( | 544 int TypeImpl<Config>::ExtendUnion( |
| 554 UnionHandle result, int size, TypeHandle type, | 545 UnionHandle result, int size, TypeHandle type, |
| 555 TypeHandle other, bool is_intersect, Region* region) { | 546 TypeHandle other, bool is_intersect, Region* region) { |
| 556 if (type->IsUnion()) { | 547 if (type->IsUnion()) { |
| 557 UnionHandle unioned = Config::template cast<UnionType>(type); | 548 UnionHandle unioned = handle(type->AsUnion()); |
| 558 for (int i = 0; i < unioned->Length(); ++i) { | 549 for (int i = 0; i < unioned->Length(); ++i) { |
| 559 TypeHandle type_i = unioned->Get(i); | 550 TypeHandle type_i = unioned->Get(i); |
| 560 DCHECK(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0)))); | 551 DCHECK(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0)))); |
| 561 if (!type_i->IsBitset()) { | 552 if (!type_i->IsBitset()) { |
| 562 size = ExtendUnion(result, size, type_i, other, is_intersect, region); | 553 size = ExtendUnion(result, size, type_i, other, is_intersect, region); |
| 563 } | 554 } |
| 564 } | 555 } |
| 565 } else if (!type->IsBitset()) { | 556 } else if (!type->IsBitset()) { |
| 566 DCHECK(type->IsClass() || type->IsConstant() || type->IsRange() || | 557 DCHECK(type->IsClass() || type->IsConstant() || type->IsRange() || |
| 567 type->IsContext() || type->IsArray() || type->IsFunction()); | 558 type->IsContext() || type->IsArray() || type->IsFunction()); |
| 568 bitset inherent_bound = type->InherentBitsetLub(); | 559 int inherent_bound = type->InherentBitsetLub(); |
| 569 bitset old_bound = type->BitsetLub(); | 560 int old_bound = type->BitsetLub(); |
| 570 bitset other_bound = type->BoundBy(other->unhandle()) & inherent_bound; | 561 int other_bound = type->BoundBy(other->unhandle()) & inherent_bound; |
| 571 bitset new_bound = | 562 int new_bound = |
| 572 is_intersect ? (old_bound & other_bound) : (old_bound | other_bound); | 563 is_intersect ? (old_bound & other_bound) : (old_bound | other_bound); |
| 573 if (new_bound != BitsetType::kNone) { | 564 if (new_bound != BitsetType::kNone) { |
| 574 int i = type->IndexInUnion(new_bound, result, size); | 565 int i = type->IndexInUnion(new_bound, result, size); |
| 575 if (i == -1) { | 566 if (i == -1) { |
| 576 i = size++; | 567 i = size++; |
| 577 } else if (result->Get(i)->IsBitset()) { | 568 } else if (result->Get(i)->IsBitset()) { |
| 578 return size; // Already fully subsumed. | 569 return size; // Already fully subsumed. |
| 579 } else { | 570 } else { |
| 580 bitset type_i_bound = result->Get(i)->BitsetLub(); | 571 int type_i_bound = result->Get(i)->BitsetLub(); |
| 581 new_bound |= type_i_bound; | 572 new_bound |= type_i_bound; |
| 582 if (new_bound == type_i_bound) return size; | 573 if (new_bound == type_i_bound) return size; |
| 583 } | 574 } |
| 584 if (new_bound != old_bound) type = type->Rebound(new_bound, region); | 575 if (new_bound != old_bound) type = type->Rebound(new_bound, region); |
| 585 result->Set(i, type); | 576 result->Set(i, type); |
| 586 } | 577 } |
| 587 } | 578 } |
| 588 return size; | 579 return size; |
| 589 } | 580 } |
| 590 | 581 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 609 } | 600 } |
| 610 | 601 |
| 611 // Slow case: may need to produce a Unioned object. | 602 // Slow case: may need to produce a Unioned object. |
| 612 int size = 0; | 603 int size = 0; |
| 613 if (!type1->IsBitset()) { | 604 if (!type1->IsBitset()) { |
| 614 size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1); | 605 size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1); |
| 615 } | 606 } |
| 616 if (!type2->IsBitset()) { | 607 if (!type2->IsBitset()) { |
| 617 size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); | 608 size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); |
| 618 } | 609 } |
| 619 bitset bits = type1->BitsetGlb() | type2->BitsetGlb(); | 610 int bitset = type1->BitsetGlb() | type2->BitsetGlb(); |
| 620 if (bits != BitsetType::kNone) ++size; | 611 if (bitset != BitsetType::kNone) ++size; |
| 621 DCHECK(size >= 1); | 612 DCHECK(size >= 1); |
| 622 | 613 |
| 623 UnionHandle unioned = UnionType::New(size, region); | 614 UnionHandle unioned = UnionType::New(size, region); |
| 624 size = 0; | 615 size = 0; |
| 625 if (bits != BitsetType::kNone) { | 616 if (bitset != BitsetType::kNone) { |
| 626 unioned->Set(size++, BitsetType::New(bits, region)); | 617 unioned->Set(size++, BitsetType::New(bitset, region)); |
| 627 } | 618 } |
| 628 size = ExtendUnion(unioned, size, type1, type2, false, region); | 619 size = ExtendUnion(unioned, size, type1, type2, false, region); |
| 629 size = ExtendUnion(unioned, size, type2, type1, false, region); | 620 size = ExtendUnion(unioned, size, type2, type1, false, region); |
| 630 | 621 |
| 631 if (size == 1) { | 622 if (size == 1) { |
| 632 return unioned->Get(0); | 623 return unioned->Get(0); |
| 633 } else { | 624 } else { |
| 634 unioned->Shrink(size); | 625 unioned->Shrink(size); |
| 635 DCHECK(unioned->Wellformed()); | 626 DCHECK(unioned->Wellformed()); |
| 636 return unioned; | 627 return unioned; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 658 } | 649 } |
| 659 | 650 |
| 660 // Slow case: may need to produce a Unioned object. | 651 // Slow case: may need to produce a Unioned object. |
| 661 int size = 0; | 652 int size = 0; |
| 662 if (!type1->IsBitset()) { | 653 if (!type1->IsBitset()) { |
| 663 size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1); | 654 size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1); |
| 664 } | 655 } |
| 665 if (!type2->IsBitset()) { | 656 if (!type2->IsBitset()) { |
| 666 size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); | 657 size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); |
| 667 } | 658 } |
| 668 bitset bits = type1->BitsetGlb() & type2->BitsetGlb(); | 659 int bitset = type1->BitsetGlb() & type2->BitsetGlb(); |
| 669 if (bits != BitsetType::kNone) ++size; | 660 if (bitset != BitsetType::kNone) ++size; |
| 670 DCHECK(size >= 1); | 661 DCHECK(size >= 1); |
| 671 | 662 |
| 672 UnionHandle unioned = UnionType::New(size, region); | 663 UnionHandle unioned = UnionType::New(size, region); |
| 673 size = 0; | 664 size = 0; |
| 674 if (bits != BitsetType::kNone) { | 665 if (bitset != BitsetType::kNone) { |
| 675 unioned->Set(size++, BitsetType::New(bits, region)); | 666 unioned->Set(size++, BitsetType::New(bitset, region)); |
| 676 } | 667 } |
| 677 size = ExtendUnion(unioned, size, type1, type2, true, region); | 668 size = ExtendUnion(unioned, size, type1, type2, true, region); |
| 678 size = ExtendUnion(unioned, size, type2, type1, true, region); | 669 size = ExtendUnion(unioned, size, type2, type1, true, region); |
| 679 | 670 |
| 680 if (size == 0) { | 671 if (size == 0) { |
| 681 return None(region); | 672 return None(region); |
| 682 } else if (size == 1) { | 673 } else if (size == 1) { |
| 683 return unioned->Get(0); | 674 return unioned->Get(0); |
| 684 } else { | 675 } else { |
| 685 unioned->Shrink(size); | 676 unioned->Shrink(size); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() { | 765 i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() { |
| 775 return TypeImplIteratorAux<Config, T>::current(get_type()); | 766 return TypeImplIteratorAux<Config, T>::current(get_type()); |
| 776 } | 767 } |
| 777 | 768 |
| 778 | 769 |
| 779 template<class Config> template<class T> | 770 template<class Config> template<class T> |
| 780 void TypeImpl<Config>::Iterator<T>::Advance() { | 771 void TypeImpl<Config>::Iterator<T>::Advance() { |
| 781 DisallowHeapAllocation no_allocation; | 772 DisallowHeapAllocation no_allocation; |
| 782 ++index_; | 773 ++index_; |
| 783 if (type_->IsUnion()) { | 774 if (type_->IsUnion()) { |
| 784 UnionHandle unioned = Config::template cast<UnionType>(type_); | 775 UnionHandle unioned = handle(type_->AsUnion()); |
| 785 for (; index_ < unioned->Length(); ++index_) { | 776 for (; index_ < unioned->Length(); ++index_) { |
| 786 if (matches(unioned->Get(index_))) return; | 777 if (matches(unioned->Get(index_))) return; |
| 787 } | 778 } |
| 788 } else if (index_ == 0 && matches(type_)) { | 779 } else if (index_ == 0 && matches(type_)) { |
| 789 return; | 780 return; |
| 790 } | 781 } |
| 791 index_ = -1; | 782 index_ = -1; |
| 792 } | 783 } |
| 793 | 784 |
| 794 | 785 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 UNREACHABLE(); | 834 UNREACHABLE(); |
| 844 return None(region); | 835 return None(region); |
| 845 } | 836 } |
| 846 } | 837 } |
| 847 | 838 |
| 848 | 839 |
| 849 // ----------------------------------------------------------------------------- | 840 // ----------------------------------------------------------------------------- |
| 850 // Printing. | 841 // Printing. |
| 851 | 842 |
| 852 template<class Config> | 843 template<class Config> |
| 853 const char* TypeImpl<Config>::BitsetType::Name(bitset bits) { | 844 const char* TypeImpl<Config>::BitsetType::Name(int bitset) { |
| 854 switch (bits) { | 845 switch (bitset) { |
| 855 case REPRESENTATION(kAny): return "Any"; | 846 case REPRESENTATION(kAny): return "Any"; |
| 856 #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ | 847 #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ |
| 857 case REPRESENTATION(k##type): return #type; | 848 case REPRESENTATION(k##type): return #type; |
| 858 REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE) | 849 REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE) |
| 859 #undef RETURN_NAMED_REPRESENTATION_TYPE | 850 #undef RETURN_NAMED_REPRESENTATION_TYPE |
| 860 | 851 |
| 861 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ | 852 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ |
| 862 case SEMANTIC(k##type): return #type; | 853 case SEMANTIC(k##type): return #type; |
| 863 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 854 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
| 864 #undef RETURN_NAMED_SEMANTIC_TYPE | 855 #undef RETURN_NAMED_SEMANTIC_TYPE |
| 865 | 856 |
| 866 default: | 857 default: |
| 867 return NULL; | 858 return NULL; |
| 868 } | 859 } |
| 869 } | 860 } |
| 870 | 861 |
| 871 | 862 |
| 872 template <class Config> | 863 template <class Config> |
| 873 void TypeImpl<Config>::BitsetType::Print(OStream& os, // NOLINT | 864 void TypeImpl<Config>::BitsetType::Print(OStream& os, // NOLINT |
| 874 bitset bits) { | 865 int bitset) { |
| 875 DisallowHeapAllocation no_allocation; | 866 DisallowHeapAllocation no_allocation; |
| 876 const char* name = Name(bits); | 867 const char* name = Name(bitset); |
| 877 if (name != NULL) { | 868 if (name != NULL) { |
| 878 os << name; | 869 os << name; |
| 879 return; | 870 return; |
| 880 } | 871 } |
| 881 | 872 |
| 882 static const bitset named_bitsets[] = { | 873 static const int named_bitsets[] = { |
| 883 #define BITSET_CONSTANT(type, value) REPRESENTATION(k##type), | 874 #define BITSET_CONSTANT(type, value) REPRESENTATION(k##type), |
| 884 REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) | 875 REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) |
| 885 #undef BITSET_CONSTANT | 876 #undef BITSET_CONSTANT |
| 886 | 877 |
| 887 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type), | 878 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type), |
| 888 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) | 879 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) |
| 889 #undef BITSET_CONSTANT | 880 #undef BITSET_CONSTANT |
| 890 }; | 881 }; |
| 891 | 882 |
| 892 bool is_first = true; | 883 bool is_first = true; |
| 893 os << "("; | 884 os << "("; |
| 894 for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) { | 885 for (int i(arraysize(named_bitsets) - 1); bitset != 0 && i >= 0; --i) { |
| 895 bitset subset = named_bitsets[i]; | 886 int subset = named_bitsets[i]; |
| 896 if ((bits & subset) == subset) { | 887 if ((bitset & subset) == subset) { |
| 897 if (!is_first) os << " | "; | 888 if (!is_first) os << " | "; |
| 898 is_first = false; | 889 is_first = false; |
| 899 os << Name(subset); | 890 os << Name(subset); |
| 900 bits -= subset; | 891 bitset -= subset; |
| 901 } | 892 } |
| 902 } | 893 } |
| 903 DCHECK(bits == 0); | 894 DCHECK(bitset == 0); |
| 904 os << ")"; | 895 os << ")"; |
| 905 } | 896 } |
| 906 | 897 |
| 907 | 898 |
| 908 template <class Config> | 899 template <class Config> |
| 909 void TypeImpl<Config>::PrintTo(OStream& os, PrintDimension dim) { // NOLINT | 900 void TypeImpl<Config>::PrintTo(OStream& os, PrintDimension dim) { // NOLINT |
| 910 DisallowHeapAllocation no_allocation; | 901 DisallowHeapAllocation no_allocation; |
| 911 if (dim != REPRESENTATION_DIM) { | 902 if (dim != REPRESENTATION_DIM) { |
| 912 if (this->IsBitset()) { | 903 if (this->IsBitset()) { |
| 913 BitsetType::Print(os, SEMANTIC(this->AsBitset())); | 904 BitsetType::Print(os, SEMANTIC(this->AsBitset())); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; | 978 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; |
| 988 | 979 |
| 989 template TypeImpl<ZoneTypeConfig>::TypeHandle | 980 template TypeImpl<ZoneTypeConfig>::TypeHandle |
| 990 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( | 981 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( |
| 991 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); | 982 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); |
| 992 template TypeImpl<HeapTypeConfig>::TypeHandle | 983 template TypeImpl<HeapTypeConfig>::TypeHandle |
| 993 TypeImpl<HeapTypeConfig>::Convert<Type>( | 984 TypeImpl<HeapTypeConfig>::Convert<Type>( |
| 994 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); | 985 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); |
| 995 | 986 |
| 996 } } // namespace v8::internal | 987 } } // namespace v8::internal |
| OLD | NEW |