LCOV - code coverage report
Current view: top level - src - code-stub-assembler.h (source / functions) Hit Total Coverage
Test: app.info Lines: 277 277 100.0 %
Date: 2019-01-20 Functions: 287 299 96.0 %

          Line data    Source code
       1             : // Copyright 2016 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             : #ifndef V8_CODE_STUB_ASSEMBLER_H_
       6             : #define V8_CODE_STUB_ASSEMBLER_H_
       7             : 
       8             : #include <functional>
       9             : 
      10             : #include "src/bailout-reason.h"
      11             : #include "src/base/macros.h"
      12             : #include "src/compiler/code-assembler.h"
      13             : #include "src/frames.h"
      14             : #include "src/globals.h"
      15             : #include "src/message-template.h"
      16             : #include "src/objects.h"
      17             : #include "src/objects/arguments.h"
      18             : #include "src/objects/bigint.h"
      19             : #include "src/objects/shared-function-info.h"
      20             : #include "src/objects/smi.h"
      21             : #include "src/roots.h"
      22             : 
      23             : #include "torque-generated/builtins-base-from-dsl-gen.h"
      24             : 
      25             : namespace v8 {
      26             : namespace internal {
      27             : 
      28             : class CallInterfaceDescriptor;
      29             : class CodeStubArguments;
      30             : class CodeStubAssembler;
      31             : class StatsCounter;
      32             : class StubCache;
      33             : 
      34             : enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
      35             : 
      36             : #define HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(V)                              \
      37             :   V(ArraySpeciesProtector, array_species_protector, ArraySpeciesProtector) \
      38             :   V(PromiseSpeciesProtector, promise_species_protector,                    \
      39             :     PromiseSpeciesProtector)                                               \
      40             :   V(TypedArraySpeciesProtector, typed_array_species_protector,             \
      41             :     TypedArraySpeciesProtector)                                            \
      42             :   V(RegExpSpeciesProtector, regexp_species_protector, RegExpSpeciesProtector)
      43             : 
      44             : #define HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V)                                \
      45             :   V(AccessorInfoMap, accessor_info_map, AccessorInfoMap)                       \
      46             :   V(AccessorPairMap, accessor_pair_map, AccessorPairMap)                       \
      47             :   V(AllocationSiteWithWeakNextMap, allocation_site_map, AllocationSiteMap)     \
      48             :   V(AllocationSiteWithoutWeakNextMap, allocation_site_without_weaknext_map,    \
      49             :     AllocationSiteWithoutWeakNextMap)                                          \
      50             :   V(BooleanMap, boolean_map, BooleanMap)                                       \
      51             :   V(CodeMap, code_map, CodeMap)                                                \
      52             :   V(EmptyFixedArray, empty_fixed_array, EmptyFixedArray)                       \
      53             :   V(EmptyPropertyDictionary, empty_property_dictionary,                        \
      54             :     EmptyPropertyDictionary)                                                   \
      55             :   V(EmptySlowElementDictionary, empty_slow_element_dictionary,                 \
      56             :     EmptySlowElementDictionary)                                                \
      57             :   V(empty_string, empty_string, EmptyString)                                   \
      58             :   V(FalseValue, false_value, False)                                            \
      59             :   V(FeedbackVectorMap, feedback_vector_map, FeedbackVectorMap)                 \
      60             :   V(FixedArrayMap, fixed_array_map, FixedArrayMap)                             \
      61             :   V(FixedCOWArrayMap, fixed_cow_array_map, FixedCOWArrayMap)                   \
      62             :   V(FixedDoubleArrayMap, fixed_double_array_map, FixedDoubleArrayMap)          \
      63             :   V(FunctionTemplateInfoMap, function_template_info_map,                       \
      64             :     FunctionTemplateInfoMap)                                                   \
      65             :   V(GlobalPropertyCellMap, global_property_cell_map, PropertyCellMap)          \
      66             :   V(has_instance_symbol, has_instance_symbol, HasInstanceSymbol)               \
      67             :   V(HeapNumberMap, heap_number_map, HeapNumberMap)                             \
      68             :   V(iterator_symbol, iterator_symbol, IteratorSymbol)                          \
      69             :   V(length_string, length_string, LengthString)                                \
      70             :   V(ManyClosuresCellMap, many_closures_cell_map, ManyClosuresCellMap)          \
      71             :   V(MetaMap, meta_map, MetaMap)                                                \
      72             :   V(MinusZeroValue, minus_zero_value, MinusZero)                               \
      73             :   V(MutableHeapNumberMap, mutable_heap_number_map, MutableHeapNumberMap)       \
      74             :   V(NanValue, nan_value, Nan)                                                  \
      75             :   V(NoClosuresCellMap, no_closures_cell_map, NoClosuresCellMap)                \
      76             :   V(NoFeedbackCellMap, no_feedback_cell_map, NoFeedbackCellMap)                \
      77             :   V(NullValue, null_value, Null)                                               \
      78             :   V(OneClosureCellMap, one_closure_cell_map, OneClosureCellMap)                \
      79             :   V(PreparseDataMap, preparse_data_map, PreparseDataMap)                       \
      80             :   V(prototype_string, prototype_string, PrototypeString)                       \
      81             :   V(SharedFunctionInfoMap, shared_function_info_map, SharedFunctionInfoMap)    \
      82             :   V(StoreHandler0Map, store_handler0_map, StoreHandler0Map)                    \
      83             :   V(SymbolMap, symbol_map, SymbolMap)                                          \
      84             :   V(TheHoleValue, the_hole_value, TheHole)                                     \
      85             :   V(TransitionArrayMap, transition_array_map, TransitionArrayMap)              \
      86             :   V(TrueValue, true_value, True)                                               \
      87             :   V(Tuple2Map, tuple2_map, Tuple2Map)                                          \
      88             :   V(Tuple3Map, tuple3_map, Tuple3Map)                                          \
      89             :   V(ArrayBoilerplateDescriptionMap, array_boilerplate_description_map,         \
      90             :     ArrayBoilerplateDescriptionMap)                                            \
      91             :   V(UncompiledDataWithoutPreparseDataMap,                                      \
      92             :     uncompiled_data_without_preparse_data_map,                                 \
      93             :     UncompiledDataWithoutPreparseDataMap)                                      \
      94             :   V(UncompiledDataWithPreparseDataMap, uncompiled_data_with_preparse_data_map, \
      95             :     UncompiledDataWithPreparseDataMap)                                         \
      96             :   V(UndefinedValue, undefined_value, Undefined)                                \
      97             :   V(WeakFixedArrayMap, weak_fixed_array_map, WeakFixedArrayMap)
      98             : 
      99             : #define HEAP_IMMOVABLE_OBJECT_LIST(V)   \
     100             :   HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(V) \
     101             :   HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V)
     102             : 
     103             : #ifdef DEBUG
     104             : #define CSA_CHECK(csa, x)                                        \
     105             :   (csa)->Check(                                                  \
     106             :       [&]() -> compiler::Node* {                                 \
     107             :         return implicit_cast<compiler::SloppyTNode<Word32T>>(x); \
     108             :       },                                                         \
     109             :       #x, __FILE__, __LINE__)
     110             : #else
     111             : #define CSA_CHECK(csa, x) (csa)->FastCheck(x)
     112             : #endif
     113             : 
     114             : #ifdef DEBUG
     115             : // Add stringified versions to the given values, except the first. That is,
     116             : // transform
     117             : //   x, a, b, c, d, e, f
     118             : // to
     119             : //   a, "a", b, "b", c, "c", d, "d", e, "e", f, "f"
     120             : //
     121             : // __VA_ARGS__  is ignored to allow the caller to pass through too many
     122             : // parameters, and the first element is ignored to support having no extra
     123             : // values without empty __VA_ARGS__ (which cause all sorts of problems with
     124             : // extra commas).
     125             : #define CSA_ASSERT_STRINGIFY_EXTRA_VALUES_5(_, v1, v2, v3, v4, v5, ...) \
     126             :   v1, #v1, v2, #v2, v3, #v3, v4, #v4, v5, #v5
     127             : 
     128             : // Stringify the given variable number of arguments. The arguments are trimmed
     129             : // to 5 if there are too many, and padded with nullptr if there are not enough.
     130             : #define CSA_ASSERT_STRINGIFY_EXTRA_VALUES(...)                                \
     131             :   CSA_ASSERT_STRINGIFY_EXTRA_VALUES_5(__VA_ARGS__, nullptr, nullptr, nullptr, \
     132             :                                       nullptr, nullptr)
     133             : 
     134             : #define CSA_ASSERT_GET_FIRST(x, ...) (x)
     135             : #define CSA_ASSERT_GET_FIRST_STR(x, ...) #x
     136             : 
     137             : // CSA_ASSERT(csa, <condition>, <extra values to print...>)
     138             : 
     139             : // We have to jump through some hoops to allow <extra values to print...> to be
     140             : // empty.
     141             : #define CSA_ASSERT(csa, ...)                                             \
     142             :   (csa)->Assert(                                                         \
     143             :       [&]() -> compiler::Node* {                                         \
     144             :         return implicit_cast<compiler::SloppyTNode<Word32T>>(            \
     145             :             EXPAND(CSA_ASSERT_GET_FIRST(__VA_ARGS__)));                  \
     146             :       },                                                                 \
     147             :       EXPAND(CSA_ASSERT_GET_FIRST_STR(__VA_ARGS__)), __FILE__, __LINE__, \
     148             :       CSA_ASSERT_STRINGIFY_EXTRA_VALUES(__VA_ARGS__))
     149             : 
     150             : // CSA_ASSERT_BRANCH(csa, [](Label* ok, Label* not_ok) {...},
     151             : //     <extra values to print...>)
     152             : 
     153             : #define CSA_ASSERT_BRANCH(csa, ...)                                      \
     154             :   (csa)->Assert(EXPAND(CSA_ASSERT_GET_FIRST(__VA_ARGS__)),               \
     155             :                 EXPAND(CSA_ASSERT_GET_FIRST_STR(__VA_ARGS__)), __FILE__, \
     156             :                 __LINE__, CSA_ASSERT_STRINGIFY_EXTRA_VALUES(__VA_ARGS__))
     157             : 
     158             : #define CSA_ASSERT_JS_ARGC_OP(csa, Op, op, expected)                       \
     159             :   (csa)->Assert(                                                           \
     160             :       [&]() -> compiler::Node* {                                           \
     161             :         compiler::Node* const argc =                                       \
     162             :             (csa)->Parameter(Descriptor::kJSActualArgumentsCount);         \
     163             :         return (csa)->Op(argc, (csa)->Int32Constant(expected));            \
     164             :       },                                                                   \
     165             :       "argc " #op " " #expected, __FILE__, __LINE__,                       \
     166             :       SmiFromInt32((csa)->Parameter(Descriptor::kJSActualArgumentsCount)), \
     167             :       "argc")
     168             : 
     169             : #define CSA_ASSERT_JS_ARGC_EQ(csa, expected) \
     170             :   CSA_ASSERT_JS_ARGC_OP(csa, Word32Equal, ==, expected)
     171             : 
     172             : #define CSA_DEBUG_INFO(name) \
     173             :   { #name, __FILE__, __LINE__ }
     174             : #define BIND(label) Bind(label, CSA_DEBUG_INFO(label))
     175             : #define VARIABLE(name, ...) \
     176             :   Variable name(this, CSA_DEBUG_INFO(name), __VA_ARGS__)
     177             : #define VARIABLE_CONSTRUCTOR(name, ...) \
     178             :   name(this, CSA_DEBUG_INFO(name), __VA_ARGS__)
     179             : #define TYPED_VARIABLE_DEF(type, name, ...) \
     180             :   TVariable<type> name(CSA_DEBUG_INFO(name), __VA_ARGS__)
     181             : #else  // DEBUG
     182             : #define CSA_ASSERT(csa, ...) ((void)0)
     183             : #define CSA_ASSERT_BRANCH(csa, ...) ((void)0)
     184             : #define CSA_ASSERT_JS_ARGC_EQ(csa, expected) ((void)0)
     185             : #define BIND(label) Bind(label)
     186             : #define VARIABLE(name, ...) Variable name(this, __VA_ARGS__)
     187             : #define VARIABLE_CONSTRUCTOR(name, ...) name(this, __VA_ARGS__)
     188             : #define TYPED_VARIABLE_DEF(type, name, ...) TVariable<type> name(__VA_ARGS__)
     189             : #endif  // DEBUG
     190             : 
     191             : #define TVARIABLE(...) EXPAND(TYPED_VARIABLE_DEF(__VA_ARGS__, this))
     192             : 
     193             : #ifdef ENABLE_SLOW_DCHECKS
     194             : #define CSA_SLOW_ASSERT(csa, ...) \
     195             :   if (FLAG_enable_slow_asserts) { \
     196             :     CSA_ASSERT(csa, __VA_ARGS__); \
     197             :   }
     198             : #else
     199             : #define CSA_SLOW_ASSERT(csa, ...) ((void)0)
     200             : #endif
     201             : 
     202             : // Provides JavaScript-specific "macro-assembler" functionality on top of the
     203             : // CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler,
     204             : // it's possible to add JavaScript-specific useful CodeAssembler "macros"
     205             : // without modifying files in the compiler directory (and requiring a review
     206             : // from a compiler directory OWNER).
     207      463132 : class V8_EXPORT_PRIVATE CodeStubAssembler
     208             :     : public compiler::CodeAssembler,
     209             :       public BaseBuiltinsFromDSLAssembler {
     210             :  public:
     211             :   using Node = compiler::Node;
     212             :   template <class T>
     213             :   using TNode = compiler::TNode<T>;
     214             :   template <class T>
     215             :   using SloppyTNode = compiler::SloppyTNode<T>;
     216             : 
     217             :   template <typename T>
     218             :   using LazyNode = std::function<TNode<T>()>;
     219             : 
     220             :   explicit CodeStubAssembler(compiler::CodeAssemblerState* state);
     221             : 
     222             :   enum AllocationFlag : uint8_t {
     223             :     kNone = 0,
     224             :     kDoubleAlignment = 1,
     225             :     kPretenured = 1 << 1,
     226             :     kAllowLargeObjectAllocation = 1 << 2,
     227             :   };
     228             : 
     229             :   enum SlackTrackingMode { kWithSlackTracking, kNoSlackTracking };
     230             : 
     231             :   typedef base::Flags<AllocationFlag> AllocationFlags;
     232             : 
     233             :   enum ParameterMode { SMI_PARAMETERS, INTPTR_PARAMETERS };
     234             : 
     235             :   // On 32-bit platforms, there is a slight performance advantage to doing all
     236             :   // of the array offset/index arithmetic with SMIs, since it's possible
     237             :   // to save a few tag/untag operations without paying an extra expense when
     238             :   // calculating array offset (the smi math can be folded away) and there are
     239             :   // fewer live ranges. Thus only convert indices to untagged value on 64-bit
     240             :   // platforms.
     241             :   ParameterMode OptimalParameterMode() const {
     242        2681 :     return Is64() ? INTPTR_PARAMETERS : SMI_PARAMETERS;
     243             :   }
     244             : 
     245             :   MachineRepresentation ParameterRepresentation(ParameterMode mode) const {
     246             :     return mode == INTPTR_PARAMETERS ? MachineType::PointerRepresentation()
     247         885 :                                      : MachineRepresentation::kTaggedSigned;
     248             :   }
     249             : 
     250             :   MachineRepresentation OptimalParameterRepresentation() const {
     251             :     return ParameterRepresentation(OptimalParameterMode());
     252             :   }
     253             : 
     254             :   TNode<IntPtrT> ParameterToIntPtr(Node* value, ParameterMode mode) {
     255       18277 :     if (mode == SMI_PARAMETERS) value = SmiUntag(value);
     256             :     return UncheckedCast<IntPtrT>(value);
     257             :   }
     258             : 
     259             :   Node* IntPtrToParameter(SloppyTNode<IntPtrT> value, ParameterMode mode) {
     260        5141 :     if (mode == SMI_PARAMETERS) return SmiTag(value);
     261             :     return value;
     262             :   }
     263             : 
     264             :   Node* Int32ToParameter(SloppyTNode<Int32T> value, ParameterMode mode) {
     265             :     return IntPtrToParameter(ChangeInt32ToIntPtr(value), mode);
     266             :   }
     267             : 
     268             :   TNode<Smi> ParameterToTagged(Node* value, ParameterMode mode) {
     269       42164 :     if (mode != SMI_PARAMETERS) return SmiTag(value);
     270             :     return UncheckedCast<Smi>(value);
     271             :   }
     272             : 
     273             :   Node* TaggedToParameter(SloppyTNode<Smi> value, ParameterMode mode) {
     274       24071 :     if (mode != SMI_PARAMETERS) return SmiUntag(value);
     275             :     return value;
     276             :   }
     277             : 
     278       14292 :   bool ToParameterConstant(Node* node, intptr_t* out, ParameterMode mode) {
     279       14292 :     if (mode == ParameterMode::SMI_PARAMETERS) {
     280        1048 :       Smi constant;
     281        1048 :       if (ToSmiConstant(node, &constant)) {
     282          10 :         *out = static_cast<intptr_t>(constant->value());
     283          10 :         return true;
     284             :       }
     285             :     } else {
     286             :       DCHECK_EQ(mode, ParameterMode::INTPTR_PARAMETERS);
     287             :       intptr_t constant;
     288       13244 :       if (ToIntPtrConstant(node, constant)) {
     289         702 :         *out = constant;
     290         702 :         return true;
     291             :       }
     292             :     }
     293             : 
     294             :     return false;
     295             :   }
     296             : 
     297             : #if defined(V8_HOST_ARCH_32_BIT)
     298             :   TNode<Smi> BIntToSmi(TNode<BInt> source) { return source; }
     299             :   TNode<IntPtrT> BIntToIntPtr(TNode<BInt> source) {
     300             :     return SmiToIntPtr(source);
     301             :   }
     302             :   TNode<BInt> SmiToBInt(TNode<Smi> source) { return source; }
     303             :   TNode<BInt> IntPtrToBInt(TNode<IntPtrT> source) {
     304             :     return SmiFromIntPtr(source);
     305             :   }
     306             : #elif defined(V8_HOST_ARCH_64_BIT)
     307             :   TNode<Smi> BIntToSmi(TNode<BInt> source) { return SmiFromIntPtr(source); }
     308             :   TNode<IntPtrT> BIntToIntPtr(TNode<BInt> source) { return source; }
     309             :   TNode<BInt> SmiToBInt(TNode<Smi> source) { return SmiToIntPtr(source); }
     310             :   TNode<BInt> IntPtrToBInt(TNode<IntPtrT> source) { return source; }
     311             : #else
     312             : #error Unknown architecture.
     313             : #endif
     314             : 
     315        1343 :   TNode<Smi> TaggedToSmi(TNode<Object> value, Label* fail) {
     316        2686 :     GotoIf(TaggedIsNotSmi(value), fail);
     317        1343 :     return UncheckedCast<Smi>(value);
     318             :   }
     319             : 
     320         896 :   TNode<Number> TaggedToNumber(TNode<Object> value, Label* fail) {
     321        1792 :     GotoIfNot(IsNumber(value), fail);
     322         896 :     return UncheckedCast<Number>(value);
     323             :   }
     324             : 
     325        6297 :   TNode<HeapObject> TaggedToHeapObject(TNode<Object> value, Label* fail) {
     326       12594 :     GotoIf(TaggedIsSmi(value), fail);
     327        6297 :     return UncheckedCast<HeapObject>(value);
     328             :   }
     329             : 
     330         789 :   TNode<JSArray> HeapObjectToJSArray(TNode<HeapObject> heap_object,
     331             :                                      Label* fail) {
     332        1578 :     GotoIfNot(IsJSArray(heap_object), fail);
     333         789 :     return UncheckedCast<JSArray>(heap_object);
     334             :   }
     335             : 
     336             :   TNode<JSArray> TaggedToFastJSArray(TNode<Context> context,
     337             :                                      TNode<Object> value, Label* fail) {
     338             :     GotoIf(TaggedIsSmi(value), fail);
     339             :     TNode<HeapObject> heap_object = CAST(value);
     340             :     GotoIfNot(IsFastJSArray(heap_object, context), fail);
     341             :     return UncheckedCast<JSArray>(heap_object);
     342             :   }
     343             : 
     344        1288 :   TNode<JSDataView> HeapObjectToJSDataView(TNode<HeapObject> heap_object,
     345             :                                            Label* fail) {
     346        2576 :     GotoIfNot(IsJSDataView(heap_object), fail);
     347        1288 :     return CAST(heap_object);
     348             :   }
     349             : 
     350         504 :   TNode<JSReceiver> HeapObjectToCallable(TNode<HeapObject> heap_object,
     351             :                                          Label* fail) {
     352        1008 :     GotoIfNot(IsCallable(heap_object), fail);
     353         504 :     return CAST(heap_object);
     354             :   }
     355             : 
     356         336 :   TNode<String> HeapObjectToString(TNode<HeapObject> heap_object, Label* fail) {
     357         672 :     GotoIfNot(IsString(heap_object), fail);
     358         336 :     return CAST(heap_object);
     359             :   }
     360             : 
     361          56 :   TNode<JSReceiver> HeapObjectToConstructor(TNode<HeapObject> heap_object,
     362             :                                             Label* fail) {
     363         112 :     GotoIfNot(IsConstructor(heap_object), fail);
     364          56 :     return CAST(heap_object);
     365             :   }
     366             : 
     367             :   Node* MatchesParameterMode(Node* value, ParameterMode mode);
     368             : 
     369             : #define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \
     370             :   Node* OpName(Node* a, Node* b, ParameterMode mode) {   \
     371             :     if (mode == SMI_PARAMETERS) {                        \
     372             :       return SmiOpName(CAST(a), CAST(b));                \
     373             :     } else {                                             \
     374             :       DCHECK_EQ(INTPTR_PARAMETERS, mode);                \
     375             :       return IntPtrOpName(a, b);                         \
     376             :     }                                                    \
     377             :   }
     378         168 :   PARAMETER_BINOP(IntPtrOrSmiMin, IntPtrMin, SmiMin)
     379      225811 :   PARAMETER_BINOP(IntPtrOrSmiAdd, IntPtrAdd, SmiAdd)
     380       34831 :   PARAMETER_BINOP(IntPtrOrSmiSub, IntPtrSub, SmiSub)
     381             :   PARAMETER_BINOP(IntPtrOrSmiLessThan, IntPtrLessThan, SmiLessThan)
     382         168 :   PARAMETER_BINOP(IntPtrOrSmiLessThanOrEqual, IntPtrLessThanOrEqual,
     383             :                   SmiLessThanOrEqual)
     384       48429 :   PARAMETER_BINOP(IntPtrOrSmiGreaterThan, IntPtrGreaterThan, SmiGreaterThan)
     385             :   PARAMETER_BINOP(IntPtrOrSmiGreaterThanOrEqual, IntPtrGreaterThanOrEqual,
     386             :                   SmiGreaterThanOrEqual)
     387             :   PARAMETER_BINOP(UintPtrOrSmiLessThan, UintPtrLessThan, SmiBelow)
     388       47343 :   PARAMETER_BINOP(UintPtrOrSmiGreaterThanOrEqual, UintPtrGreaterThanOrEqual,
     389             :                   SmiAboveOrEqual)
     390             : #undef PARAMETER_BINOP
     391             : 
     392         173 :   uintptr_t ConstexprUintPtrShl(uintptr_t a, int32_t b) { return a << b; }
     393             :   uintptr_t ConstexprUintPtrShr(uintptr_t a, int32_t b) { return a >> b; }
     394             : 
     395             :   TNode<Object> NoContextConstant();
     396             : 
     397             : #define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name)  \
     398             :   compiler::TNode<std::remove_pointer<std::remove_reference<decltype(  \
     399             :       std::declval<ReadOnlyRoots>().rootAccessorName())>::type>::type> \
     400             :       name##Constant();
     401             :   HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
     402             : #undef HEAP_CONSTANT_ACCESSOR
     403             : 
     404             : #define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \
     405             :   compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \
     406             :       std::declval<Heap>().rootAccessorName())>::type>::type>         \
     407             :       name##Constant();
     408             :   HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
     409             : #undef HEAP_CONSTANT_ACCESSOR
     410             : 
     411             : #define HEAP_CONSTANT_TEST(rootIndexName, rootAccessorName, name) \
     412             :   TNode<BoolT> Is##name(SloppyTNode<Object> value);               \
     413             :   TNode<BoolT> IsNot##name(SloppyTNode<Object> value);
     414             :   HEAP_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_TEST)
     415             : #undef HEAP_CONSTANT_TEST
     416             : 
     417             :   Node* IntPtrOrSmiConstant(int value, ParameterMode mode);
     418             : 
     419             :   bool IsIntPtrOrSmiConstantZero(Node* test, ParameterMode mode);
     420             :   bool TryGetIntPtrOrSmiConstantValue(Node* maybe_constant, int* value,
     421             :                                       ParameterMode mode);
     422             : 
     423             :   // Round the 32bits payload of the provided word up to the next power of two.
     424             :   TNode<IntPtrT> IntPtrRoundUpToPowerOfTwo32(TNode<IntPtrT> value);
     425             :   // Select the maximum of the two provided IntPtr values.
     426             :   TNode<IntPtrT> IntPtrMax(SloppyTNode<IntPtrT> left,
     427             :                            SloppyTNode<IntPtrT> right);
     428             :   // Select the minimum of the two provided IntPtr values.
     429             :   TNode<IntPtrT> IntPtrMin(SloppyTNode<IntPtrT> left,
     430             :                            SloppyTNode<IntPtrT> right);
     431             : 
     432             :   // Float64 operations.
     433             :   TNode<Float64T> Float64Ceil(SloppyTNode<Float64T> x);
     434             :   TNode<Float64T> Float64Floor(SloppyTNode<Float64T> x);
     435             :   TNode<Float64T> Float64Round(SloppyTNode<Float64T> x);
     436             :   TNode<Float64T> Float64RoundToEven(SloppyTNode<Float64T> x);
     437             :   TNode<Float64T> Float64Trunc(SloppyTNode<Float64T> x);
     438             :   // Select the minimum of the two provided Number values.
     439             :   TNode<Number> NumberMax(SloppyTNode<Number> left, SloppyTNode<Number> right);
     440             :   // Select the minimum of the two provided Number values.
     441             :   TNode<Number> NumberMin(SloppyTNode<Number> left, SloppyTNode<Number> right);
     442             : 
     443             :   // After converting an index to an integer, calculate a relative index: if
     444             :   // index < 0, max(length + index, 0); else min(index, length)
     445             :   TNode<IntPtrT> ConvertToRelativeIndex(TNode<Context> context,
     446             :                                         TNode<Object> index,
     447             :                                         TNode<IntPtrT> length);
     448             : 
     449             :   // Returns true iff the given value fits into smi range and is >= 0.
     450             :   TNode<BoolT> IsValidPositiveSmi(TNode<IntPtrT> value);
     451             : 
     452             :   // Tag an IntPtr as a Smi value.
     453             :   TNode<Smi> SmiTag(SloppyTNode<IntPtrT> value);
     454             :   // Untag a Smi value as an IntPtr.
     455             :   TNode<IntPtrT> SmiUntag(SloppyTNode<Smi> value);
     456             : 
     457             :   // Smi conversions.
     458             :   TNode<Float64T> SmiToFloat64(SloppyTNode<Smi> value);
     459        7738 :   TNode<Smi> SmiFromIntPtr(SloppyTNode<IntPtrT> value) { return SmiTag(value); }
     460             :   TNode<Smi> SmiFromInt32(SloppyTNode<Int32T> value);
     461        1410 :   TNode<IntPtrT> SmiToIntPtr(SloppyTNode<Smi> value) { return SmiUntag(value); }
     462             :   TNode<Int32T> SmiToInt32(SloppyTNode<Smi> value);
     463             : 
     464             :   // Smi operations.
     465             : #define SMI_ARITHMETIC_BINOP(SmiOpName, IntPtrOpName, Int32OpName)       \
     466             :   TNode<Smi> SmiOpName(TNode<Smi> a, TNode<Smi> b) {                     \
     467             :     if (SmiValuesAre32Bits()) {                                          \
     468             :       return BitcastWordToTaggedSigned(                                  \
     469             :           IntPtrOpName(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); \
     470             :     } else {                                                             \
     471             :       DCHECK(SmiValuesAre31Bits());                                      \
     472             :       if (kSystemPointerSize == kInt64Size) {                            \
     473             :         CSA_ASSERT(this, IsValidSmi(a));                                 \
     474             :         CSA_ASSERT(this, IsValidSmi(b));                                 \
     475             :       }                                                                  \
     476             :       return BitcastWordToTaggedSigned(ChangeInt32ToIntPtr(              \
     477             :           Int32OpName(TruncateIntPtrToInt32(BitcastTaggedToWord(a)),     \
     478             :                       TruncateIntPtrToInt32(BitcastTaggedToWord(b)))));  \
     479             :     }                                                                    \
     480             :   }
     481       83332 :   SMI_ARITHMETIC_BINOP(SmiAdd, IntPtrAdd, Int32Add)
     482       33372 :   SMI_ARITHMETIC_BINOP(SmiSub, IntPtrSub, Int32Sub)
     483        4704 :   SMI_ARITHMETIC_BINOP(SmiAnd, WordAnd, Word32And)
     484      176120 :   SMI_ARITHMETIC_BINOP(SmiOr, WordOr, Word32Or)
     485             : #undef SMI_ARITHMETIC_BINOP
     486          56 :   TNode<Smi> SmiInc(TNode<Smi> value) { return SmiAdd(value, SmiConstant(1)); }
     487             : 
     488             :   TNode<IntPtrT> TryIntPtrAdd(TNode<IntPtrT> a, TNode<IntPtrT> b,
     489             :                               Label* if_overflow);
     490             :   TNode<Smi> TrySmiAdd(TNode<Smi> a, TNode<Smi> b, Label* if_overflow);
     491             :   TNode<Smi> TrySmiSub(TNode<Smi> a, TNode<Smi> b, Label* if_overflow);
     492             : 
     493        3640 :   TNode<Smi> SmiShl(TNode<Smi> a, int shift) {
     494       10920 :     return BitcastWordToTaggedSigned(WordShl(BitcastTaggedToWord(a), shift));
     495             :   }
     496             : 
     497        2749 :   TNode<Smi> SmiShr(TNode<Smi> a, int shift) {
     498             :     return BitcastWordToTaggedSigned(
     499             :         WordAnd(WordShr(BitcastTaggedToWord(a), shift),
     500       10996 :                 BitcastTaggedToWord(SmiConstant(-1))));
     501             :   }
     502             : 
     503         280 :   TNode<Smi> SmiSar(TNode<Smi> a, int shift) {
     504             :     return BitcastWordToTaggedSigned(
     505             :         WordAnd(WordSar(BitcastTaggedToWord(a), shift),
     506        1120 :                 BitcastTaggedToWord(SmiConstant(-1))));
     507             :   }
     508             : 
     509             :   Node* WordOrSmiShl(Node* a, int shift, ParameterMode mode) {
     510             :     if (mode == SMI_PARAMETERS) {
     511             :       return SmiShl(CAST(a), shift);
     512             :     } else {
     513             :       DCHECK_EQ(INTPTR_PARAMETERS, mode);
     514             :       return WordShl(a, shift);
     515             :     }
     516             :   }
     517             : 
     518        2407 :   Node* WordOrSmiShr(Node* a, int shift, ParameterMode mode) {
     519        2407 :     if (mode == SMI_PARAMETERS) {
     520         234 :       return SmiShr(CAST(a), shift);
     521             :     } else {
     522             :       DCHECK_EQ(INTPTR_PARAMETERS, mode);
     523        4580 :       return WordShr(a, shift);
     524             :     }
     525             :   }
     526             : 
     527             : #define SMI_COMPARISON_OP(SmiOpName, IntPtrOpName, Int32OpName)            \
     528             :   TNode<BoolT> SmiOpName(TNode<Smi> a, TNode<Smi> b) {                     \
     529             :     if (SmiValuesAre32Bits()) {                                            \
     530             :       return IntPtrOpName(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); \
     531             :     } else {                                                               \
     532             :       DCHECK(SmiValuesAre31Bits());                                        \
     533             :       if (kSystemPointerSize == kInt64Size) {                              \
     534             :         CSA_ASSERT(this, IsValidSmi(a));                                   \
     535             :         CSA_ASSERT(this, IsValidSmi(b));                                   \
     536             :       }                                                                    \
     537             :       return Int32OpName(TruncateIntPtrToInt32(BitcastTaggedToWord(a)),    \
     538             :                          TruncateIntPtrToInt32(BitcastTaggedToWord(b)));   \
     539             :     }                                                                      \
     540             :   }
     541      113128 :   SMI_COMPARISON_OP(SmiEqual, WordEqual, Word32Equal)
     542        3584 :   SMI_COMPARISON_OP(SmiNotEqual, WordNotEqual, Word32NotEqual)
     543        9856 :   SMI_COMPARISON_OP(SmiAbove, UintPtrGreaterThan, Uint32GreaterThan)
     544         896 :   SMI_COMPARISON_OP(SmiAboveOrEqual, UintPtrGreaterThanOrEqual,
     545             :                     Uint32GreaterThanOrEqual)
     546        3360 :   SMI_COMPARISON_OP(SmiBelow, UintPtrLessThan, Uint32LessThan)
     547       49296 :   SMI_COMPARISON_OP(SmiLessThan, IntPtrLessThan, Int32LessThan)
     548       22500 :   SMI_COMPARISON_OP(SmiLessThanOrEqual, IntPtrLessThanOrEqual,
     549             :                     Int32LessThanOrEqual)
     550       23456 :   SMI_COMPARISON_OP(SmiGreaterThan, IntPtrGreaterThan, Int32GreaterThan)
     551       16800 :   SMI_COMPARISON_OP(SmiGreaterThanOrEqual, IntPtrGreaterThanOrEqual,
     552             :                     Int32GreaterThanOrEqual)
     553             : #undef SMI_COMPARISON_OP
     554             :   TNode<Smi> SmiMax(TNode<Smi> a, TNode<Smi> b);
     555             :   TNode<Smi> SmiMin(TNode<Smi> a, TNode<Smi> b);
     556             :   // Computes a % b for Smi inputs a and b; result is not necessarily a Smi.
     557             :   TNode<Number> SmiMod(TNode<Smi> a, TNode<Smi> b);
     558             :   // Computes a * b for Smi inputs a and b; result is not necessarily a Smi.
     559             :   TNode<Number> SmiMul(TNode<Smi> a, TNode<Smi> b);
     560             :   // Tries to compute dividend / divisor for Smi inputs; branching to bailout
     561             :   // if the division needs to be performed as a floating point operation.
     562             :   TNode<Smi> TrySmiDiv(TNode<Smi> dividend, TNode<Smi> divisor, Label* bailout);
     563             : 
     564             :   // Compares two Smis a and b as if they were converted to strings and then
     565             :   // compared lexicographically. Returns:
     566             :   // -1 iff x < y.
     567             :   //  0 iff x == y.
     568             :   //  1 iff x > y.
     569             :   TNode<Smi> SmiLexicographicCompare(TNode<Smi> x, TNode<Smi> y);
     570             : 
     571             :   // Smi | HeapNumber operations.
     572             :   TNode<Number> NumberInc(SloppyTNode<Number> value);
     573             :   TNode<Number> NumberDec(SloppyTNode<Number> value);
     574             :   TNode<Number> NumberAdd(SloppyTNode<Number> a, SloppyTNode<Number> b);
     575             :   TNode<Number> NumberSub(SloppyTNode<Number> a, SloppyTNode<Number> b);
     576             :   void GotoIfNotNumber(Node* value, Label* is_not_number);
     577             :   void GotoIfNumber(Node* value, Label* is_number);
     578             :   TNode<Number> SmiToNumber(TNode<Smi> v) { return v; }
     579             : 
     580             :   TNode<Number> BitwiseOp(Node* left32, Node* right32, Operation bitwise_op);
     581             : 
     582             :   // Allocate an object of the given size.
     583             :   TNode<HeapObject> AllocateInNewSpace(TNode<IntPtrT> size,
     584             :                                        AllocationFlags flags = kNone);
     585             :   TNode<HeapObject> AllocateInNewSpace(int size, AllocationFlags flags = kNone);
     586             :   TNode<HeapObject> Allocate(TNode<IntPtrT> size,
     587             :                              AllocationFlags flags = kNone);
     588             :   TNode<HeapObject> Allocate(int size, AllocationFlags flags = kNone);
     589             :   TNode<HeapObject> InnerAllocate(TNode<HeapObject> previous, int offset);
     590             :   TNode<HeapObject> InnerAllocate(TNode<HeapObject> previous,
     591             :                                   TNode<IntPtrT> offset);
     592             : 
     593             :   TNode<BoolT> IsRegularHeapObjectSize(TNode<IntPtrT> size);
     594             : 
     595             :   typedef std::function<void(Label*, Label*)> BranchGenerator;
     596             :   typedef std::function<Node*()> NodeGenerator;
     597             : 
     598             :   void Assert(const BranchGenerator& branch, const char* message = nullptr,
     599             :               const char* file = nullptr, int line = 0,
     600             :               Node* extra_node1 = nullptr, const char* extra_node1_name = "",
     601             :               Node* extra_node2 = nullptr, const char* extra_node2_name = "",
     602             :               Node* extra_node3 = nullptr, const char* extra_node3_name = "",
     603             :               Node* extra_node4 = nullptr, const char* extra_node4_name = "",
     604             :               Node* extra_node5 = nullptr, const char* extra_node5_name = "");
     605             :   void Assert(const NodeGenerator& condition_body,
     606             :               const char* message = nullptr, const char* file = nullptr,
     607             :               int line = 0, Node* extra_node1 = nullptr,
     608             :               const char* extra_node1_name = "", Node* extra_node2 = nullptr,
     609             :               const char* extra_node2_name = "", Node* extra_node3 = nullptr,
     610             :               const char* extra_node3_name = "", Node* extra_node4 = nullptr,
     611             :               const char* extra_node4_name = "", Node* extra_node5 = nullptr,
     612             :               const char* extra_node5_name = "");
     613             :   void Check(const BranchGenerator& branch, const char* message = nullptr,
     614             :              const char* file = nullptr, int line = 0,
     615             :              Node* extra_node1 = nullptr, const char* extra_node1_name = "",
     616             :              Node* extra_node2 = nullptr, const char* extra_node2_name = "",
     617             :              Node* extra_node3 = nullptr, const char* extra_node3_name = "",
     618             :              Node* extra_node4 = nullptr, const char* extra_node4_name = "",
     619             :              Node* extra_node5 = nullptr, const char* extra_node5_name = "");
     620             :   void Check(const NodeGenerator& condition_body, const char* message = nullptr,
     621             :              const char* file = nullptr, int line = 0,
     622             :              Node* extra_node1 = nullptr, const char* extra_node1_name = "",
     623             :              Node* extra_node2 = nullptr, const char* extra_node2_name = "",
     624             :              Node* extra_node3 = nullptr, const char* extra_node3_name = "",
     625             :              Node* extra_node4 = nullptr, const char* extra_node4_name = "",
     626             :              Node* extra_node5 = nullptr, const char* extra_node5_name = "");
     627             :   void FailAssert(
     628             :       const char* message = nullptr, const char* file = nullptr, int line = 0,
     629             :       Node* extra_node1 = nullptr, const char* extra_node1_name = "",
     630             :       Node* extra_node2 = nullptr, const char* extra_node2_name = "",
     631             :       Node* extra_node3 = nullptr, const char* extra_node3_name = "",
     632             :       Node* extra_node4 = nullptr, const char* extra_node4_name = "",
     633             :       Node* extra_node5 = nullptr, const char* extra_node5_name = "");
     634             : 
     635             :   void FastCheck(TNode<BoolT> condition);
     636             : 
     637             :   // The following Call wrappers call an object according to the semantics that
     638             :   // one finds in the EcmaScript spec, operating on an Callable (e.g. a
     639             :   // JSFunction or proxy) rather than a Code object.
     640             :   template <class... TArgs>
     641             :   TNode<Object> Call(TNode<Context> context, TNode<Object> callable,
     642             :                      TNode<JSReceiver> receiver, TArgs... args) {
     643             :     return UncheckedCast<Object>(CallJS(
     644             :         CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
     645             :         context, callable, receiver, args...));
     646             :   }
     647             :   template <class... TArgs>
     648        1008 :   TNode<Object> Call(TNode<Context> context, TNode<Object> callable,
     649             :                      TNode<Object> receiver, TArgs... args) {
     650        1008 :     if (IsUndefinedConstant(receiver) || IsNullConstant(receiver)) {
     651             :       return UncheckedCast<Object>(CallJS(
     652             :           CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
     653         392 :           context, callable, receiver, args...));
     654             :     }
     655             :     return UncheckedCast<Object>(CallJS(CodeFactory::Call(isolate()), context,
     656         616 :                                         callable, receiver, args...));
     657             :   }
     658             : 
     659             :   template <class... TArgs>
     660         952 :   TNode<JSReceiver> Construct(TNode<Context> context,
     661             :                               TNode<JSReceiver> new_target, TArgs... args) {
     662         952 :     return CAST(ConstructJS(CodeFactory::Construct(isolate()), context,
     663             :                             new_target, implicit_cast<TNode<Object>>(args)...));
     664             :   }
     665             : 
     666             :   template <class A, class F, class G>
     667       38831 :   TNode<A> Select(SloppyTNode<BoolT> condition, const F& true_body,
     668             :                   const G& false_body) {
     669             :     return UncheckedCast<A>(SelectImpl(
     670             :         condition,
     671       42756 :         [&]() -> Node* { return implicit_cast<TNode<A>>(true_body()); },
     672       48977 :         [&]() -> Node* { return implicit_cast<TNode<A>>(false_body()); },
     673      116493 :         MachineRepresentationOf<A>::value));
     674             :   }
     675             : 
     676             :   template <class A>
     677       12008 :   TNode<A> SelectConstant(TNode<BoolT> condition, TNode<A> true_value,
     678             :                           TNode<A> false_value) {
     679       12008 :     return Select<A>(condition, [=] { return true_value; },
     680       36024 :                      [=] { return false_value; });
     681             :   }
     682             : 
     683             :   TNode<Int32T> SelectInt32Constant(SloppyTNode<BoolT> condition,
     684             :                                     int true_value, int false_value);
     685             :   TNode<IntPtrT> SelectIntPtrConstant(SloppyTNode<BoolT> condition,
     686             :                                       int true_value, int false_value);
     687             :   TNode<Oddball> SelectBooleanConstant(SloppyTNode<BoolT> condition);
     688             :   TNode<Smi> SelectSmiConstant(SloppyTNode<BoolT> condition, Smi true_value,
     689             :                                Smi false_value);
     690             :   TNode<Smi> SelectSmiConstant(SloppyTNode<BoolT> condition, int true_value,
     691             :                                Smi false_value) {
     692             :     return SelectSmiConstant(condition, Smi::FromInt(true_value), false_value);
     693             :   }
     694             :   TNode<Smi> SelectSmiConstant(SloppyTNode<BoolT> condition, Smi true_value,
     695             :                                int false_value) {
     696             :     return SelectSmiConstant(condition, true_value, Smi::FromInt(false_value));
     697             :   }
     698             :   TNode<Smi> SelectSmiConstant(SloppyTNode<BoolT> condition, int true_value,
     699             :                                int false_value) {
     700             :     return SelectSmiConstant(condition, Smi::FromInt(true_value),
     701        4144 :                              Smi::FromInt(false_value));
     702             :   }
     703             : 
     704             :   TNode<Int32T> TruncateIntPtrToInt32(SloppyTNode<IntPtrT> value);
     705             : 
     706             :   // Check a value for smi-ness
     707             :   TNode<BoolT> TaggedIsSmi(SloppyTNode<Object> a);
     708             :   TNode<BoolT> TaggedIsSmi(TNode<MaybeObject> a);
     709             :   TNode<BoolT> TaggedIsNotSmi(SloppyTNode<Object> a);
     710             :   // Check that the value is a non-negative smi.
     711             :   TNode<BoolT> TaggedIsPositiveSmi(SloppyTNode<Object> a);
     712             :   // Check that a word has a word-aligned address.
     713             :   TNode<BoolT> WordIsAligned(SloppyTNode<WordT> word, size_t alignment);
     714             :   TNode<BoolT> WordIsPowerOfTwo(SloppyTNode<IntPtrT> value);
     715             : 
     716             : #if DEBUG
     717             :   void Bind(Label* label, AssemblerDebugInfo debug_info);
     718             : #endif  // DEBUG
     719             :   void Bind(Label* label);
     720             : 
     721             :   template <class... T>
     722             :   void Bind(compiler::CodeAssemblerParameterizedLabel<T...>* label,
     723             :             TNode<T>*... phis) {
     724             :     CodeAssembler::Bind(label, phis...);
     725             :   }
     726             : 
     727        7784 :   void BranchIfSmiEqual(TNode<Smi> a, TNode<Smi> b, Label* if_true,
     728             :                         Label* if_false) {
     729       15568 :     Branch(SmiEqual(a, b), if_true, if_false);
     730        7784 :   }
     731             : 
     732        5376 :   void BranchIfSmiLessThan(TNode<Smi> a, TNode<Smi> b, Label* if_true,
     733             :                            Label* if_false) {
     734       10752 :     Branch(SmiLessThan(a, b), if_true, if_false);
     735        5376 :   }
     736             : 
     737        3721 :   void BranchIfSmiLessThanOrEqual(TNode<Smi> a, TNode<Smi> b, Label* if_true,
     738             :                                   Label* if_false) {
     739        7442 :     Branch(SmiLessThanOrEqual(a, b), if_true, if_false);
     740        3721 :   }
     741             : 
     742        1680 :   void BranchIfFloat64IsNaN(Node* value, Label* if_true, Label* if_false) {
     743        3360 :     Branch(Float64Equal(value, value), if_false, if_true);
     744        1680 :   }
     745             : 
     746             :   // Branches to {if_true} if ToBoolean applied to {value} yields true,
     747             :   // otherwise goes to {if_false}.
     748             :   void BranchIfToBooleanIsTrue(Node* value, Label* if_true, Label* if_false);
     749             : 
     750             :   void BranchIfJSReceiver(Node* object, Label* if_true, Label* if_false);
     751             : 
     752             :   // Branches to {if_true} when --force-slow-path flag has been passed.
     753             :   // It's used for testing to ensure that slow path implementation behave
     754             :   // equivalent to corresponding fast paths (where applicable).
     755             :   //
     756             :   // Works only with V8_ENABLE_FORCE_SLOW_PATH compile time flag. Nop otherwise.
     757             :   void GotoIfForceSlowPath(Label* if_true);
     758             : 
     759             :   // Branches to {if_true} when Debug::ExecutionMode is DebugInfo::kSideEffect.
     760             :   void GotoIfDebugExecutionModeChecksSideEffects(Label* if_true);
     761             : 
     762             :   // Load value from current parent frame by given offset in bytes.
     763             :   Node* LoadFromParentFrame(int offset,
     764             :                             MachineType rep = MachineType::AnyTagged());
     765             : 
     766             :   // Load an object pointer from a buffer that isn't in the heap.
     767             :   Node* LoadBufferObject(Node* buffer, int offset,
     768             :                          MachineType rep = MachineType::AnyTagged());
     769             :   TNode<RawPtrT> LoadBufferPointer(TNode<RawPtrT> buffer, int offset) {
     770             :     return UncheckedCast<RawPtrT>(
     771         168 :         LoadBufferObject(buffer, offset, MachineType::Pointer()));
     772             :   }
     773             :   TNode<Smi> LoadBufferSmi(TNode<RawPtrT> buffer, int offset) {
     774         168 :     return CAST(LoadBufferObject(buffer, offset, MachineType::TaggedSigned()));
     775             :   }
     776             :   // Load a field from an object on the heap.
     777             :   Node* LoadObjectField(SloppyTNode<HeapObject> object, int offset,
     778             :                         MachineType rep);
     779             :   template <class T, typename std::enable_if<
     780             :                          std::is_convertible<TNode<T>, TNode<Object>>::value,
     781             :                          int>::type = 0>
     782             :   TNode<T> LoadObjectField(TNode<HeapObject> object, int offset) {
     783       12549 :     return CAST(LoadObjectField(object, offset, MachineTypeOf<T>::value));
     784             :   }
     785             :   template <class T, typename std::enable_if<
     786             :                          std::is_convertible<TNode<T>, TNode<UntaggedT>>::value,
     787             :                          int>::type = 0>
     788             :   TNode<T> LoadObjectField(TNode<HeapObject> object, int offset) {
     789             :     return UncheckedCast<T>(
     790       56247 :         LoadObjectField(object, offset, MachineTypeOf<T>::value));
     791             :   }
     792             :   TNode<Object> LoadObjectField(SloppyTNode<HeapObject> object, int offset) {
     793             :     return UncheckedCast<Object>(
     794      437152 :         LoadObjectField(object, offset, MachineType::AnyTagged()));
     795             :   }
     796             :   Node* LoadObjectField(SloppyTNode<HeapObject> object,
     797             :                         SloppyTNode<IntPtrT> offset, MachineType rep);
     798             :   TNode<Object> LoadObjectField(SloppyTNode<HeapObject> object,
     799             :                                 SloppyTNode<IntPtrT> offset) {
     800             :     return UncheckedCast<Object>(
     801        4429 :         LoadObjectField(object, offset, MachineType::AnyTagged()));
     802             :   }
     803             :   template <class T, typename std::enable_if<
     804             :                          std::is_convertible<TNode<T>, TNode<UntaggedT>>::value,
     805             :                          int>::type = 0>
     806         280 :   TNode<T> LoadObjectField(TNode<HeapObject> object, TNode<IntPtrT> offset) {
     807             :     return UncheckedCast<T>(
     808         280 :         LoadObjectField(object, offset, MachineTypeOf<T>::value));
     809             :   }
     810             :   // Load a SMI field and untag it.
     811             :   TNode<IntPtrT> LoadAndUntagObjectField(SloppyTNode<HeapObject> object,
     812             :                                          int offset);
     813             :   // Load a SMI field, untag it, and convert to Word32.
     814             :   TNode<Int32T> LoadAndUntagToWord32ObjectField(Node* object, int offset);
     815             :   // Load a SMI and untag it.
     816             :   TNode<IntPtrT> LoadAndUntagSmi(Node* base, int index);
     817             :   // Load a SMI root, untag it, and convert to Word32.
     818             :   TNode<Int32T> LoadAndUntagToWord32Root(RootIndex root_index);
     819             : 
     820             :   TNode<MaybeObject> LoadMaybeWeakObjectField(SloppyTNode<HeapObject> object,
     821             :                                               int offset) {
     822             :     return UncheckedCast<MaybeObject>(
     823        5656 :         LoadObjectField(object, offset, MachineType::AnyTagged()));
     824             :   }
     825             : 
     826             :   // Tag a smi and store it.
     827             :   void StoreAndTagSmi(Node* base, int offset, Node* value);
     828             : 
     829             :   // Load the floating point value of a HeapNumber.
     830             :   TNode<Float64T> LoadHeapNumberValue(SloppyTNode<HeapNumber> object);
     831             :   // Load the Map of an HeapObject.
     832             :   TNode<Map> LoadMap(SloppyTNode<HeapObject> object);
     833             :   // Load the instance type of an HeapObject.
     834             :   TNode<Int32T> LoadInstanceType(SloppyTNode<HeapObject> object);
     835             :   // Compare the instance the type of the object against the provided one.
     836             :   TNode<BoolT> HasInstanceType(SloppyTNode<HeapObject> object,
     837             :                                InstanceType type);
     838             :   TNode<BoolT> DoesntHaveInstanceType(SloppyTNode<HeapObject> object,
     839             :                                       InstanceType type);
     840             :   TNode<BoolT> TaggedDoesntHaveInstanceType(SloppyTNode<HeapObject> any_tagged,
     841             :                                             InstanceType type);
     842             :   // Load the properties backing store of a JSObject.
     843             :   TNode<HeapObject> LoadSlowProperties(SloppyTNode<JSObject> object);
     844             :   TNode<HeapObject> LoadFastProperties(SloppyTNode<JSObject> object);
     845             :   // Load the elements backing store of a JSObject.
     846             :   TNode<FixedArrayBase> LoadElements(SloppyTNode<JSObject> object) {
     847       26268 :     return LoadJSObjectElements(object);
     848             :   }
     849             :   // Load the length of a JSArray instance.
     850             :   TNode<Object> LoadJSArgumentsObjectWithLength(
     851             :       SloppyTNode<JSArgumentsObjectWithLength> array);
     852             :   // Load the length of a JSArray instance.
     853             :   TNode<Number> LoadJSArrayLength(SloppyTNode<JSArray> array);
     854             :   // Load the length of a fast JSArray instance. Returns a positive Smi.
     855             :   TNode<Smi> LoadFastJSArrayLength(SloppyTNode<JSArray> array);
     856             :   // Load the length of a fixed array base instance.
     857             :   TNode<Smi> LoadFixedArrayBaseLength(SloppyTNode<FixedArrayBase> array);
     858             :   // Load the length of a fixed array base instance.
     859             :   TNode<IntPtrT> LoadAndUntagFixedArrayBaseLength(
     860             :       SloppyTNode<FixedArrayBase> array);
     861             :   // Load the length of a WeakFixedArray.
     862             :   TNode<Smi> LoadWeakFixedArrayLength(TNode<WeakFixedArray> array);
     863             :   TNode<IntPtrT> LoadAndUntagWeakFixedArrayLength(
     864             :       SloppyTNode<WeakFixedArray> array);
     865             :   // Load the number of descriptors in DescriptorArray.
     866             :   TNode<Int32T> LoadNumberOfDescriptors(TNode<DescriptorArray> array);
     867             :   // Load the bit field of a Map.
     868             :   TNode<Int32T> LoadMapBitField(SloppyTNode<Map> map);
     869             :   // Load bit field 2 of a map.
     870             :   TNode<Int32T> LoadMapBitField2(SloppyTNode<Map> map);
     871             :   // Load bit field 3 of a map.
     872             :   TNode<Uint32T> LoadMapBitField3(SloppyTNode<Map> map);
     873             :   // Load the instance type of a map.
     874             :   TNode<Int32T> LoadMapInstanceType(SloppyTNode<Map> map);
     875             :   // Load the ElementsKind of a map.
     876             :   TNode<Int32T> LoadMapElementsKind(SloppyTNode<Map> map);
     877             :   TNode<Int32T> LoadElementsKind(SloppyTNode<HeapObject> object);
     878             :   // Load the instance descriptors of a map.
     879             :   TNode<DescriptorArray> LoadMapDescriptors(SloppyTNode<Map> map);
     880             :   // Load the prototype of a map.
     881             :   TNode<HeapObject> LoadMapPrototype(SloppyTNode<Map> map);
     882             :   // Load the prototype info of a map. The result has to be checked if it is a
     883             :   // prototype info object or not.
     884             :   TNode<PrototypeInfo> LoadMapPrototypeInfo(SloppyTNode<Map> map,
     885             :                                             Label* if_has_no_proto_info);
     886             :   // Load the instance size of a Map.
     887             :   TNode<IntPtrT> LoadMapInstanceSizeInWords(SloppyTNode<Map> map);
     888             :   // Load the inobject properties start of a Map (valid only for JSObjects).
     889             :   TNode<IntPtrT> LoadMapInobjectPropertiesStartInWords(SloppyTNode<Map> map);
     890             :   // Load the constructor function index of a Map (only for primitive maps).
     891             :   TNode<IntPtrT> LoadMapConstructorFunctionIndex(SloppyTNode<Map> map);
     892             :   // Load the constructor of a Map (equivalent to Map::GetConstructor()).
     893             :   TNode<Object> LoadMapConstructor(SloppyTNode<Map> map);
     894             :   // Load the EnumLength of a Map.
     895             :   Node* LoadMapEnumLength(SloppyTNode<Map> map);
     896             :   // Load the back-pointer of a Map.
     897             :   TNode<Object> LoadMapBackPointer(SloppyTNode<Map> map);
     898             :   // Checks that |map| has only simple properties, returns bitfield3.
     899             :   TNode<Uint32T> EnsureOnlyHasSimpleProperties(TNode<Map> map,
     900             :                                                TNode<Int32T> instance_type,
     901             :                                                Label* bailout);
     902             :   // Load the identity hash of a JSRececiver.
     903             :   TNode<IntPtrT> LoadJSReceiverIdentityHash(SloppyTNode<Object> receiver,
     904             :                                             Label* if_no_hash = nullptr);
     905             : 
     906             :   // This is only used on a newly allocated PropertyArray which
     907             :   // doesn't have an existing hash.
     908             :   void InitializePropertyArrayLength(Node* property_array, Node* length,
     909             :                                      ParameterMode mode);
     910             : 
     911             :   // Check if the map is set for slow properties.
     912             :   TNode<BoolT> IsDictionaryMap(SloppyTNode<Map> map);
     913             : 
     914             :   // Load the hash field of a name as an uint32 value.
     915             :   TNode<Uint32T> LoadNameHashField(SloppyTNode<Name> name);
     916             :   // Load the hash value of a name as an uint32 value.
     917             :   // If {if_hash_not_computed} label is specified then it also checks if
     918             :   // hash is actually computed.
     919             :   TNode<Uint32T> LoadNameHash(SloppyTNode<Name> name,
     920             :                               Label* if_hash_not_computed = nullptr);
     921             : 
     922             :   // Load length field of a String object as Smi value.
     923             :   TNode<Smi> LoadStringLengthAsSmi(SloppyTNode<String> string);
     924             :   // Load length field of a String object as intptr_t value.
     925             :   TNode<IntPtrT> LoadStringLengthAsWord(SloppyTNode<String> string);
     926             :   // Load length field of a String object as uint32_t value.
     927             :   TNode<Uint32T> LoadStringLengthAsWord32(SloppyTNode<String> string);
     928             :   // Loads a pointer to the sequential String char array.
     929             :   Node* PointerToSeqStringData(Node* seq_string);
     930             :   // Load value field of a JSValue object.
     931             :   Node* LoadJSValueValue(Node* object);
     932             : 
     933             :   // Figures out whether the value of maybe_object is:
     934             :   // - a SMI (jump to "if_smi", "extracted" will be the SMI value)
     935             :   // - a cleared weak reference (jump to "if_cleared", "extracted" will be
     936             :   // untouched)
     937             :   // - a weak reference (jump to "if_weak", "extracted" will be the object
     938             :   // pointed to)
     939             :   // - a strong reference (jump to "if_strong", "extracted" will be the object
     940             :   // pointed to)
     941             :   void DispatchMaybeObject(TNode<MaybeObject> maybe_object, Label* if_smi,
     942             :                            Label* if_cleared, Label* if_weak, Label* if_strong,
     943             :                            TVariable<Object>* extracted);
     944             :   // See MaybeObject for semantics of these functions.
     945             :   TNode<BoolT> IsStrong(TNode<MaybeObject> value);
     946             :   // This variant is for overzealous checking.
     947             :   TNode<BoolT> IsStrong(TNode<Object> value) {
     948             :     return IsStrong(ReinterpretCast<MaybeObject>(value));
     949             :   }
     950             :   TNode<HeapObject> GetHeapObjectIfStrong(TNode<MaybeObject> value,
     951             :                                           Label* if_not_strong);
     952             : 
     953             :   TNode<BoolT> IsWeakOrCleared(TNode<MaybeObject> value);
     954             :   TNode<BoolT> IsCleared(TNode<MaybeObject> value);
     955             :   TNode<BoolT> IsNotCleared(TNode<MaybeObject> value);
     956             : 
     957             :   // Removes the weak bit + asserts it was set.
     958             :   TNode<HeapObject> GetHeapObjectAssumeWeak(TNode<MaybeObject> value);
     959             : 
     960             :   TNode<HeapObject> GetHeapObjectAssumeWeak(TNode<MaybeObject> value,
     961             :                                             Label* if_cleared);
     962             : 
     963             :   TNode<BoolT> IsWeakReferenceTo(TNode<MaybeObject> object,
     964             :                                  TNode<Object> value);
     965             :   TNode<BoolT> IsNotWeakReferenceTo(TNode<MaybeObject> object,
     966             :                                     TNode<Object> value);
     967             :   TNode<BoolT> IsStrongReferenceTo(TNode<MaybeObject> object,
     968             :                                    TNode<Object> value);
     969             : 
     970             :   TNode<MaybeObject> MakeWeak(TNode<HeapObject> value);
     971             : 
     972             :   void FixedArrayBoundsCheck(TNode<FixedArrayBase> array, Node* index,
     973             :                              int additional_offset = 0,
     974             :                              ParameterMode parameter_mode = INTPTR_PARAMETERS);
     975             : 
     976             :   // Array is any array-like type that has a fixed header followed by
     977             :   // tagged elements.
     978             :   template <typename Array>
     979             :   TNode<IntPtrT> LoadArrayLength(TNode<Array> array);
     980             : 
     981             :   // Array is any array-like type that has a fixed header followed by
     982             :   // tagged elements.
     983             :   template <typename Array>
     984             :   TNode<MaybeObject> LoadArrayElement(
     985             :       TNode<Array> array, int array_header_size, Node* index,
     986             :       int additional_offset = 0,
     987             :       ParameterMode parameter_mode = INTPTR_PARAMETERS,
     988             :       LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
     989             : 
     990             :   TNode<Object> LoadFixedArrayElement(
     991             :       TNode<FixedArray> object, Node* index, int additional_offset = 0,
     992             :       ParameterMode parameter_mode = INTPTR_PARAMETERS,
     993             :       LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
     994             : 
     995             :   TNode<Object> LoadFixedArrayElement(TNode<FixedArray> object,
     996             :                                       TNode<IntPtrT> index,
     997             :                                       LoadSensitivity needs_poisoning) {
     998             :     return LoadFixedArrayElement(object, index, 0, INTPTR_PARAMETERS,
     999        8592 :                                  needs_poisoning);
    1000             :   }
    1001             : 
    1002       33261 :   TNode<Object> LoadFixedArrayElement(
    1003             :       TNode<FixedArray> object, TNode<IntPtrT> index, int additional_offset = 0,
    1004             :       LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
    1005             :     return LoadFixedArrayElement(object, index, additional_offset,
    1006       43329 :                                  INTPTR_PARAMETERS, needs_poisoning);
    1007             :   }
    1008             : 
    1009       38252 :   TNode<Object> LoadFixedArrayElement(
    1010             :       TNode<FixedArray> object, int index, int additional_offset = 0,
    1011             :       LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
    1012       38252 :     return LoadFixedArrayElement(object, IntPtrConstant(index),
    1013             :                                  additional_offset, INTPTR_PARAMETERS,
    1014       76504 :                                  needs_poisoning);
    1015             :   }
    1016         672 :   TNode<Object> LoadFixedArrayElement(TNode<FixedArray> object,
    1017             :                                       TNode<Smi> index) {
    1018        3136 :     return LoadFixedArrayElement(object, index, 0, SMI_PARAMETERS);
    1019             :   }
    1020             : 
    1021             :   TNode<Object> LoadPropertyArrayElement(TNode<PropertyArray> object,
    1022             :                                          SloppyTNode<IntPtrT> index);
    1023             :   TNode<IntPtrT> LoadPropertyArrayLength(TNode<PropertyArray> object);
    1024             : 
    1025             :   // Load an element from an array and untag it and return it as Word32.
    1026             :   // Array is any array-like type that has a fixed header followed by
    1027             :   // tagged elements.
    1028             :   template <typename Array>
    1029             :   TNode<Int32T> LoadAndUntagToWord32ArrayElement(
    1030             :       TNode<Array> array, int array_header_size, Node* index,
    1031             :       int additional_offset = 0,
    1032             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
    1033             : 
    1034             :   // Load an array element from a FixedArray, untag it and return it as Word32.
    1035             :   TNode<Int32T> LoadAndUntagToWord32FixedArrayElement(
    1036             :       TNode<FixedArray> object, Node* index, int additional_offset = 0,
    1037             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
    1038             : 
    1039             :   TNode<Int32T> LoadAndUntagToWord32FixedArrayElement(
    1040             :       TNode<FixedArray> object, int index, int additional_offset = 0) {
    1041             :     return LoadAndUntagToWord32FixedArrayElement(
    1042             :         object, IntPtrConstant(index), additional_offset, INTPTR_PARAMETERS);
    1043             :   }
    1044             : 
    1045             :   // Load an array element from a WeakFixedArray.
    1046             :   TNode<MaybeObject> LoadWeakFixedArrayElement(
    1047             :       TNode<WeakFixedArray> object, Node* index, int additional_offset = 0,
    1048             :       ParameterMode parameter_mode = INTPTR_PARAMETERS,
    1049             :       LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
    1050             : 
    1051        4928 :   TNode<MaybeObject> LoadWeakFixedArrayElement(
    1052             :       TNode<WeakFixedArray> object, int index, int additional_offset = 0,
    1053             :       LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
    1054        4928 :     return LoadWeakFixedArrayElement(object, IntPtrConstant(index),
    1055             :                                      additional_offset, INTPTR_PARAMETERS,
    1056        9856 :                                      needs_poisoning);
    1057             :   }
    1058             : 
    1059             :   // Load an array element from a FixedDoubleArray.
    1060             :   TNode<Float64T> LoadFixedDoubleArrayElement(
    1061             :       SloppyTNode<FixedDoubleArray> object, Node* index,
    1062             :       MachineType machine_type, int additional_offset = 0,
    1063             :       ParameterMode parameter_mode = INTPTR_PARAMETERS,
    1064             :       Label* if_hole = nullptr);
    1065             : 
    1066             :   Node* LoadFixedDoubleArrayElement(TNode<FixedDoubleArray> object,
    1067             :                                     TNode<Smi> index,
    1068             :                                     Label* if_hole = nullptr) {
    1069             :     return LoadFixedDoubleArrayElement(object, index, MachineType::Float64(), 0,
    1070             :                                        SMI_PARAMETERS, if_hole);
    1071             :   }
    1072             : 
    1073         112 :   Node* LoadFixedDoubleArrayElement(TNode<FixedDoubleArray> object,
    1074             :                                     TNode<IntPtrT> index,
    1075             :                                     Label* if_hole = nullptr) {
    1076             :     return LoadFixedDoubleArrayElement(object, index, MachineType::Float64(), 0,
    1077         224 :                                        INTPTR_PARAMETERS, if_hole);
    1078             :   }
    1079             : 
    1080             :   // Load an array element from a FixedArray, FixedDoubleArray or a
    1081             :   // NumberDictionary (depending on the |elements_kind|) and return
    1082             :   // it as a tagged value. Assumes that the |index| passed a length
    1083             :   // check before. Bails out to |if_accessor| if the element that
    1084             :   // was found is an accessor, or to |if_hole| if the element at
    1085             :   // the given |index| is not found in |elements|.
    1086             :   TNode<Object> LoadFixedArrayBaseElementAsTagged(
    1087             :       TNode<FixedArrayBase> elements, TNode<IntPtrT> index,
    1088             :       TNode<Int32T> elements_kind, Label* if_accessor, Label* if_hole);
    1089             : 
    1090             :   // Load a feedback slot from a FeedbackVector.
    1091             :   TNode<MaybeObject> LoadFeedbackVectorSlot(
    1092             :       Node* object, Node* index, int additional_offset = 0,
    1093             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
    1094             : 
    1095             :   TNode<IntPtrT> LoadFeedbackVectorLength(TNode<FeedbackVector>);
    1096             :   TNode<Float64T> LoadDoubleWithHoleCheck(TNode<FixedDoubleArray> array,
    1097             :                                           TNode<Smi> index,
    1098             :                                           Label* if_hole = nullptr);
    1099             :   TNode<Float64T> LoadDoubleWithHoleCheck(TNode<FixedDoubleArray> array,
    1100             :                                           TNode<IntPtrT> index,
    1101             :                                           Label* if_hole = nullptr);
    1102             : 
    1103             :   // Load Float64 value by |base| + |offset| address. If the value is a double
    1104             :   // hole then jump to |if_hole|. If |machine_type| is None then only the hole
    1105             :   // check is generated.
    1106             :   TNode<Float64T> LoadDoubleWithHoleCheck(
    1107             :       SloppyTNode<Object> base, SloppyTNode<IntPtrT> offset, Label* if_hole,
    1108             :       MachineType machine_type = MachineType::Float64());
    1109             :   TNode<RawPtrT> LoadFixedTypedArrayBackingStore(
    1110             :       TNode<FixedTypedArrayBase> typed_array);
    1111             :   Node* LoadFixedTypedArrayElementAsTagged(
    1112             :       Node* data_pointer, Node* index_node, ElementsKind elements_kind,
    1113             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
    1114             :   TNode<Numeric> LoadFixedTypedArrayElementAsTagged(
    1115             :       TNode<WordT> data_pointer, TNode<Smi> index, TNode<Int32T> elements_kind);
    1116             :   // Parts of the above, factored out for readability:
    1117             :   Node* LoadFixedBigInt64ArrayElementAsTagged(Node* data_pointer, Node* offset);
    1118             :   Node* LoadFixedBigUint64ArrayElementAsTagged(Node* data_pointer,
    1119             :                                                Node* offset);
    1120             :   // 64-bit platforms only:
    1121             :   TNode<BigInt> BigIntFromInt64(TNode<IntPtrT> value);
    1122             :   TNode<BigInt> BigIntFromUint64(TNode<UintPtrT> value);
    1123             :   // 32-bit platforms only:
    1124             :   TNode<BigInt> BigIntFromInt32Pair(TNode<IntPtrT> low, TNode<IntPtrT> high);
    1125             :   TNode<BigInt> BigIntFromUint32Pair(TNode<UintPtrT> low, TNode<UintPtrT> high);
    1126             : 
    1127             :   void StoreFixedTypedArrayElementFromTagged(
    1128             :       TNode<Context> context, TNode<FixedTypedArrayBase> elements,
    1129             :       TNode<Object> index_node, TNode<Object> value, ElementsKind elements_kind,
    1130             :       ParameterMode parameter_mode);
    1131             : 
    1132             :   // Context manipulation
    1133             :   TNode<Object> LoadContextElement(SloppyTNode<Context> context,
    1134             :                                    int slot_index);
    1135             :   TNode<Object> LoadContextElement(SloppyTNode<Context> context,
    1136             :                                    SloppyTNode<IntPtrT> slot_index);
    1137             :   TNode<Object> LoadContextElement(TNode<Context> context,
    1138             :                                    TNode<Smi> slot_index);
    1139             :   void StoreContextElement(SloppyTNode<Context> context, int slot_index,
    1140             :                            SloppyTNode<Object> value);
    1141             :   void StoreContextElement(SloppyTNode<Context> context,
    1142             :                            SloppyTNode<IntPtrT> slot_index,
    1143             :                            SloppyTNode<Object> value);
    1144             :   void StoreContextElementNoWriteBarrier(SloppyTNode<Context> context,
    1145             :                                          int slot_index,
    1146             :                                          SloppyTNode<Object> value);
    1147             :   TNode<Context> LoadNativeContext(SloppyTNode<Context> context);
    1148             :   // Calling this is only valid if there's a module context in the chain.
    1149             :   TNode<Context> LoadModuleContext(SloppyTNode<Context> context);
    1150             : 
    1151             :   void GotoIfContextElementEqual(Node* value, Node* native_context,
    1152             :                                  int slot_index, Label* if_equal) {
    1153             :     GotoIf(WordEqual(value, LoadContextElement(native_context, slot_index)),
    1154             :            if_equal);
    1155             :   }
    1156             : 
    1157             :   TNode<Map> LoadJSArrayElementsMap(ElementsKind kind,
    1158             :                                     SloppyTNode<Context> native_context);
    1159             :   TNode<Map> LoadJSArrayElementsMap(SloppyTNode<Int32T> kind,
    1160             :                                     SloppyTNode<Context> native_context);
    1161             : 
    1162             :   TNode<BoolT> IsGeneratorFunction(TNode<JSFunction> function);
    1163             :   TNode<BoolT> HasPrototypeProperty(TNode<JSFunction> function, TNode<Map> map);
    1164             :   void GotoIfPrototypeRequiresRuntimeLookup(TNode<JSFunction> function,
    1165             :                                             TNode<Map> map, Label* runtime);
    1166             :   // Load the "prototype" property of a JSFunction.
    1167             :   Node* LoadJSFunctionPrototype(Node* function, Label* if_bailout);
    1168             : 
    1169             :   TNode<BytecodeArray> LoadSharedFunctionInfoBytecodeArray(
    1170             :       SloppyTNode<SharedFunctionInfo> shared);
    1171             : 
    1172         168 :   TNode<Int32T> LoadSharedFunctionInfoFormalParameterCount(
    1173             :       TNode<SharedFunctionInfo> function) {
    1174             :     return TNode<Int32T>::UncheckedCast(LoadObjectField(
    1175             :         function, SharedFunctionInfo::kFormalParameterCountOffset,
    1176         168 :         MachineType::Uint16()));
    1177             :   }
    1178             : 
    1179             :   void StoreObjectByteNoWriteBarrier(TNode<HeapObject> object, int offset,
    1180             :                                      TNode<Word32T> value);
    1181             : 
    1182             :   // Store the floating point value of a HeapNumber.
    1183             :   void StoreHeapNumberValue(SloppyTNode<HeapNumber> object,
    1184             :                             SloppyTNode<Float64T> value);
    1185             :   void StoreMutableHeapNumberValue(SloppyTNode<MutableHeapNumber> object,
    1186             :                                    SloppyTNode<Float64T> value);
    1187             :   // Store a field to an object on the heap.
    1188             :   void StoreObjectField(Node* object, int offset, Node* value);
    1189             :   void StoreObjectField(Node* object, Node* offset, Node* value);
    1190             :   void StoreObjectFieldNoWriteBarrier(
    1191             :       Node* object, int offset, Node* value,
    1192             :       MachineRepresentation rep = MachineRepresentation::kTagged);
    1193             :   void StoreObjectFieldNoWriteBarrier(
    1194             :       Node* object, Node* offset, Node* value,
    1195             :       MachineRepresentation rep = MachineRepresentation::kTagged);
    1196             : 
    1197             :   template <class T = Object>
    1198             :   void StoreObjectFieldNoWriteBarrier(TNode<HeapObject> object,
    1199             :                                       TNode<IntPtrT> offset, TNode<T> value) {
    1200         728 :     StoreObjectFieldNoWriteBarrier(object, offset, value,
    1201             :                                    MachineRepresentationOf<T>::value);
    1202             :   }
    1203             : 
    1204             :   // Store the Map of an HeapObject.
    1205             :   void StoreMap(Node* object, Node* map);
    1206             :   void StoreMapNoWriteBarrier(Node* object, RootIndex map_root_index);
    1207             :   void StoreMapNoWriteBarrier(Node* object, Node* map);
    1208             :   void StoreObjectFieldRoot(Node* object, int offset, RootIndex root);
    1209             :   // Store an array element to a FixedArray.
    1210       21839 :   void StoreFixedArrayElement(
    1211             :       TNode<FixedArray> object, int index, SloppyTNode<Object> value,
    1212             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
    1213       21839 :     return StoreFixedArrayElement(object, IntPtrConstant(index), value,
    1214       43678 :                                   barrier_mode);
    1215             :   }
    1216        4848 :   void StoreFixedArrayElement(TNode<FixedArray> object, int index,
    1217             :                               TNode<Smi> value) {
    1218        4848 :     return StoreFixedArrayElement(object, IntPtrConstant(index), value,
    1219        9696 :                                   SKIP_WRITE_BARRIER);
    1220             :   }
    1221             : 
    1222             :   void StoreJSArrayLength(TNode<JSArray> array, TNode<Smi> length);
    1223             :   void StoreElements(TNode<Object> object, TNode<FixedArrayBase> elements);
    1224             : 
    1225             :   void StoreFixedArrayOrPropertyArrayElement(
    1226             :       Node* array, Node* index, Node* value,
    1227             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
    1228             :       int additional_offset = 0,
    1229             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
    1230             : 
    1231       24142 :   void StoreFixedArrayElement(
    1232             :       TNode<FixedArray> array, Node* index, SloppyTNode<Object> value,
    1233             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
    1234             :       int additional_offset = 0,
    1235             :       ParameterMode parameter_mode = INTPTR_PARAMETERS) {
    1236       24142 :     FixedArrayBoundsCheck(array, index, additional_offset, parameter_mode);
    1237             :     StoreFixedArrayOrPropertyArrayElement(array, index, value, barrier_mode,
    1238       39149 :                                           additional_offset, parameter_mode);
    1239       24142 :   }
    1240             : 
    1241             :   void StorePropertyArrayElement(
    1242             :       TNode<PropertyArray> array, Node* index, SloppyTNode<Object> value,
    1243             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
    1244             :       int additional_offset = 0,
    1245             :       ParameterMode parameter_mode = INTPTR_PARAMETERS) {
    1246             :     StoreFixedArrayOrPropertyArrayElement(array, index, value, barrier_mode,
    1247         728 :                                           additional_offset, parameter_mode);
    1248             :   }
    1249             : 
    1250             :   void StoreFixedArrayElementSmi(
    1251             :       TNode<FixedArray> array, TNode<Smi> index, TNode<Object> value,
    1252             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
    1253             :     StoreFixedArrayElement(array, index, value, barrier_mode, 0,
    1254        1064 :                            SMI_PARAMETERS);
    1255             :   }
    1256             :   void StoreFixedArrayElement(TNode<FixedArray> array, TNode<IntPtrT> index,
    1257             :                               TNode<Smi> value) {
    1258         896 :     StoreFixedArrayElement(array, index, value, SKIP_WRITE_BARRIER, 0);
    1259             :   }
    1260             : 
    1261             :   void StoreFixedDoubleArrayElement(
    1262             :       TNode<FixedDoubleArray> object, Node* index, TNode<Float64T> value,
    1263             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
    1264             : 
    1265             :   void StoreFixedDoubleArrayElementSmi(TNode<FixedDoubleArray> object,
    1266             :                                        TNode<Smi> index,
    1267             :                                        TNode<Float64T> value) {
    1268          56 :     StoreFixedDoubleArrayElement(object, index, value, SMI_PARAMETERS);
    1269             :   }
    1270             : 
    1271             :   void StoreFixedDoubleArrayHole(TNode<FixedDoubleArray> array, Node* index,
    1272             :                                  ParameterMode mode = INTPTR_PARAMETERS);
    1273             :   void StoreFixedDoubleArrayHoleSmi(TNode<FixedDoubleArray> array,
    1274             :                                     TNode<Smi> index) {
    1275          56 :     StoreFixedDoubleArrayHole(array, index, SMI_PARAMETERS);
    1276             :   }
    1277             : 
    1278             :   void StoreFeedbackVectorSlot(
    1279             :       Node* object, Node* index, Node* value,
    1280             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
    1281             :       int additional_offset = 0,
    1282             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
    1283             : 
    1284             :   void EnsureArrayLengthWritable(TNode<Map> map, Label* bailout);
    1285             : 
    1286             :   // EnsureArrayPushable verifies that receiver with this map is:
    1287             :   //   1. Is not a prototype.
    1288             :   //   2. Is not a dictionary.
    1289             :   //   3. Has a writeable length property.
    1290             :   // It returns ElementsKind as a node for further division into cases.
    1291             :   TNode<Int32T> EnsureArrayPushable(TNode<Map> map, Label* bailout);
    1292             : 
    1293             :   void TryStoreArrayElement(ElementsKind kind, ParameterMode mode,
    1294             :                             Label* bailout, Node* elements, Node* index,
    1295             :                             Node* value);
    1296             :   // Consumes args into the array, and returns tagged new length.
    1297             :   TNode<Smi> BuildAppendJSArray(ElementsKind kind, SloppyTNode<JSArray> array,
    1298             :                                 CodeStubArguments* args,
    1299             :                                 TVariable<IntPtrT>* arg_index, Label* bailout);
    1300             :   // Pushes value onto the end of array.
    1301             :   void BuildAppendJSArray(ElementsKind kind, Node* array, Node* value,
    1302             :                           Label* bailout);
    1303             : 
    1304             :   void StoreFieldsNoWriteBarrier(Node* start_address, Node* end_address,
    1305             :                                  Node* value);
    1306             : 
    1307             :   Node* AllocateCellWithValue(Node* value,
    1308             :                               WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
    1309             :   Node* AllocateSmiCell(int value = 0) {
    1310             :     return AllocateCellWithValue(SmiConstant(value), SKIP_WRITE_BARRIER);
    1311             :   }
    1312             : 
    1313             :   Node* LoadCellValue(Node* cell);
    1314             : 
    1315             :   void StoreCellValue(Node* cell, Node* value,
    1316             :                       WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
    1317             : 
    1318             :   // Allocate a HeapNumber without initializing its value.
    1319             :   TNode<HeapNumber> AllocateHeapNumber();
    1320             :   // Allocate a HeapNumber with a specific value.
    1321             :   TNode<HeapNumber> AllocateHeapNumberWithValue(SloppyTNode<Float64T> value);
    1322             :   TNode<HeapNumber> AllocateHeapNumberWithValue(double value) {
    1323             :     return AllocateHeapNumberWithValue(Float64Constant(value));
    1324             :   }
    1325             : 
    1326             :   // Allocate a MutableHeapNumber with a specific value.
    1327             :   TNode<MutableHeapNumber> AllocateMutableHeapNumberWithValue(
    1328             :       SloppyTNode<Float64T> value);
    1329             : 
    1330             :   // Allocate a BigInt with {length} digits. Sets the sign bit to {false}.
    1331             :   // Does not initialize the digits.
    1332             :   TNode<BigInt> AllocateBigInt(TNode<IntPtrT> length);
    1333             :   // Like above, but allowing custom bitfield initialization.
    1334             :   TNode<BigInt> AllocateRawBigInt(TNode<IntPtrT> length);
    1335             :   void StoreBigIntBitfield(TNode<BigInt> bigint, TNode<Word32T> bitfield);
    1336             :   void StoreBigIntDigit(TNode<BigInt> bigint, int digit_index,
    1337             :                         TNode<UintPtrT> digit);
    1338             :   TNode<Word32T> LoadBigIntBitfield(TNode<BigInt> bigint);
    1339             :   TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint, int digit_index);
    1340             : 
    1341             :   // Allocate a SeqOneByteString with the given length.
    1342             :   TNode<String> AllocateSeqOneByteString(uint32_t length,
    1343             :                                          AllocationFlags flags = kNone);
    1344             :   TNode<String> AllocateSeqOneByteString(Node* context, TNode<Uint32T> length,
    1345             :                                          AllocationFlags flags = kNone);
    1346             :   // Allocate a SeqTwoByteString with the given length.
    1347             :   TNode<String> AllocateSeqTwoByteString(uint32_t length,
    1348             :                                          AllocationFlags flags = kNone);
    1349             :   TNode<String> AllocateSeqTwoByteString(Node* context, TNode<Uint32T> length,
    1350             :                                          AllocationFlags flags = kNone);
    1351             : 
    1352             :   // Allocate a SlicedOneByteString with the given length, parent and offset.
    1353             :   // |length| and |offset| are expected to be tagged.
    1354             : 
    1355             :   TNode<String> AllocateSlicedOneByteString(TNode<Uint32T> length,
    1356             :                                             TNode<String> parent,
    1357             :                                             TNode<Smi> offset);
    1358             :   // Allocate a SlicedTwoByteString with the given length, parent and offset.
    1359             :   // |length| and |offset| are expected to be tagged.
    1360             :   TNode<String> AllocateSlicedTwoByteString(TNode<Uint32T> length,
    1361             :                                             TNode<String> parent,
    1362             :                                             TNode<Smi> offset);
    1363             : 
    1364             :   // Allocate a one-byte ConsString with the given length, first and second
    1365             :   // parts. |length| is expected to be tagged, and |first| and |second| are
    1366             :   // expected to be one-byte strings.
    1367             :   TNode<String> AllocateOneByteConsString(TNode<Uint32T> length,
    1368             :                                           TNode<String> first,
    1369             :                                           TNode<String> second,
    1370             :                                           AllocationFlags flags = kNone);
    1371             :   // Allocate a two-byte ConsString with the given length, first and second
    1372             :   // parts. |length| is expected to be tagged, and |first| and |second| are
    1373             :   // expected to be two-byte strings.
    1374             :   TNode<String> AllocateTwoByteConsString(TNode<Uint32T> length,
    1375             :                                           TNode<String> first,
    1376             :                                           TNode<String> second,
    1377             :                                           AllocationFlags flags = kNone);
    1378             : 
    1379             :   // Allocate an appropriate one- or two-byte ConsString with the first and
    1380             :   // second parts specified by |left| and |right|.
    1381             :   TNode<String> NewConsString(TNode<Uint32T> length, TNode<String> left,
    1382             :                               TNode<String> right,
    1383             :                               AllocationFlags flags = kNone);
    1384             : 
    1385             :   TNode<NameDictionary> AllocateNameDictionary(int at_least_space_for);
    1386             :   TNode<NameDictionary> AllocateNameDictionary(
    1387             :       TNode<IntPtrT> at_least_space_for);
    1388             :   TNode<NameDictionary> AllocateNameDictionaryWithCapacity(
    1389             :       TNode<IntPtrT> capacity);
    1390             :   TNode<NameDictionary> CopyNameDictionary(TNode<NameDictionary> dictionary,
    1391             :                                            Label* large_object_fallback);
    1392             : 
    1393             :   template <typename CollectionType>
    1394             :   Node* AllocateOrderedHashTable();
    1395             : 
    1396             :   // Builds code that finds OrderedHashTable entry for a key with hash code
    1397             :   // {hash} with using the comparison code generated by {key_compare}. The code
    1398             :   // jumps to {entry_found} if the key is found, or to {not_found} if the key
    1399             :   // was not found. In the {entry_found} branch, the variable
    1400             :   // entry_start_position will be bound to the index of the entry (relative to
    1401             :   // OrderedHashTable::kHashTableStartIndex).
    1402             :   //
    1403             :   // The {CollectionType} template parameter stands for the particular instance
    1404             :   // of OrderedHashTable, it should be OrderedHashMap or OrderedHashSet.
    1405             :   template <typename CollectionType>
    1406             :   void FindOrderedHashTableEntry(
    1407             :       Node* table, Node* hash,
    1408             :       const std::function<void(Node*, Label*, Label*)>& key_compare,
    1409             :       Variable* entry_start_position, Label* entry_found, Label* not_found);
    1410             : 
    1411             :   template <typename CollectionType>
    1412             :   TNode<CollectionType> AllocateSmallOrderedHashTable(TNode<IntPtrT> capacity);
    1413             : 
    1414             :   Node* AllocateStruct(Node* map, AllocationFlags flags = kNone);
    1415             :   void InitializeStructBody(Node* object, Node* map, Node* size,
    1416             :                             int start_offset = Struct::kHeaderSize);
    1417             : 
    1418             :   Node* AllocateJSObjectFromMap(
    1419             :       Node* map, Node* properties = nullptr, Node* elements = nullptr,
    1420             :       AllocationFlags flags = kNone,
    1421             :       SlackTrackingMode slack_tracking_mode = kNoSlackTracking);
    1422             : 
    1423             :   void InitializeJSObjectFromMap(
    1424             :       Node* object, Node* map, Node* instance_size, Node* properties = nullptr,
    1425             :       Node* elements = nullptr,
    1426             :       SlackTrackingMode slack_tracking_mode = kNoSlackTracking);
    1427             : 
    1428             :   void InitializeJSObjectBodyWithSlackTracking(Node* object, Node* map,
    1429             :                                                Node* instance_size);
    1430             :   void InitializeJSObjectBodyNoSlackTracking(
    1431             :       Node* object, Node* map, Node* instance_size,
    1432             :       int start_offset = JSObject::kHeaderSize);
    1433             : 
    1434             :   TNode<BoolT> IsValidFastJSArrayCapacity(Node* capacity,
    1435             :                                           ParameterMode capacity_mode);
    1436             : 
    1437             :   // Allocate a JSArray without elements and initialize the header fields.
    1438             :   TNode<JSArray> AllocateUninitializedJSArrayWithoutElements(
    1439             :       TNode<Map> array_map, TNode<Smi> length, Node* allocation_site = nullptr);
    1440             :   //
    1441             :   // Allocate and return a JSArray with initialized header fields and its
    1442             :   // uninitialized elements.
    1443             :   // The ParameterMode argument is only used for the capacity parameter.
    1444             :   std::pair<TNode<JSArray>, TNode<FixedArrayBase>>
    1445             :   AllocateUninitializedJSArrayWithElements(
    1446             :       ElementsKind kind, TNode<Map> array_map, TNode<Smi> length,
    1447             :       Node* allocation_site, Node* capacity,
    1448             :       ParameterMode capacity_mode = INTPTR_PARAMETERS,
    1449             :       AllocationFlags allocation_flags = kNone);
    1450             : 
    1451             :   // Allocate a JSArray and fill elements with the hole.
    1452             :   // The ParameterMode argument is only used for the capacity parameter.
    1453             :   TNode<JSArray> AllocateJSArray(
    1454             :       ElementsKind kind, TNode<Map> array_map, Node* capacity,
    1455             :       TNode<Smi> length, Node* allocation_site = nullptr,
    1456             :       ParameterMode capacity_mode = INTPTR_PARAMETERS,
    1457             :       AllocationFlags allocation_flags = kNone);
    1458             : 
    1459             :   TNode<JSArray> AllocateJSArray(ElementsKind kind, TNode<Map> array_map,
    1460             :                                  TNode<Smi> capacity, TNode<Smi> length) {
    1461             :     return AllocateJSArray(kind, array_map, capacity, length, nullptr,
    1462         224 :                            SMI_PARAMETERS);
    1463             :   }
    1464             : 
    1465             :   TNode<JSArray> AllocateJSArray(ElementsKind kind, TNode<Map> array_map,
    1466             :                                  TNode<IntPtrT> capacity, TNode<Smi> length) {
    1467             :     return AllocateJSArray(kind, array_map, capacity, length, nullptr,
    1468         336 :                            INTPTR_PARAMETERS);
    1469             :   }
    1470             : 
    1471             :   enum class HoleConversionMode { kDontConvert, kConvertToUndefined };
    1472             :   // Clone a fast JSArray |array| into a new fast JSArray.
    1473             :   // |convert_holes| tells the function to convert holes into undefined or not.
    1474             :   // If |convert_holes| is set to kConvertToUndefined, but the function did not
    1475             :   // find any hole in |array|, the resulting array will have the same elements
    1476             :   // kind as |array|. If the function did find a hole, it will convert holes in
    1477             :   // |array| to undefined in the resulting array, who will now have
    1478             :   // PACKED_ELEMENTS kind.
    1479             :   // If |convert_holes| is set kDontConvert, holes are also copied to the
    1480             :   // resulting array, who will have the same elements kind as |array|. The
    1481             :   // function generates significantly less code in this case.
    1482             :   Node* CloneFastJSArray(
    1483             :       Node* context, Node* array, ParameterMode mode = INTPTR_PARAMETERS,
    1484             :       Node* allocation_site = nullptr,
    1485             :       HoleConversionMode convert_holes = HoleConversionMode::kDontConvert);
    1486             : 
    1487             :   Node* ExtractFastJSArray(Node* context, Node* array, Node* begin, Node* count,
    1488             :                            ParameterMode mode = INTPTR_PARAMETERS,
    1489             :                            Node* capacity = nullptr,
    1490             :                            Node* allocation_site = nullptr);
    1491             : 
    1492             :   TNode<FixedArrayBase> AllocateFixedArray(
    1493             :       ElementsKind kind, Node* capacity, ParameterMode mode = INTPTR_PARAMETERS,
    1494             :       AllocationFlags flags = kNone,
    1495             :       SloppyTNode<Map> fixed_array_map = nullptr);
    1496             : 
    1497             :   TNode<FixedArrayBase> AllocateFixedArray(
    1498             :       ElementsKind kind, TNode<IntPtrT> capacity, AllocationFlags flags,
    1499             :       SloppyTNode<Map> fixed_array_map = nullptr) {
    1500             :     return AllocateFixedArray(kind, capacity, INTPTR_PARAMETERS, flags,
    1501        2087 :                               fixed_array_map);
    1502             :   }
    1503             : 
    1504        1023 :   TNode<FixedArray> AllocateZeroedFixedArray(TNode<IntPtrT> capacity) {
    1505             :     TNode<FixedArray> result = UncheckedCast<FixedArray>(
    1506             :         AllocateFixedArray(PACKED_ELEMENTS, capacity,
    1507             :                            AllocationFlag::kAllowLargeObjectAllocation));
    1508        1023 :     FillFixedArrayWithSmiZero(result, capacity);
    1509        1023 :     return result;
    1510             :   }
    1511             : 
    1512          56 :   TNode<FixedDoubleArray> AllocateZeroedFixedDoubleArray(
    1513             :       TNode<IntPtrT> capacity) {
    1514             :     TNode<FixedDoubleArray> result = UncheckedCast<FixedDoubleArray>(
    1515             :         AllocateFixedArray(PACKED_DOUBLE_ELEMENTS, capacity,
    1516             :                            AllocationFlag::kAllowLargeObjectAllocation));
    1517          56 :     FillFixedDoubleArrayWithZero(result, capacity);
    1518          56 :     return result;
    1519             :   }
    1520             : 
    1521         280 :   TNode<FixedArray> AllocateFixedArrayWithHoles(TNode<IntPtrT> capacity,
    1522             :                                                 AllocationFlags flags) {
    1523             :     TNode<FixedArray> result = UncheckedCast<FixedArray>(
    1524             :         AllocateFixedArray(PACKED_ELEMENTS, capacity, flags));
    1525         280 :     FillFixedArrayWithValue(PACKED_ELEMENTS, result, IntPtrConstant(0),
    1526         560 :                             capacity, RootIndex::kTheHoleValue);
    1527         280 :     return result;
    1528             :   }
    1529             : 
    1530             :   Node* AllocatePropertyArray(Node* capacity,
    1531             :                               ParameterMode mode = INTPTR_PARAMETERS,
    1532             :                               AllocationFlags flags = kNone);
    1533             : 
    1534             :   // Perform CreateArrayIterator (ES #sec-createarrayiterator).
    1535             :   TNode<JSArrayIterator> CreateArrayIterator(TNode<Context> context,
    1536             :                                              TNode<Object> object,
    1537             :                                              IterationKind mode);
    1538             : 
    1539             :   Node* AllocateJSIteratorResult(Node* context, Node* value, Node* done);
    1540             :   Node* AllocateJSIteratorResultForEntry(Node* context, Node* key, Node* value);
    1541             : 
    1542             :   TNode<JSReceiver> ArraySpeciesCreate(TNode<Context> context,
    1543             :                                        TNode<Object> originalArray,
    1544             :                                        TNode<Number> len);
    1545             : 
    1546             :   void FillFixedArrayWithValue(ElementsKind kind, Node* array, Node* from_index,
    1547             :                                Node* to_index, RootIndex value_root_index,
    1548             :                                ParameterMode mode = INTPTR_PARAMETERS);
    1549             : 
    1550             :   // Uses memset to effectively initialize the given FixedArray with zeroes.
    1551             :   void FillFixedArrayWithSmiZero(TNode<FixedArray> array,
    1552             :                                  TNode<IntPtrT> length);
    1553             :   void FillFixedDoubleArrayWithZero(TNode<FixedDoubleArray> array,
    1554             :                                     TNode<IntPtrT> length);
    1555             : 
    1556             :   void FillPropertyArrayWithUndefined(Node* array, Node* from_index,
    1557             :                                       Node* to_index,
    1558             :                                       ParameterMode mode = INTPTR_PARAMETERS);
    1559             : 
    1560             :   enum class DestroySource { kNo, kYes };
    1561             : 
    1562             :   // Specify DestroySource::kYes if {from_array} is being supplanted by
    1563             :   // {to_array}. This offers a slight performance benefit by simply copying the
    1564             :   // array word by word. The source may be destroyed at the end of this macro.
    1565             :   //
    1566             :   // Otherwise, specify DestroySource::kNo for operations where an Object is
    1567             :   // being cloned, to ensure that MutableHeapNumbers are unique between the
    1568             :   // source and cloned object.
    1569             :   void CopyPropertyArrayValues(Node* from_array, Node* to_array, Node* length,
    1570             :                                WriteBarrierMode barrier_mode,
    1571             :                                ParameterMode mode,
    1572             :                                DestroySource destroy_source);
    1573             : 
    1574             :   // Copies all elements from |from_array| of |length| size to
    1575             :   // |to_array| of the same size respecting the elements kind.
    1576         336 :   void CopyFixedArrayElements(
    1577             :       ElementsKind kind, Node* from_array, Node* to_array, Node* length,
    1578             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
    1579             :       ParameterMode mode = INTPTR_PARAMETERS) {
    1580             :     CopyFixedArrayElements(kind, from_array, kind, to_array,
    1581             :                            IntPtrOrSmiConstant(0, mode), length, length,
    1582         336 :                            barrier_mode, mode);
    1583         336 :   }
    1584             : 
    1585             :   // Copies |element_count| elements from |from_array| starting from element
    1586             :   // zero to |to_array| of |capacity| size respecting both array's elements
    1587             :   // kinds.
    1588        5589 :   void CopyFixedArrayElements(
    1589             :       ElementsKind from_kind, Node* from_array, ElementsKind to_kind,
    1590             :       Node* to_array, Node* element_count, Node* capacity,
    1591             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
    1592             :       ParameterMode mode = INTPTR_PARAMETERS) {
    1593             :     CopyFixedArrayElements(from_kind, from_array, to_kind, to_array,
    1594             :                            IntPtrOrSmiConstant(0, mode), element_count,
    1595        5589 :                            capacity, barrier_mode, mode);
    1596        5589 :   }
    1597             : 
    1598             :   // Copies |element_count| elements from |from_array| starting from element
    1599             :   // |first_element| to |to_array| of |capacity| size respecting both array's
    1600             :   // elements kinds.
    1601             :   // |convert_holes| tells the function whether to convert holes to undefined.
    1602             :   // |var_holes_converted| can be used to signify that the conversion happened
    1603             :   // (i.e. that there were holes). If |convert_holes_to_undefined| is
    1604             :   // HoleConversionMode::kConvertToUndefined, then it must not be the case that
    1605             :   // IsDoubleElementsKind(to_kind).
    1606             :   void CopyFixedArrayElements(
    1607             :       ElementsKind from_kind, Node* from_array, ElementsKind to_kind,
    1608             :       Node* to_array, Node* first_element, Node* element_count, Node* capacity,
    1609             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
    1610             :       ParameterMode mode = INTPTR_PARAMETERS,
    1611             :       HoleConversionMode convert_holes = HoleConversionMode::kDontConvert,
    1612             :       TVariable<BoolT>* var_holes_converted = nullptr);
    1613             : 
    1614             :   void CopyFixedArrayElements(
    1615             :       ElementsKind from_kind, TNode<FixedArrayBase> from_array,
    1616             :       ElementsKind to_kind, TNode<FixedArrayBase> to_array,
    1617             :       TNode<Smi> first_element, TNode<Smi> element_count, TNode<Smi> capacity,
    1618             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
    1619             :     CopyFixedArrayElements(from_kind, from_array, to_kind, to_array,
    1620             :                            first_element, element_count, capacity, barrier_mode,
    1621             :                            SMI_PARAMETERS);
    1622             :   }
    1623             : 
    1624             :   void JumpIfPointersFromHereAreInteresting(TNode<Object> object,
    1625             :                                             Label* interesting);
    1626             : 
    1627             :   // Efficiently copy elements within a single array. The regions
    1628             :   // [src_index, src_index + length) and [dst_index, dst_index + length)
    1629             :   // can be overlapping.
    1630             :   void MoveElements(ElementsKind kind, TNode<FixedArrayBase> elements,
    1631             :                     TNode<IntPtrT> dst_index, TNode<IntPtrT> src_index,
    1632             :                     TNode<IntPtrT> length);
    1633             : 
    1634             :   // Efficiently copy elements from one array to another. The ElementsKind
    1635             :   // needs to be the same. Copy from src_elements at
    1636             :   // [src_index, src_index + length) to dst_elements at
    1637             :   // [dst_index, dst_index + length).
    1638             :   // The function decides whether it can use memcpy. In case it cannot,
    1639             :   // |write_barrier| can help it to skip write barrier. SKIP_WRITE_BARRIER is
    1640             :   // only safe when copying to new space, or when copying to old space and the
    1641             :   // array does not contain object pointers.
    1642             :   void CopyElements(ElementsKind kind, TNode<FixedArrayBase> dst_elements,
    1643             :                     TNode<IntPtrT> dst_index,
    1644             :                     TNode<FixedArrayBase> src_elements,
    1645             :                     TNode<IntPtrT> src_index, TNode<IntPtrT> length,
    1646             :                     WriteBarrierMode write_barrier = UPDATE_WRITE_BARRIER);
    1647             : 
    1648             :   TNode<FixedArray> HeapObjectToFixedArray(TNode<HeapObject> base,
    1649             :                                            Label* cast_fail);
    1650             : 
    1651         448 :   TNode<FixedDoubleArray> HeapObjectToFixedDoubleArray(TNode<HeapObject> base,
    1652             :                                                        Label* cast_fail) {
    1653             :     GotoIf(
    1654        1344 :         WordNotEqual(LoadMap(base), LoadRoot(RootIndex::kFixedDoubleArrayMap)),
    1655         448 :         cast_fail);
    1656         448 :     return UncheckedCast<FixedDoubleArray>(base);
    1657             :   }
    1658             : 
    1659          56 :   TNode<FixedArray> HeapObjectToSloppyArgumentsElements(TNode<HeapObject> base,
    1660             :                                                         Label* cast_fail) {
    1661             :     GotoIf(WordNotEqual(LoadMap(base),
    1662         168 :                         LoadRoot(RootIndex::kSloppyArgumentsElementsMap)),
    1663          56 :            cast_fail);
    1664          56 :     return UncheckedCast<FixedArray>(base);
    1665             :   }
    1666             : 
    1667             :   TNode<Int32T> ConvertElementsKindToInt(TNode<Int32T> elements_kind) {
    1668             :     return UncheckedCast<Int32T>(elements_kind);
    1669             :   }
    1670             : 
    1671             :   enum class ExtractFixedArrayFlag {
    1672             :     kFixedArrays = 1,
    1673             :     kFixedDoubleArrays = 2,
    1674             :     kDontCopyCOW = 4,
    1675             :     kNewSpaceAllocationOnly = 8,
    1676             :     kAllFixedArrays = kFixedArrays | kFixedDoubleArrays,
    1677             :     kAllFixedArraysDontCopyCOW = kAllFixedArrays | kDontCopyCOW
    1678             :   };
    1679             : 
    1680             :   typedef base::Flags<ExtractFixedArrayFlag> ExtractFixedArrayFlags;
    1681             : 
    1682             :   // Copy a portion of an existing FixedArray or FixedDoubleArray into a new
    1683             :   // array, including special appropriate handling for empty arrays and COW
    1684             :   // arrays. The result array will be of the same type as the original array.
    1685             :   //
    1686             :   // * |source| is either a FixedArray or FixedDoubleArray from which to copy
    1687             :   // elements.
    1688             :   // * |first| is the starting element index to copy from, if nullptr is passed
    1689             :   // then index zero is used by default.
    1690             :   // * |count| is the number of elements to copy out of the source array
    1691             :   // starting from and including the element indexed by |start|. If |count| is
    1692             :   // nullptr, then all of the elements from |start| to the end of |source| are
    1693             :   // copied.
    1694             :   // * |capacity| determines the size of the allocated result array, with
    1695             :   // |capacity| >= |count|. If |capacity| is nullptr, then |count| is used as
    1696             :   // the destination array's capacity.
    1697             :   // * |extract_flags| determines whether FixedArrays, FixedDoubleArrays or both
    1698             :   // are detected and copied. Although it's always correct to pass
    1699             :   // kAllFixedArrays, the generated code is more compact and efficient if the
    1700             :   // caller can specify whether only FixedArrays or FixedDoubleArrays will be
    1701             :   // passed as the |source| parameter.
    1702             :   // * |parameter_mode| determines the parameter mode of |first|, |count| and
    1703             :   // |capacity|.
    1704             :   // * If |var_holes_converted| is given, any holes will be converted to
    1705             :   // undefined and the variable will be set according to whether or not there
    1706             :   // were any hole.
    1707             :   // * If |source_elements_kind| is given, the function will try to use the
    1708             :   // runtime elements kind of source to make copy faster. More specifically, it
    1709             :   // can skip write barriers.
    1710             :   TNode<FixedArrayBase> ExtractFixedArray(
    1711             :       Node* source, Node* first, Node* count = nullptr,
    1712             :       Node* capacity = nullptr,
    1713             :       ExtractFixedArrayFlags extract_flags =
    1714             :           ExtractFixedArrayFlag::kAllFixedArrays,
    1715             :       ParameterMode parameter_mode = INTPTR_PARAMETERS,
    1716             :       TVariable<BoolT>* var_holes_converted = nullptr,
    1717             :       Node* source_elements_kind = nullptr);
    1718             : 
    1719             :   TNode<FixedArrayBase> ExtractFixedArray(
    1720             :       TNode<FixedArrayBase> source, TNode<Smi> first, TNode<Smi> count,
    1721             :       TNode<Smi> capacity,
    1722             :       ExtractFixedArrayFlags extract_flags =
    1723             :           ExtractFixedArrayFlag::kAllFixedArrays) {
    1724             :     return ExtractFixedArray(source, first, count, capacity, extract_flags,
    1725         392 :                              SMI_PARAMETERS);
    1726             :   }
    1727             : 
    1728             :   // Copy a portion of an existing FixedArray or FixedDoubleArray into a new
    1729             :   // FixedArray, including special appropriate handling for COW arrays.
    1730             :   // * |source| is either a FixedArray or FixedDoubleArray from which to copy
    1731             :   // elements. |source| is assumed to be non-empty.
    1732             :   // * |first| is the starting element index to copy from.
    1733             :   // * |count| is the number of elements to copy out of the source array
    1734             :   // starting from and including the element indexed by |start|.
    1735             :   // * |capacity| determines the size of the allocated result array, with
    1736             :   // |capacity| >= |count|.
    1737             :   // * |source_map| is the map of the |source|.
    1738             :   // * |from_kind| is the elements kind that is consistent with |source| being
    1739             :   // a FixedArray or FixedDoubleArray. This function only cares about double vs.
    1740             :   // non-double, so as to distinguish FixedDoubleArray vs. FixedArray. It does
    1741             :   // not care about holeyness. For example, when |source| is a FixedArray,
    1742             :   // PACKED/HOLEY_ELEMENTS can be used, but not PACKED_DOUBLE_ELEMENTS.
    1743             :   // * |allocation_flags| and |extract_flags| influence how the target
    1744             :   // FixedArray is allocated.
    1745             :   // * |parameter_mode| determines the parameter mode of |first|, |count| and
    1746             :   // |capacity|.
    1747             :   // * |convert_holes| is used to signify that the target array should use
    1748             :   // undefined in places of holes.
    1749             :   // * If |convert_holes| is true and |var_holes_converted| not nullptr, then
    1750             :   // |var_holes_converted| is used to signal whether any holes were found and
    1751             :   // converted. The caller should use this information to decide which map is
    1752             :   // compatible with the result array. For example, if the input was of
    1753             :   // HOLEY_SMI_ELEMENTS kind, and a conversion took place, the result will be
    1754             :   // compatible only with HOLEY_ELEMENTS and PACKED_ELEMENTS.
    1755             :   TNode<FixedArray> ExtractToFixedArray(
    1756             :       Node* source, Node* first, Node* count, Node* capacity, Node* source_map,
    1757             :       ElementsKind from_kind = PACKED_ELEMENTS,
    1758             :       AllocationFlags allocation_flags = AllocationFlag::kNone,
    1759             :       ExtractFixedArrayFlags extract_flags =
    1760             :           ExtractFixedArrayFlag::kAllFixedArrays,
    1761             :       ParameterMode parameter_mode = INTPTR_PARAMETERS,
    1762             :       HoleConversionMode convert_holes = HoleConversionMode::kDontConvert,
    1763             :       TVariable<BoolT>* var_holes_converted = nullptr,
    1764             :       Node* source_runtime_kind = nullptr);
    1765             : 
    1766             :   // Attempt to copy a FixedDoubleArray to another FixedDoubleArray. In the case
    1767             :   // where the source array has a hole, produce a FixedArray instead where holes
    1768             :   // are replaced with undefined.
    1769             :   // * |source| is a FixedDoubleArray from which to copy elements.
    1770             :   // * |first| is the starting element index to copy from.
    1771             :   // * |count| is the number of elements to copy out of the source array
    1772             :   // starting from and including the element indexed by |start|.
    1773             :   // * |capacity| determines the size of the allocated result array, with
    1774             :   // |capacity| >= |count|.
    1775             :   // * |source_map| is the map of |source|. It will be used as the map of the
    1776             :   // target array if the target can stay a FixedDoubleArray. Otherwise if the
    1777             :   // target array needs to be a FixedArray, the FixedArrayMap will be used.
    1778             :   // * |var_holes_converted| is used to signal whether a FixedAray
    1779             :   // is produced or not.
    1780             :   // * |allocation_flags| and |extract_flags| influence how the target array is
    1781             :   // allocated.
    1782             :   // * |parameter_mode| determines the parameter mode of |first|, |count| and
    1783             :   // |capacity|.
    1784             :   TNode<FixedArrayBase> ExtractFixedDoubleArrayFillingHoles(
    1785             :       Node* source, Node* first, Node* count, Node* capacity, Node* source_map,
    1786             :       TVariable<BoolT>* var_holes_converted, AllocationFlags allocation_flags,
    1787             :       ExtractFixedArrayFlags extract_flags =
    1788             :           ExtractFixedArrayFlag::kAllFixedArrays,
    1789             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
    1790             : 
    1791             :   // Copy the entire contents of a FixedArray or FixedDoubleArray to a new
    1792             :   // array, including special appropriate handling for empty arrays and COW
    1793             :   // arrays.
    1794             :   //
    1795             :   // * |source| is either a FixedArray or FixedDoubleArray from which to copy
    1796             :   // elements.
    1797             :   // * |extract_flags| determines whether FixedArrays, FixedDoubleArrays or both
    1798             :   // are detected and copied. Although it's always correct to pass
    1799             :   // kAllFixedArrays, the generated code is more compact and efficient if the
    1800             :   // caller can specify whether only FixedArrays or FixedDoubleArrays will be
    1801             :   // passed as the |source| parameter.
    1802         351 :   Node* CloneFixedArray(Node* source,
    1803             :                         ExtractFixedArrayFlags flags =
    1804             :                             ExtractFixedArrayFlag::kAllFixedArraysDontCopyCOW) {
    1805             :     ParameterMode mode = OptimalParameterMode();
    1806             :     return ExtractFixedArray(source, IntPtrOrSmiConstant(0, mode), nullptr,
    1807         702 :                              nullptr, flags, mode);
    1808             :   }
    1809             : 
    1810             :   // Copies |character_count| elements from |from_string| to |to_string|
    1811             :   // starting at the |from_index|'th character. |from_string| and |to_string|
    1812             :   // can either be one-byte strings or two-byte strings, although if
    1813             :   // |from_string| is two-byte, then |to_string| must be two-byte.
    1814             :   // |from_index|, |to_index| and |character_count| must be intptr_ts s.t. 0 <=
    1815             :   // |from_index| <= |from_index| + |character_count| <= from_string.length and
    1816             :   // 0 <= |to_index| <= |to_index| + |character_count| <= to_string.length.
    1817             :   void CopyStringCharacters(Node* from_string, Node* to_string,
    1818             :                             TNode<IntPtrT> from_index, TNode<IntPtrT> to_index,
    1819             :                             TNode<IntPtrT> character_count,
    1820             :                             String::Encoding from_encoding,
    1821             :                             String::Encoding to_encoding);
    1822             : 
    1823             :   // Loads an element from |array| of |from_kind| elements by given |offset|
    1824             :   // (NOTE: not index!), does a hole check if |if_hole| is provided and
    1825             :   // converts the value so that it becomes ready for storing to array of
    1826             :   // |to_kind| elements.
    1827             :   Node* LoadElementAndPrepareForStore(Node* array, Node* offset,
    1828             :                                       ElementsKind from_kind,
    1829             :                                       ElementsKind to_kind, Label* if_hole);
    1830             : 
    1831             :   Node* CalculateNewElementsCapacity(Node* old_capacity,
    1832             :                                      ParameterMode mode = INTPTR_PARAMETERS);
    1833             : 
    1834             :   TNode<Smi> CalculateNewElementsCapacity(TNode<Smi> old_capacity) {
    1835         112 :     return CAST(CalculateNewElementsCapacity(old_capacity, SMI_PARAMETERS));
    1836             :   }
    1837             : 
    1838             :   // Tries to grow the |elements| array of given |object| to store the |key|
    1839             :   // or bails out if the growing gap is too big. Returns new elements.
    1840             :   Node* TryGrowElementsCapacity(Node* object, Node* elements, ElementsKind kind,
    1841             :                                 Node* key, Label* bailout);
    1842             : 
    1843             :   // Tries to grow the |capacity|-length |elements| array of given |object|
    1844             :   // to store the |key| or bails out if the growing gap is too big. Returns
    1845             :   // new elements.
    1846             :   Node* TryGrowElementsCapacity(Node* object, Node* elements, ElementsKind kind,
    1847             :                                 Node* key, Node* capacity, ParameterMode mode,
    1848             :                                 Label* bailout);
    1849             : 
    1850             :   // Grows elements capacity of given object. Returns new elements.
    1851             :   Node* GrowElementsCapacity(Node* object, Node* elements,
    1852             :                              ElementsKind from_kind, ElementsKind to_kind,
    1853             :                              Node* capacity, Node* new_capacity,
    1854             :                              ParameterMode mode, Label* bailout);
    1855             : 
    1856             :   // Given a need to grow by |growth|, allocate an appropriate new capacity
    1857             :   // if necessary, and return a new elements FixedArray object. Label |bailout|
    1858             :   // is followed for allocation failure.
    1859             :   void PossiblyGrowElementsCapacity(ParameterMode mode, ElementsKind kind,
    1860             :                                     Node* array, Node* length,
    1861             :                                     Variable* var_elements, Node* growth,
    1862             :                                     Label* bailout);
    1863             : 
    1864             :   // Allocation site manipulation
    1865             :   void InitializeAllocationMemento(Node* base_allocation,
    1866             :                                    Node* base_allocation_size,
    1867             :                                    Node* allocation_site);
    1868             : 
    1869             :   Node* TryTaggedToFloat64(Node* value, Label* if_valueisnotnumber);
    1870             :   Node* TruncateTaggedToFloat64(Node* context, Node* value);
    1871             :   Node* TruncateTaggedToWord32(Node* context, Node* value);
    1872             :   void TaggedToWord32OrBigInt(Node* context, Node* value, Label* if_number,
    1873             :                               Variable* var_word32, Label* if_bigint,
    1874             :                               Variable* var_bigint);
    1875             :   void TaggedToWord32OrBigIntWithFeedback(
    1876             :       Node* context, Node* value, Label* if_number, Variable* var_word32,
    1877             :       Label* if_bigint, Variable* var_bigint, Variable* var_feedback);
    1878             : 
    1879             :   // Truncate the floating point value of a HeapNumber to an Int32.
    1880             :   Node* TruncateHeapNumberValueToWord32(Node* object);
    1881             : 
    1882             :   // Conversions.
    1883             :   void TryHeapNumberToSmi(TNode<HeapNumber> number, TVariable<Smi>& output,
    1884             :                           Label* if_smi);
    1885             :   void TryFloat64ToSmi(TNode<Float64T> number, TVariable<Smi>& output,
    1886             :                        Label* if_smi);
    1887             :   TNode<Number> ChangeFloat64ToTagged(SloppyTNode<Float64T> value);
    1888             :   TNode<Number> ChangeInt32ToTagged(SloppyTNode<Int32T> value);
    1889             :   TNode<Number> ChangeUint32ToTagged(SloppyTNode<Uint32T> value);
    1890             :   TNode<Number> ChangeUintPtrToTagged(TNode<UintPtrT> value);
    1891             :   TNode<Uint32T> ChangeNumberToUint32(TNode<Number> value);
    1892             :   TNode<Float64T> ChangeNumberToFloat64(SloppyTNode<Number> value);
    1893             :   TNode<UintPtrT> ChangeNonnegativeNumberToUintPtr(TNode<Number> value);
    1894             : 
    1895             :   void TaggedToNumeric(Node* context, Node* value, Label* done,
    1896             :                        Variable* var_numeric);
    1897             :   void TaggedToNumericWithFeedback(Node* context, Node* value, Label* done,
    1898             :                                    Variable* var_numeric,
    1899             :                                    Variable* var_feedback);
    1900             : 
    1901             :   TNode<WordT> TimesSystemPointerSize(SloppyTNode<WordT> value);
    1902             :   TNode<IntPtrT> TimesSystemPointerSize(TNode<IntPtrT> value) {
    1903         448 :     return Signed(TimesSystemPointerSize(implicit_cast<TNode<WordT>>(value)));
    1904             :   }
    1905             :   TNode<UintPtrT> TimesSystemPointerSize(TNode<UintPtrT> value) {
    1906             :     return Unsigned(TimesSystemPointerSize(implicit_cast<TNode<WordT>>(value)));
    1907             :   }
    1908             : 
    1909             :   TNode<WordT> TimesTaggedSize(SloppyTNode<WordT> value);
    1910             :   TNode<IntPtrT> TimesTaggedSize(TNode<IntPtrT> value) {
    1911         392 :     return Signed(TimesTaggedSize(implicit_cast<TNode<WordT>>(value)));
    1912             :   }
    1913             :   TNode<UintPtrT> TimesTaggedSize(TNode<UintPtrT> value) {
    1914             :     return Unsigned(TimesTaggedSize(implicit_cast<TNode<WordT>>(value)));
    1915             :   }
    1916             : 
    1917             :   TNode<WordT> TimesDoubleSize(SloppyTNode<WordT> value);
    1918             :   TNode<UintPtrT> TimesDoubleSize(TNode<UintPtrT> value) {
    1919             :     return Unsigned(TimesDoubleSize(implicit_cast<TNode<WordT>>(value)));
    1920             :   }
    1921             :   TNode<IntPtrT> TimesDoubleSize(TNode<IntPtrT> value) {
    1922             :     return Signed(TimesDoubleSize(implicit_cast<TNode<WordT>>(value)));
    1923             :   }
    1924             : 
    1925             :   // Type conversions.
    1926             :   // Throws a TypeError for {method_name} if {value} is not coercible to Object,
    1927             :   // or returns the {value} converted to a String otherwise.
    1928             :   TNode<String> ToThisString(Node* context, Node* value,
    1929             :                              char const* method_name);
    1930             :   // Throws a TypeError for {method_name} if {value} is neither of the given
    1931             :   // {primitive_type} nor a JSValue wrapping a value of {primitive_type}, or
    1932             :   // returns the {value} (or wrapped value) otherwise.
    1933             :   Node* ToThisValue(Node* context, Node* value, PrimitiveType primitive_type,
    1934             :                     char const* method_name);
    1935             : 
    1936             :   // Throws a TypeError for {method_name} if {value} is not of the given
    1937             :   // instance type. Returns {value}'s map.
    1938             :   Node* ThrowIfNotInstanceType(Node* context, Node* value,
    1939             :                                InstanceType instance_type,
    1940             :                                char const* method_name);
    1941             :   // Throws a TypeError for {method_name} if {value} is not a JSReceiver.
    1942             :   // Returns the {value}'s map.
    1943             :   Node* ThrowIfNotJSReceiver(Node* context, Node* value,
    1944             :                              MessageTemplate msg_template,
    1945             :                              const char* method_name = nullptr);
    1946             : 
    1947             :   void ThrowRangeError(Node* context, MessageTemplate message,
    1948             :                        Node* arg0 = nullptr, Node* arg1 = nullptr,
    1949             :                        Node* arg2 = nullptr);
    1950             :   void ThrowTypeError(Node* context, MessageTemplate message,
    1951             :                       char const* arg0 = nullptr, char const* arg1 = nullptr);
    1952             :   void ThrowTypeError(Node* context, MessageTemplate message, Node* arg0,
    1953             :                       Node* arg1 = nullptr, Node* arg2 = nullptr);
    1954             : 
    1955             :   // Type checks.
    1956             :   // Check whether the map is for an object with special properties, such as a
    1957             :   // JSProxy or an object with interceptors.
    1958             :   TNode<BoolT> InstanceTypeEqual(SloppyTNode<Int32T> instance_type, int type);
    1959             :   TNode<BoolT> IsAccessorInfo(SloppyTNode<HeapObject> object);
    1960             :   TNode<BoolT> IsAccessorPair(SloppyTNode<HeapObject> object);
    1961             :   TNode<BoolT> IsAllocationSite(SloppyTNode<HeapObject> object);
    1962             :   TNode<BoolT> IsAnyHeapNumber(SloppyTNode<HeapObject> object);
    1963             :   TNode<BoolT> IsNoElementsProtectorCellInvalid();
    1964             :   TNode<BoolT> IsArrayIteratorProtectorCellInvalid();
    1965             :   TNode<BoolT> IsBigIntInstanceType(SloppyTNode<Int32T> instance_type);
    1966             :   TNode<BoolT> IsBigInt(SloppyTNode<HeapObject> object);
    1967             :   TNode<BoolT> IsBoolean(SloppyTNode<HeapObject> object);
    1968             :   TNode<BoolT> IsCallableMap(SloppyTNode<Map> map);
    1969             :   TNode<BoolT> IsCallable(SloppyTNode<HeapObject> object);
    1970             :   TNode<BoolT> TaggedIsCallable(TNode<Object> object);
    1971             :   TNode<BoolT> IsCell(SloppyTNode<HeapObject> object);
    1972             :   TNode<BoolT> IsCode(SloppyTNode<HeapObject> object);
    1973             :   TNode<BoolT> IsConsStringInstanceType(SloppyTNode<Int32T> instance_type);
    1974             :   TNode<BoolT> IsConstructorMap(SloppyTNode<Map> map);
    1975             :   TNode<BoolT> IsConstructor(SloppyTNode<HeapObject> object);
    1976             :   TNode<BoolT> IsDeprecatedMap(SloppyTNode<Map> map);
    1977             :   TNode<BoolT> IsNameDictionary(SloppyTNode<HeapObject> object);
    1978             :   TNode<BoolT> IsGlobalDictionary(SloppyTNode<HeapObject> object);
    1979             :   TNode<BoolT> IsExtensibleMap(SloppyTNode<Map> map);
    1980             :   TNode<BoolT> IsExtensibleNonPrototypeMap(TNode<Map> map);
    1981             :   TNode<BoolT> IsExternalStringInstanceType(SloppyTNode<Int32T> instance_type);
    1982             :   TNode<BoolT> IsFeedbackCell(SloppyTNode<HeapObject> object);
    1983             :   TNode<BoolT> IsFeedbackVector(SloppyTNode<HeapObject> object);
    1984             :   TNode<BoolT> IsContext(SloppyTNode<HeapObject> object);
    1985             :   TNode<BoolT> IsFixedArray(SloppyTNode<HeapObject> object);
    1986             :   TNode<BoolT> IsFixedArraySubclass(SloppyTNode<HeapObject> object);
    1987             :   TNode<BoolT> IsFixedArrayWithKind(SloppyTNode<HeapObject> object,
    1988             :                                     ElementsKind kind);
    1989             :   TNode<BoolT> IsFixedArrayWithKindOrEmpty(SloppyTNode<HeapObject> object,
    1990             :                                            ElementsKind kind);
    1991             :   TNode<BoolT> IsFixedDoubleArray(SloppyTNode<HeapObject> object);
    1992             :   TNode<BoolT> IsFixedTypedArray(SloppyTNode<HeapObject> object);
    1993             :   TNode<BoolT> IsFunctionWithPrototypeSlotMap(SloppyTNode<Map> map);
    1994             :   TNode<BoolT> IsHashTable(SloppyTNode<HeapObject> object);
    1995             :   TNode<BoolT> IsEphemeronHashTable(SloppyTNode<HeapObject> object);
    1996             :   TNode<BoolT> IsHeapNumber(SloppyTNode<HeapObject> object);
    1997             :   TNode<BoolT> IsHeapNumberInstanceType(SloppyTNode<Int32T> instance_type);
    1998             :   TNode<BoolT> IsOddball(SloppyTNode<HeapObject> object);
    1999             :   TNode<BoolT> IsOddballInstanceType(SloppyTNode<Int32T> instance_type);
    2000             :   TNode<BoolT> IsIndirectStringInstanceType(SloppyTNode<Int32T> instance_type);
    2001             :   TNode<BoolT> IsJSArrayBuffer(SloppyTNode<HeapObject> object);
    2002             :   TNode<BoolT> IsJSDataView(TNode<HeapObject> object);
    2003             :   TNode<BoolT> IsJSArrayInstanceType(SloppyTNode<Int32T> instance_type);
    2004             :   TNode<BoolT> IsJSArrayMap(SloppyTNode<Map> map);
    2005             :   TNode<BoolT> IsJSArray(SloppyTNode<HeapObject> object);
    2006             :   TNode<BoolT> IsJSArrayIterator(SloppyTNode<HeapObject> object);
    2007             :   TNode<BoolT> IsJSAsyncGeneratorObject(SloppyTNode<HeapObject> object);
    2008             :   TNode<BoolT> IsJSFunctionInstanceType(SloppyTNode<Int32T> instance_type);
    2009             :   TNode<BoolT> IsAllocationSiteInstanceType(SloppyTNode<Int32T> instance_type);
    2010             :   TNode<BoolT> IsJSFunctionMap(SloppyTNode<Map> map);
    2011             :   TNode<BoolT> IsJSFunction(SloppyTNode<HeapObject> object);
    2012             :   TNode<BoolT> IsJSGeneratorObject(SloppyTNode<HeapObject> object);
    2013             :   TNode<BoolT> IsJSGlobalProxyInstanceType(SloppyTNode<Int32T> instance_type);
    2014             :   TNode<BoolT> IsJSGlobalProxy(SloppyTNode<HeapObject> object);
    2015             :   TNode<BoolT> IsJSObjectInstanceType(SloppyTNode<Int32T> instance_type);
    2016             :   TNode<BoolT> IsJSObjectMap(SloppyTNode<Map> map);
    2017             :   TNode<BoolT> IsJSObject(SloppyTNode<HeapObject> object);
    2018             :   TNode<BoolT> IsJSPromiseMap(SloppyTNode<Map> map);
    2019             :   TNode<BoolT> IsJSPromise(SloppyTNode<HeapObject> object);
    2020             :   TNode<BoolT> IsJSProxy(SloppyTNode<HeapObject> object);
    2021             :   TNode<BoolT> IsJSReceiverInstanceType(SloppyTNode<Int32T> instance_type);
    2022             :   TNode<BoolT> IsJSReceiverMap(SloppyTNode<Map> map);
    2023             :   TNode<BoolT> IsJSReceiver(SloppyTNode<HeapObject> object);
    2024             :   TNode<BoolT> IsJSRegExp(SloppyTNode<HeapObject> object);
    2025             :   TNode<BoolT> IsJSTypedArray(SloppyTNode<HeapObject> object);
    2026             :   TNode<BoolT> IsJSValueInstanceType(SloppyTNode<Int32T> instance_type);
    2027             :   TNode<BoolT> IsJSValueMap(SloppyTNode<Map> map);
    2028             :   TNode<BoolT> IsJSValue(SloppyTNode<HeapObject> object);
    2029             :   TNode<BoolT> IsMap(SloppyTNode<HeapObject> object);
    2030             :   TNode<BoolT> IsMutableHeapNumber(SloppyTNode<HeapObject> object);
    2031             :   TNode<BoolT> IsName(SloppyTNode<HeapObject> object);
    2032             :   TNode<BoolT> IsNameInstanceType(SloppyTNode<Int32T> instance_type);
    2033             :   TNode<BoolT> IsNativeContext(SloppyTNode<HeapObject> object);
    2034             :   TNode<BoolT> IsNullOrJSReceiver(SloppyTNode<HeapObject> object);
    2035             :   TNode<BoolT> IsNullOrUndefined(SloppyTNode<Object> object);
    2036             :   TNode<BoolT> IsNumberDictionary(SloppyTNode<HeapObject> object);
    2037             :   TNode<BoolT> IsOneByteStringInstanceType(SloppyTNode<Int32T> instance_type);
    2038             :   TNode<BoolT> HasOnlyOneByteChars(TNode<Int32T> instance_type);
    2039             :   TNode<BoolT> IsPrimitiveInstanceType(SloppyTNode<Int32T> instance_type);
    2040             :   TNode<BoolT> IsPrivateSymbol(SloppyTNode<HeapObject> object);
    2041             :   TNode<BoolT> IsPromiseCapability(SloppyTNode<HeapObject> object);
    2042             :   TNode<BoolT> IsPropertyArray(SloppyTNode<HeapObject> object);
    2043             :   TNode<BoolT> IsPropertyCell(SloppyTNode<HeapObject> object);
    2044             :   TNode<BoolT> IsPrototypeInitialArrayPrototype(SloppyTNode<Context> context,
    2045             :                                                 SloppyTNode<Map> map);
    2046             :   TNode<BoolT> IsPrototypeTypedArrayPrototype(SloppyTNode<Context> context,
    2047             :                                               SloppyTNode<Map> map);
    2048             : 
    2049             :   TNode<BoolT> IsFastAliasedArgumentsMap(TNode<Context> context,
    2050             :                                          TNode<Map> map);
    2051             :   TNode<BoolT> IsSlowAliasedArgumentsMap(TNode<Context> context,
    2052             :                                          TNode<Map> map);
    2053             :   TNode<BoolT> IsSloppyArgumentsMap(TNode<Context> context, TNode<Map> map);
    2054             :   TNode<BoolT> IsStrictArgumentsMap(TNode<Context> context, TNode<Map> map);
    2055             : 
    2056             :   TNode<BoolT> IsSequentialStringInstanceType(
    2057             :       SloppyTNode<Int32T> instance_type);
    2058             :   TNode<BoolT> IsUncachedExternalStringInstanceType(
    2059             :       SloppyTNode<Int32T> instance_type);
    2060             :   TNode<BoolT> IsSpecialReceiverInstanceType(TNode<Int32T> instance_type);
    2061             :   TNode<BoolT> IsCustomElementsReceiverInstanceType(
    2062             :       TNode<Int32T> instance_type);
    2063             :   TNode<BoolT> IsSpecialReceiverMap(SloppyTNode<Map> map);
    2064             :   // Returns true if the map corresponds to non-special fast or dictionary
    2065             :   // object.
    2066             :   TNode<BoolT> IsSimpleObjectMap(TNode<Map> map);
    2067             :   TNode<BoolT> IsStringInstanceType(SloppyTNode<Int32T> instance_type);
    2068             :   TNode<BoolT> IsString(SloppyTNode<HeapObject> object);
    2069             :   TNode<BoolT> IsSymbolInstanceType(SloppyTNode<Int32T> instance_type);
    2070             :   TNode<BoolT> IsSymbol(SloppyTNode<HeapObject> object);
    2071             :   TNode<BoolT> IsUndetectableMap(SloppyTNode<Map> map);
    2072             :   TNode<BoolT> IsNotWeakFixedArraySubclass(SloppyTNode<HeapObject> object);
    2073             :   TNode<BoolT> IsZeroOrContext(SloppyTNode<Object> object);
    2074             : 
    2075             :   inline Node* IsSharedFunctionInfo(Node* object) {
    2076             :     return IsSharedFunctionInfoMap(LoadMap(object));
    2077             :   }
    2078             : 
    2079             :   TNode<BoolT> IsPromiseResolveProtectorCellInvalid();
    2080             :   TNode<BoolT> IsPromiseThenProtectorCellInvalid();
    2081             :   TNode<BoolT> IsArraySpeciesProtectorCellInvalid();
    2082             :   TNode<BoolT> IsTypedArraySpeciesProtectorCellInvalid();
    2083             :   TNode<BoolT> IsRegExpSpeciesProtectorCellInvalid();
    2084             :   TNode<BoolT> IsPromiseSpeciesProtectorCellInvalid();
    2085             : 
    2086             :   // True iff |object| is a Smi or a HeapNumber.
    2087             :   TNode<BoolT> IsNumber(SloppyTNode<Object> object);
    2088             :   // True iff |object| is a Smi or a HeapNumber or a BigInt.
    2089             :   TNode<BoolT> IsNumeric(SloppyTNode<Object> object);
    2090             : 
    2091             :   // True iff |number| is either a Smi, or a HeapNumber whose value is not
    2092             :   // within Smi range.
    2093             :   TNode<BoolT> IsNumberNormalized(SloppyTNode<Number> number);
    2094             :   TNode<BoolT> IsNumberPositive(SloppyTNode<Number> number);
    2095             :   TNode<BoolT> IsHeapNumberPositive(TNode<HeapNumber> number);
    2096             : 
    2097             :   // True iff {number} is non-negative and less or equal than 2**53-1.
    2098             :   TNode<BoolT> IsNumberNonNegativeSafeInteger(TNode<Number> number);
    2099             : 
    2100             :   // True iff {number} represents an integer value.
    2101             :   TNode<BoolT> IsInteger(TNode<Object> number);
    2102             :   TNode<BoolT> IsInteger(TNode<HeapNumber> number);
    2103             : 
    2104             :   // True iff abs({number}) <= 2**53 -1
    2105             :   TNode<BoolT> IsSafeInteger(TNode<Object> number);
    2106             :   TNode<BoolT> IsSafeInteger(TNode<HeapNumber> number);
    2107             : 
    2108             :   // True iff {number} represents a valid uint32t value.
    2109             :   TNode<BoolT> IsHeapNumberUint32(TNode<HeapNumber> number);
    2110             : 
    2111             :   // True iff {number} is a positive number and a valid array index in the range
    2112             :   // [0, 2^32-1).
    2113             :   TNode<BoolT> IsNumberArrayIndex(TNode<Number> number);
    2114             : 
    2115             :   Node* FixedArraySizeDoesntFitInNewSpace(
    2116             :       Node* element_count, int base_size = FixedArray::kHeaderSize,
    2117             :       ParameterMode mode = INTPTR_PARAMETERS);
    2118             : 
    2119             :   // ElementsKind helpers:
    2120             :   TNode<BoolT> ElementsKindEqual(TNode<Int32T> a, TNode<Int32T> b) {
    2121        2856 :     return Word32Equal(a, b);
    2122             :   }
    2123             :   bool ElementsKindEqual(ElementsKind a, ElementsKind b) { return a == b; }
    2124             :   Node* IsFastElementsKind(Node* elements_kind);
    2125             :   bool IsFastElementsKind(ElementsKind kind) {
    2126             :     return v8::internal::IsFastElementsKind(kind);
    2127             :   }
    2128             :   TNode<BoolT> IsDictionaryElementsKind(TNode<Int32T> elements_kind) {
    2129             :     return ElementsKindEqual(elements_kind, Int32Constant(DICTIONARY_ELEMENTS));
    2130             :   }
    2131             :   TNode<BoolT> IsDoubleElementsKind(TNode<Int32T> elements_kind);
    2132             :   bool IsDoubleElementsKind(ElementsKind kind) {
    2133             :     return v8::internal::IsDoubleElementsKind(kind);
    2134             :   }
    2135             :   Node* IsFastSmiOrTaggedElementsKind(Node* elements_kind);
    2136             :   Node* IsFastSmiElementsKind(Node* elements_kind);
    2137             :   Node* IsHoleyFastElementsKind(Node* elements_kind);
    2138             :   Node* IsElementsKindGreaterThan(Node* target_kind,
    2139             :                                   ElementsKind reference_kind);
    2140             :   TNode<BoolT> IsElementsKindLessThanOrEqual(TNode<Int32T> target_kind,
    2141             :                                              ElementsKind reference_kind);
    2142             : 
    2143             :   // String helpers.
    2144             :   // Load a character from a String (might flatten a ConsString).
    2145             :   TNode<Int32T> StringCharCodeAt(SloppyTNode<String> string,
    2146             :                                  SloppyTNode<IntPtrT> index);
    2147             :   // Return the single character string with only {code}.
    2148             :   TNode<String> StringFromSingleCharCode(TNode<Int32T> code);
    2149             : 
    2150             :   // Return a new string object which holds a substring containing the range
    2151             :   // [from,to[ of string.
    2152             :   TNode<String> SubString(TNode<String> string, TNode<IntPtrT> from,
    2153             :                           TNode<IntPtrT> to);
    2154             : 
    2155             :   // Return a new string object produced by concatenating |first| with |second|.
    2156             :   TNode<String> StringAdd(Node* context, TNode<String> first,
    2157             :                           TNode<String> second, AllocationFlags flags = kNone);
    2158             : 
    2159             :   // Check if |string| is an indirect (thin or flat cons) string type that can
    2160             :   // be dereferenced by DerefIndirectString.
    2161             :   void BranchIfCanDerefIndirectString(Node* string, Node* instance_type,
    2162             :                                       Label* can_deref, Label* cannot_deref);
    2163             :   // Unpack an indirect (thin or flat cons) string type.
    2164             :   void DerefIndirectString(Variable* var_string, Node* instance_type);
    2165             :   // Check if |var_string| has an indirect (thin or flat cons) string type,
    2166             :   // and unpack it if so.
    2167             :   void MaybeDerefIndirectString(Variable* var_string, Node* instance_type,
    2168             :                                 Label* did_deref, Label* cannot_deref);
    2169             :   // Check if |var_left| or |var_right| has an indirect (thin or flat cons)
    2170             :   // string type, and unpack it/them if so. Fall through if nothing was done.
    2171             :   void MaybeDerefIndirectStrings(Variable* var_left, Node* left_instance_type,
    2172             :                                  Variable* var_right, Node* right_instance_type,
    2173             :                                  Label* did_something);
    2174             :   Node* DerefIndirectString(TNode<String> string, TNode<Int32T> instance_type,
    2175             :                             Label* cannot_deref);
    2176             : 
    2177             :   TNode<String> StringFromSingleCodePoint(TNode<Int32T> codepoint,
    2178             :                                           UnicodeEncoding encoding);
    2179             : 
    2180             :   // Type conversion helpers.
    2181             :   enum class BigIntHandling { kConvertToNumber, kThrow };
    2182             :   // Convert a String to a Number.
    2183             :   TNode<Number> StringToNumber(TNode<String> input);
    2184             :   // Convert a Number to a String.
    2185             :   TNode<String> NumberToString(TNode<Number> input);
    2186             :   // Convert a Non-Number object to a Number.
    2187             :   TNode<Number> NonNumberToNumber(
    2188             :       SloppyTNode<Context> context, SloppyTNode<HeapObject> input,
    2189             :       BigIntHandling bigint_handling = BigIntHandling::kThrow);
    2190             :   // Convert a Non-Number object to a Numeric.
    2191             :   TNode<Numeric> NonNumberToNumeric(SloppyTNode<Context> context,
    2192             :                                     SloppyTNode<HeapObject> input);
    2193             :   // Convert any object to a Number.
    2194             :   // Conforms to ES#sec-tonumber if {bigint_handling} == kThrow.
    2195             :   // With {bigint_handling} == kConvertToNumber, matches behavior of
    2196             :   // tc39.github.io/proposal-bigint/#sec-number-constructor-number-value.
    2197             :   TNode<Number> ToNumber(
    2198             :       SloppyTNode<Context> context, SloppyTNode<Object> input,
    2199             :       BigIntHandling bigint_handling = BigIntHandling::kThrow);
    2200             :   TNode<Number> ToNumber_Inline(SloppyTNode<Context> context,
    2201             :                                 SloppyTNode<Object> input);
    2202             : 
    2203             :   // Try to convert an object to a BigInt. Throws on failure (e.g. for Numbers).
    2204             :   // https://tc39.github.io/proposal-bigint/#sec-to-bigint
    2205             :   TNode<BigInt> ToBigInt(SloppyTNode<Context> context,
    2206             :                          SloppyTNode<Object> input);
    2207             : 
    2208             :   // Converts |input| to one of 2^32 integer values in the range 0 through
    2209             :   // 2^32-1, inclusive.
    2210             :   // ES#sec-touint32
    2211             :   TNode<Number> ToUint32(SloppyTNode<Context> context,
    2212             :                          SloppyTNode<Object> input);
    2213             : 
    2214             :   // Convert any object to a String.
    2215             :   TNode<String> ToString(SloppyTNode<Context> context,
    2216             :                          SloppyTNode<Object> input);
    2217             :   TNode<String> ToString_Inline(SloppyTNode<Context> context,
    2218             :                                 SloppyTNode<Object> input);
    2219             : 
    2220             :   // Convert any object to a Primitive.
    2221             :   Node* JSReceiverToPrimitive(Node* context, Node* input);
    2222             : 
    2223             :   TNode<JSReceiver> ToObject(SloppyTNode<Context> context,
    2224             :                              SloppyTNode<Object> input);
    2225             : 
    2226             :   // Same as ToObject but avoids the Builtin call if |input| is already a
    2227             :   // JSReceiver.
    2228             :   TNode<JSReceiver> ToObject_Inline(TNode<Context> context,
    2229             :                                     TNode<Object> input);
    2230             : 
    2231             :   enum ToIntegerTruncationMode {
    2232             :     kNoTruncation,
    2233             :     kTruncateMinusZero,
    2234             :   };
    2235             : 
    2236             :   // ES6 7.1.17 ToIndex, but jumps to range_error if the result is not a Smi.
    2237             :   TNode<Smi> ToSmiIndex(TNode<Object> input, TNode<Context> context,
    2238             :                         Label* range_error);
    2239             : 
    2240             :   // ES6 7.1.15 ToLength, but jumps to range_error if the result is not a Smi.
    2241             :   TNode<Smi> ToSmiLength(TNode<Object> input, TNode<Context> context,
    2242             :                          Label* range_error);
    2243             : 
    2244             :   // ES6 7.1.15 ToLength, but with inlined fast path.
    2245             :   TNode<Number> ToLength_Inline(SloppyTNode<Context> context,
    2246             :                                 SloppyTNode<Object> input);
    2247             : 
    2248             :   // ES6 7.1.4 ToInteger ( argument )
    2249             :   TNode<Number> ToInteger_Inline(SloppyTNode<Context> context,
    2250             :                                  SloppyTNode<Object> input,
    2251             :                                  ToIntegerTruncationMode mode = kNoTruncation);
    2252             :   TNode<Number> ToInteger(SloppyTNode<Context> context,
    2253             :                           SloppyTNode<Object> input,
    2254             :                           ToIntegerTruncationMode mode = kNoTruncation);
    2255             : 
    2256             :   // Returns a node that contains a decoded (unsigned!) value of a bit
    2257             :   // field |BitField| in |word32|. Returns result as an uint32 node.
    2258             :   template <typename BitField>
    2259             :   TNode<Uint32T> DecodeWord32(SloppyTNode<Word32T> word32) {
    2260       33431 :     return DecodeWord32(word32, BitField::kShift, BitField::kMask);
    2261             :   }
    2262             : 
    2263             :   // Returns a node that contains a decoded (unsigned!) value of a bit
    2264             :   // field |BitField| in |word|. Returns result as a word-size node.
    2265             :   template <typename BitField>
    2266             :   TNode<UintPtrT> DecodeWord(SloppyTNode<WordT> word) {
    2267       19620 :     return DecodeWord(word, BitField::kShift, BitField::kMask);
    2268             :   }
    2269             : 
    2270             :   // Returns a node that contains a decoded (unsigned!) value of a bit
    2271             :   // field |BitField| in |word32|. Returns result as a word-size node.
    2272             :   template <typename BitField>
    2273        6684 :   TNode<UintPtrT> DecodeWordFromWord32(SloppyTNode<Word32T> word32) {
    2274       13368 :     return DecodeWord<BitField>(ChangeUint32ToWord(word32));
    2275             :   }
    2276             : 
    2277             :   // Returns a node that contains a decoded (unsigned!) value of a bit
    2278             :   // field |BitField| in |word|. Returns result as an uint32 node.
    2279             :   template <typename BitField>
    2280          56 :   TNode<Uint32T> DecodeWord32FromWord(SloppyTNode<WordT> word) {
    2281             :     return UncheckedCast<Uint32T>(
    2282          56 :         TruncateIntPtrToInt32(Signed(DecodeWord<BitField>(word))));
    2283             :   }
    2284             : 
    2285             :   // Decodes an unsigned (!) value from |word32| to an uint32 node.
    2286             :   TNode<Uint32T> DecodeWord32(SloppyTNode<Word32T> word32, uint32_t shift,
    2287             :                               uint32_t mask);
    2288             : 
    2289             :   // Decodes an unsigned (!) value from |word| to a word-size node.
    2290             :   TNode<UintPtrT> DecodeWord(SloppyTNode<WordT> word, uint32_t shift,
    2291             :                              uint32_t mask);
    2292             : 
    2293             :   // Returns a node that contains the updated values of a |BitField|.
    2294             :   template <typename BitField>
    2295             :   TNode<WordT> UpdateWord(TNode<WordT> word, TNode<WordT> value) {
    2296         392 :     return UpdateWord(word, value, BitField::kShift, BitField::kMask);
    2297             :   }
    2298             : 
    2299             :   // Returns a node that contains the updated {value} inside {word} starting
    2300             :   // at {shift} and fitting in {mask}.
    2301             :   TNode<WordT> UpdateWord(TNode<WordT> word, TNode<WordT> value, uint32_t shift,
    2302             :                           uint32_t mask);
    2303             : 
    2304             :   // Returns true if any of the |T|'s bits in given |word32| are set.
    2305             :   template <typename T>
    2306             :   TNode<BoolT> IsSetWord32(SloppyTNode<Word32T> word32) {
    2307       47014 :     return IsSetWord32(word32, T::kMask);
    2308             :   }
    2309             : 
    2310             :   // Returns true if any of the mask's bits in given |word32| are set.
    2311       60978 :   TNode<BoolT> IsSetWord32(SloppyTNode<Word32T> word32, uint32_t mask) {
    2312      121956 :     return Word32NotEqual(Word32And(word32, Int32Constant(mask)),
    2313      243912 :                           Int32Constant(0));
    2314             :   }
    2315             : 
    2316             :   // Returns true if none of the mask's bits in given |word32| are set.
    2317         392 :   TNode<BoolT> IsNotSetWord32(SloppyTNode<Word32T> word32, uint32_t mask) {
    2318         784 :     return Word32Equal(Word32And(word32, Int32Constant(mask)),
    2319        1568 :                        Int32Constant(0));
    2320             :   }
    2321             : 
    2322             :   // Returns true if all of the mask's bits in a given |word32| are set.
    2323        3981 :   TNode<BoolT> IsAllSetWord32(SloppyTNode<Word32T> word32, uint32_t mask) {
    2324        3981 :     TNode<Int32T> const_mask = Int32Constant(mask);
    2325        7962 :     return Word32Equal(Word32And(word32, const_mask), const_mask);
    2326             :   }
    2327             : 
    2328             :   // Returns true if any of the |T|'s bits in given |word| are set.
    2329             :   template <typename T>
    2330             :   TNode<BoolT> IsSetWord(SloppyTNode<WordT> word) {
    2331        6832 :     return IsSetWord(word, T::kMask);
    2332             :   }
    2333             : 
    2334             :   // Returns true if any of the mask's bits in given |word| are set.
    2335       10757 :   TNode<BoolT> IsSetWord(SloppyTNode<WordT> word, uint32_t mask) {
    2336       43028 :     return WordNotEqual(WordAnd(word, IntPtrConstant(mask)), IntPtrConstant(0));
    2337             :   }
    2338             : 
    2339             :   // Returns true if any of the mask's bit are set in the given Smi.
    2340             :   // Smi-encoding of the mask is performed implicitly!
    2341         280 :   TNode<BoolT> IsSetSmi(SloppyTNode<Smi> smi, int untagged_mask) {
    2342         280 :     intptr_t mask_word = bit_cast<intptr_t>(Smi::FromInt(untagged_mask));
    2343             :     return WordNotEqual(
    2344         840 :         WordAnd(BitcastTaggedToWord(smi), IntPtrConstant(mask_word)),
    2345         840 :         IntPtrConstant(0));
    2346             :   }
    2347             : 
    2348             :   // Returns true if all of the |T|'s bits in given |word32| are clear.
    2349             :   template <typename T>
    2350             :   TNode<BoolT> IsClearWord32(SloppyTNode<Word32T> word32) {
    2351         504 :     return IsClearWord32(word32, T::kMask);
    2352             :   }
    2353             : 
    2354             :   // Returns true if all of the mask's bits in given |word32| are clear.
    2355        3650 :   TNode<BoolT> IsClearWord32(SloppyTNode<Word32T> word32, uint32_t mask) {
    2356        7300 :     return Word32Equal(Word32And(word32, Int32Constant(mask)),
    2357       14600 :                        Int32Constant(0));
    2358             :   }
    2359             : 
    2360             :   // Returns true if all of the |T|'s bits in given |word| are clear.
    2361             :   template <typename T>
    2362             :   TNode<BoolT> IsClearWord(SloppyTNode<WordT> word) {
    2363             :     return IsClearWord(word, T::kMask);
    2364             :   }
    2365             : 
    2366             :   // Returns true if all of the mask's bits in given |word| are clear.
    2367         616 :   TNode<BoolT> IsClearWord(SloppyTNode<WordT> word, uint32_t mask) {
    2368        2464 :     return WordEqual(WordAnd(word, IntPtrConstant(mask)), IntPtrConstant(0));
    2369             :   }
    2370             : 
    2371             :   void SetCounter(StatsCounter* counter, int value);
    2372             :   void IncrementCounter(StatsCounter* counter, int delta);
    2373             :   void DecrementCounter(StatsCounter* counter, int delta);
    2374             : 
    2375             :   void Increment(Variable* variable, int value = 1,
    2376             :                  ParameterMode mode = INTPTR_PARAMETERS);
    2377             :   void Decrement(Variable* variable, int value = 1,
    2378             :                  ParameterMode mode = INTPTR_PARAMETERS) {
    2379          56 :     Increment(variable, -value, mode);
    2380             :   }
    2381             : 
    2382             :   // Generates "if (false) goto label" code. Useful for marking a label as
    2383             :   // "live" to avoid assertion failures during graph building. In the resulting
    2384             :   // code this check will be eliminated.
    2385             :   void Use(Label* label);
    2386             : 
    2387             :   // Various building blocks for stubs doing property lookups.
    2388             : 
    2389             :   // |if_notinternalized| is optional; |if_bailout| will be used by default.
    2390             :   void TryToName(Node* key, Label* if_keyisindex, Variable* var_index,
    2391             :                  Label* if_keyisunique, Variable* var_unique, Label* if_bailout,
    2392             :                  Label* if_notinternalized = nullptr);
    2393             : 
    2394             :   // Performs a hash computation and string table lookup for the given string,
    2395             :   // and jumps to:
    2396             :   // - |if_index| if the string is an array index like "123"; |var_index|
    2397             :   //              will contain the intptr representation of that index.
    2398             :   // - |if_internalized| if the string exists in the string table; the
    2399             :   //                     internalized version will be in |var_internalized|.
    2400             :   // - |if_not_internalized| if the string is not in the string table (but
    2401             :   //                         does not add it).
    2402             :   // - |if_bailout| for unsupported cases (e.g. uncachable array index).
    2403             :   void TryInternalizeString(Node* string, Label* if_index, Variable* var_index,
    2404             :                             Label* if_internalized, Variable* var_internalized,
    2405             :                             Label* if_not_internalized, Label* if_bailout);
    2406             : 
    2407             :   // Calculates array index for given dictionary entry and entry field.
    2408             :   // See Dictionary::EntryToIndex().
    2409             :   template <typename Dictionary>
    2410             :   TNode<IntPtrT> EntryToIndex(TNode<IntPtrT> entry, int field_index);
    2411             :   template <typename Dictionary>
    2412             :   TNode<IntPtrT> EntryToIndex(TNode<IntPtrT> entry) {
    2413       32151 :     return EntryToIndex<Dictionary>(entry, Dictionary::kEntryKeyIndex);
    2414             :   }
    2415             : 
    2416             :   // Loads the details for the entry with the given key_index.
    2417             :   // Returns an untagged int32.
    2418             :   template <class ContainerType>
    2419        2861 :   TNode<Uint32T> LoadDetailsByKeyIndex(Node* container, Node* key_index) {
    2420             :     static_assert(!std::is_same<ContainerType, DescriptorArray>::value,
    2421             :                   "Use the non-templatized version for DescriptorArray");
    2422             :     const int kKeyToDetailsOffset =
    2423             :         (ContainerType::kEntryDetailsIndex - ContainerType::kEntryKeyIndex) *
    2424             :         kTaggedSize;
    2425             :     return Unsigned(LoadAndUntagToWord32FixedArrayElement(
    2426        4541 :         CAST(container), key_index, kKeyToDetailsOffset));
    2427             :   }
    2428             : 
    2429             :   // Loads the value for the entry with the given key_index.
    2430             :   // Returns a tagged value.
    2431             :   template <class ContainerType>
    2432        2805 :   TNode<Object> LoadValueByKeyIndex(Node* container, Node* key_index) {
    2433             :     static_assert(!std::is_same<ContainerType, DescriptorArray>::value,
    2434             :                   "Use the non-templatized version for DescriptorArray");
    2435             :     const int kKeyToValueOffset =
    2436             :         (ContainerType::kEntryValueIndex - ContainerType::kEntryKeyIndex) *
    2437             :         kTaggedSize;
    2438        3477 :     return LoadFixedArrayElement(CAST(container), key_index, kKeyToValueOffset);
    2439             :   }
    2440             : 
    2441             :   // Stores the details for the entry with the given key_index.
    2442             :   // |details| must be a Smi.
    2443             :   template <class ContainerType>
    2444             :   void StoreDetailsByKeyIndex(TNode<ContainerType> container,
    2445             :                               TNode<IntPtrT> key_index, TNode<Smi> details) {
    2446             :     const int kKeyToDetailsOffset =
    2447             :         (ContainerType::kEntryDetailsIndex - ContainerType::kEntryKeyIndex) *
    2448             :         kTaggedSize;
    2449          56 :     StoreFixedArrayElement(container, key_index, details, SKIP_WRITE_BARRIER,
    2450             :                            kKeyToDetailsOffset);
    2451             :   }
    2452             : 
    2453             :   // Stores the value for the entry with the given key_index.
    2454             :   template <class ContainerType>
    2455             :   void StoreValueByKeyIndex(
    2456             :       TNode<ContainerType> container, TNode<IntPtrT> key_index,
    2457             :       TNode<Object> value,
    2458             :       WriteBarrierMode write_barrier = UPDATE_WRITE_BARRIER) {
    2459             :     const int kKeyToValueOffset =
    2460             :         (ContainerType::kEntryValueIndex - ContainerType::kEntryKeyIndex) *
    2461             :         kTaggedSize;
    2462         616 :     StoreFixedArrayElement(container, key_index, value, write_barrier,
    2463             :                            kKeyToValueOffset);
    2464             :   }
    2465             : 
    2466             :   // Calculate a valid size for the a hash table.
    2467             :   TNode<IntPtrT> HashTableComputeCapacity(TNode<IntPtrT> at_least_space_for);
    2468             : 
    2469             :   template <class Dictionary>
    2470        1176 :   TNode<Smi> GetNumberOfElements(TNode<Dictionary> dictionary) {
    2471        1176 :     return CAST(
    2472             :         LoadFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex));
    2473             :   }
    2474             : 
    2475             :   TNode<Smi> GetNumberDictionaryNumberOfElements(
    2476             :       TNode<NumberDictionary> dictionary) {
    2477         112 :     return GetNumberOfElements<NumberDictionary>(dictionary);
    2478             :   }
    2479             : 
    2480             :   template <class Dictionary>
    2481             :   void SetNumberOfElements(TNode<Dictionary> dictionary,
    2482             :                            TNode<Smi> num_elements_smi) {
    2483         840 :     StoreFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex,
    2484             :                            num_elements_smi, SKIP_WRITE_BARRIER);
    2485             :   }
    2486             : 
    2487             :   template <class Dictionary>
    2488         840 :   TNode<Smi> GetNumberOfDeletedElements(TNode<Dictionary> dictionary) {
    2489         840 :     return CAST(LoadFixedArrayElement(
    2490             :         dictionary, Dictionary::kNumberOfDeletedElementsIndex));
    2491             :   }
    2492             : 
    2493             :   template <class Dictionary>
    2494             :   void SetNumberOfDeletedElements(TNode<Dictionary> dictionary,
    2495             :                                   TNode<Smi> num_deleted_smi) {
    2496          56 :     StoreFixedArrayElement(dictionary,
    2497             :                            Dictionary::kNumberOfDeletedElementsIndex,
    2498             :                            num_deleted_smi, SKIP_WRITE_BARRIER);
    2499             :   }
    2500             : 
    2501             :   template <class Dictionary>
    2502        8776 :   TNode<Smi> GetCapacity(TNode<Dictionary> dictionary) {
    2503        8776 :     return CAST(LoadFixedArrayElement(dictionary, Dictionary::kCapacityIndex));
    2504             :   }
    2505             : 
    2506             :   template <class Dictionary>
    2507         784 :   TNode<Smi> GetNextEnumerationIndex(TNode<Dictionary> dictionary) {
    2508         784 :     return CAST(LoadFixedArrayElement(dictionary,
    2509             :                                       Dictionary::kNextEnumerationIndexIndex));
    2510             :   }
    2511             : 
    2512             :   template <class Dictionary>
    2513             :   void SetNextEnumerationIndex(TNode<Dictionary> dictionary,
    2514             :                                TNode<Smi> next_enum_index_smi) {
    2515         784 :     StoreFixedArrayElement(dictionary, Dictionary::kNextEnumerationIndexIndex,
    2516             :                            next_enum_index_smi, SKIP_WRITE_BARRIER);
    2517             :   }
    2518             : 
    2519             :   // Looks up an entry in a NameDictionaryBase successor. If the entry is found
    2520             :   // control goes to {if_found} and {var_name_index} contains an index of the
    2521             :   // key field of the entry found. If the key is not found control goes to
    2522             :   // {if_not_found}.
    2523             :   static const int kInlinedDictionaryProbes = 4;
    2524             :   enum LookupMode { kFindExisting, kFindInsertionIndex };
    2525             : 
    2526             :   template <typename Dictionary>
    2527             :   TNode<HeapObject> LoadName(TNode<HeapObject> key);
    2528             : 
    2529             :   template <typename Dictionary>
    2530             :   void NameDictionaryLookup(TNode<Dictionary> dictionary,
    2531             :                             TNode<Name> unique_name, Label* if_found,
    2532             :                             TVariable<IntPtrT>* var_name_index,
    2533             :                             Label* if_not_found,
    2534             :                             int inlined_probes = kInlinedDictionaryProbes,
    2535             :                             LookupMode mode = kFindExisting);
    2536             : 
    2537             :   Node* ComputeUnseededHash(Node* key);
    2538             :   Node* ComputeSeededHash(Node* key);
    2539             : 
    2540             :   void NumberDictionaryLookup(TNode<NumberDictionary> dictionary,
    2541             :                               TNode<IntPtrT> intptr_index, Label* if_found,
    2542             :                               TVariable<IntPtrT>* var_entry,
    2543             :                               Label* if_not_found);
    2544             : 
    2545             :   TNode<Object> BasicLoadNumberDictionaryElement(
    2546             :       TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index,
    2547             :       Label* not_data, Label* if_hole);
    2548             :   void BasicStoreNumberDictionaryElement(TNode<NumberDictionary> dictionary,
    2549             :                                          TNode<IntPtrT> intptr_index,
    2550             :                                          TNode<Object> value, Label* not_data,
    2551             :                                          Label* if_hole, Label* read_only);
    2552             : 
    2553             :   template <class Dictionary>
    2554             :   void FindInsertionEntry(TNode<Dictionary> dictionary, TNode<Name> key,
    2555             :                           TVariable<IntPtrT>* var_key_index);
    2556             : 
    2557             :   template <class Dictionary>
    2558             :   void InsertEntry(TNode<Dictionary> dictionary, TNode<Name> key,
    2559             :                    TNode<Object> value, TNode<IntPtrT> index,
    2560             :                    TNode<Smi> enum_index);
    2561             : 
    2562             :   template <class Dictionary>
    2563             :   void Add(TNode<Dictionary> dictionary, TNode<Name> key, TNode<Object> value,
    2564             :            Label* bailout);
    2565             : 
    2566             :   // Tries to check if {object} has own {unique_name} property.
    2567             :   void TryHasOwnProperty(Node* object, Node* map, Node* instance_type,
    2568             :                          Node* unique_name, Label* if_found,
    2569             :                          Label* if_not_found, Label* if_bailout);
    2570             : 
    2571             :   // Operating mode for TryGetOwnProperty and CallGetterIfAccessor
    2572             :   // kReturnAccessorPair is used when we're only getting the property descriptor
    2573             :   enum GetOwnPropertyMode { kCallJSGetter, kReturnAccessorPair };
    2574             :   // Tries to get {object}'s own {unique_name} property value. If the property
    2575             :   // is an accessor then it also calls a getter. If the property is a double
    2576             :   // field it re-wraps value in an immutable heap number.
    2577             :   void TryGetOwnProperty(Node* context, Node* receiver, Node* object, Node* map,
    2578             :                          Node* instance_type, Node* unique_name,
    2579             :                          Label* if_found, Variable* var_value,
    2580             :                          Label* if_not_found, Label* if_bailout);
    2581             :   void TryGetOwnProperty(Node* context, Node* receiver, Node* object, Node* map,
    2582             :                          Node* instance_type, Node* unique_name,
    2583             :                          Label* if_found, Variable* var_value,
    2584             :                          Variable* var_details, Variable* var_raw_value,
    2585             :                          Label* if_not_found, Label* if_bailout,
    2586             :                          GetOwnPropertyMode mode);
    2587             : 
    2588        8624 :   TNode<Object> GetProperty(SloppyTNode<Context> context,
    2589             :                             SloppyTNode<Object> receiver, Handle<Name> name) {
    2590       17248 :     return GetProperty(context, receiver, HeapConstant(name));
    2591             :   }
    2592             : 
    2593             :   TNode<Object> GetProperty(SloppyTNode<Context> context,
    2594             :                             SloppyTNode<Object> receiver,
    2595             :                             SloppyTNode<Object> name) {
    2596       11984 :     return CallBuiltin(Builtins::kGetProperty, context, receiver, name);
    2597             :   }
    2598             : 
    2599             :   TNode<Object> SetPropertyStrict(TNode<Context> context,
    2600             :                                   TNode<Object> receiver, TNode<Object> key,
    2601             :                                   TNode<Object> value) {
    2602        1680 :     return CallBuiltin(Builtins::kSetProperty, context, receiver, key, value);
    2603             :   }
    2604             : 
    2605             :   TNode<Object> SetPropertyInLiteral(TNode<Context> context,
    2606             :                                      TNode<JSObject> receiver,
    2607             :                                      TNode<Object> key, TNode<Object> value) {
    2608             :     return CallBuiltin(Builtins::kSetPropertyInLiteral, context, receiver, key,
    2609          56 :                        value);
    2610             :   }
    2611             : 
    2612             :   Node* GetMethod(Node* context, Node* object, Handle<Name> name,
    2613             :                   Label* if_null_or_undefined);
    2614             : 
    2615             :   template <class... TArgs>
    2616       78155 :   TNode<Object> CallBuiltin(Builtins::Name id, SloppyTNode<Object> context,
    2617             :                             TArgs... args) {
    2618             :     return CallStub<Object>(Builtins::CallableFor(isolate(), id), context,
    2619       78155 :                             args...);
    2620             :   }
    2621             : 
    2622             :   template <class... TArgs>
    2623        2912 :   void TailCallBuiltin(Builtins::Name id, SloppyTNode<Object> context,
    2624             :                        TArgs... args) {
    2625        2912 :     return TailCallStub(Builtins::CallableFor(isolate(), id), context, args...);
    2626             :   }
    2627             : 
    2628             :   void LoadPropertyFromFastObject(Node* object, Node* map,
    2629             :                                   TNode<DescriptorArray> descriptors,
    2630             :                                   Node* name_index, Variable* var_details,
    2631             :                                   Variable* var_value);
    2632             : 
    2633             :   void LoadPropertyFromFastObject(Node* object, Node* map,
    2634             :                                   TNode<DescriptorArray> descriptors,
    2635             :                                   Node* name_index, Node* details,
    2636             :                                   Variable* var_value);
    2637             : 
    2638             :   void LoadPropertyFromNameDictionary(Node* dictionary, Node* entry,
    2639             :                                       Variable* var_details,
    2640             :                                       Variable* var_value);
    2641             : 
    2642             :   void LoadPropertyFromGlobalDictionary(Node* dictionary, Node* entry,
    2643             :                                         Variable* var_details,
    2644             :                                         Variable* var_value, Label* if_deleted);
    2645             : 
    2646             :   // Generic property lookup generator. If the {object} is fast and
    2647             :   // {unique_name} property is found then the control goes to {if_found_fast}
    2648             :   // label and {var_meta_storage} and {var_name_index} will contain
    2649             :   // DescriptorArray and an index of the descriptor's name respectively.
    2650             :   // If the {object} is slow or global then the control goes to {if_found_dict}
    2651             :   // or {if_found_global} and the {var_meta_storage} and {var_name_index} will
    2652             :   // contain a dictionary and an index of the key field of the found entry.
    2653             :   // If property is not found or given lookup is not supported then
    2654             :   // the control goes to {if_not_found} or {if_bailout} respectively.
    2655             :   //
    2656             :   // Note: this code does not check if the global dictionary points to deleted
    2657             :   // entry! This has to be done by the caller.
    2658             :   void TryLookupProperty(SloppyTNode<JSObject> object, SloppyTNode<Map> map,
    2659             :                          SloppyTNode<Int32T> instance_type,
    2660             :                          SloppyTNode<Name> unique_name, Label* if_found_fast,
    2661             :                          Label* if_found_dict, Label* if_found_global,
    2662             :                          TVariable<HeapObject>* var_meta_storage,
    2663             :                          TVariable<IntPtrT>* var_name_index,
    2664             :                          Label* if_not_found, Label* if_bailout);
    2665             : 
    2666             :   // This is a building block for TryLookupProperty() above. Supports only
    2667             :   // non-special fast and dictionary objects.
    2668             :   void TryLookupPropertyInSimpleObject(TNode<JSObject> object, TNode<Map> map,
    2669             :                                        TNode<Name> unique_name,
    2670             :                                        Label* if_found_fast,
    2671             :                                        Label* if_found_dict,
    2672             :                                        TVariable<HeapObject>* var_meta_storage,
    2673             :                                        TVariable<IntPtrT>* var_name_index,
    2674             :                                        Label* if_not_found);
    2675             : 
    2676             :   // This method jumps to if_found if the element is known to exist. To
    2677             :   // if_absent if it's known to not exist. To if_not_found if the prototype
    2678             :   // chain needs to be checked. And if_bailout if the lookup is unsupported.
    2679             :   void TryLookupElement(Node* object, Node* map,
    2680             :                         SloppyTNode<Int32T> instance_type,
    2681             :                         SloppyTNode<IntPtrT> intptr_index, Label* if_found,
    2682             :                         Label* if_absent, Label* if_not_found,
    2683             :                         Label* if_bailout);
    2684             : 
    2685             :   // This is a type of a lookup in holder generator function. In case of a
    2686             :   // property lookup the {key} is guaranteed to be an unique name and in case of
    2687             :   // element lookup the key is an Int32 index.
    2688             :   typedef std::function<void(Node* receiver, Node* holder, Node* map,
    2689             :                              Node* instance_type, Node* key, Label* next_holder,
    2690             :                              Label* if_bailout)>
    2691             :       LookupInHolder;
    2692             : 
    2693             :   // For integer indexed exotic cases, check if the given string cannot be a
    2694             :   // special index. If we are not sure that the given string is not a special
    2695             :   // index with a simple check, return False. Note that "False" return value
    2696             :   // does not mean that the name_string is a special index in the current
    2697             :   // implementation.
    2698             :   void BranchIfMaybeSpecialIndex(TNode<String> name_string,
    2699             :                                  Label* if_maybe_special_index,
    2700             :                                  Label* if_not_special_index);
    2701             : 
    2702             :   // Generic property prototype chain lookup generator.
    2703             :   // For properties it generates lookup using given {lookup_property_in_holder}
    2704             :   // and for elements it uses {lookup_element_in_holder}.
    2705             :   // Upon reaching the end of prototype chain the control goes to {if_end}.
    2706             :   // If it can't handle the case {receiver}/{key} case then the control goes
    2707             :   // to {if_bailout}.
    2708             :   // If {if_proxy} is nullptr, proxies go to if_bailout.
    2709             :   void TryPrototypeChainLookup(Node* receiver, Node* key,
    2710             :                                const LookupInHolder& lookup_property_in_holder,
    2711             :                                const LookupInHolder& lookup_element_in_holder,
    2712             :                                Label* if_end, Label* if_bailout,
    2713             :                                Label* if_proxy = nullptr);
    2714             : 
    2715             :   // Instanceof helpers.
    2716             :   // Returns true if {object} has {prototype} somewhere in it's prototype
    2717             :   // chain, otherwise false is returned. Might cause arbitrary side effects
    2718             :   // due to [[GetPrototypeOf]] invocations.
    2719             :   Node* HasInPrototypeChain(Node* context, Node* object, Node* prototype);
    2720             :   // ES6 section 7.3.19 OrdinaryHasInstance (C, O)
    2721             :   Node* OrdinaryHasInstance(Node* context, Node* callable, Node* object);
    2722             : 
    2723             :   // Load type feedback vector from the stub caller's frame.
    2724             :   TNode<FeedbackVector> LoadFeedbackVectorForStub();
    2725             : 
    2726             :   // Load type feedback vector for the given closure.
    2727             :   TNode<FeedbackVector> LoadFeedbackVector(SloppyTNode<JSFunction> closure,
    2728             :                                            Label* if_undefined = nullptr);
    2729             : 
    2730             :   // Load the object from feedback vector cell for the given closure.
    2731             :   // The returned object could be undefined if the closure does not have
    2732             :   // a feedback vector associated with it.
    2733             :   TNode<Object> LoadFeedbackVectorUnchecked(SloppyTNode<JSFunction> closure);
    2734             : 
    2735             :   // Update the type feedback vector.
    2736             :   void UpdateFeedback(Node* feedback, Node* feedback_vector, Node* slot_id);
    2737             : 
    2738             :   // Returns the stricter of the Context::ScopeInfo::LanguageMode and
    2739             :   // the language mode on the SFI.
    2740             :   Node* GetLanguageMode(TNode<SharedFunctionInfo> sfi, Node* context);
    2741             :   Node* GetLanguageMode(TNode<JSFunction> closure, Node* context);
    2742             :   Node* GetLanguageMode(TNode<FeedbackVector> vector, Node* context);
    2743             : 
    2744             :   // Report that there was a feedback update, performing any tasks that should
    2745             :   // be done after a feedback update.
    2746             :   void ReportFeedbackUpdate(SloppyTNode<FeedbackVector> feedback_vector,
    2747             :                             SloppyTNode<IntPtrT> slot_id, const char* reason);
    2748             : 
    2749             :   // Combine the new feedback with the existing_feedback. Do nothing if
    2750             :   // existing_feedback is nullptr.
    2751             :   void CombineFeedback(Variable* existing_feedback, int feedback);
    2752             :   void CombineFeedback(Variable* existing_feedback, Node* feedback);
    2753             : 
    2754             :   // Overwrite the existing feedback with new_feedback. Do nothing if
    2755             :   // existing_feedback is nullptr.
    2756             :   void OverwriteFeedback(Variable* existing_feedback, int new_feedback);
    2757             : 
    2758             :   // Check if a property name might require protector invalidation when it is
    2759             :   // used for a property store or deletion.
    2760             :   void CheckForAssociatedProtector(Node* name, Label* if_protector);
    2761             : 
    2762             :   TNode<Map> LoadReceiverMap(SloppyTNode<Object> receiver);
    2763             : 
    2764             :   // Emits keyed sloppy arguments load. Returns either the loaded value.
    2765             :   Node* LoadKeyedSloppyArguments(Node* receiver, Node* key, Label* bailout) {
    2766          56 :     return EmitKeyedSloppyArguments(receiver, key, nullptr, bailout);
    2767             :   }
    2768             : 
    2769             :   // Emits keyed sloppy arguments store.
    2770             :   void StoreKeyedSloppyArguments(Node* receiver, Node* key, Node* value,
    2771             :                                  Label* bailout) {
    2772             :     DCHECK_NOT_NULL(value);
    2773         224 :     EmitKeyedSloppyArguments(receiver, key, value, bailout);
    2774             :   }
    2775             : 
    2776             :   // Loads script context from the script context table.
    2777             :   TNode<Context> LoadScriptContext(TNode<Context> context,
    2778             :                                    TNode<IntPtrT> context_index);
    2779             : 
    2780             :   Node* Int32ToUint8Clamped(Node* int32_value);
    2781             :   Node* Float64ToUint8Clamped(Node* float64_value);
    2782             : 
    2783             :   Node* PrepareValueForWriteToTypedArray(TNode<Object> input,
    2784             :                                          ElementsKind elements_kind,
    2785             :                                          TNode<Context> context);
    2786             : 
    2787             :   // Store value to an elements array with given elements kind.
    2788             :   void StoreElement(Node* elements, ElementsKind kind, Node* index, Node* value,
    2789             :                     ParameterMode mode);
    2790             : 
    2791             :   void EmitBigTypedArrayElementStore(TNode<JSTypedArray> object,
    2792             :                                      TNode<FixedTypedArrayBase> elements,
    2793             :                                      TNode<IntPtrT> intptr_key,
    2794             :                                      TNode<Object> value,
    2795             :                                      TNode<Context> context,
    2796             :                                      Label* opt_if_detached);
    2797             :   // Part of the above, refactored out to reuse in another place.
    2798             :   void EmitBigTypedArrayElementStore(TNode<FixedTypedArrayBase> elements,
    2799             :                                      TNode<RawPtrT> backing_store,
    2800             :                                      TNode<IntPtrT> offset,
    2801             :                                      TNode<BigInt> bigint_value);
    2802             :   // Implements the BigInt part of
    2803             :   // https://tc39.github.io/proposal-bigint/#sec-numbertorawbytes,
    2804             :   // including truncation to 64 bits (i.e. modulo 2^64).
    2805             :   // {var_high} is only used on 32-bit platforms.
    2806             :   void BigIntToRawBytes(TNode<BigInt> bigint, TVariable<UintPtrT>* var_low,
    2807             :                         TVariable<UintPtrT>* var_high);
    2808             : 
    2809             :   void EmitElementStore(Node* object, Node* key, Node* value,
    2810             :                         ElementsKind elements_kind,
    2811             :                         KeyedAccessStoreMode store_mode, Label* bailout,
    2812             :                         Node* context);
    2813             : 
    2814             :   Node* CheckForCapacityGrow(Node* object, Node* elements, ElementsKind kind,
    2815             :                              Node* length, Node* key, ParameterMode mode,
    2816             :                              Label* bailout);
    2817             : 
    2818             :   Node* CopyElementsOnWrite(Node* object, Node* elements, ElementsKind kind,
    2819             :                             Node* length, ParameterMode mode, Label* bailout);
    2820             : 
    2821             :   void TransitionElementsKind(Node* object, Node* map, ElementsKind from_kind,
    2822             :                               ElementsKind to_kind, Label* bailout);
    2823             : 
    2824             :   void TrapAllocationMemento(Node* object, Label* memento_found);
    2825             : 
    2826             :   TNode<IntPtrT> PageFromAddress(TNode<IntPtrT> address);
    2827             : 
    2828             :   // Store a weak in-place reference into the FeedbackVector.
    2829             :   TNode<MaybeObject> StoreWeakReferenceInFeedbackVector(
    2830             :       SloppyTNode<FeedbackVector> feedback_vector, Node* slot,
    2831             :       SloppyTNode<HeapObject> value, int additional_offset = 0,
    2832             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
    2833             : 
    2834             :   // Create a new AllocationSite and install it into a feedback vector.
    2835             :   TNode<AllocationSite> CreateAllocationSiteInFeedbackVector(
    2836             :       SloppyTNode<FeedbackVector> feedback_vector, TNode<Smi> slot);
    2837             : 
    2838             :   // TODO(ishell, cbruni): Change to HasBoilerplate.
    2839             :   TNode<BoolT> NotHasBoilerplate(TNode<Object> maybe_literal_site);
    2840             :   TNode<Smi> LoadTransitionInfo(TNode<AllocationSite> allocation_site);
    2841             :   TNode<JSObject> LoadBoilerplate(TNode<AllocationSite> allocation_site);
    2842             :   TNode<Int32T> LoadElementsKind(TNode<AllocationSite> allocation_site);
    2843             : 
    2844             :   enum class IndexAdvanceMode { kPre, kPost };
    2845             : 
    2846             :   typedef std::function<void(Node* index)> FastLoopBody;
    2847             : 
    2848             :   Node* BuildFastLoop(const VariableList& var_list, Node* start_index,
    2849             :                       Node* end_index, const FastLoopBody& body, int increment,
    2850             :                       ParameterMode parameter_mode,
    2851             :                       IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre);
    2852             : 
    2853        8893 :   Node* BuildFastLoop(Node* start_index, Node* end_index,
    2854             :                       const FastLoopBody& body, int increment,
    2855             :                       ParameterMode parameter_mode,
    2856             :                       IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre) {
    2857             :     return BuildFastLoop(VariableList(0, zone()), start_index, end_index, body,
    2858       17786 :                          increment, parameter_mode, advance_mode);
    2859             :   }
    2860             : 
    2861             :   enum class ForEachDirection { kForward, kReverse };
    2862             : 
    2863             :   typedef std::function<void(Node* fixed_array, Node* offset)>
    2864             :       FastFixedArrayForEachBody;
    2865             : 
    2866             :   void BuildFastFixedArrayForEach(
    2867             :       const CodeStubAssembler::VariableList& vars, Node* fixed_array,
    2868             :       ElementsKind kind, Node* first_element_inclusive,
    2869             :       Node* last_element_exclusive, const FastFixedArrayForEachBody& body,
    2870             :       ParameterMode mode = INTPTR_PARAMETERS,
    2871             :       ForEachDirection direction = ForEachDirection::kReverse);
    2872             : 
    2873       17815 :   void BuildFastFixedArrayForEach(
    2874             :       Node* fixed_array, ElementsKind kind, Node* first_element_inclusive,
    2875             :       Node* last_element_exclusive, const FastFixedArrayForEachBody& body,
    2876             :       ParameterMode mode = INTPTR_PARAMETERS,
    2877             :       ForEachDirection direction = ForEachDirection::kReverse) {
    2878       17815 :     CodeStubAssembler::VariableList list(0, zone());
    2879             :     BuildFastFixedArrayForEach(list, fixed_array, kind, first_element_inclusive,
    2880       17815 :                                last_element_exclusive, body, mode, direction);
    2881       17815 :   }
    2882             : 
    2883             :   TNode<IntPtrT> GetArrayAllocationSize(Node* element_count, ElementsKind kind,
    2884             :                                         ParameterMode mode, int header_size) {
    2885       17932 :     return ElementOffsetFromIndex(element_count, kind, mode, header_size);
    2886             :   }
    2887             : 
    2888             :   TNode<IntPtrT> GetFixedArrayAllocationSize(Node* element_count,
    2889             :                                              ElementsKind kind,
    2890             :                                              ParameterMode mode) {
    2891             :     return GetArrayAllocationSize(element_count, kind, mode,
    2892             :                                   FixedArray::kHeaderSize);
    2893             :   }
    2894             : 
    2895             :   TNode<IntPtrT> GetPropertyArrayAllocationSize(Node* element_count,
    2896             :                                                 ParameterMode mode) {
    2897             :     return GetArrayAllocationSize(element_count, PACKED_ELEMENTS, mode,
    2898             :                                   PropertyArray::kHeaderSize);
    2899             :   }
    2900             : 
    2901             :   void GotoIfFixedArraySizeDoesntFitInNewSpace(Node* element_count,
    2902             :                                                Label* doesnt_fit, int base_size,
    2903             :                                                ParameterMode mode);
    2904             : 
    2905             :   void InitializeFieldsWithRoot(Node* object, Node* start_offset,
    2906             :                                 Node* end_offset, RootIndex root);
    2907             : 
    2908             :   Node* RelationalComparison(Operation op, Node* left, Node* right,
    2909             :                              Node* context,
    2910             :                              Variable* var_type_feedback = nullptr);
    2911             : 
    2912             :   void BranchIfNumberRelationalComparison(Operation op, Node* left, Node* right,
    2913             :                                           Label* if_true, Label* if_false);
    2914             : 
    2915             :   void BranchIfNumberEqual(TNode<Number> left, TNode<Number> right,
    2916             :                            Label* if_true, Label* if_false) {
    2917             :     BranchIfNumberRelationalComparison(Operation::kEqual, left, right, if_true,
    2918         280 :                                        if_false);
    2919             :   }
    2920             : 
    2921             :   void BranchIfNumberNotEqual(TNode<Number> left, TNode<Number> right,
    2922             :                               Label* if_true, Label* if_false) {
    2923             :     BranchIfNumberEqual(left, right, if_false, if_true);
    2924             :   }
    2925             : 
    2926             :   void BranchIfNumberLessThan(TNode<Number> left, TNode<Number> right,
    2927             :                               Label* if_true, Label* if_false) {
    2928             :     BranchIfNumberRelationalComparison(Operation::kLessThan, left, right,
    2929        2744 :                                        if_true, if_false);
    2930             :   }
    2931             : 
    2932             :   void BranchIfNumberLessThanOrEqual(TNode<Number> left, TNode<Number> right,
    2933             :                                      Label* if_true, Label* if_false) {
    2934             :     BranchIfNumberRelationalComparison(Operation::kLessThanOrEqual, left, right,
    2935             :                                        if_true, if_false);
    2936             :   }
    2937             : 
    2938             :   void BranchIfNumberGreaterThan(TNode<Number> left, TNode<Number> right,
    2939             :                                  Label* if_true, Label* if_false) {
    2940             :     BranchIfNumberRelationalComparison(Operation::kGreaterThan, left, right,
    2941        2128 :                                        if_true, if_false);
    2942             :   }
    2943             : 
    2944             :   void BranchIfNumberGreaterThanOrEqual(TNode<Number> left, TNode<Number> right,
    2945             :                                         Label* if_true, Label* if_false) {
    2946             :     BranchIfNumberRelationalComparison(Operation::kGreaterThanOrEqual, left,
    2947         336 :                                        right, if_true, if_false);
    2948             :   }
    2949             : 
    2950         168 :   void BranchIfAccessorPair(Node* value, Label* if_accessor_pair,
    2951             :                             Label* if_not_accessor_pair) {
    2952         336 :     GotoIf(TaggedIsSmi(value), if_not_accessor_pair);
    2953         336 :     Branch(IsAccessorPair(value), if_accessor_pair, if_not_accessor_pair);
    2954         168 :   }
    2955             : 
    2956             :   void GotoIfNumberGreaterThanOrEqual(Node* left, Node* right, Label* if_false);
    2957             : 
    2958             :   Node* Equal(Node* lhs, Node* rhs, Node* context,
    2959             :               Variable* var_type_feedback = nullptr);
    2960             : 
    2961             :   Node* StrictEqual(Node* lhs, Node* rhs,
    2962             :                     Variable* var_type_feedback = nullptr);
    2963             : 
    2964             :   // ECMA#sec-samevalue
    2965             :   // Similar to StrictEqual except that NaNs are treated as equal and minus zero
    2966             :   // differs from positive zero.
    2967             :   void BranchIfSameValue(Node* lhs, Node* rhs, Label* if_true, Label* if_false);
    2968             : 
    2969             :   enum HasPropertyLookupMode { kHasProperty, kForInHasProperty };
    2970             : 
    2971             :   TNode<Oddball> HasProperty(SloppyTNode<Context> context,
    2972             :                              SloppyTNode<Object> object,
    2973             :                              SloppyTNode<Object> key,
    2974             :                              HasPropertyLookupMode mode);
    2975             : 
    2976             :   // Due to naming conflict with the builtin function namespace.
    2977         112 :   TNode<Oddball> HasProperty_Inline(TNode<Context> context,
    2978             :                                     TNode<JSReceiver> object,
    2979             :                                     TNode<Object> key) {
    2980             :     return HasProperty(context, object, key,
    2981         112 :                        HasPropertyLookupMode::kHasProperty);
    2982             :   }
    2983             : 
    2984             :   Node* Typeof(Node* value);
    2985             : 
    2986             :   TNode<Object> GetSuperConstructor(SloppyTNode<Context> context,
    2987             :                                     SloppyTNode<JSFunction> active_function);
    2988             : 
    2989             :   TNode<JSReceiver> SpeciesConstructor(
    2990             :       SloppyTNode<Context> context, SloppyTNode<Object> object,
    2991             :       SloppyTNode<JSReceiver> default_constructor);
    2992             : 
    2993             :   Node* InstanceOf(Node* object, Node* callable, Node* context);
    2994             : 
    2995             :   // Debug helpers
    2996             :   Node* IsDebugActive();
    2997             : 
    2998             :   TNode<BoolT> IsRuntimeCallStatsEnabled();
    2999             : 
    3000             :   // JSArrayBuffer helpers
    3001             :   TNode<Uint32T> LoadJSArrayBufferBitField(TNode<JSArrayBuffer> array_buffer);
    3002             :   TNode<RawPtrT> LoadJSArrayBufferBackingStore(
    3003             :       TNode<JSArrayBuffer> array_buffer);
    3004             :   Node* IsDetachedBuffer(Node* buffer);
    3005             :   void ThrowIfArrayBufferIsDetached(SloppyTNode<Context> context,
    3006             :                                     TNode<JSArrayBuffer> array_buffer,
    3007             :                                     const char* method_name);
    3008             : 
    3009             :   // JSArrayBufferView helpers
    3010             :   TNode<JSArrayBuffer> LoadJSArrayBufferViewBuffer(
    3011             :       TNode<JSArrayBufferView> array_buffer_view);
    3012             :   TNode<UintPtrT> LoadJSArrayBufferViewByteLength(
    3013             :       TNode<JSArrayBufferView> array_buffer_view);
    3014             :   TNode<UintPtrT> LoadJSArrayBufferViewByteOffset(
    3015             :       TNode<JSArrayBufferView> array_buffer_view);
    3016             :   void ThrowIfArrayBufferViewBufferIsDetached(
    3017             :       SloppyTNode<Context> context, TNode<JSArrayBufferView> array_buffer_view,
    3018             :       const char* method_name);
    3019             : 
    3020             :   // JSTypedArray helpers
    3021             :   TNode<Smi> LoadJSTypedArrayLength(TNode<JSTypedArray> typed_array);
    3022             : 
    3023             :   TNode<IntPtrT> ElementOffsetFromIndex(Node* index, ElementsKind kind,
    3024             :                                         ParameterMode mode, int base_size = 0);
    3025             : 
    3026             :   // Check that a field offset is within the bounds of the an object.
    3027             :   TNode<BoolT> IsOffsetInBounds(SloppyTNode<IntPtrT> offset,
    3028             :                                 SloppyTNode<IntPtrT> length, int header_size,
    3029             :                                 ElementsKind kind = HOLEY_ELEMENTS);
    3030             : 
    3031             :   // Load a builtin's code from the builtin array in the isolate.
    3032             :   TNode<Code> LoadBuiltin(TNode<Smi> builtin_id);
    3033             : 
    3034             :   // Figure out the SFI's code object using its data field.
    3035             :   // If |if_compile_lazy| is provided then the execution will go to the given
    3036             :   // label in case of an CompileLazy code object.
    3037             :   TNode<Code> GetSharedFunctionInfoCode(
    3038             :       SloppyTNode<SharedFunctionInfo> shared_info,
    3039             :       Label* if_compile_lazy = nullptr);
    3040             : 
    3041             :   Node* AllocateFunctionWithMapAndContext(Node* map, Node* shared_info,
    3042             :                                           Node* context);
    3043             : 
    3044             :   // Promise helpers
    3045             :   Node* IsPromiseHookEnabled();
    3046             :   Node* HasAsyncEventDelegate();
    3047             :   Node* IsPromiseHookEnabledOrHasAsyncEventDelegate();
    3048             :   Node* IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate();
    3049             : 
    3050             :   // Helpers for StackFrame markers.
    3051             :   Node* MarkerIsFrameType(Node* marker_or_function,
    3052             :                           StackFrame::Type frame_type);
    3053             :   Node* MarkerIsNotFrameType(Node* marker_or_function,
    3054             :                              StackFrame::Type frame_type);
    3055             : 
    3056             :   // for..in helpers
    3057             :   void CheckPrototypeEnumCache(Node* receiver, Node* receiver_map,
    3058             :                                Label* if_fast, Label* if_slow);
    3059             :   Node* CheckEnumCache(Node* receiver, Label* if_empty, Label* if_runtime);
    3060             : 
    3061             :   TNode<IntPtrT> GetArgumentsLength(CodeStubArguments* args);
    3062             :   TNode<Object> GetArgumentValue(CodeStubArguments* args, TNode<IntPtrT> index);
    3063             : 
    3064             :   // Support for printf-style debugging
    3065             :   void Print(const char* s);
    3066             :   void Print(const char* prefix, Node* tagged_value);
    3067             :   inline void Print(SloppyTNode<Object> tagged_value) {
    3068             :     return Print(nullptr, tagged_value);
    3069             :   }
    3070             :   inline void Print(TNode<MaybeObject> tagged_value) {
    3071             :     return Print(nullptr, tagged_value);
    3072             :   }
    3073             : 
    3074             :   template <class... TArgs>
    3075         504 :   Node* MakeTypeError(MessageTemplate message, Node* context, TArgs... args) {
    3076             :     STATIC_ASSERT(sizeof...(TArgs) <= 3);
    3077             :     Node* const make_type_error = LoadContextElement(
    3078        1512 :         LoadNativeContext(context), Context::MAKE_TYPE_ERROR_INDEX);
    3079             :     return CallJS(CodeFactory::Call(isolate()), context, make_type_error,
    3080        1512 :                   UndefinedConstant(), SmiConstant(message), args...);
    3081             :   }
    3082             : 
    3083         112 :   void Abort(AbortReason reason) {
    3084         336 :     CallRuntime(Runtime::kAbort, NoContextConstant(), SmiConstant(reason));
    3085         112 :     Unreachable();
    3086         112 :   }
    3087             : 
    3088           5 :   bool ConstexprBoolNot(bool value) { return !value; }
    3089             : 
    3090             :   bool ConstexprInt31Equal(int31_t a, int31_t b) { return a == b; }
    3091             :   uint32_t ConstexprUint32Add(uint32_t a, uint32_t b) { return a + b; }
    3092             : 
    3093             :   void PerformStackCheck(TNode<Context> context);
    3094             : 
    3095             :   void SetPropertyLength(TNode<Context> context, TNode<Object> array,
    3096             :                          TNode<Number> length);
    3097             : 
    3098             :   // Checks that {object_map}'s prototype map is the {initial_prototype_map} and
    3099             :   // makes sure that the field with name at index {descriptor} is still
    3100             :   // constant. If it is not, go to label {if_modified}.
    3101             :   //
    3102             :   // To make the checks robust, the method also asserts that the descriptor has
    3103             :   // the right key, the caller must pass the root index of the key
    3104             :   // in {field_name_root_index}.
    3105             :   //
    3106             :   // This is useful for checking that given function has not been patched
    3107             :   // on the prototype.
    3108             :   void GotoIfInitialPrototypePropertyModified(TNode<Map> object_map,
    3109             :                                               TNode<Map> initial_prototype_map,
    3110             :                                               int descfriptor,
    3111             :                                               RootIndex field_name_root_index,
    3112             :                                               Label* if_modified);
    3113             :   struct DescriptorIndexAndName {
    3114             :     DescriptorIndexAndName() {}
    3115             :     DescriptorIndexAndName(int descriptor_index, RootIndex name_root_index)
    3116             :         : descriptor_index(descriptor_index),
    3117         392 :           name_root_index(name_root_index) {}
    3118             : 
    3119             :     int descriptor_index;
    3120             :     RootIndex name_root_index;
    3121             :   };
    3122             :   void GotoIfInitialPrototypePropertiesModified(
    3123             :       TNode<Map> object_map, TNode<Map> initial_prototype_map,
    3124             :       Vector<DescriptorIndexAndName> properties, Label* if_modified);
    3125             : 
    3126             :   // Implements DescriptorArray::Search().
    3127             :   void DescriptorLookup(SloppyTNode<Name> unique_name,
    3128             :                         SloppyTNode<DescriptorArray> descriptors,
    3129             :                         SloppyTNode<Uint32T> bitfield3, Label* if_found,
    3130             :                         TVariable<IntPtrT>* var_name_index,
    3131             :                         Label* if_not_found);
    3132             : 
    3133             :   // Implements TransitionArray::SearchName() - searches for first transition
    3134             :   // entry with given name (note that there could be multiple entries with
    3135             :   // the same name).
    3136             :   void TransitionLookup(SloppyTNode<Name> unique_name,
    3137             :                         SloppyTNode<TransitionArray> transitions,
    3138             :                         Label* if_found, TVariable<IntPtrT>* var_name_index,
    3139             :                         Label* if_not_found);
    3140             : 
    3141             :   // Implements generic search procedure like i::Search<Array>().
    3142             :   template <typename Array>
    3143             :   void Lookup(TNode<Name> unique_name, TNode<Array> array,
    3144             :               TNode<Uint32T> number_of_valid_entries, Label* if_found,
    3145             :               TVariable<IntPtrT>* var_name_index, Label* if_not_found);
    3146             : 
    3147             :   // Implements generic linear search procedure like i::LinearSearch<Array>().
    3148             :   template <typename Array>
    3149             :   void LookupLinear(TNode<Name> unique_name, TNode<Array> array,
    3150             :                     TNode<Uint32T> number_of_valid_entries, Label* if_found,
    3151             :                     TVariable<IntPtrT>* var_name_index, Label* if_not_found);
    3152             : 
    3153             :   // Implements generic binary search procedure like i::BinarySearch<Array>().
    3154             :   template <typename Array>
    3155             :   void LookupBinary(TNode<Name> unique_name, TNode<Array> array,
    3156             :                     TNode<Uint32T> number_of_valid_entries, Label* if_found,
    3157             :                     TVariable<IntPtrT>* var_name_index, Label* if_not_found);
    3158             : 
    3159             :   // Converts [Descriptor/Transition]Array entry number to a fixed array index.
    3160             :   template <typename Array>
    3161             :   TNode<IntPtrT> EntryIndexToIndex(TNode<Uint32T> entry_index);
    3162             : 
    3163             :   // Implements [Descriptor/Transition]Array::ToKeyIndex.
    3164             :   template <typename Array>
    3165             :   TNode<IntPtrT> ToKeyIndex(TNode<Uint32T> entry_index);
    3166             : 
    3167             :   // Implements [Descriptor/Transition]Array::GetKey.
    3168             :   template <typename Array>
    3169             :   TNode<Name> GetKey(TNode<Array> array, TNode<Uint32T> entry_index);
    3170             : 
    3171             :   // Implements DescriptorArray::GetDetails.
    3172             :   TNode<Uint32T> DescriptorArrayGetDetails(TNode<DescriptorArray> descriptors,
    3173             :                                            TNode<Uint32T> descriptor_number);
    3174             : 
    3175             :   typedef std::function<void(TNode<IntPtrT> descriptor_key_index)>
    3176             :       ForEachDescriptorBodyFunction;
    3177             : 
    3178             :   void DescriptorArrayForEach(VariableList& variable_list,
    3179             :                               TNode<Uint32T> start_descriptor,
    3180             :                               TNode<Uint32T> end_descriptor,
    3181             :                               const ForEachDescriptorBodyFunction& body);
    3182             : 
    3183             :   // Descriptor array accessors based on key_index, which is equal to
    3184             :   // DescriptorArray::ToKeyIndex(descriptor).
    3185             :   TNode<Name> LoadKeyByKeyIndex(TNode<DescriptorArray> container,
    3186             :                                 TNode<IntPtrT> key_index);
    3187             :   TNode<Uint32T> LoadDetailsByKeyIndex(TNode<DescriptorArray> container,
    3188             :                                        TNode<IntPtrT> key_index);
    3189             :   TNode<Object> LoadValueByKeyIndex(TNode<DescriptorArray> container,
    3190             :                                     TNode<IntPtrT> key_index);
    3191             :   TNode<MaybeObject> LoadFieldTypeByKeyIndex(TNode<DescriptorArray> container,
    3192             :                                              TNode<IntPtrT> key_index);
    3193             : 
    3194             :   TNode<IntPtrT> DescriptorEntryToIndex(TNode<IntPtrT> descriptor);
    3195             : 
    3196             :   // Descriptor array accessors based on descriptor.
    3197             :   TNode<Name> LoadKeyByDescriptorEntry(TNode<DescriptorArray> descriptors,
    3198             :                                        TNode<IntPtrT> descriptor);
    3199             :   TNode<Name> LoadKeyByDescriptorEntry(TNode<DescriptorArray> descriptors,
    3200             :                                        int descriptor);
    3201             :   TNode<Uint32T> LoadDetailsByDescriptorEntry(
    3202             :       TNode<DescriptorArray> descriptors, TNode<IntPtrT> descriptor);
    3203             :   TNode<Uint32T> LoadDetailsByDescriptorEntry(
    3204             :       TNode<DescriptorArray> descriptors, int descriptor);
    3205             :   TNode<Object> LoadValueByDescriptorEntry(TNode<DescriptorArray> descriptors,
    3206             :                                            int descriptor);
    3207             :   TNode<MaybeObject> LoadFieldTypeByDescriptorEntry(
    3208             :       TNode<DescriptorArray> descriptors, TNode<IntPtrT> descriptor);
    3209             : 
    3210             :   typedef std::function<void(TNode<Name> key, TNode<Object> value)>
    3211             :       ForEachKeyValueFunction;
    3212             : 
    3213             :   // For each JSObject property (in DescriptorArray order), check if the key is
    3214             :   // enumerable, and if so, load the value from the receiver and evaluate the
    3215             :   // closure.
    3216             :   void ForEachEnumerableOwnProperty(TNode<Context> context, TNode<Map> map,
    3217             :                                     TNode<JSObject> object,
    3218             :                                     const ForEachKeyValueFunction& body,
    3219             :                                     Label* bailout);
    3220             : 
    3221             :   TNode<Object> CallGetterIfAccessor(Node* value, Node* details, Node* context,
    3222             :                                      Node* receiver, Label* if_bailout,
    3223             :                                      GetOwnPropertyMode mode = kCallJSGetter);
    3224             : 
    3225             :   TNode<IntPtrT> TryToIntptr(Node* key, Label* miss);
    3226             : 
    3227             :   void BranchIfPrototypesHaveNoElements(Node* receiver_map,
    3228             :                                         Label* definitely_no_elements,
    3229             :                                         Label* possibly_elements);
    3230             : 
    3231             :   void InitializeFunctionContext(Node* native_context, Node* context,
    3232             :                                  int slots);
    3233             : 
    3234             :   TNode<JSArray> ArrayCreate(TNode<Context> context, TNode<Number> length);
    3235             : 
    3236             :   // Allocate a clone of a mutable primitive, if {object} is a
    3237             :   // MutableHeapNumber.
    3238             :   TNode<Object> CloneIfMutablePrimitive(TNode<Object> object);
    3239             : 
    3240             :  private:
    3241             :   friend class CodeStubArguments;
    3242             : 
    3243             :   void HandleBreakOnNode();
    3244             : 
    3245             :   TNode<HeapObject> AllocateRawDoubleAligned(TNode<IntPtrT> size_in_bytes,
    3246             :                                              AllocationFlags flags,
    3247             :                                              TNode<RawPtrT> top_address,
    3248             :                                              TNode<RawPtrT> limit_address);
    3249             :   TNode<HeapObject> AllocateRawUnaligned(TNode<IntPtrT> size_in_bytes,
    3250             :                                          AllocationFlags flags,
    3251             :                                          TNode<RawPtrT> top_address,
    3252             :                                          TNode<RawPtrT> limit_address);
    3253             :   TNode<HeapObject> AllocateRaw(TNode<IntPtrT> size_in_bytes,
    3254             :                                 AllocationFlags flags,
    3255             :                                 TNode<RawPtrT> top_address,
    3256             :                                 TNode<RawPtrT> limit_address);
    3257             : 
    3258             :   // Allocate and return a JSArray of given total size in bytes with header
    3259             :   // fields initialized.
    3260             :   TNode<JSArray> AllocateUninitializedJSArray(TNode<Map> array_map,
    3261             :                                               TNode<Smi> length,
    3262             :                                               Node* allocation_site,
    3263             :                                               TNode<IntPtrT> size_in_bytes);
    3264             : 
    3265             :   TNode<BoolT> IsValidSmi(TNode<Smi> smi);
    3266             :   Node* SmiShiftBitsConstant();
    3267             : 
    3268             :   // Emits keyed sloppy arguments load if the |value| is nullptr or store
    3269             :   // otherwise. Returns either the loaded value or |value|.
    3270             :   Node* EmitKeyedSloppyArguments(Node* receiver, Node* key, Node* value,
    3271             :                                  Label* bailout);
    3272             : 
    3273             :   TNode<String> AllocateSlicedString(RootIndex map_root_index,
    3274             :                                      TNode<Uint32T> length,
    3275             :                                      TNode<String> parent, TNode<Smi> offset);
    3276             : 
    3277             :   TNode<String> AllocateConsString(RootIndex map_root_index,
    3278             :                                    TNode<Uint32T> length, TNode<String> first,
    3279             :                                    TNode<String> second, AllocationFlags flags);
    3280             : 
    3281             :   // Allocate a MutableHeapNumber without initializing its value.
    3282             :   TNode<MutableHeapNumber> AllocateMutableHeapNumber();
    3283             : 
    3284             :   Node* SelectImpl(TNode<BoolT> condition, const NodeGenerator& true_body,
    3285             :                    const NodeGenerator& false_body, MachineRepresentation rep);
    3286             : 
    3287             :   // Implements [Descriptor/Transition]Array::number_of_entries.
    3288             :   template <typename Array>
    3289             :   TNode<Uint32T> NumberOfEntries(TNode<Array> array);
    3290             : 
    3291             :   // Implements [Descriptor/Transition]Array::GetSortedKeyIndex.
    3292             :   template <typename Array>
    3293             :   TNode<Uint32T> GetSortedKeyIndex(TNode<Array> descriptors,
    3294             :                                    TNode<Uint32T> entry_index);
    3295             : 
    3296             :   TNode<Smi> CollectFeedbackForString(SloppyTNode<Int32T> instance_type);
    3297             :   void GenerateEqual_Same(Node* value, Label* if_equal, Label* if_notequal,
    3298             :                           Variable* var_type_feedback = nullptr);
    3299             :   TNode<String> AllocAndCopyStringCharacters(Node* from,
    3300             :                                              Node* from_instance_type,
    3301             :                                              TNode<IntPtrT> from_index,
    3302             :                                              TNode<IntPtrT> character_count);
    3303             : 
    3304             :   static const int kElementLoopUnrollThreshold = 8;
    3305             : 
    3306             :   // {convert_bigint} is only meaningful when {mode} == kToNumber.
    3307             :   Node* NonNumberToNumberOrNumeric(
    3308             :       Node* context, Node* input, Object::Conversion mode,
    3309             :       BigIntHandling bigint_handling = BigIntHandling::kThrow);
    3310             : 
    3311             :   void TaggedToNumeric(Node* context, Node* value, Label* done,
    3312             :                        Variable* var_numeric, Variable* var_feedback);
    3313             : 
    3314             :   template <Object::Conversion conversion>
    3315             :   void TaggedToWord32OrBigIntImpl(Node* context, Node* value, Label* if_number,
    3316             :                                   Variable* var_word32,
    3317             :                                   Label* if_bigint = nullptr,
    3318             :                                   Variable* var_bigint = nullptr,
    3319             :                                   Variable* var_feedback = nullptr);
    3320             : 
    3321             :  private:
    3322             :   // Low-level accessors for Descriptor arrays.
    3323             :   TNode<MaybeObject> LoadDescriptorArrayElement(TNode<DescriptorArray> object,
    3324             :                                                 Node* index,
    3325             :                                                 int additional_offset = 0);
    3326             : };
    3327             : 
    3328             : class CodeStubArguments {
    3329             :  public:
    3330             :   typedef compiler::Node Node;
    3331             :   template <class T>
    3332             :   using TNode = compiler::TNode<T>;
    3333             :   template <class T>
    3334             :   using SloppyTNode = compiler::SloppyTNode<T>;
    3335             :   enum ReceiverMode { kHasReceiver, kNoReceiver };
    3336             : 
    3337             :   // |argc| is an intptr value which specifies the number of arguments passed
    3338             :   // to the builtin excluding the receiver. The arguments will include a
    3339             :   // receiver iff |receiver_mode| is kHasReceiver.
    3340             :   CodeStubArguments(CodeStubAssembler* assembler, Node* argc,
    3341             :                     ReceiverMode receiver_mode = ReceiverMode::kHasReceiver)
    3342             :       : CodeStubArguments(assembler, argc, nullptr,
    3343        6495 :                           CodeStubAssembler::INTPTR_PARAMETERS, receiver_mode) {
    3344             :   }
    3345             : 
    3346             :   // |argc| is either a smi or intptr depending on |param_mode|. The arguments
    3347             :   // include a receiver iff |receiver_mode| is kHasReceiver.
    3348             :   CodeStubArguments(CodeStubAssembler* assembler, Node* argc, Node* fp,
    3349             :                     CodeStubAssembler::ParameterMode param_mode,
    3350             :                     ReceiverMode receiver_mode = ReceiverMode::kHasReceiver);
    3351             : 
    3352             :   TNode<Object> GetReceiver() const;
    3353             :   // Replaces receiver argument on the expression stack. Should be used only
    3354             :   // for manipulating arguments in trampoline builtins before tail calling
    3355             :   // further with passing all the JS arguments as is.
    3356             :   void SetReceiver(TNode<Object> object) const;
    3357             : 
    3358             :   TNode<RawPtr<Object>> AtIndexPtr(
    3359             :       Node* index, CodeStubAssembler::ParameterMode mode =
    3360             :                        CodeStubAssembler::INTPTR_PARAMETERS) const;
    3361             : 
    3362             :   // |index| is zero-based and does not include the receiver
    3363             :   TNode<Object> AtIndex(Node* index,
    3364             :                         CodeStubAssembler::ParameterMode mode =
    3365             :                             CodeStubAssembler::INTPTR_PARAMETERS) const;
    3366             : 
    3367             :   TNode<Object> AtIndex(int index) const;
    3368             : 
    3369        4256 :   TNode<Object> GetOptionalArgumentValue(int index) {
    3370        8512 :     return GetOptionalArgumentValue(index, assembler_->UndefinedConstant());
    3371             :   }
    3372             :   TNode<Object> GetOptionalArgumentValue(int index,
    3373             :                                          TNode<Object> default_value);
    3374             : 
    3375             :   Node* GetLength(CodeStubAssembler::ParameterMode mode) const {
    3376             :     DCHECK_EQ(mode, argc_mode_);
    3377             :     return argc_;
    3378             :   }
    3379             : 
    3380        4480 :   TNode<Object> GetOptionalArgumentValue(TNode<IntPtrT> index) {
    3381        8960 :     return GetOptionalArgumentValue(index, assembler_->UndefinedConstant());
    3382             :   }
    3383             :   TNode<Object> GetOptionalArgumentValue(TNode<IntPtrT> index,
    3384             :                                          TNode<Object> default_value);
    3385             :   TNode<IntPtrT> GetLength() const {
    3386             :     DCHECK_EQ(argc_mode_, CodeStubAssembler::INTPTR_PARAMETERS);
    3387             :     return assembler_->UncheckedCast<IntPtrT>(argc_);
    3388             :   }
    3389             : 
    3390             :   typedef std::function<void(Node* arg)> ForEachBodyFunction;
    3391             : 
    3392             :   // Iteration doesn't include the receiver. |first| and |last| are zero-based.
    3393         112 :   void ForEach(const ForEachBodyFunction& body, Node* first = nullptr,
    3394             :                Node* last = nullptr,
    3395             :                CodeStubAssembler::ParameterMode mode =
    3396             :                    CodeStubAssembler::INTPTR_PARAMETERS) {
    3397         112 :     CodeStubAssembler::VariableList list(0, assembler_->zone());
    3398         112 :     ForEach(list, body, first, last);
    3399         112 :   }
    3400             : 
    3401             :   // Iteration doesn't include the receiver. |first| and |last| are zero-based.
    3402             :   void ForEach(const CodeStubAssembler::VariableList& vars,
    3403             :                const ForEachBodyFunction& body, Node* first = nullptr,
    3404             :                Node* last = nullptr,
    3405             :                CodeStubAssembler::ParameterMode mode =
    3406             :                    CodeStubAssembler::INTPTR_PARAMETERS);
    3407             : 
    3408             :   void PopAndReturn(Node* value);
    3409             : 
    3410             :  private:
    3411             :   Node* GetArguments();
    3412             : 
    3413             :   CodeStubAssembler* assembler_;
    3414             :   CodeStubAssembler::ParameterMode argc_mode_;
    3415             :   ReceiverMode receiver_mode_;
    3416             :   Node* argc_;
    3417             :   TNode<RawPtr<Object>> arguments_;
    3418             :   Node* fp_;
    3419             : };
    3420             : 
    3421        8736 : class ToDirectStringAssembler : public CodeStubAssembler {
    3422             :  private:
    3423             :   enum StringPointerKind { PTR_TO_DATA, PTR_TO_STRING };
    3424             : 
    3425             :  public:
    3426             :   enum Flag {
    3427             :     kDontUnpackSlicedStrings = 1 << 0,
    3428             :   };
    3429             :   typedef base::Flags<Flag> Flags;
    3430             : 
    3431             :   ToDirectStringAssembler(compiler::CodeAssemblerState* state, Node* string,
    3432             :                           Flags flags = Flags());
    3433             : 
    3434             :   // Converts flat cons, thin, and sliced strings and returns the direct
    3435             :   // string. The result can be either a sequential or external string.
    3436             :   // Jumps to if_bailout if the string if the string is indirect and cannot
    3437             :   // be unpacked.
    3438             :   TNode<String> TryToDirect(Label* if_bailout);
    3439             : 
    3440             :   // Returns a pointer to the beginning of the string data.
    3441             :   // Jumps to if_bailout if the external string cannot be unpacked.
    3442             :   TNode<RawPtrT> PointerToData(Label* if_bailout) {
    3443        3752 :     return TryToSequential(PTR_TO_DATA, if_bailout);
    3444             :   }
    3445             : 
    3446             :   // Returns a pointer that, offset-wise, looks like a String.
    3447             :   // Jumps to if_bailout if the external string cannot be unpacked.
    3448             :   TNode<RawPtrT> PointerToString(Label* if_bailout) {
    3449         448 :     return TryToSequential(PTR_TO_STRING, if_bailout);
    3450             :   }
    3451             : 
    3452          56 :   Node* string() { return var_string_.value(); }
    3453        4592 :   Node* instance_type() { return var_instance_type_.value(); }
    3454             :   TNode<IntPtrT> offset() {
    3455        4704 :     return UncheckedCast<IntPtrT>(var_offset_.value());
    3456             :   }
    3457        4816 :   Node* is_external() { return var_is_external_.value(); }
    3458             : 
    3459             :  private:
    3460             :   TNode<RawPtrT> TryToSequential(StringPointerKind ptr_kind, Label* if_bailout);
    3461             : 
    3462             :   Variable var_string_;
    3463             :   Variable var_instance_type_;
    3464             :   Variable var_offset_;
    3465             :   Variable var_is_external_;
    3466             : 
    3467             :   const Flags flags_;
    3468             : };
    3469             : 
    3470             : DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags);
    3471             : 
    3472             : }  // namespace internal
    3473             : }  // namespace v8
    3474             : #endif  // V8_CODE_STUB_ASSEMBLER_H_

Generated by: LCOV version 1.10