| 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 | 
|---|