5 #ifndef V8_CODE_STUB_ASSEMBLER_H_ 6 #define V8_CODE_STUB_ASSEMBLER_H_ 10 #include "src/bailout-reason.h" 11 #include "src/base/macros.h" 12 #include "src/compiler/code-assembler.h" 13 #include "src/globals.h" 14 #include "src/message-template.h" 15 #include "src/objects.h" 16 #include "src/objects/arguments.h" 17 #include "src/objects/bigint.h" 18 #include "src/objects/smi.h" 19 #include "src/roots.h" 21 #include "torque-generated/builtins-base-from-dsl-gen.h" 26 class CallInterfaceDescriptor;
27 class CodeStubArguments;
28 class CodeStubAssembler;
32 enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
34 #define HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(V) \ 35 V(ArraySpeciesProtector, array_species_protector, ArraySpeciesProtector) \ 36 V(PromiseSpeciesProtector, promise_species_protector, \ 37 PromiseSpeciesProtector) \ 38 V(TypedArraySpeciesProtector, typed_array_species_protector, \ 39 TypedArraySpeciesProtector) \ 40 V(RegExpSpeciesProtector, regexp_species_protector, RegExpSpeciesProtector) 42 #define HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V) \ 43 V(AccessorInfoMap, accessor_info_map, AccessorInfoMap) \ 44 V(AccessorPairMap, accessor_pair_map, AccessorPairMap) \ 45 V(AllocationSiteWithWeakNextMap, allocation_site_map, AllocationSiteMap) \ 46 V(AllocationSiteWithoutWeakNextMap, allocation_site_without_weaknext_map, \ 47 AllocationSiteWithoutWeakNextMap) \ 48 V(BooleanMap, boolean_map, BooleanMap) \ 49 V(CodeMap, code_map, CodeMap) \ 50 V(EmptyFixedArray, empty_fixed_array, EmptyFixedArray) \ 51 V(EmptyPropertyDictionary, empty_property_dictionary, \ 52 EmptyPropertyDictionary) \ 53 V(EmptySlowElementDictionary, empty_slow_element_dictionary, \ 54 EmptySlowElementDictionary) \ 55 V(empty_string, empty_string, EmptyString) \ 56 V(FalseValue, false_value, False) \ 57 V(FeedbackVectorMap, feedback_vector_map, FeedbackVectorMap) \ 58 V(FixedArrayMap, fixed_array_map, FixedArrayMap) \ 59 V(FixedCOWArrayMap, fixed_cow_array_map, FixedCOWArrayMap) \ 60 V(FixedDoubleArrayMap, fixed_double_array_map, FixedDoubleArrayMap) \ 61 V(FunctionTemplateInfoMap, function_template_info_map, \ 62 FunctionTemplateInfoMap) \ 63 V(GlobalPropertyCellMap, global_property_cell_map, PropertyCellMap) \ 64 V(has_instance_symbol, has_instance_symbol, HasInstanceSymbol) \ 65 V(HeapNumberMap, heap_number_map, HeapNumberMap) \ 66 V(iterator_symbol, iterator_symbol, IteratorSymbol) \ 67 V(length_string, length_string, LengthString) \ 68 V(ManyClosuresCellMap, many_closures_cell_map, ManyClosuresCellMap) \ 69 V(MetaMap, meta_map, MetaMap) \ 70 V(MinusZeroValue, minus_zero_value, MinusZero) \ 71 V(MutableHeapNumberMap, mutable_heap_number_map, MutableHeapNumberMap) \ 72 V(NanValue, nan_value, Nan) \ 73 V(NoClosuresCellMap, no_closures_cell_map, NoClosuresCellMap) \ 74 V(NoFeedbackCellMap, no_feedback_cell_map, NoFeedbackCellMap) \ 75 V(NullValue, null_value, Null) \ 76 V(OneClosureCellMap, one_closure_cell_map, OneClosureCellMap) \ 77 V(PreParsedScopeDataMap, pre_parsed_scope_data_map, PreParsedScopeDataMap) \ 78 V(prototype_string, prototype_string, PrototypeString) \ 79 V(SharedFunctionInfoMap, shared_function_info_map, SharedFunctionInfoMap) \ 80 V(StoreHandler0Map, store_handler0_map, StoreHandler0Map) \ 81 V(SymbolMap, symbol_map, SymbolMap) \ 82 V(TheHoleValue, the_hole_value, TheHole) \ 83 V(TransitionArrayMap, transition_array_map, TransitionArrayMap) \ 84 V(TrueValue, true_value, True) \ 85 V(Tuple2Map, tuple2_map, Tuple2Map) \ 86 V(Tuple3Map, tuple3_map, Tuple3Map) \ 87 V(ArrayBoilerplateDescriptionMap, array_boilerplate_description_map, \ 88 ArrayBoilerplateDescriptionMap) \ 89 V(UncompiledDataWithoutPreParsedScopeMap, \ 90 uncompiled_data_without_pre_parsed_scope_map, \ 91 UncompiledDataWithoutPreParsedScopeMap) \ 92 V(UncompiledDataWithPreParsedScopeMap, \ 93 uncompiled_data_with_pre_parsed_scope_map, \ 94 UncompiledDataWithPreParsedScopeMap) \ 95 V(UndefinedValue, undefined_value, Undefined) \ 96 V(WeakFixedArrayMap, weak_fixed_array_map, WeakFixedArrayMap) 98 #define HEAP_IMMOVABLE_OBJECT_LIST(V) \ 99 HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(V) \ 100 HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V) 103 #define CSA_CHECK(csa, x) \ 105 [&]() -> compiler::Node* { \ 106 return implicit_cast<compiler::SloppyTNode<Word32T>>(x); \ 108 #x, __FILE__, __LINE__) 110 #define CSA_CHECK(csa, x) (csa)->FastCheck(x) 124 #define CSA_ASSERT_STRINGIFY_EXTRA_VALUES_5(_, v1, v2, v3, v4, v5, ...) \ 125 v1, #v1, v2, #v2, v3, #v3, v4, #v4, v5, #v5 129 #define CSA_ASSERT_STRINGIFY_EXTRA_VALUES(...) \ 130 CSA_ASSERT_STRINGIFY_EXTRA_VALUES_5(__VA_ARGS__, nullptr, nullptr, nullptr, \ 133 #define CSA_ASSERT_GET_FIRST(x, ...) (x) 134 #define CSA_ASSERT_GET_FIRST_STR(x, ...) #x 140 #define CSA_ASSERT(csa, ...) \ 142 [&]() -> compiler::Node* { \ 143 return implicit_cast<compiler::SloppyTNode<Word32T>>( \ 144 EXPAND(CSA_ASSERT_GET_FIRST(__VA_ARGS__))); \ 146 EXPAND(CSA_ASSERT_GET_FIRST_STR(__VA_ARGS__)), __FILE__, __LINE__, \ 147 CSA_ASSERT_STRINGIFY_EXTRA_VALUES(__VA_ARGS__)) 152 #define CSA_ASSERT_BRANCH(csa, ...) \ 153 (csa)->Assert(EXPAND(CSA_ASSERT_GET_FIRST(__VA_ARGS__)), \ 154 EXPAND(CSA_ASSERT_GET_FIRST_STR(__VA_ARGS__)), __FILE__, \ 155 __LINE__, CSA_ASSERT_STRINGIFY_EXTRA_VALUES(__VA_ARGS__)) 157 #define CSA_ASSERT_JS_ARGC_OP(csa, Op, op, expected) \ 159 [&]() -> compiler::Node* { \ 160 compiler::Node* const argc = \ 161 (csa)->Parameter(Descriptor::kJSActualArgumentsCount); \ 162 return (csa)->Op(argc, (csa)->Int32Constant(expected)); \ 164 "argc " #op " " #expected, __FILE__, __LINE__, \ 165 SmiFromInt32((csa)->Parameter(Descriptor::kJSActualArgumentsCount)), \ 168 #define CSA_ASSERT_JS_ARGC_EQ(csa, expected) \ 169 CSA_ASSERT_JS_ARGC_OP(csa, Word32Equal, ==, expected) 171 #define CSA_DEBUG_INFO(name) \ 172 { #name, __FILE__, __LINE__ } 173 #define BIND(label) Bind(label, CSA_DEBUG_INFO(label)) 174 #define VARIABLE(name, ...) \ 175 Variable name(this, CSA_DEBUG_INFO(name), __VA_ARGS__) 176 #define VARIABLE_CONSTRUCTOR(name, ...) \ 177 name(this, CSA_DEBUG_INFO(name), __VA_ARGS__) 178 #define TYPED_VARIABLE_DEF(type, name, ...) \ 179 TVariable<type> name(CSA_DEBUG_INFO(name), __VA_ARGS__) 181 #define CSA_ASSERT(csa, ...) ((void)0) 182 #define CSA_ASSERT_BRANCH(csa, ...) ((void)0) 183 #define CSA_ASSERT_JS_ARGC_EQ(csa, expected) ((void)0) 184 #define BIND(label) Bind(label) 185 #define VARIABLE(name, ...) Variable name(this, __VA_ARGS__) 186 #define VARIABLE_CONSTRUCTOR(name, ...) name(this, __VA_ARGS__) 187 #define TYPED_VARIABLE_DEF(type, name, ...) TVariable<type> name(__VA_ARGS__) 190 #define TVARIABLE(...) EXPAND(TYPED_VARIABLE_DEF(__VA_ARGS__, this)) 192 #ifdef ENABLE_SLOW_DCHECKS 193 #define CSA_SLOW_ASSERT(csa, ...) \ 194 if (FLAG_enable_slow_asserts) { \ 195 CSA_ASSERT(csa, __VA_ARGS__); \ 198 #define CSA_SLOW_ASSERT(csa, ...) ((void)0) 216 template <
typename T>
217 using LazyNode = std::function<TNode<T>()>;
221 enum AllocationFlag : uint8_t {
223 kDoubleAlignment = 1,
224 kPretenured = 1 << 1,
225 kAllowLargeObjectAllocation = 1 << 2,
228 enum SlackTrackingMode { kWithSlackTracking, kNoSlackTracking };
232 enum ParameterMode { SMI_PARAMETERS, INTPTR_PARAMETERS };
240 ParameterMode OptimalParameterMode()
const {
241 return Is64() ? INTPTR_PARAMETERS : SMI_PARAMETERS;
244 MachineRepresentation ParameterRepresentation(ParameterMode mode)
const {
245 return mode == INTPTR_PARAMETERS ? MachineType::PointerRepresentation()
246 : MachineRepresentation::kTaggedSigned;
249 MachineRepresentation OptimalParameterRepresentation()
const {
250 return ParameterRepresentation(OptimalParameterMode());
254 if (mode == SMI_PARAMETERS) value = SmiUntag(value);
255 return UncheckedCast<IntPtrT>(value);
259 if (mode == SMI_PARAMETERS)
return SmiTag(value);
264 return IntPtrToParameter(ChangeInt32ToIntPtr(value), mode);
268 if (mode != SMI_PARAMETERS)
return SmiTag(value);
269 return UncheckedCast<Smi>(value);
273 if (mode != SMI_PARAMETERS)
return SmiUntag(value);
278 GotoIf(TaggedIsNotSmi(value), fail);
279 return UncheckedCast<Smi>(value);
283 GotoIfNot(IsNumber(value), fail);
284 return UncheckedCast<Number>(value);
288 GotoIf(TaggedIsSmi(value), fail);
289 return UncheckedCast<HeapObject>(value);
294 GotoIfNot(IsJSArray(heap_object), fail);
295 return UncheckedCast<JSArray>(heap_object);
300 GotoIf(TaggedIsSmi(value), fail);
302 GotoIfNot(IsFastJSArray(heap_object, context), fail);
303 return UncheckedCast<JSArray>(heap_object);
308 GotoIfNot(IsJSDataView(heap_object), fail);
309 return CAST(heap_object);
314 GotoIfNot(IsCallable(heap_object), fail);
315 return CAST(heap_object);
319 GotoIfNot(IsString(heap_object), fail);
320 return CAST(heap_object);
325 GotoIfNot(IsConstructor(heap_object), fail);
326 return CAST(heap_object);
329 Node* MatchesParameterMode(
Node* value, ParameterMode mode);
331 #define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \ 332 Node* OpName(Node* a, Node* b, ParameterMode mode) { \ 333 if (mode == SMI_PARAMETERS) { \ 334 return SmiOpName(CAST(a), CAST(b)); \ 336 DCHECK_EQ(INTPTR_PARAMETERS, mode); \ 337 return IntPtrOpName(a, b); \ 340 PARAMETER_BINOP(IntPtrOrSmiMin, IntPtrMin, SmiMin)
341 PARAMETER_BINOP(IntPtrOrSmiAdd, IntPtrAdd, SmiAdd)
342 PARAMETER_BINOP(IntPtrOrSmiSub, IntPtrSub, SmiSub)
343 PARAMETER_BINOP(IntPtrOrSmiLessThan, IntPtrLessThan, SmiLessThan)
344 PARAMETER_BINOP(IntPtrOrSmiLessThanOrEqual, IntPtrLessThanOrEqual,
346 PARAMETER_BINOP(IntPtrOrSmiGreaterThan, IntPtrGreaterThan, SmiGreaterThan)
347 PARAMETER_BINOP(IntPtrOrSmiGreaterThanOrEqual, IntPtrGreaterThanOrEqual,
348 SmiGreaterThanOrEqual)
349 PARAMETER_BINOP(UintPtrOrSmiLessThan, UintPtrLessThan, SmiBelow)
350 PARAMETER_BINOP(UintPtrOrSmiGreaterThanOrEqual, UintPtrGreaterThanOrEqual,
352 #undef PARAMETER_BINOP 356 #define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \ 357 compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \ 358 std::declval<ReadOnlyRoots>().rootAccessorName())>::type>::type> \ 360 HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
361 #undef HEAP_CONSTANT_ACCESSOR 363 #define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \ 364 compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \ 365 std::declval<Heap>().rootAccessorName())>::type>::type> \ 367 HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
368 #undef HEAP_CONSTANT_ACCESSOR 370 #define HEAP_CONSTANT_TEST(rootIndexName, rootAccessorName, name) \ 371 TNode<BoolT> Is##name(SloppyTNode<Object> value); \ 372 TNode<BoolT> IsNot##name(SloppyTNode<Object> value); 373 HEAP_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_TEST)
374 #undef HEAP_CONSTANT_TEST 376 Node* IntPtrOrSmiConstant(
int value, ParameterMode mode);
377 TNode<Smi> LanguageModeConstant(LanguageMode mode) {
378 return SmiConstant(static_cast<int>(mode));
381 bool IsIntPtrOrSmiConstantZero(
Node* test, ParameterMode mode);
382 bool TryGetIntPtrOrSmiConstantValue(
Node* maybe_constant,
int* value,
427 #define SMI_ARITHMETIC_BINOP(SmiOpName, IntPtrOpName, Int32OpName) \ 428 TNode<Smi> SmiOpName(TNode<Smi> a, TNode<Smi> b) { \ 429 if (SmiValuesAre32Bits()) { \ 430 return BitcastWordToTaggedSigned( \ 431 IntPtrOpName(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); \ 433 DCHECK(SmiValuesAre31Bits()); \ 434 if (kPointerSize == kInt64Size) { \ 435 CSA_ASSERT(this, IsValidSmi(a)); \ 436 CSA_ASSERT(this, IsValidSmi(b)); \ 438 return BitcastWordToTaggedSigned(ChangeInt32ToIntPtr( \ 439 Int32OpName(TruncateIntPtrToInt32(BitcastTaggedToWord(a)), \ 440 TruncateIntPtrToInt32(BitcastTaggedToWord(b))))); \ 443 SMI_ARITHMETIC_BINOP(SmiAdd, IntPtrAdd, Int32Add)
444 SMI_ARITHMETIC_BINOP(SmiSub, IntPtrSub, Int32Sub)
445 SMI_ARITHMETIC_BINOP(SmiAnd, WordAnd, Word32And)
446 SMI_ARITHMETIC_BINOP(SmiOr, WordOr, Word32Or)
447 #undef SMI_ARITHMETIC_BINOP 456 return BitcastWordToTaggedSigned(WordShl(BitcastTaggedToWord(a), shift));
460 return BitcastWordToTaggedSigned(
461 WordAnd(WordShr(BitcastTaggedToWord(a), shift),
462 BitcastTaggedToWord(SmiConstant(-1))));
465 Node* WordOrSmiShl(
Node* a,
int shift, ParameterMode mode) {
466 if (mode == SMI_PARAMETERS) {
467 return SmiShl(CAST(a), shift);
469 DCHECK_EQ(INTPTR_PARAMETERS, mode);
470 return WordShl(a, shift);
474 Node* WordOrSmiShr(
Node* a,
int shift, ParameterMode mode) {
475 if (mode == SMI_PARAMETERS) {
476 return SmiShr(CAST(a), shift);
478 DCHECK_EQ(INTPTR_PARAMETERS, mode);
479 return WordShr(a, shift);
483 #define SMI_COMPARISON_OP(SmiOpName, IntPtrOpName, Int32OpName) \ 484 TNode<BoolT> SmiOpName(TNode<Smi> a, TNode<Smi> b) { \ 485 if (SmiValuesAre32Bits()) { \ 486 return IntPtrOpName(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); \ 488 DCHECK(SmiValuesAre31Bits()); \ 489 if (kPointerSize == kInt64Size) { \ 490 CSA_ASSERT(this, IsValidSmi(a)); \ 491 CSA_ASSERT(this, IsValidSmi(b)); \ 493 return Int32OpName(TruncateIntPtrToInt32(BitcastTaggedToWord(a)), \ 494 TruncateIntPtrToInt32(BitcastTaggedToWord(b))); \ 497 SMI_COMPARISON_OP(SmiEqual, WordEqual, Word32Equal)
498 SMI_COMPARISON_OP(SmiNotEqual, WordNotEqual, Word32NotEqual)
499 SMI_COMPARISON_OP(SmiAbove, UintPtrGreaterThan, Uint32GreaterThan)
500 SMI_COMPARISON_OP(SmiAboveOrEqual, UintPtrGreaterThanOrEqual,
501 Uint32GreaterThanOrEqual)
502 SMI_COMPARISON_OP(SmiBelow, UintPtrLessThan, Uint32LessThan)
503 SMI_COMPARISON_OP(SmiLessThan, IntPtrLessThan, Int32LessThan)
504 SMI_COMPARISON_OP(SmiLessThanOrEqual, IntPtrLessThanOrEqual,
505 Int32LessThanOrEqual)
506 SMI_COMPARISON_OP(SmiGreaterThan, IntPtrGreaterThan, Int32GreaterThan)
507 SMI_COMPARISON_OP(SmiGreaterThanOrEqual, IntPtrGreaterThanOrEqual,
508 Int32GreaterThanOrEqual)
509 #undef SMI_COMPARISON_OP 532 void GotoIfNotNumber(
Node* value,
Label* is_not_number);
533 void GotoIfNumber(
Node* value,
Label* is_number);
551 typedef std::function<void(Label*, Label*)> BranchGenerator;
552 typedef std::function<Node*()> NodeGenerator;
554 void Assert(
const BranchGenerator& branch,
const char* message =
nullptr,
555 const char* file =
nullptr,
int line = 0,
556 Node* extra_node1 =
nullptr,
const char* extra_node1_name =
"",
557 Node* extra_node2 =
nullptr,
const char* extra_node2_name =
"",
558 Node* extra_node3 =
nullptr,
const char* extra_node3_name =
"",
559 Node* extra_node4 =
nullptr,
const char* extra_node4_name =
"",
560 Node* extra_node5 =
nullptr,
const char* extra_node5_name =
"");
561 void Assert(
const NodeGenerator& condition_body,
562 const char* message =
nullptr,
const char* file =
nullptr,
563 int line = 0,
Node* extra_node1 =
nullptr,
564 const char* extra_node1_name =
"",
Node* extra_node2 =
nullptr,
565 const char* extra_node2_name =
"",
Node* extra_node3 =
nullptr,
566 const char* extra_node3_name =
"",
Node* extra_node4 =
nullptr,
567 const char* extra_node4_name =
"",
Node* extra_node5 =
nullptr,
568 const char* extra_node5_name =
"");
569 void Check(
const BranchGenerator& branch,
const char* message =
nullptr,
570 const char* file =
nullptr,
int line = 0,
571 Node* extra_node1 =
nullptr,
const char* extra_node1_name =
"",
572 Node* extra_node2 =
nullptr,
const char* extra_node2_name =
"",
573 Node* extra_node3 =
nullptr,
const char* extra_node3_name =
"",
574 Node* extra_node4 =
nullptr,
const char* extra_node4_name =
"",
575 Node* extra_node5 =
nullptr,
const char* extra_node5_name =
"");
576 void Check(
const NodeGenerator& condition_body,
const char* message =
nullptr,
577 const char* file =
nullptr,
int line = 0,
578 Node* extra_node1 =
nullptr,
const char* extra_node1_name =
"",
579 Node* extra_node2 =
nullptr,
const char* extra_node2_name =
"",
580 Node* extra_node3 =
nullptr,
const char* extra_node3_name =
"",
581 Node* extra_node4 =
nullptr,
const char* extra_node4_name =
"",
582 Node* extra_node5 =
nullptr,
const char* extra_node5_name =
"");
584 const char* message =
nullptr,
const char* file =
nullptr,
int line = 0,
585 Node* extra_node1 =
nullptr,
const char* extra_node1_name =
"",
586 Node* extra_node2 =
nullptr,
const char* extra_node2_name =
"",
587 Node* extra_node3 =
nullptr,
const char* extra_node3_name =
"",
588 Node* extra_node4 =
nullptr,
const char* extra_node4_name =
"",
589 Node* extra_node5 =
nullptr,
const char* extra_node5_name =
"");
596 template <
class... TArgs>
599 return UncheckedCast<Object>(CallJS(
600 CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
601 context, callable, receiver, args...));
603 template <
class... TArgs>
606 if (IsUndefinedConstant(receiver) || IsNullConstant(receiver)) {
607 return UncheckedCast<Object>(CallJS(
608 CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
609 context, callable, receiver, args...));
611 return UncheckedCast<Object>(CallJS(CodeFactory::Call(isolate()), context,
612 callable, receiver, args...));
615 template <
class... TArgs>
618 return CAST(ConstructJS(CodeFactory::Construct(isolate()), context,
622 template <
class A,
class F,
class G>
624 const G& false_body) {
625 return UncheckedCast<A>(SelectImpl(
627 [&]() ->
Node* {
return implicit_cast<
TNode<A>>(true_body()); },
628 [&]() ->
Node* {
return implicit_cast<
TNode<A>>(false_body()); },
635 return Select<A>(condition, [=] {
return true_value; },
636 [=] {
return false_value; });
640 int true_value,
int false_value);
642 int true_value,
int false_value);
648 return SelectSmiConstant(condition, Smi::FromInt(true_value), false_value);
652 return SelectSmiConstant(condition, true_value, Smi::FromInt(false_value));
656 return SelectSmiConstant(condition, Smi::FromInt(true_value),
657 Smi::FromInt(false_value));
675 void Bind(
Label* label);
677 template <
class...
T>
680 CodeAssembler::Bind(label, phis...);
685 Branch(SmiEqual(a, b), if_true, if_false);
690 Branch(SmiLessThan(a, b), if_true, if_false);
695 Branch(SmiLessThanOrEqual(a, b), if_true, if_false);
698 void BranchIfFloat64IsNaN(
Node* value,
Label* if_true,
Label* if_false) {
699 Branch(Float64Equal(value, value), if_false, if_true);
704 void BranchIfToBooleanIsTrue(
Node* value,
Label* if_true,
Label* if_false);
706 void BranchIfJSReceiver(
Node*
object,
Label* if_true,
Label* if_false);
713 void GotoIfForceSlowPath(
Label* if_true);
716 void GotoIfDebugExecutionModeChecksSideEffects(
Label* if_true);
719 Node* LoadFromFrame(
int offset,
MachineType rep = MachineType::AnyTagged());
721 Node* LoadFromParentFrame(
int offset,
733 Node* LoadBufferObject(
Node* buffer,
int offset,
738 template <
class T,
typename std::enable_if<
744 template <
class T,
typename std::enable_if<
748 return UncheckedCast<T>(
752 return UncheckedCast<Object>(
753 LoadObjectField(
object, offset, MachineType::AnyTagged()));
759 return UncheckedCast<Object>(
760 LoadObjectField(
object, offset, MachineType::AnyTagged()));
762 template <
class T,
typename std::enable_if<
766 return UncheckedCast<T>(
777 TNode<Int32T> LoadAndUntagToWord32Root(RootIndex root_index);
781 return UncheckedCast<MaybeObject>(
782 LoadObjectField(
object, offset, MachineType::AnyTagged()));
786 Node* StoreAndTagSmi(
Node* base,
int offset,
Node* value);
842 Label* if_has_no_proto_info);
861 Label* if_no_hash =
nullptr);
865 void InitializePropertyArrayLength(
Node* property_array,
Node* length,
877 Label* if_hash_not_computed =
nullptr);
886 Node* PointerToSeqStringData(
Node* seq_string);
888 Node* LoadJSValueValue(
Node*
object);
905 return IsStrong(ReinterpretCast<MaybeObject>(value));
908 Label* if_not_strong);
930 int additional_offset = 0,
931 ParameterMode parameter_mode = INTPTR_PARAMETERS);
935 template <
typename Array>
940 template <
typename Array>
943 int additional_offset = 0,
944 ParameterMode parameter_mode = INTPTR_PARAMETERS,
945 LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
949 ParameterMode parameter_mode = INTPTR_PARAMETERS,
950 LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
954 LoadSensitivity needs_poisoning) {
955 return LoadFixedArrayElement(
object, index, 0, INTPTR_PARAMETERS,
961 LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
962 return LoadFixedArrayElement(
object, index, additional_offset,
963 INTPTR_PARAMETERS, needs_poisoning);
968 LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
969 return LoadFixedArrayElement(
object, IntPtrConstant(index),
970 additional_offset, INTPTR_PARAMETERS,
975 return LoadFixedArrayElement(
object, index, 0, SMI_PARAMETERS);
985 template <
typename Array>
988 int additional_offset = 0,
989 ParameterMode parameter_mode = INTPTR_PARAMETERS);
994 ParameterMode parameter_mode = INTPTR_PARAMETERS);
998 return LoadAndUntagToWord32FixedArrayElement(
999 object, IntPtrConstant(index), additional_offset, INTPTR_PARAMETERS);
1005 ParameterMode parameter_mode = INTPTR_PARAMETERS,
1006 LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
1010 LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
1011 return LoadWeakFixedArrayElement(
object, IntPtrConstant(index),
1012 additional_offset, INTPTR_PARAMETERS,
1019 MachineType machine_type,
int additional_offset = 0,
1020 ParameterMode parameter_mode = INTPTR_PARAMETERS,
1021 Label* if_hole =
nullptr);
1025 Label* if_hole =
nullptr) {
1026 return LoadFixedDoubleArrayElement(
object, index, MachineType::Float64(), 0,
1027 SMI_PARAMETERS, if_hole);
1032 Label* if_hole =
nullptr) {
1033 return LoadFixedDoubleArrayElement(
object, index, MachineType::Float64(), 0,
1034 INTPTR_PARAMETERS, if_hole);
1049 Node*
object,
Node* index,
int additional_offset = 0,
1050 ParameterMode parameter_mode = INTPTR_PARAMETERS);
1055 Label* if_hole =
nullptr);
1058 Label* if_hole =
nullptr);
1065 MachineType machine_type = MachineType::Float64());
1068 Node* LoadFixedTypedArrayElementAsTagged(
1069 Node* data_pointer,
Node* index_node, ElementsKind elements_kind,
1070 ParameterMode parameter_mode = INTPTR_PARAMETERS);
1074 Node* LoadFixedBigInt64ArrayElementAsTagged(
Node* data_pointer,
Node* offset);
1075 Node* LoadFixedBigUint64ArrayElementAsTagged(
Node* data_pointer,
1084 void StoreFixedTypedArrayElementFromTagged(
1087 ParameterMode parameter_mode);
1108 void GotoIfContextElementEqual(
Node* value,
Node* native_context,
1109 int slot_index,
Label* if_equal) {
1110 GotoIf(WordEqual(value, LoadContextElement(native_context, slot_index)),
1114 TNode<Map> LoadJSArrayElementsMap(ElementsKind kind,
1124 Node* LoadJSFunctionPrototype(
Node*
function,
Label* if_bailout);
1131 return LoadObjectField(
function, JSFunction::kPrototypeOrInitialMapOffset);
1143 Node* StoreObjectField(
Node*
object,
int offset,
Node* value);
1145 Node* StoreObjectFieldNoWriteBarrier(
1146 Node*
object,
int offset,
Node* value,
1147 MachineRepresentation rep = MachineRepresentation::kTagged);
1148 Node* StoreObjectFieldNoWriteBarrier(
1150 MachineRepresentation rep = MachineRepresentation::kTagged);
1152 template <
class T = Object>
1156 return UncheckedCast<T>(StoreObjectFieldNoWriteBarrier(
1162 Node* StoreMapNoWriteBarrier(
Node*
object, RootIndex map_root_index);
1164 Node* StoreObjectFieldRoot(
Node*
object,
int offset, RootIndex root);
1166 void StoreFixedArrayElement(
1168 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
1169 return StoreFixedArrayElement(
object, IntPtrConstant(index), value,
1174 return StoreFixedArrayElement(
object, IntPtrConstant(index), value,
1175 SKIP_WRITE_BARRIER);
1181 void StoreFixedArrayOrPropertyArrayElement(
1183 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
1184 int additional_offset = 0,
1185 ParameterMode parameter_mode = INTPTR_PARAMETERS);
1187 void StoreFixedArrayElement(
1189 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
1190 int additional_offset = 0,
1191 ParameterMode parameter_mode = INTPTR_PARAMETERS) {
1192 FixedArrayBoundsCheck(array, index, additional_offset, parameter_mode);
1193 StoreFixedArrayOrPropertyArrayElement(array, index, value, barrier_mode,
1194 additional_offset, parameter_mode);
1197 void StorePropertyArrayElement(
1199 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
1200 int additional_offset = 0,
1201 ParameterMode parameter_mode = INTPTR_PARAMETERS) {
1202 StoreFixedArrayOrPropertyArrayElement(array, index, value, barrier_mode,
1203 additional_offset, parameter_mode);
1206 void StoreFixedArrayElementSmi(
1208 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
1209 StoreFixedArrayElement(array, index, value, barrier_mode, 0,
1214 StoreFixedArrayElement(array, index, value, SKIP_WRITE_BARRIER, 0);
1217 void StoreFixedDoubleArrayElement(
1219 ParameterMode parameter_mode = INTPTR_PARAMETERS);
1224 StoreFixedDoubleArrayElement(
object, index, value, SMI_PARAMETERS);
1228 ParameterMode mode = INTPTR_PARAMETERS);
1231 StoreFixedDoubleArrayHole(array, index, SMI_PARAMETERS);
1234 Node* StoreFeedbackVectorSlot(
1236 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
1237 int additional_offset = 0,
1238 ParameterMode parameter_mode = INTPTR_PARAMETERS);
1249 void TryStoreArrayElement(ElementsKind kind, ParameterMode mode,
1257 void BuildAppendJSArray(ElementsKind kind,
Node* array,
Node* value,
1260 void StoreFieldsNoWriteBarrier(
Node* start_address,
Node* end_address,
1263 Node* AllocateCellWithValue(
Node* value,
1264 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
1265 Node* AllocateSmiCell(
int value = 0) {
1266 return AllocateCellWithValue(SmiConstant(value), SKIP_WRITE_BARRIER);
1272 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
1279 return AllocateHeapNumberWithValue(Float64Constant(value));
1292 void StoreBigIntDigit(
TNode<BigInt> bigint,
int digit_index,
1347 Label* large_object_fallback);
1349 template <
typename CollectionType>
1350 Node* AllocateOrderedHashTable();
1361 template <
typename CollectionType>
1362 void FindOrderedHashTableEntry(
1367 template <
typename CollectionType>
1371 void InitializeStructBody(
Node*
object,
Node* map,
Node* size,
1372 int start_offset = Struct::kHeaderSize);
1374 Node* AllocateJSObjectFromMap(
1375 Node* map,
Node* properties =
nullptr,
Node* elements =
nullptr,
1377 SlackTrackingMode slack_tracking_mode = kNoSlackTracking);
1379 void InitializeJSObjectFromMap(
1381 Node* elements =
nullptr,
1382 SlackTrackingMode slack_tracking_mode = kNoSlackTracking);
1384 void InitializeJSObjectBodyWithSlackTracking(
Node*
object,
Node* map,
1385 Node* instance_size);
1386 void InitializeJSObjectBodyNoSlackTracking(
1388 int start_offset = JSObject::kHeaderSize);
1391 ParameterMode capacity_mode);
1401 AllocateUninitializedJSArrayWithElements(
1403 Node* allocation_site,
Node* capacity,
1404 ParameterMode capacity_mode = INTPTR_PARAMETERS,
1412 ParameterMode capacity_mode = INTPTR_PARAMETERS,
1417 return AllocateJSArray(kind, array_map, capacity, length,
nullptr,
1423 return AllocateJSArray(kind, array_map, capacity, length,
nullptr,
1427 enum class HoleConversionMode { kDontConvert, kConvertToUndefined };
1438 Node* CloneFastJSArray(
1439 Node* context,
Node* array, ParameterMode mode = INTPTR_PARAMETERS,
1440 Node* allocation_site =
nullptr,
1441 HoleConversionMode convert_holes = HoleConversionMode::kDontConvert);
1444 ParameterMode mode = INTPTR_PARAMETERS,
1445 Node* capacity =
nullptr,
1446 Node* allocation_site =
nullptr);
1449 ElementsKind kind,
Node* capacity, ParameterMode mode = INTPTR_PARAMETERS,
1456 return AllocateFixedArray(kind, capacity, INTPTR_PARAMETERS, flags,
1462 AllocateFixedArray(PACKED_ELEMENTS, capacity,
1463 AllocationFlag::kAllowLargeObjectAllocation));
1464 FillFixedArrayWithSmiZero(result, capacity);
1471 AllocateFixedArray(PACKED_DOUBLE_ELEMENTS, capacity,
1472 AllocationFlag::kAllowLargeObjectAllocation));
1473 FillFixedDoubleArrayWithZero(result, capacity);
1480 AllocateFixedArray(PACKED_ELEMENTS, capacity, flags));
1481 FillFixedArrayWithValue(PACKED_ELEMENTS, result, IntPtrConstant(0),
1482 capacity, RootIndex::kTheHoleValue);
1486 Node* AllocatePropertyArray(
Node* capacity,
1487 ParameterMode mode = INTPTR_PARAMETERS,
1493 IterationKind mode);
1496 Node* AllocateJSIteratorResultForEntry(
Node* context,
Node* key,
Node* value);
1504 void FillFixedArrayWithValue(ElementsKind kind,
Node* array,
Node* from_index,
1505 Node* to_index, RootIndex value_root_index,
1506 ParameterMode mode = INTPTR_PARAMETERS);
1514 void FillPropertyArrayWithUndefined(
Node* array,
Node* from_index,
1516 ParameterMode mode = INTPTR_PARAMETERS);
1518 enum class DestroySource { kNo, kYes };
1527 void CopyPropertyArrayValues(
Node* from_array,
Node* to_array,
Node* length,
1528 WriteBarrierMode barrier_mode,
1530 DestroySource destroy_source);
1534 void CopyFixedArrayElements(
1535 ElementsKind kind,
Node* from_array,
Node* to_array,
Node* length,
1536 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
1537 ParameterMode mode = INTPTR_PARAMETERS) {
1538 CopyFixedArrayElements(kind, from_array, kind, to_array,
1539 IntPtrOrSmiConstant(0, mode), length, length,
1540 barrier_mode, mode);
1546 void CopyFixedArrayElements(
1547 ElementsKind from_kind,
Node* from_array, ElementsKind to_kind,
1549 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
1550 ParameterMode mode = INTPTR_PARAMETERS) {
1551 CopyFixedArrayElements(from_kind, from_array, to_kind, to_array,
1552 IntPtrOrSmiConstant(0, mode), element_count,
1553 capacity, barrier_mode, mode);
1564 void CopyFixedArrayElements(
1565 ElementsKind from_kind,
Node* from_array, ElementsKind to_kind,
1567 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
1568 ParameterMode mode = INTPTR_PARAMETERS,
1569 HoleConversionMode convert_holes = HoleConversionMode::kDontConvert,
1572 void CopyFixedArrayElements(
1576 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) {
1577 CopyFixedArrayElements(from_kind, from_array, to_kind, to_array,
1578 first_element, element_count, capacity, barrier_mode,
1582 void JumpIfPointersFromHereAreInteresting(
TNode<Object> object,
1583 Label* interesting);
1604 WriteBarrierMode write_barrier = UPDATE_WRITE_BARRIER);
1612 WordNotEqual(LoadMap(base), LoadRoot(RootIndex::kFixedDoubleArrayMap)),
1614 return UncheckedCast<FixedDoubleArray>(base);
1619 GotoIf(WordNotEqual(LoadMap(base),
1620 LoadRoot(RootIndex::kSloppyArgumentsElementsMap)),
1622 return UncheckedCast<FixedArray>(base);
1626 return UncheckedCast<Int32T>(elements_kind);
1629 enum class ExtractFixedArrayFlag {
1631 kFixedDoubleArrays = 2,
1633 kNewSpaceAllocationOnly = 8,
1634 kAllFixedArrays = kFixedArrays | kFixedDoubleArrays,
1635 kAllFixedArraysDontCopyCOW = kAllFixedArrays | kDontCopyCOW
1670 Node* capacity =
nullptr,
1672 ExtractFixedArrayFlag::kAllFixedArrays,
1673 ParameterMode parameter_mode = INTPTR_PARAMETERS,
1675 Node* source_elements_kind =
nullptr);
1681 ExtractFixedArrayFlag::kAllFixedArrays) {
1682 return ExtractFixedArray(source, first, count, capacity, extract_flags,
1715 ElementsKind from_kind = PACKED_ELEMENTS,
1718 ExtractFixedArrayFlag::kAllFixedArrays,
1719 ParameterMode parameter_mode = INTPTR_PARAMETERS,
1720 HoleConversionMode convert_holes = HoleConversionMode::kDontConvert,
1722 Node* source_runtime_kind =
nullptr);
1746 ExtractFixedArrayFlag::kAllFixedArrays,
1747 ParameterMode parameter_mode = INTPTR_PARAMETERS);
1760 Node* CloneFixedArray(
Node* source,
1762 ExtractFixedArrayFlag::kAllFixedArraysDontCopyCOW) {
1763 ParameterMode mode = OptimalParameterMode();
1764 return ExtractFixedArray(source, IntPtrOrSmiConstant(0, mode),
nullptr,
1765 nullptr, flags, mode);
1775 void CopyStringCharacters(
Node* from_string,
Node* to_string,
1778 String::Encoding from_encoding,
1779 String::Encoding to_encoding);
1785 Node* LoadElementAndPrepareForStore(
Node* array,
Node* offset,
1786 ElementsKind from_kind,
1787 ElementsKind to_kind,
Label* if_hole);
1789 Node* CalculateNewElementsCapacity(
Node* old_capacity,
1790 ParameterMode mode = INTPTR_PARAMETERS);
1793 return CAST(CalculateNewElementsCapacity(old_capacity, SMI_PARAMETERS));
1798 Node* TryGrowElementsCapacity(
Node*
object,
Node* elements, ElementsKind kind,
1804 Node* TryGrowElementsCapacity(
Node*
object,
Node* elements, ElementsKind kind,
1805 Node* key,
Node* capacity, ParameterMode mode,
1809 Node* GrowElementsCapacity(
Node*
object,
Node* elements,
1810 ElementsKind from_kind, ElementsKind to_kind,
1811 Node* capacity,
Node* new_capacity,
1812 ParameterMode mode,
Label* bailout);
1817 void PossiblyGrowElementsCapacity(ParameterMode mode, ElementsKind kind,
1823 void InitializeAllocationMemento(
Node* base_allocation,
1824 Node* base_allocation_size,
1825 Node* allocation_site);
1827 Node* TryTaggedToFloat64(
Node* value,
Label* if_valueisnotnumber);
1828 Node* TruncateTaggedToFloat64(
Node* context,
Node* value);
1829 Node* TruncateTaggedToWord32(
Node* context,
Node* value);
1830 void TaggedToWord32OrBigInt(
Node* context,
Node* value,
Label* if_number,
1833 void TaggedToWord32OrBigIntWithFeedback(
1838 Node* TruncateHeapNumberValueToWord32(
Node*
object);
1853 void TaggedToNumeric(
Node* context,
Node* value,
Label* done,
1855 void TaggedToNumericWithFeedback(
Node* context,
Node* value,
Label* done,
1861 return Signed(TimesPointerSize(implicit_cast<
TNode<WordT>>(value)));
1864 return Unsigned(TimesPointerSize(implicit_cast<
TNode<WordT>>(value)));
1868 return Unsigned(TimesDoubleSize(implicit_cast<
TNode<WordT>>(value)));
1871 return Signed(TimesDoubleSize(implicit_cast<
TNode<WordT>>(value)));
1878 char const* method_name);
1882 Node* ToThisValue(
Node* context,
Node* value, PrimitiveType primitive_type,
1883 char const* method_name);
1887 Node* ThrowIfNotInstanceType(
Node* context,
Node* value,
1888 InstanceType instance_type,
1889 char const* method_name);
1893 MessageTemplate msg_template,
1894 const char* method_name =
nullptr);
1896 void ThrowRangeError(
Node* context, MessageTemplate message,
1897 Node* arg0 =
nullptr,
Node* arg1 =
nullptr,
1898 Node* arg2 =
nullptr);
1899 void ThrowTypeError(
Node* context, MessageTemplate message,
1900 char const* arg0 =
nullptr,
char const* arg1 =
nullptr);
1901 void ThrowTypeError(
Node* context, MessageTemplate message,
Node* arg0,
1902 Node* arg1 =
nullptr,
Node* arg2 =
nullptr);
2024 inline Node* IsSharedFunctionInfo(
Node*
object) {
2025 return IsSharedFunctionInfoMap(LoadMap(
object));
2031 TNode<BoolT> IsTypedArraySpeciesProtectorCellInvalid();
2064 Node* FixedArraySizeDoesntFitInNewSpace(
2065 Node* element_count,
int base_size = FixedArray::kHeaderSize,
2066 ParameterMode mode = INTPTR_PARAMETERS);
2070 return Word32Equal(a, b);
2072 bool ElementsKindEqual(ElementsKind a, ElementsKind b) {
return a == b; }
2073 Node* IsFastElementsKind(
Node* elements_kind);
2074 bool IsFastElementsKind(ElementsKind kind) {
2075 return v8::internal::IsFastElementsKind(kind);
2078 return ElementsKindEqual(elements_kind, Int32Constant(DICTIONARY_ELEMENTS));
2081 bool IsDoubleElementsKind(ElementsKind kind) {
2082 return v8::internal::IsDoubleElementsKind(kind);
2084 Node* IsFastSmiOrTaggedElementsKind(
Node* elements_kind);
2085 Node* IsFastSmiElementsKind(
Node* elements_kind);
2086 Node* IsHoleyFastElementsKind(
Node* elements_kind);
2087 Node* IsElementsKindGreaterThan(
Node* target_kind,
2088 ElementsKind reference_kind);
2090 ElementsKind reference_kind);
2110 void BranchIfCanDerefIndirectString(
Node*
string,
Node* instance_type,
2113 void DerefIndirectString(
Variable* var_string,
Node* instance_type);
2116 void MaybeDerefIndirectString(
Variable* var_string,
Node* instance_type,
2120 void MaybeDerefIndirectStrings(
Variable* var_left,
Node* left_instance_type,
2122 Label* did_something);
2124 Label* cannot_deref);
2127 UnicodeEncoding encoding);
2130 enum class BigIntHandling { kConvertToNumber, kThrow };
2138 BigIntHandling bigint_handling = BigIntHandling::kThrow);
2148 BigIntHandling bigint_handling = BigIntHandling::kThrow);
2170 Node* JSReceiverToPrimitive(
Node* context,
Node* input);
2180 enum ToIntegerTruncationMode {
2187 Label* range_error);
2191 Label* range_error);
2200 ToIntegerTruncationMode mode = kNoTruncation);
2203 ToIntegerTruncationMode mode = kNoTruncation);
2207 template <
typename BitField>
2209 return DecodeWord32(word32, BitField::kShift, BitField::kMask);
2214 template <
typename BitField>
2216 return DecodeWord(word, BitField::kShift, BitField::kMask);
2221 template <
typename BitField>
2223 return DecodeWord<BitField>(ChangeUint32ToWord(word32));
2228 template <
typename BitField>
2230 return UncheckedCast<Uint32T>(
2231 TruncateIntPtrToInt32(Signed(DecodeWord<BitField>(word))));
2243 template <
typename BitField>
2245 return UpdateWord(word, value, BitField::kShift, BitField::kMask);
2254 template <
typename T>
2256 return IsSetWord32(word32, T::kMask);
2261 return Word32NotEqual(Word32And(word32, Int32Constant(mask)),
2267 return Word32Equal(Word32And(word32, Int32Constant(mask)),
2274 return Word32Equal(Word32And(word32, const_mask), const_mask);
2278 template <
typename T>
2280 return IsSetWord(word, T::kMask);
2285 return WordNotEqual(WordAnd(word, IntPtrConstant(mask)), IntPtrConstant(0));
2291 intptr_t mask_word = bit_cast<intptr_t>(Smi::FromInt(untagged_mask));
2292 return WordNotEqual(
2293 WordAnd(BitcastTaggedToWord(smi), IntPtrConstant(mask_word)),
2298 template <
typename T>
2300 return IsClearWord32(word32, T::kMask);
2305 return Word32Equal(Word32And(word32, Int32Constant(mask)),
2310 template <
typename T>
2312 return IsClearWord(word, T::kMask);
2317 return WordEqual(WordAnd(word, IntPtrConstant(mask)), IntPtrConstant(0));
2321 void IncrementCounter(
StatsCounter* counter,
int delta);
2322 void DecrementCounter(
StatsCounter* counter,
int delta);
2324 void Increment(
Variable* variable,
int value = 1,
2325 ParameterMode mode = INTPTR_PARAMETERS);
2326 void Decrement(
Variable* variable,
int value = 1,
2327 ParameterMode mode = INTPTR_PARAMETERS) {
2328 Increment(variable, -value, mode);
2334 void Use(
Label* label);
2341 Label* if_notinternalized =
nullptr);
2354 Label* if_not_internalized,
Label* if_bailout);
2358 template <
typename Dictionary>
2360 template <
typename Dictionary>
2362 return EntryToIndex<Dictionary>(entry, Dictionary::kEntryKeyIndex);
2367 template <
class ContainerType>
2369 static_assert(!std::is_same<ContainerType, DescriptorArray>::value,
2370 "Use the non-templatized version for DescriptorArray");
2371 const int kKeyToDetailsOffset =
2372 (ContainerType::kEntryDetailsIndex - ContainerType::kEntryKeyIndex) *
2374 return Unsigned(LoadAndUntagToWord32FixedArrayElement(
2375 CAST(container), key_index, kKeyToDetailsOffset));
2380 template <
class ContainerType>
2382 static_assert(!std::is_same<ContainerType, DescriptorArray>::value,
2383 "Use the non-templatized version for DescriptorArray");
2384 const int kKeyToValueOffset =
2385 (ContainerType::kEntryValueIndex - ContainerType::kEntryKeyIndex) *
2387 return LoadFixedArrayElement(CAST(container), key_index, kKeyToValueOffset);
2392 template <
class ContainerType>
2395 const int kKeyToDetailsOffset =
2396 (ContainerType::kEntryDetailsIndex - ContainerType::kEntryKeyIndex) *
2398 StoreFixedArrayElement(container, key_index, details, SKIP_WRITE_BARRIER,
2399 kKeyToDetailsOffset);
2403 template <
class ContainerType>
2404 void StoreValueByKeyIndex(
2407 WriteBarrierMode write_barrier = UPDATE_WRITE_BARRIER) {
2408 const int kKeyToValueOffset =
2409 (ContainerType::kEntryValueIndex - ContainerType::kEntryKeyIndex) *
2411 StoreFixedArrayElement(container, key_index, value, write_barrier,
2418 template <
class Dictionary>
2421 LoadFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex));
2424 TNode<Smi> GetNumberDictionaryNumberOfElements(
2426 return GetNumberOfElements<NumberDictionary>(dictionary);
2429 template <
class Dictionary>
2432 StoreFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex,
2433 num_elements_smi, SKIP_WRITE_BARRIER);
2436 template <
class Dictionary>
2438 return CAST(LoadFixedArrayElement(
2439 dictionary, Dictionary::kNumberOfDeletedElementsIndex));
2442 template <
class Dictionary>
2445 StoreFixedArrayElement(dictionary,
2446 Dictionary::kNumberOfDeletedElementsIndex,
2447 num_deleted_smi, SKIP_WRITE_BARRIER);
2450 template <
class Dictionary>
2452 return CAST(LoadFixedArrayElement(dictionary, Dictionary::kCapacityIndex));
2455 template <
class Dictionary>
2457 return CAST(LoadFixedArrayElement(dictionary,
2458 Dictionary::kNextEnumerationIndexIndex));
2461 template <
class Dictionary>
2464 StoreFixedArrayElement(dictionary, Dictionary::kNextEnumerationIndexIndex,
2465 next_enum_index_smi, SKIP_WRITE_BARRIER);
2472 static const int kInlinedDictionaryProbes = 4;
2473 enum LookupMode { kFindExisting, kFindInsertionIndex };
2475 template <
typename Dictionary>
2478 template <
typename Dictionary>
2482 Label* if_not_found,
2483 int inlined_probes = kInlinedDictionaryProbes,
2484 LookupMode mode = kFindExisting);
2486 Node* ComputeUnseededHash(
Node* key);
2487 Node* ComputeSeededHash(
Node* key);
2492 Label* if_not_found);
2502 template <
class Dictionary>
2506 template <
class Dictionary>
2511 template <
class Dictionary>
2516 void TryHasOwnProperty(
Node*
object,
Node* map,
Node* instance_type,
2522 enum GetOwnPropertyMode { kCallJSGetter, kReturnAccessorPair };
2526 void TryGetOwnProperty(
Node* context,
Node* receiver,
Node*
object,
Node* map,
2527 Node* instance_type,
Node* unique_name,
2530 void TryGetOwnProperty(
Node* context,
Node* receiver,
Node*
object,
Node* map,
2531 Node* instance_type,
Node* unique_name,
2535 GetOwnPropertyMode mode);
2539 return GetProperty(context, receiver, HeapConstant(name));
2545 return CallBuiltin(Builtins::kGetProperty, context, receiver, name);
2551 return CallBuiltin(Builtins::kSetProperty, context, receiver, key, value);
2557 return CallBuiltin(Builtins::kSetPropertyInLiteral, context, receiver, key,
2562 Label* if_null_or_undefined);
2564 template <
class... TArgs>
2567 return CallStub<Object>(Builtins::CallableFor(isolate(),
id), context,
2571 template <
class... TArgs>
2574 return TailCallStub(Builtins::CallableFor(isolate(),
id), context, args...);
2577 void LoadPropertyFromFastObject(
Node*
object,
Node* map,
2582 void LoadPropertyFromFastObject(
Node*
object,
Node* map,
2587 void LoadPropertyFromNameDictionary(
Node* dictionary,
Node* entry,
2591 void LoadPropertyFromGlobalDictionary(
Node* dictionary,
Node* entry,
2610 Label* if_found_dict,
Label* if_found_global,
2619 Label* if_found_fast,
2620 Label* if_found_dict,
2623 Label* if_not_found);
2628 void TryLookupElement(
Node*
object,
Node* map,
2637 typedef std::function<void(
Node* receiver,
Node* holder,
Node* map,
2648 Label* if_maybe_special_index,
2649 Label* if_not_special_index);
2658 void TryPrototypeChainLookup(
Node* receiver,
Node* key,
2659 const LookupInHolder& lookup_property_in_holder,
2660 const LookupInHolder& lookup_element_in_holder,
2662 Label* if_proxy =
nullptr);
2677 Label* if_undefined =
nullptr);
2685 void UpdateFeedback(
Node* feedback,
Node* feedback_vector,
Node* slot_id);
2694 void CombineFeedback(
Variable* existing_feedback,
int feedback);
2695 void CombineFeedback(
Variable* existing_feedback,
Node* feedback);
2699 void OverwriteFeedback(
Variable* existing_feedback,
int new_feedback);
2703 void CheckForAssociatedProtector(
Node* name,
Label* if_protector);
2709 return EmitKeyedSloppyArguments(receiver, key,
nullptr, bailout);
2713 void StoreKeyedSloppyArguments(
Node* receiver,
Node* key,
Node* value,
2715 DCHECK_NOT_NULL(value);
2716 EmitKeyedSloppyArguments(receiver, key, value, bailout);
2723 Node* Int32ToUint8Clamped(
Node* int32_value);
2724 Node* Float64ToUint8Clamped(
Node* float64_value);
2727 ElementsKind elements_kind,
2731 void StoreElement(
Node* elements, ElementsKind kind,
Node* index,
Node* value,
2732 ParameterMode mode);
2739 Label* opt_if_neutered);
2752 void EmitElementStore(
Node*
object,
Node* key,
Node* value,
2753 ElementsKind elements_kind,
2754 KeyedAccessStoreMode store_mode,
Label* bailout,
2757 Node* CheckForCapacityGrow(
Node*
object,
Node* elements, ElementsKind kind,
2758 Node* length,
Node* key, ParameterMode mode,
2761 Node* CopyElementsOnWrite(
Node*
object,
Node* elements, ElementsKind kind,
2762 Node* length, ParameterMode mode,
Label* bailout);
2764 void TransitionElementsKind(
Node*
object,
Node* map, ElementsKind from_kind,
2765 ElementsKind to_kind,
Label* bailout);
2767 void TrapAllocationMemento(
Node*
object,
Label* memento_found);
2775 ParameterMode parameter_mode = INTPTR_PARAMETERS);
2787 enum class IndexAdvanceMode { kPre, kPost };
2789 typedef std::function<void(Node* index)> FastLoopBody;
2792 Node* end_index,
const FastLoopBody& body,
int increment,
2793 ParameterMode parameter_mode,
2794 IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre);
2796 Node* BuildFastLoop(
Node* start_index,
Node* end_index,
2797 const FastLoopBody& body,
int increment,
2798 ParameterMode parameter_mode,
2799 IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre) {
2800 return BuildFastLoop(
VariableList(0, zone()), start_index, end_index, body,
2801 increment, parameter_mode, advance_mode);
2804 enum class ForEachDirection { kForward, kReverse };
2806 typedef std::function<void(Node* fixed_array, Node* offset)>
2807 FastFixedArrayForEachBody;
2809 void BuildFastFixedArrayForEach(
2811 ElementsKind kind,
Node* first_element_inclusive,
2812 Node* last_element_exclusive,
const FastFixedArrayForEachBody& body,
2813 ParameterMode mode = INTPTR_PARAMETERS,
2814 ForEachDirection direction = ForEachDirection::kReverse);
2816 void BuildFastFixedArrayForEach(
2817 Node* fixed_array, ElementsKind kind,
Node* first_element_inclusive,
2818 Node* last_element_exclusive,
const FastFixedArrayForEachBody& body,
2819 ParameterMode mode = INTPTR_PARAMETERS,
2820 ForEachDirection direction = ForEachDirection::kReverse) {
2822 BuildFastFixedArrayForEach(list, fixed_array, kind, first_element_inclusive,
2823 last_element_exclusive, body, mode, direction);
2827 ParameterMode mode,
int header_size) {
2828 return ElementOffsetFromIndex(element_count, kind, mode, header_size);
2833 ParameterMode mode) {
2834 return GetArrayAllocationSize(element_count, kind, mode,
2835 FixedArray::kHeaderSize);
2839 ParameterMode mode) {
2840 return GetArrayAllocationSize(element_count, PACKED_ELEMENTS, mode,
2841 PropertyArray::kHeaderSize);
2844 void GotoIfFixedArraySizeDoesntFitInNewSpace(
Node* element_count,
2845 Label* doesnt_fit,
int base_size,
2846 ParameterMode mode);
2848 void InitializeFieldsWithRoot(
Node*
object,
Node* start_offset,
2849 Node* end_offset, RootIndex root);
2851 Node* RelationalComparison(Operation op,
Node* left,
Node* right,
2853 Variable* var_type_feedback =
nullptr);
2855 void BranchIfNumberRelationalComparison(Operation op,
Node* left,
Node* right,
2860 BranchIfNumberRelationalComparison(Operation::kEqual, left, right, if_true,
2866 BranchIfNumberEqual(left, right, if_false, if_true);
2871 BranchIfNumberRelationalComparison(Operation::kLessThan, left, right,
2877 BranchIfNumberRelationalComparison(Operation::kLessThanOrEqual, left, right,
2883 BranchIfNumberRelationalComparison(Operation::kGreaterThan, left, right,
2889 BranchIfNumberRelationalComparison(Operation::kGreaterThanOrEqual, left,
2890 right, if_true, if_false);
2893 void BranchIfAccessorPair(
Node* value,
Label* if_accessor_pair,
2894 Label* if_not_accessor_pair) {
2895 GotoIf(TaggedIsSmi(value), if_not_accessor_pair);
2896 Branch(IsAccessorPair(value), if_accessor_pair, if_not_accessor_pair);
2899 void GotoIfNumberGreaterThanOrEqual(
Node* left,
Node* right,
Label* if_false);
2902 Variable* var_type_feedback =
nullptr);
2905 Variable* var_type_feedback =
nullptr);
2912 enum HasPropertyLookupMode { kHasProperty, kForInHasProperty };
2917 HasPropertyLookupMode mode);
2923 return HasProperty(context,
object, key,
2924 HasPropertyLookupMode::kHasProperty);
2939 Node* IsDebugActive();
2947 Node* IsDetachedBuffer(
Node* buffer);
2950 const char* method_name);
2959 void ThrowIfArrayBufferViewBufferIsDetached(
2961 const char* method_name);
2967 ParameterMode mode,
int base_size = 0);
2972 ElementsKind kind = HOLEY_ELEMENTS);
2982 Label* if_compile_lazy =
nullptr);
2984 Node* AllocateFunctionWithMapAndContext(
Node* map,
Node* shared_info,
2988 Node* IsPromiseHookEnabled();
2989 Node* HasAsyncEventDelegate();
2990 Node* IsPromiseHookEnabledOrHasAsyncEventDelegate();
2991 Node* IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate();
2994 Node* MarkerIsFrameType(
Node* marker_or_function,
2995 StackFrame::Type frame_type);
2996 Node* MarkerIsNotFrameType(
Node* marker_or_function,
2997 StackFrame::Type frame_type);
3000 void CheckPrototypeEnumCache(
Node* receiver,
Node* receiver_map,
3008 void Print(
const char* s);
3009 void Print(
const char* prefix,
Node* tagged_value);
3011 return Print(
nullptr, tagged_value);
3014 return Print(
nullptr, tagged_value);
3017 template <
class... TArgs>
3018 Node* MakeTypeError(MessageTemplate message,
Node* context, TArgs... args) {
3019 STATIC_ASSERT(
sizeof...(TArgs) <= 3);
3020 Node*
const make_type_error = LoadContextElement(
3021 LoadNativeContext(context), Context::MAKE_TYPE_ERROR_INDEX);
3022 return CallJS(CodeFactory::Call(isolate()), context, make_type_error,
3023 UndefinedConstant(), SmiConstant(message), args...);
3026 void Abort(AbortReason reason) {
3027 CallRuntime(Runtime::kAbort, NoContextConstant(), SmiConstant(reason));
3031 bool ConstexprBoolNot(
bool value) {
return !value; }
3033 bool ConstexprInt31Equal(
int31_t a,
int31_t b) {
return a == b; }
3051 void GotoIfInitialPrototypePropertyModified(
TNode<Map> object_map,
3054 RootIndex field_name_root_index,
3055 Label* if_modified);
3059 : descriptor_index(descriptor_index),
3060 name_root_index(name_root_index) {}
3062 int descriptor_index;
3063 RootIndex name_root_index;
3065 void GotoIfInitialPrototypePropertiesModified(
3074 Label* if_not_found);
3082 Label* if_not_found);
3085 template <
typename Array>
3091 template <
typename Array>
3097 template <
typename Array>
3103 template <
typename Array>
3107 template <
typename Array>
3111 template <
typename Array>
3118 typedef std::function<void(TNode<IntPtrT> descriptor_key_index)>
3119 ForEachDescriptorBodyFunction;
3121 void DescriptorArrayForEach(
VariableList& variable_list,
3124 const ForEachDescriptorBodyFunction& body);
3153 typedef std::function<void(TNode<Name> key,
TNode<Object> value)>
3154 ForEachKeyValueFunction;
3161 const ForEachKeyValueFunction& body,
3166 GetOwnPropertyMode mode = kCallJSGetter);
3170 void BranchIfPrototypesHaveNoElements(
Node* receiver_map,
3171 Label* definitely_no_elements,
3172 Label* possibly_elements);
3174 void InitializeFunctionContext(
Node* native_context,
Node* context,
3186 void HandleBreakOnNode();
3205 Node* allocation_site,
3209 Node* SmiShiftBitsConstant();
3216 TNode<String> AllocateSlicedString(RootIndex map_root_index,
3228 const NodeGenerator& false_body, MachineRepresentation rep);
3231 template <
typename Array>
3235 template <
typename Array>
3240 void GenerateEqual_Same(
Node* value,
Label* if_equal,
Label* if_notequal,
3241 Variable* var_type_feedback =
nullptr);
3243 Node* from_instance_type,
3247 static const int kElementLoopUnrollThreshold = 8;
3250 Node* NonNumberToNumberOrNumeric(
3251 Node* context,
Node* input, Object::Conversion mode,
3252 BigIntHandling bigint_handling = BigIntHandling::kThrow);
3254 void TaggedToNumeric(
Node* context,
Node* value,
Label* done,
3257 template <Object::Conversion conversion>
3258 void TaggedToWord32OrBigIntImpl(
Node* context,
Node* value,
Label* if_number,
3260 Label* if_bigint =
nullptr,
3268 int additional_offset = 0);
3278 enum ReceiverMode { kHasReceiver, kNoReceiver };
3284 ReceiverMode receiver_mode = ReceiverMode::kHasReceiver)
3286 CodeStubAssembler::INTPTR_PARAMETERS, receiver_mode) {
3292 CodeStubAssembler::ParameterMode param_mode,
3293 ReceiverMode receiver_mode = ReceiverMode::kHasReceiver);
3302 Node* index, CodeStubAssembler::ParameterMode mode =
3303 CodeStubAssembler::INTPTR_PARAMETERS)
const;
3307 CodeStubAssembler::ParameterMode mode =
3308 CodeStubAssembler::INTPTR_PARAMETERS)
const;
3313 return GetOptionalArgumentValue(index, assembler_->UndefinedConstant());
3318 Node* GetLength(CodeStubAssembler::ParameterMode mode)
const {
3319 DCHECK_EQ(mode, argc_mode_);
3324 return GetOptionalArgumentValue(index, assembler_->UndefinedConstant());
3329 DCHECK_EQ(argc_mode_, CodeStubAssembler::INTPTR_PARAMETERS);
3330 return assembler_->UncheckedCast<
IntPtrT>(argc_);
3333 typedef std::function<void(Node* arg)> ForEachBodyFunction;
3336 void ForEach(
const ForEachBodyFunction& body,
Node* first =
nullptr,
3337 Node* last =
nullptr,
3338 CodeStubAssembler::ParameterMode mode =
3339 CodeStubAssembler::INTPTR_PARAMETERS) {
3341 ForEach(list, body, first, last);
3346 const ForEachBodyFunction& body,
Node* first =
nullptr,
3347 Node* last =
nullptr,
3348 CodeStubAssembler::ParameterMode mode =
3349 CodeStubAssembler::INTPTR_PARAMETERS);
3351 void PopAndReturn(
Node* value);
3354 Node* GetArguments();
3357 CodeStubAssembler::ParameterMode argc_mode_;
3358 ReceiverMode receiver_mode_;
3366 enum StringPointerKind { PTR_TO_DATA, PTR_TO_STRING };
3370 kDontUnpackSlicedStrings = 1 << 0,
3386 return TryToSequential(PTR_TO_DATA, if_bailout);
3392 return TryToSequential(PTR_TO_STRING, if_bailout);
3395 Node* string() {
return var_string_.value(); }
3396 Node* instance_type() {
return var_instance_type_.value(); }
3398 return UncheckedCast<IntPtrT>(var_offset_.value());
3400 Node* is_external() {
return var_is_external_.value(); }
3417 #endif // V8_CODE_STUB_ASSEMBLER_H_