LCOV - code coverage report
Current view: top level - src - code-stub-assembler.h (source / functions) Hit Total Coverage
Test: app.info Lines: 319 319 100.0 %
Date: 2019-04-17 Functions: 268 276 97.1 %

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

Generated by: LCOV version 1.10