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