// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_CODEGEN_CODE_STUB_ASSEMBLER_H_
#define V8_CODEGEN_CODE_STUB_ASSEMBLER_H_

#include <functional>

#include "src/base/macros.h"
#include "src/codegen/bailout-reason.h"
#include "src/common/external-pointer.h"
#include "src/common/globals.h"
#include "src/common/message-template.h"
#include "src/compiler/code-assembler.h"
#include "src/objects/arguments.h"
#include "src/objects/bigint.h"
#include "src/objects/feedback-vector.h"
#include "src/objects/js-function.h"
#include "src/objects/objects.h"
#include "src/objects/promise.h"
#include "src/objects/shared-function-info.h"
#include "src/objects/smi.h"
#include "src/objects/tagged-index.h"
#include "src/roots/roots.h"
#include "torque-generated/exported-macros-assembler.h"

namespace v8 {
namespace internal {

class CallInterfaceDescriptor;
class CodeStubArguments;
class CodeStubAssembler;
class StatsCounter;
class StubCache;

enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };

#define HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(V)                                  \
  V(ArrayIteratorProtector, array_iterator_protector, ArrayIteratorProtector)  \
  V(ArraySpeciesProtector, array_species_protector, ArraySpeciesProtector)     \
  V(AsyncFunctionAwaitRejectSharedFun, async_function_await_reject_shared_fun, \
    AsyncFunctionAwaitRejectSharedFun)                                         \
  V(AsyncFunctionAwaitResolveSharedFun,                                        \
    async_function_await_resolve_shared_fun,                                   \
    AsyncFunctionAwaitResolveSharedFun)                                        \
  V(AsyncGeneratorAwaitRejectSharedFun,                                        \
    async_generator_await_reject_shared_fun,                                   \
    AsyncGeneratorAwaitRejectSharedFun)                                        \
  V(AsyncGeneratorAwaitResolveSharedFun,                                       \
    async_generator_await_resolve_shared_fun,                                  \
    AsyncGeneratorAwaitResolveSharedFun)                                       \
  V(AsyncGeneratorReturnClosedRejectSharedFun,                                 \
    async_generator_return_closed_reject_shared_fun,                           \
    AsyncGeneratorReturnClosedRejectSharedFun)                                 \
  V(AsyncGeneratorReturnClosedResolveSharedFun,                                \
    async_generator_return_closed_resolve_shared_fun,                          \
    AsyncGeneratorReturnClosedResolveSharedFun)                                \
  V(AsyncGeneratorReturnResolveSharedFun,                                      \
    async_generator_return_resolve_shared_fun,                                 \
    AsyncGeneratorReturnResolveSharedFun)                                      \
  V(AsyncGeneratorYieldResolveSharedFun,                                       \
    async_generator_yield_resolve_shared_fun,                                  \
    AsyncGeneratorYieldResolveSharedFun)                                       \
  V(AsyncIteratorValueUnwrapSharedFun, async_iterator_value_unwrap_shared_fun, \
    AsyncIteratorValueUnwrapSharedFun)                                         \
  V(MapIteratorProtector, map_iterator_protector, MapIteratorProtector)        \
  V(NoElementsProtector, no_elements_protector, NoElementsProtector)           \
  V(NumberStringCache, number_string_cache, NumberStringCache)                 \
  V(PromiseAllResolveElementSharedFun, promise_all_resolve_element_shared_fun, \
    PromiseAllResolveElementSharedFun)                                         \
  V(PromiseAllSettledRejectElementSharedFun,                                   \
    promise_all_settled_reject_element_shared_fun,                             \
    PromiseAllSettledRejectElementSharedFun)                                   \
  V(PromiseAllSettledResolveElementSharedFun,                                  \
    promise_all_settled_resolve_element_shared_fun,                            \
    PromiseAllSettledResolveElementSharedFun)                                  \
  V(PromiseAnyRejectElementSharedFun, promise_any_reject_element_shared_fun,   \
    PromiseAnyRejectElementSharedFun)                                          \
  V(PromiseCapabilityDefaultRejectSharedFun,                                   \
    promise_capability_default_reject_shared_fun,                              \
    PromiseCapabilityDefaultRejectSharedFun)                                   \
  V(PromiseCapabilityDefaultResolveSharedFun,                                  \
    promise_capability_default_resolve_shared_fun,                             \
    PromiseCapabilityDefaultResolveSharedFun)                                  \
  V(PromiseCatchFinallySharedFun, promise_catch_finally_shared_fun,            \
    PromiseCatchFinallySharedFun)                                              \
  V(PromiseGetCapabilitiesExecutorSharedFun,                                   \
    promise_get_capabilities_executor_shared_fun,                              \
    PromiseGetCapabilitiesExecutorSharedFun)                                   \
  V(PromiseResolveProtector, promise_resolve_protector,                        \
    PromiseResolveProtector)                                                   \
  V(PromiseSpeciesProtector, promise_species_protector,                        \
    PromiseSpeciesProtector)                                                   \
  V(PromiseThenFinallySharedFun, promise_then_finally_shared_fun,              \
    PromiseThenFinallySharedFun)                                               \
  V(PromiseThenProtector, promise_then_protector, PromiseThenProtector)        \
  V(PromiseThrowerFinallySharedFun, promise_thrower_finally_shared_fun,        \
    PromiseThrowerFinallySharedFun)                                            \
  V(PromiseValueThunkFinallySharedFun, promise_value_thunk_finally_shared_fun, \
    PromiseValueThunkFinallySharedFun)                                         \
  V(ProxyRevokeSharedFun, proxy_revoke_shared_fun, ProxyRevokeSharedFun)       \
  V(RegExpSpeciesProtector, regexp_species_protector, RegExpSpeciesProtector)  \
  V(SetIteratorProtector, set_iterator_protector, SetIteratorProtector)        \
  V(SingleCharacterStringCache, single_character_string_cache,                 \
    SingleCharacterStringCache)                                                \
  V(StringIteratorProtector, string_iterator_protector,                        \
    StringIteratorProtector)                                                   \
  V(TypedArraySpeciesProtector, typed_array_species_protector,                 \
    TypedArraySpeciesProtector)

#define UNIQUE_INSTANCE_TYPE_IMMUTABLE_IMMOVABLE_MAP_ADAPTER( \
    V, rootIndexName, rootAccessorName, class_name)           \
  V(rootIndexName, rootAccessorName, class_name##Map)

#define HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V)                              \
  V(AllocationSiteWithoutWeakNextMap, allocation_site_without_weaknext_map,  \
    AllocationSiteWithoutWeakNextMap)                                        \
  V(AllocationSiteWithWeakNextMap, allocation_site_map, AllocationSiteMap)   \
  V(arguments_to_string, arguments_to_string, ArgumentsToString)             \
  V(Array_string, Array_string, ArrayString)                                 \
  V(array_to_string, array_to_string, ArrayToString)                         \
  V(BooleanMap, boolean_map, BooleanMap)                                     \
  V(boolean_to_string, boolean_to_string, BooleanToString)                   \
  V(ConsOneByteStringMap, cons_one_byte_string_map, ConsOneByteStringMap)    \
  V(ConsStringMap, cons_string_map, ConsStringMap)                           \
  V(constructor_string, constructor_string, ConstructorString)               \
  V(date_to_string, date_to_string, DateToString)                            \
  V(default_string, default_string, DefaultString)                           \
  V(EmptyByteArray, empty_byte_array, EmptyByteArray)                        \
  V(EmptyFixedArray, empty_fixed_array, EmptyFixedArray)                     \
  V(EmptyScopeInfo, empty_scope_info, EmptyScopeInfo)                        \
  V(EmptyPropertyDictionary, empty_property_dictionary,                      \
    EmptyPropertyDictionary)                                                 \
  V(EmptySlowElementDictionary, empty_slow_element_dictionary,               \
    EmptySlowElementDictionary)                                              \
  V(empty_string, empty_string, EmptyString)                                 \
  V(error_to_string, error_to_string, ErrorToString)                         \
  V(errors_string, errors_string, ErrorsString)                              \
  V(FalseValue, false_value, False)                                          \
  V(FixedArrayMap, fixed_array_map, FixedArrayMap)                           \
  V(FixedCOWArrayMap, fixed_cow_array_map, FixedCOWArrayMap)                 \
  V(Function_string, function_string, FunctionString)                        \
  V(function_to_string, function_to_string, FunctionToString)                \
  V(GlobalPropertyCellMap, global_property_cell_map, PropertyCellMap)        \
  V(has_instance_symbol, has_instance_symbol, HasInstanceSymbol)             \
  V(Infinity_string, Infinity_string, InfinityString)                        \
  V(is_concat_spreadable_symbol, is_concat_spreadable_symbol,                \
    IsConcatSpreadableSymbol)                                                \
  V(iterator_symbol, iterator_symbol, IteratorSymbol)                        \
  V(length_string, length_string, LengthString)                              \
  V(ManyClosuresCellMap, many_closures_cell_map, ManyClosuresCellMap)        \
  V(match_symbol, match_symbol, MatchSymbol)                                 \
  V(megamorphic_symbol, megamorphic_symbol, MegamorphicSymbol)               \
  V(message_string, message_string, MessageString)                           \
  V(minus_Infinity_string, minus_Infinity_string, MinusInfinityString)       \
  V(MinusZeroValue, minus_zero_value, MinusZero)                             \
  V(name_string, name_string, NameString)                                    \
  V(NanValue, nan_value, Nan)                                                \
  V(NaN_string, NaN_string, NaNString)                                       \
  V(next_string, next_string, NextString)                                    \
  V(NoClosuresCellMap, no_closures_cell_map, NoClosuresCellMap)              \
  V(null_to_string, null_to_string, NullToString)                            \
  V(NullValue, null_value, Null)                                             \
  V(number_string, number_string, NumberString)                              \
  V(number_to_string, number_to_string, NumberToString)                      \
  V(Object_string, Object_string, ObjectString)                              \
  V(object_to_string, object_to_string, ObjectToString)                      \
  V(OneByteStringMap, one_byte_string_map, OneByteStringMap)                 \
  V(OneClosureCellMap, one_closure_cell_map, OneClosureCellMap)              \
  V(OnePointerFillerMap, one_pointer_filler_map, OnePointerFillerMap)        \
  V(PromiseCapabilityMap, promise_capability_map, PromiseCapabilityMap)      \
  V(promise_forwarding_handler_symbol, promise_forwarding_handler_symbol,    \
    PromiseForwardingHandlerSymbol)                                          \
  V(PromiseFulfillReactionJobTaskMap, promise_fulfill_reaction_job_task_map, \
    PromiseFulfillReactionJobTaskMap)                                        \
  V(promise_handled_by_symbol, promise_handled_by_symbol,                    \
    PromiseHandledBySymbol)                                                  \
  V(PromiseReactionMap, promise_reaction_map, PromiseReactionMap)            \
  V(PromiseRejectReactionJobTaskMap, promise_reject_reaction_job_task_map,   \
    PromiseRejectReactionJobTaskMap)                                         \
  V(PromiseResolveThenableJobTaskMap, promise_resolve_thenable_job_task_map, \
    PromiseResolveThenableJobTaskMap)                                        \
  V(prototype_string, prototype_string, PrototypeString)                     \
  V(replace_symbol, replace_symbol, ReplaceSymbol)                           \
  V(regexp_to_string, regexp_to_string, RegexpToString)                      \
  V(resolve_string, resolve_string, ResolveString)                           \
  V(return_string, return_string, ReturnString)                              \
  V(species_symbol, species_symbol, SpeciesSymbol)                           \
  V(StaleRegister, stale_register, StaleRegister)                            \
  V(StoreHandler0Map, store_handler0_map, StoreHandler0Map)                  \
  V(string_string, string_string, StringString)                              \
  V(string_to_string, string_to_string, StringToString)                      \
  V(StringMap, string_map, StringMap)                                        \
  V(TheHoleValue, the_hole_value, TheHole)                                   \
  V(then_string, then_string, ThenString)                                    \
  V(toString_string, toString_string, ToStringString)                        \
  V(to_primitive_symbol, to_primitive_symbol, ToPrimitiveSymbol)             \
  V(to_string_tag_symbol, to_string_tag_symbol, ToStringTagSymbol)           \
  V(TrueValue, true_value, True)                                             \
  V(undefined_to_string, undefined_to_string, UndefinedToString)             \
  V(UndefinedValue, undefined_value, Undefined)                              \
  V(uninitialized_symbol, uninitialized_symbol, UninitializedSymbol)         \
  V(valueOf_string, valueOf_string, ValueOfString)                           \
  V(wasm_wrapped_object_symbol, wasm_wrapped_object_symbol,                  \
    WasmWrappedObjectSymbol)                                                 \
  V(zero_string, zero_string, ZeroString)                                    \
  UNIQUE_INSTANCE_TYPE_MAP_LIST_GENERATOR(                                   \
      UNIQUE_INSTANCE_TYPE_IMMUTABLE_IMMOVABLE_MAP_ADAPTER, V)

#define HEAP_IMMOVABLE_OBJECT_LIST(V)   \
  HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(V) \
  HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V)

#ifdef DEBUG
#define CSA_CHECK(csa, x) \
  (csa)->Check([&]() -> TNode<BoolT> { return x; }, #x, __FILE__, __LINE__)
#else
#define CSA_CHECK(csa, x) (csa)->FastCheck(x)
#endif

#ifdef DEBUG
// CSA_ASSERT_ARGS generates an
// std::initializer_list<CodeStubAssembler::ExtraNode> from __VA_ARGS__. It
// currently supports between 0 and 2 arguments.

// clang-format off
#define CSA_ASSERT_0_ARGS(...) {}
#define CSA_ASSERT_1_ARG(a, ...) {{a, #a}}
#define CSA_ASSERT_2_ARGS(a, b, ...) {{a, #a}, {b, #b}}
// clang-format on
#define SWITCH_CSA_ASSERT_ARGS(dummy, a, b, FUNC, ...) FUNC(a, b)
#define CSA_ASSERT_ARGS(...)                                        \
  CALL(SWITCH_CSA_ASSERT_ARGS, (, ##__VA_ARGS__, CSA_ASSERT_2_ARGS, \
                                CSA_ASSERT_1_ARG, CSA_ASSERT_0_ARGS))
// Workaround for MSVC to skip comma in empty __VA_ARGS__.
#define CALL(x, y) x y

// CSA_ASSERT(csa, <condition>, <extra values to print...>)

#define CSA_ASSERT(csa, condition_node, ...)                         \
  (csa)->Assert(condition_node, #condition_node, __FILE__, __LINE__, \
                CSA_ASSERT_ARGS(__VA_ARGS__))

// CSA_ASSERT_BRANCH(csa, [](Label* ok, Label* not_ok) {...},
//     <extra values to print...>)

#define CSA_ASSERT_BRANCH(csa, gen, ...) \
  (csa)->Assert(gen, #gen, __FILE__, __LINE__, CSA_ASSERT_ARGS(__VA_ARGS__))

#define CSA_ASSERT_JS_ARGC_OP(csa, Op, op, expected)                    \
  (csa)->Assert(                                                        \
      [&]() -> TNode<BoolT> {                                           \
        const TNode<Word32T> argc = (csa)->UncheckedParameter<Word32T>( \
            Descriptor::kJSActualArgumentsCount);                       \
        return (csa)->Op(argc, (csa)->Int32Constant(expected));         \
      },                                                                \
      "argc " #op " " #expected, __FILE__, __LINE__,                    \
      {{SmiFromInt32((csa)->UncheckedParameter<Int32T>(                 \
            Descriptor::kJSActualArgumentsCount)),                      \
        "argc"}})

#define CSA_ASSERT_JS_ARGC_EQ(csa, expected) \
  CSA_ASSERT_JS_ARGC_OP(csa, Word32Equal, ==, expected)

#define CSA_DEBUG_INFO(name) \
  { #name, __FILE__, __LINE__ }
#define BIND(label) Bind(label, CSA_DEBUG_INFO(label))
#define TYPED_VARIABLE_DEF(type, name, ...) \
  TVariable<type> name(CSA_DEBUG_INFO(name), __VA_ARGS__)
#define TYPED_VARIABLE_CONSTRUCTOR(name, ...) \
  name(CSA_DEBUG_INFO(name), __VA_ARGS__)
#else  // DEBUG
#define CSA_ASSERT(csa, ...) ((void)0)
#define CSA_ASSERT_BRANCH(csa, ...) ((void)0)
#define CSA_ASSERT_JS_ARGC_EQ(csa, expected) ((void)0)
#define BIND(label) Bind(label)
#define TYPED_VARIABLE_DEF(type, name, ...) TVariable<type> name(__VA_ARGS__)
#define TYPED_VARIABLE_CONSTRUCTOR(name, ...) name(__VA_ARGS__)
#endif  // DEBUG

#define TVARIABLE(...) EXPAND(TYPED_VARIABLE_DEF(__VA_ARGS__, this))
#define TVARIABLE_CONSTRUCTOR(...) \
  EXPAND(TYPED_VARIABLE_CONSTRUCTOR(__VA_ARGS__, this))

#ifdef ENABLE_SLOW_DCHECKS
#define CSA_SLOW_ASSERT(csa, ...) \
  if (FLAG_enable_slow_asserts) { \
    CSA_ASSERT(csa, __VA_ARGS__); \
  }
#else
#define CSA_SLOW_ASSERT(csa, ...) ((void)0)
#endif

// Provides a constexpr boolean to be used inside Torque.
#ifdef V8_NO_ARGUMENTS_ADAPTOR
constexpr bool kNoArgumentsAdaptor = true;
#else
constexpr bool kNoArgumentsAdaptor = false;
#endif

// Provides JavaScript-specific "macro-assembler" functionality on top of the
// CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler,
// it's possible to add JavaScript-specific useful CodeAssembler "macros"
// without modifying files in the compiler directory (and requiring a review
// from a compiler directory OWNER).
class V8_EXPORT_PRIVATE CodeStubAssembler
    : public compiler::CodeAssembler,
      public TorqueGeneratedExportedMacrosAssembler {
 public:
  using Node = compiler::Node;
  using ScopedExceptionHandler = compiler::ScopedExceptionHandler;

  template <typename T>
  using LazyNode = std::function<TNode<T>()>;

  explicit CodeStubAssembler(compiler::CodeAssemblerState* state);

  enum AllocationFlag : uint8_t {
    kNone = 0,
    kDoubleAlignment = 1,
    kPretenured = 1 << 1,
    kAllowLargeObjectAllocation = 1 << 2,
  };

  enum SlackTrackingMode { kWithSlackTracking, kNoSlackTracking };

  using AllocationFlags = base::Flags<AllocationFlag>;

  TNode<IntPtrT> ParameterToIntPtr(TNode<Smi> value) { return SmiUntag(value); }
  TNode<IntPtrT> ParameterToIntPtr(TNode<IntPtrT> value) { return value; }
  TNode<IntPtrT> ParameterToIntPtr(TNode<UintPtrT> value) {
    return Signed(value);
  }

  TNode<Smi> ParameterToTagged(TNode<Smi> value) { return value; }

  TNode<Smi> ParameterToTagged(TNode<IntPtrT> value) { return SmiTag(value); }

  template <typename TIndex>
  TNode<TIndex> TaggedToParameter(TNode<Smi> value);

  bool ToParameterConstant(TNode<Smi> node, intptr_t* out) {
    Smi constant;
    if (ToSmiConstant(node, &constant)) {
      *out = static_cast<intptr_t>(constant.value());
      return true;
    }
    return false;
  }

  bool ToParameterConstant(TNode<IntPtrT> node, intptr_t* out) {
    intptr_t constant;
    if (ToIntPtrConstant(node, &constant)) {
      *out = constant;
      return true;
    }
    return false;
  }

#if defined(BINT_IS_SMI)
  TNode<Smi> BIntToSmi(TNode<BInt> source) { return source; }
  TNode<IntPtrT> BIntToIntPtr(TNode<BInt> source) {
    return SmiToIntPtr(source);
  }
  TNode<BInt> SmiToBInt(TNode<Smi> source) { return source; }
  TNode<BInt> IntPtrToBInt(TNode<IntPtrT> source) {
    return SmiFromIntPtr(source);
  }
#elif defined(BINT_IS_INTPTR)
  TNode<Smi> BIntToSmi(TNode<BInt> source) { return SmiFromIntPtr(source); }
  TNode<IntPtrT> BIntToIntPtr(TNode<BInt> source) { return source; }
  TNode<BInt> SmiToBInt(TNode<Smi> source) { return SmiToIntPtr(source); }
  TNode<BInt> IntPtrToBInt(TNode<IntPtrT> source) { return source; }
#else
#error Unknown architecture.
#endif

  TNode<IntPtrT> TaggedIndexToIntPtr(TNode<TaggedIndex> value);
  TNode<TaggedIndex> IntPtrToTaggedIndex(TNode<IntPtrT> value);
  // TODO(v8:10047): Get rid of these convertions eventually.
  TNode<Smi> TaggedIndexToSmi(TNode<TaggedIndex> value);
  TNode<TaggedIndex> SmiToTaggedIndex(TNode<Smi> value);

  // Pointer compression specific. Ensures that the upper 32 bits of a Smi
  // contain the sign of a lower 32 bits so that the Smi can be directly used
  // as an index in element offset computation.
  TNode<Smi> NormalizeSmiIndex(TNode<Smi> smi_index);

  TNode<Smi> TaggedToSmi(TNode<Object> value, Label* fail) {
    GotoIf(TaggedIsNotSmi(value), fail);
    return UncheckedCast<Smi>(value);
  }

  TNode<Smi> TaggedToPositiveSmi(TNode<Object> value, Label* fail) {
    GotoIfNot(TaggedIsPositiveSmi(value), fail);
    return UncheckedCast<Smi>(value);
  }

  TNode<String> TaggedToDirectString(TNode<Object> value, Label* fail);

  TNode<HeapObject> TaggedToHeapObject(TNode<Object> value, Label* fail) {
    GotoIf(TaggedIsSmi(value), fail);
    return UncheckedCast<HeapObject>(value);
  }

  TNode<Uint16T> Uint16Constant(uint16_t t) {
    return UncheckedCast<Uint16T>(Int32Constant(t));
  }

  TNode<JSDataView> HeapObjectToJSDataView(TNode<HeapObject> heap_object,
                                           Label* fail) {
    GotoIfNot(IsJSDataView(heap_object), fail);
    return CAST(heap_object);
  }

  TNode<JSProxy> HeapObjectToJSProxy(TNode<HeapObject> heap_object,
                                     Label* fail) {
    GotoIfNot(IsJSProxy(heap_object), fail);
    return CAST(heap_object);
  }

  TNode<JSStringIterator> HeapObjectToJSStringIterator(
      TNode<HeapObject> heap_object, Label* fail) {
    GotoIfNot(IsJSStringIterator(heap_object), fail);
    return CAST(heap_object);
  }

  TNode<JSReceiver> HeapObjectToCallable(TNode<HeapObject> heap_object,
                                         Label* fail) {
    GotoIfNot(IsCallable(heap_object), fail);
    return CAST(heap_object);
  }

  TNode<String> HeapObjectToString(TNode<HeapObject> heap_object, Label* fail) {
    GotoIfNot(IsString(heap_object), fail);
    return CAST(heap_object);
  }

  TNode<JSReceiver> HeapObjectToConstructor(TNode<HeapObject> heap_object,
                                            Label* fail) {
    GotoIfNot(IsConstructor(heap_object), fail);
    return CAST(heap_object);
  }

  TNode<JSFunction> HeapObjectToJSFunctionWithPrototypeSlot(
      TNode<HeapObject> heap_object, Label* fail) {
    GotoIfNot(IsJSFunctionWithPrototypeSlot(heap_object), fail);
    return CAST(heap_object);
  }

#define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName)                    \
  TNode<Smi> OpName(TNode<Smi> a, TNode<Smi> b) { return SmiOpName(a, b); } \
  TNode<IntPtrT> OpName(TNode<IntPtrT> a, TNode<IntPtrT> b) {               \
    return IntPtrOpName(a, b);                                              \
  }                                                                         \
  TNode<UintPtrT> OpName(TNode<UintPtrT> a, TNode<UintPtrT> b) {            \
    return Unsigned(IntPtrOpName(Signed(a), Signed(b)));                    \
  }                                                                         \
  TNode<RawPtrT> OpName(TNode<RawPtrT> a, TNode<RawPtrT> b) {               \
    return ReinterpretCast<RawPtrT>(IntPtrOpName(                           \
        ReinterpretCast<IntPtrT>(a), ReinterpretCast<IntPtrT>(b)));         \
  }
  // TODO(v8:9708): Define BInt operations once all uses are ported.
  PARAMETER_BINOP(IntPtrOrSmiAdd, IntPtrAdd, SmiAdd)
  PARAMETER_BINOP(IntPtrOrSmiSub, IntPtrSub, SmiSub)
#undef PARAMETER_BINOP

#define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName)                      \
  TNode<BoolT> OpName(TNode<Smi> a, TNode<Smi> b) { return SmiOpName(a, b); } \
  TNode<BoolT> OpName(TNode<IntPtrT> a, TNode<IntPtrT> b) {                   \
    return IntPtrOpName(a, b);                                                \
  }                                                                           \
  TNode<BoolT> OpName(TNode<UintPtrT> a, TNode<UintPtrT> b) {                 \
    return IntPtrOpName(Signed(a), Signed(b));                                \
  }                                                                           \
  TNode<BoolT> OpName(TNode<RawPtrT> a, TNode<RawPtrT> b) {                   \
    return IntPtrOpName(a, b);                                                \
  }
  // TODO(v8:9708): Define BInt operations once all uses are ported.
  PARAMETER_BINOP(IntPtrOrSmiEqual, WordEqual, SmiEqual)
  PARAMETER_BINOP(IntPtrOrSmiNotEqual, WordNotEqual, SmiNotEqual)
  PARAMETER_BINOP(IntPtrOrSmiLessThanOrEqual, IntPtrLessThanOrEqual,
                  SmiLessThanOrEqual)
  PARAMETER_BINOP(IntPtrOrSmiGreaterThan, IntPtrGreaterThan, SmiGreaterThan)
  PARAMETER_BINOP(UintPtrOrSmiLessThan, UintPtrLessThan, SmiBelow)
  PARAMETER_BINOP(UintPtrOrSmiGreaterThanOrEqual, UintPtrGreaterThanOrEqual,
                  SmiAboveOrEqual)
#undef PARAMETER_BINOP

  uintptr_t ConstexprUintPtrShl(uintptr_t a, int32_t b) { return a << b; }
  uintptr_t ConstexprUintPtrShr(uintptr_t a, int32_t b) { return a >> b; }
  intptr_t ConstexprIntPtrAdd(intptr_t a, intptr_t b) { return a + b; }
  uintptr_t ConstexprUintPtrAdd(uintptr_t a, uintptr_t b) { return a + b; }
  intptr_t ConstexprWordNot(intptr_t a) { return ~a; }
  uintptr_t ConstexprWordNot(uintptr_t a) { return ~a; }

  TNode<BoolT> TaggedEqual(TNode<AnyTaggedT> a, TNode<AnyTaggedT> b) {
    if (COMPRESS_POINTERS_BOOL) {
      return Word32Equal(ReinterpretCast<Word32T>(a),
                         ReinterpretCast<Word32T>(b));
    } else {
      return WordEqual(ReinterpretCast<WordT>(a), ReinterpretCast<WordT>(b));
    }
  }

  TNode<BoolT> TaggedNotEqual(TNode<AnyTaggedT> a, TNode<AnyTaggedT> b) {
    return Word32BinaryNot(TaggedEqual(a, b));
  }

  TNode<Smi> NoContextConstant();

#define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name)  \
  TNode<std::remove_pointer<std::remove_reference<decltype(            \
      std::declval<ReadOnlyRoots>().rootAccessorName())>::type>::type> \
      name##Constant();
  HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
#undef HEAP_CONSTANT_ACCESSOR

#define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \
  TNode<std::remove_pointer<std::remove_reference<decltype(           \
      std::declval<Heap>().rootAccessorName())>::type>::type>         \
      name##Constant();
  HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
#undef HEAP_CONSTANT_ACCESSOR

#define HEAP_CONSTANT_TEST(rootIndexName, rootAccessorName, name) \
  TNode<BoolT> Is##name(SloppyTNode<Object> value);               \
  TNode<BoolT> IsNot##name(SloppyTNode<Object> value);
  HEAP_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_TEST)
#undef HEAP_CONSTANT_TEST

  TNode<BInt> BIntConstant(int value);

  template <typename TIndex>
  TNode<TIndex> IntPtrOrSmiConstant(int value);

  bool TryGetIntPtrOrSmiConstantValue(TNode<Smi> maybe_constant, int* value);
  bool TryGetIntPtrOrSmiConstantValue(TNode<IntPtrT> maybe_constant,
                                      int* value);

  // Round the 32bits payload of the provided word up to the next power of two.
  TNode<IntPtrT> IntPtrRoundUpToPowerOfTwo32(TNode<IntPtrT> value);
  // Select the maximum of the two provided IntPtr values.
  TNode<IntPtrT> IntPtrMax(SloppyTNode<IntPtrT> left,
                           SloppyTNode<IntPtrT> right);
  // Select the minimum of the two provided IntPtr values.
  TNode<IntPtrT> IntPtrMin(SloppyTNode<IntPtrT> left,
                           SloppyTNode<IntPtrT> right);
  TNode<UintPtrT> UintPtrMin(TNode<UintPtrT> left, TNode<UintPtrT> right);

  // Float64 operations.
  TNode<Float64T> Float64Ceil(SloppyTNode<Float64T> x);
  TNode<Float64T> Float64Floor(SloppyTNode<Float64T> x);
  TNode<Float64T> Float64Round(SloppyTNode<Float64T> x);
  TNode<Float64T> Float64RoundToEven(SloppyTNode<Float64T> x);
  TNode<Float64T> Float64Trunc(SloppyTNode<Float64T> x);
  // Select the minimum of the two provided Number values.
  TNode<Number> NumberMax(TNode<Number> left, TNode<Number> right);
  // Select the minimum of the two provided Number values.
  TNode<Number> NumberMin(TNode<Number> left, TNode<Number> right);

  // Returns true iff the given value fits into smi range and is >= 0.
  TNode<BoolT> IsValidPositiveSmi(TNode<IntPtrT> value);

  // Tag an IntPtr as a Smi value.
  TNode<Smi> SmiTag(SloppyTNode<IntPtrT> value);
  // Untag a Smi value as an IntPtr.
  TNode<IntPtrT> SmiUntag(SloppyTNode<Smi> value);

  // Smi conversions.
  TNode<Float64T> SmiToFloat64(SloppyTNode<Smi> value);
  TNode<Smi> SmiFromIntPtr(SloppyTNode<IntPtrT> value) { return SmiTag(value); }
  TNode<Smi> SmiFromInt32(SloppyTNode<Int32T> value);
  TNode<Smi> SmiFromUint32(TNode<Uint32T> value);
  TNode<IntPtrT> SmiToIntPtr(SloppyTNode<Smi> value) { return SmiUntag(value); }
  TNode<Int32T> SmiToInt32(SloppyTNode<Smi> value);

  // Smi operations.
#define SMI_ARITHMETIC_BINOP(SmiOpName, IntPtrOpName, Int32OpName)          \
  TNode<Smi> SmiOpName(TNode<Smi> a, TNode<Smi> b) {                        \
    if (SmiValuesAre32Bits()) {                                             \
      return BitcastWordToTaggedSigned(                                     \
          IntPtrOpName(BitcastTaggedToWordForTagAndSmiBits(a),              \
                       BitcastTaggedToWordForTagAndSmiBits(b)));            \
    } else {                                                                \
      DCHECK(SmiValuesAre31Bits());                                         \
      return BitcastWordToTaggedSigned(ChangeInt32ToIntPtr(Int32OpName(     \
          TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(a)),    \
          TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(b))))); \
    }                                                                       \
  }
  SMI_ARITHMETIC_BINOP(SmiAdd, IntPtrAdd, Int32Add)
  SMI_ARITHMETIC_BINOP(SmiSub, IntPtrSub, Int32Sub)
  SMI_ARITHMETIC_BINOP(SmiAnd, WordAnd, Word32And)
  SMI_ARITHMETIC_BINOP(SmiOr, WordOr, Word32Or)
#undef SMI_ARITHMETIC_BINOP

  TNode<IntPtrT> TryIntPtrAdd(TNode<IntPtrT> a, TNode<IntPtrT> b,
                              Label* if_overflow);
  TNode<IntPtrT> TryIntPtrSub(TNode<IntPtrT> a, TNode<IntPtrT> b,
                              Label* if_overflow);
  TNode<Int32T> TryInt32Mul(TNode<Int32T> a, TNode<Int32T> b,
                            Label* if_overflow);
  TNode<Smi> TrySmiAdd(TNode<Smi> a, TNode<Smi> b, Label* if_overflow);
  TNode<Smi> TrySmiSub(TNode<Smi> a, TNode<Smi> b, Label* if_overflow);
  TNode<Smi> TrySmiAbs(TNode<Smi> a, Label* if_overflow);

  TNode<Smi> SmiShl(TNode<Smi> a, int shift) {
    return BitcastWordToTaggedSigned(
        WordShl(BitcastTaggedToWordForTagAndSmiBits(a), shift));
  }

  TNode<Smi> SmiShr(TNode<Smi> a, int shift) {
    if (kTaggedSize == kInt64Size) {
      return BitcastWordToTaggedSigned(
          WordAnd(WordShr(BitcastTaggedToWordForTagAndSmiBits(a), shift),
                  BitcastTaggedToWordForTagAndSmiBits(SmiConstant(-1))));
    } else {
      // For pointer compressed Smis, we want to make sure that we truncate to
      // int32 before shifting, to avoid the values of the top 32-bits from
      // leaking into the sign bit of the smi.
      return BitcastWordToTaggedSigned(WordAnd(
          ChangeInt32ToIntPtr(Word32Shr(
              TruncateWordToInt32(BitcastTaggedToWordForTagAndSmiBits(a)),
              shift)),
          BitcastTaggedToWordForTagAndSmiBits(SmiConstant(-1))));
    }
  }

  TNode<Smi> SmiSar(TNode<Smi> a, int shift) {
    if (kTaggedSize == kInt64Size) {
      return BitcastWordToTaggedSigned(
          WordAnd(WordSar(BitcastTaggedToWordForTagAndSmiBits(a), shift),
                  BitcastTaggedToWordForTagAndSmiBits(SmiConstant(-1))));
    } else {
      // For pointer compressed Smis, we want to make sure that we truncate to
      // int32 before shifting, to avoid the values of the top 32-bits from
      // changing the sign bit of the smi.
      return BitcastWordToTaggedSigned(WordAnd(
          ChangeInt32ToIntPtr(Word32Sar(
              TruncateWordToInt32(BitcastTaggedToWordForTagAndSmiBits(a)),
              shift)),
          BitcastTaggedToWordForTagAndSmiBits(SmiConstant(-1))));
    }
  }

  TNode<Smi> WordOrSmiShr(TNode<Smi> a, int shift) { return SmiShr(a, shift); }

  TNode<IntPtrT> WordOrSmiShr(TNode<IntPtrT> a, int shift) {
    return WordShr(a, shift);
  }

#define SMI_COMPARISON_OP(SmiOpName, IntPtrOpName, Int32OpName)           \
  TNode<BoolT> SmiOpName(TNode<Smi> a, TNode<Smi> b) {                    \
    if (kTaggedSize == kInt64Size) {                                      \
      return IntPtrOpName(BitcastTaggedToWordForTagAndSmiBits(a),         \
                          BitcastTaggedToWordForTagAndSmiBits(b));        \
    } else {                                                              \
      DCHECK_EQ(kTaggedSize, kInt32Size);                                 \
      DCHECK(SmiValuesAre31Bits());                                       \
      return Int32OpName(                                                 \
          TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(a)),  \
          TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(b))); \
    }                                                                     \
  }
  SMI_COMPARISON_OP(SmiEqual, WordEqual, Word32Equal)
  SMI_COMPARISON_OP(SmiNotEqual, WordNotEqual, Word32NotEqual)
  SMI_COMPARISON_OP(SmiAbove, UintPtrGreaterThan, Uint32GreaterThan)
  SMI_COMPARISON_OP(SmiAboveOrEqual, UintPtrGreaterThanOrEqual,
                    Uint32GreaterThanOrEqual)
  SMI_COMPARISON_OP(SmiBelow, UintPtrLessThan, Uint32LessThan)
  SMI_COMPARISON_OP(SmiLessThan, IntPtrLessThan, Int32LessThan)
  SMI_COMPARISON_OP(SmiLessThanOrEqual, IntPtrLessThanOrEqual,
                    Int32LessThanOrEqual)
  SMI_COMPARISON_OP(SmiGreaterThan, IntPtrGreaterThan, Int32GreaterThan)
  SMI_COMPARISON_OP(SmiGreaterThanOrEqual, IntPtrGreaterThanOrEqual,
                    Int32GreaterThanOrEqual)
#undef SMI_COMPARISON_OP
  TNode<Smi> SmiMax(TNode<Smi> a, TNode<Smi> b);
  TNode<Smi> SmiMin(TNode<Smi> a, TNode<Smi> b);
  // Computes a % b for Smi inputs a and b; result is not necessarily a Smi.
  TNode<Number> SmiMod(TNode<Smi> a, TNode<Smi> b);
  // Computes a * b for Smi inputs a and b; result is not necessarily a Smi.
  TNode<Number> SmiMul(TNode<Smi> a, TNode<Smi> b);
  // Tries to compute dividend / divisor for Smi inputs; branching to bailout
  // if the division needs to be performed as a floating point operation.
  TNode<Smi> TrySmiDiv(TNode<Smi> dividend, TNode<Smi> divisor, Label* bailout);

  // Compares two Smis a and b as if they were converted to strings and then
  // compared lexicographically. Returns:
  // -1 iff x < y.
  //  0 iff x == y.
  //  1 iff x > y.
  TNode<Smi> SmiLexicographicCompare(TNode<Smi> x, TNode<Smi> y);

#ifdef BINT_IS_SMI
#define BINT_COMPARISON_OP(BIntOpName, SmiOpName, IntPtrOpName) \
  TNode<BoolT> BIntOpName(TNode<BInt> a, TNode<BInt> b) {       \
    return SmiOpName(a, b);                                     \
  }
#else
#define BINT_COMPARISON_OP(BIntOpName, SmiOpName, IntPtrOpName) \
  TNode<BoolT> BIntOpName(TNode<BInt> a, TNode<BInt> b) {       \
    return IntPtrOpName(a, b);                                  \
  }
#endif
  BINT_COMPARISON_OP(BIntEqual, SmiEqual, WordEqual)
  BINT_COMPARISON_OP(BIntNotEqual, SmiNotEqual, WordNotEqual)
  BINT_COMPARISON_OP(BIntAbove, SmiAbove, UintPtrGreaterThan)
  BINT_COMPARISON_OP(BIntAboveOrEqual, SmiAboveOrEqual,
                     UintPtrGreaterThanOrEqual)
  BINT_COMPARISON_OP(BIntBelow, SmiBelow, UintPtrLessThan)
  BINT_COMPARISON_OP(BIntLessThan, SmiLessThan, IntPtrLessThan)
  BINT_COMPARISON_OP(BIntLessThanOrEqual, SmiLessThanOrEqual,
                     IntPtrLessThanOrEqual)
  BINT_COMPARISON_OP(BIntGreaterThan, SmiGreaterThan, IntPtrGreaterThan)
  BINT_COMPARISON_OP(BIntGreaterThanOrEqual, SmiGreaterThanOrEqual,
                     IntPtrGreaterThanOrEqual)
#undef BINT_COMPARISON_OP

  // Smi | HeapNumber operations.
  TNode<Number> NumberInc(TNode<Number> value);
  TNode<Number> NumberDec(TNode<Number> value);
  TNode<Number> NumberAdd(TNode<Number> a, TNode<Number> b);
  TNode<Number> NumberSub(TNode<Number> a, TNode<Number> b);
  void GotoIfNotNumber(TNode<Object> value, Label* is_not_number);
  void GotoIfNumber(TNode<Object> value, Label* is_number);
  TNode<Number> SmiToNumber(TNode<Smi> v) { return v; }

  TNode<Number> BitwiseOp(TNode<Word32T> left32, TNode<Word32T> right32,
                          Operation bitwise_op);

  // Allocate an object of the given size.
  TNode<HeapObject> AllocateInNewSpace(TNode<IntPtrT> size,
                                       AllocationFlags flags = kNone);
  TNode<HeapObject> AllocateInNewSpace(int size, AllocationFlags flags = kNone);
  TNode<HeapObject> Allocate(TNode<IntPtrT> size,
                             AllocationFlags flags = kNone);

  TNode<HeapObject> Allocate(int size, AllocationFlags flags = kNone);
  TNode<HeapObject> InnerAllocate(TNode<HeapObject> previous, int offset);
  TNode<HeapObject> InnerAllocate(TNode<HeapObject> previous,
                                  TNode<IntPtrT> offset);

  TNode<BoolT> IsRegularHeapObjectSize(TNode<IntPtrT> size);

  using BranchGenerator = std::function<void(Label*, Label*)>;
  template <typename T>
  using NodeGenerator = std::function<TNode<T>()>;
  using ExtraNode = std::pair<TNode<Object>, const char*>;

  void Assert(const BranchGenerator& branch, const char* message,
              const char* file, int line,
              std::initializer_list<ExtraNode> extra_nodes = {});
  void Assert(const NodeGenerator<BoolT>& condition_body, const char* message,
              const char* file, int line,
              std::initializer_list<ExtraNode> extra_nodes = {});
  void Assert(TNode<Word32T> condition_node, const char* message,
              const char* file, int line,
              std::initializer_list<ExtraNode> extra_nodes = {});
  void Check(const BranchGenerator& branch, const char* message,
             const char* file, int line,
             std::initializer_list<ExtraNode> extra_nodes = {});
  void Check(const NodeGenerator<BoolT>& condition_body, const char* message,
             const char* file, int line,
             std::initializer_list<ExtraNode> extra_nodes = {});
  void Check(TNode<Word32T> condition_node, const char* message,
             const char* file, int line,
             std::initializer_list<ExtraNode> extra_nodes = {});
  void FailAssert(const char* message,
                  const std::vector<FileAndLine>& files_and_lines,
                  std::initializer_list<ExtraNode> extra_nodes = {});

  void FastCheck(TNode<BoolT> condition);

  // The following Call wrappers call an object according to the semantics that
  // one finds in the EcmaScript spec, operating on an Callable (e.g. a
  // JSFunction or proxy) rather than a Code object.
  template <class... TArgs>
  TNode<Object> Call(TNode<Context> context, TNode<Object> callable,
                     TNode<JSReceiver> receiver, TArgs... args) {
    return UncheckedCast<Object>(CallJS(
        CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
        context, callable, receiver, args...));
  }
  template <class... TArgs>
  TNode<Object> Call(TNode<Context> context, TNode<Object> callable,
                     TNode<Object> receiver, TArgs... args) {
    if (IsUndefinedConstant(receiver) || IsNullConstant(receiver)) {
      return UncheckedCast<Object>(CallJS(
          CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
          context, callable, receiver, args...));
    }
    return UncheckedCast<Object>(CallJS(CodeFactory::Call(isolate()), context,
                                        callable, receiver, args...));
  }

  TNode<Object> CallApiCallback(TNode<Object> context, TNode<RawPtrT> callback,
                                TNode<IntPtrT> argc, TNode<Object> data,
                                TNode<Object> holder, TNode<Object> receiver);

  TNode<Object> CallApiCallback(TNode<Object> context, TNode<RawPtrT> callback,
                                TNode<IntPtrT> argc, TNode<Object> data,
                                TNode<Object> holder, TNode<Object> receiver,
                                TNode<Object> value);

  TNode<Object> CallRuntimeNewArray(TNode<Context> context,
                                    TNode<Object> receiver,
                                    TNode<Object> length,
                                    TNode<Object> new_target,
                                    TNode<Object> allocation_site);

  void TailCallRuntimeNewArray(TNode<Context> context, TNode<Object> receiver,
                               TNode<Object> length, TNode<Object> new_target,
                               TNode<Object> allocation_site);

  template <class... TArgs>
  TNode<JSReceiver> ConstructWithTarget(TNode<Context> context,
                                        TNode<JSReceiver> target,
                                        TNode<JSReceiver> new_target,
                                        TArgs... args) {
    return CAST(ConstructJSWithTarget(CodeFactory::Construct(isolate()),
                                      context, target, new_target,
                                      implicit_cast<TNode<Object>>(args)...));
  }
  template <class... TArgs>
  TNode<JSReceiver> Construct(TNode<Context> context,
                              TNode<JSReceiver> new_target, TArgs... args) {
    return ConstructWithTarget(context, new_target, new_target, args...);
  }

  template <typename T>
  TNode<T> Select(TNode<BoolT> condition, const NodeGenerator<T>& true_body,
                  const NodeGenerator<T>& false_body) {
    TVARIABLE(T, value);
    Label vtrue(this), vfalse(this), end(this);
    Branch(condition, &vtrue, &vfalse);

    BIND(&vtrue);
    {
      value = true_body();
      Goto(&end);
    }
    BIND(&vfalse);
    {
      value = false_body();
      Goto(&end);
    }

    BIND(&end);
    return value.value();
  }

  template <class A>
  TNode<A> SelectConstant(TNode<BoolT> condition, TNode<A> true_value,
                          TNode<A> false_value) {
    return Select<A>(
        condition, [=] { return true_value; }, [=] { return false_value; });
  }

  TNode<Int32T> SelectInt32Constant(TNode<BoolT> condition, int true_value,
                                    int false_value);
  TNode<IntPtrT> SelectIntPtrConstant(TNode<BoolT> condition, int true_value,
                                      int false_value);
  TNode<Oddball> SelectBooleanConstant(TNode<BoolT> condition);
  TNode<Smi> SelectSmiConstant(TNode<BoolT> condition, Smi true_value,
                               Smi false_value);
  TNode<Smi> SelectSmiConstant(TNode<BoolT> condition, int true_value,
                               Smi false_value) {
    return SelectSmiConstant(condition, Smi::FromInt(true_value), false_value);
  }
  TNode<Smi> SelectSmiConstant(TNode<BoolT> condition, Smi true_value,
                               int false_value) {
    return SelectSmiConstant(condition, true_value, Smi::FromInt(false_value));
  }
  TNode<Smi> SelectSmiConstant(TNode<BoolT> condition, int true_value,
                               int false_value) {
    return SelectSmiConstant(condition, Smi::FromInt(true_value),
                             Smi::FromInt(false_value));
  }

  TNode<String> SingleCharacterStringConstant(char const* single_char) {
    DCHECK_EQ(strlen(single_char), 1);
    return HeapConstant(
        isolate()->factory()->LookupSingleCharacterStringFromCode(
            single_char[0]));
  }

  TNode<Int32T> TruncateWordToInt32(SloppyTNode<WordT> value);
  TNode<Int32T> TruncateIntPtrToInt32(SloppyTNode<IntPtrT> value);

  // Check a value for smi-ness
  TNode<BoolT> TaggedIsSmi(TNode<MaybeObject> a);
  TNode<BoolT> TaggedIsNotSmi(TNode<MaybeObject> a);

  // Check that the value is a non-negative smi.
  TNode<BoolT> TaggedIsPositiveSmi(SloppyTNode<Object> a);
  // Check that a word has a word-aligned address.
  TNode<BoolT> WordIsAligned(SloppyTNode<WordT> word, size_t alignment);
  TNode<BoolT> WordIsPowerOfTwo(SloppyTNode<IntPtrT> value);

  // Check if lower_limit <= value <= higher_limit.
  template <typename U>
  TNode<BoolT> IsInRange(TNode<Word32T> value, U lower_limit, U higher_limit) {
    DCHECK_LE(lower_limit, higher_limit);
    STATIC_ASSERT(sizeof(U) <= kInt32Size);
    return Uint32LessThanOrEqual(Int32Sub(value, Int32Constant(lower_limit)),
                                 Int32Constant(higher_limit - lower_limit));
  }

  TNode<BoolT> IsInRange(TNode<WordT> value, intptr_t lower_limit,
                         intptr_t higher_limit) {
    DCHECK_LE(lower_limit, higher_limit);
    return UintPtrLessThanOrEqual(IntPtrSub(value, IntPtrConstant(lower_limit)),
                                  IntPtrConstant(higher_limit - lower_limit));
  }

#if DEBUG
  void Bind(Label* label, AssemblerDebugInfo debug_info);
#endif  // DEBUG
  void Bind(Label* label);

  template <class... T>
  void Bind(compiler::CodeAssemblerParameterizedLabel<T...>* label,
            TNode<T>*... phis) {
    CodeAssembler::Bind(label, phis...);
  }

  void BranchIfSmiEqual(TNode<Smi> a, TNode<Smi> b, Label* if_true,
                        Label* if_false) {
    Branch(SmiEqual(a, b), if_true, if_false);
  }

  void BranchIfSmiLessThan(TNode<Smi> a, TNode<Smi> b, Label* if_true,
                           Label* if_false) {
    Branch(SmiLessThan(a, b), if_true, if_false);
  }

  void BranchIfSmiLessThanOrEqual(TNode<Smi> a, TNode<Smi> b, Label* if_true,
                                  Label* if_false) {
    Branch(SmiLessThanOrEqual(a, b), if_true, if_false);
  }

  void BranchIfFloat64IsNaN(TNode<Float64T> value, Label* if_true,
                            Label* if_false) {
    Branch(Float64Equal(value, value), if_false, if_true);
  }

  // Branches to {if_true} if ToBoolean applied to {value} yields true,
  // otherwise goes to {if_false}.
  void BranchIfToBooleanIsTrue(SloppyTNode<Object> value, Label* if_true,
                               Label* if_false);

  // Branches to {if_false} if ToBoolean applied to {value} yields false,
  // otherwise goes to {if_true}.
  void BranchIfToBooleanIsFalse(SloppyTNode<Object> value, Label* if_false,
                                Label* if_true) {
    BranchIfToBooleanIsTrue(value, if_true, if_false);
  }

  void BranchIfJSReceiver(SloppyTNode<Object> object, Label* if_true,
                          Label* if_false);

  // Branches to {if_true} when --force-slow-path flag has been passed.
  // It's used for testing to ensure that slow path implementation behave
  // equivalent to corresponding fast paths (where applicable).
  //
  // Works only with V8_ENABLE_FORCE_SLOW_PATH compile time flag. Nop otherwise.
  void GotoIfForceSlowPath(Label* if_true);

  //
  // ExternalPointerT-related functionality.
  //

  TNode<ExternalPointerT> ChangeUint32ToExternalPointer(TNode<Uint32T> value);
  TNode<Uint32T> ChangeExternalPointerToUint32(TNode<ExternalPointerT> value);

  // Initialize an external pointer field in an object.
  void InitializeExternalPointerField(TNode<HeapObject> object, int offset) {
    InitializeExternalPointerField(object, IntPtrConstant(offset));
  }
  void InitializeExternalPointerField(TNode<HeapObject> object,
                                      TNode<IntPtrT> offset);

  // Initialize an external pointer field in an object with given value.
  void InitializeExternalPointerField(TNode<HeapObject> object, int offset,
                                      TNode<RawPtrT> pointer,
                                      ExternalPointerTag tag) {
    InitializeExternalPointerField(object, IntPtrConstant(offset), pointer,
                                   tag);
  }

  void InitializeExternalPointerField(TNode<HeapObject> object,
                                      TNode<IntPtrT> offset,
                                      TNode<RawPtrT> pointer,
                                      ExternalPointerTag tag) {
    InitializeExternalPointerField(object, offset);
    StoreExternalPointerToObject(object, offset, pointer, tag);
  }

  // Load an external pointer value from an object.
  TNode<RawPtrT> LoadExternalPointerFromObject(TNode<HeapObject> object,
                                               int offset,
                                               ExternalPointerTag tag) {
    return LoadExternalPointerFromObject(object, IntPtrConstant(offset), tag);
  }

  TNode<RawPtrT> LoadExternalPointerFromObject(TNode<HeapObject> object,
                                               TNode<IntPtrT> offset,
                                               ExternalPointerTag tag);

  // Store external object pointer to object.
  void StoreExternalPointerToObject(TNode<HeapObject> object, int offset,
                                    TNode<RawPtrT> pointer,
                                    ExternalPointerTag tag) {
    StoreExternalPointerToObject(object, IntPtrConstant(offset), pointer, tag);
  }

  void StoreExternalPointerToObject(TNode<HeapObject> object,
                                    TNode<IntPtrT> offset,
                                    TNode<RawPtrT> pointer,
                                    ExternalPointerTag tag);

  TNode<RawPtrT> LoadForeignForeignAddressPtr(TNode<Foreign> object) {
    return LoadExternalPointerFromObject(object, Foreign::kForeignAddressOffset,
                                         kForeignForeignAddressTag);
  }

  TNode<RawPtrT> LoadExternalStringResourcePtr(TNode<ExternalString> object) {
    return LoadExternalPointerFromObject(
        object, ExternalString::kResourceOffset, kExternalStringResourceTag);
  }

  TNode<RawPtrT> LoadExternalStringResourceDataPtr(
      TNode<ExternalString> object) {
    return LoadExternalPointerFromObject(object,
                                         ExternalString::kResourceDataOffset,
                                         kExternalStringResourceDataTag);
  }

  TNode<RawPtrT> LoadJSTypedArrayExternalPointerPtr(
      TNode<JSTypedArray> holder) {
    return LoadExternalPointerFromObject(holder,
                                         JSTypedArray::kExternalPointerOffset,
                                         kTypedArrayExternalPointerTag);
  }

  void StoreJSTypedArrayExternalPointerPtr(TNode<JSTypedArray> holder,
                                           TNode<RawPtrT> value) {
    StoreExternalPointerToObject(holder, JSTypedArray::kExternalPointerOffset,
                                 value, kTypedArrayExternalPointerTag);
  }

  // Load value from current parent frame by given offset in bytes.
  TNode<Object> LoadFromParentFrame(int offset);

  // Load an object pointer from a buffer that isn't in the heap.
  TNode<Object> LoadBufferObject(TNode<RawPtrT> buffer, int offset) {
    return LoadFullTagged(buffer, IntPtrConstant(offset));
  }
  template <typename T>
  TNode<T> LoadBufferData(TNode<RawPtrT> buffer, int offset) {
    return UncheckedCast<T>(
        Load(MachineTypeOf<T>::value, buffer, IntPtrConstant(offset)));
  }
  TNode<RawPtrT> LoadBufferPointer(TNode<RawPtrT> buffer, int offset) {
    return LoadBufferData<RawPtrT>(buffer, offset);
  }
  TNode<Smi> LoadBufferSmi(TNode<RawPtrT> buffer, int offset) {
    return CAST(LoadBufferObject(buffer, offset));
  }
  TNode<IntPtrT> LoadBufferIntptr(TNode<RawPtrT> buffer, int offset) {
    return LoadBufferData<IntPtrT>(buffer, offset);
  }
  // Load a field from an object on the heap.
  template <class T, typename std::enable_if<
                         std::is_convertible<TNode<T>, TNode<Object>>::value,
                         int>::type = 0>
  TNode<T> LoadObjectField(TNode<HeapObject> object, int offset) {
    return CAST(LoadFromObject(MachineTypeOf<T>::value, object,
                               IntPtrConstant(offset - kHeapObjectTag)));
  }
  template <class T, typename std::enable_if<
                         std::is_convertible<TNode<T>, TNode<UntaggedT>>::value,
                         int>::type = 0>
  TNode<T> LoadObjectField(TNode<HeapObject> object, int offset) {
    return UncheckedCast<T>(
        LoadFromObject(MachineTypeOf<T>::value, object,
                       IntPtrConstant(offset - kHeapObjectTag)));
  }
  TNode<Object> LoadObjectField(TNode<HeapObject> object, int offset) {
    return UncheckedCast<Object>(
        LoadFromObject(MachineType::AnyTagged(), object,
                       IntPtrConstant(offset - kHeapObjectTag)));
  }
  TNode<Object> LoadObjectField(TNode<HeapObject> object,
                                TNode<IntPtrT> offset) {
    return UncheckedCast<Object>(
        LoadFromObject(MachineType::AnyTagged(), object,
                       IntPtrSub(offset, IntPtrConstant(kHeapObjectTag))));
  }
  template <class T, typename std::enable_if<
                         std::is_convertible<TNode<T>, TNode<UntaggedT>>::value,
                         int>::type = 0>
  TNode<T> LoadObjectField(TNode<HeapObject> object, TNode<IntPtrT> offset) {
    return UncheckedCast<T>(
        LoadFromObject(MachineTypeOf<T>::value, object,
                       IntPtrSub(offset, IntPtrConstant(kHeapObjectTag))));
  }
  // Load a SMI field and untag it.
  TNode<IntPtrT> LoadAndUntagObjectField(TNode<HeapObject> object, int offset);
  // Load a SMI field, untag it, and convert to Word32.
  TNode<Int32T> LoadAndUntagToWord32ObjectField(TNode<HeapObject> object,
                                                int offset);

  TNode<MaybeObject> LoadMaybeWeakObjectField(TNode<HeapObject> object,
                                              int offset) {
    return UncheckedCast<MaybeObject>(LoadObjectField(object, offset));
  }

  TNode<Object> LoadConstructorOrBackPointer(TNode<Map> map) {
    return LoadObjectField(map,
                           Map::kConstructorOrBackPointerOrNativeContextOffset);
  }

  // Reference is the CSA-equivalent of a Torque reference value,
  // representing an inner pointer into a HeapObject.
  // TODO(gsps): Remove in favor of flattened {Load,Store}Reference interface
  struct Reference {
    TNode<HeapObject> object;
    TNode<IntPtrT> offset;

    std::tuple<TNode<HeapObject>, TNode<IntPtrT>> Flatten() const {
      return std::make_tuple(object, offset);
    }
  };

  template <class T, typename std::enable_if<
                         std::is_convertible<TNode<T>, TNode<Object>>::value,
                         int>::type = 0>
  TNode<T> LoadReference(Reference reference) {
    TNode<IntPtrT> offset =
        IntPtrSub(reference.offset, IntPtrConstant(kHeapObjectTag));
    return CAST(
        LoadFromObject(MachineTypeOf<T>::value, reference.object, offset));
  }
  template <class T,
            typename std::enable_if<
                std::is_convertible<TNode<T>, TNode<UntaggedT>>::value ||
                    std::is_same<T, MaybeObject>::value,
                int>::type = 0>
  TNode<T> LoadReference(Reference reference) {
    TNode<IntPtrT> offset =
        IntPtrSub(reference.offset, IntPtrConstant(kHeapObjectTag));
    return UncheckedCast<T>(
        LoadFromObject(MachineTypeOf<T>::value, reference.object, offset));
  }
  template <class T, typename std::enable_if<
                         std::is_convertible<TNode<T>, TNode<Object>>::value ||
                             std::is_same<T, MaybeObject>::value,
                         int>::type = 0>
  void StoreReference(Reference reference, TNode<T> value) {
    MachineRepresentation rep = MachineRepresentationOf<T>::value;
    StoreToObjectWriteBarrier write_barrier = StoreToObjectWriteBarrier::kFull;
    if (std::is_same<T, Smi>::value) {
      write_barrier = StoreToObjectWriteBarrier::kNone;
    } else if (std::is_same<T, Map>::value) {
      write_barrier = StoreToObjectWriteBarrier::kMap;
    }
    TNode<IntPtrT> offset =
        IntPtrSub(reference.offset, IntPtrConstant(kHeapObjectTag));
    StoreToObject(rep, reference.object, offset, value, write_barrier);
  }
  template <class T, typename std::enable_if<
                         std::is_convertible<TNode<T>, TNode<UntaggedT>>::value,
                         int>::type = 0>
  void StoreReference(Reference reference, TNode<T> value) {
    TNode<IntPtrT> offset =
        IntPtrSub(reference.offset, IntPtrConstant(kHeapObjectTag));
    StoreToObject(MachineRepresentationOf<T>::value, reference.object, offset,
                  value, StoreToObjectWriteBarrier::kNone);
  }

  // Load the floating point value of a HeapNumber.
  TNode<Float64T> LoadHeapNumberValue(TNode<HeapObject> object);
  // Load the Map of an HeapObject.
  TNode<Map> LoadMap(TNode<HeapObject> object);
  // Load the instance type of an HeapObject.
  TNode<Uint16T> LoadInstanceType(TNode<HeapObject> object);
  // Compare the instance the type of the object against the provided one.
  TNode<BoolT> HasInstanceType(TNode<HeapObject> object, InstanceType type);
  TNode<BoolT> DoesntHaveInstanceType(TNode<HeapObject> object,
                                      InstanceType type);
  TNode<BoolT> TaggedDoesntHaveInstanceType(TNode<HeapObject> any_tagged,
                                            InstanceType type);

  TNode<Word32T> IsStringWrapperElementsKind(TNode<Map> map);
  void GotoIfMapHasSlowProperties(TNode<Map> map, Label* if_slow);

  // Load the properties backing store of a JSReceiver.
  TNode<HeapObject> LoadSlowProperties(TNode<JSReceiver> object);
  TNode<HeapObject> LoadFastProperties(TNode<JSReceiver> object);
  // Load the elements backing store of a JSObject.
  TNode<FixedArrayBase> LoadElements(TNode<JSObject> object) {
    return LoadJSObjectElements(object);
  }
  // Load the length of a JSArray instance.
  TNode<Object> LoadJSArgumentsObjectLength(TNode<Context> context,
                                            TNode<JSArgumentsObject> array);
  // Load the length of a fast JSArray instance. Returns a positive Smi.
  TNode<Smi> LoadFastJSArrayLength(TNode<JSArray> array);
  // Load the length of a fixed array base instance.
  TNode<Smi> LoadFixedArrayBaseLength(TNode<FixedArrayBase> array);
  // Load the length of a fixed array base instance.
  TNode<IntPtrT> LoadAndUntagFixedArrayBaseLength(TNode<FixedArrayBase> array);
  // Load the length of a WeakFixedArray.
  TNode<Smi> LoadWeakFixedArrayLength(TNode<WeakFixedArray> array);
  TNode<IntPtrT> LoadAndUntagWeakFixedArrayLength(TNode<WeakFixedArray> array);
  // Load the number of descriptors in DescriptorArray.
  TNode<Int32T> LoadNumberOfDescriptors(TNode<DescriptorArray> array);
  // Load the number of own descriptors of a map.
  TNode<Int32T> LoadNumberOfOwnDescriptors(TNode<Map> map);
  // Load the bit field of a Map.
  TNode<Int32T> LoadMapBitField(TNode<Map> map);
  // Load bit field 2 of a map.
  TNode<Int32T> LoadMapBitField2(TNode<Map> map);
  // Load bit field 3 of a map.
  TNode<Uint32T> LoadMapBitField3(TNode<Map> map);
  // Load the instance type of a map.
  TNode<Uint16T> LoadMapInstanceType(TNode<Map> map);
  // Load the ElementsKind of a map.
  TNode<Int32T> LoadMapElementsKind(TNode<Map> map);
  TNode<Int32T> LoadElementsKind(TNode<HeapObject> object);
  // Load the instance descriptors of a map.
  TNode<DescriptorArray> LoadMapDescriptors(TNode<Map> map);
  // Load the prototype of a map.
  TNode<HeapObject> LoadMapPrototype(TNode<Map> map);
  // Load the instance size of a Map.
  TNode<IntPtrT> LoadMapInstanceSizeInWords(TNode<Map> map);
  // Load the inobject properties start of a Map (valid only for JSObjects).
  TNode<IntPtrT> LoadMapInobjectPropertiesStartInWords(TNode<Map> map);
  // Load the constructor function index of a Map (only for primitive maps).
  TNode<IntPtrT> LoadMapConstructorFunctionIndex(TNode<Map> map);
  // Load the constructor of a Map (equivalent to Map::GetConstructor()).
  TNode<Object> LoadMapConstructor(TNode<Map> map);
  // Load the EnumLength of a Map.
  TNode<WordT> LoadMapEnumLength(TNode<Map> map);
  // Load the back-pointer of a Map.
  TNode<Object> LoadMapBackPointer(TNode<Map> map);
  // Checks that |map| has only simple properties, returns bitfield3.
  TNode<Uint32T> EnsureOnlyHasSimpleProperties(TNode<Map> map,
                                               TNode<Int32T> instance_type,
                                               Label* bailout);
  // Load the identity hash of a JSRececiver.
  TNode<IntPtrT> LoadJSReceiverIdentityHash(SloppyTNode<Object> receiver,
                                            Label* if_no_hash = nullptr);

  // This is only used on a newly allocated PropertyArray which
  // doesn't have an existing hash.
  void InitializePropertyArrayLength(TNode<PropertyArray> property_array,
                                     TNode<IntPtrT> length);

  // Check if the map is set for slow properties.
  TNode<BoolT> IsDictionaryMap(TNode<Map> map);

  // Load the Name::hash() value of a name as an uint32 value.
  // If {if_hash_not_computed} label is specified then it also checks if
  // hash is actually computed.
  TNode<Uint32T> LoadNameHash(TNode<Name> name,
                              Label* if_hash_not_computed = nullptr);
  TNode<Uint32T> LoadNameHashAssumeComputed(TNode<Name> name);

  // Load length field of a String object as Smi value.
  TNode<Smi> LoadStringLengthAsSmi(TNode<String> string);
  // Load length field of a String object as intptr_t value.
  TNode<IntPtrT> LoadStringLengthAsWord(TNode<String> string);
  // Load length field of a String object as uint32_t value.
  TNode<Uint32T> LoadStringLengthAsWord32(TNode<String> string);
  // Load value field of a JSPrimitiveWrapper object.
  TNode<Object> LoadJSPrimitiveWrapperValue(TNode<JSPrimitiveWrapper> object);

  // Figures out whether the value of maybe_object is:
  // - a SMI (jump to "if_smi", "extracted" will be the SMI value)
  // - a cleared weak reference (jump to "if_cleared", "extracted" will be
  // untouched)
  // - a weak reference (jump to "if_weak", "extracted" will be the object
  // pointed to)
  // - a strong reference (jump to "if_strong", "extracted" will be the object
  // pointed to)
  void DispatchMaybeObject(TNode<MaybeObject> maybe_object, Label* if_smi,
                           Label* if_cleared, Label* if_weak, Label* if_strong,
                           TVariable<Object>* extracted);
  // See MaybeObject for semantics of these functions.
  TNode<BoolT> IsStrong(TNode<MaybeObject> value);
  TNode<HeapObject> GetHeapObjectIfStrong(TNode<MaybeObject> value,
                                          Label* if_not_strong);

  TNode<BoolT> IsWeakOrCleared(TNode<MaybeObject> value);
  TNode<BoolT> IsCleared(TNode<MaybeObject> value);
  TNode<BoolT> IsNotCleared(TNode<MaybeObject> value) {
    return Word32BinaryNot(IsCleared(value));
  }

  // Removes the weak bit + asserts it was set.
  TNode<HeapObject> GetHeapObjectAssumeWeak(TNode<MaybeObject> value);

  TNode<HeapObject> GetHeapObjectAssumeWeak(TNode<MaybeObject> value,
                                            Label* if_cleared);

  // Checks if |maybe_object| is a weak reference to given |heap_object|.
  // Works for both any tagged |maybe_object| values.
  TNode<BoolT> IsWeakReferenceTo(TNode<MaybeObject> maybe_object,
                                 TNode<HeapObject> heap_object);
  // Returns true if the |object| is a HeapObject and |maybe_object| is a weak
  // reference to |object|.
  // The |maybe_object| must not be a Smi.
  TNode<BoolT> IsWeakReferenceToObject(TNode<MaybeObject> maybe_object,
                                       TNode<Object> object);

  TNode<MaybeObject> MakeWeak(TNode<HeapObject> value);

  void FixedArrayBoundsCheck(TNode<FixedArrayBase> array, TNode<Smi> index,
                             int additional_offset);

  void FixedArrayBoundsCheck(TNode<FixedArrayBase> array, TNode<IntPtrT> index,
                             int additional_offset);

  void FixedArrayBoundsCheck(TNode<FixedArrayBase> array, TNode<UintPtrT> index,
                             int additional_offset) {
    FixedArrayBoundsCheck(array, Signed(index), additional_offset);
  }

  // Array is any array-like type that has a fixed header followed by
  // tagged elements.
  template <typename Array>
  TNode<IntPtrT> LoadArrayLength(TNode<Array> array);

  // Array is any array-like type that has a fixed header followed by
  // tagged elements.
  template <typename Array, typename TIndex, typename TValue = MaybeObject>
  TNode<TValue> LoadArrayElement(
      TNode<Array> array, int array_header_size, TNode<TIndex> index,
      int additional_offset = 0,
      LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);

  template <typename TIndex>
  TNode<Object> LoadFixedArrayElement(
      TNode<FixedArray> object, TNode<TIndex> index, int additional_offset = 0,
      LoadSensitivity needs_poisoning = LoadSensitivity::kSafe,
      CheckBounds check_bounds = CheckBounds::kAlways);

  // This doesn't emit a bounds-check. As part of the security-performance
  // tradeoff, only use it if it is performance critical.
  TNode<Object> UnsafeLoadFixedArrayElement(
      TNode<FixedArray> object, TNode<IntPtrT> index, int additional_offset = 0,
      LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
    return LoadFixedArrayElement(object, index, additional_offset,
                                 needs_poisoning, CheckBounds::kDebugOnly);
  }

  TNode<Object> LoadFixedArrayElement(
      TNode<FixedArray> object, int index, int additional_offset = 0,
      LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
    return LoadFixedArrayElement(object, IntPtrConstant(index),
                                 additional_offset, needs_poisoning);
  }
  // This doesn't emit a bounds-check. As part of the security-performance
  // tradeoff, only use it if it is performance critical.
  TNode<Object> UnsafeLoadFixedArrayElement(
      TNode<FixedArray> object, int index, int additional_offset = 0,
      LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
    return LoadFixedArrayElement(object, IntPtrConstant(index),
                                 additional_offset, needs_poisoning,
                                 CheckBounds::kDebugOnly);
  }

  TNode<Object> LoadPropertyArrayElement(TNode<PropertyArray> object,
                                         SloppyTNode<IntPtrT> index);
  TNode<IntPtrT> LoadPropertyArrayLength(TNode<PropertyArray> object);

  // Load an element from an array and untag it and return it as Word32.
  // Array is any array-like type that has a fixed header followed by
  // tagged elements.
  template <typename Array>
  TNode<Int32T> LoadAndUntagToWord32ArrayElement(TNode<Array> array,
                                                 int array_header_size,
                                                 TNode<IntPtrT> index,
                                                 int additional_offset = 0);

  // Load an array element from a FixedArray, untag it and return it as Word32.
  TNode<Int32T> LoadAndUntagToWord32FixedArrayElement(
      TNode<FixedArray> object, TNode<IntPtrT> index,
      int additional_offset = 0);

  // Load an array element from a WeakFixedArray.
  TNode<MaybeObject> LoadWeakFixedArrayElement(TNode<WeakFixedArray> object,
                                               TNode<IntPtrT> index,
                                               int additional_offset = 0);

  // Load an array element from a FixedDoubleArray.
  TNode<Float64T> LoadFixedDoubleArrayElement(
      TNode<FixedDoubleArray> object, TNode<IntPtrT> index,
      Label* if_hole = nullptr,
      MachineType machine_type = MachineType::Float64());

  // Load an array element from a FixedArray, FixedDoubleArray or a
  // NumberDictionary (depending on the |elements_kind|) and return
  // it as a tagged value. Assumes that the |index| passed a length
  // check before. Bails out to |if_accessor| if the element that
  // was found is an accessor, or to |if_hole| if the element at
  // the given |index| is not found in |elements|.
  TNode<Object> LoadFixedArrayBaseElementAsTagged(
      TNode<FixedArrayBase> elements, TNode<IntPtrT> index,
      TNode<Int32T> elements_kind, Label* if_accessor, Label* if_hole);

  // Load a feedback slot from a FeedbackVector.
  template <typename TIndex>
  TNode<MaybeObject> LoadFeedbackVectorSlot(
      TNode<FeedbackVector> feedback_vector, TNode<TIndex> slot,
      int additional_offset = 0);

  TNode<IntPtrT> LoadFeedbackVectorLength(TNode<FeedbackVector>);
  TNode<Float64T> LoadDoubleWithHoleCheck(TNode<FixedDoubleArray> array,
                                          TNode<IntPtrT> index,
                                          Label* if_hole = nullptr);

  TNode<BoolT> IsDoubleHole(TNode<Object> base, TNode<IntPtrT> offset);
  // Load Float64 value by |base| + |offset| address. If the value is a double
  // hole then jump to |if_hole|. If |machine_type| is None then only the hole
  // check is generated.
  TNode<Float64T> LoadDoubleWithHoleCheck(
      TNode<Object> base, TNode<IntPtrT> offset, Label* if_hole,
      MachineType machine_type = MachineType::Float64());
  TNode<Numeric> LoadFixedTypedArrayElementAsTagged(TNode<RawPtrT> data_pointer,
                                                    TNode<UintPtrT> index,
                                                    ElementsKind elements_kind);
  TNode<Numeric> LoadFixedTypedArrayElementAsTagged(
      TNode<RawPtrT> data_pointer, TNode<UintPtrT> index,
      TNode<Int32T> elements_kind);
  // Parts of the above, factored out for readability:
  TNode<BigInt> LoadFixedBigInt64ArrayElementAsTagged(
      SloppyTNode<RawPtrT> data_pointer, SloppyTNode<IntPtrT> offset);
  TNode<BigInt> LoadFixedBigUint64ArrayElementAsTagged(
      SloppyTNode<RawPtrT> data_pointer, SloppyTNode<IntPtrT> offset);
  // 64-bit platforms only:
  TNode<BigInt> BigIntFromInt64(TNode<IntPtrT> value);
  TNode<BigInt> BigIntFromUint64(TNode<UintPtrT> value);
  // 32-bit platforms only:
  TNode<BigInt> BigIntFromInt32Pair(TNode<IntPtrT> low, TNode<IntPtrT> high);
  TNode<BigInt> BigIntFromUint32Pair(TNode<UintPtrT> low, TNode<UintPtrT> high);

  // ScopeInfo:
  TNode<ScopeInfo> LoadScopeInfo(TNode<Context> context);
  TNode<BoolT> LoadScopeInfoHasExtensionField(TNode<ScopeInfo> scope_info);

  // Context manipulation:
  void StoreContextElementNoWriteBarrier(TNode<Context> context, int slot_index,
                                         SloppyTNode<Object> value);
  TNode<NativeContext> LoadNativeContext(TNode<Context> context);
  // Calling this is only valid if there's a module context in the chain.
  TNode<Context> LoadModuleContext(TNode<Context> context);

  void GotoIfContextElementEqual(SloppyTNode<Object> value,
                                 TNode<NativeContext> native_context,
                                 int slot_index, Label* if_equal) {
    GotoIf(TaggedEqual(value, LoadContextElement(native_context, slot_index)),
           if_equal);
  }

  // Loads the initial map of the the Object constructor.
  TNode<Map> LoadObjectFunctionInitialMap(TNode<NativeContext> native_context);
  TNode<Map> LoadSlowObjectWithNullPrototypeMap(
      TNode<NativeContext> native_context);

  TNode<Map> LoadJSArrayElementsMap(ElementsKind kind,
                                    TNode<NativeContext> native_context);
  TNode<Map> LoadJSArrayElementsMap(SloppyTNode<Int32T> kind,
                                    TNode<NativeContext> native_context);

  TNode<BoolT> IsJSFunctionWithPrototypeSlot(TNode<HeapObject> object);
  TNode<BoolT> IsGeneratorFunction(TNode<JSFunction> function);
  void BranchIfHasPrototypeProperty(TNode<JSFunction> function,
                                    TNode<Int32T> function_map_bit_field,
                                    Label* if_true, Label* if_false);
  void GotoIfPrototypeRequiresRuntimeLookup(TNode<JSFunction> function,
                                            TNode<Map> map, Label* runtime);
  // Load the "prototype" property of a JSFunction.
  TNode<HeapObject> LoadJSFunctionPrototype(TNode<JSFunction> function,
                                            Label* if_bailout);

  TNode<BytecodeArray> LoadSharedFunctionInfoBytecodeArray(
      TNode<SharedFunctionInfo> shared);

  void StoreObjectByteNoWriteBarrier(TNode<HeapObject> object, int offset,
                                     TNode<Word32T> value);

  // Store the floating point value of a HeapNumber.
  void StoreHeapNumberValue(SloppyTNode<HeapNumber> object,
                            SloppyTNode<Float64T> value);
  // Store a field to an object on the heap.
  void StoreObjectField(TNode<HeapObject> object, int offset,
                        TNode<Object> value);
  void StoreObjectField(TNode<HeapObject> object, TNode<IntPtrT> offset,
                        TNode<Object> value);
  template <class T>
  void StoreObjectFieldNoWriteBarrier(TNode<HeapObject> object,
                                      SloppyTNode<IntPtrT> offset,
                                      TNode<T> value) {
    int const_offset;
    if (ToInt32Constant(offset, &const_offset)) {
      return StoreObjectFieldNoWriteBarrier<T>(object, const_offset, value);
    }
    StoreNoWriteBarrier(MachineRepresentationOf<T>::value, object,
                        IntPtrSub(offset, IntPtrConstant(kHeapObjectTag)),
                        value);
  }
  template <class T>
  void StoreObjectFieldNoWriteBarrier(TNode<HeapObject> object, int offset,
                                      TNode<T> value) {
    if (CanBeTaggedPointer(MachineRepresentationOf<T>::value)) {
      OptimizedStoreFieldAssertNoWriteBarrier(MachineRepresentationOf<T>::value,
                                              object, offset, value);
    } else {
      OptimizedStoreFieldUnsafeNoWriteBarrier(MachineRepresentationOf<T>::value,
                                              object, offset, value);
    }
  }

  void UnsafeStoreObjectFieldNoWriteBarrier(TNode<HeapObject> object,
                                            int offset, TNode<Object> value);

  // Store the Map of an HeapObject.
  void StoreMap(TNode<HeapObject> object, TNode<Map> map);
  void StoreMapNoWriteBarrier(TNode<HeapObject> object,
                              RootIndex map_root_index);
  void StoreMapNoWriteBarrier(TNode<HeapObject> object, TNode<Map> map);
  void StoreObjectFieldRoot(TNode<HeapObject> object, int offset,
                            RootIndex root);
  // Store an array element to a FixedArray.
  void StoreFixedArrayElement(
      TNode<FixedArray> object, int index, SloppyTNode<Object> value,
      WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
      CheckBounds check_bounds = CheckBounds::kAlways) {
    return StoreFixedArrayElement(object, IntPtrConstant(index), value,
                                  barrier_mode, 0, check_bounds);
  }
  // This doesn't emit a bounds-check. As part of the security-performance
  // tradeoff, only use it if it is performance critical.
  void UnsafeStoreFixedArrayElement(
      TNode<FixedArray> object, int index, TNode<Object> value,
      WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
    return StoreFixedArrayElement(object, index, value, barrier_mode,
                                  CheckBounds::kDebugOnly);
  }
  void UnsafeStoreFixedArrayElement(TNode<FixedArray> object, int index,
                                    TNode<Smi> value) {
    return StoreFixedArrayElement(object, index, value,
                                  UNSAFE_SKIP_WRITE_BARRIER,
                                  CheckBounds::kDebugOnly);
  }
  void StoreFixedArrayElement(TNode<FixedArray> object, int index,
                              TNode<Smi> value,
                              CheckBounds check_bounds = CheckBounds::kAlways) {
    return StoreFixedArrayElement(object, IntPtrConstant(index), value,
                                  UNSAFE_SKIP_WRITE_BARRIER, 0, check_bounds);
  }
  template <typename TIndex>
  void StoreFixedArrayElement(
      TNode<FixedArray> array, TNode<TIndex> index, SloppyTNode<Object> value,
      WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
      int additional_offset = 0,
      CheckBounds check_bounds = CheckBounds::kAlways) {
    // TODO(v8:9708): Do we want to keep both IntPtrT and UintPtrT variants?
    static_assert(std::is_same<TIndex, Smi>::value ||
                      std::is_same<TIndex, UintPtrT>::value ||
                      std::is_same<TIndex, IntPtrT>::value,
                  "Only Smi, UintPtrT or IntPtrT index is allowed");
    if (NeedsBoundsCheck(check_bounds)) {
      FixedArrayBoundsCheck(array, index, additional_offset);
    }
    StoreFixedArrayOrPropertyArrayElement(array, index, value, barrier_mode,
                                          additional_offset);
  }
  // This doesn't emit a bounds-check. As part of the security-performance
  // tradeoff, only use it if it is performance critical.
  void UnsafeStoreFixedArrayElement(
      TNode<FixedArray> array, TNode<IntPtrT> index, TNode<Object> value,
      WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
      int additional_offset = 0) {
    return StoreFixedArrayElement(array, index, value, barrier_mode,
                                  additional_offset, CheckBounds::kDebugOnly);
  }

  void UnsafeStoreFixedArrayElement(TNode<FixedArray> array,
                                    TNode<IntPtrT> index, TNode<Smi> value,
                                    int additional_offset) {
    return StoreFixedArrayElement(array, index, value,
                                  UNSAFE_SKIP_WRITE_BARRIER, additional_offset,
                                  CheckBounds::kDebugOnly);
  }

  void StorePropertyArrayElement(TNode<PropertyArray> array,
                                 TNode<IntPtrT> index, TNode<Object> value) {
    StoreFixedArrayOrPropertyArrayElement(array, index, value,
                                          UPDATE_WRITE_BARRIER);
  }

  void StoreFixedArrayElement(
      TNode<FixedArray> array, TNode<Smi> index, TNode<Object> value,
      WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
    StoreFixedArrayElement(array, index, value, barrier_mode, 0);
  }
  void StoreFixedArrayElement(
      TNode<FixedArray> array, TNode<IntPtrT> index, TNode<Smi> value,
      WriteBarrierMode barrier_mode = SKIP_WRITE_BARRIER,
      int additional_offset = 0) {
    DCHECK_EQ(SKIP_WRITE_BARRIER, barrier_mode);
    StoreFixedArrayElement(array, index, TNode<Object>{value},
                           UNSAFE_SKIP_WRITE_BARRIER, additional_offset);
  }
  void StoreFixedArrayElement(
      TNode<FixedArray> array, TNode<Smi> index, TNode<Smi> value,
      WriteBarrierMode barrier_mode = SKIP_WRITE_BARRIER,
      int additional_offset = 0) {
    DCHECK_EQ(SKIP_WRITE_BARRIER, barrier_mode);
    StoreFixedArrayElement(array, index, TNode<Object>{value},
                           UNSAFE_SKIP_WRITE_BARRIER, additional_offset);
  }

  template <typename TIndex>
  void StoreFixedDoubleArrayElement(
      TNode<FixedDoubleArray> object, TNode<TIndex> index,
      TNode<Float64T> value, CheckBounds check_bounds = CheckBounds::kAlways);

  void StoreDoubleHole(TNode<HeapObject> object, TNode<IntPtrT> offset);
  void StoreFixedDoubleArrayHole(TNode<FixedDoubleArray> array,
                                 TNode<IntPtrT> index);
  void StoreFeedbackVectorSlot(
      TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot,
      TNode<AnyTaggedT> value,
      WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
      int additional_offset = 0);

  // EnsureArrayPushable verifies that receiver with this map is:
  //   1. Is not a prototype.
  //   2. Is not a dictionary.
  //   3. Has a writeable length property.
  // It returns ElementsKind as a node for further division into cases.
  TNode<Int32T> EnsureArrayPushable(TNode<Context> context, TNode<Map> map,
                                    Label* bailout);

  void TryStoreArrayElement(ElementsKind kind, Label* bailout,
                            TNode<FixedArrayBase> elements, TNode<BInt> index,
                            TNode<Object> value);
  // Consumes args into the array, and returns tagged new length.
  TNode<Smi> BuildAppendJSArray(ElementsKind kind, TNode<JSArray> array,
                                CodeStubArguments* args,
                                TVariable<IntPtrT>* arg_index, Label* bailout);
  // Pushes value onto the end of array.
  void BuildAppendJSArray(ElementsKind kind, TNode<JSArray> array,
                          TNode<Object> value, Label* bailout);

  void StoreFieldsNoWriteBarrier(TNode<IntPtrT> start_address,
                                 TNode<IntPtrT> end_address,
                                 TNode<Object> value);

  // Marks the FixedArray copy-on-write without moving it.
  void MakeFixedArrayCOW(TNode<FixedArray> array);

  TNode<Cell> AllocateCellWithValue(
      TNode<Object> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
  TNode<Cell> AllocateSmiCell(int value = 0) {
    return AllocateCellWithValue(SmiConstant(value), SKIP_WRITE_BARRIER);
  }

  TNode<Object> LoadCellValue(TNode<Cell> cell);

  void StoreCellValue(TNode<Cell> cell, TNode<Object> value,
                      WriteBarrierMode mode = UPDATE_WRITE_BARRIER);

  // Allocate a HeapNumber without initializing its value.
  TNode<HeapNumber> AllocateHeapNumber();
  // Allocate a HeapNumber with a specific value.
  TNode<HeapNumber> AllocateHeapNumberWithValue(SloppyTNode<Float64T> value);
  TNode<HeapNumber> AllocateHeapNumberWithValue(double value) {
    return AllocateHeapNumberWithValue(Float64Constant(value));
  }

  // Allocate a BigInt with {length} digits. Sets the sign bit to {false}.
  // Does not initialize the digits.
  TNode<BigInt> AllocateBigInt(TNode<IntPtrT> length);
  // Like above, but allowing custom bitfield initialization.
  TNode<BigInt> AllocateRawBigInt(TNode<IntPtrT> length);
  void StoreBigIntBitfield(TNode<BigInt> bigint, TNode<Word32T> bitfield);
  void StoreBigIntDigit(TNode<BigInt> bigint, intptr_t digit_index,
                        TNode<UintPtrT> digit);
  void StoreBigIntDigit(TNode<BigInt> bigint, TNode<IntPtrT> digit_index,
                        TNode<UintPtrT> digit);

  TNode<Word32T> LoadBigIntBitfield(TNode<BigInt> bigint);
  TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint, intptr_t digit_index);
  TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint,
                                  TNode<IntPtrT> digit_index);

  // Allocate a ByteArray with the given length.
  TNode<ByteArray> AllocateByteArray(TNode<UintPtrT> length,
                                     AllocationFlags flags = kNone);

  // Allocate a SeqOneByteString with the given length.
  TNode<String> AllocateSeqOneByteString(uint32_t length,
                                         AllocationFlags flags = kNone);
  using TorqueGeneratedExportedMacrosAssembler::AllocateSeqOneByteString;

  // Allocate a SeqTwoByteString with the given length.
  TNode<String> AllocateSeqTwoByteString(uint32_t length,
                                         AllocationFlags flags = kNone);
  using TorqueGeneratedExportedMacrosAssembler::AllocateSeqTwoByteString;

  // Allocate a SlicedOneByteString with the given length, parent and offset.
  // |length| and |offset| are expected to be tagged.

  TNode<String> AllocateSlicedOneByteString(TNode<Uint32T> length,
                                            TNode<String> parent,
                                            TNode<Smi> offset);
  // Allocate a SlicedTwoByteString with the given length, parent and offset.
  // |length| and |offset| are expected to be tagged.
  TNode<String> AllocateSlicedTwoByteString(TNode<Uint32T> length,
                                            TNode<String> parent,
                                            TNode<Smi> offset);

  TNode<NameDictionary> AllocateNameDictionary(int at_least_space_for);
  TNode<NameDictionary> AllocateNameDictionary(
      TNode<IntPtrT> at_least_space_for, AllocationFlags = kNone);
  TNode<NameDictionary> AllocateNameDictionaryWithCapacity(
      TNode<IntPtrT> capacity, AllocationFlags = kNone);
  TNode<NameDictionary> CopyNameDictionary(TNode<NameDictionary> dictionary,
                                           Label* large_object_fallback);

  template <typename CollectionType>
  TNode<CollectionType> AllocateOrderedHashTable();

  TNode<JSObject> AllocateJSObjectFromMap(
      TNode<Map> map,
      base::Optional<TNode<HeapObject>> properties = base::nullopt,
      base::Optional<TNode<FixedArray>> elements = base::nullopt,
      AllocationFlags flags = kNone,
      SlackTrackingMode slack_tracking_mode = kNoSlackTracking);

  void InitializeJSObjectFromMap(
      TNode<HeapObject> object, TNode<Map> map, TNode<IntPtrT> instance_size,
      base::Optional<TNode<HeapObject>> properties = base::nullopt,
      base::Optional<TNode<FixedArray>> elements = base::nullopt,
      SlackTrackingMode slack_tracking_mode = kNoSlackTracking);

  void InitializeJSObjectBodyWithSlackTracking(
      TNode<HeapObject> object, TNode<Map> map,
      SloppyTNode<IntPtrT> instance_size);
  void InitializeJSObjectBodyNoSlackTracking(
      TNode<HeapObject> object, TNode<Map> map,
      SloppyTNode<IntPtrT> instance_size,
      int start_offset = JSObject::kHeaderSize);

  TNode<BoolT> IsValidFastJSArrayCapacity(TNode<IntPtrT> capacity);

  //
  // Allocate and return a JSArray with initialized header fields and its
  // uninitialized elements.
  std::pair<TNode<JSArray>, TNode<FixedArrayBase>>
  AllocateUninitializedJSArrayWithElements(
      ElementsKind kind, TNode<Map> array_map, TNode<Smi> length,
      base::Optional<TNode<AllocationSite>> allocation_site,
      TNode<IntPtrT> capacity, AllocationFlags allocation_flags = kNone,
      int array_header_size = JSArray::kHeaderSize);

  // Allocate a JSArray and fill elements with the hole.
  TNode<JSArray> AllocateJSArray(
      ElementsKind kind, TNode<Map> array_map, TNode<IntPtrT> capacity,
      TNode<Smi> length, base::Optional<TNode<AllocationSite>> allocation_site,
      AllocationFlags allocation_flags = kNone);
  TNode<JSArray> AllocateJSArray(
      ElementsKind kind, TNode<Map> array_map, TNode<Smi> capacity,
      TNode<Smi> length, base::Optional<TNode<AllocationSite>> allocation_site,
      AllocationFlags allocation_flags = kNone) {
    return AllocateJSArray(kind, array_map, SmiUntag(capacity), length,
                           allocation_site, allocation_flags);
  }
  TNode<JSArray> AllocateJSArray(ElementsKind kind, TNode<Map> array_map,
                                 TNode<Smi> capacity, TNode<Smi> length,
                                 AllocationFlags allocation_flags = kNone) {
    return AllocateJSArray(kind, array_map, SmiUntag(capacity), length,
                           base::nullopt, allocation_flags);
  }
  TNode<JSArray> AllocateJSArray(ElementsKind kind, TNode<Map> array_map,
                                 TNode<IntPtrT> capacity, TNode<Smi> length,
                                 AllocationFlags allocation_flags = kNone) {
    return AllocateJSArray(kind, array_map, capacity, length, base::nullopt,
                           allocation_flags);
  }

  // Allocate a JSArray and initialize the header fields.
  TNode<JSArray> AllocateJSArray(
      TNode<Map> array_map, TNode<FixedArrayBase> elements, TNode<Smi> length,
      base::Optional<TNode<AllocationSite>> allocation_site = base::nullopt,
      int array_header_size = JSArray::kHeaderSize);

  enum class HoleConversionMode { kDontConvert, kConvertToUndefined };
  // Clone a fast JSArray |array| into a new fast JSArray.
  // |convert_holes| tells the function to convert holes into undefined or not.
  // If |convert_holes| is set to kConvertToUndefined, but the function did not
  // find any hole in |array|, the resulting array will have the same elements
  // kind as |array|. If the function did find a hole, it will convert holes in
  // |array| to undefined in the resulting array, who will now have
  // PACKED_ELEMENTS kind.
  // If |convert_holes| is set kDontConvert, holes are also copied to the
  // resulting array, who will have the same elements kind as |array|. The
  // function generates significantly less code in this case.
  TNode<JSArray> CloneFastJSArray(
      TNode<Context> context, TNode<JSArray> array,
      base::Optional<TNode<AllocationSite>> allocation_site = base::nullopt,
      HoleConversionMode convert_holes = HoleConversionMode::kDontConvert);

  TNode<JSArray> ExtractFastJSArray(TNode<Context> context,
                                    TNode<JSArray> array, TNode<BInt> begin,
                                    TNode<BInt> count);

  template <typename TIndex>
  TNode<FixedArrayBase> AllocateFixedArray(
      ElementsKind kind, TNode<TIndex> capacity, AllocationFlags flags = kNone,
      base::Optional<TNode<Map>> fixed_array_map = base::nullopt);

  TNode<NativeContext> GetCreationContext(TNode<JSReceiver> receiver,
                                          Label* if_bailout);
  TNode<Object> GetConstructor(TNode<Map> map);

  TNode<Map> GetInstanceTypeMap(InstanceType instance_type);

  TNode<FixedArray> AllocateUninitializedFixedArray(intptr_t capacity) {
    return UncheckedCast<FixedArray>(AllocateFixedArray(
        PACKED_ELEMENTS, IntPtrConstant(capacity), AllocationFlag::kNone));
  }

  TNode<FixedArray> AllocateZeroedFixedArray(TNode<IntPtrT> capacity) {
    TNode<FixedArray> result = UncheckedCast<FixedArray>(
        AllocateFixedArray(PACKED_ELEMENTS, capacity,
                           AllocationFlag::kAllowLargeObjectAllocation));
    FillFixedArrayWithSmiZero(result, capacity);
    return result;
  }

  TNode<FixedDoubleArray> AllocateZeroedFixedDoubleArray(
      TNode<IntPtrT> capacity) {
    TNode<FixedDoubleArray> result = UncheckedCast<FixedDoubleArray>(
        AllocateFixedArray(PACKED_DOUBLE_ELEMENTS, capacity,
                           AllocationFlag::kAllowLargeObjectAllocation));
    FillFixedDoubleArrayWithZero(result, capacity);
    return result;
  }

  TNode<FixedArray> AllocateFixedArrayWithHoles(TNode<IntPtrT> capacity,
                                                AllocationFlags flags) {
    TNode<FixedArray> result = UncheckedCast<FixedArray>(
        AllocateFixedArray(PACKED_ELEMENTS, capacity, flags));
    FillFixedArrayWithValue(PACKED_ELEMENTS, result, IntPtrConstant(0),
                            capacity, RootIndex::kTheHoleValue);
    return result;
  }

  TNode<FixedDoubleArray> AllocateFixedDoubleArrayWithHoles(
      TNode<IntPtrT> capacity, AllocationFlags flags) {
    TNode<FixedDoubleArray> result = UncheckedCast<FixedDoubleArray>(
        AllocateFixedArray(PACKED_DOUBLE_ELEMENTS, capacity, flags));
    FillFixedArrayWithValue(PACKED_DOUBLE_ELEMENTS, result, IntPtrConstant(0),
                            capacity, RootIndex::kTheHoleValue);
    return result;
  }

  TNode<PropertyArray> AllocatePropertyArray(TNode<IntPtrT> capacity);

  // TODO(v8:9722): Return type should be JSIteratorResult
  TNode<JSObject> AllocateJSIteratorResult(TNode<Context> context,
                                           SloppyTNode<Object> value,
                                           SloppyTNode<Oddball> done);

  // TODO(v8:9722): Return type should be JSIteratorResult
  TNode<JSObject> AllocateJSIteratorResultForEntry(TNode<Context> context,
                                                   TNode<Object> key,
                                                   SloppyTNode<Object> value);

  TNode<JSReceiver> ArraySpeciesCreate(TNode<Context> context,
                                       TNode<Object> originalArray,
                                       TNode<Number> len);

  template <typename TIndex>
  void FillFixedArrayWithValue(ElementsKind kind, TNode<FixedArrayBase> array,
                               TNode<TIndex> from_index, TNode<TIndex> to_index,
                               RootIndex value_root_index);

  // Uses memset to effectively initialize the given FixedArray with zeroes.
  void FillFixedArrayWithSmiZero(TNode<FixedArray> array,
                                 TNode<IntPtrT> length);
  void FillFixedDoubleArrayWithZero(TNode<FixedDoubleArray> array,
                                    TNode<IntPtrT> length);

  void FillPropertyArrayWithUndefined(TNode<PropertyArray> array,
                                      TNode<IntPtrT> from_index,
                                      TNode<IntPtrT> to_index);

  enum class DestroySource { kNo, kYes };

  // Increment the call count for a CALL_IC or construct call.
  // The call count is located at feedback_vector[slot_id + 1].
  void IncrementCallCount(TNode<FeedbackVector> feedback_vector,
                          TNode<UintPtrT> slot_id);

  // Specify DestroySource::kYes if {from_array} is being supplanted by
  // {to_array}. This offers a slight performance benefit by simply copying the
  // array word by word. The source may be destroyed at the end of this macro.
  //
  // Otherwise, specify DestroySource::kNo for operations where an Object is
  // being cloned, to ensure that mutable HeapNumbers are unique between the
  // source and cloned object.
  void CopyPropertyArrayValues(TNode<HeapObject> from_array,
                               TNode<PropertyArray> to_array,
                               TNode<IntPtrT> length,
                               WriteBarrierMode barrier_mode,
                               DestroySource destroy_source);

  // Copies all elements from |from_array| of |length| size to
  // |to_array| of the same size respecting the elements kind.
  template <typename TIndex>
  void CopyFixedArrayElements(
      ElementsKind kind, TNode<FixedArrayBase> from_array,
      TNode<FixedArrayBase> to_array, TNode<TIndex> length,
      WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
    CopyFixedArrayElements(kind, from_array, kind, to_array,
                           IntPtrOrSmiConstant<TIndex>(0), length, length,
                           barrier_mode);
  }

  // Copies |element_count| elements from |from_array| starting from element
  // zero to |to_array| of |capacity| size respecting both array's elements
  // kinds.
  template <typename TIndex>
  void CopyFixedArrayElements(
      ElementsKind from_kind, TNode<FixedArrayBase> from_array,
      ElementsKind to_kind, TNode<FixedArrayBase> to_array,
      TNode<TIndex> element_count, TNode<TIndex> capacity,
      WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
    CopyFixedArrayElements(from_kind, from_array, to_kind, to_array,
                           IntPtrOrSmiConstant<TIndex>(0), element_count,
                           capacity, barrier_mode);
  }

  // Copies |element_count| elements from |from_array| starting from element
  // |first_element| to |to_array| of |capacity| size respecting both array's
  // elements kinds.
  // |convert_holes| tells the function whether to convert holes to undefined.
  // |var_holes_converted| can be used to signify that the conversion happened
  // (i.e. that there were holes). If |convert_holes_to_undefined| is
  // HoleConversionMode::kConvertToUndefined, then it must not be the case that
  // IsDoubleElementsKind(to_kind).
  template <typename TIndex>
  void CopyFixedArrayElements(
      ElementsKind from_kind, TNode<FixedArrayBase> from_array,
      ElementsKind to_kind, TNode<FixedArrayBase> to_array,
      TNode<TIndex> first_element, TNode<TIndex> element_count,
      TNode<TIndex> capacity,
      WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
      HoleConversionMode convert_holes = HoleConversionMode::kDontConvert,
      TVariable<BoolT>* var_holes_converted = nullptr);

  void JumpIfPointersFromHereAreInteresting(TNode<Object> object,
                                            Label* interesting);

  // Efficiently copy elements within a single array. The regions
  // [src_index, src_index + length) and [dst_index, dst_index + length)
  // can be overlapping.
  void MoveElements(ElementsKind kind, TNode<FixedArrayBase> elements,
                    TNode<IntPtrT> dst_index, TNode<IntPtrT> src_index,
                    TNode<IntPtrT> length);

  // Efficiently copy elements from one array to another. The ElementsKind
  // needs to be the same. Copy from src_elements at
  // [src_index, src_index + length) to dst_elements at
  // [dst_index, dst_index + length).
  // The function decides whether it can use memcpy. In case it cannot,
  // |write_barrier| can help it to skip write barrier. SKIP_WRITE_BARRIER is
  // only safe when copying to new space, or when copying to old space and the
  // array does not contain object pointers.
  void CopyElements(ElementsKind kind, TNode<FixedArrayBase> dst_elements,
                    TNode<IntPtrT> dst_index,
                    TNode<FixedArrayBase> src_elements,
                    TNode<IntPtrT> src_index, TNode<IntPtrT> length,
                    WriteBarrierMode write_barrier = UPDATE_WRITE_BARRIER);

  TNode<FixedArray> HeapObjectToFixedArray(TNode<HeapObject> base,
                                           Label* cast_fail);

  TNode<FixedDoubleArray> HeapObjectToFixedDoubleArray(TNode<HeapObject> base,
                                                       Label* cast_fail) {
    GotoIf(TaggedNotEqual(LoadMap(base), FixedDoubleArrayMapConstant()),
           cast_fail);
    return UncheckedCast<FixedDoubleArray>(base);
  }

  TNode<Int32T> ConvertElementsKindToInt(TNode<Int32T> elements_kind) {
    return UncheckedCast<Int32T>(elements_kind);
  }

  template <typename T>
  bool ClassHasMapConstant() {
    return false;
  }

  template <typename T>
  TNode<Map> GetClassMapConstant() {
    UNREACHABLE();
    return TNode<Map>();
  }

  enum class ExtractFixedArrayFlag {
    kFixedArrays = 1,
    kFixedDoubleArrays = 2,
    kDontCopyCOW = 4,
    kNewSpaceAllocationOnly = 8,
    kAllFixedArrays = kFixedArrays | kFixedDoubleArrays,
    kAllFixedArraysDontCopyCOW = kAllFixedArrays | kDontCopyCOW
  };

  using ExtractFixedArrayFlags = base::Flags<ExtractFixedArrayFlag>;

  // Copy a portion of an existing FixedArray or FixedDoubleArray into a new
  // array, including special appropriate handling for empty arrays and COW
  // arrays. The result array will be of the same type as the original array.
  //
  // * |source| is either a FixedArray or FixedDoubleArray from which to copy
  // elements.
  // * |first| is the starting element index to copy from, if nullptr is passed
  // then index zero is used by default.
  // * |count| is the number of elements to copy out of the source array
  // starting from and including the element indexed by |start|. If |count| is
  // nullptr, then all of the elements from |start| to the end of |source| are
  // copied.
  // * |capacity| determines the size of the allocated result array, with
  // |capacity| >= |count|. If |capacity| is nullptr, then |count| is used as
  // the destination array's capacity.
  // * |extract_flags| determines whether FixedArrays, FixedDoubleArrays or both
  // are detected and copied. Although it's always correct to pass
  // kAllFixedArrays, the generated code is more compact and efficient if the
  // caller can specify whether only FixedArrays or FixedDoubleArrays will be
  // passed as the |source| parameter.
  // * |parameter_mode| determines the parameter mode of |first|, |count| and
  // |capacity|.
  // * If |var_holes_converted| is given, any holes will be converted to
  // undefined and the variable will be set according to whether or not there
  // were any hole.
  // * If |source_elements_kind| is given, the function will try to use the
  // runtime elements kind of source to make copy faster. More specifically, it
  // can skip write barriers.
  template <typename TIndex>
  TNode<FixedArrayBase> ExtractFixedArray(
      TNode<FixedArrayBase> source, base::Optional<TNode<TIndex>> first,
      base::Optional<TNode<TIndex>> count = base::nullopt,
      base::Optional<TNode<TIndex>> capacity = base::nullopt,
      ExtractFixedArrayFlags extract_flags =
          ExtractFixedArrayFlag::kAllFixedArrays,
      TVariable<BoolT>* var_holes_converted = nullptr,
      base::Optional<TNode<Int32T>> source_elements_kind = base::nullopt);

  // Copy a portion of an existing FixedArray or FixedDoubleArray into a new
  // FixedArray, including special appropriate handling for COW arrays.
  // * |source| is either a FixedArray or FixedDoubleArray from which to copy
  // elements. |source| is assumed to be non-empty.
  // * |first| is the starting element index to copy from.
  // * |count| is the number of elements to copy out of the source array
  // starting from and including the element indexed by |start|.
  // * |capacity| determines the size of the allocated result array, with
  // |capacity| >= |count|.
  // * |source_map| is the map of the |source|.
  // * |from_kind| is the elements kind that is consistent with |source| being
  // a FixedArray or FixedDoubleArray. This function only cares about double vs.
  // non-double, so as to distinguish FixedDoubleArray vs. FixedArray. It does
  // not care about holeyness. For example, when |source| is a FixedArray,
  // PACKED/HOLEY_ELEMENTS can be used, but not PACKED_DOUBLE_ELEMENTS.
  // * |allocation_flags| and |extract_flags| influence how the target
  // FixedArray is allocated.
  // * |convert_holes| is used to signify that the target array should use
  // undefined in places of holes.
  // * If |convert_holes| is true and |var_holes_converted| not nullptr, then
  // |var_holes_converted| is used to signal whether any holes were found and
  // converted. The caller should use this information to decide which map is
  // compatible with the result array. For example, if the input was of
  // HOLEY_SMI_ELEMENTS kind, and a conversion took place, the result will be
  // compatible only with HOLEY_ELEMENTS and PACKED_ELEMENTS.
  template <typename TIndex>
  TNode<FixedArray> ExtractToFixedArray(
      TNode<FixedArrayBase> source, TNode<TIndex> first, TNode<TIndex> count,
      TNode<TIndex> capacity, TNode<Map> source_map, ElementsKind from_kind,
      AllocationFlags allocation_flags, ExtractFixedArrayFlags extract_flags,
      HoleConversionMode convert_holes,
      TVariable<BoolT>* var_holes_converted = nullptr,
      base::Optional<TNode<Int32T>> source_runtime_kind = base::nullopt);

  // Attempt to copy a FixedDoubleArray to another FixedDoubleArray. In the case
  // where the source array has a hole, produce a FixedArray instead where holes
  // are replaced with undefined.
  // * |source| is a FixedDoubleArray from which to copy elements.
  // * |first| is the starting element index to copy from.
  // * |count| is the number of elements to copy out of the source array
  // starting from and including the element indexed by |start|.
  // * |capacity| determines the size of the allocated result array, with
  // |capacity| >= |count|.
  // * |source_map| is the map of |source|. It will be used as the map of the
  // target array if the target can stay a FixedDoubleArray. Otherwise if the
  // target array needs to be a FixedArray, the FixedArrayMap will be used.
  // * |var_holes_converted| is used to signal whether a FixedAray
  // is produced or not.
  // * |allocation_flags| and |extract_flags| influence how the target array is
  // allocated.
  template <typename TIndex>
  TNode<FixedArrayBase> ExtractFixedDoubleArrayFillingHoles(
      TNode<FixedArrayBase> source, TNode<TIndex> first, TNode<TIndex> count,
      TNode<TIndex> capacity, TNode<Map> source_map,
      TVariable<BoolT>* var_holes_converted, AllocationFlags allocation_flags,
      ExtractFixedArrayFlags extract_flags);

  // Copy the entire contents of a FixedArray or FixedDoubleArray to a new
  // array, including special appropriate handling for empty arrays and COW
  // arrays.
  //
  // * |source| is either a FixedArray or FixedDoubleArray from which to copy
  // elements.
  // * |extract_flags| determines whether FixedArrays, FixedDoubleArrays or both
  // are detected and copied. Although it's always correct to pass
  // kAllFixedArrays, the generated code is more compact and efficient if the
  // caller can specify whether only FixedArrays or FixedDoubleArrays will be
  // passed as the |source| parameter.
  TNode<FixedArrayBase> CloneFixedArray(
      TNode<FixedArrayBase> source,
      ExtractFixedArrayFlags flags =
          ExtractFixedArrayFlag::kAllFixedArraysDontCopyCOW);

  // Loads an element from |array| of |from_kind| elements by given |offset|
  // (NOTE: not index!), does a hole check if |if_hole| is provided and
  // converts the value so that it becomes ready for storing to array of
  // |to_kind| elements.
  Node* LoadElementAndPrepareForStore(TNode<FixedArrayBase> array,
                                      TNode<IntPtrT> offset,
                                      ElementsKind from_kind,
                                      ElementsKind to_kind, Label* if_hole);

  template <typename TIndex>
  TNode<TIndex> CalculateNewElementsCapacity(TNode<TIndex> old_capacity);

  // Tries to grow the |elements| array of given |object| to store the |key|
  // or bails out if the growing gap is too big. Returns new elements.
  TNode<FixedArrayBase> TryGrowElementsCapacity(TNode<HeapObject> object,
                                                TNode<FixedArrayBase> elements,
                                                ElementsKind kind,
                                                TNode<Smi> key, Label* bailout);

  // Tries to grow the |capacity|-length |elements| array of given |object|
  // to store the |key| or bails out if the growing gap is too big. Returns
  // new elements.
  template <typename TIndex>
  TNode<FixedArrayBase> TryGrowElementsCapacity(TNode<HeapObject> object,
                                                TNode<FixedArrayBase> elements,
                                                ElementsKind kind,
                                                TNode<TIndex> key,
                                                TNode<TIndex> capacity,
                                                Label* bailout);

  // Grows elements capacity of given object. Returns new elements.
  template <typename TIndex>
  TNode<FixedArrayBase> GrowElementsCapacity(
      TNode<HeapObject> object, TNode<FixedArrayBase> elements,
      ElementsKind from_kind, ElementsKind to_kind, TNode<TIndex> capacity,
      TNode<TIndex> new_capacity, Label* bailout);

  // Given a need to grow by |growth|, allocate an appropriate new capacity
  // if necessary, and return a new elements FixedArray object. Label |bailout|
  // is followed for allocation failure.
  void PossiblyGrowElementsCapacity(ElementsKind kind, TNode<HeapObject> array,
                                    TNode<BInt> length,
                                    TVariable<FixedArrayBase>* var_elements,
                                    TNode<BInt> growth, Label* bailout);

  // Allocation site manipulation
  void InitializeAllocationMemento(TNode<HeapObject> base,
                                   TNode<IntPtrT> base_allocation_size,
                                   TNode<AllocationSite> allocation_site);

  TNode<Float64T> TryTaggedToFloat64(TNode<Object> value,
                                     Label* if_valueisnotnumber);
  TNode<Float64T> TruncateTaggedToFloat64(TNode<Context> context,
                                          SloppyTNode<Object> value);
  TNode<Word32T> TruncateTaggedToWord32(TNode<Context> context,
                                        SloppyTNode<Object> value);
  void TaggedToWord32OrBigInt(TNode<Context> context, TNode<Object> value,
                              Label* if_number, TVariable<Word32T>* var_word32,
                              Label* if_bigint,
                              TVariable<BigInt>* var_maybe_bigint);
  void TaggedToWord32OrBigIntWithFeedback(TNode<Context> context,
                                          TNode<Object> value, Label* if_number,
                                          TVariable<Word32T>* var_word32,
                                          Label* if_bigint,
                                          TVariable<BigInt>* var_maybe_bigint,
                                          TVariable<Smi>* var_feedback);

  TNode<Int32T> TruncateNumberToWord32(TNode<Number> value);
  // Truncate the floating point value of a HeapNumber to an Int32.
  TNode<Int32T> TruncateHeapNumberValueToWord32(TNode<HeapNumber> object);

  // Conversions.
  void TryHeapNumberToSmi(TNode<HeapNumber> number, TVariable<Smi>* output,
                          Label* if_smi);
  void TryFloat32ToSmi(TNode<Float32T> number, TVariable<Smi>* output,
                       Label* if_smi);
  void TryFloat64ToSmi(TNode<Float64T> number, TVariable<Smi>* output,
                       Label* if_smi);
  TNode<Number> ChangeFloat32ToTagged(TNode<Float32T> value);
  TNode<Number> ChangeFloat64ToTagged(SloppyTNode<Float64T> value);
  TNode<Number> ChangeInt32ToTagged(SloppyTNode<Int32T> value);
  TNode<Number> ChangeUint32ToTagged(SloppyTNode<Uint32T> value);
  TNode<Number> ChangeUintPtrToTagged(TNode<UintPtrT> value);
  TNode<Uint32T> ChangeNumberToUint32(TNode<Number> value);
  TNode<Float64T> ChangeNumberToFloat64(TNode<Number> value);

  TNode<Int32T> ChangeTaggedNonSmiToInt32(TNode<Context> context,
                                          TNode<HeapObject> input);
  TNode<Float64T> ChangeTaggedToFloat64(TNode<Context> context,
                                        TNode<Object> input);

  void TaggedToNumeric(TNode<Context> context, TNode<Object> value,
                       TVariable<Numeric>* var_numeric);
  void TaggedToNumericWithFeedback(TNode<Context> context, TNode<Object> value,
                                   TVariable<Numeric>* var_numeric,
                                   TVariable<Smi>* var_feedback);

  TNode<WordT> TimesSystemPointerSize(SloppyTNode<WordT> value);
  TNode<IntPtrT> TimesSystemPointerSize(TNode<IntPtrT> value) {
    return Signed(TimesSystemPointerSize(implicit_cast<TNode<WordT>>(value)));
  }
  TNode<UintPtrT> TimesSystemPointerSize(TNode<UintPtrT> value) {
    return Unsigned(TimesSystemPointerSize(implicit_cast<TNode<WordT>>(value)));
  }

  TNode<WordT> TimesTaggedSize(SloppyTNode<WordT> value);
  TNode<IntPtrT> TimesTaggedSize(TNode<IntPtrT> value) {
    return Signed(TimesTaggedSize(implicit_cast<TNode<WordT>>(value)));
  }
  TNode<UintPtrT> TimesTaggedSize(TNode<UintPtrT> value) {
    return Unsigned(TimesTaggedSize(implicit_cast<TNode<WordT>>(value)));
  }

  TNode<WordT> TimesDoubleSize(SloppyTNode<WordT> value);
  TNode<UintPtrT> TimesDoubleSize(TNode<UintPtrT> value) {
    return Unsigned(TimesDoubleSize(implicit_cast<TNode<WordT>>(value)));
  }
  TNode<IntPtrT> TimesDoubleSize(TNode<IntPtrT> value) {
    return Signed(TimesDoubleSize(implicit_cast<TNode<WordT>>(value)));
  }

  // Type conversions.
  // Throws a TypeError for {method_name} if {value} is not coercible to Object,
  // or returns the {value} converted to a String otherwise.
  TNode<String> ToThisString(TNode<Context> context, TNode<Object> value,
                             TNode<String> method_name);
  TNode<String> ToThisString(TNode<Context> context, TNode<Object> value,
                             char const* method_name) {
    return ToThisString(context, value, StringConstant(method_name));
  }

  // Throws a TypeError for {method_name} if {value} is neither of the given
  // {primitive_type} nor a JSPrimitiveWrapper wrapping a value of
  // {primitive_type}, or returns the {value} (or wrapped value) otherwise.
  TNode<Object> ToThisValue(TNode<Context> context, TNode<Object> value,
                            PrimitiveType primitive_type,
                            char const* method_name);

  // Throws a TypeError for {method_name} if {value} is not of the given
  // instance type.
  void ThrowIfNotInstanceType(TNode<Context> context, TNode<Object> value,
                              InstanceType instance_type,
                              char const* method_name);
  // Throws a TypeError for {method_name} if {value} is not a JSReceiver.
  void ThrowIfNotJSReceiver(TNode<Context> context, TNode<Object> value,
                            MessageTemplate msg_template,
                            const char* method_name);
  void ThrowIfNotCallable(TNode<Context> context, TNode<Object> value,
                          const char* method_name);

  void ThrowRangeError(TNode<Context> context, MessageTemplate message,
                       base::Optional<TNode<Object>> arg0 = base::nullopt,
                       base::Optional<TNode<Object>> arg1 = base::nullopt,
                       base::Optional<TNode<Object>> arg2 = base::nullopt);
  void ThrowTypeError(TNode<Context> context, MessageTemplate message,
                      char const* arg0 = nullptr, char const* arg1 = nullptr);
  void ThrowTypeError(TNode<Context> context, MessageTemplate message,
                      base::Optional<TNode<Object>> arg0,
                      base::Optional<TNode<Object>> arg1 = base::nullopt,
                      base::Optional<TNode<Object>> arg2 = base::nullopt);

  // Type checks.
  // Check whether the map is for an object with special properties, such as a
  // JSProxy or an object with interceptors.
  TNode<BoolT> InstanceTypeEqual(SloppyTNode<Int32T> instance_type, int type);
  TNode<BoolT> IsNoElementsProtectorCellInvalid();
  TNode<BoolT> IsArrayIteratorProtectorCellInvalid();
  TNode<BoolT> IsBigIntInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsBigInt(TNode<HeapObject> object);
  TNode<BoolT> IsBoolean(TNode<HeapObject> object);
  TNode<BoolT> IsCallableMap(TNode<Map> map);
  TNode<BoolT> IsCallable(TNode<HeapObject> object);
  TNode<BoolT> TaggedIsCallable(TNode<Object> object);
  TNode<BoolT> IsConsStringInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsConstructorMap(TNode<Map> map);
  TNode<BoolT> IsConstructor(TNode<HeapObject> object);
  TNode<BoolT> IsDeprecatedMap(TNode<Map> map);
  TNode<BoolT> IsNameDictionary(TNode<HeapObject> object);
  TNode<BoolT> IsGlobalDictionary(TNode<HeapObject> object);
  TNode<BoolT> IsExtensibleMap(TNode<Map> map);
  TNode<BoolT> IsExtensibleNonPrototypeMap(TNode<Map> map);
  TNode<BoolT> IsExternalStringInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsFixedArray(TNode<HeapObject> object);
  TNode<BoolT> IsFixedArraySubclass(TNode<HeapObject> object);
  TNode<BoolT> IsFixedArrayWithKind(TNode<HeapObject> object,
                                    ElementsKind kind);
  TNode<BoolT> IsFixedArrayWithKindOrEmpty(TNode<FixedArrayBase> object,
                                           ElementsKind kind);
  TNode<BoolT> IsFunctionWithPrototypeSlotMap(TNode<Map> map);
  TNode<BoolT> IsHashTable(TNode<HeapObject> object);
  TNode<BoolT> IsEphemeronHashTable(TNode<HeapObject> object);
  TNode<BoolT> IsHeapNumberInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsOddball(TNode<HeapObject> object);
  TNode<BoolT> IsOddballInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsIndirectStringInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsJSArrayBuffer(TNode<HeapObject> object);
  TNode<BoolT> IsJSDataView(TNode<HeapObject> object);
  TNode<BoolT> IsJSArrayInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsJSArrayMap(TNode<Map> map);
  TNode<BoolT> IsJSArray(TNode<HeapObject> object);
  TNode<BoolT> IsJSArrayIterator(TNode<HeapObject> object);
  TNode<BoolT> IsJSAsyncGeneratorObject(TNode<HeapObject> object);
  TNode<BoolT> IsJSFunctionInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsJSFunctionMap(TNode<Map> map);
  TNode<BoolT> IsJSFunction(TNode<HeapObject> object);
  TNode<BoolT> IsJSBoundFunction(TNode<HeapObject> object);
  TNode<BoolT> IsJSGeneratorObject(TNode<HeapObject> object);
  TNode<BoolT> IsJSGlobalProxyInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsJSGlobalProxyMap(TNode<Map> map);
  TNode<BoolT> IsJSGlobalProxy(TNode<HeapObject> object);
  TNode<BoolT> IsJSObjectInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsJSObjectMap(TNode<Map> map);
  TNode<BoolT> IsJSObject(TNode<HeapObject> object);
  TNode<BoolT> IsJSFinalizationRegistryMap(TNode<Map> map);
  TNode<BoolT> IsJSFinalizationRegistry(TNode<HeapObject> object);
  TNode<BoolT> IsJSPromiseMap(TNode<Map> map);
  TNode<BoolT> IsJSPromise(TNode<HeapObject> object);
  TNode<BoolT> IsJSProxy(TNode<HeapObject> object);
  TNode<BoolT> IsJSStringIterator(TNode<HeapObject> object);
  TNode<BoolT> IsJSRegExpStringIterator(TNode<HeapObject> object);
  TNode<BoolT> IsJSReceiverInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsJSReceiverMap(TNode<Map> map);
  TNode<BoolT> IsJSReceiver(TNode<HeapObject> object);
  TNode<BoolT> IsJSRegExp(TNode<HeapObject> object);
  TNode<BoolT> IsJSTypedArrayInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsJSTypedArrayMap(TNode<Map> map);
  TNode<BoolT> IsJSTypedArray(TNode<HeapObject> object);
  TNode<BoolT> IsJSGeneratorMap(TNode<Map> map);
  TNode<BoolT> IsJSPrimitiveWrapperInstanceType(
      SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsJSPrimitiveWrapperMap(TNode<Map> map);
  TNode<BoolT> IsJSPrimitiveWrapper(TNode<HeapObject> object);
  TNode<BoolT> IsMap(TNode<HeapObject> object);
  TNode<BoolT> IsName(TNode<HeapObject> object);
  TNode<BoolT> IsNameInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsNullOrJSReceiver(TNode<HeapObject> object);
  TNode<BoolT> IsNullOrUndefined(SloppyTNode<Object> object);
  TNode<BoolT> IsNumberDictionary(TNode<HeapObject> object);
  TNode<BoolT> IsOneByteStringInstanceType(TNode<Int32T> instance_type);
  TNode<BoolT> IsSeqOneByteStringInstanceType(TNode<Int32T> instance_type);
  TNode<BoolT> IsPrimitiveInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsPrivateName(SloppyTNode<Symbol> symbol);
  TNode<BoolT> IsPropertyArray(TNode<HeapObject> object);
  TNode<BoolT> IsPropertyCell(TNode<HeapObject> object);
  TNode<BoolT> IsPromiseReactionJobTask(TNode<HeapObject> object);
  TNode<BoolT> IsPrototypeInitialArrayPrototype(TNode<Context> context,
                                                TNode<Map> map);
  TNode<BoolT> IsPrototypeTypedArrayPrototype(TNode<Context> context,
                                              TNode<Map> map);

  TNode<BoolT> IsFastAliasedArgumentsMap(TNode<Context> context,
                                         TNode<Map> map);
  TNode<BoolT> IsSlowAliasedArgumentsMap(TNode<Context> context,
                                         TNode<Map> map);
  TNode<BoolT> IsSloppyArgumentsMap(TNode<Context> context, TNode<Map> map);
  TNode<BoolT> IsStrictArgumentsMap(TNode<Context> context, TNode<Map> map);

  TNode<BoolT> IsSequentialStringInstanceType(
      SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsUncachedExternalStringInstanceType(
      SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsSpecialReceiverInstanceType(TNode<Int32T> instance_type);
  TNode<BoolT> IsCustomElementsReceiverInstanceType(
      TNode<Int32T> instance_type);
  TNode<BoolT> IsSpecialReceiverMap(TNode<Map> map);
  TNode<BoolT> IsStringInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsString(TNode<HeapObject> object);
  TNode<BoolT> IsSeqOneByteString(TNode<HeapObject> object);

  TNode<BoolT> IsSymbolInstanceType(SloppyTNode<Int32T> instance_type);
  TNode<BoolT> IsInternalizedStringInstanceType(TNode<Int32T> instance_type);
  TNode<BoolT> IsUniqueName(TNode<HeapObject> object);
  TNode<BoolT> IsUniqueNameNoIndex(TNode<HeapObject> object);
  TNode<BoolT> IsUniqueNameNoCachedIndex(TNode<HeapObject> object);
  TNode<BoolT> IsUndetectableMap(TNode<Map> map);
  TNode<BoolT> IsNotWeakFixedArraySubclass(TNode<HeapObject> object);
  TNode<BoolT> IsZeroOrContext(SloppyTNode<Object> object);

  TNode<BoolT> IsPromiseResolveProtectorCellInvalid();
  TNode<BoolT> IsPromiseThenProtectorCellInvalid();
  TNode<BoolT> IsArraySpeciesProtectorCellInvalid();
  TNode<BoolT> IsTypedArraySpeciesProtectorCellInvalid();
  TNode<BoolT> IsRegExpSpeciesProtectorCellInvalid();
  TNode<BoolT> IsPromiseSpeciesProtectorCellInvalid();

  TNode<BoolT> IsMockArrayBufferAllocatorFlag() {
    TNode<Word32T> flag_value = UncheckedCast<Word32T>(Load(
        MachineType::Uint8(),
        ExternalConstant(
            ExternalReference::address_of_mock_arraybuffer_allocator_flag())));
    return Word32NotEqual(Word32And(flag_value, Int32Constant(0xFF)),
                          Int32Constant(0));
  }

  // True iff |object| is a Smi or a HeapNumber or a BigInt.
  TNode<BoolT> IsNumeric(SloppyTNode<Object> object);

  // True iff |number| is either a Smi, or a HeapNumber whose value is not
  // within Smi range.
  TNode<BoolT> IsNumberNormalized(TNode<Number> number);
  TNode<BoolT> IsNumberPositive(TNode<Number> number);
  TNode<BoolT> IsHeapNumberPositive(TNode<HeapNumber> number);

  // True iff {number} is non-negative and less or equal than 2**53-1.
  TNode<BoolT> IsNumberNonNegativeSafeInteger(TNode<Number> number);

  // True iff {number} represents an integer value.
  TNode<BoolT> IsInteger(TNode<Object> number);
  TNode<BoolT> IsInteger(TNode<HeapNumber> number);

  // True iff abs({number}) <= 2**53 -1
  TNode<BoolT> IsSafeInteger(TNode<Object> number);
  TNode<BoolT> IsSafeInteger(TNode<HeapNumber> number);

  // True iff {number} represents a valid uint32t value.
  TNode<BoolT> IsHeapNumberUint32(TNode<HeapNumber> number);

  // True iff {number} is a positive number and a valid array index in the range
  // [0, 2^32-1).
  TNode<BoolT> IsNumberArrayIndex(TNode<Number> number);

  template <typename TIndex>
  TNode<BoolT> FixedArraySizeDoesntFitInNewSpace(TNode<TIndex> element_count,
                                                 int base_size);

  TNode<BoolT> IsMetaMap(TNode<HeapObject> o) { return IsMapMap(o); }

  // ElementsKind helpers:
  TNode<BoolT> ElementsKindEqual(TNode<Int32T> a, TNode<Int32T> b) {
    return Word32Equal(a, b);
  }
  bool ElementsKindEqual(ElementsKind a, ElementsKind b) { return a == b; }
  TNode<BoolT> IsFastElementsKind(TNode<Int32T> elements_kind);
  bool IsFastElementsKind(ElementsKind kind) {
    return v8::internal::IsFastElementsKind(kind);
  }
  TNode<BoolT> IsFastOrNonExtensibleOrSealedElementsKind(
      TNode<Int32T> elements_kind);

  TNode<BoolT> IsDictionaryElementsKind(TNode<Int32T> elements_kind) {
    return ElementsKindEqual(elements_kind, Int32Constant(DICTIONARY_ELEMENTS));
  }
  TNode<BoolT> IsDoubleElementsKind(TNode<Int32T> elements_kind);
  bool IsDoubleElementsKind(ElementsKind kind) {
    return v8::internal::IsDoubleElementsKind(kind);
  }
  TNode<BoolT> IsFastSmiOrTaggedElementsKind(TNode<Int32T> elements_kind);
  TNode<BoolT> IsFastSmiElementsKind(SloppyTNode<Int32T> elements_kind);
  TNode<BoolT> IsHoleyFastElementsKind(TNode<Int32T> elements_kind);
  TNode<BoolT> IsHoleyFastElementsKindForRead(TNode<Int32T> elements_kind);
  TNode<BoolT> IsElementsKindGreaterThan(TNode<Int32T> target_kind,
                                         ElementsKind reference_kind);
  TNode<BoolT> IsElementsKindLessThanOrEqual(TNode<Int32T> target_kind,
                                             ElementsKind reference_kind);
  // Check if lower_reference_kind <= target_kind <= higher_reference_kind.
  TNode<BoolT> IsElementsKindInRange(TNode<Int32T> target_kind,
                                     ElementsKind lower_reference_kind,
                                     ElementsKind higher_reference_kind) {
    return IsInRange(target_kind, lower_reference_kind, higher_reference_kind);
  }

  // String helpers.
  // Load a character from a String (might flatten a ConsString).
  TNode<Int32T> StringCharCodeAt(TNode<String> string, TNode<UintPtrT> index);
  // Return the single character string with only {code}.
  TNode<String> StringFromSingleCharCode(TNode<Int32T> code);

  // Type conversion helpers.
  enum class BigIntHandling { kConvertToNumber, kThrow };
  // Convert a String to a Number.
  TNode<Number> StringToNumber(TNode<String> input);
  // Convert a Number to a String.
  TNode<String> NumberToString(TNode<Number> input);
  TNode<String> NumberToString(TNode<Number> input, Label* bailout);

  // Convert a Non-Number object to a Number.
  TNode<Number> NonNumberToNumber(
      TNode<Context> context, TNode<HeapObject> input,
      BigIntHandling bigint_handling = BigIntHandling::kThrow);
  // Convert a Non-Number object to a Numeric.
  TNode<Numeric> NonNumberToNumeric(TNode<Context> context,
                                    TNode<HeapObject> input);
  // Convert any object to a Number.
  // Conforms to ES#sec-tonumber if {bigint_handling} == kThrow.
  // With {bigint_handling} == kConvertToNumber, matches behavior of
  // tc39.github.io/proposal-bigint/#sec-number-constructor-number-value.
  TNode<Number> ToNumber(
      TNode<Context> context, SloppyTNode<Object> input,
      BigIntHandling bigint_handling = BigIntHandling::kThrow);
  TNode<Number> ToNumber_Inline(TNode<Context> context,
                                SloppyTNode<Object> input);
  // Convert any plain primitive to a Number. No need to handle BigInts since
  // they are not plain primitives.
  TNode<Number> PlainPrimitiveToNumber(TNode<Object> input);

  // Try to convert an object to a BigInt. Throws on failure (e.g. for Numbers).
  // https://tc39.github.io/proposal-bigint/#sec-to-bigint
  TNode<BigInt> ToBigInt(TNode<Context> context, TNode<Object> input);

  // Converts |input| to one of 2^32 integer values in the range 0 through
  // 2^32-1, inclusive.
  // ES#sec-touint32
  TNode<Number> ToUint32(TNode<Context> context, SloppyTNode<Object> input);

  // Convert any object to a String.
  TNode<String> ToString_Inline(TNode<Context> context,
                                SloppyTNode<Object> input);

  TNode<JSReceiver> ToObject(TNode<Context> context, SloppyTNode<Object> input);

  // Same as ToObject but avoids the Builtin call if |input| is already a
  // JSReceiver.
  TNode<JSReceiver> ToObject_Inline(TNode<Context> context,
                                    TNode<Object> input);

  // ES6 7.1.15 ToLength, but with inlined fast path.
  TNode<Number> ToLength_Inline(TNode<Context> context,
                                SloppyTNode<Object> input);

  TNode<Object> OrdinaryToPrimitive(TNode<Context> context, TNode<Object> input,
                                    OrdinaryToPrimitiveHint hint);

  // Returns a node that contains a decoded (unsigned!) value of a bit
  // field |BitField| in |word32|. Returns result as an uint32 node.
  template <typename BitField>
  TNode<Uint32T> DecodeWord32(TNode<Word32T> word32) {
    return DecodeWord32(word32, BitField::kShift, BitField::kMask);
  }

  // Returns a node that contains a decoded (unsigned!) value of a bit
  // field |BitField| in |word|. Returns result as a word-size node.
  template <typename BitField>
  TNode<UintPtrT> DecodeWord(SloppyTNode<WordT> word) {
    return DecodeWord(word, BitField::kShift, BitField::kMask);
  }

  // Returns a node that contains a decoded (unsigned!) value of a bit
  // field |BitField| in |word32|. Returns result as a word-size node.
  template <typename BitField>
  TNode<UintPtrT> DecodeWordFromWord32(TNode<Word32T> word32) {
    return DecodeWord<BitField>(ChangeUint32ToWord(word32));
  }

  // Returns a node that contains a decoded (unsigned!) value of a bit
  // field |BitField| in |word|. Returns result as an uint32 node.
  template <typename BitField>
  TNode<Uint32T> DecodeWord32FromWord(SloppyTNode<WordT> word) {
    return UncheckedCast<Uint32T>(
        TruncateIntPtrToInt32(Signed(DecodeWord<BitField>(word))));
  }

  // Decodes an unsigned (!) value from |word32| to an uint32 node.
  TNode<Uint32T> DecodeWord32(TNode<Word32T> word32, uint32_t shift,
                              uint32_t mask);

  // Decodes an unsigned (!) value from |word| to a word-size node.
  TNode<UintPtrT> DecodeWord(SloppyTNode<WordT> word, uint32_t shift,
                             uintptr_t mask);

  // Returns a node that contains the updated values of a |BitField|.
  template <typename BitField>
  TNode<Word32T> UpdateWord32(TNode<Word32T> word, TNode<Uint32T> value,
                              bool starts_as_zero = false) {
    return UpdateWord32(word, value, BitField::kShift, BitField::kMask,
                        starts_as_zero);
  }

  // Returns a node that contains the updated values of a |BitField|.
  template <typename BitField>
  TNode<WordT> UpdateWord(TNode<WordT> word, TNode<UintPtrT> value,
                          bool starts_as_zero = false) {
    return UpdateWord(word, value, BitField::kShift, BitField::kMask,
                      starts_as_zero);
  }

  // Returns a node that contains the updated values of a |BitField|.
  template <typename BitField>
  TNode<Word32T> UpdateWordInWord32(TNode<Word32T> word, TNode<UintPtrT> value,
                                    bool starts_as_zero = false) {
    return UncheckedCast<Uint32T>(
        TruncateIntPtrToInt32(Signed(UpdateWord<BitField>(
            ChangeUint32ToWord(word), value, starts_as_zero))));
  }

  // Returns a node that contains the updated values of a |BitField|.
  template <typename BitField>
  TNode<WordT> UpdateWord32InWord(TNode<WordT> word, TNode<Uint32T> value,
                                  bool starts_as_zero = false) {
    return UpdateWord<BitField>(word, ChangeUint32ToWord(value),
                                starts_as_zero);
  }

  // Returns a node that contains the updated {value} inside {word} starting
  // at {shift} and fitting in {mask}.
  TNode<Word32T> UpdateWord32(TNode<Word32T> word, TNode<Uint32T> value,
                              uint32_t shift, uint32_t mask,
                              bool starts_as_zero = false);

  // Returns a node that contains the updated {value} inside {word} starting
  // at {shift} and fitting in {mask}.
  TNode<WordT> UpdateWord(TNode<WordT> word, TNode<UintPtrT> value,
                          uint32_t shift, uintptr_t mask,
                          bool starts_as_zero = false);

  // Returns true if any of the |T|'s bits in given |word32| are set.
  template <typename T>
  TNode<BoolT> IsSetWord32(TNode<Word32T> word32) {
    return IsSetWord32(word32, T::kMask);
  }

  // Returns true if any of the mask's bits in given |word32| are set.
  TNode<BoolT> IsSetWord32(TNode<Word32T> word32, uint32_t mask) {
    return Word32NotEqual(Word32And(word32, Int32Constant(mask)),
                          Int32Constant(0));
  }

  // Returns true if none of the mask's bits in given |word32| are set.
  TNode<BoolT> IsNotSetWord32(TNode<Word32T> word32, uint32_t mask) {
    return Word32Equal(Word32And(word32, Int32Constant(mask)),
                       Int32Constant(0));
  }

  // Returns true if all of the mask's bits in a given |word32| are set.
  TNode<BoolT> IsAllSetWord32(TNode<Word32T> word32, uint32_t mask) {
    TNode<Int32T> const_mask = Int32Constant(mask);
    return Word32Equal(Word32And(word32, const_mask), const_mask);
  }

  // Returns true if the bit field |BitField| in |word32| is equal to a given.
  // constant |value|. Avoids a shift compared to using DecodeWord32.
  template <typename BitField>
  TNode<BoolT> IsEqualInWord32(TNode<Word32T> word32,
                               typename BitField::FieldType value) {
    TNode<Word32T> masked_word32 =
        Word32And(word32, Int32Constant(BitField::kMask));
    return Word32Equal(masked_word32, Int32Constant(BitField::encode(value)));
  }

  // Returns true if any of the |T|'s bits in given |word| are set.
  template <typename T>
  TNode<BoolT> IsSetWord(SloppyTNode<WordT> word) {
    return IsSetWord(word, T::kMask);
  }

  // Returns true if any of the mask's bits in given |word| are set.
  TNode<BoolT> IsSetWord(SloppyTNode<WordT> word, uint32_t mask) {
    return WordNotEqual(WordAnd(word, IntPtrConstant(mask)), IntPtrConstant(0));
  }

  // Returns true if any of the mask's bit are set in the given Smi.
  // Smi-encoding of the mask is performed implicitly!
  TNode<BoolT> IsSetSmi(SloppyTNode<Smi> smi, int untagged_mask) {
    intptr_t mask_word = bit_cast<intptr_t>(Smi::FromInt(untagged_mask));
    return WordNotEqual(WordAnd(BitcastTaggedToWordForTagAndSmiBits(smi),
                                IntPtrConstant(mask_word)),
                        IntPtrConstant(0));
  }

  // Returns true if all of the |T|'s bits in given |word32| are clear.
  template <typename T>
  TNode<BoolT> IsClearWord32(TNode<Word32T> word32) {
    return IsClearWord32(word32, T::kMask);
  }

  // Returns true if all of the mask's bits in given |word32| are clear.
  TNode<BoolT> IsClearWord32(TNode<Word32T> word32, uint32_t mask) {
    return Word32Equal(Word32And(word32, Int32Constant(mask)),
                       Int32Constant(0));
  }

  // Returns true if all of the |T|'s bits in given |word| are clear.
  template <typename T>
  TNode<BoolT> IsClearWord(SloppyTNode<WordT> word) {
    return IsClearWord(word, T::kMask);
  }

  // Returns true if all of the mask's bits in given |word| are clear.
  TNode<BoolT> IsClearWord(SloppyTNode<WordT> word, uint32_t mask) {
    return IntPtrEqual(WordAnd(word, IntPtrConstant(mask)), IntPtrConstant(0));
  }

  void SetCounter(StatsCounter* counter, int value);
  void IncrementCounter(StatsCounter* counter, int delta);
  void DecrementCounter(StatsCounter* counter, int delta);

  template <typename TIndex>
  void Increment(TVariable<TIndex>* variable, int value = 1);

  template <typename TIndex>
  void Decrement(TVariable<TIndex>* variable, int value = 1) {
    Increment(variable, -value);
  }

  // Generates "if (false) goto label" code. Useful for marking a label as
  // "live" to avoid assertion failures during graph building. In the resulting
  // code this check will be eliminated.
  void Use(Label* label);

  // Various building blocks for stubs doing property lookups.

  // |if_notinternalized| is optional; |if_bailout| will be used by default.
  // Note: If |key| does not yet have a hash, |if_notinternalized| will be taken
  // even if |key| is an array index. |if_keyisunique| will never
  // be taken for array indices.
  void TryToName(SloppyTNode<Object> key, Label* if_keyisindex,
                 TVariable<IntPtrT>* var_index, Label* if_keyisunique,
                 TVariable<Name>* var_unique, Label* if_bailout,
                 Label* if_notinternalized = nullptr);

  // Performs a hash computation and string table lookup for the given string,
  // and jumps to:
  // - |if_index| if the string is an array index like "123"; |var_index|
  //              will contain the intptr representation of that index.
  // - |if_internalized| if the string exists in the string table; the
  //                     internalized version will be in |var_internalized|.
  // - |if_not_internalized| if the string is not in the string table (but
  //                         does not add it).
  // - |if_bailout| for unsupported cases (e.g. uncachable array index).
  void TryInternalizeString(TNode<String> string, Label* if_index,
                            TVariable<IntPtrT>* var_index,
                            Label* if_internalized,
                            TVariable<Name>* var_internalized,
                            Label* if_not_internalized, Label* if_bailout);

  // Calculates array index for given dictionary entry and entry field.
  // See Dictionary::EntryToIndex().
  template <typename Dictionary>
  TNode<IntPtrT> EntryToIndex(TNode<IntPtrT> entry, int field_index);
  template <typename Dictionary>
  TNode<IntPtrT> EntryToIndex(TNode<IntPtrT> entry) {
    return EntryToIndex<Dictionary>(entry, Dictionary::kEntryKeyIndex);
  }

  // Loads the details for the entry with the given key_index.
  // Returns an untagged int32.
  template <class ContainerType>
  TNode<Uint32T> LoadDetailsByKeyIndex(TNode<ContainerType> container,
                                       TNode<IntPtrT> key_index) {
    static_assert(!std::is_same<ContainerType, DescriptorArray>::value,
                  "Use the non-templatized version for DescriptorArray");
    const int kKeyToDetailsOffset =
        (ContainerType::kEntryDetailsIndex - ContainerType::kEntryKeyIndex) *
        kTaggedSize;
    return Unsigned(LoadAndUntagToWord32FixedArrayElement(container, key_index,
                                                          kKeyToDetailsOffset));
  }

  // Loads the value for the entry with the given key_index.
  // Returns a tagged value.
  template <class ContainerType>
  TNode<Object> LoadValueByKeyIndex(TNode<ContainerType> container,
                                    TNode<IntPtrT> key_index) {
    static_assert(!std::is_same<ContainerType, DescriptorArray>::value,
                  "Use the non-templatized version for DescriptorArray");
    const int kKeyToValueOffset =
        (ContainerType::kEntryValueIndex - ContainerType::kEntryKeyIndex) *
        kTaggedSize;
    return LoadFixedArrayElement(container, key_index, kKeyToValueOffset);
  }

  // Stores the details for the entry with the given key_index.
  // |details| must be a Smi.
  template <class ContainerType>
  void StoreDetailsByKeyIndex(TNode<ContainerType> container,
                              TNode<IntPtrT> key_index, TNode<Smi> details) {
    const int kKeyToDetailsOffset =
        (ContainerType::kEntryDetailsIndex - ContainerType::kEntryKeyIndex) *
        kTaggedSize;
    StoreFixedArrayElement(container, key_index, details, SKIP_WRITE_BARRIER,
                           kKeyToDetailsOffset);
  }

  // Stores the value for the entry with the given key_index.
  template <class ContainerType>
  void StoreValueByKeyIndex(
      TNode<ContainerType> container, TNode<IntPtrT> key_index,
      TNode<Object> value,
      WriteBarrierMode write_barrier = UPDATE_WRITE_BARRIER) {
    const int kKeyToValueOffset =
        (ContainerType::kEntryValueIndex - ContainerType::kEntryKeyIndex) *
        kTaggedSize;
    StoreFixedArrayElement(container, key_index, value, write_barrier,
                           kKeyToValueOffset);
  }

  // Calculate a valid size for the a hash table.
  TNode<IntPtrT> HashTableComputeCapacity(TNode<IntPtrT> at_least_space_for);

  template <class Dictionary>
  TNode<Smi> GetNumberOfElements(TNode<Dictionary> dictionary) {
    return CAST(
        LoadFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex));
  }

  TNode<Smi> GetNumberDictionaryNumberOfElements(
      TNode<NumberDictionary> dictionary) {
    return GetNumberOfElements<NumberDictionary>(dictionary);
  }

  template <class Dictionary>
  void SetNumberOfElements(TNode<Dictionary> dictionary,
                           TNode<Smi> num_elements_smi) {
    StoreFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex,
                           num_elements_smi, SKIP_WRITE_BARRIER);
  }

  template <class Dictionary>
  TNode<Smi> GetNumberOfDeletedElements(TNode<Dictionary> dictionary) {
    return CAST(LoadFixedArrayElement(
        dictionary, Dictionary::kNumberOfDeletedElementsIndex));
  }

  template <class Dictionary>
  void SetNumberOfDeletedElements(TNode<Dictionary> dictionary,
                                  TNode<Smi> num_deleted_smi) {
    StoreFixedArrayElement(dictionary,
                           Dictionary::kNumberOfDeletedElementsIndex,
                           num_deleted_smi, SKIP_WRITE_BARRIER);
  }

  template <class Dictionary>
  TNode<Smi> GetCapacity(TNode<Dictionary> dictionary) {
    return CAST(
        UnsafeLoadFixedArrayElement(dictionary, Dictionary::kCapacityIndex));
  }

  template <class Dictionary>
  TNode<Smi> GetNextEnumerationIndex(TNode<Dictionary> dictionary) {
    return CAST(LoadFixedArrayElement(dictionary,
                                      Dictionary::kNextEnumerationIndexIndex));
  }

  template <class Dictionary>
  void SetNextEnumerationIndex(TNode<Dictionary> dictionary,
                               TNode<Smi> next_enum_index_smi) {
    StoreFixedArrayElement(dictionary, Dictionary::kNextEnumerationIndexIndex,
                           next_enum_index_smi, SKIP_WRITE_BARRIER);
  }

  // Looks up an entry in a NameDictionaryBase successor. If the entry is found
  // control goes to {if_found} and {var_name_index} contains an index of the
  // key field of the entry found. If the key is not found control goes to
  // {if_not_found}.
  enum LookupMode { kFindExisting, kFindInsertionIndex };

  template <typename Dictionary>
  TNode<HeapObject> LoadName(TNode<HeapObject> key);

  template <typename Dictionary>
  void NameDictionaryLookup(TNode<Dictionary> dictionary,
                            TNode<Name> unique_name, Label* if_found,
                            TVariable<IntPtrT>* var_name_index,
                            Label* if_not_found,
                            LookupMode mode = kFindExisting);

  TNode<Word32T> ComputeSeededHash(TNode<IntPtrT> key);

  void NumberDictionaryLookup(TNode<NumberDictionary> dictionary,
                              TNode<IntPtrT> intptr_index, Label* if_found,
                              TVariable<IntPtrT>* var_entry,
                              Label* if_not_found);

  TNode<Object> BasicLoadNumberDictionaryElement(
      TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index,
      Label* not_data, Label* if_hole);

  template <class Dictionary>
  void FindInsertionEntry(TNode<Dictionary> dictionary, TNode<Name> key,
                          TVariable<IntPtrT>* var_key_index);

  template <class Dictionary>
  void InsertEntry(TNode<Dictionary> dictionary, TNode<Name> key,
                   TNode<Object> value, TNode<IntPtrT> index,
                   TNode<Smi> enum_index);

  template <class Dictionary>
  void Add(TNode<Dictionary> dictionary, TNode<Name> key, TNode<Object> value,
           Label* bailout);

  // Tries to check if {object} has own {unique_name} property.
  void TryHasOwnProperty(TNode<HeapObject> object, TNode<Map> map,
                         TNode<Int32T> instance_type, TNode<Name> unique_name,
                         Label* if_found, Label* if_not_found,
                         Label* if_bailout);

  // Operating mode for TryGetOwnProperty and CallGetterIfAccessor
  // kReturnAccessorPair is used when we're only getting the property descriptor
  enum GetOwnPropertyMode { kCallJSGetter, kReturnAccessorPair };
  // Tries to get {object}'s own {unique_name} property value. If the property
  // is an accessor then it also calls a getter. If the property is a double
  // field it re-wraps value in an immutable heap number. {unique_name} must be
  // a unique name (Symbol or InternalizedString) that is not an array index.
  void TryGetOwnProperty(TNode<Context> context, TNode<Object> receiver,
                         TNode<JSReceiver> object, TNode<Map> map,
                         TNode<Int32T> instance_type, TNode<Name> unique_name,
                         Label* if_found_value, TVariable<Object>* var_value,
                         Label* if_not_found, Label* if_bailout);
  void TryGetOwnProperty(TNode<Context> context, TNode<Object> receiver,
                         TNode<JSReceiver> object, TNode<Map> map,
                         TNode<Int32T> instance_type, TNode<Name> unique_name,
                         Label* if_found_value, TVariable<Object>* var_value,
                         TVariable<Uint32T>* var_details,
                         TVariable<Object>* var_raw_value, Label* if_not_found,
                         Label* if_bailout, GetOwnPropertyMode mode);

  TNode<Object> GetProperty(TNode<Context> context,
                            SloppyTNode<Object> receiver, Handle<Name> name) {
    return GetProperty(context, receiver, HeapConstant(name));
  }

  TNode<Object> GetProperty(TNode<Context> context,
                            SloppyTNode<Object> receiver,
                            SloppyTNode<Object> name) {
    return CallBuiltin(Builtins::kGetProperty, context, receiver, name);
  }

  TNode<Object> SetPropertyStrict(TNode<Context> context,
                                  TNode<Object> receiver, TNode<Object> key,
                                  TNode<Object> value) {
    return CallBuiltin(Builtins::kSetProperty, context, receiver, key, value);
  }

  TNode<Object> SetPropertyInLiteral(TNode<Context> context,
                                     TNode<JSObject> receiver,
                                     TNode<Object> key, TNode<Object> value) {
    return CallBuiltin(Builtins::kSetPropertyInLiteral, context, receiver, key,
                       value);
  }

  TNode<Object> GetMethod(TNode<Context> context, TNode<Object> object,
                          Handle<Name> name, Label* if_null_or_undefined);

  TNode<Object> GetIteratorMethod(TNode<Context> context,
                                  TNode<HeapObject> heap_obj,
                                  Label* if_iteratorundefined);

  template <class... TArgs>
  TNode<Object> CallBuiltin(Builtins::Name id, SloppyTNode<Object> context,
                            TArgs... args) {
    return CallStub<Object>(Builtins::CallableFor(isolate(), id), context,
                            args...);
  }

  template <class... TArgs>
  void TailCallBuiltin(Builtins::Name id, SloppyTNode<Object> context,
                       TArgs... args) {
    return TailCallStub(Builtins::CallableFor(isolate(), id), context, args...);
  }

  void LoadPropertyFromFastObject(TNode<HeapObject> object, TNode<Map> map,
                                  TNode<DescriptorArray> descriptors,
                                  TNode<IntPtrT> name_index,
                                  TVariable<Uint32T>* var_details,
                                  TVariable<Object>* var_value);

  void LoadPropertyFromFastObject(TNode<HeapObject> object, TNode<Map> map,
                                  TNode<DescriptorArray> descriptors,
                                  TNode<IntPtrT> name_index, TNode<Uint32T>,
                                  TVariable<Object>* var_value);

  void LoadPropertyFromNameDictionary(TNode<NameDictionary> dictionary,
                                      TNode<IntPtrT> name_index,
                                      TVariable<Uint32T>* var_details,
                                      TVariable<Object>* var_value);
  void LoadPropertyFromGlobalDictionary(TNode<GlobalDictionary> dictionary,
                                        TNode<IntPtrT> name_index,
                                        TVariable<Uint32T>* var_details,
                                        TVariable<Object>* var_value,
                                        Label* if_deleted);

  // Generic property lookup generator. If the {object} is fast and
  // {unique_name} property is found then the control goes to {if_found_fast}
  // label and {var_meta_storage} and {var_name_index} will contain
  // DescriptorArray and an index of the descriptor's name respectively.
  // If the {object} is slow or global then the control goes to {if_found_dict}
  // or {if_found_global} and the {var_meta_storage} and {var_name_index} will
  // contain a dictionary and an index of the key field of the found entry.
  // If property is not found or given lookup is not supported then
  // the control goes to {if_not_found} or {if_bailout} respectively.
  //
  // Note: this code does not check if the global dictionary points to deleted
  // entry! This has to be done by the caller.
  void TryLookupProperty(TNode<HeapObject> object, TNode<Map> map,
                         SloppyTNode<Int32T> instance_type,
                         TNode<Name> unique_name, Label* if_found_fast,
                         Label* if_found_dict, Label* if_found_global,
                         TVariable<HeapObject>* var_meta_storage,
                         TVariable<IntPtrT>* var_name_index,
                         Label* if_not_found, Label* if_bailout);

  // This is a building block for TryLookupProperty() above. Supports only
  // non-special fast and dictionary objects.
  void TryLookupPropertyInSimpleObject(TNode<JSObject> object, TNode<Map> map,
                                       TNode<Name> unique_name,
                                       Label* if_found_fast,
                                       Label* if_found_dict,
                                       TVariable<HeapObject>* var_meta_storage,
                                       TVariable<IntPtrT>* var_name_index,
                                       Label* if_not_found);

  // This method jumps to if_found if the element is known to exist. To
  // if_absent if it's known to not exist. To if_not_found if the prototype
  // chain needs to be checked. And if_bailout if the lookup is unsupported.
  void TryLookupElement(TNode<HeapObject> object, TNode<Map> map,
                        SloppyTNode<Int32T> instance_type,
                        SloppyTNode<IntPtrT> intptr_index, Label* if_found,
                        Label* if_absent, Label* if_not_found,
                        Label* if_bailout);

  // For integer indexed exotic cases, check if the given string cannot be a
  // special index. If we are not sure that the given string is not a special
  // index with a simple check, return False. Note that "False" return value
  // does not mean that the name_string is a special index in the current
  // implementation.
  void BranchIfMaybeSpecialIndex(TNode<String> name_string,
                                 Label* if_maybe_special_index,
                                 Label* if_not_special_index);

  // This is a type of a lookup property in holder generator function. The {key}
  // is guaranteed to be an unique name.
  using LookupPropertyInHolder = std::function<void(
      TNode<HeapObject> receiver, TNode<HeapObject> holder, TNode<Map> map,
      TNode<Int32T> instance_type, TNode<Name> key, Label* next_holder,
      Label* if_bailout)>;

  // This is a type of a lookup element in holder generator function. The {key}
  // is an Int32 index.
  using LookupElementInHolder = std::function<void(
      TNode<HeapObject> receiver, TNode<HeapObject> holder, TNode<Map> map,
      TNode<Int32T> instance_type, TNode<IntPtrT> key, Label* next_holder,
      Label* if_bailout)>;

  // Generic property prototype chain lookup generator.
  // For properties it generates lookup using given {lookup_property_in_holder}
  // and for elements it uses {lookup_element_in_holder}.
  // Upon reaching the end of prototype chain the control goes to {if_end}.
  // If it can't handle the case {receiver}/{key} case then the control goes
  // to {if_bailout}.
  // If {if_proxy} is nullptr, proxies go to if_bailout.
  void TryPrototypeChainLookup(
      TNode<Object> receiver, TNode<Object> object, TNode<Object> key,
      const LookupPropertyInHolder& lookup_property_in_holder,
      const LookupElementInHolder& lookup_element_in_holder, Label* if_end,
      Label* if_bailout, Label* if_proxy);

  // Instanceof helpers.
  // Returns true if {object} has {prototype} somewhere in it's prototype
  // chain, otherwise false is returned. Might cause arbitrary side effects
  // due to [[GetPrototypeOf]] invocations.
  TNode<Oddball> HasInPrototypeChain(TNode<Context> context,
                                     TNode<HeapObject> object,
                                     TNode<Object> prototype);
  // ES6 section 7.3.19 OrdinaryHasInstance (C, O)
  TNode<Oddball> OrdinaryHasInstance(TNode<Context> context,
                                     TNode<Object> callable,
                                     TNode<Object> object);

  // Load type feedback vector from the stub caller's frame.
  TNode<FeedbackVector> LoadFeedbackVectorForStub();

  // Load the value from closure's feedback cell.
  TNode<HeapObject> LoadFeedbackCellValue(TNode<JSFunction> closure);

  // Load the object from feedback vector cell for the given closure.
  // The returned object could be undefined if the closure does not have
  // a feedback vector associated with it.
  TNode<HeapObject> LoadFeedbackVector(TNode<JSFunction> closure);

  // Load the ClosureFeedbackCellArray that contains the feedback cells
  // used when creating closures from this function. This array could be
  // directly hanging off the FeedbackCell when there is no feedback vector
  // or available from the feedback vector's header.
  TNode<ClosureFeedbackCellArray> LoadClosureFeedbackArray(
      TNode<JSFunction> closure);

  // Update the type feedback vector.
  void UpdateFeedback(TNode<Smi> feedback,
                      TNode<HeapObject> maybe_feedback_vector,
                      TNode<UintPtrT> slot_id);

  // Report that there was a feedback update, performing any tasks that should
  // be done after a feedback update.
  void ReportFeedbackUpdate(TNode<FeedbackVector> feedback_vector,
                            SloppyTNode<UintPtrT> slot_id, const char* reason);

  // Combine the new feedback with the existing_feedback. Do nothing if
  // existing_feedback is nullptr.
  void CombineFeedback(TVariable<Smi>* existing_feedback, int feedback);
  void CombineFeedback(TVariable<Smi>* existing_feedback, TNode<Smi> feedback);

  // Overwrite the existing feedback with new_feedback. Do nothing if
  // existing_feedback is nullptr.
  void OverwriteFeedback(TVariable<Smi>* existing_feedback, int new_feedback);

  // Check if a property name might require protector invalidation when it is
  // used for a property store or deletion.
  void CheckForAssociatedProtector(TNode<Name> name, Label* if_protector);

  TNode<Map> LoadReceiverMap(SloppyTNode<Object> receiver);

  // Loads script context from the script context table.
  TNode<Context> LoadScriptContext(TNode<Context> context,
                                   TNode<IntPtrT> context_index);

  TNode<Uint8T> Int32ToUint8Clamped(TNode<Int32T> int32_value);
  TNode<Uint8T> Float64ToUint8Clamped(TNode<Float64T> float64_value);

  Node* PrepareValueForWriteToTypedArray(TNode<Object> input,
                                         ElementsKind elements_kind,
                                         TNode<Context> context);

  template <typename T>
  TNode<T> PrepareValueForWriteToTypedArray(TNode<Object> input,
                                            ElementsKind elements_kind,
                                            TNode<Context> context);

  // Store value to an elements array with given elements kind.
  // TODO(turbofan): For BIGINT64_ELEMENTS and BIGUINT64_ELEMENTS
  // we pass {value} as BigInt object instead of int64_t. We should
  // teach TurboFan to handle int64_t on 32-bit platforms eventually.
  template <typename TIndex>
  void StoreElement(TNode<RawPtrT> elements, ElementsKind kind,
                    TNode<TIndex> index, Node* value);

  // Implements the BigInt part of
  // https://tc39.github.io/proposal-bigint/#sec-numbertorawbytes,
  // including truncation to 64 bits (i.e. modulo 2^64).
  // {var_high} is only used on 32-bit platforms.
  void BigIntToRawBytes(TNode<BigInt> bigint, TVariable<UintPtrT>* var_low,
                        TVariable<UintPtrT>* var_high);

  void EmitElementStore(TNode<JSObject> object, TNode<Object> key,
                        TNode<Object> value, ElementsKind elements_kind,
                        KeyedAccessStoreMode store_mode, Label* bailout,
                        TNode<Context> context,
                        TVariable<Object>* maybe_converted_value = nullptr);

  TNode<FixedArrayBase> CheckForCapacityGrow(
      TNode<JSObject> object, TNode<FixedArrayBase> elements, ElementsKind kind,
      TNode<UintPtrT> length, TNode<IntPtrT> key, Label* bailout);

  TNode<FixedArrayBase> CopyElementsOnWrite(TNode<HeapObject> object,
                                            TNode<FixedArrayBase> elements,
                                            ElementsKind kind,
                                            TNode<IntPtrT> length,
                                            Label* bailout);

  void TransitionElementsKind(TNode<JSObject> object, TNode<Map> map,
                              ElementsKind from_kind, ElementsKind to_kind,
                              Label* bailout);

  void TrapAllocationMemento(TNode<JSObject> object, Label* memento_found);

  TNode<IntPtrT> PageFromAddress(TNode<IntPtrT> address);

  // Store a weak in-place reference into the FeedbackVector.
  TNode<MaybeObject> StoreWeakReferenceInFeedbackVector(
      TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot,
      TNode<HeapObject> value, int additional_offset = 0);

  // Create a new AllocationSite and install it into a feedback vector.
  TNode<AllocationSite> CreateAllocationSiteInFeedbackVector(
      TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot);

  TNode<BoolT> HasBoilerplate(TNode<Object> maybe_literal_site);
  TNode<Smi> LoadTransitionInfo(TNode<AllocationSite> allocation_site);
  TNode<JSObject> LoadBoilerplate(TNode<AllocationSite> allocation_site);
  TNode<Int32T> LoadElementsKind(TNode<AllocationSite> allocation_site);

  enum class IndexAdvanceMode { kPre, kPost };

  template <typename TIndex>
  using FastLoopBody = std::function<void(TNode<TIndex> index)>;

  template <typename TIndex>
  TNode<TIndex> BuildFastLoop(
      const VariableList& var_list, TNode<TIndex> start_index,
      TNode<TIndex> end_index, const FastLoopBody<TIndex>& body, int increment,
      IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre);

  template <typename TIndex>
  TNode<TIndex> BuildFastLoop(
      TNode<TIndex> start_index, TNode<TIndex> end_index,
      const FastLoopBody<TIndex>& body, int increment,
      IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre) {
    return BuildFastLoop(VariableList(0, zone()), start_index, end_index, body,
                         increment, advance_mode);
  }

  enum class ForEachDirection { kForward, kReverse };

  using FastArrayForEachBody =
      std::function<void(TNode<HeapObject> array, TNode<IntPtrT> offset)>;

  template <typename TIndex>
  void BuildFastArrayForEach(
      TNode<UnionT<UnionT<FixedArray, PropertyArray>, HeapObject>> array,
      ElementsKind kind, TNode<TIndex> first_element_inclusive,
      TNode<TIndex> last_element_exclusive, const FastArrayForEachBody& body,
      ForEachDirection direction = ForEachDirection::kReverse);

  template <typename TIndex>
  TNode<IntPtrT> GetArrayAllocationSize(TNode<TIndex> element_count,
                                        ElementsKind kind, int header_size) {
    return ElementOffsetFromIndex(element_count, kind, header_size);
  }

  template <typename TIndex>
  TNode<IntPtrT> GetFixedArrayAllocationSize(TNode<TIndex> element_count,
                                             ElementsKind kind) {
    return GetArrayAllocationSize(element_count, kind, FixedArray::kHeaderSize);
  }

  TNode<IntPtrT> GetPropertyArrayAllocationSize(TNode<IntPtrT> element_count) {
    return GetArrayAllocationSize(element_count, PACKED_ELEMENTS,
                                  PropertyArray::kHeaderSize);
  }

  template <typename TIndex>
  void GotoIfFixedArraySizeDoesntFitInNewSpace(TNode<TIndex> element_count,
                                               Label* doesnt_fit,
                                               int base_size);

  void InitializeFieldsWithRoot(TNode<HeapObject> object,
                                TNode<IntPtrT> start_offset,
                                TNode<IntPtrT> end_offset, RootIndex root);

  TNode<Oddball> RelationalComparison(
      Operation op, TNode<Object> left, TNode<Object> right,
      TNode<Context> context, TVariable<Smi>* var_type_feedback = nullptr);

  void BranchIfNumberRelationalComparison(Operation op, TNode<Number> left,
                                          TNode<Number> right, Label* if_true,
                                          Label* if_false);

  void BranchIfNumberEqual(TNode<Number> left, TNode<Number> right,
                           Label* if_true, Label* if_false) {
    BranchIfNumberRelationalComparison(Operation::kEqual, left, right, if_true,
                                       if_false);
  }

  void BranchIfNumberNotEqual(TNode<Number> left, TNode<Number> right,
                              Label* if_true, Label* if_false) {
    BranchIfNumberEqual(left, right, if_false, if_true);
  }

  void BranchIfNumberLessThan(TNode<Number> left, TNode<Number> right,
                              Label* if_true, Label* if_false) {
    BranchIfNumberRelationalComparison(Operation::kLessThan, left, right,
                                       if_true, if_false);
  }

  void BranchIfNumberLessThanOrEqual(TNode<Number> left, TNode<Number> right,
                                     Label* if_true, Label* if_false) {
    BranchIfNumberRelationalComparison(Operation::kLessThanOrEqual, left, right,
                                       if_true, if_false);
  }

  void BranchIfNumberGreaterThan(TNode<Number> left, TNode<Number> right,
                                 Label* if_true, Label* if_false) {
    BranchIfNumberRelationalComparison(Operation::kGreaterThan, left, right,
                                       if_true, if_false);
  }

  void BranchIfNumberGreaterThanOrEqual(TNode<Number> left, TNode<Number> right,
                                        Label* if_true, Label* if_false) {
    BranchIfNumberRelationalComparison(Operation::kGreaterThanOrEqual, left,
                                       right, if_true, if_false);
  }

  void BranchIfAccessorPair(TNode<Object> value, Label* if_accessor_pair,
                            Label* if_not_accessor_pair) {
    GotoIf(TaggedIsSmi(value), if_not_accessor_pair);
    Branch(IsAccessorPair(CAST(value)), if_accessor_pair, if_not_accessor_pair);
  }

  void GotoIfNumberGreaterThanOrEqual(TNode<Number> left, TNode<Number> right,
                                      Label* if_false);

  TNode<Oddball> Equal(SloppyTNode<Object> lhs, SloppyTNode<Object> rhs,
                       TNode<Context> context,
                       TVariable<Smi>* var_type_feedback = nullptr);

  TNode<Oddball> StrictEqual(SloppyTNode<Object> lhs, SloppyTNode<Object> rhs,
                             TVariable<Smi>* var_type_feedback = nullptr);

  // ECMA#sec-samevalue
  // Similar to StrictEqual except that NaNs are treated as equal and minus zero
  // differs from positive zero.
  enum class SameValueMode { kNumbersOnly, kFull };
  void BranchIfSameValue(SloppyTNode<Object> lhs, SloppyTNode<Object> rhs,
                         Label* if_true, Label* if_false,
                         SameValueMode mode = SameValueMode::kFull);
  // A part of BranchIfSameValue() that handles two double values.
  // Treats NaN == NaN and +0 != -0.
  void BranchIfSameNumberValue(TNode<Float64T> lhs_value,
                               TNode<Float64T> rhs_value, Label* if_true,
                               Label* if_false);

  enum HasPropertyLookupMode { kHasProperty, kForInHasProperty };

  TNode<Oddball> HasProperty(TNode<Context> context, SloppyTNode<Object> object,
                             SloppyTNode<Object> key,
                             HasPropertyLookupMode mode);

  // Due to naming conflict with the builtin function namespace.
  TNode<Oddball> HasProperty_Inline(TNode<Context> context,
                                    TNode<JSReceiver> object,
                                    TNode<Object> key) {
    return HasProperty(context, object, key,
                       HasPropertyLookupMode::kHasProperty);
  }

  void ForInPrepare(TNode<HeapObject> enumerator, TNode<UintPtrT> slot,
                    TNode<HeapObject> maybe_feedback_vector,
                    TNode<FixedArray>* cache_array_out,
                    TNode<Smi>* cache_length_out);
  // Returns {cache_array} and {cache_length} in a fixed array of length 2.
  // TODO(jgruber): Tuple2 would be a slightly better fit as the return type,
  // but FixedArray has better support and there are no effective drawbacks to
  // using it instead of Tuple2 in practice.
  TNode<FixedArray> ForInPrepareForTorque(
      TNode<HeapObject> enumerator, TNode<UintPtrT> slot,
      TNode<HeapObject> maybe_feedback_vector);

  TNode<String> Typeof(SloppyTNode<Object> value);

  TNode<HeapObject> GetSuperConstructor(TNode<JSFunction> active_function);

  TNode<JSReceiver> SpeciesConstructor(TNode<Context> context,
                                       SloppyTNode<Object> object,
                                       TNode<JSReceiver> default_constructor);

  TNode<Oddball> InstanceOf(TNode<Object> object, TNode<Object> callable,
                            TNode<Context> context);

  // Debug helpers
  TNode<BoolT> IsDebugActive();

  // JSArrayBuffer helpers
  TNode<RawPtrT> LoadJSArrayBufferBackingStorePtr(
      TNode<JSArrayBuffer> array_buffer);
  void ThrowIfArrayBufferIsDetached(TNode<Context> context,
                                    TNode<JSArrayBuffer> array_buffer,
                                    const char* method_name);

  // JSArrayBufferView helpers
  TNode<JSArrayBuffer> LoadJSArrayBufferViewBuffer(
      TNode<JSArrayBufferView> array_buffer_view);
  TNode<UintPtrT> LoadJSArrayBufferViewByteLength(
      TNode<JSArrayBufferView> array_buffer_view);
  TNode<UintPtrT> LoadJSArrayBufferViewByteOffset(
      TNode<JSArrayBufferView> array_buffer_view);
  void ThrowIfArrayBufferViewBufferIsDetached(
      TNode<Context> context, TNode<JSArrayBufferView> array_buffer_view,
      const char* method_name);

  // JSTypedArray helpers
  TNode<UintPtrT> LoadJSTypedArrayLength(TNode<JSTypedArray> typed_array);
  TNode<RawPtrT> LoadJSTypedArrayDataPtr(TNode<JSTypedArray> typed_array);
  TNode<JSArrayBuffer> GetTypedArrayBuffer(TNode<Context> context,
                                           TNode<JSTypedArray> array);

  template <typename TIndex>
  TNode<IntPtrT> ElementOffsetFromIndex(TNode<TIndex> index, ElementsKind kind,
                                        int base_size = 0);

  // Check that a field offset is within the bounds of the an object.
  TNode<BoolT> IsOffsetInBounds(SloppyTNode<IntPtrT> offset,
                                SloppyTNode<IntPtrT> length, int header_size,
                                ElementsKind kind = HOLEY_ELEMENTS);

  // Load a builtin's code from the builtin array in the isolate.
  TNode<Code> LoadBuiltin(TNode<Smi> builtin_id);

  // Figure out the SFI's code object using its data field.
  // If |if_compile_lazy| is provided then the execution will go to the given
  // label in case of an CompileLazy code object.
  TNode<Code> GetSharedFunctionInfoCode(TNode<SharedFunctionInfo> shared_info,
                                        Label* if_compile_lazy = nullptr);

  TNode<JSFunction> AllocateFunctionWithMapAndContext(
      TNode<Map> map, TNode<SharedFunctionInfo> shared_info,
      TNode<Context> context);

  // Promise helpers
  TNode<BoolT> IsPromiseHookEnabled();
  TNode<BoolT> HasAsyncEventDelegate();
  TNode<BoolT> IsPromiseHookEnabledOrHasAsyncEventDelegate();
  TNode<BoolT> IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate();

  // for..in helpers
  void CheckPrototypeEnumCache(TNode<JSReceiver> receiver,
                               TNode<Map> receiver_map, Label* if_fast,
                               Label* if_slow);
  TNode<Map> CheckEnumCache(TNode<JSReceiver> receiver, Label* if_empty,
                            Label* if_runtime);

  TNode<Object> GetArgumentValue(TorqueStructArguments args,
                                 TNode<IntPtrT> index);

  TorqueStructArguments GetFrameArguments(TNode<RawPtrT> frame,
                                          TNode<IntPtrT> argc);

  // Support for printf-style debugging
  void Print(const char* s);
  void Print(const char* prefix, TNode<MaybeObject> tagged_value);
  void Print(TNode<MaybeObject> tagged_value) {
    return Print(nullptr, tagged_value);
  }

  template <class... TArgs>
  TNode<HeapObject> MakeTypeError(MessageTemplate message,
                                  TNode<Context> context, TArgs... args) {
    STATIC_ASSERT(sizeof...(TArgs) <= 3);
    return CAST(CallRuntime(Runtime::kNewTypeError, context,
                            SmiConstant(message), args...));
  }

  void Abort(AbortReason reason) {
    CallRuntime(Runtime::kAbort, NoContextConstant(), SmiConstant(reason));
    Unreachable();
  }

  bool ConstexprBoolNot(bool value) { return !value; }

  bool ConstexprInt31Equal(int31_t a, int31_t b) { return a == b; }
  bool ConstexprInt31NotEqual(int31_t a, int31_t b) { return a != b; }
  bool ConstexprInt31GreaterThanEqual(int31_t a, int31_t b) { return a >= b; }
  bool ConstexprUint32Equal(uint32_t a, uint32_t b) { return a == b; }
  bool ConstexprUint32NotEqual(uint32_t a, uint32_t b) { return a != b; }
  bool ConstexprInt32Equal(int32_t a, int32_t b) { return a == b; }
  bool ConstexprInt32NotEqual(int32_t a, int32_t b) { return a != b; }
  bool ConstexprInt32GreaterThanEqual(int32_t a, int32_t b) { return a >= b; }
  uint32_t ConstexprUint32Add(uint32_t a, uint32_t b) { return a + b; }
  int32_t ConstexprUint32Sub(uint32_t a, uint32_t b) { return a - b; }
  int31_t ConstexprInt31Add(int31_t a, int31_t b) {
    int32_t val;
    CHECK(!base::bits::SignedAddOverflow32(a, b, &val));
    return val;
  }
  int31_t ConstexprInt31Mul(int31_t a, int31_t b) {
    int32_t val;
    CHECK(!base::bits::SignedMulOverflow32(a, b, &val));
    return val;
  }

  int32_t ConstexprWord32Or(int32_t a, int32_t b) { return a | b; }

  bool ConstexprUintPtrLessThan(uintptr_t a, uintptr_t b) { return a < b; }

  // CSA does not support 64-bit types on 32-bit platforms so as a workaround
  // the kMaxSafeIntegerUint64 is defined as uintptr and allowed to be used only
  // inside if constexpr (Is64()) i.e. on 64-bit architectures.
  static uintptr_t MaxSafeIntegerUintPtr() {
#if defined(V8_HOST_ARCH_64_BIT)
    // This ifdef is required to avoid build issues on 32-bit MSVC which
    // complains about static_cast<uintptr_t>(kMaxSafeIntegerUint64).
    return kMaxSafeIntegerUint64;
#else
    UNREACHABLE();
#endif
  }

  void PerformStackCheck(TNode<Context> context);

  void SetPropertyLength(TNode<Context> context, TNode<Object> array,
                         TNode<Number> length);

  // Implements DescriptorArray::Search().
  void DescriptorLookup(TNode<Name> unique_name,
                        TNode<DescriptorArray> descriptors,
                        TNode<Uint32T> bitfield3, Label* if_found,
                        TVariable<IntPtrT>* var_name_index,
                        Label* if_not_found);

  // Implements TransitionArray::SearchName() - searches for first transition
  // entry with given name (note that there could be multiple entries with
  // the same name).
  void TransitionLookup(TNode<Name> unique_name,
                        TNode<TransitionArray> transitions, Label* if_found,
                        TVariable<IntPtrT>* var_name_index,
                        Label* if_not_found);

  // Implements generic search procedure like i::Search<Array>().
  template <typename Array>
  void Lookup(TNode<Name> unique_name, TNode<Array> array,
              TNode<Uint32T> number_of_valid_entries, Label* if_found,
              TVariable<IntPtrT>* var_name_index, Label* if_not_found);

  // Implements generic linear search procedure like i::LinearSearch<Array>().
  template <typename Array>
  void LookupLinear(TNode<Name> unique_name, TNode<Array> array,
                    TNode<Uint32T> number_of_valid_entries, Label* if_found,
                    TVariable<IntPtrT>* var_name_index, Label* if_not_found);

  // Implements generic binary search procedure like i::BinarySearch<Array>().
  template <typename Array>
  void LookupBinary(TNode<Name> unique_name, TNode<Array> array,
                    TNode<Uint32T> number_of_valid_entries, Label* if_found,
                    TVariable<IntPtrT>* var_name_index, Label* if_not_found);

  // Converts [Descriptor/Transition]Array entry number to a fixed array index.
  template <typename Array>
  TNode<IntPtrT> EntryIndexToIndex(TNode<Uint32T> entry_index);

  // Implements [Descriptor/Transition]Array::ToKeyIndex.
  template <typename Array>
  TNode<IntPtrT> ToKeyIndex(TNode<Uint32T> entry_index);

  // Implements [Descriptor/Transition]Array::GetKey.
  template <typename Array>
  TNode<Name> GetKey(TNode<Array> array, TNode<Uint32T> entry_index);

  // Implements DescriptorArray::GetDetails.
  TNode<Uint32T> DescriptorArrayGetDetails(TNode<DescriptorArray> descriptors,
                                           TNode<Uint32T> descriptor_number);

  using ForEachDescriptorBodyFunction =
      std::function<void(TNode<IntPtrT> descriptor_key_index)>;

  // Descriptor array accessors based on key_index, which is equal to
  // DescriptorArray::ToKeyIndex(descriptor).
  TNode<Name> LoadKeyByKeyIndex(TNode<DescriptorArray> container,
                                TNode<IntPtrT> key_index);
  TNode<Uint32T> LoadDetailsByKeyIndex(TNode<DescriptorArray> container,
                                       TNode<IntPtrT> key_index);
  TNode<Object> LoadValueByKeyIndex(TNode<DescriptorArray> container,
                                    TNode<IntPtrT> key_index);
  TNode<MaybeObject> LoadFieldTypeByKeyIndex(TNode<DescriptorArray> container,
                                             TNode<IntPtrT> key_index);

  TNode<IntPtrT> DescriptorEntryToIndex(TNode<IntPtrT> descriptor);

  // Descriptor array accessors based on descriptor.
  TNode<Name> LoadKeyByDescriptorEntry(TNode<DescriptorArray> descriptors,
                                       TNode<IntPtrT> descriptor);
  TNode<Name> LoadKeyByDescriptorEntry(TNode<DescriptorArray> descriptors,
                                       int descriptor);
  TNode<Uint32T> LoadDetailsByDescriptorEntry(
      TNode<DescriptorArray> descriptors, TNode<IntPtrT> descriptor);
  TNode<Uint32T> LoadDetailsByDescriptorEntry(
      TNode<DescriptorArray> descriptors, int descriptor);
  TNode<Object> LoadValueByDescriptorEntry(TNode<DescriptorArray> descriptors,
                                           int descriptor);
  TNode<MaybeObject> LoadFieldTypeByDescriptorEntry(
      TNode<DescriptorArray> descriptors, TNode<IntPtrT> descriptor);

  using ForEachKeyValueFunction =
      std::function<void(TNode<Name> key, TNode<Object> value)>;

  enum ForEachEnumerationMode {
    // String and then Symbol properties according to the spec
    // ES#sec-object.assign
    kEnumerationOrder,
    // Order of property addition
    kPropertyAdditionOrder,
  };

  // For each JSObject property (in DescriptorArray order), check if the key is
  // enumerable, and if so, load the value from the receiver and evaluate the
  // closure.
  void ForEachEnumerableOwnProperty(TNode<Context> context, TNode<Map> map,
                                    TNode<JSObject> object,
                                    ForEachEnumerationMode mode,
                                    const ForEachKeyValueFunction& body,
                                    Label* bailout);

  TNode<Object> CallGetterIfAccessor(TNode<Object> value,
                                     TNode<HeapObject> holder,
                                     TNode<Uint32T> details,
                                     TNode<Context> context,
                                     TNode<Object> receiver, Label* if_bailout,
                                     GetOwnPropertyMode mode = kCallJSGetter);

  TNode<IntPtrT> TryToIntptr(SloppyTNode<Object> key, Label* if_not_intptr,
                             TVariable<Int32T>* var_instance_type = nullptr);

  TNode<JSArray> ArrayCreate(TNode<Context> context, TNode<Number> length);

  // Allocate a clone of a mutable primitive, if {object} is a mutable
  // HeapNumber.
  TNode<Object> CloneIfMutablePrimitive(TNode<Object> object);

  TNode<Smi> RefillMathRandom(TNode<NativeContext> native_context);

  void RemoveFinalizationRegistryCellFromUnregisterTokenMap(
      TNode<JSFinalizationRegistry> finalization_registry,
      TNode<WeakCell> weak_cell);

  TNode<IntPtrT> FeedbackIteratorSizeFor(int number_of_entries) {
    return IntPtrConstant(FeedbackIterator::SizeFor(number_of_entries));
  }

  TNode<IntPtrT> FeedbackIteratorMapIndexForEntry(int entry) {
    return IntPtrConstant(FeedbackIterator::MapIndexForEntry(entry));
  }

  TNode<IntPtrT> FeedbackIteratorHandlerIndexForEntry(int entry) {
    return IntPtrConstant(FeedbackIterator::HandlerIndexForEntry(entry));
  }

 private:
  friend class CodeStubArguments;

  void HandleBreakOnNode();

  TNode<HeapObject> AllocateRawDoubleAligned(TNode<IntPtrT> size_in_bytes,
                                             AllocationFlags flags,
                                             TNode<RawPtrT> top_address,
                                             TNode<RawPtrT> limit_address);
  TNode<HeapObject> AllocateRawUnaligned(TNode<IntPtrT> size_in_bytes,
                                         AllocationFlags flags,
                                         TNode<RawPtrT> top_address,
                                         TNode<RawPtrT> limit_address);
  TNode<HeapObject> AllocateRaw(TNode<IntPtrT> size_in_bytes,
                                AllocationFlags flags,
                                TNode<RawPtrT> top_address,
                                TNode<RawPtrT> limit_address);

  // Allocate and return a JSArray of given total size in bytes with header
  // fields initialized.
  TNode<JSArray> AllocateUninitializedJSArray(
      TNode<Map> array_map, TNode<Smi> length,
      base::Optional<TNode<AllocationSite>> allocation_site,
      TNode<IntPtrT> size_in_bytes);

  TNode<IntPtrT> SmiShiftBitsConstant() {
    return IntPtrConstant(kSmiShiftSize + kSmiTagSize);
  }
  TNode<Int32T> SmiShiftBitsConstant32() {
    return Int32Constant(kSmiShiftSize + kSmiTagSize);
  }

  TNode<String> AllocateSlicedString(RootIndex map_root_index,
                                     TNode<Uint32T> length,
                                     TNode<String> parent, TNode<Smi> offset);

  // Implements [Descriptor/Transition]Array::number_of_entries.
  template <typename Array>
  TNode<Uint32T> NumberOfEntries(TNode<Array> array);

  // Implements [Descriptor/Transition]Array::GetSortedKeyIndex.
  template <typename Array>
  TNode<Uint32T> GetSortedKeyIndex(TNode<Array> descriptors,
                                   TNode<Uint32T> entry_index);

  TNode<Smi> CollectFeedbackForString(SloppyTNode<Int32T> instance_type);
  void GenerateEqual_Same(SloppyTNode<Object> value, Label* if_equal,
                          Label* if_notequal,
                          TVariable<Smi>* var_type_feedback = nullptr);

  static const int kElementLoopUnrollThreshold = 8;

  // {convert_bigint} is only meaningful when {mode} == kToNumber.
  TNode<Numeric> NonNumberToNumberOrNumeric(
      TNode<Context> context, TNode<HeapObject> input, Object::Conversion mode,
      BigIntHandling bigint_handling = BigIntHandling::kThrow);

  void TaggedToNumeric(TNode<Context> context, TNode<Object> value,
                       TVariable<Numeric>* var_numeric,
                       TVariable<Smi>* var_feedback);

  template <Object::Conversion conversion>
  void TaggedToWord32OrBigIntImpl(TNode<Context> context, TNode<Object> value,
                                  Label* if_number,
                                  TVariable<Word32T>* var_word32,
                                  Label* if_bigint = nullptr,
                                  TVariable<BigInt>* var_maybe_bigint = nullptr,
                                  TVariable<Smi>* var_feedback = nullptr);

  // Low-level accessors for Descriptor arrays.
  template <typename T>
  TNode<T> LoadDescriptorArrayElement(TNode<DescriptorArray> object,
                                      TNode<IntPtrT> index,
                                      int additional_offset);

  // Hide LoadRoot for subclasses of CodeStubAssembler. If you get an error
  // complaining about this method, don't make it public, add your root to
  // HEAP_(IM)MUTABLE_IMMOVABLE_OBJECT_LIST instead. If you *really* need
  // LoadRoot, use CodeAssembler::LoadRoot.
  TNode<Object> LoadRoot(RootIndex root_index) {
    return CodeAssembler::LoadRoot(root_index);
  }

  template <typename TIndex>
  void StoreFixedArrayOrPropertyArrayElement(
      TNode<UnionT<FixedArray, PropertyArray>> array, TNode<TIndex> index,
      TNode<Object> value, WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
      int additional_offset = 0);

  // Store value to an elements array with given elements kind.
  // TODO(turbofan): For BIGINT64_ELEMENTS and BIGUINT64_ELEMENTS
  // we pass {value} as BigInt object instead of int64_t. We should
  // teach TurboFan to handle int64_t on 32-bit platforms eventually.
  // TODO(solanes): This method can go away and simplify into only one version
  // of StoreElement once we have "if constexpr" available to use.
  template <typename TArray, typename TIndex>
  void StoreElementBigIntOrTypedArray(TNode<TArray> elements, ElementsKind kind,
                                      TNode<TIndex> index, Node* value);

  template <typename TIndex>
  void StoreElement(TNode<FixedArrayBase> elements, ElementsKind kind,
                    TNode<TIndex> index, Node* value);

  // Converts {input} to a number if {input} is a plain primitve (i.e. String or
  // Oddball) and stores the result in {var_result}. Otherwise, it bails out to
  // {if_bailout}.
  void TryPlainPrimitiveNonNumberToNumber(TNode<HeapObject> input,
                                          TVariable<Number>* var_result,
                                          Label* if_bailout);
};

class V8_EXPORT_PRIVATE CodeStubArguments {
 public:
  using Node = compiler::Node;

  // |argc| specifies the number of arguments passed to the builtin excluding
  // the receiver. The arguments include the receiver.
  CodeStubArguments(CodeStubAssembler* assembler, TNode<IntPtrT> argc)
      : CodeStubArguments(assembler, argc, TNode<RawPtrT>()) {}
  CodeStubArguments(CodeStubAssembler* assembler, TNode<Int32T> argc)
      : CodeStubArguments(assembler, assembler->ChangeInt32ToIntPtr(argc)) {}
  CodeStubArguments(CodeStubAssembler* assembler, TNode<IntPtrT> argc,
                    TNode<RawPtrT> fp);

  // Used by Torque to construct arguments based on a Torque-defined
  // struct of values.
  CodeStubArguments(CodeStubAssembler* assembler,
                    TorqueStructArguments torque_arguments)
      : assembler_(assembler),
        argc_(torque_arguments.length),
        base_(torque_arguments.base),
        fp_(torque_arguments.frame) {}

  TNode<Object> GetReceiver() const;
  // Replaces receiver argument on the expression stack. Should be used only
  // for manipulating arguments in trampoline builtins before tail calling
  // further with passing all the JS arguments as is.
  void SetReceiver(TNode<Object> object) const;

  // Computes address of the index'th argument.
  TNode<RawPtrT> AtIndexPtr(TNode<IntPtrT> index) const;

  // |index| is zero-based and does not include the receiver
  TNode<Object> AtIndex(TNode<IntPtrT> index) const;
  TNode<Object> AtIndex(int index) const;

  TNode<IntPtrT> GetLength() const { return argc_; }

  TorqueStructArguments GetTorqueArguments() const {
    return TorqueStructArguments{fp_, base_, argc_};
  }

  TNode<Object> GetOptionalArgumentValue(TNode<IntPtrT> index,
                                         TNode<Object> default_value);
  TNode<Object> GetOptionalArgumentValue(TNode<IntPtrT> index) {
    return GetOptionalArgumentValue(index, assembler_->UndefinedConstant());
  }
  TNode<Object> GetOptionalArgumentValue(int index) {
    return GetOptionalArgumentValue(assembler_->IntPtrConstant(index));
  }

  // Iteration doesn't include the receiver. |first| and |last| are zero-based.
  using ForEachBodyFunction = std::function<void(TNode<Object> arg)>;
  void ForEach(const ForEachBodyFunction& body, TNode<IntPtrT> first = {},
               TNode<IntPtrT> last = {}) const {
    CodeStubAssembler::VariableList list(0, assembler_->zone());
    ForEach(list, body, first, last);
  }
  void ForEach(const CodeStubAssembler::VariableList& vars,
               const ForEachBodyFunction& body, TNode<IntPtrT> first = {},
               TNode<IntPtrT> last = {}) const;

  void PopAndReturn(TNode<Object> value);

 private:
  CodeStubAssembler* assembler_;
  TNode<IntPtrT> argc_;
  TNode<RawPtrT> base_;
  TNode<RawPtrT> fp_;
};

class ToDirectStringAssembler : public CodeStubAssembler {
 private:
  enum StringPointerKind { PTR_TO_DATA, PTR_TO_STRING };

 public:
  enum Flag {
    kDontUnpackSlicedStrings = 1 << 0,
  };
  using Flags = base::Flags<Flag>;

  ToDirectStringAssembler(compiler::CodeAssemblerState* state,
                          TNode<String> string, Flags flags = Flags());

  // Converts flat cons, thin, and sliced strings and returns the direct
  // string. The result can be either a sequential or external string.
  // Jumps to if_bailout if the string if the string is indirect and cannot
  // be unpacked.
  TNode<String> TryToDirect(Label* if_bailout);

  // Returns a pointer to the beginning of the string data.
  // Jumps to if_bailout if the external string cannot be unpacked.
  TNode<RawPtrT> PointerToData(Label* if_bailout) {
    return TryToSequential(PTR_TO_DATA, if_bailout);
  }

  // Returns a pointer that, offset-wise, looks like a String.
  // Jumps to if_bailout if the external string cannot be unpacked.
  TNode<RawPtrT> PointerToString(Label* if_bailout) {
    return TryToSequential(PTR_TO_STRING, if_bailout);
  }

  TNode<String> string() { return var_string_.value(); }
  TNode<Int32T> instance_type() { return var_instance_type_.value(); }
  TNode<IntPtrT> offset() { return var_offset_.value(); }
  TNode<Word32T> is_external() { return var_is_external_.value(); }

 private:
  TNode<RawPtrT> TryToSequential(StringPointerKind ptr_kind, Label* if_bailout);

  TVariable<String> var_string_;
  TVariable<Int32T> var_instance_type_;
  // TODO(v8:9880): Use UintPtrT here.
  TVariable<IntPtrT> var_offset_;
  TVariable<Word32T> var_is_external_;

  const Flags flags_;
};

// Performs checks on a given prototype (e.g. map identity, property
// verification), intended for use in fast path checks.
class PrototypeCheckAssembler : public CodeStubAssembler {
 public:
  enum Flag {
    kCheckPrototypePropertyConstness = 1 << 0,
    kCheckPrototypePropertyIdentity = 1 << 1,
    kCheckFull =
        kCheckPrototypePropertyConstness | kCheckPrototypePropertyIdentity,
  };
  using Flags = base::Flags<Flag>;

  // A tuple describing a relevant property. It contains the descriptor index of
  // the property (within the descriptor array), the property's expected name
  // (stored as a root), and the property's expected value (stored on the native
  // context).
  struct DescriptorIndexNameValue {
    int descriptor_index;
    RootIndex name_root_index;
    int expected_value_context_index;
  };

  PrototypeCheckAssembler(compiler::CodeAssemblerState* state, Flags flags,
                          TNode<NativeContext> native_context,
                          TNode<Map> initial_prototype_map,
                          Vector<DescriptorIndexNameValue> properties);

  void CheckAndBranch(TNode<HeapObject> prototype, Label* if_unmodified,
                      Label* if_modified);

 private:
  const Flags flags_;
  const TNode<NativeContext> native_context_;
  const TNode<Map> initial_prototype_map_;
  const Vector<DescriptorIndexNameValue> properties_;
};

DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags)

#define CLASS_MAP_CONSTANT_ADAPTER(V, rootIndexName, rootAccessorName,     \
                                   class_name)                             \
  template <>                                                              \
  inline bool CodeStubAssembler::ClassHasMapConstant<class_name>() {       \
    return true;                                                           \
  }                                                                        \
  template <>                                                              \
  inline TNode<Map> CodeStubAssembler::GetClassMapConstant<class_name>() { \
    return class_name##MapConstant();                                      \
  }

UNIQUE_INSTANCE_TYPE_MAP_LIST_GENERATOR(CLASS_MAP_CONSTANT_ADAPTER, _)

}  // namespace internal
}  // namespace v8
#endif  // V8_CODEGEN_CODE_STUB_ASSEMBLER_H_
