LCOV - code coverage report
Current view: top level - src/compiler - types.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 341 396 86.1 %
Date: 2019-04-17 Functions: 43 57 75.4 %

          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             : // -----------------------------------------------------------------------------
      18             : // Range-related helper functions.
      19             : 
      20     3188410 : bool RangeType::Limits::IsEmpty() { return this->min > this->max; }
      21             : 
      22           0 : RangeType::Limits RangeType::Limits::Intersect(Limits lhs, Limits rhs) {
      23             :   DisallowHeapAllocation no_allocation;
      24             :   Limits result(lhs);
      25     1896862 :   if (lhs.min < rhs.min) result.min = rhs.min;
      26     1896862 :   if (lhs.max > rhs.max) result.max = rhs.max;
      27           0 :   return result;
      28             : }
      29             : 
      30           0 : RangeType::Limits RangeType::Limits::Union(Limits lhs, Limits rhs) {
      31             :   DisallowHeapAllocation no_allocation;
      32     3958490 :   if (lhs.IsEmpty()) return rhs;
      33     3958490 :   if (rhs.IsEmpty()) return lhs;
      34             :   Limits result(lhs);
      35     3317346 :   if (lhs.min > rhs.min) result.min = rhs.min;
      36     3317346 :   if (lhs.max < rhs.max) result.max = rhs.max;
      37           0 :   return result;
      38             : }
      39             : 
      40           0 : bool Type::Overlap(const RangeType* lhs, const RangeType* rhs) {
      41             :   DisallowHeapAllocation no_allocation;
      42             :   return !RangeType::Limits::Intersect(RangeType::Limits(lhs),
      43             :                                        RangeType::Limits(rhs))
      44     1255504 :               .IsEmpty();
      45             : }
      46             : 
      47           0 : bool Type::Contains(const RangeType* lhs, const RangeType* rhs) {
      48             :   DisallowHeapAllocation no_allocation;
      49    23512707 :   return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
      50             : }
      51             : 
      52             : // -----------------------------------------------------------------------------
      53             : // Min and Max computation.
      54             : 
      55    13349801 : double Type::Min() const {
      56             :   DCHECK(this->Is(Number()));
      57             :   DCHECK(!this->Is(NaN()));
      58    13931746 :   if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
      59    12767856 :   if (this->IsUnion()) {
      60       49372 :     double min = +V8_INFINITY;
      61      205880 :     for (int i = 1, n = AsUnion()->Length(); i < n; ++i) {
      62      156508 :       min = std::min(min, AsUnion()->Get(i).Min());
      63             :     }
      64       49372 :     Type bitset = AsUnion()->Get(0);
      65       68259 :     if (!bitset.Is(NaN())) min = std::min(min, bitset.Min());
      66       49372 :     return min;
      67             :   }
      68    25397548 :   if (this->IsRange()) return this->AsRange()->Min();
      69             :   DCHECK(this->IsOtherNumberConstant());
      70       39420 :   return this->AsOtherNumberConstant()->Value();
      71             : }
      72             : 
      73    13560424 : double Type::Max() const {
      74             :   DCHECK(this->Is(Number()));
      75             :   DCHECK(!this->Is(NaN()));
      76    14325283 :   if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
      77    12795565 :   if (this->IsUnion()) {
      78       44898 :     double max = -V8_INFINITY;
      79      192458 :     for (int i = 1, n = this->AsUnion()->Length(); i < n; ++i) {
      80      147561 :       max = std::max(max, this->AsUnion()->Get(i).Max());
      81             :     }
      82       44897 :     Type bitset = this->AsUnion()->Get(0);
      83       59295 :     if (!bitset.Is(NaN())) max = std::max(max, bitset.Max());
      84       44896 :     return max;
      85             :   }
      86    25465798 :   if (this->IsRange()) return this->AsRange()->Max();
      87             :   DCHECK(this->IsOtherNumberConstant());
      88       35536 :   return this->AsOtherNumberConstant()->Value();
      89             : }
      90             : 
      91             : // -----------------------------------------------------------------------------
      92             : // Glb and lub computation.
      93             : 
      94             : // The largest bitset subsumed by this type.
      95   130214046 : Type::bitset Type::BitsetGlb() const {
      96             :   DisallowHeapAllocation no_allocation;
      97             :   // Fast case.
      98   130214046 :   if (IsBitset()) {
      99    38411209 :     return AsBitset();
     100    91802837 :   } else if (IsUnion()) {
     101             :     SLOW_DCHECK(AsUnion()->Wellformed());
     102    55267270 :     return AsUnion()->Get(0).BitsetGlb() |
     103    27633690 :            AsUnion()->Get(1).BitsetGlb();  // Shortcut.
     104    64169421 :   } else if (IsRange()) {
     105    41282682 :     bitset glb = BitsetType::Glb(AsRange()->Min(), AsRange()->Max());
     106    41283870 :     return glb;
     107             :   } else {
     108             :     return BitsetType::kNone;
     109             :   }
     110             : }
     111             : 
     112             : // The smallest bitset subsuming this type, possibly not a proper one.
     113   371978365 : Type::bitset Type::BitsetLub() const {
     114             :   DisallowHeapAllocation no_allocation;
     115   612565723 :   if (IsBitset()) return AsBitset();
     116   131391007 :   if (IsUnion()) {
     117             :     // Take the representation from the first element, which is always
     118             :     // a bitset.
     119    10893376 :     int bitset = AsUnion()->Get(0).BitsetLub();
     120    71271294 :     for (int i = 0, n = AsUnion()->Length(); i < n; ++i) {
     121             :       // Other elements only contribute their semantic part.
     122    30191240 :       bitset |= AsUnion()->Get(i).BitsetLub();
     123             :     }
     124    10894607 :     return bitset;
     125             :   }
     126   159185064 :   if (IsHeapConstant()) return AsHeapConstant()->Lub();
     127    81810198 :   if (IsOtherNumberConstant()) {
     128             :     return AsOtherNumberConstant()->Lub();
     129             :   }
     130   138711786 :   if (IsRange()) return AsRange()->Lub();
     131        4158 :   if (IsTuple()) return BitsetType::kOtherInternal;
     132           0 :   UNREACHABLE();
     133             : }
     134             : 
     135             : // TODO(neis): Once the broker mode kDisabled is gone, change the input type to
     136             : // MapRef and get rid of the HeapObjectType class.
     137             : template <typename MapRefLike>
     138    18435917 : Type::bitset BitsetType::Lub(const MapRefLike& map) {
     139    18435917 :   switch (map.instance_type()) {
     140             :     case EMPTY_STRING_TYPE:
     141             :       return kEmptyString;
     142             :     case CONS_STRING_TYPE:
     143             :     case SLICED_STRING_TYPE:
     144             :     case EXTERNAL_STRING_TYPE:
     145             :     case UNCACHED_EXTERNAL_STRING_TYPE:
     146             :     case STRING_TYPE:
     147             :     case THIN_STRING_TYPE:
     148         639 :       return kNonEmptyTwoByteString;
     149             :     case CONS_ONE_BYTE_STRING_TYPE:
     150             :     case SLICED_ONE_BYTE_STRING_TYPE:
     151             :     case EXTERNAL_ONE_BYTE_STRING_TYPE:
     152             :     case UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE:
     153             :     case ONE_BYTE_STRING_TYPE:
     154             :     case THIN_ONE_BYTE_STRING_TYPE:
     155         331 :       return kNonEmptyOneByteString;
     156             :     case EXTERNAL_INTERNALIZED_STRING_TYPE:
     157             :     case UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE:
     158             :     case INTERNALIZED_STRING_TYPE:
     159        4219 :       return kNonEmptyInternalizedTwoByteString;
     160             :     case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
     161             :     case UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
     162             :     case ONE_BYTE_INTERNALIZED_STRING_TYPE:
     163     3130858 :       return kNonEmptyInternalizedOneByteString;
     164             :     case SYMBOL_TYPE:
     165         599 :       return kSymbol;
     166             :     case BIGINT_TYPE:
     167        2385 :       return kBigInt;
     168             :     case ODDBALL_TYPE:
     169    10681594 :       switch (map.oddball_type()) {
     170             :         case OddballType::kNone:
     171             :           break;
     172             :         case OddballType::kHole:
     173             :           return kHole;
     174             :         case OddballType::kBoolean:
     175     6623761 :           return kBoolean;
     176             :         case OddballType::kNull:
     177       32572 :           return kNull;
     178             :         case OddballType::kUndefined:
     179      965496 :           return kUndefined;
     180             :         case OddballType::kUninitialized:
     181             :         case OddballType::kOther:
     182             :           // TODO(neis): We should add a kOtherOddball type.
     183     1470070 :           return kOtherInternal;
     184             :       }
     185           0 :       UNREACHABLE();
     186             :     case HEAP_NUMBER_TYPE:
     187           0 :       return kNumber;
     188             :     case JS_OBJECT_TYPE:
     189             :     case JS_ARGUMENTS_TYPE:
     190             :     case JS_ERROR_TYPE:
     191             :     case JS_GLOBAL_OBJECT_TYPE:
     192             :     case JS_GLOBAL_PROXY_TYPE:
     193             :     case JS_API_OBJECT_TYPE:
     194             :     case JS_SPECIAL_API_OBJECT_TYPE:
     195     1154209 :       if (map.is_undetectable()) {
     196             :         // Currently we assume that every undetectable receiver is also
     197             :         // callable, which is what we need to support document.all.  We
     198             :         // could add another Type bit to support other use cases in the
     199             :         // future if necessary.
     200             :         DCHECK(map.is_callable());
     201             :         return kOtherUndetectable;
     202             :       }
     203     1154143 :       if (map.is_callable()) {
     204             :         return kOtherCallable;
     205             :       }
     206     1154143 :       return kOtherObject;
     207             :     case JS_ARRAY_TYPE:
     208      561868 :       return kArray;
     209             :     case JS_VALUE_TYPE:
     210             :     case JS_MESSAGE_OBJECT_TYPE:
     211             :     case JS_DATE_TYPE:
     212             : #ifdef V8_INTL_SUPPORT
     213             :     case JS_INTL_V8_BREAK_ITERATOR_TYPE:
     214             :     case JS_INTL_COLLATOR_TYPE:
     215             :     case JS_INTL_DATE_TIME_FORMAT_TYPE:
     216             :     case JS_INTL_LIST_FORMAT_TYPE:
     217             :     case JS_INTL_LOCALE_TYPE:
     218             :     case JS_INTL_NUMBER_FORMAT_TYPE:
     219             :     case JS_INTL_PLURAL_RULES_TYPE:
     220             :     case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
     221             :     case JS_INTL_SEGMENT_ITERATOR_TYPE:
     222             :     case JS_INTL_SEGMENTER_TYPE:
     223             : #endif  // V8_INTL_SUPPORT
     224             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
     225             :     case JS_GENERATOR_OBJECT_TYPE:
     226             :     case JS_ASYNC_FUNCTION_OBJECT_TYPE:
     227             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
     228             :     case JS_MODULE_NAMESPACE_TYPE:
     229             :     case JS_ARRAY_BUFFER_TYPE:
     230             :     case JS_ARRAY_ITERATOR_TYPE:
     231             :     case JS_REGEXP_TYPE:  // TODO(rossberg): there should be a RegExp type.
     232             :     case JS_REGEXP_STRING_ITERATOR_TYPE:
     233             :     case JS_TYPED_ARRAY_TYPE:
     234             :     case JS_DATA_VIEW_TYPE:
     235             :     case JS_SET_TYPE:
     236             :     case JS_MAP_TYPE:
     237             :     case JS_SET_KEY_VALUE_ITERATOR_TYPE:
     238             :     case JS_SET_VALUE_ITERATOR_TYPE:
     239             :     case JS_MAP_KEY_ITERATOR_TYPE:
     240             :     case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
     241             :     case JS_MAP_VALUE_ITERATOR_TYPE:
     242             :     case JS_STRING_ITERATOR_TYPE:
     243             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
     244             :     case JS_FINALIZATION_GROUP_TYPE:
     245             :     case JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE:
     246             :     case JS_WEAK_MAP_TYPE:
     247             :     case JS_WEAK_REF_TYPE:
     248             :     case JS_WEAK_SET_TYPE:
     249             :     case JS_PROMISE_TYPE:
     250             :     case WASM_EXCEPTION_TYPE:
     251             :     case WASM_GLOBAL_TYPE:
     252             :     case WASM_INSTANCE_TYPE:
     253             :     case WASM_MEMORY_TYPE:
     254             :     case WASM_MODULE_TYPE:
     255             :     case WASM_TABLE_TYPE:
     256             :     case WEAK_CELL_TYPE:
     257             :       DCHECK(!map.is_callable());
     258             :       DCHECK(!map.is_undetectable());
     259        4240 :       return kOtherObject;
     260             :     case JS_BOUND_FUNCTION_TYPE:
     261             :       DCHECK(!map.is_undetectable());
     262         163 :       return kBoundFunction;
     263             :     case JS_FUNCTION_TYPE:
     264             :       DCHECK(!map.is_undetectable());
     265      550957 :       return kFunction;
     266             :     case JS_PROXY_TYPE:
     267             :       DCHECK(!map.is_undetectable());
     268         394 :       if (map.is_callable()) return kCallableProxy;
     269         190 :       return kOtherProxy;
     270             :     case MAP_TYPE:
     271             :     case ALLOCATION_SITE_TYPE:
     272             :     case ACCESSOR_INFO_TYPE:
     273             :     case SHARED_FUNCTION_INFO_TYPE:
     274             :     case FUNCTION_TEMPLATE_INFO_TYPE:
     275             :     case FUNCTION_TEMPLATE_RARE_DATA_TYPE:
     276             :     case ACCESSOR_PAIR_TYPE:
     277             :     case EMBEDDER_DATA_ARRAY_TYPE:
     278             :     case FIXED_ARRAY_TYPE:
     279             :     case HASH_TABLE_TYPE:
     280             :     case ORDERED_HASH_MAP_TYPE:
     281             :     case ORDERED_HASH_SET_TYPE:
     282             :     case ORDERED_NAME_DICTIONARY_TYPE:
     283             :     case NAME_DICTIONARY_TYPE:
     284             :     case GLOBAL_DICTIONARY_TYPE:
     285             :     case NUMBER_DICTIONARY_TYPE:
     286             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
     287             :     case STRING_TABLE_TYPE:
     288             :     case EPHEMERON_HASH_TABLE_TYPE:
     289             :     case WEAK_FIXED_ARRAY_TYPE:
     290             :     case WEAK_ARRAY_LIST_TYPE:
     291             :     case FIXED_DOUBLE_ARRAY_TYPE:
     292             :     case FEEDBACK_METADATA_TYPE:
     293             :     case BYTE_ARRAY_TYPE:
     294             :     case BYTECODE_ARRAY_TYPE:
     295             :     case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
     296             :     case ARRAY_BOILERPLATE_DESCRIPTION_TYPE:
     297             :     case DESCRIPTOR_ARRAY_TYPE:
     298             :     case TRANSITION_ARRAY_TYPE:
     299             :     case FEEDBACK_CELL_TYPE:
     300             :     case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
     301             :     case FEEDBACK_VECTOR_TYPE:
     302             :     case PROPERTY_ARRAY_TYPE:
     303             :     case FOREIGN_TYPE:
     304             :     case SCOPE_INFO_TYPE:
     305             :     case SCRIPT_CONTEXT_TABLE_TYPE:
     306             :     case AWAIT_CONTEXT_TYPE:
     307             :     case BLOCK_CONTEXT_TYPE:
     308             :     case CATCH_CONTEXT_TYPE:
     309             :     case DEBUG_EVALUATE_CONTEXT_TYPE:
     310             :     case EVAL_CONTEXT_TYPE:
     311             :     case FUNCTION_CONTEXT_TYPE:
     312             :     case MODULE_CONTEXT_TYPE:
     313             :     case NATIVE_CONTEXT_TYPE:
     314             :     case SCRIPT_CONTEXT_TYPE:
     315             :     case WITH_CONTEXT_TYPE:
     316             :     case SCRIPT_TYPE:
     317             :     case CODE_TYPE:
     318             :     case PROPERTY_CELL_TYPE:
     319             :     case MODULE_TYPE:
     320             :     case MODULE_INFO_ENTRY_TYPE:
     321             :     case CELL_TYPE:
     322             :     case PREPARSE_DATA_TYPE:
     323             :     case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE:
     324             :     case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE:
     325      938739 :       return kOtherInternal;
     326             : 
     327             :     // Remaining instance types are unsupported for now. If any of them do
     328             :     // require bit set types, they should get kOtherInternal.
     329             :     case MUTABLE_HEAP_NUMBER_TYPE:
     330             :     case FREE_SPACE_TYPE:
     331             : #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
     332             :   case FIXED_##TYPE##_ARRAY_TYPE:
     333             : 
     334             :       TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
     335             : #undef FIXED_TYPED_ARRAY_CASE
     336             :     case FILLER_TYPE:
     337             :     case ACCESS_CHECK_INFO_TYPE:
     338             :     case ASM_WASM_DATA_TYPE:
     339             :     case CALL_HANDLER_INFO_TYPE:
     340             :     case INTERCEPTOR_INFO_TYPE:
     341             :     case OBJECT_TEMPLATE_INFO_TYPE:
     342             :     case ALLOCATION_MEMENTO_TYPE:
     343             :     case ALIASED_ARGUMENTS_ENTRY_TYPE:
     344             :     case PROMISE_CAPABILITY_TYPE:
     345             :     case PROMISE_REACTION_TYPE:
     346             :     case CLASS_POSITIONS_TYPE:
     347             :     case DEBUG_INFO_TYPE:
     348             :     case STACK_FRAME_INFO_TYPE:
     349             :     case STACK_TRACE_FRAME_TYPE:
     350             :     case SMALL_ORDERED_HASH_MAP_TYPE:
     351             :     case SMALL_ORDERED_HASH_SET_TYPE:
     352             :     case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
     353             :     case PROTOTYPE_INFO_TYPE:
     354             :     case INTERPRETER_DATA_TYPE:
     355             :     case TUPLE2_TYPE:
     356             :     case TUPLE3_TYPE:
     357             :     case ENUM_CACHE_TYPE:
     358             :     case WASM_DEBUG_INFO_TYPE:
     359             :     case WASM_EXCEPTION_TAG_TYPE:
     360             :     case WASM_EXPORTED_FUNCTION_DATA_TYPE:
     361             :     case LOAD_HANDLER_TYPE:
     362             :     case STORE_HANDLER_TYPE:
     363             :     case ASYNC_GENERATOR_REQUEST_TYPE:
     364             :     case CODE_DATA_CONTAINER_TYPE:
     365             :     case CALLBACK_TASK_TYPE:
     366             :     case CALLABLE_TASK_TYPE:
     367             :     case PROMISE_FULFILL_REACTION_JOB_TASK_TYPE:
     368             :     case PROMISE_REJECT_REACTION_JOB_TASK_TYPE:
     369             :     case PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE:
     370             :     case FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE:
     371           0 :       UNREACHABLE();
     372             :   }
     373           0 :   UNREACHABLE();
     374             : }
     375             : 
     376             : // Explicit instantiation.
     377             : template Type::bitset BitsetType::Lub<MapRef>(const MapRef& map);
     378             : 
     379           0 : Type::bitset BitsetType::Lub(double value) {
     380             :   DisallowHeapAllocation no_allocation;
     381           0 :   if (IsMinusZero(value)) return kMinusZero;
     382           0 :   if (std::isnan(value)) return kNaN;
     383           0 :   if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
     384             :   return kOtherNumber;
     385             : }
     386             : 
     387             : // Minimum values of plain numeric bitsets.
     388             : const BitsetType::Boundary BitsetType::BoundariesArray[] = {
     389             :     {kOtherNumber, kPlainNumber, -V8_INFINITY},
     390             :     {kOtherSigned32, kNegative32, kMinInt},
     391             :     {kNegative31, kNegative31, -0x40000000},
     392             :     {kUnsigned30, kUnsigned30, 0},
     393             :     {kOtherUnsigned31, kUnsigned31, 0x40000000},
     394             :     {kOtherUnsigned32, kUnsigned32, 0x80000000},
     395             :     {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
     396             : 
     397             : const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; }
     398             : 
     399             : size_t BitsetType::BoundariesSize() {
     400             :   // Windows doesn't like arraysize here.
     401             :   // return arraysize(BoundariesArray);
     402             :   return 7;
     403             : }
     404             : 
     405       12257 : Type::bitset BitsetType::ExpandInternals(Type::bitset bits) {
     406             :   DCHECK_IMPLIES(bits & kOtherOneByteString,
     407             :                  bits & kNonEmptyInternalizedOneByteString);
     408             :   DCHECK_IMPLIES(bits & kOtherTwoByteString,
     409             :                  bits & kNonEmptyInternalizedTwoByteString);
     410             :   DisallowHeapAllocation no_allocation;
     411       12596 :   if (!(bits & kPlainNumber)) return bits;  // Shortcut.
     412             :   const Boundary* boundaries = Boundaries();
     413           0 :   for (size_t i = 0; i < BoundariesSize(); ++i) {
     414             :     DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external));
     415           0 :     if (bits & boundaries[i].internal) bits |= boundaries[i].external;
     416             :   }
     417             :   return bits;
     418             : }
     419             : 
     420           0 : Type::bitset BitsetType::Lub(double min, double max) {
     421             :   DisallowHeapAllocation no_allocation;
     422             :   int lub = kNone;
     423             :   const Boundary* mins = Boundaries();
     424             : 
     425   191948617 :   for (size_t i = 1; i < BoundariesSize(); ++i) {
     426    97685520 :     if (min < mins[i].min) {
     427    57152311 :       lub |= mins[i - 1].internal;
     428    57152311 :       if (max < mins[i].min) return lub;
     429             :     }
     430             :   }
     431     8986347 :   return lub | mins[BoundariesSize() - 1].internal;
     432             : }
     433             : 
     434    15637032 : Type::bitset BitsetType::NumberBits(bitset bits) { return bits & kPlainNumber; }
     435             : 
     436    41282133 : Type::bitset BitsetType::Glb(double min, double max) {
     437             :   DisallowHeapAllocation no_allocation;
     438             :   int glb = kNone;
     439             :   const Boundary* mins = Boundaries();
     440             : 
     441             :   // If the range does not touch 0, the bound is empty.
     442    41282133 :   if (max < -1 || min > 0) return glb;
     443             : 
     444   137683501 :   for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
     445   122614350 :     if (min <= mins[i].min) {
     446    92102088 :       if (max + 1 < mins[i + 1].min) break;
     447    77227304 :       glb |= mins[i].external;
     448             :     }
     449             :   }
     450             :   // OtherNumber also contains float numbers, so it can never be
     451             :   // in the greatest lower bound.
     452    29943935 :   return glb & ~(kOtherNumber);
     453             : }
     454             : 
     455     7164393 : double BitsetType::Min(bitset bits) {
     456             :   DisallowHeapAllocation no_allocation;
     457             :   DCHECK(Is(bits, kNumber));
     458             :   DCHECK(!Is(bits, kNaN));
     459             :   const Boundary* mins = Boundaries();
     460     7164393 :   bool mz = bits & kMinusZero;
     461    24188615 :   for (size_t i = 0; i < BoundariesSize(); ++i) {
     462    31312686 :     if (Is(mins[i].internal, bits)) {
     463     7197274 :       return mz ? std::min(0.0, mins[i].min) : mins[i].min;
     464             :     }
     465             :   }
     466             :   DCHECK(mz);
     467             :   return 0;
     468             : }
     469             : 
     470     7346555 : double BitsetType::Max(bitset bits) {
     471             :   DisallowHeapAllocation no_allocation;
     472             :   DCHECK(Is(bits, kNumber));
     473             :   DCHECK(!Is(bits, kNaN));
     474             :   const Boundary* mins = Boundaries();
     475     7346555 :   bool mz = bits & kMinusZero;
     476     7346555 :   if (BitsetType::Is(mins[BoundariesSize() - 1].internal, bits)) {
     477             :     return +V8_INFINITY;
     478             :   }
     479    10742405 :   for (size_t i = BoundariesSize() - 1; i-- > 0;) {
     480    21453346 :     if (Is(mins[i].internal, bits)) {
     481     6175546 :       return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1;
     482             :     }
     483             :   }
     484             :   DCHECK(mz);
     485             :   return 0;
     486             : }
     487             : 
     488             : // static
     489     1640802 : bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
     490             :   // Not an integer, not NaN, and not -0.
     491     3281604 :   return !std::isnan(value) && !RangeType::IsInteger(value) &&
     492     1640802 :          !IsMinusZero(value);
     493             : }
     494             : 
     495           0 : HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
     496             :                                    const HeapObjectRef& heap_ref)
     497    18423310 :     : TypeBase(kHeapConstant), bitset_(bitset), heap_ref_(heap_ref) {}
     498             : 
     499     2047977 : Handle<HeapObject> HeapConstantType::Value() const {
     500    23745135 :   return heap_ref_.object();
     501             : }
     502             : 
     503             : // -----------------------------------------------------------------------------
     504             : // Predicates.
     505             : 
     506    15708147 : bool Type::SimplyEquals(Type that) const {
     507             :   DisallowHeapAllocation no_allocation;
     508    15708147 :   if (this->IsHeapConstant()) {
     509    23416051 :     return that.IsHeapConstant() &&
     510    10848539 :            this->AsHeapConstant()->Value().address() ==
     511    10848536 :                that.AsHeapConstant()->Value().address();
     512             :   }
     513     3140632 :   if (this->IsOtherNumberConstant()) {
     514     3964980 :     return that.IsOtherNumberConstant() &&
     515             :            this->AsOtherNumberConstant()->Value() ==
     516             :                that.AsOtherNumberConstant()->Value();
     517             :   }
     518      330806 :   if (this->IsRange()) {
     519      661617 :     if (that.IsHeapConstant() || that.IsOtherNumberConstant()) return false;
     520             :   }
     521           0 :   if (this->IsTuple()) {
     522           0 :     if (!that.IsTuple()) return false;
     523             :     const TupleType* this_tuple = this->AsTuple();
     524             :     const TupleType* that_tuple = that.AsTuple();
     525           0 :     if (this_tuple->Arity() != that_tuple->Arity()) {
     526             :       return false;
     527             :     }
     528           0 :     for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
     529           0 :       if (!this_tuple->Element(i).Equals(that_tuple->Element(i))) return false;
     530             :     }
     531             :     return true;
     532             :   }
     533           0 :   UNREACHABLE();
     534             : }
     535             : 
     536             : // Check if [this] <= [that].
     537   399554280 : bool Type::SlowIs(Type that) const {
     538             :   DisallowHeapAllocation no_allocation;
     539             : 
     540             :   // Fast bitset cases
     541   399554280 :   if (that.IsBitset()) {
     542   553598175 :     return BitsetType::Is(this->BitsetLub(), that.AsBitset());
     543             :   }
     544             : 
     545   122758623 :   if (this->IsBitset()) {
     546    68430697 :     return BitsetType::Is(this->AsBitset(), that.BitsetGlb());
     547             :   }
     548             : 
     549             :   // (T1 \/ ... \/ Tn) <= T  if  (T1 <= T) /\ ... /\ (Tn <= T)
     550    88542923 :   if (this->IsUnion()) {
     551    24987812 :     for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
     552    18958354 :       if (!this->AsUnion()->Get(i).Is(that)) return false;
     553             :     }
     554             :     return true;
     555             :   }
     556             : 
     557             :   // T <= (T1 \/ ... \/ Tn)  if  (T <= T1) \/ ... \/ (T <= Tn)
     558    74158923 :   if (that.IsUnion()) {
     559    51272487 :     for (int i = 0, n = that.AsUnion()->Length(); i < n; ++i) {
     560    27611581 :       if (this->Is(that.AsUnion()->Get(i))) return true;
     561    24149374 :       if (i > 1 && this->IsRange()) return false;  // Shortcut.
     562             :     }
     563             :     return false;
     564             :   }
     565             : 
     566    61672668 :   if (that.IsRange()) {
     567    66304404 :     return (this->IsRange() && Contains(that.AsRange(), this->AsRange()));
     568             :   }
     569    18880971 :   if (this->IsRange()) return false;
     570             : 
     571    15336148 :   return this->SimplyEquals(that);
     572             : }
     573             : 
     574             : // Check if [this] and [that] overlap.
     575    21066917 : bool Type::Maybe(Type that) const {
     576             :   DisallowHeapAllocation no_allocation;
     577             : 
     578    21066917 :   if (BitsetType::IsNone(this->BitsetLub() & that.BitsetLub())) return false;
     579             : 
     580             :   // (T1 \/ ... \/ Tn) overlaps T  if  (T1 overlaps T) \/ ... \/ (Tn overlaps T)
     581     9898234 :   if (this->IsUnion()) {
     582     1113718 :     for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
     583      693043 :       if (this->AsUnion()->Get(i).Maybe(that)) return true;
     584             :     }
     585             :     return false;
     586             :   }
     587             : 
     588             :   // T overlaps (T1 \/ ... \/ Tn)  if  (T overlaps T1) \/ ... \/ (T overlaps Tn)
     589     9469254 :   if (that.IsUnion()) {
     590      811769 :     for (int i = 0, n = that.AsUnion()->Length(); i < n; ++i) {
     591      416159 :       if (this->Maybe(that.AsUnion()->Get(i))) return true;
     592             :     }
     593             :     return false;
     594             :   }
     595             : 
     596     9249241 :   if (this->IsBitset() && that.IsBitset()) return true;
     597             : 
     598     4935306 :   if (this->IsRange()) {
     599     2375160 :     if (that.IsRange()) {
     600     1255504 :       return Overlap(this->AsRange(), that.AsRange());
     601             :     }
     602     1119656 :     if (that.IsBitset()) {
     603             :       bitset number_bits = BitsetType::NumberBits(that.AsBitset());
     604      789322 :       if (number_bits == BitsetType::kNone) {
     605             :         return false;
     606             :       }
     607     1578536 :       double min = std::max(BitsetType::Min(number_bits), this->Min());
     608     1578323 :       double max = std::min(BitsetType::Max(number_bits), this->Max());
     609      789113 :       return min <= max;
     610             :     }
     611             :   }
     612     2890480 :   if (that.IsRange()) {
     613     1073272 :     return that.Maybe(*this);  // This case is handled above.
     614             :   }
     615             : 
     616     1817208 :   if (this->IsBitset() || that.IsBitset()) return true;
     617             : 
     618      369788 :   return this->SimplyEquals(that);
     619             : }
     620             : 
     621             : // Return the range in [this], or [nullptr].
     622    37215725 : Type Type::GetRange() const {
     623             :   DisallowHeapAllocation no_allocation;
     624    37215725 :   if (this->IsRange()) return *this;
     625    43833042 :   if (this->IsUnion() && this->AsUnion()->Get(1).IsRange()) {
     626             :     return this->AsUnion()->Get(1);
     627             :   }
     628    19629615 :   return nullptr;
     629             : }
     630             : 
     631           0 : bool UnionType::Wellformed() const {
     632             :   DisallowHeapAllocation no_allocation;
     633             :   // This checks the invariants of the union representation:
     634             :   // 1. There are at least two elements.
     635             :   // 2. The first element is a bitset, no other element is a bitset.
     636             :   // 3. At most one element is a range, and it must be the second one.
     637             :   // 4. No element is itself a union.
     638             :   // 5. No element (except the bitset) is a subtype of any other.
     639             :   // 6. If there is a range, then the bitset type does not contain
     640             :   //    plain number bits.
     641             :   DCHECK_LE(2, this->Length());      // (1)
     642             :   DCHECK(this->Get(0).IsBitset());   // (2a)
     643             : 
     644             :   for (int i = 0; i < this->Length(); ++i) {
     645             :     if (i != 0) DCHECK(!this->Get(i).IsBitset());  // (2b)
     646             :     if (i != 1) DCHECK(!this->Get(i).IsRange());   // (3)
     647             :     DCHECK(!this->Get(i).IsUnion());               // (4)
     648             :     for (int j = 0; j < this->Length(); ++j) {
     649             :       if (i != j && i != 0) DCHECK(!this->Get(i).Is(this->Get(j)));  // (5)
     650             :     }
     651             :   }
     652             :   DCHECK(!this->Get(1).IsRange() ||
     653             :          (BitsetType::NumberBits(this->Get(0).AsBitset()) ==
     654             :           BitsetType::kNone));  // (6)
     655           0 :   return true;
     656             : }
     657             : 
     658             : // -----------------------------------------------------------------------------
     659             : // Union and intersection
     660             : 
     661    27309883 : Type Type::Intersect(Type type1, Type type2, Zone* zone) {
     662             :   // Fast case: bit sets.
     663    43688385 :   if (type1.IsBitset() && type2.IsBitset()) {
     664    15584645 :     return NewBitset(type1.AsBitset() & type2.AsBitset());
     665             :   }
     666             : 
     667             :   // Fast case: top or bottom types.
     668    23426152 :   if (type1.IsNone() || type2.IsAny()) return type1;  // Shortcut.
     669    11491030 :   if (type2.IsNone() || type1.IsAny()) return type2;  // Shortcut.
     670             : 
     671             :   // Semi-fast case.
     672    11401316 :   if (type1.Is(type2)) return type1;
     673     3672896 :   if (type2.Is(type1)) return type2;
     674             : 
     675             :   // Slow case: create union.
     676             : 
     677             :   // Semantic subtyping check - this is needed for consistency with the
     678             :   // semi-fast case above.
     679     1932966 :   if (type1.Is(type2)) {
     680           0 :     type2 = Any();
     681     1932975 :   } else if (type2.Is(type1)) {
     682           0 :     type1 = Any();
     683             :   }
     684             : 
     685     1932975 :   bitset bits = type1.BitsetGlb() & type2.BitsetGlb();
     686     1932932 :   int size1 = type1.IsUnion() ? type1.AsUnion()->Length() : 1;
     687     1932932 :   int size2 = type2.IsUnion() ? type2.AsUnion()->Length() : 1;
     688             :   int size;
     689     1932932 :   if (base::bits::SignedAddOverflow32(size1, size2, &size)) return Any();
     690     1932932 :   if (base::bits::SignedAddOverflow32(size, 2, &size)) return Any();
     691     1932932 :   UnionType* result = UnionType::New(size, zone);
     692             :   size = 0;
     693             : 
     694             :   // Deal with bitsets.
     695             :   result->Set(size++, NewBitset(bits));
     696             : 
     697     1932909 :   RangeType::Limits lims = RangeType::Limits::Empty();
     698     1932909 :   size = IntersectAux(type1, type2, result, size, &lims, zone);
     699             : 
     700             :   // If the range is not empty, then insert it into the union and
     701             :   // remove the number bits from the bitset.
     702     1932906 :   if (!lims.IsEmpty()) {
     703      641025 :     size = UpdateRange(Type::Range(lims, zone), result, size, zone);
     704             : 
     705             :     // Remove the number bits.
     706             :     bitset number_bits = BitsetType::NumberBits(bits);
     707      641057 :     bits &= ~number_bits;
     708             :     result->Set(0, NewBitset(bits));
     709             :   }
     710     1932931 :   return NormalizeUnion(result, size, zone);
     711             : }
     712             : 
     713      641055 : int Type::UpdateRange(Type range, UnionType* result, int size, Zone* zone) {
     714      641055 :   if (size == 1) {
     715      628382 :     result->Set(size++, range);
     716             :   } else {
     717             :     // Make space for the range.
     718       12673 :     result->Set(size++, result->Get(1));
     719             :     result->Set(1, range);
     720             :   }
     721             : 
     722             :   // Remove any components that just got subsumed.
     723      654264 :   for (int i = 2; i < size;) {
     724       26418 :     if (result->Get(i).Is(range)) {
     725           0 :       result->Set(i, result->Get(--size));
     726             :     } else {
     727       13209 :       ++i;
     728             :     }
     729             :   }
     730      641055 :   return size;
     731             : }
     732             : 
     733      323096 : RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) {
     734             :   bitset number_bits = BitsetType::NumberBits(bits);
     735             : 
     736      323096 :   if (number_bits == BitsetType::kNone) {
     737             :     return RangeType::Limits::Empty();
     738             :   }
     739             : 
     740             :   return RangeType::Limits(BitsetType::Min(number_bits),
     741      323096 :                            BitsetType::Max(number_bits));
     742             : }
     743             : 
     744      323094 : RangeType::Limits Type::IntersectRangeAndBitset(Type range, Type bitset,
     745             :                                                 Zone* zone) {
     746             :   RangeType::Limits range_lims(range.AsRange());
     747      323094 :   RangeType::Limits bitset_lims = ToLimits(bitset.AsBitset(), zone);
     748      323094 :   return RangeType::Limits::Intersect(range_lims, bitset_lims);
     749             : }
     750             : 
     751     3359216 : int Type::IntersectAux(Type lhs, Type rhs, UnionType* result, int size,
     752             :                        RangeType::Limits* lims, Zone* zone) {
     753     3359216 :   if (lhs.IsUnion()) {
     754     2361242 :     for (int i = 0, n = lhs.AsUnion()->Length(); i < n; ++i) {
     755      984748 :       size = IntersectAux(lhs.AsUnion()->Get(i), rhs, result, size, lims, zone);
     756             :     }
     757             :     return size;
     758             :   }
     759     2967410 :   if (rhs.IsUnion()) {
     760      606070 :     for (int i = 0, n = rhs.AsUnion()->Length(); i < n; ++i) {
     761      247257 :       size = IntersectAux(lhs, rhs.AsUnion()->Get(i), result, size, lims, zone);
     762             :     }
     763             :     return size;
     764             :   }
     765             : 
     766     2855848 :   if (BitsetType::IsNone(lhs.BitsetLub() & rhs.BitsetLub())) return size;
     767             : 
     768     1048996 :   if (lhs.IsRange()) {
     769      801225 :     if (rhs.IsBitset()) {
     770      323094 :       RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
     771             : 
     772      323093 :       if (!lim.IsEmpty()) {
     773      323093 :         *lims = RangeType::Limits::Union(lim, *lims);
     774             :       }
     775             :       return size;
     776             :     }
     777      478131 :     if (rhs.IsRange()) {
     778             :       RangeType::Limits lim = RangeType::Limits::Intersect(
     779             :           RangeType::Limits(lhs.AsRange()), RangeType::Limits(rhs.AsRange()));
     780      318264 :       if (!lim.IsEmpty()) {
     781      318051 :         *lims = RangeType::Limits::Union(lim, *lims);
     782             :       }
     783             :     }
     784             :     return size;
     785             :   }
     786      247771 :   if (rhs.IsRange()) {
     787             :     // This case is handled symmetrically above.
     788      194543 :     return IntersectAux(rhs, lhs, result, size, lims, zone);
     789             :   }
     790       53228 :   if (lhs.IsBitset() || rhs.IsBitset()) {
     791       51032 :     return AddToUnion(lhs.IsBitset() ? rhs : lhs, result, size, zone);
     792             :   }
     793        2196 :   if (lhs.SimplyEquals(rhs)) {
     794         588 :     return AddToUnion(lhs, result, size, zone);
     795             :   }
     796             :   return size;
     797             : }
     798             : 
     799             : // Make sure that we produce a well-formed range and bitset:
     800             : // If the range is non-empty, the number bits in the bitset should be
     801             : // clear. Moreover, if we have a canonical range (such as Signed32),
     802             : // we want to produce a bitset rather than a range.
     803    13883557 : Type Type::NormalizeRangeAndBitset(Type range, bitset* bits, Zone* zone) {
     804             :   // Fast path: If the bitset does not mention numbers, we can just keep the
     805             :   // range.
     806    13883557 :   bitset number_bits = BitsetType::NumberBits(*bits);
     807    13883557 :   if (number_bits == 0) {
     808     7502339 :     return range;
     809             :   }
     810             : 
     811             :   // If the range is semantically contained within the bitset, return None and
     812             :   // leave the bitset untouched.
     813     6381218 :   bitset range_lub = range.BitsetLub();
     814    12762436 :   if (BitsetType::Is(range_lub, *bits)) {
     815             :     return None();
     816             :   }
     817             : 
     818             :   // Slow path: reconcile the bitset range and the range.
     819     5470954 :   double bitset_min = BitsetType::Min(number_bits);
     820     5470954 :   double bitset_max = BitsetType::Max(number_bits);
     821             : 
     822     5470954 :   double range_min = range.Min();
     823     5470954 :   double range_max = range.Max();
     824             : 
     825             :   // Remove the number bits from the bitset, they would just confuse us now.
     826             :   // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
     827             :   // case we already returned after the subtype check above.
     828     5470954 :   *bits &= ~number_bits;
     829             : 
     830     5470954 :   if (range_min <= bitset_min && range_max >= bitset_max) {
     831             :     // Bitset is contained within the range, just return the range.
     832     5075514 :     return range;
     833             :   }
     834             : 
     835      395440 :   if (bitset_min < range_min) {
     836             :     range_min = bitset_min;
     837             :   }
     838      395440 :   if (bitset_max > range_max) {
     839             :     range_max = bitset_max;
     840             :   }
     841             :   return Type::Range(range_min, range_max, zone);
     842             : }
     843             : 
     844     7917854 : Type Type::NewConstant(double value, Zone* zone) {
     845     7917854 :   if (RangeType::IsInteger(value)) {
     846             :     return Range(value, value, zone);
     847     1659221 :   } else if (IsMinusZero(value)) {
     848             :     return Type::MinusZero();
     849     1645838 :   } else if (std::isnan(value)) {
     850             :     return Type::NaN();
     851             :   }
     852             : 
     853             :   DCHECK(OtherNumberConstantType::IsOtherNumberConstant(value));
     854             :   return OtherNumberConstant(value, zone);
     855             : }
     856             : 
     857    11570179 : Type Type::NewConstant(JSHeapBroker* broker, Handle<i::Object> value,
     858             :                        Zone* zone) {
     859    11570179 :   ObjectRef ref(broker, value);
     860    11570174 :   if (ref.IsSmi()) {
     861      642303 :     return NewConstant(static_cast<double>(ref.AsSmi()), zone);
     862             :   }
     863    10927871 :   if (ref.IsHeapNumber()) {
     864     2718620 :     return NewConstant(ref.AsHeapNumber().value(), zone);
     865             :   }
     866     8209248 :   if (ref.IsString() && !ref.IsInternalizedString()) {
     867         339 :     return For(ref.AsString().map());
     868             :   }
     869    16417805 :   return HeapConstant(ref.AsHeapObject(), zone);
     870             : }
     871             : 
     872    48177781 : Type Type::Union(Type type1, Type type2, Zone* zone) {
     873             :   // Fast case: bit sets.
     874    73375040 :   if (type1.IsBitset() && type2.IsBitset()) {
     875    15981864 :     return NewBitset(type1.AsBitset() | type2.AsBitset());
     876             :   }
     877             : 
     878             :   // Fast case: top or bottom types.
     879    64225940 :   if (type1.IsAny() || type2.IsNone()) return type1;
     880    30774910 :   if (type2.IsAny() || type1.IsNone()) return type2;
     881             : 
     882             :   // Semi-fast case.
     883    27740311 :   if (type1.Is(type2)) return type2;
     884    25702196 :   if (type2.Is(type1)) return type1;
     885             : 
     886             :   // Slow case: create union.
     887    18411038 :   int size1 = type1.IsUnion() ? type1.AsUnion()->Length() : 1;
     888    18411038 :   int size2 = type2.IsUnion() ? type2.AsUnion()->Length() : 1;
     889             :   int size;
     890    18411038 :   if (base::bits::SignedAddOverflow32(size1, size2, &size)) return Any();
     891    18411038 :   if (base::bits::SignedAddOverflow32(size, 2, &size)) return Any();
     892    18411038 :   UnionType* result = UnionType::New(size, zone);
     893             :   size = 0;
     894             : 
     895             :   // Compute the new bitset.
     896    18411030 :   bitset new_bitset = type1.BitsetGlb() | type2.BitsetGlb();
     897             : 
     898             :   // Deal with ranges.
     899             :   Type range = None();
     900    18411022 :   Type range1 = type1.GetRange();
     901    18411023 :   Type range2 = type2.GetRange();
     902    18411053 :   if (range1 != nullptr && range2 != nullptr) {
     903             :     RangeType::Limits lims =
     904             :         RangeType::Limits::Union(RangeType::Limits(range1.AsRange()),
     905             :                                  RangeType::Limits(range2.AsRange()));
     906     3317347 :     Type union_range = Type::Range(lims, zone);
     907     3317347 :     range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
     908    15093707 :   } else if (range1 != nullptr) {
     909     5906573 :     range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
     910     9187134 :   } else if (range2 != nullptr) {
     911     4659652 :     range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
     912             :   }
     913    18411053 :   Type bits = NewBitset(new_bitset);
     914             :   result->Set(size++, bits);
     915    18411053 :   if (!range.IsNone()) result->Set(size++, range);
     916             : 
     917    18411053 :   size = AddToUnion(type1, result, size, zone);
     918    18411035 :   size = AddToUnion(type2, result, size, zone);
     919    18411043 :   return NormalizeUnion(result, size, zone);
     920             : }
     921             : 
     922             : // Add [type] to [result] unless [type] is bitset, range, or already subsumed.
     923             : // Return new size of [result].
     924    75631863 : int Type::AddToUnion(Type type, UnionType* result, int size, Zone* zone) {
     925   128403843 :   if (type.IsBitset() || type.IsRange()) return size;
     926    35571170 :   if (type.IsUnion()) {
     927    91184702 :     for (int i = 0, n = type.AsUnion()->Length(); i < n; ++i) {
     928    38758362 :       size = AddToUnion(type.AsUnion()->Get(i), result, size, zone);
     929             :     }
     930             :     return size;
     931             :   }
     932   106718748 :   for (int i = 0; i < size; ++i) {
     933    44178478 :     if (type.Is(result->Get(i))) return size;
     934             :   }
     935    20132474 :   result->Set(size++, type);
     936    20132474 :   return size;
     937             : }
     938             : 
     939    20343977 : Type Type::NormalizeUnion(UnionType* unioned, int size, Zone* zone) {
     940             :   DCHECK_LE(1, size);
     941             :   DCHECK(unioned->Get(0).IsBitset());
     942             :   // If the union has just one element, return it.
     943    20343977 :   if (size == 1) {
     944             :     return unioned->Get(0);
     945             :   }
     946             :   bitset bits = unioned->Get(0).AsBitset();
     947             :   // If the union only consists of a range, we can get rid of the union.
     948    18563804 :   if (size == 2 && bits == BitsetType::kNone) {
     949     1848314 :     if (unioned->Get(1).IsRange()) {
     950             :       return Type::Range(unioned->Get(1).AsRange()->Min(),
     951             :                          unioned->Get(1).AsRange()->Max(), zone);
     952             :     }
     953             :   }
     954             :   unioned->Shrink(size);
     955             :   SLOW_DCHECK(unioned->Wellformed());
     956    16716659 :   return Type(unioned);
     957             : }
     958             : 
     959       86394 : int Type::NumConstants() const {
     960             :   DisallowHeapAllocation no_allocation;
     961      171534 :   if (this->IsHeapConstant() || this->IsOtherNumberConstant()) {
     962             :     return 1;
     963       84002 :   } else if (this->IsUnion()) {
     964             :     int result = 0;
     965       39956 :     for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
     966       16462 :       if (this->AsUnion()->Get(i).IsHeapConstant()) ++result;
     967             :     }
     968             :     return result;
     969             :   } else {
     970             :     return 0;
     971             :   }
     972             : }
     973             : 
     974             : // -----------------------------------------------------------------------------
     975             : // Printing.
     976             : 
     977      142389 : const char* BitsetType::Name(bitset bits) {
     978      142389 :   switch (bits) {
     979             : #define RETURN_NAMED_TYPE(type, value) \
     980             :   case k##type:                        \
     981             :     return #type;
     982           0 :     PROPER_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
     983           0 :     INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
     984             : #undef RETURN_NAMED_TYPE
     985             : 
     986             :     default:
     987           0 :       return nullptr;
     988             :   }
     989             : }
     990             : 
     991      142389 : void BitsetType::Print(std::ostream& os,  // NOLINT
     992             :                        bitset bits) {
     993             :   DisallowHeapAllocation no_allocation;
     994      142389 :   const char* name = Name(bits);
     995      142389 :   if (name != nullptr) {
     996      142389 :     os << name;
     997             :     return;
     998             :   }
     999             : 
    1000             :   // clang-format off
    1001             :   static const bitset named_bitsets[] = {
    1002             : #define BITSET_CONSTANT(type, value) k##type,
    1003             :     INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
    1004             :     PROPER_BITSET_TYPE_LIST(BITSET_CONSTANT)
    1005             : #undef BITSET_CONSTANT
    1006             :   };
    1007             :   // clang-format on
    1008             : 
    1009             :   bool is_first = true;
    1010           0 :   os << "(";
    1011           0 :   for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
    1012           0 :     bitset subset = named_bitsets[i];
    1013           0 :     if ((bits & subset) == subset) {
    1014           0 :       if (!is_first) os << " | ";
    1015             :       is_first = false;
    1016           0 :       os << Name(subset);
    1017           0 :       bits -= subset;
    1018             :     }
    1019             :   }
    1020             :   DCHECK_EQ(0, bits);
    1021           0 :   os << ")";
    1022             : }
    1023             : 
    1024      142517 : void Type::PrintTo(std::ostream& os) const {
    1025             :   DisallowHeapAllocation no_allocation;
    1026      142517 :   if (this->IsBitset()) {
    1027      142389 :     BitsetType::Print(os, this->AsBitset());
    1028         128 :   } else if (this->IsHeapConstant()) {
    1029         160 :     os << "HeapConstant(" << Brief(*this->AsHeapConstant()->Value()) << ")";
    1030          48 :   } else if (this->IsOtherNumberConstant()) {
    1031             :     os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value()
    1032           0 :        << ")";
    1033          48 :   } else if (this->IsRange()) {
    1034          29 :     std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
    1035          29 :     std::streamsize saved_precision = os.precision(0);
    1036             :     os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
    1037          29 :        << ")";
    1038          29 :     os.flags(saved_flags);
    1039          29 :     os.precision(saved_precision);
    1040          19 :   } else if (this->IsUnion()) {
    1041          19 :     os << "(";
    1042          95 :     for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
    1043          38 :       Type type_i = this->AsUnion()->Get(i);
    1044          38 :       if (i > 0) os << " | ";
    1045          38 :       os << type_i;
    1046             :     }
    1047          19 :     os << ")";
    1048           0 :   } else if (this->IsTuple()) {
    1049           0 :     os << "<";
    1050           0 :     for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
    1051           0 :       Type type_i = this->AsTuple()->Element(i);
    1052           0 :       if (i > 0) os << ", ";
    1053           0 :       os << type_i;
    1054             :     }
    1055           0 :     os << ">";
    1056             :   } else {
    1057           0 :     UNREACHABLE();
    1058             :   }
    1059      142517 : }
    1060             : 
    1061             : #ifdef DEBUG
    1062             : void Type::Print() const {
    1063             :   StdoutStream os;
    1064             :   PrintTo(os);
    1065             :   os << std::endl;
    1066             : }
    1067             : void BitsetType::Print(bitset bits) {
    1068             :   StdoutStream os;
    1069             :   Print(os, bits);
    1070             :   os << std::endl;
    1071             : }
    1072             : #endif
    1073             : 
    1074     6829747 : BitsetType::bitset BitsetType::SignedSmall() {
    1075     6829747 :   return SmiValuesAre31Bits() ? kSigned31 : kSigned32;
    1076             : }
    1077             : 
    1078      231946 : BitsetType::bitset BitsetType::UnsignedSmall() {
    1079      231946 :   return SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
    1080             : }
    1081             : 
    1082             : // static
    1083        1386 : Type Type::Tuple(Type first, Type second, Type third, Zone* zone) {
    1084        1386 :   TupleType* tuple = TupleType::New(3, zone);
    1085             :   tuple->InitElement(0, first);
    1086             :   tuple->InitElement(1, second);
    1087             :   tuple->InitElement(2, third);
    1088        1386 :   return FromTypeBase(tuple);
    1089             : }
    1090             : 
    1091             : // static
    1092           0 : Type Type::OtherNumberConstant(double value, Zone* zone) {
    1093     1640802 :   return FromTypeBase(OtherNumberConstantType::New(value, zone));
    1094             : }
    1095             : 
    1096             : // static
    1097    10214432 : Type Type::HeapConstant(JSHeapBroker* broker, Handle<i::Object> value,
    1098             :                         Zone* zone) {
    1099             :   return FromTypeBase(
    1100    20428890 :       HeapConstantType::New(HeapObjectRef(broker, value), zone));
    1101             : }
    1102             : 
    1103             : // static
    1104           0 : Type Type::HeapConstant(const HeapObjectRef& value, Zone* zone) {
    1105     8208894 :   return HeapConstantType::New(value, zone);
    1106             : }
    1107             : 
    1108             : // static
    1109     8936689 : Type Type::Range(double min, double max, Zone* zone) {
    1110     8936695 :   return FromTypeBase(RangeType::New(min, max, zone));
    1111             : }
    1112             : 
    1113             : // static
    1114           0 : Type Type::Range(RangeType::Limits lims, Zone* zone) {
    1115     3958378 :   return FromTypeBase(RangeType::New(lims, zone));
    1116             : }
    1117             : 
    1118             : // static
    1119           0 : Type Type::Union(int length, Zone* zone) {
    1120           0 :   return FromTypeBase(UnionType::New(length, zone));
    1121             : }
    1122             : 
    1123     2384088 : const HeapConstantType* Type::AsHeapConstant() const {
    1124             :   DCHECK(IsKind(TypeBase::kHeapConstant));
    1125     2384088 :   return static_cast<const HeapConstantType*>(ToTypeBase());
    1126             : }
    1127             : 
    1128          57 : const OtherNumberConstantType* Type::AsOtherNumberConstant() const {
    1129             :   DCHECK(IsKind(TypeBase::kOtherNumberConstant));
    1130          57 :   return static_cast<const OtherNumberConstantType*>(ToTypeBase());
    1131             : }
    1132             : 
    1133       45250 : const RangeType* Type::AsRange() const {
    1134             :   DCHECK(IsKind(TypeBase::kRange));
    1135       45250 :   return static_cast<const RangeType*>(ToTypeBase());
    1136             : }
    1137             : 
    1138        8316 : const TupleType* Type::AsTuple() const {
    1139             :   DCHECK(IsKind(TypeBase::kTuple));
    1140        8316 :   return static_cast<const TupleType*>(ToTypeBase());
    1141             : }
    1142             : 
    1143        7032 : const UnionType* Type::AsUnion() const {
    1144             :   DCHECK(IsKind(TypeBase::kUnion));
    1145        7032 :   return static_cast<const UnionType*>(ToTypeBase());
    1146             : }
    1147             : 
    1148      142345 : std::ostream& operator<<(std::ostream& os, Type type) {
    1149      142345 :   type.PrintTo(os);
    1150      142345 :   return os;
    1151             : }
    1152             : 
    1153             : }  // namespace compiler
    1154             : }  // namespace internal
    1155      121996 : }  // namespace v8

Generated by: LCOV version 1.10