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 |