| 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 <iomanip> | 5 #include <iomanip> |
| 6 | 6 |
| 7 #include "src/types.h" | 7 #include "src/compiler/types.h" |
| 8 | 8 |
| 9 #include "src/handles-inl.h" | 9 #include "src/handles-inl.h" |
| 10 #include "src/ostreams.h" | 10 #include "src/ostreams.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 | 14 |
| 15 | |
| 16 // NOTE: If code is marked as being a "shortcut", this means that removing | 15 // NOTE: If code is marked as being a "shortcut", this means that removing |
| 17 // the code won't affect the semantics of the surrounding function definition. | 16 // the code won't affect the semantics of the surrounding function definition. |
| 18 | 17 |
| 19 // static | 18 // static |
| 20 bool Type::IsInteger(i::Object* x) { | 19 bool Type::IsInteger(i::Object* x) { |
| 21 return x->IsNumber() && Type::IsInteger(x->Number()); | 20 return x->IsNumber() && Type::IsInteger(x->Number()); |
| 22 } | 21 } |
| 23 | 22 |
| 24 // ----------------------------------------------------------------------------- | 23 // ----------------------------------------------------------------------------- |
| 25 // Range-related helper functions. | 24 // Range-related helper functions. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 51 .IsEmpty(); | 50 .IsEmpty(); |
| 52 } | 51 } |
| 53 | 52 |
| 54 bool Type::Contains(RangeType* lhs, RangeType* rhs) { | 53 bool Type::Contains(RangeType* lhs, RangeType* rhs) { |
| 55 DisallowHeapAllocation no_allocation; | 54 DisallowHeapAllocation no_allocation; |
| 56 return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max(); | 55 return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max(); |
| 57 } | 56 } |
| 58 | 57 |
| 59 bool Type::Contains(RangeType* lhs, ConstantType* rhs) { | 58 bool Type::Contains(RangeType* lhs, ConstantType* rhs) { |
| 60 DisallowHeapAllocation no_allocation; | 59 DisallowHeapAllocation no_allocation; |
| 61 return IsInteger(*rhs->Value()) && | 60 return IsInteger(*rhs->Value()) && lhs->Min() <= rhs->Value()->Number() && |
| 62 lhs->Min() <= rhs->Value()->Number() && | |
| 63 rhs->Value()->Number() <= lhs->Max(); | 61 rhs->Value()->Number() <= lhs->Max(); |
| 64 } | 62 } |
| 65 | 63 |
| 66 bool Type::Contains(RangeType* range, i::Object* val) { | 64 bool Type::Contains(RangeType* range, i::Object* val) { |
| 67 DisallowHeapAllocation no_allocation; | 65 DisallowHeapAllocation no_allocation; |
| 68 return IsInteger(val) && | 66 return IsInteger(val) && range->Min() <= val->Number() && |
| 69 range->Min() <= val->Number() && val->Number() <= range->Max(); | 67 val->Number() <= range->Max(); |
| 70 } | 68 } |
| 71 | 69 |
| 72 | |
| 73 // ----------------------------------------------------------------------------- | 70 // ----------------------------------------------------------------------------- |
| 74 // Min and Max computation. | 71 // Min and Max computation. |
| 75 | 72 |
| 76 double Type::Min() { | 73 double Type::Min() { |
| 77 DCHECK(this->SemanticIs(Number())); | 74 DCHECK(this->SemanticIs(Number())); |
| 78 if (this->IsBitset()) return BitsetType::Min(this->AsBitset()); | 75 if (this->IsBitset()) return BitsetType::Min(this->AsBitset()); |
| 79 if (this->IsUnion()) { | 76 if (this->IsUnion()) { |
| 80 double min = +V8_INFINITY; | 77 double min = +V8_INFINITY; |
| 81 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 78 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
| 82 min = std::min(min, this->AsUnion()->Get(i)->Min()); | 79 min = std::min(min, this->AsUnion()->Get(i)->Min()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 98 max = std::max(max, this->AsUnion()->Get(i)->Max()); | 95 max = std::max(max, this->AsUnion()->Get(i)->Max()); |
| 99 } | 96 } |
| 100 return max; | 97 return max; |
| 101 } | 98 } |
| 102 if (this->IsRange()) return this->AsRange()->Max(); | 99 if (this->IsRange()) return this->AsRange()->Max(); |
| 103 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); | 100 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); |
| 104 UNREACHABLE(); | 101 UNREACHABLE(); |
| 105 return 0; | 102 return 0; |
| 106 } | 103 } |
| 107 | 104 |
| 108 | |
| 109 // ----------------------------------------------------------------------------- | 105 // ----------------------------------------------------------------------------- |
| 110 // Glb and lub computation. | 106 // Glb and lub computation. |
| 111 | 107 |
| 112 | |
| 113 // The largest bitset subsumed by this type. | 108 // The largest bitset subsumed by this type. |
| 114 Type::bitset BitsetType::Glb(Type* type) { | 109 Type::bitset BitsetType::Glb(Type* type) { |
| 115 DisallowHeapAllocation no_allocation; | 110 DisallowHeapAllocation no_allocation; |
| 116 // Fast case. | 111 // Fast case. |
| 117 if (IsBitset(type)) { | 112 if (IsBitset(type)) { |
| 118 return type->AsBitset(); | 113 return type->AsBitset(); |
| 119 } else if (type->IsUnion()) { | 114 } else if (type->IsUnion()) { |
| 120 SLOW_DCHECK(type->AsUnion()->Wellformed()); | 115 SLOW_DCHECK(type->AsUnion()->Wellformed()); |
| 121 return type->AsUnion()->Get(0)->BitsetGlb() | | 116 return type->AsUnion()->Get(0)->BitsetGlb() | |
| 122 SEMANTIC(type->AsUnion()->Get(1)->BitsetGlb()); // Shortcut. | 117 SEMANTIC(type->AsUnion()->Get(1)->BitsetGlb()); // Shortcut. |
| 123 } else if (type->IsRange()) { | 118 } else if (type->IsRange()) { |
| 124 bitset glb = SEMANTIC( | 119 bitset glb = SEMANTIC( |
| 125 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max())); | 120 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max())); |
| 126 return glb | REPRESENTATION(type->BitsetLub()); | 121 return glb | REPRESENTATION(type->BitsetLub()); |
| 127 } else { | 122 } else { |
| 128 return type->Representation(); | 123 return type->Representation(); |
| 129 } | 124 } |
| 130 } | 125 } |
| 131 | 126 |
| 132 | |
| 133 // The smallest bitset subsuming this type, possibly not a proper one. | 127 // The smallest bitset subsuming this type, possibly not a proper one. |
| 134 Type::bitset BitsetType::Lub(Type* type) { | 128 Type::bitset BitsetType::Lub(Type* type) { |
| 135 DisallowHeapAllocation no_allocation; | 129 DisallowHeapAllocation no_allocation; |
| 136 if (IsBitset(type)) return type->AsBitset(); | 130 if (IsBitset(type)) return type->AsBitset(); |
| 137 if (type->IsUnion()) { | 131 if (type->IsUnion()) { |
| 138 // Take the representation from the first element, which is always | 132 // Take the representation from the first element, which is always |
| 139 // a bitset. | 133 // a bitset. |
| 140 int bitset = type->AsUnion()->Get(0)->BitsetLub(); | 134 int bitset = type->AsUnion()->Get(0)->BitsetLub(); |
| 141 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { | 135 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { |
| 142 // Other elements only contribute their semantic part. | 136 // Other elements only contribute their semantic part. |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 return kNone; | 273 return kNone; |
| 280 } | 274 } |
| 281 UNREACHABLE(); | 275 UNREACHABLE(); |
| 282 return kNone; | 276 return kNone; |
| 283 } | 277 } |
| 284 | 278 |
| 285 Type::bitset BitsetType::Lub(i::Object* value) { | 279 Type::bitset BitsetType::Lub(i::Object* value) { |
| 286 DisallowHeapAllocation no_allocation; | 280 DisallowHeapAllocation no_allocation; |
| 287 if (value->IsNumber()) { | 281 if (value->IsNumber()) { |
| 288 return Lub(value->Number()) & | 282 return Lub(value->Number()) & |
| 289 (value->IsSmi() ? kTaggedSigned : kTaggedPointer); | 283 (value->IsSmi() ? kTaggedSigned : kTaggedPointer); |
| 290 } | 284 } |
| 291 return Lub(i::HeapObject::cast(value)->map()); | 285 return Lub(i::HeapObject::cast(value)->map()); |
| 292 } | 286 } |
| 293 | 287 |
| 294 Type::bitset BitsetType::Lub(double value) { | 288 Type::bitset BitsetType::Lub(double value) { |
| 295 DisallowHeapAllocation no_allocation; | 289 DisallowHeapAllocation no_allocation; |
| 296 if (i::IsMinusZero(value)) return kMinusZero; | 290 if (i::IsMinusZero(value)) return kMinusZero; |
| 297 if (std::isnan(value)) return kNaN; | 291 if (std::isnan(value)) return kNaN; |
| 298 if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value); | 292 if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value); |
| 299 return kOtherNumber; | 293 return kOtherNumber; |
| 300 } | 294 } |
| 301 | 295 |
| 302 | |
| 303 // Minimum values of plain numeric bitsets. | 296 // Minimum values of plain numeric bitsets. |
| 304 const BitsetType::Boundary BitsetType::BoundariesArray[] = { | 297 const BitsetType::Boundary BitsetType::BoundariesArray[] = { |
| 305 {kOtherNumber, kPlainNumber, -V8_INFINITY}, | 298 {kOtherNumber, kPlainNumber, -V8_INFINITY}, |
| 306 {kOtherSigned32, kNegative32, kMinInt}, | 299 {kOtherSigned32, kNegative32, kMinInt}, |
| 307 {kNegative31, kNegative31, -0x40000000}, | 300 {kNegative31, kNegative31, -0x40000000}, |
| 308 {kUnsigned30, kUnsigned30, 0}, | 301 {kUnsigned30, kUnsigned30, 0}, |
| 309 {kOtherUnsigned31, kUnsigned31, 0x40000000}, | 302 {kOtherUnsigned31, kUnsigned31, 0x40000000}, |
| 310 {kOtherUnsigned32, kUnsigned32, 0x80000000}, | 303 {kOtherUnsigned32, kUnsigned32, 0x80000000}, |
| 311 {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}}; | 304 {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}}; |
| 312 | 305 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 330 return bits; | 323 return bits; |
| 331 } | 324 } |
| 332 | 325 |
| 333 Type::bitset BitsetType::Lub(double min, double max) { | 326 Type::bitset BitsetType::Lub(double min, double max) { |
| 334 DisallowHeapAllocation no_allocation; | 327 DisallowHeapAllocation no_allocation; |
| 335 int lub = kNone; | 328 int lub = kNone; |
| 336 const Boundary* mins = Boundaries(); | 329 const Boundary* mins = Boundaries(); |
| 337 | 330 |
| 338 for (size_t i = 1; i < BoundariesSize(); ++i) { | 331 for (size_t i = 1; i < BoundariesSize(); ++i) { |
| 339 if (min < mins[i].min) { | 332 if (min < mins[i].min) { |
| 340 lub |= mins[i-1].internal; | 333 lub |= mins[i - 1].internal; |
| 341 if (max < mins[i].min) return lub; | 334 if (max < mins[i].min) return lub; |
| 342 } | 335 } |
| 343 } | 336 } |
| 344 return lub | mins[BoundariesSize() - 1].internal; | 337 return lub | mins[BoundariesSize() - 1].internal; |
| 345 } | 338 } |
| 346 | 339 |
| 347 Type::bitset BitsetType::NumberBits(bitset bits) { | 340 Type::bitset BitsetType::NumberBits(bitset bits) { |
| 348 return SEMANTIC(bits & kPlainNumber); | 341 return SEMANTIC(bits & kPlainNumber); |
| 349 } | 342 } |
| 350 | 343 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 double BitsetType::Max(bitset bits) { | 377 double BitsetType::Max(bitset bits) { |
| 385 DisallowHeapAllocation no_allocation; | 378 DisallowHeapAllocation no_allocation; |
| 386 DCHECK(Is(SEMANTIC(bits), kNumber)); | 379 DCHECK(Is(SEMANTIC(bits), kNumber)); |
| 387 const Boundary* mins = Boundaries(); | 380 const Boundary* mins = Boundaries(); |
| 388 bool mz = SEMANTIC(bits & kMinusZero); | 381 bool mz = SEMANTIC(bits & kMinusZero); |
| 389 if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].internal), bits)) { | 382 if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].internal), bits)) { |
| 390 return +V8_INFINITY; | 383 return +V8_INFINITY; |
| 391 } | 384 } |
| 392 for (size_t i = BoundariesSize() - 1; i-- > 0;) { | 385 for (size_t i = BoundariesSize() - 1; i-- > 0;) { |
| 393 if (Is(SEMANTIC(mins[i].internal), bits)) { | 386 if (Is(SEMANTIC(mins[i].internal), bits)) { |
| 394 return mz ? | 387 return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1; |
| 395 std::max(0.0, mins[i+1].min - 1) : mins[i+1].min - 1; | |
| 396 } | 388 } |
| 397 } | 389 } |
| 398 if (mz) return 0; | 390 if (mz) return 0; |
| 399 return std::numeric_limits<double>::quiet_NaN(); | 391 return std::numeric_limits<double>::quiet_NaN(); |
| 400 } | 392 } |
| 401 | 393 |
| 402 | |
| 403 // ----------------------------------------------------------------------------- | 394 // ----------------------------------------------------------------------------- |
| 404 // Predicates. | 395 // Predicates. |
| 405 | 396 |
| 406 bool Type::SimplyEquals(Type* that) { | 397 bool Type::SimplyEquals(Type* that) { |
| 407 DisallowHeapAllocation no_allocation; | 398 DisallowHeapAllocation no_allocation; |
| 408 if (this->IsConstant()) { | 399 if (this->IsConstant()) { |
| 409 return that->IsConstant() | 400 return that->IsConstant() && |
| 410 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); | 401 *this->AsConstant()->Value() == *that->AsConstant()->Value(); |
| 411 } | 402 } |
| 412 if (this->IsTuple()) { | 403 if (this->IsTuple()) { |
| 413 if (!that->IsTuple()) return false; | 404 if (!that->IsTuple()) return false; |
| 414 TupleType* this_tuple = this->AsTuple(); | 405 TupleType* this_tuple = this->AsTuple(); |
| 415 TupleType* that_tuple = that->AsTuple(); | 406 TupleType* that_tuple = that->AsTuple(); |
| 416 if (this_tuple->Arity() != that_tuple->Arity()) { | 407 if (this_tuple->Arity() != that_tuple->Arity()) { |
| 417 return false; | 408 return false; |
| 418 } | 409 } |
| 419 for (int i = 0, n = this_tuple->Arity(); i < n; ++i) { | 410 for (int i = 0, n = this_tuple->Arity(); i < n; ++i) { |
| 420 if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false; | 411 if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false; |
| 421 } | 412 } |
| 422 return true; | 413 return true; |
| 423 } | 414 } |
| 424 UNREACHABLE(); | 415 UNREACHABLE(); |
| 425 return false; | 416 return false; |
| 426 } | 417 } |
| 427 | 418 |
| 428 Type::bitset Type::Representation() { | 419 Type::bitset Type::Representation() { |
| 429 return REPRESENTATION(this->BitsetLub()); | 420 return REPRESENTATION(this->BitsetLub()); |
| 430 } | 421 } |
| 431 | 422 |
| 432 | |
| 433 // Check if [this] <= [that]. | 423 // Check if [this] <= [that]. |
| 434 bool Type::SlowIs(Type* that) { | 424 bool Type::SlowIs(Type* that) { |
| 435 DisallowHeapAllocation no_allocation; | 425 DisallowHeapAllocation no_allocation; |
| 436 | 426 |
| 437 // Fast bitset cases | 427 // Fast bitset cases |
| 438 if (that->IsBitset()) { | 428 if (that->IsBitset()) { |
| 439 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); | 429 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); |
| 440 } | 430 } |
| 441 | 431 |
| 442 if (this->IsBitset()) { | 432 if (this->IsBitset()) { |
| 443 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); | 433 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); |
| 444 } | 434 } |
| 445 | 435 |
| 446 // Check the representations. | 436 // Check the representations. |
| 447 if (!BitsetType::Is(Representation(), that->Representation())) { | 437 if (!BitsetType::Is(Representation(), that->Representation())) { |
| 448 return false; | 438 return false; |
| 449 } | 439 } |
| 450 | 440 |
| 451 // Check the semantic part. | 441 // Check the semantic part. |
| 452 return SemanticIs(that); | 442 return SemanticIs(that); |
| 453 } | 443 } |
| 454 | 444 |
| 455 | |
| 456 // Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method | 445 // Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method |
| 457 // should be independent of the representation axis of the types. | 446 // should be independent of the representation axis of the types. |
| 458 bool Type::SemanticIs(Type* that) { | 447 bool Type::SemanticIs(Type* that) { |
| 459 DisallowHeapAllocation no_allocation; | 448 DisallowHeapAllocation no_allocation; |
| 460 | 449 |
| 461 if (this == that) return true; | 450 if (this == that) return true; |
| 462 | 451 |
| 463 if (that->IsBitset()) { | 452 if (that->IsBitset()) { |
| 464 return BitsetType::Is(SEMANTIC(this->BitsetLub()), that->AsBitset()); | 453 return BitsetType::Is(SEMANTIC(this->BitsetLub()), that->AsBitset()); |
| 465 } | 454 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 487 if (that->IsRange()) { | 476 if (that->IsRange()) { |
| 488 return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || | 477 return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || |
| 489 (this->IsConstant() && | 478 (this->IsConstant() && |
| 490 Contains(that->AsRange(), this->AsConstant())); | 479 Contains(that->AsRange(), this->AsConstant())); |
| 491 } | 480 } |
| 492 if (this->IsRange()) return false; | 481 if (this->IsRange()) return false; |
| 493 | 482 |
| 494 return this->SimplyEquals(that); | 483 return this->SimplyEquals(that); |
| 495 } | 484 } |
| 496 | 485 |
| 497 | |
| 498 // Check if [this] and [that] overlap. | 486 // Check if [this] and [that] overlap. |
| 499 bool Type::Maybe(Type* that) { | 487 bool Type::Maybe(Type* that) { |
| 500 DisallowHeapAllocation no_allocation; | 488 DisallowHeapAllocation no_allocation; |
| 501 | 489 |
| 502 // Take care of the representation part (and also approximate | 490 // Take care of the representation part (and also approximate |
| 503 // the semantic part). | 491 // the semantic part). |
| 504 if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub())) | 492 if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub())) |
| 505 return false; | 493 return false; |
| 506 | 494 |
| 507 return SemanticMaybe(that); | 495 return SemanticMaybe(that); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 } | 538 } |
| 551 if (that->IsRange()) { | 539 if (that->IsRange()) { |
| 552 return that->SemanticMaybe(this); // This case is handled above. | 540 return that->SemanticMaybe(this); // This case is handled above. |
| 553 } | 541 } |
| 554 | 542 |
| 555 if (this->IsBitset() || that->IsBitset()) return true; | 543 if (this->IsBitset() || that->IsBitset()) return true; |
| 556 | 544 |
| 557 return this->SimplyEquals(that); | 545 return this->SimplyEquals(that); |
| 558 } | 546 } |
| 559 | 547 |
| 560 | |
| 561 // Return the range in [this], or [NULL]. | 548 // Return the range in [this], or [NULL]. |
| 562 Type* Type::GetRange() { | 549 Type* Type::GetRange() { |
| 563 DisallowHeapAllocation no_allocation; | 550 DisallowHeapAllocation no_allocation; |
| 564 if (this->IsRange()) return this; | 551 if (this->IsRange()) return this; |
| 565 if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) { | 552 if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) { |
| 566 return this->AsUnion()->Get(1); | 553 return this->AsUnion()->Get(1); |
| 567 } | 554 } |
| 568 return NULL; | 555 return NULL; |
| 569 } | 556 } |
| 570 | 557 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 583 bool UnionType::Wellformed() { | 570 bool UnionType::Wellformed() { |
| 584 DisallowHeapAllocation no_allocation; | 571 DisallowHeapAllocation no_allocation; |
| 585 // This checks the invariants of the union representation: | 572 // This checks the invariants of the union representation: |
| 586 // 1. There are at least two elements. | 573 // 1. There are at least two elements. |
| 587 // 2. The first element is a bitset, no other element is a bitset. | 574 // 2. The first element is a bitset, no other element is a bitset. |
| 588 // 3. At most one element is a range, and it must be the second one. | 575 // 3. At most one element is a range, and it must be the second one. |
| 589 // 4. No element is itself a union. | 576 // 4. No element is itself a union. |
| 590 // 5. No element (except the bitset) is a subtype of any other. | 577 // 5. No element (except the bitset) is a subtype of any other. |
| 591 // 6. If there is a range, then the bitset type does not contain | 578 // 6. If there is a range, then the bitset type does not contain |
| 592 // plain number bits. | 579 // plain number bits. |
| 593 DCHECK(this->Length() >= 2); // (1) | 580 DCHECK(this->Length() >= 2); // (1) |
| 594 DCHECK(this->Get(0)->IsBitset()); // (2a) | 581 DCHECK(this->Get(0)->IsBitset()); // (2a) |
| 595 | 582 |
| 596 for (int i = 0; i < this->Length(); ++i) { | 583 for (int i = 0; i < this->Length(); ++i) { |
| 597 if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2b) | 584 if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2b) |
| 598 if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3) | 585 if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3) |
| 599 DCHECK(!this->Get(i)->IsUnion()); // (4) | 586 DCHECK(!this->Get(i)->IsUnion()); // (4) |
| 600 for (int j = 0; j < this->Length(); ++j) { | 587 for (int j = 0; j < this->Length(); ++j) { |
| 601 if (i != j && i != 0) | 588 if (i != j && i != 0) |
| 602 DCHECK(!this->Get(i)->SemanticIs(this->Get(j))); // (5) | 589 DCHECK(!this->Get(i)->SemanticIs(this->Get(j))); // (5) |
| 603 } | 590 } |
| 604 } | 591 } |
| 605 DCHECK(!this->Get(1)->IsRange() || | 592 DCHECK(!this->Get(1)->IsRange() || |
| 606 (BitsetType::NumberBits(this->Get(0)->AsBitset()) == | 593 (BitsetType::NumberBits(this->Get(0)->AsBitset()) == |
| 607 BitsetType::kNone)); // (6) | 594 BitsetType::kNone)); // (6) |
| 608 return true; | 595 return true; |
| 609 } | 596 } |
| 610 | 597 |
| 611 | |
| 612 // ----------------------------------------------------------------------------- | 598 // ----------------------------------------------------------------------------- |
| 613 // Union and intersection | 599 // Union and intersection |
| 614 | 600 |
| 615 | |
| 616 static bool AddIsSafe(int x, int y) { | 601 static bool AddIsSafe(int x, int y) { |
| 617 return x >= 0 ? | 602 return x >= 0 ? y <= std::numeric_limits<int>::max() - x |
| 618 y <= std::numeric_limits<int>::max() - x : | 603 : y >= std::numeric_limits<int>::min() - x; |
| 619 y >= std::numeric_limits<int>::min() - x; | |
| 620 } | 604 } |
| 621 | 605 |
| 622 Type* Type::Intersect(Type* type1, Type* type2, Zone* zone) { | 606 Type* Type::Intersect(Type* type1, Type* type2, Zone* zone) { |
| 623 // Fast case: bit sets. | 607 // Fast case: bit sets. |
| 624 if (type1->IsBitset() && type2->IsBitset()) { | 608 if (type1->IsBitset() && type2->IsBitset()) { |
| 625 return BitsetType::New(type1->AsBitset() & type2->AsBitset()); | 609 return BitsetType::New(type1->AsBitset() & type2->AsBitset()); |
| 626 } | 610 } |
| 627 | 611 |
| 628 // Fast case: top or bottom types. | 612 // Fast case: top or bottom types. |
| 629 if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut. | 613 if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 int Type::UpdateRange(Type* range, UnionType* result, int size, Zone* zone) { | 671 int Type::UpdateRange(Type* range, UnionType* result, int size, Zone* zone) { |
| 688 if (size == 1) { | 672 if (size == 1) { |
| 689 result->Set(size++, range); | 673 result->Set(size++, range); |
| 690 } else { | 674 } else { |
| 691 // Make space for the range. | 675 // Make space for the range. |
| 692 result->Set(size++, result->Get(1)); | 676 result->Set(size++, result->Get(1)); |
| 693 result->Set(1, range); | 677 result->Set(1, range); |
| 694 } | 678 } |
| 695 | 679 |
| 696 // Remove any components that just got subsumed. | 680 // Remove any components that just got subsumed. |
| 697 for (int i = 2; i < size; ) { | 681 for (int i = 2; i < size;) { |
| 698 if (result->Get(i)->SemanticIs(range)) { | 682 if (result->Get(i)->SemanticIs(range)) { |
| 699 result->Set(i, result->Get(--size)); | 683 result->Set(i, result->Get(--size)); |
| 700 } else { | 684 } else { |
| 701 ++i; | 685 ++i; |
| 702 } | 686 } |
| 703 } | 687 } |
| 704 return size; | 688 return size; |
| 705 } | 689 } |
| 706 | 690 |
| 707 RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) { | 691 RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 } | 754 } |
| 771 if (lhs->IsBitset() || rhs->IsBitset()) { | 755 if (lhs->IsBitset() || rhs->IsBitset()) { |
| 772 return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone); | 756 return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone); |
| 773 } | 757 } |
| 774 if (lhs->SimplyEquals(rhs)) { | 758 if (lhs->SimplyEquals(rhs)) { |
| 775 return AddToUnion(lhs, result, size, zone); | 759 return AddToUnion(lhs, result, size, zone); |
| 776 } | 760 } |
| 777 return size; | 761 return size; |
| 778 } | 762 } |
| 779 | 763 |
| 780 | |
| 781 // Make sure that we produce a well-formed range and bitset: | 764 // Make sure that we produce a well-formed range and bitset: |
| 782 // If the range is non-empty, the number bits in the bitset should be | 765 // If the range is non-empty, the number bits in the bitset should be |
| 783 // clear. Moreover, if we have a canonical range (such as Signed32), | 766 // clear. Moreover, if we have a canonical range (such as Signed32), |
| 784 // we want to produce a bitset rather than a range. | 767 // we want to produce a bitset rather than a range. |
| 785 Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) { | 768 Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) { |
| 786 // Fast path: If the bitset does not mention numbers, we can just keep the | 769 // Fast path: If the bitset does not mention numbers, we can just keep the |
| 787 // range. | 770 // range. |
| 788 bitset number_bits = BitsetType::NumberBits(*bits); | 771 bitset number_bits = BitsetType::NumberBits(*bits); |
| 789 if (number_bits == 0) { | 772 if (number_bits == 0) { |
| 790 return range; | 773 return range; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 876 new_bitset = SEMANTIC(new_bitset) | representation; | 859 new_bitset = SEMANTIC(new_bitset) | representation; |
| 877 Type* bits = BitsetType::New(new_bitset); | 860 Type* bits = BitsetType::New(new_bitset); |
| 878 result->Set(size++, bits); | 861 result->Set(size++, bits); |
| 879 if (!range->IsNone()) result->Set(size++, range); | 862 if (!range->IsNone()) result->Set(size++, range); |
| 880 | 863 |
| 881 size = AddToUnion(type1, result, size, zone); | 864 size = AddToUnion(type1, result, size, zone); |
| 882 size = AddToUnion(type2, result, size, zone); | 865 size = AddToUnion(type2, result, size, zone); |
| 883 return NormalizeUnion(result_type, size, zone); | 866 return NormalizeUnion(result_type, size, zone); |
| 884 } | 867 } |
| 885 | 868 |
| 886 | |
| 887 // Add [type] to [result] unless [type] is bitset, range, or already subsumed. | 869 // Add [type] to [result] unless [type] is bitset, range, or already subsumed. |
| 888 // Return new size of [result]. | 870 // Return new size of [result]. |
| 889 int Type::AddToUnion(Type* type, UnionType* result, int size, Zone* zone) { | 871 int Type::AddToUnion(Type* type, UnionType* result, int size, Zone* zone) { |
| 890 if (type->IsBitset() || type->IsRange()) return size; | 872 if (type->IsBitset() || type->IsRange()) return size; |
| 891 if (type->IsUnion()) { | 873 if (type->IsUnion()) { |
| 892 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { | 874 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { |
| 893 size = AddToUnion(type->AsUnion()->Get(i), result, size, zone); | 875 size = AddToUnion(type->AsUnion()->Get(i), result, size, zone); |
| 894 } | 876 } |
| 895 return size; | 877 return size; |
| 896 } | 878 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 920 return RangeType::New(unioned->Get(1)->AsRange()->Min(), | 902 return RangeType::New(unioned->Get(1)->AsRange()->Min(), |
| 921 unioned->Get(1)->AsRange()->Max(), | 903 unioned->Get(1)->AsRange()->Max(), |
| 922 unioned->Get(0)->AsBitset(), zone); | 904 unioned->Get(0)->AsBitset(), zone); |
| 923 } | 905 } |
| 924 } | 906 } |
| 925 unioned->Shrink(size); | 907 unioned->Shrink(size); |
| 926 SLOW_DCHECK(unioned->Wellformed()); | 908 SLOW_DCHECK(unioned->Wellformed()); |
| 927 return union_type; | 909 return union_type; |
| 928 } | 910 } |
| 929 | 911 |
| 930 | |
| 931 // ----------------------------------------------------------------------------- | 912 // ----------------------------------------------------------------------------- |
| 932 // Component extraction | 913 // Component extraction |
| 933 | 914 |
| 934 // static | 915 // static |
| 935 Type* Type::Representation(Type* t, Zone* zone) { | 916 Type* Type::Representation(Type* t, Zone* zone) { |
| 936 return BitsetType::New(t->Representation()); | 917 return BitsetType::New(t->Representation()); |
| 937 } | 918 } |
| 938 | 919 |
| 939 | |
| 940 // static | 920 // static |
| 941 Type* Type::Semantic(Type* t, Zone* zone) { | 921 Type* Type::Semantic(Type* t, Zone* zone) { |
| 942 return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone); | 922 return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone); |
| 943 } | 923 } |
| 944 | 924 |
| 945 | |
| 946 // ----------------------------------------------------------------------------- | 925 // ----------------------------------------------------------------------------- |
| 947 // Iteration. | 926 // Iteration. |
| 948 | 927 |
| 949 int Type::NumConstants() { | 928 int Type::NumConstants() { |
| 950 DisallowHeapAllocation no_allocation; | 929 DisallowHeapAllocation no_allocation; |
| 951 if (this->IsConstant()) { | 930 if (this->IsConstant()) { |
| 952 return 1; | 931 return 1; |
| 953 } else if (this->IsUnion()) { | 932 } else if (this->IsUnion()) { |
| 954 int result = 0; | 933 int result = 0; |
| 955 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 934 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
| 956 if (this->AsUnion()->Get(i)->IsConstant()) ++result; | 935 if (this->AsUnion()->Get(i)->IsConstant()) ++result; |
| 957 } | 936 } |
| 958 return result; | 937 return result; |
| 959 } else { | 938 } else { |
| 960 return 0; | 939 return 0; |
| 961 } | 940 } |
| 962 } | 941 } |
| 963 | 942 |
| 964 template <class T> | 943 template <class T> |
| 965 Type* Type::Iterator<T>::get_type() { | 944 Type* Type::Iterator<T>::get_type() { |
| 966 DCHECK(!Done()); | 945 DCHECK(!Done()); |
| 967 return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_; | 946 return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_; |
| 968 } | 947 } |
| 969 | 948 |
| 970 | |
| 971 // C++ cannot specialise nested templates, so we have to go through this | 949 // C++ cannot specialise nested templates, so we have to go through this |
| 972 // contortion with an auxiliary template to simulate it. | 950 // contortion with an auxiliary template to simulate it. |
| 973 template <class T> | 951 template <class T> |
| 974 struct TypeImplIteratorAux { | 952 struct TypeImplIteratorAux { |
| 975 static bool matches(Type* type); | 953 static bool matches(Type* type); |
| 976 static i::Handle<T> current(Type* type); | 954 static i::Handle<T> current(Type* type); |
| 977 }; | 955 }; |
| 978 | 956 |
| 979 template <> | 957 template <> |
| 980 struct TypeImplIteratorAux<i::Object> { | 958 struct TypeImplIteratorAux<i::Object> { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1001 if (type_->IsUnion()) { | 979 if (type_->IsUnion()) { |
| 1002 for (int n = type_->AsUnion()->Length(); index_ < n; ++index_) { | 980 for (int n = type_->AsUnion()->Length(); index_ < n; ++index_) { |
| 1003 if (matches(type_->AsUnion()->Get(index_))) return; | 981 if (matches(type_->AsUnion()->Get(index_))) return; |
| 1004 } | 982 } |
| 1005 } else if (index_ == 0 && matches(type_)) { | 983 } else if (index_ == 0 && matches(type_)) { |
| 1006 return; | 984 return; |
| 1007 } | 985 } |
| 1008 index_ = -1; | 986 index_ = -1; |
| 1009 } | 987 } |
| 1010 | 988 |
| 1011 | |
| 1012 // ----------------------------------------------------------------------------- | 989 // ----------------------------------------------------------------------------- |
| 1013 // Printing. | 990 // Printing. |
| 1014 | 991 |
| 1015 const char* BitsetType::Name(bitset bits) { | 992 const char* BitsetType::Name(bitset bits) { |
| 1016 switch (bits) { | 993 switch (bits) { |
| 1017 case REPRESENTATION(kAny): return "Any"; | 994 case REPRESENTATION(kAny): |
| 1018 #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ | 995 return "Any"; |
| 1019 case REPRESENTATION(k##type): return #type; | 996 #define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \ |
| 1020 REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE) | 997 case REPRESENTATION(k##type): \ |
| 1021 #undef RETURN_NAMED_REPRESENTATION_TYPE | 998 return #type; |
| 999 REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE) |
| 1000 #undef RETURN_NAMED_REPRESENTATION_TYPE |
| 1022 | 1001 |
| 1023 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ | 1002 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ |
| 1024 case SEMANTIC(k##type): return #type; | 1003 case SEMANTIC(k##type): \ |
| 1025 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 1004 return #type; |
| 1026 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 1005 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
| 1027 #undef RETURN_NAMED_SEMANTIC_TYPE | 1006 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
| 1007 #undef RETURN_NAMED_SEMANTIC_TYPE |
| 1028 | 1008 |
| 1029 default: | 1009 default: |
| 1030 return NULL; | 1010 return NULL; |
| 1031 } | 1011 } |
| 1032 } | 1012 } |
| 1033 | 1013 |
| 1034 void BitsetType::Print(std::ostream& os, // NOLINT | 1014 void BitsetType::Print(std::ostream& os, // NOLINT |
| 1035 bitset bits) { | 1015 bitset bits) { |
| 1036 DisallowHeapAllocation no_allocation; | 1016 DisallowHeapAllocation no_allocation; |
| 1037 const char* name = Name(bits); | 1017 const char* name = Name(bits); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 } else { | 1081 } else { |
| 1102 UNREACHABLE(); | 1082 UNREACHABLE(); |
| 1103 } | 1083 } |
| 1104 } | 1084 } |
| 1105 if (dim == BOTH_DIMS) os << "/"; | 1085 if (dim == BOTH_DIMS) os << "/"; |
| 1106 if (dim != SEMANTIC_DIM) { | 1086 if (dim != SEMANTIC_DIM) { |
| 1107 BitsetType::Print(os, REPRESENTATION(this->BitsetLub())); | 1087 BitsetType::Print(os, REPRESENTATION(this->BitsetLub())); |
| 1108 } | 1088 } |
| 1109 } | 1089 } |
| 1110 | 1090 |
| 1111 | |
| 1112 #ifdef DEBUG | 1091 #ifdef DEBUG |
| 1113 void Type::Print() { | 1092 void Type::Print() { |
| 1114 OFStream os(stdout); | 1093 OFStream os(stdout); |
| 1115 PrintTo(os); | 1094 PrintTo(os); |
| 1116 os << std::endl; | 1095 os << std::endl; |
| 1117 } | 1096 } |
| 1118 void BitsetType::Print(bitset bits) { | 1097 void BitsetType::Print(bitset bits) { |
| 1119 OFStream os(stdout); | 1098 OFStream os(stdout); |
| 1120 Print(os, bits); | 1099 Print(os, bits); |
| 1121 os << std::endl; | 1100 os << std::endl; |
| 1122 } | 1101 } |
| 1123 #endif | 1102 #endif |
| 1124 | 1103 |
| 1125 BitsetType::bitset BitsetType::SignedSmall() { | 1104 BitsetType::bitset BitsetType::SignedSmall() { |
| 1126 return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32; | 1105 return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32; |
| 1127 } | 1106 } |
| 1128 | 1107 |
| 1129 BitsetType::bitset BitsetType::UnsignedSmall() { | 1108 BitsetType::bitset BitsetType::UnsignedSmall() { |
| 1130 return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31; | 1109 return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31; |
| 1131 } | 1110 } |
| 1132 | 1111 |
| 1133 // ----------------------------------------------------------------------------- | 1112 // ----------------------------------------------------------------------------- |
| 1134 // Instantiations. | 1113 // Instantiations. |
| 1135 | 1114 |
| 1136 template class Type::Iterator<i::Object>; | 1115 template class Type::Iterator<i::Object>; |
| 1137 | 1116 |
| 1138 } // namespace internal | 1117 } // namespace internal |
| 1139 } // namespace v8 | 1118 } // namespace v8 |
| OLD | NEW |