LCOV - code coverage report
Current view: top level - src - code-stub-assembler.h (source / functions) Hit Total Coverage
Test: app.info Lines: 154 155 99.4 %
Date: 2017-10-20 Functions: 81 81 100.0 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_CODE_STUB_ASSEMBLER_H_
       6             : #define V8_CODE_STUB_ASSEMBLER_H_
       7             : 
       8             : #include <functional>
       9             : 
      10             : #include "src/compiler/code-assembler.h"
      11             : #include "src/globals.h"
      12             : #include "src/objects.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17             : class CallInterfaceDescriptor;
      18             : class CodeStubArguments;
      19             : class CodeStubAssembler;
      20             : class StatsCounter;
      21             : class StubCache;
      22             : 
      23             : enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
      24             : 
      25             : #define HEAP_CONSTANT_LIST(V)                                            \
      26             :   V(AccessorInfoMap, accessor_info_map, AccessorInfoMap)                 \
      27             :   V(AccessorPairMap, accessor_pair_map, AccessorPairMap)                 \
      28             :   V(AllocationSiteMap, allocation_site_map, AllocationSiteMap)           \
      29             :   V(BooleanMap, boolean_map, BooleanMap)                                 \
      30             :   V(CodeMap, code_map, CodeMap)                                          \
      31             :   V(EmptyPropertyDictionary, empty_property_dictionary,                  \
      32             :     EmptyPropertyDictionary)                                             \
      33             :   V(EmptyFixedArray, empty_fixed_array, EmptyFixedArray)                 \
      34             :   V(EmptySlowElementDictionary, empty_slow_element_dictionary,           \
      35             :     EmptySlowElementDictionary)                                          \
      36             :   V(empty_string, empty_string, EmptyString)                             \
      37             :   V(EmptyWeakCell, empty_weak_cell, EmptyWeakCell)                       \
      38             :   V(FalseValue, false_value, False)                                      \
      39             :   V(FeedbackVectorMap, feedback_vector_map, FeedbackVectorMap)           \
      40             :   V(FixedArrayMap, fixed_array_map, FixedArrayMap)                       \
      41             :   V(FixedCOWArrayMap, fixed_cow_array_map, FixedCOWArrayMap)             \
      42             :   V(FixedDoubleArrayMap, fixed_double_array_map, FixedDoubleArrayMap)    \
      43             :   V(FunctionTemplateInfoMap, function_template_info_map,                 \
      44             :     FunctionTemplateInfoMap)                                             \
      45             :   V(GlobalPropertyCellMap, global_property_cell_map, PropertyCellMap)    \
      46             :   V(has_instance_symbol, has_instance_symbol, HasInstanceSymbol)         \
      47             :   V(HeapNumberMap, heap_number_map, HeapNumberMap)                       \
      48             :   V(length_string, length_string, LengthString)                          \
      49             :   V(ManyClosuresCellMap, many_closures_cell_map, ManyClosuresCellMap)    \
      50             :   V(MetaMap, meta_map, MetaMap)                                          \
      51             :   V(MinusZeroValue, minus_zero_value, MinusZero)                         \
      52             :   V(MutableHeapNumberMap, mutable_heap_number_map, MutableHeapNumberMap) \
      53             :   V(NanValue, nan_value, Nan)                                            \
      54             :   V(NoClosuresCellMap, no_closures_cell_map, NoClosuresCellMap)          \
      55             :   V(NullValue, null_value, Null)                                         \
      56             :   V(OneClosureCellMap, one_closure_cell_map, OneClosureCellMap)          \
      57             :   V(prototype_string, prototype_string, PrototypeString)                 \
      58             :   V(SpeciesProtector, species_protector, SpeciesProtector)               \
      59             :   V(SymbolMap, symbol_map, SymbolMap)                                    \
      60             :   V(TheHoleValue, the_hole_value, TheHole)                               \
      61             :   V(TrueValue, true_value, True)                                         \
      62             :   V(Tuple2Map, tuple2_map, Tuple2Map)                                    \
      63             :   V(Tuple3Map, tuple3_map, Tuple3Map)                                    \
      64             :   V(UndefinedValue, undefined_value, Undefined)                          \
      65             :   V(WeakCellMap, weak_cell_map, WeakCellMap)                             \
      66             :   V(SharedFunctionInfoMap, shared_function_info_map, SharedFunctionInfoMap)
      67             : 
      68             : // Provides JavaScript-specific "macro-assembler" functionality on top of the
      69             : // CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler,
      70             : // it's possible to add JavaScript-specific useful CodeAssembler "macros"
      71             : // without modifying files in the compiler directory (and requiring a review
      72             : // from a compiler directory OWNER).
      73       58359 : class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
      74             :  public:
      75             :   using Node = compiler::Node;
      76             :   template <class T>
      77             :   using TNode = compiler::TNode<T>;
      78             :   template <class T>
      79             :   using SloppyTNode = compiler::SloppyTNode<T>;
      80             : 
      81             :   CodeStubAssembler(compiler::CodeAssemblerState* state);
      82             : 
      83             :   enum AllocationFlag : uint8_t {
      84             :     kNone = 0,
      85             :     kDoubleAlignment = 1,
      86             :     kPretenured = 1 << 1,
      87             :     kAllowLargeObjectAllocation = 1 << 2,
      88             :   };
      89             : 
      90             :   typedef base::Flags<AllocationFlag> AllocationFlags;
      91             : 
      92             :   enum ParameterMode { SMI_PARAMETERS, INTPTR_PARAMETERS };
      93             :   // On 32-bit platforms, there is a slight performance advantage to doing all
      94             :   // of the array offset/index arithmetic with SMIs, since it's possible
      95             :   // to save a few tag/untag operations without paying an extra expense when
      96             :   // calculating array offset (the smi math can be folded away) and there are
      97             :   // fewer live ranges. Thus only convert indices to untagged value on 64-bit
      98             :   // platforms.
      99             :   ParameterMode OptimalParameterMode() const {
     100        2761 :     return Is64() ? INTPTR_PARAMETERS : SMI_PARAMETERS;
     101             :   }
     102             : 
     103             :   MachineRepresentation ParameterRepresentation(ParameterMode mode) const {
     104             :     return mode == INTPTR_PARAMETERS ? MachineType::PointerRepresentation()
     105        1170 :                                      : MachineRepresentation::kTaggedSigned;
     106             :   }
     107             : 
     108             :   MachineRepresentation OptimalParameterRepresentation() const {
     109             :     return ParameterRepresentation(OptimalParameterMode());
     110             :   }
     111             : 
     112             :   Node* ParameterToWord(Node* value, ParameterMode mode) {
     113        3968 :     if (mode == SMI_PARAMETERS) value = SmiUntag(value);
     114             :     return value;
     115             :   }
     116             : 
     117             :   Node* WordToParameter(SloppyTNode<IntPtrT> value, ParameterMode mode) {
     118         860 :     if (mode == SMI_PARAMETERS) return SmiTag(value);
     119             :     return value;
     120             :   }
     121             : 
     122          93 :   Node* Word32ToParameter(SloppyTNode<Int32T> value, ParameterMode mode) {
     123         186 :     return WordToParameter(ChangeInt32ToIntPtr(value), mode);
     124             :   }
     125             : 
     126             :   TNode<Smi> ParameterToTagged(Node* value, ParameterMode mode) {
     127       23421 :     if (mode != SMI_PARAMETERS) return SmiTag(value);
     128             :     return UncheckedCast<Smi>(value);
     129             :   }
     130             : 
     131             :   Node* TaggedToParameter(SloppyTNode<Smi> value, ParameterMode mode) {
     132       16447 :     if (mode != SMI_PARAMETERS) return SmiUntag(value);
     133             :     return value;
     134             :   }
     135             : 
     136             :   Node* MatchesParameterMode(Node* value, ParameterMode mode);
     137             : 
     138             : #define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \
     139             :   Node* OpName(Node* a, Node* b, ParameterMode mode) {   \
     140             :     if (mode == SMI_PARAMETERS) {                        \
     141             :       return SmiOpName(a, b);                            \
     142             :     } else {                                             \
     143             :       DCHECK_EQ(INTPTR_PARAMETERS, mode);                \
     144             :       return IntPtrOpName(a, b);                         \
     145             :     }                                                    \
     146             :   }
     147          93 :   PARAMETER_BINOP(IntPtrOrSmiMin, IntPtrMin, SmiMin)
     148      121698 :   PARAMETER_BINOP(IntPtrOrSmiAdd, IntPtrAdd, SmiAdd)
     149        8907 :   PARAMETER_BINOP(IntPtrOrSmiSub, IntPtrSub, SmiSub)
     150             :   PARAMETER_BINOP(IntPtrOrSmiLessThan, IntPtrLessThan, SmiLessThan)
     151          93 :   PARAMETER_BINOP(IntPtrOrSmiLessThanOrEqual, IntPtrLessThanOrEqual,
     152             :                   SmiLessThanOrEqual)
     153        4369 :   PARAMETER_BINOP(IntPtrOrSmiGreaterThan, IntPtrGreaterThan, SmiGreaterThan)
     154             :   PARAMETER_BINOP(IntPtrOrSmiGreaterThanOrEqual, IntPtrGreaterThanOrEqual,
     155             :                   SmiGreaterThanOrEqual)
     156             :   PARAMETER_BINOP(UintPtrOrSmiLessThan, UintPtrLessThan, SmiBelow)
     157       13156 :   PARAMETER_BINOP(UintPtrOrSmiGreaterThanOrEqual, UintPtrGreaterThanOrEqual,
     158             :                   SmiAboveOrEqual)
     159             : #undef PARAMETER_BINOP
     160             : 
     161             :   Node* NoContextConstant();
     162             : #define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \
     163             :   compiler::TNode<std::remove_reference<decltype(                     \
     164             :       *std::declval<Heap>().rootAccessorName())>::type>               \
     165             :       name##Constant();
     166             :   HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR)
     167             : #undef HEAP_CONSTANT_ACCESSOR
     168             : 
     169             : #define HEAP_CONSTANT_TEST(rootIndexName, rootAccessorName, name) \
     170             :   TNode<BoolT> Is##name(SloppyTNode<Object> value);               \
     171             :   TNode<BoolT> IsNot##name(SloppyTNode<Object> value);
     172             :   HEAP_CONSTANT_LIST(HEAP_CONSTANT_TEST)
     173             : #undef HEAP_CONSTANT_TEST
     174             : 
     175             :   Node* HashSeed();
     176             :   Node* StaleRegisterConstant();
     177             : 
     178             :   Node* IntPtrOrSmiConstant(int value, ParameterMode mode);
     179             : 
     180             :   bool IsIntPtrOrSmiConstantZero(Node* test, ParameterMode mode);
     181             :   bool TryGetIntPtrOrSmiConstantValue(Node* maybe_constant, int* value,
     182             :                                       ParameterMode mode);
     183             : 
     184             :   // Round the 32bits payload of the provided word up to the next power of two.
     185             :   Node* IntPtrRoundUpToPowerOfTwo32(Node* value);
     186             :   // Select the maximum of the two provided IntPtr values.
     187             :   TNode<IntPtrT> IntPtrMax(SloppyTNode<IntPtrT> left,
     188             :                            SloppyTNode<IntPtrT> right);
     189             :   // Select the minimum of the two provided IntPtr values.
     190             :   TNode<IntPtrT> IntPtrMin(SloppyTNode<IntPtrT> left,
     191             :                            SloppyTNode<IntPtrT> right);
     192             : 
     193             :   // Float64 operations.
     194             :   TNode<Float64T> Float64Ceil(SloppyTNode<Float64T> x);
     195             :   TNode<Float64T> Float64Floor(SloppyTNode<Float64T> x);
     196             :   TNode<Float64T> Float64Round(SloppyTNode<Float64T> x);
     197             :   TNode<Float64T> Float64RoundToEven(SloppyTNode<Float64T> x);
     198             :   TNode<Float64T> Float64Trunc(SloppyTNode<Float64T> x);
     199             :   // Select the minimum of the two provided Number values.
     200             :   TNode<Object> NumberMax(SloppyTNode<Object> left, SloppyTNode<Object> right);
     201             :   // Select the minimum of the two provided Number values.
     202             :   TNode<Object> NumberMin(SloppyTNode<Object> left, SloppyTNode<Object> right);
     203             : 
     204             :   // Tag a Word as a Smi value.
     205             :   TNode<Smi> SmiTag(SloppyTNode<IntPtrT> value);
     206             :   // Untag a Smi value as a Word.
     207             :   TNode<IntPtrT> SmiUntag(SloppyTNode<Smi> value);
     208             : 
     209             :   // Smi conversions.
     210             :   TNode<Float64T> SmiToFloat64(SloppyTNode<Smi> value);
     211        3509 :   TNode<Smi> SmiFromWord(SloppyTNode<IntPtrT> value) { return SmiTag(value); }
     212             :   TNode<Smi> SmiFromWord32(SloppyTNode<Int32T> value);
     213        3100 :   TNode<IntPtrT> SmiToWord(SloppyTNode<Smi> value) { return SmiUntag(value); }
     214             :   TNode<Int32T> SmiToWord32(SloppyTNode<Smi> value);
     215             : 
     216             :   // Smi operations.
     217             : #define SMI_ARITHMETIC_BINOP(SmiOpName, IntPtrOpName)                  \
     218             :   TNode<Smi> SmiOpName(SloppyTNode<Smi> a, SloppyTNode<Smi> b) {       \
     219             :     return BitcastWordToTaggedSigned(                                  \
     220             :         IntPtrOpName(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); \
     221             :   }
     222       26924 :   SMI_ARITHMETIC_BINOP(SmiAdd, IntPtrAdd)
     223        8052 :   SMI_ARITHMETIC_BINOP(SmiSub, IntPtrSub)
     224        1488 :   SMI_ARITHMETIC_BINOP(SmiAnd, WordAnd)
     225       97340 :   SMI_ARITHMETIC_BINOP(SmiOr, WordOr)
     226             : #undef SMI_ARITHMETIC_BINOP
     227             : 
     228        1116 :   Node* SmiShl(Node* a, int shift) {
     229        4464 :     return BitcastWordToTaggedSigned(WordShl(BitcastTaggedToWord(a), shift));
     230             :   }
     231             : 
     232         905 :   Node* SmiShr(Node* a, int shift) {
     233             :     return BitcastWordToTaggedSigned(
     234             :         WordAnd(WordShr(BitcastTaggedToWord(a), shift),
     235        4525 :                 BitcastTaggedToWord(SmiConstant(-1))));
     236             :   }
     237             : 
     238             :   Node* WordOrSmiShl(Node* a, int shift, ParameterMode mode) {
     239             :     if (mode == SMI_PARAMETERS) {
     240             :       return SmiShl(a, shift);
     241             :     } else {
     242             :       DCHECK_EQ(INTPTR_PARAMETERS, mode);
     243             :       return WordShl(a, shift);
     244             :     }
     245             :   }
     246             : 
     247         971 :   Node* WordOrSmiShr(Node* a, int shift, ParameterMode mode) {
     248         971 :     if (mode == SMI_PARAMETERS) {
     249          37 :       return SmiShr(a, shift);
     250             :     } else {
     251             :       DCHECK_EQ(INTPTR_PARAMETERS, mode);
     252        1868 :       return WordShr(a, shift);
     253             :     }
     254             :   }
     255             : 
     256             : #define SMI_COMPARISON_OP(SmiOpName, IntPtrOpName)                       \
     257             :   Node* SmiOpName(Node* a, Node* b) {                                    \
     258             :     return IntPtrOpName(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); \
     259             :   }
     260       49445 :   SMI_COMPARISON_OP(SmiEqual, WordEqual)
     261         930 :   SMI_COMPARISON_OP(SmiNotEqual, WordNotEqual)
     262       12710 :   SMI_COMPARISON_OP(SmiAbove, UintPtrGreaterThan)
     263        5425 :   SMI_COMPARISON_OP(SmiAboveOrEqual, UintPtrGreaterThanOrEqual)
     264        2480 :   SMI_COMPARISON_OP(SmiBelow, UintPtrLessThan)
     265       16275 :   SMI_COMPARISON_OP(SmiLessThan, IntPtrLessThan)
     266        5325 :   SMI_COMPARISON_OP(SmiLessThanOrEqual, IntPtrLessThanOrEqual)
     267        4245 :   SMI_COMPARISON_OP(SmiGreaterThan, IntPtrGreaterThan)
     268        7130 :   SMI_COMPARISON_OP(SmiGreaterThanOrEqual, IntPtrGreaterThanOrEqual)
     269             : #undef SMI_COMPARISON_OP
     270             :   TNode<Smi> SmiMax(SloppyTNode<Smi> a, SloppyTNode<Smi> b);
     271             :   TNode<Smi> SmiMin(SloppyTNode<Smi> a, SloppyTNode<Smi> b);
     272             :   // Computes a % b for Smi inputs a and b; result is not necessarily a Smi.
     273             :   Node* SmiMod(Node* a, Node* b);
     274             :   // Computes a * b for Smi inputs a and b; result is not necessarily a Smi.
     275             :   Node* SmiMul(Node* a, Node* b);
     276             :   // Tries to computes dividend / divisor for Smi inputs; branching to bailout
     277             :   // if the division needs to be performed as a floating point operation.
     278             :   Node* TrySmiDiv(Node* dividend, Node* divisor, Label* bailout);
     279             : 
     280             :   // Smi | HeapNumber operations.
     281             :   Node* NumberInc(Node* value);
     282             :   Node* NumberDec(Node* value);
     283             :   Node* NumberAdd(Node* a, Node* b);
     284             :   Node* NumberSub(Node* a, Node* b);
     285             :   void GotoIfNotNumber(Node* value, Label* is_not_number);
     286             :   void GotoIfNumber(Node* value, Label* is_number);
     287             : 
     288             :   Node* BitwiseOp(Node* left32, Node* right32, Token::Value bitwise_op);
     289             : 
     290             :   // Allocate an object of the given size.
     291             :   Node* AllocateInNewSpace(Node* size, AllocationFlags flags = kNone);
     292             :   Node* AllocateInNewSpace(int size, AllocationFlags flags = kNone);
     293             :   Node* Allocate(Node* size, AllocationFlags flags = kNone);
     294             :   Node* Allocate(int size, AllocationFlags flags = kNone);
     295             :   Node* InnerAllocate(Node* previous, int offset);
     296             :   Node* InnerAllocate(Node* previous, Node* offset);
     297             :   Node* IsRegularHeapObjectSize(Node* size);
     298             : 
     299             :   typedef std::function<Node*()> NodeGenerator;
     300             : 
     301             :   void Assert(const NodeGenerator& condition_body,
     302             :               const char* message = nullptr, const char* file = nullptr,
     303             :               int line = 0, Node* extra_node1 = nullptr,
     304             :               const char* extra_node1_name = "", Node* extra_node2 = nullptr,
     305             :               const char* extra_node2_name = "", Node* extra_node3 = nullptr,
     306             :               const char* extra_node3_name = "", Node* extra_node4 = nullptr,
     307             :               const char* extra_node4_name = "", Node* extra_node5 = nullptr,
     308             :               const char* extra_node5_name = "");
     309             :   void Check(const NodeGenerator& condition_body, const char* message = nullptr,
     310             :              const char* file = nullptr, int line = 0,
     311             :              Node* extra_node1 = nullptr, const char* extra_node1_name = "",
     312             :              Node* extra_node2 = nullptr, const char* extra_node2_name = "",
     313             :              Node* extra_node3 = nullptr, const char* extra_node3_name = "",
     314             :              Node* extra_node4 = nullptr, const char* extra_node4_name = "",
     315             :              Node* extra_node5 = nullptr, const char* extra_node5_name = "");
     316             : 
     317             :   Node* Select(SloppyTNode<BoolT> condition, const NodeGenerator& true_body,
     318             :                const NodeGenerator& false_body, MachineRepresentation rep);
     319             :   template <class A, class F, class G>
     320         124 :   TNode<A> Select(SloppyTNode<BoolT> condition, const F& true_body,
     321             :                   const G& false_body, MachineRepresentation rep) {
     322             :     return UncheckedCast<A>(
     323             :         Select(condition,
     324             :                [&]() -> Node* {
     325         124 :                  return base::implicit_cast<SloppyTNode<A>>(true_body());
     326             :                },
     327         124 :                [&]() -> Node* {
     328         248 :                  return base::implicit_cast<SloppyTNode<A>>(false_body());
     329             :                },
     330         372 :                rep));
     331             :   }
     332             : 
     333             :   Node* SelectConstant(Node* condition, Node* true_value, Node* false_value,
     334             :                        MachineRepresentation rep);
     335             :   template <class A>
     336             :   TNode<A> SelectConstant(TNode<BoolT> condition, TNode<A> true_value,
     337             :                           TNode<A> false_value, MachineRepresentation rep) {
     338             :     return UncheckedCast<A>(
     339             :         SelectConstant(condition, static_cast<Node*>(true_value),
     340        8840 :                        static_cast<Node*>(false_value), rep));
     341             :   }
     342             : 
     343             :   Node* SelectInt32Constant(Node* condition, int true_value, int false_value);
     344             :   Node* SelectIntPtrConstant(Node* condition, int true_value, int false_value);
     345             :   Node* SelectBooleanConstant(Node* condition);
     346             :   template <class A>
     347             :   TNode<A> SelectTaggedConstant(SloppyTNode<BoolT> condition,
     348             :                                 TNode<A> true_value,
     349             :                                 SloppyTNode<A> false_value) {
     350             :     static_assert(std::is_base_of<Object, A>::value, "not a tagged type");
     351             :     return SelectConstant(condition, true_value, false_value,
     352             :                           MachineRepresentation::kTagged);
     353             :   }
     354             :   Node* SelectSmiConstant(Node* condition, Smi* true_value, Smi* false_value);
     355             :   Node* SelectSmiConstant(Node* condition, int true_value, Smi* false_value) {
     356             :     return SelectSmiConstant(condition, Smi::FromInt(true_value), false_value);
     357             :   }
     358             :   Node* SelectSmiConstant(Node* condition, Smi* true_value, int false_value) {
     359             :     return SelectSmiConstant(condition, true_value, Smi::FromInt(false_value));
     360             :   }
     361             :   Node* SelectSmiConstant(Node* condition, int true_value, int false_value) {
     362             :     return SelectSmiConstant(condition, Smi::FromInt(true_value),
     363        2232 :                              Smi::FromInt(false_value));
     364             :   }
     365             : 
     366             :   TNode<Int32T> TruncateWordToWord32(SloppyTNode<IntPtrT> value);
     367             : 
     368             :   // Check a value for smi-ness
     369             :   TNode<BoolT> TaggedIsSmi(SloppyTNode<Object> a);
     370             :   TNode<BoolT> TaggedIsNotSmi(SloppyTNode<Object> a);
     371             :   // Check that the value is a non-negative smi.
     372             :   TNode<BoolT> TaggedIsPositiveSmi(SloppyTNode<Object> a);
     373             :   // Check that a word has a word-aligned address.
     374             :   TNode<BoolT> WordIsWordAligned(SloppyTNode<WordT> word);
     375             :   TNode<BoolT> WordIsPowerOfTwo(SloppyTNode<IntPtrT> value);
     376             : 
     377         372 :   Node* IsNotTheHole(Node* value) { return Word32BinaryNot(IsTheHole(value)); }
     378             : 
     379             : #if DEBUG
     380             :   void Bind(Label* label, AssemblerDebugInfo debug_info);
     381             : #else
     382             :   void Bind(Label* label);
     383             : #endif  // DEBUG
     384             : 
     385        1798 :   void BranchIfSmiEqual(Node* a, Node* b, Label* if_true, Label* if_false) {
     386        3596 :     Branch(SmiEqual(a, b), if_true, if_false);
     387        1798 :   }
     388             : 
     389         372 :   void BranchIfSmiLessThan(Node* a, Node* b, Label* if_true, Label* if_false) {
     390         744 :     Branch(SmiLessThan(a, b), if_true, if_false);
     391         372 :   }
     392             : 
     393         600 :   void BranchIfSmiLessThanOrEqual(Node* a, Node* b, Label* if_true,
     394             :                                   Label* if_false) {
     395        1200 :     Branch(SmiLessThanOrEqual(a, b), if_true, if_false);
     396         600 :   }
     397             : 
     398         930 :   void BranchIfFloat64IsNaN(Node* value, Label* if_true, Label* if_false) {
     399        1860 :     Branch(Float64Equal(value, value), if_false, if_true);
     400         930 :   }
     401             : 
     402             :   // Branches to {if_true} if ToBoolean applied to {value} yields true,
     403             :   // otherwise goes to {if_false}.
     404             :   void BranchIfToBooleanIsTrue(Node* value, Label* if_true, Label* if_false);
     405             : 
     406             :   void BranchIfJSReceiver(Node* object, Label* if_true, Label* if_false);
     407             :   void BranchIfJSObject(Node* object, Label* if_true, Label* if_false);
     408             : 
     409             :   void BranchIfFastJSArray(Node* object, Node* context, Label* if_true,
     410             :                            Label* if_false);
     411             :   void BranchIfFastJSArrayForCopy(Node* object, Node* context, Label* if_true,
     412             :                                   Label* if_false);
     413             : 
     414             :   // Load value from current frame by given offset in bytes.
     415             :   Node* LoadFromFrame(int offset, MachineType rep = MachineType::AnyTagged());
     416             :   // Load value from current parent frame by given offset in bytes.
     417             :   Node* LoadFromParentFrame(int offset,
     418             :                             MachineType rep = MachineType::AnyTagged());
     419             : 
     420             :   // Load an object pointer from a buffer that isn't in the heap.
     421             :   Node* LoadBufferObject(Node* buffer, int offset,
     422             :                          MachineType rep = MachineType::AnyTagged());
     423             :   // Load a field from an object on the heap.
     424             :   Node* LoadObjectField(SloppyTNode<HeapObject> object, int offset,
     425             :                         MachineType rep);
     426             :   template <class T, typename std::enable_if<
     427             :                          std::is_convertible<TNode<T>, TNode<Object>>::value,
     428             :                          int>::type = 0>
     429             :   TNode<T> LoadObjectField(TNode<HeapObject> object, int offset) {
     430        7241 :     return CAST(LoadObjectField(object, offset, MachineTypeOf<T>::value));
     431             :   }
     432             :   template <class T, typename std::enable_if<
     433             :                          std::is_convertible<TNode<T>, TNode<UntaggedT>>::value,
     434             :                          int>::type = 0>
     435             :   TNode<T> LoadObjectField(TNode<HeapObject> object, int offset) {
     436             :     return UncheckedCast<T>(
     437        8441 :         LoadObjectField(object, offset, MachineTypeOf<T>::value));
     438             :   }
     439             :   TNode<Object> LoadObjectField(SloppyTNode<HeapObject> object, int offset) {
     440             :     return UncheckedCast<Object>(
     441      259675 :         LoadObjectField(object, offset, MachineType::AnyTagged()));
     442             :   }
     443             :   Node* LoadObjectField(SloppyTNode<HeapObject> object,
     444             :                         SloppyTNode<IntPtrT> offset, MachineType rep);
     445             :   TNode<Object> LoadObjectField(SloppyTNode<HeapObject> object,
     446             :                                 SloppyTNode<IntPtrT> offset) {
     447             :     return UncheckedCast<Object>(
     448        3323 :         LoadObjectField(object, offset, MachineType::AnyTagged()));
     449             :   }
     450             :   // Load a SMI field and untag it.
     451             :   TNode<IntPtrT> LoadAndUntagObjectField(SloppyTNode<HeapObject> object,
     452             :                                          int offset);
     453             :   // Load a SMI field, untag it, and convert to Word32.
     454             :   TNode<Int32T> LoadAndUntagToWord32ObjectField(Node* object, int offset);
     455             :   // Load a SMI and untag it.
     456             :   TNode<IntPtrT> LoadAndUntagSmi(Node* base, int index);
     457             :   // Load a SMI root, untag it, and convert to Word32.
     458             :   Node* LoadAndUntagToWord32Root(Heap::RootListIndex root_index);
     459             : 
     460             :   // Tag a smi and store it.
     461             :   Node* StoreAndTagSmi(Node* base, int offset, Node* value);
     462             : 
     463             :   // Load the floating point value of a HeapNumber.
     464             :   TNode<Float64T> LoadHeapNumberValue(SloppyTNode<HeapNumber> object);
     465             :   // Load the Map of an HeapObject.
     466             :   TNode<Map> LoadMap(SloppyTNode<HeapObject> object);
     467             :   // Load the instance type of an HeapObject.
     468             :   TNode<Int32T> LoadInstanceType(SloppyTNode<HeapObject> object);
     469             :   // Compare the instance the type of the object against the provided one.
     470             :   Node* HasInstanceType(Node* object, InstanceType type);
     471             :   Node* DoesntHaveInstanceType(Node* object, InstanceType type);
     472             :   Node* TaggedDoesntHaveInstanceType(Node* any_tagged, InstanceType type);
     473             :   // Load the properties backing store of a JSObject.
     474             :   TNode<HeapObject> LoadSlowProperties(SloppyTNode<JSObject> object);
     475             :   TNode<HeapObject> LoadFastProperties(SloppyTNode<JSObject> object);
     476             :   // Load the hash from the backing store of a JSObject.
     477             :   TNode<Int32T> LoadHashForJSObject(SloppyTNode<JSObject> jsobject,
     478             :                                     SloppyTNode<Int32T> instance_type);
     479             :   // Load the elements backing store of a JSObject.
     480             :   TNode<FixedArrayBase> LoadElements(SloppyTNode<JSObject> object);
     481             :   // Load the length of a JSArray instance.
     482             :   TNode<Object> LoadJSArrayLength(SloppyTNode<JSArray> array);
     483             :   // Load the length of a fast JSArray instance. Returns a positive Smi.
     484             :   TNode<Smi> LoadFastJSArrayLength(SloppyTNode<JSArray> array);
     485             :   // Load the length of a fixed array base instance.
     486             :   TNode<Smi> LoadFixedArrayBaseLength(SloppyTNode<FixedArrayBase> array);
     487             :   // Load the length of a fixed array base instance.
     488             :   TNode<IntPtrT> LoadAndUntagFixedArrayBaseLength(
     489             :       SloppyTNode<FixedArrayBase> array);
     490             :   // Load the bit field of a Map.
     491             :   TNode<Int32T> LoadMapBitField(SloppyTNode<Map> map);
     492             :   // Load bit field 2 of a map.
     493             :   TNode<Int32T> LoadMapBitField2(SloppyTNode<Map> map);
     494             :   // Load bit field 3 of a map.
     495             :   TNode<Uint32T> LoadMapBitField3(SloppyTNode<Map> map);
     496             :   // Load the instance type of a map.
     497             :   TNode<Int32T> LoadMapInstanceType(SloppyTNode<Map> map);
     498             :   // Load the ElementsKind of a map.
     499             :   TNode<Int32T> LoadMapElementsKind(SloppyTNode<Map> map);
     500             :   // Load the instance descriptors of a map.
     501             :   TNode<DescriptorArray> LoadMapDescriptors(SloppyTNode<Map> map);
     502             :   // Load the prototype of a map.
     503             :   TNode<Object> LoadMapPrototype(SloppyTNode<Map> map);
     504             :   // Load the prototype info of a map. The result has to be checked if it is a
     505             :   // prototype info object or not.
     506             :   TNode<PrototypeInfo> LoadMapPrototypeInfo(SloppyTNode<Map> map,
     507             :                                             Label* if_has_no_proto_info);
     508             :   // Load the instance size of a Map.
     509             :   TNode<IntPtrT> LoadMapInstanceSize(SloppyTNode<Map> map);
     510             :   // Load the inobject properties count of a Map (valid only for JSObjects).
     511             :   TNode<IntPtrT> LoadMapInobjectProperties(SloppyTNode<Map> map);
     512             :   // Load the constructor function index of a Map (only for primitive maps).
     513             :   TNode<IntPtrT> LoadMapConstructorFunctionIndex(SloppyTNode<Map> map);
     514             :   // Load the constructor of a Map (equivalent to Map::GetConstructor()).
     515             :   TNode<Object> LoadMapConstructor(SloppyTNode<Map> map);
     516             :   // Load the EnumLength of a Map.
     517             :   Node* LoadMapEnumLength(SloppyTNode<Map> map);
     518             : 
     519             :   // This is only used on a newly allocated PropertyArray which
     520             :   // doesn't have an existing hash.
     521             :   void InitializePropertyArrayLength(Node* property_array, Node* length,
     522             :                                      ParameterMode mode);
     523             : 
     524             :   // Check if the map is set for slow properties.
     525             :   TNode<BoolT> IsDictionaryMap(SloppyTNode<Map> map);
     526             : 
     527             :   // Load the hash field of a name as an uint32 value.
     528             :   TNode<Uint32T> LoadNameHashField(SloppyTNode<Name> name);
     529             :   // Load the hash value of a name as an uint32 value.
     530             :   // If {if_hash_not_computed} label is specified then it also checks if
     531             :   // hash is actually computed.
     532             :   TNode<Uint32T> LoadNameHash(SloppyTNode<Name> name,
     533             :                               Label* if_hash_not_computed = nullptr);
     534             : 
     535             :   // Load length field of a String object.
     536             :   TNode<Smi> LoadStringLength(SloppyTNode<String> object);
     537             :   // Loads a pointer to the sequential String char array.
     538             :   Node* PointerToSeqStringData(Node* seq_string);
     539             :   // Load value field of a JSValue object.
     540             :   Node* LoadJSValueValue(Node* object);
     541             :   // Load value field of a WeakCell object.
     542             :   Node* LoadWeakCellValueUnchecked(Node* weak_cell);
     543             :   Node* LoadWeakCellValue(Node* weak_cell, Label* if_cleared = nullptr);
     544             : 
     545             :   // Load an array element from a FixedArray.
     546             :   Node* LoadFixedArrayElement(Node* object, Node* index,
     547             :                               int additional_offset = 0,
     548             :                               ParameterMode parameter_mode = INTPTR_PARAMETERS);
     549       31407 :   Node* LoadFixedArrayElement(Node* object, int index,
     550             :                               int additional_offset = 0) {
     551       31407 :     return LoadFixedArrayElement(object, IntPtrConstant(index),
     552       62814 :                                  additional_offset);
     553             :   }
     554             :   // Load an array element from a FixedArray, untag it and return it as Word32.
     555             :   Node* LoadAndUntagToWord32FixedArrayElement(
     556             :       Node* object, Node* index, int additional_offset = 0,
     557             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
     558             :   // Load an array element from a FixedDoubleArray.
     559             :   Node* LoadFixedDoubleArrayElement(
     560             :       Node* object, Node* index, MachineType machine_type,
     561             :       int additional_offset = 0,
     562             :       ParameterMode parameter_mode = INTPTR_PARAMETERS,
     563             :       Label* if_hole = nullptr);
     564             : 
     565             :   // Load a feedback slot from a FeedbackVector.
     566             :   Node* LoadFeedbackVectorSlot(
     567             :       Node* object, Node* index, int additional_offset = 0,
     568             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
     569             : 
     570             :   // Load Float64 value by |base| + |offset| address. If the value is a double
     571             :   // hole then jump to |if_hole|. If |machine_type| is None then only the hole
     572             :   // check is generated.
     573             :   Node* LoadDoubleWithHoleCheck(
     574             :       Node* base, Node* offset, Label* if_hole,
     575             :       MachineType machine_type = MachineType::Float64());
     576             :   Node* LoadFixedTypedArrayElement(
     577             :       Node* data_pointer, Node* index_node, ElementsKind elements_kind,
     578             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
     579             :   Node* LoadFixedTypedArrayElementAsTagged(
     580             :       Node* data_pointer, Node* index_node, ElementsKind elements_kind,
     581             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
     582             : 
     583             :   // Context manipulation
     584             :   TNode<Object> LoadContextElement(SloppyTNode<Context> context,
     585             :                                    int slot_index);
     586             :   TNode<Object> LoadContextElement(SloppyTNode<Context> context,
     587             :                                    SloppyTNode<IntPtrT> slot_index);
     588             :   void StoreContextElement(SloppyTNode<Context> context, int slot_index,
     589             :                            SloppyTNode<Object> value);
     590             :   void StoreContextElement(SloppyTNode<Context> context,
     591             :                            SloppyTNode<IntPtrT> slot_index,
     592             :                            SloppyTNode<Object> value);
     593             :   void StoreContextElementNoWriteBarrier(SloppyTNode<Context> context,
     594             :                                          int slot_index,
     595             :                                          SloppyTNode<Object> value);
     596             :   TNode<Context> LoadNativeContext(SloppyTNode<Context> context);
     597             : 
     598             :   TNode<Map> LoadJSArrayElementsMap(ElementsKind kind,
     599             :                                     SloppyTNode<Context> native_context);
     600             :   TNode<Map> LoadJSArrayElementsMap(SloppyTNode<Int32T> kind,
     601             :                                     SloppyTNode<Context> native_context);
     602             : 
     603             :   // Load the "prototype" property of a JSFunction.
     604             :   Node* LoadJSFunctionPrototype(Node* function, Label* if_bailout);
     605             : 
     606             :   // Store the floating point value of a HeapNumber.
     607             :   void StoreHeapNumberValue(SloppyTNode<HeapNumber> object,
     608             :                             SloppyTNode<Float64T> value);
     609             :   // Store a field to an object on the heap.
     610             :   Node* StoreObjectField(Node* object, int offset, Node* value);
     611             :   Node* StoreObjectField(Node* object, Node* offset, Node* value);
     612             :   Node* StoreObjectFieldNoWriteBarrier(
     613             :       Node* object, int offset, Node* value,
     614             :       MachineRepresentation rep = MachineRepresentation::kTagged);
     615             :   Node* StoreObjectFieldNoWriteBarrier(
     616             :       Node* object, Node* offset, Node* value,
     617             :       MachineRepresentation rep = MachineRepresentation::kTagged);
     618             :   // Store the Map of an HeapObject.
     619             :   Node* StoreMap(Node* object, Node* map);
     620             :   Node* StoreMapNoWriteBarrier(Node* object,
     621             :                                Heap::RootListIndex map_root_index);
     622             :   Node* StoreMapNoWriteBarrier(Node* object, Node* map);
     623             :   Node* StoreObjectFieldRoot(Node* object, int offset,
     624             :                              Heap::RootListIndex root);
     625             :   // Store an array element to a FixedArray.
     626       11719 :   Node* StoreFixedArrayElement(
     627             :       Node* object, int index, Node* value,
     628             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
     629       11719 :     return StoreFixedArrayElement(object, IntPtrConstant(index), value,
     630       23438 :                                   barrier_mode);
     631             :   }
     632             : 
     633             :   Node* StoreFixedArrayElement(
     634             :       Node* object, Node* index, Node* value,
     635             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
     636             :       int additional_offset = 0,
     637             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
     638             : 
     639             :   Node* StoreFixedDoubleArrayElement(
     640             :       Node* object, Node* index, Node* value,
     641             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
     642             : 
     643             :   Node* StoreFeedbackVectorSlot(
     644             :       Node* object, Node* index, Node* value,
     645             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
     646             :       int additional_offset = 0,
     647             :       ParameterMode parameter_mode = INTPTR_PARAMETERS);
     648             : 
     649             :   void EnsureArrayLengthWritable(Node* map, Label* bailout);
     650             : 
     651             :   // EnsureArrayPushable verifies that receiver is:
     652             :   //   1. Is not a prototype.
     653             :   //   2. Is not a dictionary.
     654             :   //   3. Has a writeable length property.
     655             :   // It returns ElementsKind as a node for further division into cases.
     656             :   Node* EnsureArrayPushable(Node* receiver, Label* bailout);
     657             : 
     658             :   void TryStoreArrayElement(ElementsKind kind, ParameterMode mode,
     659             :                             Label* bailout, Node* elements, Node* index,
     660             :                             Node* value);
     661             :   // Consumes args into the array, and returns tagged new length.
     662             :   TNode<Smi> BuildAppendJSArray(ElementsKind kind, SloppyTNode<JSArray> array,
     663             :                                 CodeStubArguments* args,
     664             :                                 TVariable<IntPtrT>* arg_index, Label* bailout);
     665             :   // Pushes value onto the end of array.
     666             :   void BuildAppendJSArray(ElementsKind kind, Node* array, Node* value,
     667             :                           Label* bailout);
     668             : 
     669             :   void StoreFieldsNoWriteBarrier(Node* start_address, Node* end_address,
     670             :                                  Node* value);
     671             : 
     672             :   Node* AllocateCellWithValue(Node* value,
     673             :                               WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
     674          31 :   Node* AllocateSmiCell(int value = 0) {
     675          62 :     return AllocateCellWithValue(SmiConstant(value), SKIP_WRITE_BARRIER);
     676             :   }
     677             : 
     678             :   Node* LoadCellValue(Node* cell);
     679             : 
     680             :   Node* StoreCellValue(Node* cell, Node* value,
     681             :                        WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
     682             : 
     683             :   // Allocate a HeapNumber without initializing its value.
     684             :   TNode<HeapNumber> AllocateHeapNumber(MutableMode mode = IMMUTABLE);
     685             :   // Allocate a HeapNumber with a specific value.
     686             :   TNode<HeapNumber> AllocateHeapNumberWithValue(SloppyTNode<Float64T> value,
     687             :                                                 MutableMode mode = IMMUTABLE);
     688             :   // Allocate a SeqOneByteString with the given length.
     689             :   Node* AllocateSeqOneByteString(int length, AllocationFlags flags = kNone);
     690             :   Node* AllocateSeqOneByteString(Node* context, Node* length,
     691             :                                  ParameterMode mode = INTPTR_PARAMETERS,
     692             :                                  AllocationFlags flags = kNone);
     693             :   // Allocate a SeqTwoByteString with the given length.
     694             :   Node* AllocateSeqTwoByteString(int length, AllocationFlags flags = kNone);
     695             :   Node* AllocateSeqTwoByteString(Node* context, Node* length,
     696             :                                  ParameterMode mode = INTPTR_PARAMETERS,
     697             :                                  AllocationFlags flags = kNone);
     698             : 
     699             :   // Allocate a SlicedOneByteString with the given length, parent and offset.
     700             :   // |length| and |offset| are expected to be tagged.
     701             :   Node* AllocateSlicedOneByteString(Node* length, Node* parent, Node* offset);
     702             :   // Allocate a SlicedTwoByteString with the given length, parent and offset.
     703             :   // |length| and |offset| are expected to be tagged.
     704             :   Node* AllocateSlicedTwoByteString(Node* length, Node* parent, Node* offset);
     705             : 
     706             :   // Allocate a one-byte ConsString with the given length, first and second
     707             :   // parts. |length| is expected to be tagged, and |first| and |second| are
     708             :   // expected to be one-byte strings.
     709             :   Node* AllocateOneByteConsString(Node* length, Node* first, Node* second,
     710             :                                   AllocationFlags flags = kNone);
     711             :   // Allocate a two-byte ConsString with the given length, first and second
     712             :   // parts. |length| is expected to be tagged, and |first| and |second| are
     713             :   // expected to be two-byte strings.
     714             :   Node* AllocateTwoByteConsString(Node* length, Node* first, Node* second,
     715             :                                   AllocationFlags flags = kNone);
     716             : 
     717             :   // Allocate an appropriate one- or two-byte ConsString with the first and
     718             :   // second parts specified by |first| and |second|.
     719             :   Node* NewConsString(Node* context, Node* length, Node* left, Node* right,
     720             :                       AllocationFlags flags = kNone);
     721             : 
     722             :   Node* AllocateNameDictionary(int at_least_space_for);
     723             :   Node* AllocateNameDictionary(Node* at_least_space_for);
     724             :   Node* AllocateNameDictionaryWithCapacity(Node* capacity);
     725             :   Node* CopyNameDictionary(Node* dictionary, Label* large_object_fallback);
     726             : 
     727             :   Node* AllocateStruct(Node* map, AllocationFlags flags = kNone);
     728             :   void InitializeStructBody(Node* object, Node* map, Node* size,
     729             :                             int start_offset = Struct::kHeaderSize);
     730             :   Node* AllocateJSObjectFromMap(Node* map, Node* properties = nullptr,
     731             :                                 Node* elements = nullptr,
     732             :                                 AllocationFlags flags = kNone);
     733             : 
     734             :   void InitializeJSObjectFromMap(Node* object, Node* map, Node* size,
     735             :                                  Node* properties = nullptr,
     736             :                                  Node* elements = nullptr);
     737             : 
     738             :   void InitializeJSObjectBody(Node* object, Node* map, Node* size,
     739             :                               int start_offset = JSObject::kHeaderSize);
     740             : 
     741             :   // Allocate a JSArray without elements and initialize the header fields.
     742             :   Node* AllocateUninitializedJSArrayWithoutElements(Node* array_map,
     743             :                                                     Node* length,
     744             :                                                     Node* allocation_site);
     745             :   // Allocate and return a JSArray with initialized header fields and its
     746             :   // uninitialized elements.
     747             :   // The ParameterMode argument is only used for the capacity parameter.
     748             :   std::pair<Node*, Node*> AllocateUninitializedJSArrayWithElements(
     749             :       ElementsKind kind, Node* array_map, Node* length, Node* allocation_site,
     750             :       Node* capacity, ParameterMode capacity_mode = INTPTR_PARAMETERS);
     751             :   // Allocate a JSArray and fill elements with the hole.
     752             :   // The ParameterMode argument is only used for the capacity parameter.
     753             :   Node* AllocateJSArray(ElementsKind kind, Node* array_map, Node* capacity,
     754             :                         Node* length, Node* allocation_site = nullptr,
     755             :                         ParameterMode capacity_mode = INTPTR_PARAMETERS);
     756             : 
     757             :   Node* CloneFastJSArray(Node* context, Node* array,
     758             :                          ParameterMode mode = INTPTR_PARAMETERS,
     759             :                          Node* allocation_site = nullptr);
     760             : 
     761             :   Node* ExtractFastJSArray(Node* context, Node* array, Node* begin, Node* count,
     762             :                            ParameterMode mode = INTPTR_PARAMETERS,
     763             :                            Node* capacity = nullptr,
     764             :                            Node* allocation_site = nullptr);
     765             : 
     766             :   Node* AllocateFixedArray(ElementsKind kind, Node* capacity,
     767             :                            ParameterMode mode = INTPTR_PARAMETERS,
     768             :                            AllocationFlags flags = kNone,
     769             :                            Node* fixed_array_map = nullptr);
     770             : 
     771             :   Node* AllocatePropertyArray(Node* capacity,
     772             :                               ParameterMode mode = INTPTR_PARAMETERS,
     773             :                               AllocationFlags flags = kNone);
     774             :   // Perform CreateArrayIterator (ES6 #sec-createarrayiterator).
     775             :   Node* CreateArrayIterator(Node* array, Node* array_map, Node* array_type,
     776             :                             Node* context, IterationKind mode);
     777             : 
     778             :   Node* AllocateJSArrayIterator(Node* array, Node* array_map, Node* map);
     779             :   Node* AllocateJSIteratorResult(Node* context, Node* value, Node* done);
     780             :   Node* AllocateJSIteratorResultForEntry(Node* context, Node* key, Node* value);
     781             : 
     782             :   Node* TypedArraySpeciesCreateByLength(Node* context, Node* originalArray,
     783             :                                         Node* len);
     784             : 
     785             :   void FillFixedArrayWithValue(ElementsKind kind, Node* array, Node* from_index,
     786             :                                Node* to_index,
     787             :                                Heap::RootListIndex value_root_index,
     788             :                                ParameterMode mode = INTPTR_PARAMETERS);
     789             : 
     790             :   void FillPropertyArrayWithUndefined(Node* array, Node* from_index,
     791             :                                       Node* to_index,
     792             :                                       ParameterMode mode = INTPTR_PARAMETERS);
     793             : 
     794             :   void CopyPropertyArrayValues(
     795             :       Node* from_array, Node* to_array, Node* length,
     796             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
     797             :       ParameterMode mode = INTPTR_PARAMETERS);
     798             : 
     799             :   // Copies all elements from |from_array| of |length| size to
     800             :   // |to_array| of the same size respecting the elements kind.
     801         155 :   void CopyFixedArrayElements(
     802             :       ElementsKind kind, Node* from_array, Node* to_array, Node* length,
     803             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
     804             :       ParameterMode mode = INTPTR_PARAMETERS) {
     805             :     CopyFixedArrayElements(kind, from_array, kind, to_array,
     806             :                            IntPtrOrSmiConstant(0, mode), length, length,
     807         155 :                            barrier_mode, mode);
     808         155 :   }
     809             : 
     810             :   // Copies |element_count| elements from |from_array| starting from element
     811             :   // zero to |to_array| of |capacity| size respecting both array's elements
     812             :   // kinds.
     813        2230 :   void CopyFixedArrayElements(
     814             :       ElementsKind from_kind, Node* from_array, ElementsKind to_kind,
     815             :       Node* to_array, Node* element_count, Node* capacity,
     816             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
     817             :       ParameterMode mode = INTPTR_PARAMETERS) {
     818             :     CopyFixedArrayElements(from_kind, from_array, to_kind, to_array,
     819             :                            IntPtrOrSmiConstant(0, mode), element_count,
     820        2230 :                            capacity, barrier_mode, mode);
     821        2230 :   }
     822             : 
     823             :   // Copies |element_count| elements from |from_array| starting from element
     824             :   // |first_element| to |to_array| of |capacity| size respecting both array's
     825             :   // elements kinds.
     826             :   void CopyFixedArrayElements(
     827             :       ElementsKind from_kind, Node* from_array, ElementsKind to_kind,
     828             :       Node* to_array, Node* first_element, Node* element_count, Node* capacity,
     829             :       WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
     830             :       ParameterMode mode = INTPTR_PARAMETERS);
     831             : 
     832             :   enum class ExtractFixedArrayFlag {
     833             :     kFixedArrays = 1,
     834             :     kFixedDoubleArrays = 2,
     835             :     kDontCopyCOW = 4,
     836             :     kNewSpaceAllocationOnly = 8,
     837             :     kAllFixedArrays = kFixedArrays | kFixedDoubleArrays,
     838             :     kAllFixedArraysDontCopyCOW = kAllFixedArrays | kDontCopyCOW
     839             :   };
     840             : 
     841             :   typedef base::Flags<ExtractFixedArrayFlag> ExtractFixedArrayFlags;
     842             : 
     843             :   // Copy a portion of an existing FixedArray or FixedDoubleArray into a new
     844             :   // FixedArray, including special appropriate handling for empty arrays and COW
     845             :   // arrays.
     846             :   //
     847             :   // * |source| is either a FixedArray or FixedDoubleArray from which to copy
     848             :   // elements.
     849             :   // * |first| is the starting element index to copy from, if nullptr is passed
     850             :   // then index zero is used by default.
     851             :   // * |count| is the number of elements to copy out of the source array
     852             :   // starting from and including the element indexed by |start|. If |count| is
     853             :   // nullptr, then all of the elements from |start| to the end of |source| are
     854             :   // copied.
     855             :   // * |capacity| determines the size of the allocated result array, with
     856             :   // |capacity| >= |count|. If |capacity| is nullptr, then |count| is used as
     857             :   // the destination array's capacity.
     858             :   // * |extract_flags| determines whether FixedArrays, FixedDoubleArrays or both
     859             :   // are detected and copied. Although it's always correct to pass
     860             :   // kAllFixedArrays, the generated code is more compact and efficient if the
     861             :   // caller can specify whether only FixedArrays or FixedDoubleArrays will be
     862             :   // passed as the |source| parameter.
     863             :   // * |parameter_mode| determines the parameter mode of |first|, |count| and
     864             :   // |capacity|.
     865             :   Node* ExtractFixedArray(Node* source, Node* first, Node* count = nullptr,
     866             :                           Node* capacity = nullptr,
     867             :                           ExtractFixedArrayFlags extract_flags =
     868             :                               ExtractFixedArrayFlag::kAllFixedArrays,
     869             :                           ParameterMode parameter_mode = INTPTR_PARAMETERS);
     870             : 
     871             :   // Copy the entire contents of a FixedArray or FixedDoubleArray to a new
     872             :   // array, including special appropriate handling for empty arrays and COW
     873             :   // arrays.
     874             :   //
     875             :   // * |source| is either a FixedArray or FixedDoubleArray from which to copy
     876             :   // elements.
     877             :   // * |extract_flags| determines whether FixedArrays, FixedDoubleArrays or both
     878             :   // are detected and copied. Although it's always correct to pass
     879             :   // kAllFixedArrays, the generated code is more compact and efficient if the
     880             :   // caller can specify whether only FixedArrays or FixedDoubleArrays will be
     881             :   // passed as the |source| parameter.
     882         297 :   Node* CloneFixedArray(Node* source,
     883             :                         ExtractFixedArrayFlags flags =
     884             :                             ExtractFixedArrayFlag::kAllFixedArraysDontCopyCOW) {
     885             :     ParameterMode mode = OptimalParameterMode();
     886             :     return ExtractFixedArray(source, IntPtrOrSmiConstant(0, mode), nullptr,
     887         297 :                              nullptr, flags, mode);
     888             :   }
     889             : 
     890             :   // Copies |character_count| elements from |from_string| to |to_string|
     891             :   // starting at the |from_index|'th character. |from_string| and |to_string|
     892             :   // can either be one-byte strings or two-byte strings, although if
     893             :   // |from_string| is two-byte, then |to_string| must be two-byte.
     894             :   // |from_index|, |to_index| and |character_count| must be either Smis or
     895             :   // intptr_ts depending on |mode| s.t. 0 <= |from_index| <= |from_index| +
     896             :   // |character_count| <= from_string.length and 0 <= |to_index| <= |to_index| +
     897             :   // |character_count| <= to_string.length.
     898             :   void CopyStringCharacters(Node* from_string, Node* to_string,
     899             :                             Node* from_index, Node* to_index,
     900             :                             Node* character_count,
     901             :                             String::Encoding from_encoding,
     902             :                             String::Encoding to_encoding, ParameterMode mode);
     903             : 
     904             :   // Loads an element from |array| of |from_kind| elements by given |offset|
     905             :   // (NOTE: not index!), does a hole check if |if_hole| is provided and
     906             :   // converts the value so that it becomes ready for storing to array of
     907             :   // |to_kind| elements.
     908             :   Node* LoadElementAndPrepareForStore(Node* array, Node* offset,
     909             :                                       ElementsKind from_kind,
     910             :                                       ElementsKind to_kind, Label* if_hole);
     911             : 
     912             :   Node* CalculateNewElementsCapacity(Node* old_capacity,
     913             :                                      ParameterMode mode = INTPTR_PARAMETERS);
     914             : 
     915             :   // Tries to grow the |elements| array of given |object| to store the |key|
     916             :   // or bails out if the growing gap is too big. Returns new elements.
     917             :   Node* TryGrowElementsCapacity(Node* object, Node* elements, ElementsKind kind,
     918             :                                 Node* key, Label* bailout);
     919             : 
     920             :   // Tries to grow the |capacity|-length |elements| array of given |object|
     921             :   // to store the |key| or bails out if the growing gap is too big. Returns
     922             :   // new elements.
     923             :   Node* TryGrowElementsCapacity(Node* object, Node* elements, ElementsKind kind,
     924             :                                 Node* key, Node* capacity, ParameterMode mode,
     925             :                                 Label* bailout);
     926             : 
     927             :   // Grows elements capacity of given object. Returns new elements.
     928             :   Node* GrowElementsCapacity(Node* object, Node* elements,
     929             :                              ElementsKind from_kind, ElementsKind to_kind,
     930             :                              Node* capacity, Node* new_capacity,
     931             :                              ParameterMode mode, Label* bailout);
     932             : 
     933             :   // Given a need to grow by |growth|, allocate an appropriate new capacity
     934             :   // if necessary, and return a new elements FixedArray object. Label |bailout|
     935             :   // is followed for allocation failure.
     936             :   void PossiblyGrowElementsCapacity(ParameterMode mode, ElementsKind kind,
     937             :                                     Node* array, Node* length,
     938             :                                     Variable* var_elements, Node* growth,
     939             :                                     Label* bailout);
     940             : 
     941             :   // Allocation site manipulation
     942             :   void InitializeAllocationMemento(Node* base_allocation,
     943             :                                    Node* base_allocation_size,
     944             :                                    Node* allocation_site);
     945             : 
     946             :   Node* TryTaggedToFloat64(Node* value, Label* if_valueisnotnumber);
     947             :   Node* TruncateTaggedToFloat64(Node* context, Node* value);
     948             :   Node* TruncateTaggedToWord32(Node* context, Node* value);
     949             :   void TaggedToWord32OrBigInt(Node* context, Node* value, Label* if_number,
     950             :                               Variable* var_word32, Label* if_bigint,
     951             :                               Variable* var_bigint);
     952             :   void TaggedToWord32OrBigIntWithFeedback(
     953             :       Node* context, Node* value, Label* if_number, Variable* var_word32,
     954             :       Label* if_bigint, Variable* var_bigint, Variable* var_feedback);
     955             : 
     956             :   // Truncate the floating point value of a HeapNumber to an Int32.
     957             :   Node* TruncateHeapNumberValueToWord32(Node* object);
     958             : 
     959             :   // Conversions.
     960             :   TNode<Number> ChangeFloat64ToTagged(SloppyTNode<Float64T> value);
     961             :   TNode<Number> ChangeInt32ToTagged(SloppyTNode<Int32T> value);
     962             :   TNode<Number> ChangeUint32ToTagged(SloppyTNode<Uint32T> value);
     963             :   TNode<Float64T> ChangeNumberToFloat64(SloppyTNode<Number> value);
     964             :   TNode<UintPtrT> ChangeNonnegativeNumberToUintPtr(SloppyTNode<Number> value);
     965             : 
     966             :   void TaggedToNumeric(Node* context, Node* value, Label* done,
     967             :                        Variable* var_numeric);
     968             :   void TaggedToNumericWithFeedback(Node* context, Node* value, Label* done,
     969             :                                    Variable* var_numeric,
     970             :                                    Variable* var_feedback);
     971             : 
     972             :   Node* TimesPointerSize(Node* value);
     973             : 
     974             :   // Type conversions.
     975             :   // Throws a TypeError for {method_name} if {value} is not coercible to Object,
     976             :   // or returns the {value} converted to a String otherwise.
     977             :   Node* ToThisString(Node* context, Node* value, char const* method_name);
     978             :   // Throws a TypeError for {method_name} if {value} is neither of the given
     979             :   // {primitive_type} nor a JSValue wrapping a value of {primitive_type}, or
     980             :   // returns the {value} (or wrapped value) otherwise.
     981             :   Node* ToThisValue(Node* context, Node* value, PrimitiveType primitive_type,
     982             :                     char const* method_name);
     983             : 
     984             :   // Throws a TypeError for {method_name}. Terminates the current block.
     985             :   void ThrowIncompatibleMethodReceiver(Node* context, char const* method_name,
     986             :                                        Node* receiver);
     987             : 
     988             :   // Throws a TypeError for {method_name} if {value} is not of the given
     989             :   // instance type. Returns {value}'s map.
     990             :   Node* ThrowIfNotInstanceType(Node* context, Node* value,
     991             :                                InstanceType instance_type,
     992             :                                char const* method_name);
     993             :   // Throws a TypeError for {method_name} if {value} is not a JSReceiver.
     994             :   // Returns the {value}'s map.
     995             :   Node* ThrowIfNotJSReceiver(Node* context, Node* value,
     996             :                              MessageTemplate::Template msg_template,
     997             :                              const char* method_name = nullptr);
     998             :   void ThrowTypeError(Node* context, MessageTemplate::Template message,
     999             :                       char const* arg0 = nullptr, char const* arg1 = nullptr);
    1000             :   void ThrowTypeError(Node* context, MessageTemplate::Template message,
    1001             :                       Node* arg0, Node* arg1 = nullptr, Node* arg2 = nullptr);
    1002             : 
    1003             :   // Type checks.
    1004             :   // Check whether the map is for an object with special properties, such as a
    1005             :   // JSProxy or an object with interceptors.
    1006             :   Node* InstanceTypeEqual(Node* instance_type, int type);
    1007             :   Node* IsAccessorInfo(Node* object);
    1008             :   Node* IsAccessorPair(Node* object);
    1009             :   Node* IsAllocationSite(Node* object);
    1010             :   Node* IsAnyHeapNumber(Node* object);
    1011             :   Node* IsArrayIteratorInstanceType(Node* instance_type);
    1012             :   Node* IsBoolean(Node* object);
    1013             :   Node* IsExtensibleMap(Node* map);
    1014             :   Node* IsCallableMap(Node* map);
    1015             :   Node* IsCallable(Node* object);
    1016             :   Node* IsCell(Node* object);
    1017             :   Node* IsConsStringInstanceType(Node* instance_type);
    1018             :   Node* IsConstructorMap(Node* map);
    1019             :   Node* IsConstructor(Node* object);
    1020             :   Node* IsFunctionWithPrototypeSlotMap(Node* map);
    1021             :   Node* IsDeprecatedMap(Node* map);
    1022             :   Node* IsDictionary(Node* object);
    1023             :   Node* IsExternalStringInstanceType(Node* instance_type);
    1024             :   Node* IsFeedbackVector(Node* object);
    1025             :   Node* IsFixedArray(Node* object);
    1026             :   Node* IsFixedArrayWithKind(Node* object, ElementsKind kind);
    1027             :   Node* IsFixedArrayWithKindOrEmpty(Node* object, ElementsKind kind);
    1028             :   Node* IsFixedDoubleArray(Node* object);
    1029             :   Node* IsFixedTypedArray(Node* object);
    1030             :   Node* IsZeroOrFixedArray(Node* object);
    1031             :   Node* IsHashTable(Node* object);
    1032             :   Node* IsHeapNumber(Node* object);
    1033             :   Node* IsIndirectStringInstanceType(Node* instance_type);
    1034             :   Node* IsJSArrayBuffer(Node* object);
    1035             :   Node* IsJSArrayInstanceType(Node* instance_type);
    1036             :   Node* IsJSArrayMap(Node* object);
    1037             :   Node* IsJSArray(Node* object);
    1038             :   Node* IsJSFunctionInstanceType(Node* instance_type);
    1039             :   Node* IsJSFunctionMap(Node* object);
    1040             :   Node* IsJSFunction(Node* object);
    1041             :   Node* IsJSGlobalProxy(Node* object);
    1042             :   Node* IsJSObjectInstanceType(Node* instance_type);
    1043             :   Node* IsJSObjectMap(Node* map);
    1044             :   Node* IsJSObject(Node* object);
    1045             :   Node* IsJSGlobalProxyInstanceType(Node* instance_type);
    1046             :   Node* IsJSProxy(Node* object);
    1047             :   Node* IsJSReceiverInstanceType(Node* instance_type);
    1048             :   Node* IsJSReceiverMap(Node* map);
    1049             :   Node* IsJSReceiver(Node* object);
    1050             :   Node* IsNullOrJSReceiver(Node* object);
    1051             :   Node* IsJSRegExp(Node* object);
    1052             :   Node* IsJSTypedArray(Node* object);
    1053             :   Node* IsJSValueInstanceType(Node* instance_type);
    1054             :   Node* IsJSValueMap(Node* map);
    1055             :   Node* IsJSValue(Node* object);
    1056             :   Node* IsMap(Node* object);
    1057             :   Node* IsMutableHeapNumber(Node* object);
    1058             :   Node* IsName(Node* object);
    1059             :   Node* IsNativeContext(Node* object);
    1060             :   Node* IsOneByteStringInstanceType(Node* instance_type);
    1061             :   Node* IsPrimitiveInstanceType(Node* instance_type);
    1062             :   Node* IsPrivateSymbol(Node* object);
    1063             :   Node* IsPropertyArray(Node* object);
    1064             :   Node* IsPropertyCell(Node* object);
    1065             :   Node* IsSequentialStringInstanceType(Node* instance_type);
    1066             :   inline Node* IsSharedFunctionInfo(Node* object) {
    1067             :     return IsSharedFunctionInfoMap(LoadMap(object));
    1068             :   }
    1069             :   Node* IsShortExternalStringInstanceType(Node* instance_type);
    1070             :   Node* IsSpecialReceiverInstanceType(Node* instance_type);
    1071             :   Node* IsSpecialReceiverMap(Node* map);
    1072             :   Node* IsStringInstanceType(Node* instance_type);
    1073             :   Node* IsString(Node* object);
    1074             :   Node* IsSymbolInstanceType(Node* instance_type);
    1075             :   Node* IsSymbol(Node* object);
    1076             :   Node* IsBigIntInstanceType(Node* instance_type);
    1077             :   Node* IsBigInt(Node* object);
    1078             :   Node* IsUnseededNumberDictionary(Node* object);
    1079             :   Node* IsWeakCell(Node* object);
    1080             :   Node* IsUndetectableMap(Node* map);
    1081             :   Node* IsArrayProtectorCellInvalid();
    1082             :   Node* IsSpeciesProtectorCellInvalid();
    1083             :   Node* IsPrototypeInitialArrayPrototype(Node* context, Node* map);
    1084             : 
    1085             :   // True iff |object| is a Smi or a HeapNumber.
    1086             :   Node* IsNumber(Node* object);
    1087             :   // True iff |object| is a Smi or a HeapNumber or a BigInt.
    1088             :   Node* IsNumeric(Node* object);
    1089             : 
    1090             :   // True iff |number| is either a Smi, or a HeapNumber whose value is not
    1091             :   // within Smi range.
    1092             :   Node* IsNumberNormalized(Node* number);
    1093             :   Node* IsNumberPositive(Node* number);
    1094             :   // True iff {number} is a positive number and a valid array index in the range
    1095             :   // [0, 2^32-1).
    1096             :   Node* IsNumberArrayIndex(Node* number);
    1097             : 
    1098             :   // ElementsKind helpers:
    1099             :   Node* IsFastElementsKind(Node* elements_kind);
    1100             :   Node* IsHoleyFastElementsKind(Node* elements_kind);
    1101             :   Node* IsElementsKindGreaterThan(Node* target_kind,
    1102             :                                   ElementsKind reference_kind);
    1103             : 
    1104             :   Node* FixedArraySizeDoesntFitInNewSpace(
    1105             :       Node* element_count, int base_size = FixedArray::kHeaderSize,
    1106             :       ParameterMode mode = INTPTR_PARAMETERS);
    1107             : 
    1108             :   // String helpers.
    1109             :   // Load a character from a String (might flatten a ConsString).
    1110             :   TNode<Uint32T> StringCharCodeAt(
    1111             :       SloppyTNode<String> string, Node* index,
    1112             :       ParameterMode parameter_mode = SMI_PARAMETERS);
    1113             :   // Return the single character string with only {code}.
    1114             :   Node* StringFromCharCode(Node* code);
    1115             : 
    1116             :   enum class SubStringFlags { NONE, FROM_TO_ARE_BOUNDED };
    1117             : 
    1118             :   // Return a new string object which holds a substring containing the range
    1119             :   // [from,to[ of string.  |from| and |to| are expected to be tagged.
    1120             :   // If flags has the value FROM_TO_ARE_BOUNDED then from and to are in
    1121             :   // the range [0, string-length)
    1122             :   Node* SubString(Node* context, Node* string, Node* from, Node* to,
    1123             :                   SubStringFlags flags = SubStringFlags::NONE);
    1124             : 
    1125             :   // Return a new string object produced by concatenating |first| with |second|.
    1126             :   Node* StringAdd(Node* context, Node* first, Node* second,
    1127             :                   AllocationFlags flags = kNone);
    1128             : 
    1129             :   // Check if |string| is an indirect (thin or flat cons) string type that can
    1130             :   // be dereferenced by DerefIndirectString.
    1131             :   void BranchIfCanDerefIndirectString(Node* string, Node* instance_type,
    1132             :                                       Label* can_deref, Label* cannot_deref);
    1133             :   // Unpack an indirect (thin or flat cons) string type.
    1134             :   void DerefIndirectString(Variable* var_string, Node* instance_type);
    1135             :   // Check if |var_string| has an indirect (thin or flat cons) string type,
    1136             :   // and unpack it if so.
    1137             :   void MaybeDerefIndirectString(Variable* var_string, Node* instance_type,
    1138             :                                 Label* did_deref, Label* cannot_deref);
    1139             :   // Check if |var_left| or |var_right| has an indirect (thin or flat cons)
    1140             :   // string type, and unpack it/them if so. Fall through if nothing was done.
    1141             :   void MaybeDerefIndirectStrings(Variable* var_left, Node* left_instance_type,
    1142             :                                  Variable* var_right, Node* right_instance_type,
    1143             :                                  Label* did_something);
    1144             : 
    1145             :   Node* StringFromCodePoint(Node* codepoint, UnicodeEncoding encoding);
    1146             : 
    1147             :   // Type conversion helpers.
    1148             :   // Convert a String to a Number.
    1149             :   TNode<Number> StringToNumber(SloppyTNode<Context> context,
    1150             :                                SloppyTNode<String> input);
    1151             :   Node* NumberToString(Node* context, Node* input);
    1152             :   // Convert an object to a name.
    1153             :   Node* ToName(Node* context, Node* input);
    1154             :   // Convert a Non-Number object to a Number.
    1155             :   TNode<Number> NonNumberToNumber(SloppyTNode<Context> context,
    1156             :                                   SloppyTNode<HeapObject> input);
    1157             :   // Convert a Non-Number object to a Numeric.
    1158             :   TNode<Numeric> NonNumberToNumeric(SloppyTNode<Context> context,
    1159             :                                     SloppyTNode<HeapObject> input);
    1160             :   // Convert any object to a Number.
    1161             :   TNode<Number> ToNumber(SloppyTNode<Context> context,
    1162             :                          SloppyTNode<Object> input);
    1163             : 
    1164             :   // Converts |input| to one of 2^32 integer values in the range 0 through
    1165             :   // 2^32-1, inclusive.
    1166             :   // ES#sec-touint32
    1167             :   TNode<Number> ToUint32(SloppyTNode<Context> context,
    1168             :                          SloppyTNode<Object> input);
    1169             : 
    1170             :   // Convert any object to a String.
    1171             :   TNode<String> ToString(SloppyTNode<Context> context,
    1172             :                          SloppyTNode<Object> input);
    1173             :   Node* ToString_Inline(Node* const context, Node* const input);
    1174             : 
    1175             :   // Convert any object to a Primitive.
    1176             :   Node* JSReceiverToPrimitive(Node* context, Node* input);
    1177             : 
    1178             :   enum ToIntegerTruncationMode {
    1179             :     kNoTruncation,
    1180             :     kTruncateMinusZero,
    1181             :   };
    1182             : 
    1183             :   // ES6 7.1.17 ToIndex, but jumps to range_error if the result is not a Smi.
    1184             :   Node* ToSmiIndex(Node* const input, Node* const context, Label* range_error);
    1185             : 
    1186             :   // ES6 7.1.15 ToLength, but jumps to range_error if the result is not a Smi.
    1187             :   Node* ToSmiLength(Node* input, Node* const context, Label* range_error);
    1188             : 
    1189             :   // ES6 7.1.15 ToLength, but with inlined fast path.
    1190             :   Node* ToLength_Inline(Node* const context, Node* const input);
    1191             : 
    1192             :   // Convert any object to an Integer.
    1193             :   TNode<Number> ToInteger(SloppyTNode<Context> context,
    1194             :                           SloppyTNode<Object> input,
    1195             :                           ToIntegerTruncationMode mode = kNoTruncation);
    1196             : 
    1197             :   // Returns a node that contains a decoded (unsigned!) value of a bit
    1198             :   // field |BitField| in |word32|. Returns result as an uint32 node.
    1199             :   template <typename BitField>
    1200             :   TNode<Uint32T> DecodeWord32(SloppyTNode<Word32T> word32) {
    1201       10445 :     return DecodeWord32(word32, BitField::kShift, BitField::kMask);
    1202             :   }
    1203             : 
    1204             :   // Returns a node that contains a decoded (unsigned!) value of a bit
    1205             :   // field |BitField| in |word|. Returns result as a word-size node.
    1206             :   template <typename BitField>
    1207             :   Node* DecodeWord(Node* word) {
    1208       12951 :     return DecodeWord(word, BitField::kShift, BitField::kMask);
    1209             :   }
    1210             : 
    1211             :   // Returns a node that contains a decoded (unsigned!) value of a bit
    1212             :   // field |BitField| in |word32|. Returns result as a word-size node.
    1213             :   template <typename BitField>
    1214        2659 :   Node* DecodeWordFromWord32(Node* word32) {
    1215        5318 :     return DecodeWord<BitField>(ChangeUint32ToWord(word32));
    1216             :   }
    1217             : 
    1218             :   // Returns a node that contains a decoded (unsigned!) value of a bit
    1219             :   // field |BitField| in |word|. Returns result as an uint32 node.
    1220             :   template <typename BitField>
    1221          31 :   Node* DecodeWord32FromWord(Node* word) {
    1222          62 :     return TruncateWordToWord32(DecodeWord<BitField>(word));
    1223             :   }
    1224             : 
    1225             :   // Decodes an unsigned (!) value from |word32| to an uint32 node.
    1226             :   TNode<Uint32T> DecodeWord32(SloppyTNode<Word32T> word32, uint32_t shift,
    1227             :                               uint32_t mask);
    1228             : 
    1229             :   // Decodes an unsigned (!) value from |word| to a word-size node.
    1230             :   Node* DecodeWord(Node* word, uint32_t shift, uint32_t mask);
    1231             : 
    1232             :   // Returns a node that contains the updated values of a |BitField|.
    1233             :   template <typename BitField>
    1234             :   Node* UpdateWord(Node* word, Node* value) {
    1235         217 :     return UpdateWord(word, value, BitField::kShift, BitField::kMask);
    1236             :   }
    1237             : 
    1238             :   // Returns a node that contains the updated {value} inside {word} starting
    1239             :   // at {shift} and fitting in {mask}.
    1240             :   Node* UpdateWord(Node* word, Node* value, uint32_t shift, uint32_t mask);
    1241             : 
    1242             :   // Returns true if any of the |T|'s bits in given |word32| are set.
    1243             :   template <typename T>
    1244             :   TNode<BoolT> IsSetWord32(SloppyTNode<Word32T> word32) {
    1245        9263 :     return IsSetWord32(word32, T::kMask);
    1246             :   }
    1247             : 
    1248             :   // Returns true if any of the mask's bits in given |word32| are set.
    1249       24680 :   TNode<BoolT> IsSetWord32(SloppyTNode<Word32T> word32, uint32_t mask) {
    1250       49360 :     return Word32NotEqual(Word32And(word32, Int32Constant(mask)),
    1251       98720 :                           Int32Constant(0));
    1252             :   }
    1253             : 
    1254             :   // Returns true if none of the mask's bits in given |word32| are set.
    1255         155 :   TNode<BoolT> IsNotSetWord32(SloppyTNode<Word32T> word32, uint32_t mask) {
    1256         310 :     return Word32Equal(Word32And(word32, Int32Constant(mask)),
    1257         620 :                        Int32Constant(0));
    1258             :   }
    1259             : 
    1260             :   // Returns true if any of the |T|'s bits in given |word| are set.
    1261             :   template <typename T>
    1262             :   Node* IsSetWord(Node* word) {
    1263        7471 :     return IsSetWord(word, T::kMask);
    1264             :   }
    1265             : 
    1266             :   // Returns true if any of the mask's bits in given |word| are set.
    1267        9461 :   Node* IsSetWord(Node* word, uint32_t mask) {
    1268       47305 :     return WordNotEqual(WordAnd(word, IntPtrConstant(mask)), IntPtrConstant(0));
    1269             :   }
    1270             : 
    1271             :   // Returns true if any of the mask's bit are set in the given Smi.
    1272             :   // Smi-encoding of the mask is performed implicitly!
    1273         403 :   Node* IsSetSmi(Node* smi, int untagged_mask) {
    1274             :     intptr_t mask_word = bit_cast<intptr_t>(Smi::FromInt(untagged_mask));
    1275             :     return WordNotEqual(
    1276        1209 :         WordAnd(BitcastTaggedToWord(smi), IntPtrConstant(mask_word)),
    1277        1612 :         IntPtrConstant(0));
    1278             :   }
    1279             : 
    1280             :   // Returns true if all of the |T|'s bits in given |word32| are clear.
    1281             :   template <typename T>
    1282             :   Node* IsClearWord32(Node* word32) {
    1283         279 :     return IsClearWord32(word32, T::kMask);
    1284             :   }
    1285             : 
    1286             :   // Returns true if all of the mask's bits in given |word32| are clear.
    1287        1686 :   Node* IsClearWord32(Node* word32, uint32_t mask) {
    1288        3372 :     return Word32Equal(Word32And(word32, Int32Constant(mask)),
    1289        8430 :                        Int32Constant(0));
    1290             :   }
    1291             : 
    1292             :   // Returns true if all of the |T|'s bits in given |word| are clear.
    1293             :   template <typename T>
    1294             :   Node* IsClearWord(Node* word) {
    1295             :     return IsClearWord(word, T::kMask);
    1296             :   }
    1297             : 
    1298             :   // Returns true if all of the mask's bits in given |word| are clear.
    1299             :   Node* IsClearWord(Node* word, uint32_t mask) {
    1300             :     return WordEqual(WordAnd(word, IntPtrConstant(mask)), IntPtrConstant(0));
    1301             :   }
    1302             : 
    1303             :   void SetCounter(StatsCounter* counter, int value);
    1304             :   void IncrementCounter(StatsCounter* counter, int delta);
    1305             :   void DecrementCounter(StatsCounter* counter, int delta);
    1306             : 
    1307             :   void Increment(Variable* variable, int value = 1,
    1308             :                  ParameterMode mode = INTPTR_PARAMETERS);
    1309             :   void Decrement(Variable* variable, int value = 1,
    1310             :                  ParameterMode mode = INTPTR_PARAMETERS) {
    1311          31 :     Increment(variable, -value, mode);
    1312             :   }
    1313             : 
    1314             :   // Generates "if (false) goto label" code. Useful for marking a label as
    1315             :   // "live" to avoid assertion failures during graph building. In the resulting
    1316             :   // code this check will be eliminated.
    1317             :   void Use(Label* label);
    1318             : 
    1319             :   // Various building blocks for stubs doing property lookups.
    1320             : 
    1321             :   // |if_notinternalized| is optional; |if_bailout| will be used by default.
    1322             :   void TryToName(Node* key, Label* if_keyisindex, Variable* var_index,
    1323             :                  Label* if_keyisunique, Variable* var_unique, Label* if_bailout,
    1324             :                  Label* if_notinternalized = nullptr);
    1325             : 
    1326             :   // Performs a hash computation and string table lookup for the given string,
    1327             :   // and jumps to:
    1328             :   // - |if_index| if the string is an array index like "123"; |var_index|
    1329             :   //              will contain the intptr representation of that index.
    1330             :   // - |if_internalized| if the string exists in the string table; the
    1331             :   //                     internalized version will be in |var_internalized|.
    1332             :   // - |if_not_internalized| if the string is not in the string table (but
    1333             :   //                         does not add it).
    1334             :   // - |if_bailout| for unsupported cases (e.g. uncachable array index).
    1335             :   void TryInternalizeString(Node* string, Label* if_index, Variable* var_index,
    1336             :                             Label* if_internalized, Variable* var_internalized,
    1337             :                             Label* if_not_internalized, Label* if_bailout);
    1338             : 
    1339             :   // Calculates array index for given dictionary entry and entry field.
    1340             :   // See Dictionary::EntryToIndex().
    1341             :   template <typename Dictionary>
    1342             :   Node* EntryToIndex(Node* entry, int field_index);
    1343             :   template <typename Dictionary>
    1344             :   Node* EntryToIndex(Node* entry) {
    1345       21234 :     return EntryToIndex<Dictionary>(entry, Dictionary::kEntryKeyIndex);
    1346             :   }
    1347             : 
    1348             :   // Loads the details for the entry with the given key_index.
    1349             :   // Returns an untagged int32.
    1350             :   template <class ContainerType>
    1351             :   Node* LoadDetailsByKeyIndex(Node* container, Node* key_index) {
    1352             :     const int kKeyToDetailsOffset =
    1353             :         (ContainerType::kEntryDetailsIndex - ContainerType::kEntryKeyIndex) *
    1354             :         kPointerSize;
    1355             :     return LoadAndUntagToWord32FixedArrayElement(container, key_index,
    1356        3205 :                                                  kKeyToDetailsOffset);
    1357             :   }
    1358             : 
    1359             :   // Loads the value for the entry with the given key_index.
    1360             :   // Returns a tagged value.
    1361             :   template <class ContainerType>
    1362             :   Node* LoadValueByKeyIndex(Node* container, Node* key_index) {
    1363             :     const int kKeyToValueOffset =
    1364             :         (ContainerType::kEntryValueIndex - ContainerType::kEntryKeyIndex) *
    1365             :         kPointerSize;
    1366        2864 :     return LoadFixedArrayElement(container, key_index, kKeyToValueOffset);
    1367             :   }
    1368             : 
    1369             :   // Stores the details for the entry with the given key_index.
    1370             :   // |details| must be a Smi.
    1371             :   template <class ContainerType>
    1372             :   void StoreDetailsByKeyIndex(Node* container, Node* key_index, Node* details) {
    1373             :     const int kKeyToDetailsOffset =
    1374             :         (ContainerType::kEntryDetailsIndex - ContainerType::kEntryKeyIndex) *
    1375             :         kPointerSize;
    1376         434 :     StoreFixedArrayElement(container, key_index, details, SKIP_WRITE_BARRIER,
    1377             :                            kKeyToDetailsOffset);
    1378             :   }
    1379             : 
    1380             :   // Stores the value for the entry with the given key_index.
    1381             :   template <class ContainerType>
    1382             :   void StoreValueByKeyIndex(
    1383             :       Node* container, Node* key_index, Node* value,
    1384             :       WriteBarrierMode write_barrier = UPDATE_WRITE_BARRIER) {
    1385             :     const int kKeyToValueOffset =
    1386             :         (ContainerType::kEntryValueIndex - ContainerType::kEntryKeyIndex) *
    1387             :         kPointerSize;
    1388         806 :     StoreFixedArrayElement(container, key_index, value, write_barrier,
    1389             :                            kKeyToValueOffset);
    1390             :   }
    1391             : 
    1392             :   // Calculate a valid size for the a hash table.
    1393             :   TNode<IntPtrT> HashTableComputeCapacity(
    1394             :       SloppyTNode<IntPtrT> at_least_space_for);
    1395             : 
    1396             :   template <class Dictionary>
    1397             :   Node* GetNumberOfElements(Node* dictionary) {
    1398             :     return LoadFixedArrayElement(dictionary,
    1399         434 :                                  Dictionary::kNumberOfElementsIndex);
    1400             :   }
    1401             : 
    1402             :   template <class Dictionary>
    1403             :   void SetNumberOfElements(Node* dictionary, Node* num_elements_smi) {
    1404         434 :     StoreFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex,
    1405             :                            num_elements_smi, SKIP_WRITE_BARRIER);
    1406             :   }
    1407             : 
    1408             :   template <class Dictionary>
    1409             :   Node* GetNumberOfDeletedElements(Node* dictionary) {
    1410             :     return LoadFixedArrayElement(dictionary,
    1411         434 :                                  Dictionary::kNumberOfDeletedElementsIndex);
    1412             :   }
    1413             : 
    1414             :   template <class Dictionary>
    1415             :   void SetNumberOfDeletedElements(Node* dictionary, Node* num_deleted_smi) {
    1416          31 :     StoreFixedArrayElement(dictionary,
    1417             :                            Dictionary::kNumberOfDeletedElementsIndex,
    1418             :                            num_deleted_smi, SKIP_WRITE_BARRIER);
    1419             :   }
    1420             : 
    1421             :   template <class Dictionary>
    1422             :   Node* GetCapacity(Node* dictionary) {
    1423        5386 :     return LoadFixedArrayElement(dictionary, Dictionary::kCapacityIndex);
    1424             :   }
    1425             : 
    1426             :   template <class Dictionary>
    1427             :   Node* GetNextEnumerationIndex(Node* dictionary);
    1428             : 
    1429             :   template <class Dictionary>
    1430             :   void SetNextEnumerationIndex(Node* dictionary, Node* next_enum_index_smi);
    1431             : 
    1432             :   // Looks up an entry in a NameDictionaryBase successor. If the entry is found
    1433             :   // control goes to {if_found} and {var_name_index} contains an index of the
    1434             :   // key field of the entry found. If the key is not found control goes to
    1435             :   // {if_not_found}.
    1436             :   static const int kInlinedDictionaryProbes = 4;
    1437             :   enum LookupMode { kFindExisting, kFindInsertionIndex };
    1438             : 
    1439             :   template <typename Dictionary>
    1440             :   Node* LoadName(Node* key);
    1441             : 
    1442             :   template <typename Dictionary>
    1443             :   void NameDictionaryLookup(Node* dictionary, Node* unique_name,
    1444             :                             Label* if_found, Variable* var_name_index,
    1445             :                             Label* if_not_found,
    1446             :                             int inlined_probes = kInlinedDictionaryProbes,
    1447             :                             LookupMode mode = kFindExisting);
    1448             : 
    1449             :   Node* ComputeIntegerHash(Node* key);
    1450             :   Node* ComputeIntegerHash(Node* key, Node* seed);
    1451             : 
    1452             :   template <typename Dictionary>
    1453             :   void NumberDictionaryLookup(Node* dictionary, Node* intptr_index,
    1454             :                               Label* if_found, Variable* var_entry,
    1455             :                               Label* if_not_found);
    1456             : 
    1457             :   template <class Dictionary>
    1458             :   void FindInsertionEntry(Node* dictionary, Node* key, Variable* var_key_index);
    1459             : 
    1460             :   template <class Dictionary>
    1461             :   void InsertEntry(Node* dictionary, Node* key, Node* value, Node* index,
    1462             :                    Node* enum_index);
    1463             : 
    1464             :   template <class Dictionary>
    1465             :   void Add(Node* dictionary, Node* key, Node* value, Label* bailout);
    1466             : 
    1467             :   // Tries to check if {object} has own {unique_name} property.
    1468             :   void TryHasOwnProperty(Node* object, Node* map, Node* instance_type,
    1469             :                          Node* unique_name, Label* if_found,
    1470             :                          Label* if_not_found, Label* if_bailout);
    1471             : 
    1472             :   // Operating mode for TryGetOwnProperty and CallGetterIfAccessor
    1473             :   // kReturnAccessorPair is used when we're only getting the property descriptor
    1474             :   enum GetOwnPropertyMode { kCallJSGetter, kReturnAccessorPair };
    1475             :   // Tries to get {object}'s own {unique_name} property value. If the property
    1476             :   // is an accessor then it also calls a getter. If the property is a double
    1477             :   // field it re-wraps value in an immutable heap number.
    1478             :   void TryGetOwnProperty(Node* context, Node* receiver, Node* object, Node* map,
    1479             :                          Node* instance_type, Node* unique_name,
    1480             :                          Label* if_found, Variable* var_value,
    1481             :                          Label* if_not_found, Label* if_bailout);
    1482             :   void TryGetOwnProperty(Node* context, Node* receiver, Node* object, Node* map,
    1483             :                          Node* instance_type, Node* unique_name,
    1484             :                          Label* if_found, Variable* var_value,
    1485             :                          Variable* var_details, Variable* var_raw_value,
    1486             :                          Label* if_not_found, Label* if_bailout,
    1487             :                          GetOwnPropertyMode mode = kCallJSGetter);
    1488             : 
    1489        3168 :   Node* GetProperty(Node* context, Node* receiver, Handle<Name> name) {
    1490        6336 :     return GetProperty(context, receiver, HeapConstant(name));
    1491             :   }
    1492             : 
    1493        3602 :   Node* GetProperty(Node* context, Node* receiver, Node* const name) {
    1494             :     return CallStub(CodeFactory::GetProperty(isolate()), context, receiver,
    1495        3602 :                     name);
    1496             :   }
    1497             : 
    1498             :   Node* GetMethod(Node* context, Node* object, Handle<Name> name,
    1499             :                   Label* if_null_or_undefined);
    1500             : 
    1501             :   template <class... TArgs>
    1502       20677 :   Node* CallBuiltin(Builtins::Name id, Node* context, TArgs... args) {
    1503       20677 :     return CallStub(Builtins::CallableFor(isolate(), id), context, args...);
    1504             :   }
    1505             : 
    1506             :   template <class... TArgs>
    1507         589 :   Node* TailCallBuiltin(Builtins::Name id, Node* context, TArgs... args) {
    1508         589 :     return TailCallStub(Builtins::CallableFor(isolate(), id), context, args...);
    1509             :   }
    1510             : 
    1511             :   void LoadPropertyFromFastObject(Node* object, Node* map, Node* descriptors,
    1512             :                                   Node* name_index, Variable* var_details,
    1513             :                                   Variable* var_value);
    1514             : 
    1515             :   void LoadPropertyFromNameDictionary(Node* dictionary, Node* entry,
    1516             :                                       Variable* var_details,
    1517             :                                       Variable* var_value);
    1518             : 
    1519             :   void LoadPropertyFromGlobalDictionary(Node* dictionary, Node* entry,
    1520             :                                         Variable* var_details,
    1521             :                                         Variable* var_value, Label* if_deleted);
    1522             : 
    1523             :   // Generic property lookup generator. If the {object} is fast and
    1524             :   // {unique_name} property is found then the control goes to {if_found_fast}
    1525             :   // label and {var_meta_storage} and {var_name_index} will contain
    1526             :   // DescriptorArray and an index of the descriptor's name respectively.
    1527             :   // If the {object} is slow or global then the control goes to {if_found_dict}
    1528             :   // or {if_found_global} and the {var_meta_storage} and {var_name_index} will
    1529             :   // contain a dictionary and an index of the key field of the found entry.
    1530             :   // If property is not found or given lookup is not supported then
    1531             :   // the control goes to {if_not_found} or {if_bailout} respectively.
    1532             :   //
    1533             :   // Note: this code does not check if the global dictionary points to deleted
    1534             :   // entry! This has to be done by the caller.
    1535             :   void TryLookupProperty(Node* object, Node* map, Node* instance_type,
    1536             :                          Node* unique_name, Label* if_found_fast,
    1537             :                          Label* if_found_dict, Label* if_found_global,
    1538             :                          Variable* var_meta_storage, Variable* var_name_index,
    1539             :                          Label* if_not_found, Label* if_bailout);
    1540             : 
    1541             :   // This method jumps to if_found if the element is known to exist. To
    1542             :   // if_absent if it's known to not exist. To if_not_found if the prototype
    1543             :   // chain needs to be checked. And if_bailout if the lookup is unsupported.
    1544             :   void TryLookupElement(Node* object, Node* map, Node* instance_type,
    1545             :                         Node* intptr_index, Label* if_found, Label* if_absent,
    1546             :                         Label* if_not_found, Label* if_bailout);
    1547             : 
    1548             :   // This is a type of a lookup in holder generator function. In case of a
    1549             :   // property lookup the {key} is guaranteed to be an unique name and in case of
    1550             :   // element lookup the key is an Int32 index.
    1551             :   typedef std::function<void(Node* receiver, Node* holder, Node* map,
    1552             :                              Node* instance_type, Node* key, Label* next_holder,
    1553             :                              Label* if_bailout)>
    1554             :       LookupInHolder;
    1555             : 
    1556             :   // Generic property prototype chain lookup generator.
    1557             :   // For properties it generates lookup using given {lookup_property_in_holder}
    1558             :   // and for elements it uses {lookup_element_in_holder}.
    1559             :   // Upon reaching the end of prototype chain the control goes to {if_end}.
    1560             :   // If it can't handle the case {receiver}/{key} case then the control goes
    1561             :   // to {if_bailout}.
    1562             :   // If {if_proxy} is nullptr, proxies go to if_bailout.
    1563             :   void TryPrototypeChainLookup(Node* receiver, Node* key,
    1564             :                                const LookupInHolder& lookup_property_in_holder,
    1565             :                                const LookupInHolder& lookup_element_in_holder,
    1566             :                                Label* if_end, Label* if_bailout,
    1567             :                                Label* if_proxy = nullptr);
    1568             : 
    1569             :   // Instanceof helpers.
    1570             :   // Returns true if {object} has {prototype} somewhere in it's prototype
    1571             :   // chain, otherwise false is returned. Might cause arbitrary side effects
    1572             :   // due to [[GetPrototypeOf]] invocations.
    1573             :   Node* HasInPrototypeChain(Node* context, Node* object, Node* prototype);
    1574             :   // ES6 section 7.3.19 OrdinaryHasInstance (C, O)
    1575             :   Node* OrdinaryHasInstance(Node* context, Node* callable, Node* object);
    1576             : 
    1577             :   // Load type feedback vector from the stub caller's frame.
    1578             :   Node* LoadFeedbackVectorForStub();
    1579             : 
    1580             :   // Load type feedback vector for the given closure.
    1581             :   Node* LoadFeedbackVector(Node* closure);
    1582             : 
    1583             :   // Update the type feedback vector.
    1584             :   void UpdateFeedback(Node* feedback, Node* feedback_vector, Node* slot_id);
    1585             : 
    1586             :   // Combine the new feedback with the existing_feedback.
    1587             :   void CombineFeedback(Variable* existing_feedback, Node* feedback);
    1588             : 
    1589             :   // Check if a property name might require protector invalidation when it is
    1590             :   // used for a property store or deletion.
    1591             :   void CheckForAssociatedProtector(Node* name, Label* if_protector);
    1592             : 
    1593             :   Node* LoadReceiverMap(Node* receiver);
    1594             : 
    1595             :   // Emits keyed sloppy arguments load. Returns either the loaded value.
    1596             :   Node* LoadKeyedSloppyArguments(Node* receiver, Node* key, Label* bailout) {
    1597         295 :     return EmitKeyedSloppyArguments(receiver, key, nullptr, bailout);
    1598             :   }
    1599             : 
    1600             :   // Emits keyed sloppy arguments store.
    1601             :   void StoreKeyedSloppyArguments(Node* receiver, Node* key, Node* value,
    1602             :                                  Label* bailout) {
    1603             :     DCHECK_NOT_NULL(value);
    1604           0 :     EmitKeyedSloppyArguments(receiver, key, value, bailout);
    1605             :   }
    1606             : 
    1607             :   // Loads script context from the script context table.
    1608             :   Node* LoadScriptContext(Node* context, int context_index);
    1609             : 
    1610             :   Node* Int32ToUint8Clamped(Node* int32_value);
    1611             :   Node* Float64ToUint8Clamped(Node* float64_value);
    1612             : 
    1613             :   Node* PrepareValueForWriteToTypedArray(Node* key, ElementsKind elements_kind,
    1614             :                                          Label* bailout);
    1615             : 
    1616             :   // Store value to an elements array with given elements kind.
    1617             :   void StoreElement(Node* elements, ElementsKind kind, Node* index, Node* value,
    1618             :                     ParameterMode mode);
    1619             : 
    1620             :   void EmitElementStore(Node* object, Node* key, Node* value, bool is_jsarray,
    1621             :                         ElementsKind elements_kind,
    1622             :                         KeyedAccessStoreMode store_mode, Label* bailout);
    1623             : 
    1624             :   Node* CheckForCapacityGrow(Node* object, Node* elements, ElementsKind kind,
    1625             :                              Node* length, Node* key, ParameterMode mode,
    1626             :                              bool is_js_array, Label* bailout);
    1627             : 
    1628             :   Node* CopyElementsOnWrite(Node* object, Node* elements, ElementsKind kind,
    1629             :                             Node* length, ParameterMode mode, Label* bailout);
    1630             : 
    1631             :   void TransitionElementsKind(Node* object, Node* map, ElementsKind from_kind,
    1632             :                               ElementsKind to_kind, bool is_jsarray,
    1633             :                               Label* bailout);
    1634             : 
    1635             :   void TrapAllocationMemento(Node* object, Label* memento_found);
    1636             : 
    1637             :   Node* PageFromAddress(Node* address);
    1638             : 
    1639             :   // Create a new weak cell with a specified value and install it into a
    1640             :   // feedback vector.
    1641             :   Node* CreateWeakCellInFeedbackVector(Node* feedback_vector, Node* slot,
    1642             :                                        Node* value);
    1643             : 
    1644             :   // Create a new AllocationSite and install it into a feedback vector.
    1645             :   Node* CreateAllocationSiteInFeedbackVector(Node* feedback_vector, Node* slot);
    1646             : 
    1647             :   // Given a recently allocated object {object}, with map {initial_map},
    1648             :   // initialize remaining fields appropriately to comply with slack tracking.
    1649             :   void HandleSlackTracking(Node* context, Node* object, Node* initial_map,
    1650             :                            int start_offset);
    1651             : 
    1652             :   enum class IndexAdvanceMode { kPre, kPost };
    1653             : 
    1654             :   typedef std::function<void(Node* index)> FastLoopBody;
    1655             : 
    1656             :   Node* BuildFastLoop(const VariableList& var_list, Node* start_index,
    1657             :                       Node* end_index, const FastLoopBody& body, int increment,
    1658             :                       ParameterMode parameter_mode,
    1659             :                       IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre);
    1660             : 
    1661        5930 :   Node* BuildFastLoop(Node* start_index, Node* end_index,
    1662             :                       const FastLoopBody& body, int increment,
    1663             :                       ParameterMode parameter_mode,
    1664             :                       IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre) {
    1665             :     return BuildFastLoop(VariableList(0, zone()), start_index, end_index, body,
    1666        5930 :                          increment, parameter_mode, advance_mode);
    1667             :   }
    1668             : 
    1669             :   enum class ForEachDirection { kForward, kReverse };
    1670             : 
    1671             :   typedef std::function<void(Node* fixed_array, Node* offset)>
    1672             :       FastFixedArrayForEachBody;
    1673             : 
    1674             :   void BuildFastFixedArrayForEach(
    1675             :       const CodeStubAssembler::VariableList& vars, Node* fixed_array,
    1676             :       ElementsKind kind, Node* first_element_inclusive,
    1677             :       Node* last_element_exclusive, const FastFixedArrayForEachBody& body,
    1678             :       ParameterMode mode = INTPTR_PARAMETERS,
    1679             :       ForEachDirection direction = ForEachDirection::kReverse);
    1680             : 
    1681        5907 :   void BuildFastFixedArrayForEach(
    1682             :       Node* fixed_array, ElementsKind kind, Node* first_element_inclusive,
    1683             :       Node* last_element_exclusive, const FastFixedArrayForEachBody& body,
    1684             :       ParameterMode mode = INTPTR_PARAMETERS,
    1685             :       ForEachDirection direction = ForEachDirection::kReverse) {
    1686        5907 :     CodeStubAssembler::VariableList list(0, zone());
    1687             :     BuildFastFixedArrayForEach(list, fixed_array, kind, first_element_inclusive,
    1688        5907 :                                last_element_exclusive, body, mode, direction);
    1689        5907 :   }
    1690             : 
    1691             :   Node* GetArrayAllocationSize(Node* element_count, ElementsKind kind,
    1692             :                                ParameterMode mode, int header_size) {
    1693        9441 :     return ElementOffsetFromIndex(element_count, kind, mode, header_size);
    1694             :   }
    1695             : 
    1696             :   Node* GetFixedArrayAllocationSize(Node* element_count, ElementsKind kind,
    1697             :                                     ParameterMode mode) {
    1698             :     return GetArrayAllocationSize(element_count, kind, mode,
    1699             :                                   FixedArray::kHeaderSize);
    1700             :   }
    1701             : 
    1702             :   Node* GetPropertyArrayAllocationSize(Node* element_count,
    1703             :                                        ParameterMode mode) {
    1704             :     return GetArrayAllocationSize(element_count, PACKED_ELEMENTS, mode,
    1705             :                                   PropertyArray::kHeaderSize);
    1706             :   }
    1707             : 
    1708             :   void GotoIfFixedArraySizeDoesntFitInNewSpace(Node* element_count,
    1709             :                                                Label* doesnt_fit, int base_size,
    1710             :                                                ParameterMode mode);
    1711             : 
    1712             :   void InitializeFieldsWithRoot(Node* object, Node* start_offset,
    1713             :                                 Node* end_offset, Heap::RootListIndex root);
    1714             : 
    1715             :   enum RelationalComparisonMode {
    1716             :     kLessThan,
    1717             :     kLessThanOrEqual,
    1718             :     kGreaterThan,
    1719             :     kGreaterThanOrEqual
    1720             :   };
    1721             : 
    1722             :   Node* RelationalComparison(RelationalComparisonMode mode, Node* lhs,
    1723             :                              Node* rhs, Node* context,
    1724             :                              Variable* var_type_feedback = nullptr);
    1725             : 
    1726             :   void BranchIfNumericRelationalComparison(RelationalComparisonMode mode,
    1727             :                                            Node* lhs, Node* rhs, Label* if_true,
    1728             :                                            Label* if_false);
    1729             : 
    1730          93 :   void BranchIfAccessorPair(Node* value, Label* if_accessor_pair,
    1731             :                             Label* if_not_accessor_pair) {
    1732         186 :     GotoIf(TaggedIsSmi(value), if_not_accessor_pair);
    1733         186 :     Branch(IsAccessorPair(value), if_accessor_pair, if_not_accessor_pair);
    1734          93 :   }
    1735             : 
    1736             :   void GotoIfNumberGreaterThanOrEqual(Node* lhs, Node* rhs, Label* if_false);
    1737             : 
    1738             :   Node* Equal(Node* lhs, Node* rhs, Node* context,
    1739             :               Variable* var_type_feedback = nullptr);
    1740             : 
    1741             :   Node* StrictEqual(Node* lhs, Node* rhs,
    1742             :                     Variable* var_type_feedback = nullptr);
    1743             : 
    1744             :   // ECMA#sec-samevalue
    1745             :   // Similar to StrictEqual except that NaNs are treated as equal and minus zero
    1746             :   // differs from positive zero.
    1747             :   void BranchIfSameValue(Node* lhs, Node* rhs, Label* if_true, Label* if_false);
    1748             : 
    1749             :   enum HasPropertyLookupMode { kHasProperty, kForInHasProperty };
    1750             : 
    1751             :   Node* HasProperty(Node* object, Node* key, Node* context,
    1752             :                     HasPropertyLookupMode mode);
    1753             : 
    1754             :   Node* ClassOf(Node* object);
    1755             : 
    1756             :   Node* Typeof(Node* value);
    1757             : 
    1758             :   Node* GetSuperConstructor(Node* value, Node* context);
    1759             : 
    1760             :   Node* InstanceOf(Node* object, Node* callable, Node* context);
    1761             : 
    1762             :   // Debug helpers
    1763             :   Node* IsDebugActive();
    1764             : 
    1765             :   // TypedArray/ArrayBuffer helpers
    1766             :   Node* IsDetachedBuffer(Node* buffer);
    1767             : 
    1768             :   Node* ElementOffsetFromIndex(Node* index, ElementsKind kind,
    1769             :                                ParameterMode mode, int base_size = 0);
    1770             : 
    1771             :   Node* AllocateFunctionWithMapAndContext(Node* map, Node* shared_info,
    1772             :                                           Node* context);
    1773             : 
    1774             :   // Promise helpers
    1775             :   Node* IsPromiseHookEnabledOrDebugIsActive();
    1776             : 
    1777             :   Node* AllocatePromiseReactionJobInfo(Node* value, Node* tasks,
    1778             :                                        Node* deferred_promise,
    1779             :                                        Node* deferred_on_resolve,
    1780             :                                        Node* deferred_on_reject, Node* context);
    1781             : 
    1782             :   // Helpers for StackFrame markers.
    1783             :   Node* MarkerIsFrameType(Node* marker_or_function,
    1784             :                           StackFrame::Type frame_type);
    1785             :   Node* MarkerIsNotFrameType(Node* marker_or_function,
    1786             :                              StackFrame::Type frame_type);
    1787             : 
    1788             :   // for..in helpers
    1789             :   void CheckPrototypeEnumCache(Node* receiver, Node* receiver_map,
    1790             :                                Label* if_fast, Label* if_slow);
    1791             :   Node* CheckEnumCache(Node* receiver, Label* if_empty, Label* if_runtime);
    1792             : 
    1793             :   // Support for printf-style debugging
    1794             :   void Print(const char* s);
    1795             :   void Print(const char* prefix, Node* tagged_value);
    1796             :   inline void Print(Node* tagged_value) { return Print(nullptr, tagged_value); }
    1797             : 
    1798             :   template <class... TArgs>
    1799         310 :   Node* MakeTypeError(MessageTemplate::Template message, Node* context,
    1800             :                       TArgs... args) {
    1801             :     STATIC_ASSERT(sizeof...(TArgs) <= 3);
    1802             :     Node* const make_type_error = LoadContextElement(
    1803         930 :         LoadNativeContext(context), Context::MAKE_TYPE_ERROR_INDEX);
    1804             :     return CallJS(CodeFactory::Call(isolate()), context, make_type_error,
    1805         620 :                   UndefinedConstant(), SmiConstant(message), args...);
    1806             :   }
    1807             : 
    1808          31 :   void Abort(BailoutReason reason) {
    1809          31 :     CallRuntime(Runtime::kAbort, NoContextConstant(), SmiConstant(reason));
    1810          31 :     Unreachable();
    1811          31 :   }
    1812             : 
    1813             :  protected:
    1814             :   void DescriptorLookup(Node* unique_name, Node* descriptors, Node* bitfield3,
    1815             :                         Label* if_found, Variable* var_name_index,
    1816             :                         Label* if_not_found);
    1817             :   void DescriptorLookupLinear(Node* unique_name, Node* descriptors, Node* nof,
    1818             :                               Label* if_found, Variable* var_name_index,
    1819             :                               Label* if_not_found);
    1820             :   void DescriptorLookupBinary(Node* unique_name, Node* descriptors, Node* nof,
    1821             :                               Label* if_found, Variable* var_name_index,
    1822             :                               Label* if_not_found);
    1823             :   // Implements DescriptorArray::ToKeyIndex.
    1824             :   // Returns an untagged IntPtr.
    1825             :   Node* DescriptorArrayToKeyIndex(Node* descriptor_number);
    1826             :   // Implements DescriptorArray::GetKey.
    1827             :   Node* DescriptorArrayGetKey(Node* descriptors, Node* descriptor_number);
    1828             : 
    1829             :   Node* CallGetterIfAccessor(Node* value, Node* details, Node* context,
    1830             :                              Node* receiver, Label* if_bailout,
    1831             :                              GetOwnPropertyMode mode = kCallJSGetter);
    1832             : 
    1833             :   Node* TryToIntptr(Node* key, Label* miss);
    1834             : 
    1835             :   void BranchIfPrototypesHaveNoElements(Node* receiver_map,
    1836             :                                         Label* definitely_no_elements,
    1837             :                                         Label* possibly_elements);
    1838             : 
    1839             :  private:
    1840             :   friend class CodeStubArguments;
    1841             : 
    1842             :   void HandleBreakOnNode();
    1843             : 
    1844             :   Node* AllocateRawDoubleAligned(Node* size_in_bytes, AllocationFlags flags,
    1845             :                                  Node* top_address, Node* limit_address);
    1846             :   Node* AllocateRawUnaligned(Node* size_in_bytes, AllocationFlags flags,
    1847             :                              Node* top_adddress, Node* limit_address);
    1848             :   Node* AllocateRaw(Node* size_in_bytes, AllocationFlags flags,
    1849             :                     Node* top_address, Node* limit_address);
    1850             :   // Allocate and return a JSArray of given total size in bytes with header
    1851             :   // fields initialized.
    1852             :   Node* AllocateUninitializedJSArray(Node* array_map, Node* length,
    1853             :                                      Node* allocation_site,
    1854             :                                      Node* size_in_bytes);
    1855             : 
    1856             :   Node* SmiShiftBitsConstant();
    1857             : 
    1858             :   // Emits keyed sloppy arguments load if the |value| is nullptr or store
    1859             :   // otherwise. Returns either the loaded value or |value|.
    1860             :   Node* EmitKeyedSloppyArguments(Node* receiver, Node* key, Node* value,
    1861             :                                  Label* bailout);
    1862             : 
    1863             :   Node* AllocateSlicedString(Heap::RootListIndex map_root_index, Node* length,
    1864             :                              Node* parent, Node* offset);
    1865             : 
    1866             :   Node* AllocateConsString(Heap::RootListIndex map_root_index, Node* length,
    1867             :                            Node* first, Node* second, AllocationFlags flags);
    1868             : 
    1869             :   // Implements DescriptorArray::number_of_entries.
    1870             :   // Returns an untagged int32.
    1871             :   Node* DescriptorArrayNumberOfEntries(Node* descriptors);
    1872             :   // Implements DescriptorArray::GetSortedKeyIndex.
    1873             :   // Returns an untagged int32.
    1874             :   Node* DescriptorArrayGetSortedKeyIndex(Node* descriptors,
    1875             :                                          Node* descriptor_number);
    1876             : 
    1877             :   Node* CollectFeedbackForString(Node* instance_type);
    1878             :   void GenerateEqual_Same(Node* value, Label* if_equal, Label* if_notequal,
    1879             :                           Variable* var_type_feedback = nullptr);
    1880             :   Node* AllocAndCopyStringCharacters(Node* context, Node* from,
    1881             :                                      Node* from_instance_type, Node* from_index,
    1882             :                                      Node* character_count);
    1883             : 
    1884             :   static const int kElementLoopUnrollThreshold = 8;
    1885             : 
    1886             :   Node* NonNumberToNumberOrNumeric(Node* context, Node* input,
    1887             :                                    Object::Conversion mode);
    1888             : 
    1889             :   enum class Feedback { kCollect, kNone };
    1890             :   template <Feedback feedback>
    1891             :   void TaggedToNumeric(Node* context, Node* value, Label* done,
    1892             :                        Variable* var_numeric, Variable* var_feedback = nullptr);
    1893             : 
    1894             :   template <Feedback feedback, Object::Conversion conversion>
    1895             :   void TaggedToWord32OrBigIntImpl(Node* context, Node* value, Label* if_number,
    1896             :                                   Variable* var_word32,
    1897             :                                   Label* if_bigint = nullptr,
    1898             :                                   Variable* var_bigint = nullptr,
    1899             :                                   Variable* var_feedback = nullptr);
    1900             : };
    1901             : 
    1902             : class CodeStubArguments {
    1903             :  public:
    1904             :   typedef compiler::Node Node;
    1905             :   template <class T>
    1906             :   using TNode = compiler::TNode<T>;
    1907             :   template <class T>
    1908             :   using SloppyTNode = compiler::SloppyTNode<T>;
    1909             :   enum ReceiverMode { kHasReceiver, kNoReceiver };
    1910             : 
    1911             :   // |argc| is an intptr value which specifies the number of arguments passed
    1912             :   // to the builtin excluding the receiver. The arguments will include a
    1913             :   // receiver iff |receiver_mode| is kHasReceiver.
    1914             :   CodeStubArguments(CodeStubAssembler* assembler, SloppyTNode<IntPtrT> argc,
    1915             :                     ReceiverMode receiver_mode = ReceiverMode::kHasReceiver)
    1916             :       : CodeStubArguments(assembler, argc, nullptr,
    1917        1864 :                           CodeStubAssembler::INTPTR_PARAMETERS, receiver_mode) {
    1918             :   }
    1919             :   // |argc| is either a smi or intptr depending on |param_mode|. The arguments
    1920             :   // include a receiver iff |receiver_mode| is kHasReceiver.
    1921             :   CodeStubArguments(CodeStubAssembler* assembler, SloppyTNode<IntPtrT> argc,
    1922             :                     Node* fp, CodeStubAssembler::ParameterMode param_mode,
    1923             :                     ReceiverMode receiver_mode = ReceiverMode::kHasReceiver);
    1924             : 
    1925             :   TNode<Object> GetReceiver() const;
    1926             : 
    1927             :   TNode<RawPtr<Object>> AtIndexPtr(
    1928             :       Node* index, CodeStubAssembler::ParameterMode mode =
    1929             :                        CodeStubAssembler::INTPTR_PARAMETERS) const;
    1930             : 
    1931             :   // |index| is zero-based and does not include the receiver
    1932             :   TNode<Object> AtIndex(Node* index,
    1933             :                         CodeStubAssembler::ParameterMode mode =
    1934             :                             CodeStubAssembler::INTPTR_PARAMETERS) const;
    1935             : 
    1936             :   TNode<Object> AtIndex(int index) const;
    1937             : 
    1938        1798 :   TNode<Object> GetOptionalArgumentValue(int index) {
    1939        3596 :     return GetOptionalArgumentValue(index, assembler_->UndefinedConstant());
    1940             :   }
    1941             :   TNode<Object> GetOptionalArgumentValue(int index,
    1942             :                                          SloppyTNode<Object> default_value);
    1943             : 
    1944             :   TNode<IntPtrT> GetLength() const { return argc_; }
    1945             : 
    1946             :   typedef std::function<void(Node* arg)> ForEachBodyFunction;
    1947             : 
    1948             :   // Iteration doesn't include the receiver. |first| and |last| are zero-based.
    1949          31 :   void ForEach(const ForEachBodyFunction& body, Node* first = nullptr,
    1950             :                Node* last = nullptr, CodeStubAssembler::ParameterMode mode =
    1951             :                                          CodeStubAssembler::INTPTR_PARAMETERS) {
    1952          31 :     CodeStubAssembler::VariableList list(0, assembler_->zone());
    1953          31 :     ForEach(list, body, first, last);
    1954          31 :   }
    1955             : 
    1956             :   // Iteration doesn't include the receiver. |first| and |last| are zero-based.
    1957             :   void ForEach(const CodeStubAssembler::VariableList& vars,
    1958             :                const ForEachBodyFunction& body, Node* first = nullptr,
    1959             :                Node* last = nullptr, CodeStubAssembler::ParameterMode mode =
    1960             :                                          CodeStubAssembler::INTPTR_PARAMETERS);
    1961             : 
    1962             :   void PopAndReturn(Node* value);
    1963             : 
    1964             :  private:
    1965             :   Node* GetArguments();
    1966             : 
    1967             :   CodeStubAssembler* assembler_;
    1968             :   CodeStubAssembler::ParameterMode argc_mode_;
    1969             :   ReceiverMode receiver_mode_;
    1970             :   TNode<IntPtrT> argc_;
    1971             :   TNode<RawPtr<Object>> arguments_;
    1972             :   Node* fp_;
    1973             : };
    1974             : 
    1975        5022 : class ToDirectStringAssembler : public CodeStubAssembler {
    1976             :  private:
    1977             :   enum StringPointerKind { PTR_TO_DATA, PTR_TO_STRING };
    1978             : 
    1979             :  public:
    1980             :   enum Flag {
    1981             :     kDontUnpackSlicedStrings = 1 << 0,
    1982             :   };
    1983             :   typedef base::Flags<Flag> Flags;
    1984             : 
    1985             :   ToDirectStringAssembler(compiler::CodeAssemblerState* state, Node* string,
    1986             :                           Flags flags = Flags());
    1987             : 
    1988             :   // Converts flat cons, thin, and sliced strings and returns the direct
    1989             :   // string. The result can be either a sequential or external string.
    1990             :   // Jumps to if_bailout if the string if the string is indirect and cannot
    1991             :   // be unpacked.
    1992             :   Node* TryToDirect(Label* if_bailout);
    1993             : 
    1994             :   // Returns a pointer to the beginning of the string data.
    1995             :   // Jumps to if_bailout if the external string cannot be unpacked.
    1996             :   Node* PointerToData(Label* if_bailout) {
    1997        1705 :     return TryToSequential(PTR_TO_DATA, if_bailout);
    1998             :   }
    1999             : 
    2000             :   // Returns a pointer that, offset-wise, looks like a String.
    2001             :   // Jumps to if_bailout if the external string cannot be unpacked.
    2002             :   Node* PointerToString(Label* if_bailout) {
    2003         713 :     return TryToSequential(PTR_TO_STRING, if_bailout);
    2004             :   }
    2005             : 
    2006          31 :   Node* string() { return var_string_.value(); }
    2007        3131 :   Node* instance_type() { return var_instance_type_.value(); }
    2008        2697 :   Node* offset() { return var_offset_.value(); }
    2009        3224 :   Node* is_external() { return var_is_external_.value(); }
    2010             : 
    2011             :  private:
    2012             :   Node* TryToSequential(StringPointerKind ptr_kind, Label* if_bailout);
    2013             : 
    2014             :   Variable var_string_;
    2015             :   Variable var_instance_type_;
    2016             :   Variable var_offset_;
    2017             :   Variable var_is_external_;
    2018             : 
    2019             :   const Flags flags_;
    2020             : };
    2021             : 
    2022             : #define CSA_CHECK(csa, x)                                              \
    2023             :   (csa)->Check(                                                        \
    2024             :       [&]() -> compiler::Node* {                                       \
    2025             :         return base::implicit_cast<compiler::SloppyTNode<Word32T>>(x); \
    2026             :       },                                                               \
    2027             :       #x, __FILE__, __LINE__)
    2028             : 
    2029             : #ifdef DEBUG
    2030             : // Add stringified versions to the given values, except the first. That is,
    2031             : // transform
    2032             : //   x, a, b, c, d, e, f
    2033             : // to
    2034             : //   a, "a", b, "b", c, "c", d, "d", e, "e", f, "f"
    2035             : //
    2036             : // __VA_ARGS__  is ignored to allow the caller to pass through too many
    2037             : // parameters, and the first element is ignored to support having no extra
    2038             : // values without empty __VA_ARGS__ (which cause all sorts of problems with
    2039             : // extra commas).
    2040             : #define CSA_ASSERT_STRINGIFY_EXTRA_VALUES_5(_, v1, v2, v3, v4, v5, ...) \
    2041             :   v1, #v1, v2, #v2, v3, #v3, v4, #v4, v5, #v5
    2042             : 
    2043             : // Stringify the given variable number of arguments. The arguments are trimmed
    2044             : // to 5 if there are too many, and padded with nullptr if there are not enough.
    2045             : #define CSA_ASSERT_STRINGIFY_EXTRA_VALUES(...)                                \
    2046             :   CSA_ASSERT_STRINGIFY_EXTRA_VALUES_5(__VA_ARGS__, nullptr, nullptr, nullptr, \
    2047             :                                       nullptr, nullptr)
    2048             : 
    2049             : #define CSA_ASSERT_GET_CONDITION(x, ...) (x)
    2050             : #define CSA_ASSERT_GET_CONDITION_STR(x, ...) #x
    2051             : 
    2052             : // CSA_ASSERT(csa, <condition>, <extra values to print...>)
    2053             : 
    2054             : // We have to jump through some hoops to allow <extra values to print...> to be
    2055             : // empty.
    2056             : #define CSA_ASSERT(csa, ...)                                                 \
    2057             :   (csa)->Assert(                                                             \
    2058             :       [&]() -> compiler::Node* {                                             \
    2059             :         return base::implicit_cast<compiler::SloppyTNode<Word32T>>(          \
    2060             :             EXPAND(CSA_ASSERT_GET_CONDITION(__VA_ARGS__)));                  \
    2061             :       },                                                                     \
    2062             :       EXPAND(CSA_ASSERT_GET_CONDITION_STR(__VA_ARGS__)), __FILE__, __LINE__, \
    2063             :       CSA_ASSERT_STRINGIFY_EXTRA_VALUES(__VA_ARGS__))
    2064             : 
    2065             : #define CSA_ASSERT_JS_ARGC_OP(csa, Op, op, expected)                      \
    2066             :   (csa)->Assert(                                                          \
    2067             :       [&]() -> compiler::Node* {                                          \
    2068             :         compiler::Node* const argc =                                      \
    2069             :             (csa)->Parameter(Descriptor::kActualArgumentsCount);          \
    2070             :         return (csa)->Op(argc, (csa)->Int32Constant(expected));           \
    2071             :       },                                                                  \
    2072             :       "argc " #op " " #expected, __FILE__, __LINE__,                      \
    2073             :       SmiFromWord32((csa)->Parameter(Descriptor::kActualArgumentsCount)), \
    2074             :       "argc")
    2075             : 
    2076             : #define CSA_ASSERT_JS_ARGC_EQ(csa, expected) \
    2077             :   CSA_ASSERT_JS_ARGC_OP(csa, Word32Equal, ==, expected)
    2078             : 
    2079             : #define CSA_DEBUG_INFO(name) \
    2080             :   { #name, __FILE__, __LINE__ }
    2081             : #define BIND(label) Bind(label, CSA_DEBUG_INFO(label))
    2082             : #define VARIABLE(name, ...) \
    2083             :   Variable name(this, CSA_DEBUG_INFO(name), __VA_ARGS__)
    2084             : #define VARIABLE_CONSTRUCTOR(name, ...) \
    2085             :   name(this, CSA_DEBUG_INFO(name), __VA_ARGS__)
    2086             : #define TYPED_VARIABLE_DEF(type, name, ...) \
    2087             :   TVariable<type> name(CSA_DEBUG_INFO(name), __VA_ARGS__)
    2088             : #else  // DEBUG
    2089             : #define CSA_ASSERT(csa, ...) ((void)0)
    2090             : #define CSA_ASSERT_JS_ARGC_EQ(csa, expected) ((void)0)
    2091             : #define BIND(label) Bind(label)
    2092             : #define VARIABLE(name, ...) Variable name(this, __VA_ARGS__)
    2093             : #define VARIABLE_CONSTRUCTOR(name, ...) name(this, __VA_ARGS__)
    2094             : #define TYPED_VARIABLE_DEF(type, name, ...) TVariable<type> name(__VA_ARGS__)
    2095             : #endif  // DEBUG
    2096             : 
    2097             : #define TVARIABLE(...) EXPAND(TYPED_VARIABLE_DEF(__VA_ARGS__, this))
    2098             : 
    2099             : #ifdef ENABLE_SLOW_DCHECKS
    2100             : #define CSA_SLOW_ASSERT(csa, ...) \
    2101             :   if (FLAG_enable_slow_asserts) { \
    2102             :     CSA_ASSERT(csa, __VA_ARGS__); \
    2103             :   }
    2104             : #else
    2105             : #define CSA_SLOW_ASSERT(csa, ...) ((void)0)
    2106             : #endif
    2107             : 
    2108             : DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags);
    2109             : 
    2110             : }  // namespace internal
    2111             : }  // namespace v8
    2112             : #endif  // V8_CODE_STUB_ASSEMBLER_H_

Generated by: LCOV version 1.10