LCOV - code coverage report
Current view: top level - src/compiler - types.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 329 385 85.5 %
Date: 2017-04-26 Functions: 36 45 80.0 %

          Line data    Source code
       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
       3             : // 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             : namespace v8 {
      14             : namespace internal {
      15             : namespace compiler {
      16             : 
      17             : // NOTE: If code is marked as being a "shortcut", this means that removing
      18             : // the code won't affect the semantics of the surrounding function definition.
      19             : 
      20             : // static
      21    13966995 : bool Type::IsInteger(i::Object* x) {
      22    19229705 :   return x->IsNumber() && Type::IsInteger(x->Number());
      23             : }
      24             : 
      25             : // -----------------------------------------------------------------------------
      26             : // Range-related helper functions.
      27             : 
      28     3355517 : bool RangeType::Limits::IsEmpty() { return this->min > this->max; }
      29             : 
      30           0 : RangeType::Limits RangeType::Limits::Intersect(Limits lhs, Limits rhs) {
      31             :   DisallowHeapAllocation no_allocation;
      32             :   Limits result(lhs);
      33     3174380 :   if (lhs.min < rhs.min) result.min = rhs.min;
      34     3174380 :   if (lhs.max > rhs.max) result.max = rhs.max;
      35           0 :   return result;
      36             : }
      37             : 
      38           0 : RangeType::Limits RangeType::Limits::Union(Limits lhs, Limits rhs) {
      39             :   DisallowHeapAllocation no_allocation;
      40     3459889 :   if (lhs.IsEmpty()) return rhs;
      41     3459888 :   if (rhs.IsEmpty()) return lhs;
      42             :   Limits result(lhs);
      43     3261143 :   if (lhs.min > rhs.min) result.min = rhs.min;
      44     3261143 :   if (lhs.max < rhs.max) result.max = rhs.max;
      45           0 :   return result;
      46             : }
      47             : 
      48           0 : bool Type::Overlap(RangeType* lhs, RangeType* rhs) {
      49             :   DisallowHeapAllocation no_allocation;
      50             :   return !RangeType::Limits::Intersect(RangeType::Limits(lhs),
      51             :                                        RangeType::Limits(rhs))
      52     2975615 :               .IsEmpty();
      53             : }
      54             : 
      55    28562198 : bool Type::Contains(RangeType* lhs, RangeType* rhs) {
      56             :   DisallowHeapAllocation no_allocation;
      57    28562198 :   return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
      58             : }
      59             : 
      60           0 : bool Type::Contains(RangeType* range, i::Object* val) {
      61             :   DisallowHeapAllocation no_allocation;
      62           0 :   return IsInteger(val) && range->Min() <= val->Number() &&
      63           0 :          val->Number() <= range->Max();
      64             : }
      65             : 
      66             : // -----------------------------------------------------------------------------
      67             : // Min and Max computation.
      68             : 
      69    10951173 : double Type::Min() {
      70             :   DCHECK(this->Is(Number()));
      71    11618195 :   if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
      72    10284151 :   if (this->IsUnion()) {
      73       19727 :     double min = +V8_INFINITY;
      74       66471 :     for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
      75      140232 :       min = std::min(min, this->AsUnion()->Get(i)->Min());
      76             :     }
      77       19727 :     return min;
      78             :   }
      79    10264424 :   if (this->IsRange()) return this->AsRange()->Min();
      80       11279 :   if (this->IsOtherNumberConstant())
      81       11279 :     return this->AsOtherNumberConstant()->Value();
      82           0 :   UNREACHABLE();
      83             :   return 0;
      84             : }
      85             : 
      86    11075702 : double Type::Max() {
      87             :   DCHECK(this->Is(Number()));
      88    11916378 :   if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
      89    10235026 :   if (this->IsUnion()) {
      90       17154 :     double max = -V8_INFINITY;
      91       58752 :     for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
      92      124794 :       max = std::max(max, this->AsUnion()->Get(i)->Max());
      93             :     }
      94       17154 :     return max;
      95             :   }
      96    10217872 :   if (this->IsRange()) return this->AsRange()->Max();
      97       10769 :   if (this->IsOtherNumberConstant())
      98       10769 :     return this->AsOtherNumberConstant()->Value();
      99           0 :   UNREACHABLE();
     100             :   return 0;
     101             : }
     102             : 
     103             : // -----------------------------------------------------------------------------
     104             : // Glb and lub computation.
     105             : 
     106             : // The largest bitset subsumed by this type.
     107    96238182 : Type::bitset BitsetType::Glb(Type* type) {
     108             :   DisallowHeapAllocation no_allocation;
     109             :   // Fast case.
     110    96238182 :   if (IsBitset(type)) {
     111    28654286 :     return type->AsBitset();
     112    67583896 :   } else if (type->IsUnion()) {
     113             :     SLOW_DCHECK(type->AsUnion()->Wellformed());
     114    42524074 :     return type->AsUnion()->Get(0)->BitsetGlb() |
     115    42523924 :            type->AsUnion()->Get(1)->BitsetGlb();  // Shortcut.
     116    46321859 :   } else if (type->IsRange()) {
     117             :     bitset glb =
     118    30067180 :         BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max());
     119    30067664 :     return glb;
     120             :   } else {
     121             :     return kNone;
     122             :   }
     123             : }
     124             : 
     125             : // The smallest bitset subsuming this type, possibly not a proper one.
     126   278617607 : Type::bitset BitsetType::Lub(Type* type) {
     127             :   DisallowHeapAllocation no_allocation;
     128   450178644 :   if (IsBitset(type)) return type->AsBitset();
     129   107056570 :   if (type->IsUnion()) {
     130             :     // Take the representation from the first element, which is always
     131             :     // a bitset.
     132    16324638 :     int bitset = type->AsUnion()->Get(0)->BitsetLub();
     133    29652082 :     for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
     134             :       // Other elements only contribute their semantic part.
     135    42981398 :       bitset |= type->AsUnion()->Get(i)->BitsetLub();
     136             :     }
     137     8161383 :     return bitset;
     138             :   }
     139    98894251 :   if (type->IsHeapConstant()) return type->AsHeapConstant()->Lub();
     140    72001264 :   if (type->IsOtherNumberConstant())
     141             :     return type->AsOtherNumberConstant()->Lub();
     142    60464098 :   if (type->IsRange()) return type->AsRange()->Lub();
     143        3927 :   if (type->IsTuple()) return kOtherInternal;
     144           0 :   UNREACHABLE();
     145             :   return kNone;
     146             : }
     147             : 
     148     9534860 : Type::bitset BitsetType::Lub(i::Map* map) {
     149             :   DisallowHeapAllocation no_allocation;
     150     9534860 :   switch (map->instance_type()) {
     151             :     case STRING_TYPE:
     152             :     case ONE_BYTE_STRING_TYPE:
     153             :     case CONS_STRING_TYPE:
     154             :     case CONS_ONE_BYTE_STRING_TYPE:
     155             :     case THIN_STRING_TYPE:
     156             :     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             :     case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
     162             :     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             :     case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
     171             :     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     1311815 :       return kInternalizedString;
     175             :     case SYMBOL_TYPE:
     176        1717 :       return kSymbol;
     177             :     case ODDBALL_TYPE: {
     178    15121764 :       Heap* heap = map->GetHeap();
     179     5084736 :       if (map == heap->undefined_map()) return kUndefined;
     180     4249880 :       if (map == heap->null_map()) return kNull;
     181     4211290 :       if (map == heap->boolean_map()) return kBoolean;
     182     1575858 :       if (map == heap->the_hole_map()) return kHole;
     183             :       DCHECK(map == heap->uninitialized_map() ||
     184             :              map == heap->termination_exception_map() ||
     185             :              map == heap->arguments_marker_map() ||
     186             :              map == heap->optimized_out_map() ||
     187             :              map == heap->stale_register_map());
     188      588742 :       return kOtherInternal;
     189             :     }
     190             :     case HEAP_NUMBER_TYPE:
     191           0 :       return kNumber;
     192             :     case JS_OBJECT_TYPE:
     193             :     case JS_ARGUMENTS_TYPE:
     194             :     case JS_ERROR_TYPE:
     195             :     case JS_GLOBAL_OBJECT_TYPE:
     196             :     case JS_GLOBAL_PROXY_TYPE:
     197             :     case JS_API_OBJECT_TYPE:
     198             :     case JS_SPECIAL_API_OBJECT_TYPE:
     199     1295013 :       if (map->is_undetectable()) {
     200             :         // Currently we assume that every undetectable receiver is also
     201             :         // callable, which is what we need to support document.all.  We
     202             :         // could add another Type bit to support other use cases in the
     203             :         // future if necessary.
     204             :         DCHECK(map->is_callable());
     205             :         return kOtherUndetectable;
     206             :       }
     207     1294911 :       if (map->is_callable()) {
     208             :         return kOtherCallable;
     209             :       }
     210     1294901 :       return kOtherObject;
     211             :     case JS_ARRAY_TYPE:
     212      606561 :       return kArray;
     213             :     case JS_VALUE_TYPE:
     214             :     case JS_MESSAGE_OBJECT_TYPE:
     215             :     case JS_DATE_TYPE:
     216             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
     217             :     case JS_GENERATOR_OBJECT_TYPE:
     218             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
     219             :     case JS_MODULE_NAMESPACE_TYPE:
     220             :     case JS_ARRAY_BUFFER_TYPE:
     221             :     case JS_REGEXP_TYPE:  // TODO(rossberg): there should be a RegExp type.
     222             :     case JS_TYPED_ARRAY_TYPE:
     223             :     case JS_DATA_VIEW_TYPE:
     224             :     case JS_SET_TYPE:
     225             :     case JS_MAP_TYPE:
     226             :     case JS_SET_ITERATOR_TYPE:
     227             :     case JS_MAP_ITERATOR_TYPE:
     228             :     case JS_STRING_ITERATOR_TYPE:
     229             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
     230             : 
     231             :     case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
     232             :     case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
     233             :     case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
     234             :     case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     235             :     case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     236             :     case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     237             :     case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     238             :     case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     239             :     case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     240             :     case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     241             :     case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     242             :     case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     243             :     case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     244             :     case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     245             :     case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     246             :     case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     247             :     case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     248             :     case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     249             :     case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
     250             :     case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
     251             :     case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
     252             :     case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
     253             :     case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
     254             :     case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
     255             :     case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
     256             :     case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
     257             :     case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
     258             :     case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
     259             :     case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
     260             :     case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
     261             :     case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
     262             :     case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
     263             :     case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
     264             :     case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
     265             :     case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
     266             : 
     267             :     case JS_WEAK_MAP_TYPE:
     268             :     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        5089 :       return kOtherObject;
     274             :     case JS_BOUND_FUNCTION_TYPE:
     275             :       DCHECK(!map->is_undetectable());
     276         192 :       return kBoundFunction;
     277             :     case JS_FUNCTION_TYPE:
     278             :       DCHECK(!map->is_undetectable());
     279      624634 :       return kFunction;
     280             :     case JS_PROXY_TYPE:
     281             :       DCHECK(!map->is_undetectable());
     282        1057 :       if (map->is_callable()) return kCallableProxy;
     283         937 :       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             :     case ACCESSOR_PAIR_TYPE:
     290             :     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      604059 :       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             :     case MUTABLE_HEAP_NUMBER_TYPE:
     306             :     case FREE_SPACE_TYPE:
     307             : #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
     308             :   case FIXED_##TYPE##_ARRAY_TYPE:
     309             : 
     310             :       TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
     311             : #undef FIXED_TYPED_ARRAY_CASE
     312             :     case FILLER_TYPE:
     313             :     case ACCESS_CHECK_INFO_TYPE:
     314             :     case INTERCEPTOR_INFO_TYPE:
     315             :     case OBJECT_TEMPLATE_INFO_TYPE:
     316             :     case ALLOCATION_MEMENTO_TYPE:
     317             :     case ALIASED_ARGUMENTS_ENTRY_TYPE:
     318             :     case PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE:
     319             :     case PROMISE_REACTION_JOB_INFO_TYPE:
     320             :     case DEBUG_INFO_TYPE:
     321             :     case STACK_FRAME_INFO_TYPE:
     322             :     case CELL_TYPE:
     323             :     case WEAK_CELL_TYPE:
     324             :     case PROTOTYPE_INFO_TYPE:
     325             :     case TUPLE2_TYPE:
     326             :     case TUPLE3_TYPE:
     327             :     case CONTEXT_EXTENSION_TYPE:
     328             :     case ASYNC_GENERATOR_REQUEST_TYPE:
     329             :     case PADDING_TYPE_1:
     330             :     case PADDING_TYPE_2:
     331             :     case PADDING_TYPE_3:
     332             :     case PADDING_TYPE_4:
     333           0 :       UNREACHABLE();
     334             :       return kNone;
     335             :   }
     336           0 :   UNREACHABLE();
     337             :   return kNone;
     338             : }
     339             : 
     340     9518534 : Type::bitset BitsetType::Lub(i::Object* value) {
     341             :   DisallowHeapAllocation no_allocation;
     342     9518538 :   if (value->IsNumber()) {
     343        1410 :     return Lub(value->Number());
     344             :   }
     345     9517128 :   return Lub(i::HeapObject::cast(value)->map());
     346             : }
     347             : 
     348        1410 : Type::bitset BitsetType::Lub(double value) {
     349             :   DisallowHeapAllocation no_allocation;
     350        1410 :   if (i::IsMinusZero(value)) return kMinusZero;
     351        1410 :   if (std::isnan(value)) return kNaN;
     352        2820 :   if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
     353             :   return kOtherNumber;
     354             : }
     355             : 
     356             : // Minimum values of plain numeric bitsets.
     357             : const BitsetType::Boundary BitsetType::BoundariesArray[] = {
     358             :     {kOtherNumber, kPlainNumber, -V8_INFINITY},
     359             :     {kOtherSigned32, kNegative32, kMinInt},
     360             :     {kNegative31, kNegative31, -0x40000000},
     361             :     {kUnsigned30, kUnsigned30, 0},
     362             :     {kOtherUnsigned31, kUnsigned31, 0x40000000},
     363             :     {kOtherUnsigned32, kUnsigned32, 0x80000000},
     364             :     {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
     365             : 
     366             : const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; }
     367             : 
     368             : size_t BitsetType::BoundariesSize() {
     369             :   // Windows doesn't like arraysize here.
     370             :   // return arraysize(BoundariesArray);
     371             :   return 7;
     372             : }
     373             : 
     374       20082 : Type::bitset BitsetType::ExpandInternals(Type::bitset bits) {
     375             :   DisallowHeapAllocation no_allocation;
     376       20082 :   if (!(bits & kPlainNumber)) return bits;  // Shortcut.
     377             :   const Boundary* boundaries = Boundaries();
     378        9870 :   for (size_t i = 0; i < BoundariesSize(); ++i) {
     379             :     DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external));
     380        9870 :     if (bits & boundaries[i].internal) bits |= boundaries[i].external;
     381             :   }
     382             :   return bits;
     383             : }
     384             : 
     385    10431097 : Type::bitset BitsetType::Lub(double min, double max) {
     386             :   DisallowHeapAllocation no_allocation;
     387             :   int lub = kNone;
     388             :   const Boundary* mins = Boundaries();
     389             : 
     390    99575087 :   for (size_t i = 1; i < BoundariesSize(); ++i) {
     391   102903960 :     if (min < mins[i].min) {
     392    57193546 :       lub |= mins[i - 1].internal;
     393    57193546 :       if (max < mins[i].min) return lub;
     394             :     }
     395             :   }
     396     8146637 :   return lub | mins[BoundariesSize() - 1].internal;
     397             : }
     398             : 
     399    12095951 : Type::bitset BitsetType::NumberBits(bitset bits) { return bits & kPlainNumber; }
     400             : 
     401    30067231 : Type::bitset BitsetType::Glb(double min, double max) {
     402             :   DisallowHeapAllocation no_allocation;
     403             :   int glb = kNone;
     404             :   const Boundary* mins = Boundaries();
     405             : 
     406             :   // If the range does not touch 0, the bound is empty.
     407    30067231 :   if (max < -1 || min > 0) return glb;
     408             : 
     409    99390991 :   for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
     410    87410307 :     if (min <= mins[i].min) {
     411    70914150 :       if (max + 1 < mins[i + 1].min) break;
     412    62819646 :       glb |= mins[i].external;
     413             :     }
     414             :   }
     415             :   // OtherNumber also contains float numbers, so it can never be
     416             :   // in the greatest lower bound.
     417    20075188 :   return glb & ~(kOtherNumber);
     418             : }
     419             : 
     420     7268436 : double BitsetType::Min(bitset bits) {
     421             :   DisallowHeapAllocation no_allocation;
     422             :   DCHECK(Is(bits, kNumber));
     423             :   const Boundary* mins = Boundaries();
     424     7268436 :   bool mz = bits & kMinusZero;
     425    16882378 :   for (size_t i = 0; i < BoundariesSize(); ++i) {
     426    33722870 :     if (Is(mins[i].internal, bits)) {
     427     7332596 :       return mz ? std::min(0.0, mins[i].min) : mins[i].min;
     428             :     }
     429             :   }
     430       20943 :   if (mz) return 0;
     431        7805 :   return std::numeric_limits<double>::quiet_NaN();
     432             : }
     433             : 
     434     7441747 : double BitsetType::Max(bitset bits) {
     435             :   DisallowHeapAllocation no_allocation;
     436             :   DCHECK(Is(bits, kNumber));
     437             :   const Boundary* mins = Boundaries();
     438     7441747 :   bool mz = bits & kMinusZero;
     439     7441747 :   if (BitsetType::Is(mins[BoundariesSize() - 1].internal, bits)) {
     440             :     return +V8_INFINITY;
     441             :   }
     442    10562489 :   for (size_t i = BoundariesSize() - 1; i-- > 0;) {
     443    21088174 :     if (Is(mins[i].internal, bits)) {
     444     6462003 :       return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1;
     445             :     }
     446             :   }
     447       18402 :   if (mz) return 0;
     448        7815 :   return std::numeric_limits<double>::quiet_NaN();
     449             : }
     450             : 
     451             : // static
     452     1808357 : bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
     453             :   // Not an integer, not NaN, and not -0.
     454     5425071 :   return !std::isnan(value) && !Type::IsInteger(value) &&
     455     1808357 :          !i::IsMinusZero(value);
     456             : }
     457             : 
     458             : // static
     459           0 : bool OtherNumberConstantType::IsOtherNumberConstant(Object* value) {
     460           0 :   return value->IsHeapNumber() &&
     461           0 :          IsOtherNumberConstant(HeapNumber::cast(value)->value());
     462             : }
     463             : 
     464     3973508 : HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
     465             :                                    i::Handle<i::HeapObject> object)
     466     9516208 :     : TypeBase(kHeapConstant), bitset_(bitset), object_(object) {
     467             :   DCHECK(!object->IsHeapNumber());
     468             :   DCHECK_IMPLIES(object->IsString(), object->IsInternalizedString());
     469     3973508 : }
     470             : 
     471             : // -----------------------------------------------------------------------------
     472             : // Predicates.
     473             : 
     474    10025804 : bool Type::SimplyEquals(Type* that) {
     475             :   DisallowHeapAllocation no_allocation;
     476    10025804 :   if (this->IsHeapConstant()) {
     477     6773314 :     return that->IsHeapConstant() &&
     478             :            this->AsHeapConstant()->Value().address() ==
     479     6773314 :                that->AsHeapConstant()->Value().address();
     480             :   }
     481     3252490 :   if (this->IsOtherNumberConstant()) {
     482     4423037 :     return that->IsOtherNumberConstant() &&
     483     1337716 :            this->AsOtherNumberConstant()->Value() ==
     484     4423037 :                that->AsOtherNumberConstant()->Value();
     485             :   }
     486      167169 :   if (this->IsRange()) {
     487      334110 :     if (that->IsHeapConstant() || that->IsOtherNumberConstant()) return false;
     488             :   }
     489         114 :   if (this->IsTuple()) {
     490         114 :     if (!that->IsTuple()) return false;
     491             :     TupleType* this_tuple = this->AsTuple();
     492             :     TupleType* that_tuple = that->AsTuple();
     493         114 :     if (this_tuple->Arity() != that_tuple->Arity()) {
     494             :       return false;
     495             :     }
     496         342 :     for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
     497         342 :       if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false;
     498             :     }
     499             :     return true;
     500             :   }
     501           0 :   UNREACHABLE();
     502             :   return false;
     503             : }
     504             : 
     505             : // Check if [this] <= [that].
     506   268334931 : bool Type::SlowIs(Type* that) {
     507             :   DisallowHeapAllocation no_allocation;
     508             : 
     509             :   // Fast bitset cases
     510   268334931 :   if (that->IsBitset()) {
     511   181240210 :     return BitsetType::Is(this->BitsetLub(), that->AsBitset());
     512             :   }
     513             : 
     514    87092155 :   if (this->IsBitset()) {
     515    24140843 :     return BitsetType::Is(this->AsBitset(), that->BitsetGlb());
     516             :   }
     517             : 
     518             :   // (T1 \/ ... \/ Tn) <= T  if  (T1 <= T) /\ ... /\ (Tn <= T)
     519    62950869 :   if (this->IsUnion()) {
     520    14143678 :     for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
     521    27396778 :       if (!this->AsUnion()->Get(i)->Is(that)) return false;
     522             :     }
     523             :     return true;
     524             :   }
     525             : 
     526             :   // T <= (T1 \/ ... \/ Tn)  if  (T <= T1) \/ ... \/ (T <= Tn)
     527    52466461 :   if (that->IsUnion()) {
     528    24385626 :     for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
     529    41928974 :       if (this->Is(that->AsUnion()->Get(i))) return true;
     530    19113634 :       if (i > 1 && this->IsRange()) return false;  // Shortcut.
     531             :     }
     532             :     return false;
     533             :   }
     534             : 
     535    42935866 :   if (that->IsRange()) {
     536    46022940 :     return (this->IsRange() && Contains(that->AsRange(), this->AsRange()));
     537             :   }
     538    13214991 :   if (this->IsRange()) return false;
     539             : 
     540     9810268 :   return this->SimplyEquals(that);
     541             : }
     542             : 
     543             : // Check if [this] and [that] overlap.
     544    13174824 : bool Type::Maybe(Type* that) {
     545             :   DisallowHeapAllocation no_allocation;
     546             : 
     547    13980684 :   if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub()))
     548             :     return false;
     549             : 
     550             :   // (T1 \/ ... \/ Tn) overlaps T  if  (T1 overlaps T) \/ ... \/ (Tn overlaps T)
     551     8469240 :   if (this->IsUnion()) {
     552      219819 :     for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
     553      386944 :       if (this->AsUnion()->Get(i)->Maybe(that)) return true;
     554             :     }
     555             :     return false;
     556             :   }
     557             : 
     558             :   // T overlaps (T1 \/ ... \/ Tn)  if  (T overlaps T1) \/ ... \/ (T overlaps Tn)
     559     8351430 :   if (that->IsUnion()) {
     560      260174 :     for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
     561      398756 :       if (this->Maybe(that->AsUnion()->Get(i))) return true;
     562             :     }
     563             :     return false;
     564             :   }
     565             : 
     566     8235581 :   if (this->IsBitset() && that->IsBitset()) return true;
     567             : 
     568     5116999 :   if (this->IsRange()) {
     569     3919371 :     if (that->IsRange()) {
     570     2975615 :       return Overlap(this->AsRange(), that->AsRange());
     571             :     }
     572      943756 :     if (that->IsBitset()) {
     573             :       bitset number_bits = BitsetType::NumberBits(that->AsBitset());
     574      776799 :       if (number_bits == BitsetType::kNone) {
     575             :         return false;
     576             :       }
     577     1553605 :       double min = std::max(BitsetType::Min(number_bits), this->Min());
     578     1553582 :       double max = std::min(BitsetType::Max(number_bits), this->Max());
     579      776776 :       return min <= max;
     580             :     }
     581             :   }
     582     1364585 :   if (that->IsRange()) {
     583             :     return that->Maybe(this);  // This case is handled above.
     584             :   }
     585             : 
     586      555842 :   if (this->IsBitset() || that->IsBitset()) return true;
     587             : 
     588      214306 :   return this->SimplyEquals(that);
     589             : }
     590             : 
     591             : // Return the range in [this], or [NULL].
     592    29249741 : Type* Type::GetRange() {
     593             :   DisallowHeapAllocation no_allocation;
     594    29249741 :   if (this->IsRange()) return this;
     595    33112720 :   if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) {
     596    15938088 :     return this->AsUnion()->Get(1);
     597             :   }
     598             :   return NULL;
     599             : }
     600             : 
     601           0 : bool UnionType::Wellformed() {
     602             :   DisallowHeapAllocation no_allocation;
     603             :   // This checks the invariants of the union representation:
     604             :   // 1. There are at least two elements.
     605             :   // 2. The first element is a bitset, no other element is a bitset.
     606             :   // 3. At most one element is a range, and it must be the second one.
     607             :   // 4. No element is itself a union.
     608             :   // 5. No element (except the bitset) is a subtype of any other.
     609             :   // 6. If there is a range, then the bitset type does not contain
     610             :   //    plain number bits.
     611             :   DCHECK(this->Length() >= 2);       // (1)
     612             :   DCHECK(this->Get(0)->IsBitset());  // (2a)
     613             : 
     614             :   for (int i = 0; i < this->Length(); ++i) {
     615             :     if (i != 0) DCHECK(!this->Get(i)->IsBitset());  // (2b)
     616             :     if (i != 1) DCHECK(!this->Get(i)->IsRange());   // (3)
     617             :     DCHECK(!this->Get(i)->IsUnion());               // (4)
     618             :     for (int j = 0; j < this->Length(); ++j) {
     619             :       if (i != j && i != 0) DCHECK(!this->Get(i)->Is(this->Get(j)));  // (5)
     620             :     }
     621             :   }
     622             :   DCHECK(!this->Get(1)->IsRange() ||
     623             :          (BitsetType::NumberBits(this->Get(0)->AsBitset()) ==
     624             :           BitsetType::kNone));  // (6)
     625           0 :   return true;
     626             : }
     627             : 
     628             : // -----------------------------------------------------------------------------
     629             : // Union and intersection
     630             : 
     631             : static bool AddIsSafe(int x, int y) {
     632    29533494 :   return x >= 0 ? y <= std::numeric_limits<int>::max() - x
     633    59066988 :                 : y >= std::numeric_limits<int>::min() - x;
     634             : }
     635             : 
     636    20748229 : Type* Type::Intersect(Type* type1, Type* type2, Zone* zone) {
     637             :   // Fast case: bit sets.
     638    36423029 :   if (type1->IsBitset() && type2->IsBitset()) {
     639    30083214 :     return BitsetType::New(type1->AsBitset() & type2->AsBitset());
     640             :   }
     641             : 
     642             :   // Fast case: top or bottom types.
     643     5706622 :   if (type1->IsNone() || type2->IsAny()) return type1;  // Shortcut.
     644     5532941 :   if (type2->IsNone() || type1->IsAny()) return type2;  // Shortcut.
     645             : 
     646             :   // Semi-fast case.
     647     5396120 :   if (type1->Is(type2)) return type1;
     648     1518181 :   if (type2->Is(type1)) return type2;
     649             : 
     650             :   // Slow case: create union.
     651             : 
     652             :   // Semantic subtyping check - this is needed for consistency with the
     653             :   // semi-fast case above.
     654      379905 :   if (type1->Is(type2)) {
     655             :     type2 = Any();
     656      379903 :   } else if (type2->Is(type1)) {
     657             :     type1 = Any();
     658             :   }
     659             : 
     660      379898 :   bitset bits = type1->BitsetGlb() & type2->BitsetGlb();
     661      379898 :   int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
     662      379898 :   int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
     663      379898 :   if (!AddIsSafe(size1, size2)) return Any();
     664      379900 :   int size = size1 + size2;
     665      379900 :   if (!AddIsSafe(size, 2)) return Any();
     666      379900 :   size += 2;
     667      379900 :   Type* result_type = UnionType::New(size, zone);
     668             :   UnionType* result = result_type->AsUnion();
     669             :   size = 0;
     670             : 
     671             :   // Deal with bitsets.
     672      578632 :   result->Set(size++, BitsetType::New(bits));
     673             : 
     674      379899 :   RangeType::Limits lims = RangeType::Limits::Empty();
     675      379899 :   size = IntersectAux(type1, type2, result, size, &lims, zone);
     676             : 
     677             :   // If the range is not empty, then insert it into the union and
     678             :   // remove the number bits from the bitset.
     679      379902 :   if (!lims.IsEmpty()) {
     680      198741 :     size = UpdateRange(RangeType::New(lims, zone), result, size, zone);
     681             : 
     682             :     // Remove the number bits.
     683             :     bitset number_bits = BitsetType::NumberBits(bits);
     684      198733 :     bits &= ~number_bits;
     685             :     result->Set(0, BitsetType::New(bits));
     686             :   }
     687      379894 :   return NormalizeUnion(result_type, size, zone);
     688             : }
     689             : 
     690      198733 : int Type::UpdateRange(Type* range, UnionType* result, int size, Zone* zone) {
     691      198733 :   if (size == 1) {
     692      199644 :     result->Set(size++, range);
     693             :   } else {
     694             :     // Make space for the range.
     695         319 :     result->Set(size++, result->Get(1));
     696             :     result->Set(1, range);
     697             :   }
     698             : 
     699             :   // Remove any components that just got subsumed.
     700      199325 :   for (int i = 2; i < size;) {
     701         592 :     if (result->Get(i)->Is(range)) {
     702           0 :       result->Set(i, result->Get(--size));
     703             :     } else {
     704         592 :       ++i;
     705             :     }
     706             :   }
     707      198733 :   return size;
     708             : }
     709             : 
     710      136257 : RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) {
     711             :   bitset number_bits = BitsetType::NumberBits(bits);
     712             : 
     713      136257 :   if (number_bits == BitsetType::kNone) {
     714             :     return RangeType::Limits::Empty();
     715             :   }
     716             : 
     717             :   return RangeType::Limits(BitsetType::Min(number_bits),
     718      136257 :                            BitsetType::Max(number_bits));
     719             : }
     720             : 
     721      136256 : RangeType::Limits Type::IntersectRangeAndBitset(Type* range, Type* bitset,
     722             :                                                 Zone* zone) {
     723             :   RangeType::Limits range_lims(range->AsRange());
     724      136256 :   RangeType::Limits bitset_lims = ToLimits(bitset->AsBitset(), zone);
     725      136257 :   return RangeType::Limits::Intersect(range_lims, bitset_lims);
     726             : }
     727             : 
     728      657632 : int Type::IntersectAux(Type* lhs, Type* rhs, UnionType* result, int size,
     729             :                        RangeType::Limits* lims, Zone* zone) {
     730      701820 :   if (lhs->IsUnion()) {
     731      360325 :     for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) {
     732             :       size =
     733      508580 :           IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, lims, zone);
     734             :     }
     735             :     return size;
     736             :   }
     737      595788 :   if (rhs->IsUnion()) {
     738       35178 :     for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) {
     739             :       size =
     740       46908 :           IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, zone);
     741             :     }
     742             :     return size;
     743             :   }
     744             : 
     745      584071 :   if (!BitsetType::IsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) {
     746             :     return size;
     747             :   }
     748             : 
     749      300395 :   if (lhs->IsRange()) {
     750      238944 :     if (rhs->IsBitset()) {
     751      136256 :       RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
     752             : 
     753      136257 :       if (!lim.IsEmpty()) {
     754      136257 :         *lims = RangeType::Limits::Union(lim, *lims);
     755             :       }
     756             :       return size;
     757             :     }
     758      102688 :     if (rhs->IsRange()) {
     759             :       RangeType::Limits lim = RangeType::Limits::Intersect(
     760             :           RangeType::Limits(lhs->AsRange()), RangeType::Limits(rhs->AsRange()));
     761       62508 :       if (!lim.IsEmpty()) {
     762       62489 :         *lims = RangeType::Limits::Union(lim, *lims);
     763             :       }
     764             :     }
     765      102688 :     return size;
     766             :   }
     767       61451 :   if (rhs->IsRange()) {
     768             :     // This case is handled symmetrically above.
     769             :     return IntersectAux(rhs, lhs, result, size, lims, zone);
     770             :   }
     771       17263 :   if (lhs->IsBitset() || rhs->IsBitset()) {
     772       16041 :     return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone);
     773             :   }
     774        1222 :   if (lhs->SimplyEquals(rhs)) {
     775           2 :     return AddToUnion(lhs, result, size, zone);
     776             :   }
     777             :   return size;
     778             : }
     779             : 
     780             : // Make sure that we produce a well-formed range and bitset:
     781             : // If the range is non-empty, the number bits in the bitset should be
     782             : // clear. Moreover, if we have a canonical range (such as Signed32),
     783             : // we want to produce a bitset rather than a range.
     784    10984162 : Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) {
     785             :   // Fast path: If the bitset does not mention numbers, we can just keep the
     786             :   // range.
     787    10984162 :   bitset number_bits = BitsetType::NumberBits(*bits);
     788    10984162 :   if (number_bits == 0) {
     789             :     return range;
     790             :   }
     791             : 
     792             :   // If the range is semantically contained within the bitset, return None and
     793             :   // leave the bitset untouched.
     794             :   bitset range_lub = range->BitsetLub();
     795    13260128 :   if (BitsetType::Is(range_lub, *bits)) {
     796             :     return None();
     797             :   }
     798             : 
     799             :   // Slow path: reconcile the bitset range and the range.
     800     5688507 :   double bitset_min = BitsetType::Min(number_bits);
     801     5688507 :   double bitset_max = BitsetType::Max(number_bits);
     802             : 
     803     5688507 :   double range_min = range->Min();
     804     5688507 :   double range_max = range->Max();
     805             : 
     806             :   // Remove the number bits from the bitset, they would just confuse us now.
     807             :   // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
     808             :   // case we already returned after the subtype check above.
     809     5688507 :   *bits &= ~number_bits;
     810             : 
     811     5688507 :   if (range_min <= bitset_min && range_max >= bitset_max) {
     812             :     // Bitset is contained within the range, just return the range.
     813             :     return range;
     814             :   }
     815             : 
     816      485687 :   if (bitset_min < range_min) {
     817             :     range_min = bitset_min;
     818             :   }
     819      485687 :   if (bitset_max > range_max) {
     820             :     range_max = bitset_max;
     821             :   }
     822      485687 :   return RangeType::New(range_min, range_max, zone);
     823             : }
     824             : 
     825     4678588 : Type* Type::NewConstant(double value, Zone* zone) {
     826     4678588 :   if (IsInteger(value)) {
     827     2851186 :     return Range(value, value, zone);
     828     1827404 :   } else if (i::IsMinusZero(value)) {
     829             :     return Type::MinusZero();
     830     1814288 :   } else if (std::isnan(value)) {
     831             :     return Type::NaN();
     832             :   }
     833             : 
     834             :   DCHECK(OtherNumberConstantType::IsOtherNumberConstant(value));
     835     1808357 :   return OtherNumberConstant(value, zone);
     836             : }
     837             : 
     838    10808264 : Type* Type::NewConstant(i::Handle<i::Object> value, Zone* zone) {
     839    10808264 :   if (IsInteger(*value)) {
     840             :     double v = value->Number();
     841     3468507 :     return Range(v, v, zone);
     842     7339767 :   } else if (value->IsHeapNumber()) {
     843     1794196 :     return NewConstant(value->Number(), zone);
     844     6047172 :   } else if (value->IsString() && !value->IsInternalizedString()) {
     845             :     return Type::OtherString();
     846             :   }
     847     5542700 :   return HeapConstant(i::Handle<i::HeapObject>::cast(value), zone);
     848             : }
     849             : 
     850    36622722 : Type* Type::Union(Type* type1, Type* type2, Zone* zone) {
     851             :   // Fast case: bit sets.
     852    54924636 :   if (type1->IsBitset() && type2->IsBitset()) {
     853    19901484 :     return BitsetType::New(type1->AsBitset() | type2->AsBitset());
     854             :   }
     855             : 
     856             :   // Fast case: top or bottom types.
     857    26671980 :   if (type1->IsAny() || type2->IsNone()) return type1;
     858    25983364 :   if (type2->IsAny() || type1->IsNone()) return type2;
     859             : 
     860             :   // Semi-fast case.
     861    22410257 :   if (type1->Is(type2)) return type2;
     862    20691891 :   if (type2->Is(type1)) return type1;
     863             : 
     864             :   // Slow case: create union.
     865    14386847 :   int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
     866    14386847 :   int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
     867    14386847 :   if (!AddIsSafe(size1, size2)) return Any();
     868    14386849 :   int size = size1 + size2;
     869    14386849 :   if (!AddIsSafe(size, 2)) return Any();
     870    14386849 :   size += 2;
     871    14386849 :   Type* result_type = UnionType::New(size, zone);
     872             :   UnionType* result = result_type->AsUnion();
     873             :   size = 0;
     874             : 
     875             :   // Compute the new bitset.
     876    14386851 :   bitset new_bitset = type1->BitsetGlb() | type2->BitsetGlb();
     877             : 
     878             :   // Deal with ranges.
     879             :   Type* range = None();
     880    14386851 :   Type* range1 = type1->GetRange();
     881    14386852 :   Type* range2 = type2->GetRange();
     882    14386852 :   if (range1 != NULL && range2 != NULL) {
     883             :     RangeType::Limits lims =
     884             :         RangeType::Limits::Union(RangeType::Limits(range1->AsRange()),
     885     3261143 :                                  RangeType::Limits(range2->AsRange()));
     886     3261143 :     Type* union_range = RangeType::New(lims, zone);
     887     3261143 :     range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
     888    11125709 :   } else if (range1 != NULL) {
     889     5149330 :     range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
     890     5976379 :   } else if (range2 != NULL) {
     891     2573695 :     range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
     892             :   }
     893    14386849 :   Type* bits = BitsetType::New(new_bitset);
     894    24429457 :   result->Set(size++, bits);
     895    14386849 :   if (!range->IsNone()) result->Set(size++, range);
     896             : 
     897    14386849 :   size = AddToUnion(type1, result, size, zone);
     898    14386847 :   size = AddToUnion(type2, result, size, zone);
     899    14386844 :   return NormalizeUnion(result_type, size, zone);
     900             : }
     901             : 
     902             : // Add [type] to [result] unless [type] is bitset, range, or already subsumed.
     903             : // Return new size of [result].
     904    58859808 : int Type::AddToUnion(Type* type, UnionType* result, int size, Zone* zone) {
     905   100051530 :   if (type->IsBitset() || type->IsRange()) return size;
     906    26946423 :   if (type->IsUnion()) {
     907    40672788 :     for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
     908    60140176 :       size = AddToUnion(type->AsUnion()->Get(i), result, size, zone);
     909             :     }
     910             :     return size;
     911             :   }
     912    30354042 :   for (int i = 0; i < size; ++i) {
     913    78957513 :     if (type->Is(result->Get(i))) return size;
     914             :   }
     915    14438024 :   result->Set(size++, type);
     916    14438024 :   return size;
     917             : }
     918             : 
     919    14766743 : Type* Type::NormalizeUnion(Type* union_type, int size, Zone* zone) {
     920             :   UnionType* unioned = union_type->AsUnion();
     921             :   DCHECK(size >= 1);
     922             :   DCHECK(unioned->Get(0)->IsBitset());
     923             :   // If the union has just one element, return it.
     924    14766743 :   if (size == 1) {
     925     1458772 :     return unioned->Get(0);
     926             :   }
     927             :   bitset bits = unioned->Get(0)->AsBitset();
     928             :   // If the union only consists of a range, we can get rid of the union.
     929    14037357 :   if (size == 2 && bits == BitsetType::kNone) {
     930     1213281 :     if (unioned->Get(1)->IsRange()) {
     931             :       return RangeType::New(unioned->Get(1)->AsRange()->Min(),
     932     2419249 :                             unioned->Get(1)->AsRange()->Max(), zone);
     933             :     }
     934             :   }
     935             :   unioned->Shrink(size);
     936             :   SLOW_DCHECK(unioned->Wellformed());
     937    12827733 :   return union_type;
     938             : }
     939             : 
     940       74200 : int Type::NumConstants() {
     941             :   DisallowHeapAllocation no_allocation;
     942      147286 :   if (this->IsHeapConstant() || this->IsOtherNumberConstant()) {
     943             :     return 1;
     944       72222 :   } else if (this->IsUnion()) {
     945             :     int result = 0;
     946       13632 :     for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
     947       18316 :       if (this->AsUnion()->Get(i)->IsHeapConstant()) ++result;
     948             :     }
     949             :     return result;
     950             :   } else {
     951             :     return 0;
     952             :   }
     953             : }
     954             : 
     955             : // -----------------------------------------------------------------------------
     956             : // Printing.
     957             : 
     958      117806 : const char* BitsetType::Name(bitset bits) {
     959      117806 :   switch (bits) {
     960             : #define RETURN_NAMED_TYPE(type, value) \
     961             :   case k##type:                        \
     962             :     return #type;
     963           0 :     PROPER_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
     964           0 :     INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
     965             : #undef RETURN_NAMED_TYPE
     966             : 
     967             :     default:
     968           0 :       return NULL;
     969             :   }
     970             : }
     971             : 
     972      117806 : void BitsetType::Print(std::ostream& os,  // NOLINT
     973             :                        bitset bits) {
     974             :   DisallowHeapAllocation no_allocation;
     975      117806 :   const char* name = Name(bits);
     976      117806 :   if (name != NULL) {
     977      117806 :     os << name;
     978      117806 :     return;
     979             :   }
     980             : 
     981             :   // clang-format off
     982             :   static const bitset named_bitsets[] = {
     983             : #define BITSET_CONSTANT(type, value) k##type,
     984             :     INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
     985             :     PROPER_BITSET_TYPE_LIST(BITSET_CONSTANT)
     986             : #undef BITSET_CONSTANT
     987             :   };
     988             :   // clang-format on
     989             : 
     990             :   bool is_first = true;
     991           0 :   os << "(";
     992           0 :   for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
     993           0 :     bitset subset = named_bitsets[i];
     994           0 :     if ((bits & subset) == subset) {
     995           0 :       if (!is_first) os << " | ";
     996             :       is_first = false;
     997           0 :       os << Name(subset);
     998           0 :       bits -= subset;
     999             :     }
    1000             :   }
    1001             :   DCHECK(bits == 0);
    1002           0 :   os << ")";
    1003             : }
    1004             : 
    1005      117806 : void Type::PrintTo(std::ostream& os) {
    1006             :   DisallowHeapAllocation no_allocation;
    1007      117806 :   if (this->IsBitset()) {
    1008      117806 :     BitsetType::Print(os, this->AsBitset());
    1009           0 :   } else if (this->IsHeapConstant()) {
    1010           0 :     os << "HeapConstant(" << Brief(*this->AsHeapConstant()->Value()) << ")";
    1011           0 :   } else if (this->IsOtherNumberConstant()) {
    1012           0 :     os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value()
    1013           0 :        << ")";
    1014           0 :   } else if (this->IsRange()) {
    1015           0 :     std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
    1016             :     std::streamsize saved_precision = os.precision(0);
    1017           0 :     os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
    1018           0 :        << ")";
    1019           0 :     os.flags(saved_flags);
    1020             :     os.precision(saved_precision);
    1021           0 :   } else if (this->IsUnion()) {
    1022           0 :     os << "(";
    1023           0 :     for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
    1024           0 :       Type* type_i = this->AsUnion()->Get(i);
    1025           0 :       if (i > 0) os << " | ";
    1026           0 :       type_i->PrintTo(os);
    1027             :     }
    1028           0 :     os << ")";
    1029           0 :   } else if (this->IsTuple()) {
    1030           0 :     os << "<";
    1031           0 :     for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
    1032             :       Type* type_i = this->AsTuple()->Element(i);
    1033           0 :       if (i > 0) os << ", ";
    1034           0 :       type_i->PrintTo(os);
    1035             :     }
    1036           0 :     os << ">";
    1037             :   } else {
    1038           0 :     UNREACHABLE();
    1039             :   }
    1040      117806 : }
    1041             : 
    1042             : #ifdef DEBUG
    1043             : void Type::Print() {
    1044             :   OFStream os(stdout);
    1045             :   PrintTo(os);
    1046             :   os << std::endl;
    1047             : }
    1048             : void BitsetType::Print(bitset bits) {
    1049             :   OFStream os(stdout);
    1050             :   Print(os, bits);
    1051             :   os << std::endl;
    1052             : }
    1053             : #endif
    1054             : 
    1055     2260636 : BitsetType::bitset BitsetType::SignedSmall() {
    1056     2260636 :   return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
    1057             : }
    1058             : 
    1059       73437 : BitsetType::bitset BitsetType::UnsignedSmall() {
    1060       73437 :   return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
    1061             : }
    1062             : 
    1063             : }  // namespace compiler
    1064             : }  // namespace internal
    1065             : }  // namespace v8

Generated by: LCOV version 1.10