types.cc 33.4 KB
Newer Older
1 2 3
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5
#include <iomanip>
6

7
#include "src/compiler/types.h"
8

9
#include "src/handles-inl.h"
10
#include "src/objects-inl.h"
11
#include "src/ostreams.h"
12 13 14

namespace v8 {
namespace internal {
15
namespace compiler {
16

17 18
// NOTE: If code is marked as being a "shortcut", this means that removing
// the code won't affect the semantics of the surrounding function definition.
19

20 21 22 23
// static
bool Type::IsInteger(i::Object* x) {
  return x->IsNumber() && Type::IsInteger(x->Number());
}
24

25 26
// -----------------------------------------------------------------------------
// Range-related helper functions.
27

28
bool RangeType::Limits::IsEmpty() { return this->min > this->max; }
29

30
RangeType::Limits RangeType::Limits::Intersect(Limits lhs, Limits rhs) {
31 32
  DisallowHeapAllocation no_allocation;
  Limits result(lhs);
33 34
  if (lhs.min < rhs.min) result.min = rhs.min;
  if (lhs.max > rhs.max) result.max = rhs.max;
35
  return result;
36 37
}

38
RangeType::Limits RangeType::Limits::Union(Limits lhs, Limits rhs) {
39
  DisallowHeapAllocation no_allocation;
40 41
  if (lhs.IsEmpty()) return rhs;
  if (rhs.IsEmpty()) return lhs;
42
  Limits result(lhs);
43 44
  if (lhs.min > rhs.min) result.min = rhs.min;
  if (lhs.max < rhs.max) result.max = rhs.max;
45
  return result;
46 47
}

48
bool Type::Overlap(RangeType* lhs, RangeType* rhs) {
49
  DisallowHeapAllocation no_allocation;
50 51 52
  return !RangeType::Limits::Intersect(RangeType::Limits(lhs),
                                       RangeType::Limits(rhs))
              .IsEmpty();
53 54
}

55
bool Type::Contains(RangeType* lhs, RangeType* rhs) {
56
  DisallowHeapAllocation no_allocation;
57
  return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
58 59
}

60
bool Type::Contains(RangeType* range, i::Object* val) {
61
  DisallowHeapAllocation no_allocation;
62 63
  return IsInteger(val) && range->Min() <= val->Number() &&
         val->Number() <= range->Max();
64 65
}

66 67 68
// -----------------------------------------------------------------------------
// Min and Max computation.

69
double Type::Min() {
70
  DCHECK(this->Is(Number()));
71 72
  if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
  if (this->IsUnion()) {
73
    double min = +V8_INFINITY;
74
    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
75 76 77 78
      min = std::min(min, this->AsUnion()->Get(i)->Min());
    }
    return min;
  }
79
  if (this->IsRange()) return this->AsRange()->Min();
80 81
  if (this->IsOtherNumberConstant())
    return this->AsOtherNumberConstant()->Value();
82 83
  UNREACHABLE();
  return 0;
84 85
}

86
double Type::Max() {
87
  DCHECK(this->Is(Number()));
88 89
  if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
  if (this->IsUnion()) {
90
    double max = -V8_INFINITY;
91
    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
92 93 94 95
      max = std::max(max, this->AsUnion()->Get(i)->Max());
    }
    return max;
  }
96
  if (this->IsRange()) return this->AsRange()->Max();
97 98
  if (this->IsOtherNumberConstant())
    return this->AsOtherNumberConstant()->Value();
99 100
  UNREACHABLE();
  return 0;
101 102
}

103 104 105 106
// -----------------------------------------------------------------------------
// Glb and lub computation.

// The largest bitset subsumed by this type.
107
Type::bitset BitsetType::Glb(Type* type) {
108
  DisallowHeapAllocation no_allocation;
109
  // Fast case.
110
  if (IsBitset(type)) {
111 112 113
    return type->AsBitset();
  } else if (type->IsUnion()) {
    SLOW_DCHECK(type->AsUnion()->Wellformed());
114
    return type->AsUnion()->Get(0)->BitsetGlb() |
115
           type->AsUnion()->Get(1)->BitsetGlb();  // Shortcut.
116
  } else if (type->IsRange()) {
117 118 119
    bitset glb =
        BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max());
    return glb;
120
  } else {
121
    return kNone;
122
  }
123 124
}

125
// The smallest bitset subsuming this type, possibly not a proper one.
126
Type::bitset BitsetType::Lub(Type* type) {
127
  DisallowHeapAllocation no_allocation;
128
  if (IsBitset(type)) return type->AsBitset();
129
  if (type->IsUnion()) {
130 131 132
    // Take the representation from the first element, which is always
    // a bitset.
    int bitset = type->AsUnion()->Get(0)->BitsetLub();
133
    for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
134
      // Other elements only contribute their semantic part.
135
      bitset |= type->AsUnion()->Get(i)->BitsetLub();
136 137
    }
    return bitset;
138
  }
139 140 141
  if (type->IsHeapConstant()) return type->AsHeapConstant()->Lub();
  if (type->IsOtherNumberConstant())
    return type->AsOtherNumberConstant()->Lub();
142
  if (type->IsRange()) return type->AsRange()->Lub();
143
  if (type->IsTuple()) return kOtherInternal;
144 145
  UNREACHABLE();
  return kNone;
146 147
}

148
Type::bitset BitsetType::Lub(i::Map* map) {
149
  DisallowHeapAllocation no_allocation;
150 151
  switch (map->instance_type()) {
    case STRING_TYPE:
152
    case ONE_BYTE_STRING_TYPE:
153
    case CONS_STRING_TYPE:
154
    case CONS_ONE_BYTE_STRING_TYPE:
155 156
    case THIN_STRING_TYPE:
    case THIN_ONE_BYTE_STRING_TYPE:
157
    case SLICED_STRING_TYPE:
158
    case SLICED_ONE_BYTE_STRING_TYPE:
159
    case EXTERNAL_STRING_TYPE:
160
    case EXTERNAL_ONE_BYTE_STRING_TYPE:
161 162
    case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
    case SHORT_EXTERNAL_STRING_TYPE:
163
    case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE:
164
    case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
165
      return kOtherString;
166
    case INTERNALIZED_STRING_TYPE:
167
    case ONE_BYTE_INTERNALIZED_STRING_TYPE:
168
    case EXTERNAL_INTERNALIZED_STRING_TYPE:
169
    case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
170 171
    case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
    case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
172
    case SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
173
    case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
174
      return kInternalizedString;
175 176
    case SYMBOL_TYPE:
      return kSymbol;
177 178 179 180 181
    case ODDBALL_TYPE: {
      Heap* heap = map->GetHeap();
      if (map == heap->undefined_map()) return kUndefined;
      if (map == heap->null_map()) return kNull;
      if (map == heap->boolean_map()) return kBoolean;
182 183
      if (map == heap->the_hole_map()) return kHole;
      DCHECK(map == heap->uninitialized_map() ||
184
             map == heap->no_interceptor_result_sentinel_map() ||
185
             map == heap->termination_exception_map() ||
186
             map == heap->arguments_marker_map() ||
187 188
             map == heap->optimized_out_map() ||
             map == heap->stale_register_map());
189
      return kOtherInternal;
190
    }
191
    case HEAP_NUMBER_TYPE:
192
      return kNumber;
193
    case SIMD128_VALUE_TYPE:
194
      return kSimd;
195
    case JS_OBJECT_TYPE:
196 197
    case JS_ARGUMENTS_TYPE:
    case JS_ERROR_TYPE:
198 199
    case JS_GLOBAL_OBJECT_TYPE:
    case JS_GLOBAL_PROXY_TYPE:
200
    case JS_API_OBJECT_TYPE:
201
    case JS_SPECIAL_API_OBJECT_TYPE:
202 203 204 205 206 207 208 209 210 211 212
      if (map->is_undetectable()) {
        // Currently we assume that every undetectable receiver is also
        // callable, which is what we need to support document.all.  We
        // could add another Type bit to support other use cases in the
        // future if necessary.
        DCHECK(map->is_callable());
        return kOtherUndetectable;
      }
      if (map->is_callable()) {
        return kOtherCallable;
      }
213
      return kOtherObject;
214
    case JS_VALUE_TYPE:
215
    case JS_MESSAGE_OBJECT_TYPE:
216 217 218
    case JS_DATE_TYPE:
    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    case JS_GENERATOR_OBJECT_TYPE:
219
    case JS_MODULE_NAMESPACE_TYPE:
220
    case JS_ARRAY_BUFFER_TYPE:
221
    case JS_ARRAY_TYPE:
222
    case JS_REGEXP_TYPE:  // TODO(rossberg): there should be a RegExp type.
223 224 225 226
    case JS_TYPED_ARRAY_TYPE:
    case JS_DATA_VIEW_TYPE:
    case JS_SET_TYPE:
    case JS_MAP_TYPE:
227 228
    case JS_SET_ITERATOR_TYPE:
    case JS_MAP_ITERATOR_TYPE:
229
    case JS_STRING_ITERATOR_TYPE:
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266

    case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
    case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
    case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
    case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
    case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:

267 268
    case JS_WEAK_MAP_TYPE:
    case JS_WEAK_SET_TYPE:
269
    case JS_PROMISE_CAPABILITY_TYPE:
270
    case JS_PROMISE_TYPE:
271
      DCHECK(!map->is_callable());
272
      DCHECK(!map->is_undetectable());
273
      return kOtherObject;
274 275 276
    case JS_BOUND_FUNCTION_TYPE:
      DCHECK(!map->is_undetectable());
      return kBoundFunction;
277
    case JS_FUNCTION_TYPE:
278
      DCHECK(!map->is_undetectable());
279
      return kFunction;
280
    case JS_PROXY_TYPE:
281
      DCHECK(!map->is_undetectable());
282 283
      if (map->is_callable()) return kCallableProxy;
      return kOtherProxy;
284
    case MAP_TYPE:
285
    case ALLOCATION_SITE_TYPE:
286
    case ACCESSOR_INFO_TYPE:
287
    case SHARED_FUNCTION_INFO_TYPE:
288
    case FUNCTION_TEMPLATE_INFO_TYPE:
289 290
    case ACCESSOR_PAIR_TYPE:
    case FIXED_ARRAY_TYPE:
291
    case FIXED_DOUBLE_ARRAY_TYPE:
292
    case BYTE_ARRAY_TYPE:
293
    case BYTECODE_ARRAY_TYPE:
294
    case TRANSITION_ARRAY_TYPE:
295
    case FOREIGN_TYPE:
296
    case SCRIPT_TYPE:
297
    case CODE_TYPE:
298
    case PROPERTY_CELL_TYPE:
299
    case MODULE_TYPE:
300
    case MODULE_INFO_ENTRY_TYPE:
301
      return kOtherInternal;
302 303

    // Remaining instance types are unsupported for now. If any of them do
304
    // require bit set types, they should get kOtherInternal.
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
    case MUTABLE_HEAP_NUMBER_TYPE:
    case FREE_SPACE_TYPE:
#define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
  case FIXED_##TYPE##_ARRAY_TYPE:

      TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
#undef FIXED_TYPED_ARRAY_CASE
    case FILLER_TYPE:
    case ACCESS_CHECK_INFO_TYPE:
    case INTERCEPTOR_INFO_TYPE:
    case CALL_HANDLER_INFO_TYPE:
    case OBJECT_TEMPLATE_INFO_TYPE:
    case ALLOCATION_MEMENTO_TYPE:
    case TYPE_FEEDBACK_INFO_TYPE:
    case ALIASED_ARGUMENTS_ENTRY_TYPE:
    case BOX_TYPE:
321
    case PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE:
322
    case PROMISE_REACTION_JOB_INFO_TYPE:
323 324 325 326 327
    case DEBUG_INFO_TYPE:
    case BREAK_POINT_INFO_TYPE:
    case CELL_TYPE:
    case WEAK_CELL_TYPE:
    case PROTOTYPE_INFO_TYPE:
328
    case TUPLE2_TYPE:
329
    case TUPLE3_TYPE:
330
    case CONTEXT_EXTENSION_TYPE:
331
    case CONSTANT_ELEMENTS_PAIR_TYPE:
332 333
      UNREACHABLE();
      return kNone;
334
  }
335 336
  UNREACHABLE();
  return kNone;
337 338
}

339
Type::bitset BitsetType::Lub(i::Object* value) {
340 341
  DisallowHeapAllocation no_allocation;
  if (value->IsNumber()) {
342
    return Lub(value->Number());
343 344 345 346
  }
  return Lub(i::HeapObject::cast(value)->map());
}

347
Type::bitset BitsetType::Lub(double value) {
348
  DisallowHeapAllocation no_allocation;
349 350
  if (i::IsMinusZero(value)) return kMinusZero;
  if (std::isnan(value)) return kNaN;
351
  if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
352
  return kOtherNumber;
353
}
354

355
// Minimum values of plain numeric bitsets.
356 357 358 359 360 361 362 363 364 365 366 367
const BitsetType::Boundary BitsetType::BoundariesArray[] = {
    {kOtherNumber, kPlainNumber, -V8_INFINITY},
    {kOtherSigned32, kNegative32, kMinInt},
    {kNegative31, kNegative31, -0x40000000},
    {kUnsigned30, kUnsigned30, 0},
    {kOtherUnsigned31, kUnsigned31, 0x40000000},
    {kOtherUnsigned32, kUnsigned32, 0x80000000},
    {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};

const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; }

size_t BitsetType::BoundariesSize() {
368 369 370 371
  // Windows doesn't like arraysize here.
  // return arraysize(BoundariesArray);
  return 7;
}
372

373
Type::bitset BitsetType::ExpandInternals(Type::bitset bits) {
374
  DisallowHeapAllocation no_allocation;
375
  if (!(bits & kPlainNumber)) return bits;  // Shortcut.
376 377 378
  const Boundary* boundaries = Boundaries();
  for (size_t i = 0; i < BoundariesSize(); ++i) {
    DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external));
379
    if (bits & boundaries[i].internal) bits |= boundaries[i].external;
380 381 382 383
  }
  return bits;
}

384
Type::bitset BitsetType::Lub(double min, double max) {
385 386
  DisallowHeapAllocation no_allocation;
  int lub = kNone;
387
  const Boundary* mins = Boundaries();
388

389
  for (size_t i = 1; i < BoundariesSize(); ++i) {
390
    if (min < mins[i].min) {
391
      lub |= mins[i - 1].internal;
392 393 394
      if (max < mins[i].min) return lub;
    }
  }
395
  return lub | mins[BoundariesSize() - 1].internal;
396 397
}

398
Type::bitset BitsetType::NumberBits(bitset bits) { return bits & kPlainNumber; }
399

400
Type::bitset BitsetType::Glb(double min, double max) {
401 402 403 404 405 406 407 408 409 410
  DisallowHeapAllocation no_allocation;
  int glb = kNone;
  const Boundary* mins = Boundaries();

  // If the range does not touch 0, the bound is empty.
  if (max < -1 || min > 0) return glb;

  for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
    if (min <= mins[i].min) {
      if (max + 1 < mins[i + 1].min) break;
411
      glb |= mins[i].external;
412 413 414
    }
  }
  // OtherNumber also contains float numbers, so it can never be
415
  // in the greatest lower bound.
416
  return glb & ~(kOtherNumber);
417 418
}

419
double BitsetType::Min(bitset bits) {
420
  DisallowHeapAllocation no_allocation;
421
  DCHECK(Is(bits, kNumber));
422
  const Boundary* mins = Boundaries();
423
  bool mz = bits & kMinusZero;
424
  for (size_t i = 0; i < BoundariesSize(); ++i) {
425
    if (Is(mins[i].internal, bits)) {
426 427
      return mz ? std::min(0.0, mins[i].min) : mins[i].min;
    }
428
  }
429
  if (mz) return 0;
430
  return std::numeric_limits<double>::quiet_NaN();
431 432
}

433
double BitsetType::Max(bitset bits) {
434
  DisallowHeapAllocation no_allocation;
435
  DCHECK(Is(bits, kNumber));
436
  const Boundary* mins = Boundaries();
437 438
  bool mz = bits & kMinusZero;
  if (BitsetType::Is(mins[BoundariesSize() - 1].internal, bits)) {
439
    return +V8_INFINITY;
440
  }
441
  for (size_t i = BoundariesSize() - 1; i-- > 0;) {
442
    if (Is(mins[i].internal, bits)) {
443
      return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1;
444
    }
445
  }
446
  if (mz) return 0;
447
  return std::numeric_limits<double>::quiet_NaN();
448 449
}

450 451 452 453 454 455 456 457 458 459 460 461 462 463
// static
bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
  // Not an integer, not NaN, and not -0.
  return !std::isnan(value) && !Type::IsInteger(value) &&
         !i::IsMinusZero(value);
}

// static
bool OtherNumberConstantType::IsOtherNumberConstant(Object* value) {
  return value->IsHeapNumber() &&
         IsOtherNumberConstant(HeapNumber::cast(value)->value());
}

HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
464
                                   i::Handle<i::HeapObject> object)
465
    : TypeBase(kHeapConstant), bitset_(bitset), object_(object) {
466
  DCHECK(!object->IsHeapNumber());
467
  DCHECK_IMPLIES(object->IsString(), object->IsInternalizedString());
468 469
}

470 471 472
// -----------------------------------------------------------------------------
// Predicates.

473
bool Type::SimplyEquals(Type* that) {
474
  DisallowHeapAllocation no_allocation;
475 476
  if (this->IsHeapConstant()) {
    return that->IsHeapConstant() &&
477 478
           this->AsHeapConstant()->Value().address() ==
               that->AsHeapConstant()->Value().address();
479 480 481 482 483 484 485 486
  }
  if (this->IsOtherNumberConstant()) {
    return that->IsOtherNumberConstant() &&
           this->AsOtherNumberConstant()->Value() ==
               that->AsOtherNumberConstant()->Value();
  }
  if (this->IsRange()) {
    if (that->IsHeapConstant() || that->IsOtherNumberConstant()) return false;
487
  }
488 489 490 491 492 493 494 495 496 497 498 499
  if (this->IsTuple()) {
    if (!that->IsTuple()) return false;
    TupleType* this_tuple = this->AsTuple();
    TupleType* that_tuple = that->AsTuple();
    if (this_tuple->Arity() != that_tuple->Arity()) {
      return false;
    }
    for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
      if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false;
    }
    return true;
  }
500 501 502 503 504
  UNREACHABLE();
  return false;
}

// Check if [this] <= [that].
505
bool Type::SlowIs(Type* that) {
506
  DisallowHeapAllocation no_allocation;
507

508
  // Fast bitset cases
509 510 511
  if (that->IsBitset()) {
    return BitsetType::Is(this->BitsetLub(), that->AsBitset());
  }
512

513 514 515 516 517
  if (this->IsBitset()) {
    return BitsetType::Is(this->AsBitset(), that->BitsetGlb());
  }

  // (T1 \/ ... \/ Tn) <= T  if  (T1 <= T) /\ ... /\ (Tn <= T)
518
  if (this->IsUnion()) {
519
    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
520
      if (!this->AsUnion()->Get(i)->Is(that)) return false;
521 522 523 524
    }
    return true;
  }

525 526
  // T <= (T1 \/ ... \/ Tn)  if  (T <= T1) \/ ... \/ (T <= Tn)
  if (that->IsUnion()) {
527
    for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
528
      if (this->Is(that->AsUnion()->Get(i))) return true;
529 530 531
      if (i > 1 && this->IsRange()) return false;  // Shortcut.
    }
    return false;
532
  }
533 534

  if (that->IsRange()) {
535
    return (this->IsRange() && Contains(that->AsRange(), this->AsRange()));
536 537
  }
  if (this->IsRange()) return false;
538

539
  return this->SimplyEquals(that);
540 541
}

542
// Check if [this] and [that] overlap.
543
bool Type::Maybe(Type* that) {
544 545
  DisallowHeapAllocation no_allocation;

546 547 548
  if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub()))
    return false;

549
  // (T1 \/ ... \/ Tn) overlaps T  if  (T1 overlaps T) \/ ... \/ (Tn overlaps T)
550
  if (this->IsUnion()) {
551
    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
552
      if (this->AsUnion()->Get(i)->Maybe(that)) return true;
553 554 555 556
    }
    return false;
  }

557
  // T overlaps (T1 \/ ... \/ Tn)  if  (T overlaps T1) \/ ... \/ (T overlaps Tn)
558
  if (that->IsUnion()) {
559
    for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
560
      if (this->Maybe(that->AsUnion()->Get(i))) return true;
561 562 563 564
    }
    return false;
  }

565
  if (this->IsBitset() && that->IsBitset()) return true;
566 567

  if (this->IsRange()) {
568 569 570 571 572 573 574 575 576 577 578
    if (that->IsRange()) {
      return Overlap(this->AsRange(), that->AsRange());
    }
    if (that->IsBitset()) {
      bitset number_bits = BitsetType::NumberBits(that->AsBitset());
      if (number_bits == BitsetType::kNone) {
        return false;
      }
      double min = std::max(BitsetType::Min(number_bits), this->Min());
      double max = std::min(BitsetType::Max(number_bits), this->Max());
      return min <= max;
579
    }
580
  }
581
  if (that->IsRange()) {
582
    return that->Maybe(this);  // This case is handled above.
583 584
  }

585 586
  if (this->IsBitset() || that->IsBitset()) return true;

587
  return this->SimplyEquals(that);
588 589
}

590
// Return the range in [this], or [NULL].
591
Type* Type::GetRange() {
592
  DisallowHeapAllocation no_allocation;
593
  if (this->IsRange()) return this;
594
  if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) {
595
    return this->AsUnion()->Get(1);
596
  }
597 598 599
  return NULL;
}

600
bool UnionType::Wellformed() {
601 602 603
  DisallowHeapAllocation no_allocation;
  // This checks the invariants of the union representation:
  // 1. There are at least two elements.
604 605
  // 2. The first element is a bitset, no other element is a bitset.
  // 3. At most one element is a range, and it must be the second one.
606
  // 4. No element is itself a union.
607
  // 5. No element (except the bitset) is a subtype of any other.
608 609
  // 6. If there is a range, then the bitset type does not contain
  //    plain number bits.
610
  DCHECK(this->Length() >= 2);       // (1)
611
  DCHECK(this->Get(0)->IsBitset());  // (2a)
612

613
  for (int i = 0; i < this->Length(); ++i) {
614
    if (i != 0) DCHECK(!this->Get(i)->IsBitset());  // (2b)
615 616
    if (i != 1) DCHECK(!this->Get(i)->IsRange());   // (3)
    DCHECK(!this->Get(i)->IsUnion());               // (4)
617
    for (int j = 0; j < this->Length(); ++j) {
618
      if (i != j && i != 0) DCHECK(!this->Get(i)->Is(this->Get(j)));  // (5)
619 620
    }
  }
621 622 623
  DCHECK(!this->Get(1)->IsRange() ||
         (BitsetType::NumberBits(this->Get(0)->AsBitset()) ==
          BitsetType::kNone));  // (6)
624 625 626 627 628 629
  return true;
}

// -----------------------------------------------------------------------------
// Union and intersection

630
static bool AddIsSafe(int x, int y) {
631 632
  return x >= 0 ? y <= std::numeric_limits<int>::max() - x
                : y >= std::numeric_limits<int>::min() - x;
633 634
}

635
Type* Type::Intersect(Type* type1, Type* type2, Zone* zone) {
636 637
  // Fast case: bit sets.
  if (type1->IsBitset() && type2->IsBitset()) {
638
    return BitsetType::New(type1->AsBitset() & type2->AsBitset());
639
  }
640 641 642 643 644 645 646 647 648 649

  // Fast case: top or bottom types.
  if (type1->IsNone() || type2->IsAny()) return type1;  // Shortcut.
  if (type2->IsNone() || type1->IsAny()) return type2;  // Shortcut.

  // Semi-fast case.
  if (type1->Is(type2)) return type1;
  if (type2->Is(type1)) return type2;

  // Slow case: create union.
650 651

  // Semantic subtyping check - this is needed for consistency with the
652 653
  // semi-fast case above.
  if (type1->Is(type2)) {
654
    type2 = Any();
655
  } else if (type2->Is(type1)) {
656
    type1 = Any();
657 658
  }

659
  bitset bits = type1->BitsetGlb() & type2->BitsetGlb();
660 661
  int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
  int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
662
  if (!AddIsSafe(size1, size2)) return Any();
663
  int size = size1 + size2;
664
  if (!AddIsSafe(size, 2)) return Any();
665
  size += 2;
666 667
  Type* result_type = UnionType::New(size, zone);
  UnionType* result = result_type->AsUnion();
668 669 670
  size = 0;

  // Deal with bitsets.
671
  result->Set(size++, BitsetType::New(bits));
672

673 674
  RangeType::Limits lims = RangeType::Limits::Empty();
  size = IntersectAux(type1, type2, result, size, &lims, zone);
675 676 677

  // If the range is not empty, then insert it into the union and
  // remove the number bits from the bitset.
678
  if (!lims.IsEmpty()) {
679
    size = UpdateRange(RangeType::New(lims, zone), result, size, zone);
680 681 682 683

    // Remove the number bits.
    bitset number_bits = BitsetType::NumberBits(bits);
    bits &= ~number_bits;
684
    result->Set(0, BitsetType::New(bits));
685
  }
686
  return NormalizeUnion(result_type, size, zone);
687 688
}

689
int Type::UpdateRange(Type* range, UnionType* result, int size, Zone* zone) {
690 691 692 693 694 695
  if (size == 1) {
    result->Set(size++, range);
  } else {
    // Make space for the range.
    result->Set(size++, result->Get(1));
    result->Set(1, range);
696 697 698
  }

  // Remove any components that just got subsumed.
699
  for (int i = 2; i < size;) {
700
    if (result->Get(i)->Is(range)) {
701 702 703
      result->Set(i, result->Get(--size));
    } else {
      ++i;
704
    }
705
  }
706
  return size;
707 708
}

709
RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) {
710 711
  bitset number_bits = BitsetType::NumberBits(bits);

712
  if (number_bits == BitsetType::kNone) {
713
    return RangeType::Limits::Empty();
714 715
  }

716 717
  return RangeType::Limits(BitsetType::Min(number_bits),
                           BitsetType::Max(number_bits));
718 719
}

720 721 722 723 724
RangeType::Limits Type::IntersectRangeAndBitset(Type* range, Type* bitset,
                                                Zone* zone) {
  RangeType::Limits range_lims(range->AsRange());
  RangeType::Limits bitset_lims = ToLimits(bitset->AsBitset(), zone);
  return RangeType::Limits::Intersect(range_lims, bitset_lims);
725 726
}

727 728
int Type::IntersectAux(Type* lhs, Type* rhs, UnionType* result, int size,
                       RangeType::Limits* lims, Zone* zone) {
729
  if (lhs->IsUnion()) {
730
    for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) {
731
      size =
732
          IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, lims, zone);
733 734 735 736
    }
    return size;
  }
  if (rhs->IsUnion()) {
737
    for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) {
738
      size =
739
          IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, zone);
740 741
    }
    return size;
742 743
  }

744
  if (!BitsetType::IsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) {
745
    return size;
746 747
  }

748
  if (lhs->IsRange()) {
749
    if (rhs->IsBitset()) {
750
      RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
751

752
      if (!lim.IsEmpty()) {
753
        *lims = RangeType::Limits::Union(lim, *lims);
754 755 756 757
      }
      return size;
    }
    if (rhs->IsRange()) {
758 759
      RangeType::Limits lim = RangeType::Limits::Intersect(
          RangeType::Limits(lhs->AsRange()), RangeType::Limits(rhs->AsRange()));
760
      if (!lim.IsEmpty()) {
761
        *lims = RangeType::Limits::Union(lim, *lims);
762 763
      }
    }
764
    return size;
765
  }
766
  if (rhs->IsRange()) {
767
    // This case is handled symmetrically above.
768
    return IntersectAux(rhs, lhs, result, size, lims, zone);
769
  }
770
  if (lhs->IsBitset() || rhs->IsBitset()) {
771
    return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone);
772
  }
773 774
  if (lhs->SimplyEquals(rhs)) {
    return AddToUnion(lhs, result, size, zone);
775 776
  }
  return size;
777 778
}

779 780
// Make sure that we produce a well-formed range and bitset:
// If the range is non-empty, the number bits in the bitset should be
781
// clear. Moreover, if we have a canonical range (such as Signed32),
782
// we want to produce a bitset rather than a range.
783
Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) {
784 785 786 787 788 789 790
  // Fast path: If the bitset does not mention numbers, we can just keep the
  // range.
  bitset number_bits = BitsetType::NumberBits(*bits);
  if (number_bits == 0) {
    return range;
  }

791 792
  // If the range is semantically contained within the bitset, return None and
  // leave the bitset untouched.
793
  bitset range_lub = range->BitsetLub();
794
  if (BitsetType::Is(range_lub, *bits)) {
795
    return None();
796 797 798 799 800 801
  }

  // Slow path: reconcile the bitset range and the range.
  double bitset_min = BitsetType::Min(number_bits);
  double bitset_max = BitsetType::Max(number_bits);

802 803
  double range_min = range->Min();
  double range_max = range->Max();
804 805

  // Remove the number bits from the bitset, they would just confuse us now.
806 807
  // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
  // case we already returned after the subtype check above.
808 809
  *bits &= ~number_bits;

810
  if (range_min <= bitset_min && range_max >= bitset_max) {
811 812 813 814 815
    // Bitset is contained within the range, just return the range.
    return range;
  }

  if (bitset_min < range_min) {
816
    range_min = bitset_min;
817 818
  }
  if (bitset_max > range_max) {
819
    range_max = bitset_max;
820
  }
821
  return RangeType::New(range_min, range_max, zone);
822 823
}

824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
Type* Type::NewConstant(double value, Zone* zone) {
  if (IsInteger(value)) {
    return Range(value, value, zone);
  } else if (i::IsMinusZero(value)) {
    return Type::MinusZero();
  } else if (std::isnan(value)) {
    return Type::NaN();
  }

  DCHECK(OtherNumberConstantType::IsOtherNumberConstant(value));
  return OtherNumberConstant(value, zone);
}

Type* Type::NewConstant(i::Handle<i::Object> value, Zone* zone) {
  if (IsInteger(*value)) {
    double v = value->Number();
    return Range(v, v, zone);
  } else if (value->IsHeapNumber()) {
    return NewConstant(value->Number(), zone);
843 844
  } else if (value->IsString() && !value->IsInternalizedString()) {
    return Type::OtherString();
845
  }
846
  return HeapConstant(i::Handle<i::HeapObject>::cast(value), zone);
847 848
}

849
Type* Type::Union(Type* type1, Type* type2, Zone* zone) {
850
  // Fast case: bit sets.
851
  if (type1->IsBitset() && type2->IsBitset()) {
852
    return BitsetType::New(type1->AsBitset() | type2->AsBitset());
853 854
  }

855
  // Fast case: top or bottom types.
856 857
  if (type1->IsAny() || type2->IsNone()) return type1;
  if (type2->IsAny() || type1->IsNone()) return type2;
858

859 860 861 862 863 864 865
  // Semi-fast case.
  if (type1->Is(type2)) return type2;
  if (type2->Is(type1)) return type1;

  // Slow case: create union.
  int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
  int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
866
  if (!AddIsSafe(size1, size2)) return Any();
867
  int size = size1 + size2;
868
  if (!AddIsSafe(size, 2)) return Any();
869
  size += 2;
870 871
  Type* result_type = UnionType::New(size, zone);
  UnionType* result = result_type->AsUnion();
872 873
  size = 0;

874
  // Compute the new bitset.
875
  bitset new_bitset = type1->BitsetGlb() | type2->BitsetGlb();
876 877

  // Deal with ranges.
878 879 880
  Type* range = None();
  Type* range1 = type1->GetRange();
  Type* range2 = type2->GetRange();
881
  if (range1 != NULL && range2 != NULL) {
882 883 884
    RangeType::Limits lims =
        RangeType::Limits::Union(RangeType::Limits(range1->AsRange()),
                                 RangeType::Limits(range2->AsRange()));
885
    Type* union_range = RangeType::New(lims, zone);
886
    range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
887
  } else if (range1 != NULL) {
888
    range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
889
  } else if (range2 != NULL) {
890
    range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
891
  }
892
  Type* bits = BitsetType::New(new_bitset);
893
  result->Set(size++, bits);
894
  if (!range->IsNone()) result->Set(size++, range);
895

896 897 898
  size = AddToUnion(type1, result, size, zone);
  size = AddToUnion(type2, result, size, zone);
  return NormalizeUnion(result_type, size, zone);
899 900 901 902
}

// Add [type] to [result] unless [type] is bitset, range, or already subsumed.
// Return new size of [result].
903
int Type::AddToUnion(Type* type, UnionType* result, int size, Zone* zone) {
904 905
  if (type->IsBitset() || type->IsRange()) return size;
  if (type->IsUnion()) {
906
    for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
907
      size = AddToUnion(type->AsUnion()->Get(i), result, size, zone);
908 909
    }
    return size;
910
  }
911
  for (int i = 0; i < size; ++i) {
912
    if (type->Is(result->Get(i))) return size;
913
  }
914 915 916
  result->Set(size++, type);
  return size;
}
917

918 919
Type* Type::NormalizeUnion(Type* union_type, int size, Zone* zone) {
  UnionType* unioned = union_type->AsUnion();
920 921 922 923 924
  DCHECK(size >= 1);
  DCHECK(unioned->Get(0)->IsBitset());
  // If the union has just one element, return it.
  if (size == 1) {
    return unioned->Get(0);
925
  }
926 927
  bitset bits = unioned->Get(0)->AsBitset();
  // If the union only consists of a range, we can get rid of the union.
928
  if (size == 2 && bits == BitsetType::kNone) {
929 930
    if (unioned->Get(1)->IsRange()) {
      return RangeType::New(unioned->Get(1)->AsRange()->Min(),
931
                            unioned->Get(1)->AsRange()->Max(), zone);
932
    }
933
  }
934 935
  unioned->Shrink(size);
  SLOW_DCHECK(unioned->Wellformed());
936
  return union_type;
937 938
}

939
int Type::NumConstants() {
940
  DisallowHeapAllocation no_allocation;
941
  if (this->IsHeapConstant() || this->IsOtherNumberConstant()) {
942 943 944
    return 1;
  } else if (this->IsUnion()) {
    int result = 0;
945
    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
946
      if (this->AsUnion()->Get(i)->IsHeapConstant()) ++result;
947 948 949 950 951 952 953 954 955
    }
    return result;
  } else {
    return 0;
  }
}

// -----------------------------------------------------------------------------
// Printing.
956

957
const char* BitsetType::Name(bitset bits) {
958
  switch (bits) {
959 960
#define RETURN_NAMED_TYPE(type, value) \
  case k##type:                        \
961
    return #type;
962 963 964
    PROPER_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
    INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
#undef RETURN_NAMED_TYPE
965

966 967 968 969 970
    default:
      return NULL;
  }
}

971 972
void BitsetType::Print(std::ostream& os,  // NOLINT
                       bitset bits) {
973
  DisallowHeapAllocation no_allocation;
974
  const char* name = Name(bits);
975
  if (name != NULL) {
976 977 978 979
    os << name;
    return;
  }

980
  // clang-format off
981
  static const bitset named_bitsets[] = {
982
#define BITSET_CONSTANT(type, value) k##type,
983
    INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
984
    PROPER_BITSET_TYPE_LIST(BITSET_CONSTANT)
985 986
#undef BITSET_CONSTANT
  };
987
  // clang-format on
988 989 990

  bool is_first = true;
  os << "(";
991 992 993
  for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
    bitset subset = named_bitsets[i];
    if ((bits & subset) == subset) {
994 995 996
      if (!is_first) os << " | ";
      is_first = false;
      os << Name(subset);
997
      bits -= subset;
998 999
    }
  }
1000
  DCHECK(bits == 0);
1001
  os << ")";
1002 1003
}

1004
void Type::PrintTo(std::ostream& os) {
1005
  DisallowHeapAllocation no_allocation;
1006 1007
  if (this->IsBitset()) {
    BitsetType::Print(os, this->AsBitset());
1008 1009 1010 1011 1012
  } else if (this->IsHeapConstant()) {
    os << "HeapConstant(" << Brief(*this->AsHeapConstant()->Value()) << ")";
  } else if (this->IsOtherNumberConstant()) {
    os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value()
       << ")";
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
  } else if (this->IsRange()) {
    std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
    std::streamsize saved_precision = os.precision(0);
    os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
       << ")";
    os.flags(saved_flags);
    os.precision(saved_precision);
  } else if (this->IsUnion()) {
    os << "(";
    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
      Type* type_i = this->AsUnion()->Get(i);
      if (i > 0) os << " | ";
      type_i->PrintTo(os);
1026
    }
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
    os << ")";
  } else if (this->IsTuple()) {
    os << "<";
    for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
      Type* type_i = this->AsTuple()->Element(i);
      if (i > 0) os << ", ";
      type_i->PrintTo(os);
    }
    os << ">";
  } else {
    UNREACHABLE();
1038 1039 1040
  }
}

1041
#ifdef DEBUG
1042
void Type::Print() {
1043 1044
  OFStream os(stdout);
  PrintTo(os);
1045
  os << std::endl;
1046
}
1047
void BitsetType::Print(bitset bits) {
1048 1049
  OFStream os(stdout);
  Print(os, bits);
1050
  os << std::endl;
1051
}
1052 1053
#endif

1054 1055 1056 1057 1058 1059 1060 1061
BitsetType::bitset BitsetType::SignedSmall() {
  return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
}

BitsetType::bitset BitsetType::UnsignedSmall() {
  return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
}

1062
}  // namespace compiler
1063 1064
}  // namespace internal
}  // namespace v8