5 #ifndef V8_COMPILER_CODE_ASSEMBLER_H_ 6 #define V8_COMPILER_CODE_ASSEMBLER_H_ 13 #include "src/allocation.h" 14 #include "src/base/macros.h" 15 #include "src/builtins/builtins.h" 16 #include "src/code-factory.h" 17 #include "src/globals.h" 18 #include "src/heap/heap.h" 19 #include "src/machine-type.h" 20 #include "src/objects.h" 21 #include "src/objects/arguments.h" 22 #include "src/objects/data-handler.h" 23 #include "src/objects/map.h" 24 #include "src/objects/maybe-object.h" 25 #include "src/runtime/runtime.h" 26 #include "src/zone/zone-containers.h" 33 class AsyncGeneratorRequest;
35 class CallInterfaceDescriptor;
38 class InterpreterData;
40 class JSAsyncFunctionObject;
41 class JSAsyncGeneratorObject;
44 class JSDateTimeFormat;
49 class JSRegExpStringIterator;
50 class JSRelativeTimeFormat;
51 class JSSegmentIterator;
53 class JSV8BreakIterator;
55 class JSWeakCollection;
57 class JSWeakFactoryCleanupIterator;
62 class PromiseCapability;
63 class PromiseFulfillReactionJobTask;
64 class PromiseReaction;
65 class PromiseReactionJobTask;
66 class PromiseRejectReactionJobTask;
67 class WeakFactoryCleanupJobTask;
78 static const MachineRepresentation kMachineRepresentation =
79 (kPointerSize == 4) ? MachineRepresentation::kWord32
80 : MachineRepresentation::kWord64;
84 static constexpr
MachineType kMachineType = MachineType::Pointer();
91 static const MachineRepresentation kMachineRepresentation =
92 MachineRepresentation::kWord32;
95 static constexpr
MachineType kMachineType = MachineType::Int32();
98 static constexpr
MachineType kMachineType = MachineType::Uint32();
102 static const MachineRepresentation kMachineRepresentation =
103 MachineRepresentation::kWord64;
106 static constexpr
MachineType kMachineType = MachineType::Int64();
109 static constexpr
MachineType kMachineType = MachineType::Uint64();
113 static constexpr
MachineType kMachineType = MachineType::IntPtr();
116 static constexpr
MachineType kMachineType = MachineType::UintPtr();
120 static const MachineRepresentation kMachineRepresentation =
121 MachineRepresentation::kFloat32;
122 static constexpr
MachineType kMachineType = MachineType::Float32();
126 static const MachineRepresentation kMachineRepresentation =
127 MachineRepresentation::kFloat64;
128 static constexpr
MachineType kMachineType = MachineType::Float64();
135 template <
class T1,
class T2>
140 return (type1 == type2) ? type1
141 : ((type1.IsTagged() && type2.IsTagged())
142 ? MachineType::AnyTagged()
143 : MachineType::None());
146 template <
class Type,
class Enable =
void>
148 static constexpr
MachineType value = Type::kMachineType;
151 template <
class Type,
class Enable>
156 static constexpr
MachineType value = MachineType::AnyTagged();
160 static constexpr
MachineType value = MachineType::AnyTagged();
164 static constexpr
MachineType value = MachineType::TaggedSigned();
166 template <
class HeapObjectSubtype>
169 typename
std::enable_if<
170 std::is_base_of<HeapObject, HeapObjectSubtype>::value ||
171 std::is_base_of<HeapObjectPtr, HeapObjectSubtype>::value>
::type> {
172 static constexpr
MachineType value = MachineType::TaggedPointer();
175 template <
class HeapObjectSubtype>
178 typename std::enable_if<
179 std::is_base_of<HeapObject, HeapObjectSubtype>::value ||
180 std::is_base_of<HeapObjectPtr, HeapObjectSubtype>::value>
::type>::value;
182 template <
class Type,
class Enable =
void>
184 static const MachineRepresentation value = Type::kMachineRepresentation;
188 T, typename
std::enable_if<std::is_base_of<Object, T>::value>
::type> {
189 static const MachineRepresentation value =
194 T, typename
std::enable_if<std::is_base_of<ObjectPtr, T>::value>
::type> {
195 static const MachineRepresentation value =
200 T, typename
std::enable_if<std::is_base_of<MaybeObject, T>::value>
::type> {
201 static const MachineRepresentation value =
207 static const bool value = std::is_base_of<Object, T>::value ||
208 std::is_base_of<ObjectPtr, T>::value ||
209 std::is_base_of<UntaggedT, T>::value ||
210 std::is_base_of<MaybeObject, T>::value ||
211 std::is_same<ExternalReference, T>::value;
212 static const bool is_tagged = std::is_base_of<Object, T>::value ||
213 std::is_base_of<ObjectPtr, T>::value ||
214 std::is_base_of<MaybeObject, T>::value;
217 template <
class T1,
class T2>
219 static const bool value =
221 static const bool is_tagged =
false;
224 template <
class T1,
class T2>
227 template <
class T1,
class T2>
229 static const bool is_tagged =
231 static const bool value = is_tagged;
234 template <
class T1,
class T2>
238 static const MachineRepresentation kMachineRepresentation =
239 kMachineType.representation();
240 static_assert(kMachineRepresentation != MachineRepresentation::kNone,
241 "no common representation");
244 "union types are only possible for tagged values");
247 using Number = UnionT<Smi, HeapNumber>;
248 using Numeric = UnionT<Number, BigInt>;
253 int31_t(
int value) : value_(value) {
254 DCHECK_EQ((value & 0x80000000) != 0, (value & 0x40000000) != 0);
256 int31_t& operator=(
int value) {
257 DCHECK_EQ((value & 0x80000000) != 0, (value & 0x40000000) != 0);
261 int32_t value()
const {
return value_; }
262 operator int32_t()
const {
return value_; }
268 #define ENUM_ELEMENT(Name) k##Name, 269 #define ENUM_STRUCT_ELEMENT(NAME, Name, name) k##Name, 270 enum class ObjectType {
272 OBJECT_TYPE_LIST(ENUM_ELEMENT) HEAP_OBJECT_TYPE_LIST(ENUM_ELEMENT)
273 STRUCT_LIST(ENUM_STRUCT_ELEMENT)
276 #undef ENUM_STRUCT_ELEMENT 278 class AccessCheckNeeded;
280 class ClassBoilerplate;
281 class BooleanWrapper;
282 class CompilationCacheTable;
285 class FunctionTemplateRareData;
286 class InternalizedString;
287 class JSArgumentsObject;
288 class JSContextExtensionObject;
290 class JSSloppyArgumentsObject;
292 class MutableHeapNumber;
296 class SloppyArgumentsElements;
301 class WasmExceptionObject;
302 class WasmExportedFunctionData;
303 class WasmGlobalObject;
304 class WasmMemoryObject;
305 class WasmModuleObject;
306 class WasmTableObject;
311 #define OBJECT_TYPE_CASE(Name) \ 313 struct ObjectTypeOf<Name> { \ 314 static const ObjectType value = ObjectType::k##Name; \ 316 #define OBJECT_TYPE_STRUCT_CASE(NAME, Name, name) \ 318 struct ObjectTypeOf<Name> { \ 319 static const ObjectType value = ObjectType::k##Name; \ 321 #define OBJECT_TYPE_TEMPLATE_CASE(Name) \ 322 template <class... Args> \ 323 struct ObjectTypeOf<Name<Args...>> { \ 324 static const ObjectType value = ObjectType::k##Name; \ 327 OBJECT_TYPE_LIST(OBJECT_TYPE_CASE)
328 HEAP_OBJECT_ORDINARY_TYPE_LIST(OBJECT_TYPE_CASE)
329 STRUCT_LIST(OBJECT_TYPE_STRUCT_CASE)
330 HEAP_OBJECT_TEMPLATE_TYPE_LIST(OBJECT_TYPE_TEMPLATE_CASE)
331 #undef OBJECT_TYPE_CASE 332 #undef OBJECT_TYPE_STRUCT_CASE 333 #undef OBJECT_TYPE_TEMPLATE_CASE 338 Address CheckObjectType(
Object* value, Address raw_type, Address raw_location);
342 class CallDescriptor;
344 class CodeAssemblerVariable;
354 typedef std::function<void()> CodeAssemblerCallback;
360 template <
class T,
class U>
362 static const bool value = std::is_base_of<U, T>::value ||
363 (std::is_base_of<U, HeapObject>::value &&
364 std::is_base_of<HeapObjectPtr, T>::value);
369 static const bool value =
true;
371 template <
class T1,
class T2,
class U>
373 static const bool value =
376 template <
class T,
class U1,
class U2>
378 static const bool value =
381 template <
class T1,
class T2,
class U1,
class U2>
383 static const bool value =
388 template <
class T,
class U>
416 template <
class T1,
class T2,
class U>
422 template <
class T,
class U1,
class U2>
427 template <
class T1,
class T2,
class U1,
class U2>
460 typename std::enable_if<is_subtype<U, T>::value,
int>
::type = 0>
462 TNode() : node_(
nullptr) {}
465 DCHECK_NOT_NULL(other.node_);
490 template <class U, typename std::enable_if<is_subtype<U, T>::value,
496 template <
class... Types>
500 #define PAIR_TYPE(T1, T2) PairT<T1, T2> 502 #define CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \ 503 V(Float32Equal, BoolT, Float32T, Float32T) \ 504 V(Float32LessThan, BoolT, Float32T, Float32T) \ 505 V(Float32LessThanOrEqual, BoolT, Float32T, Float32T) \ 506 V(Float32GreaterThan, BoolT, Float32T, Float32T) \ 507 V(Float32GreaterThanOrEqual, BoolT, Float32T, Float32T) \ 508 V(Float64Equal, BoolT, Float64T, Float64T) \ 509 V(Float64NotEqual, BoolT, Float64T, Float64T) \ 510 V(Float64LessThan, BoolT, Float64T, Float64T) \ 511 V(Float64LessThanOrEqual, BoolT, Float64T, Float64T) \ 512 V(Float64GreaterThan, BoolT, Float64T, Float64T) \ 513 V(Float64GreaterThanOrEqual, BoolT, Float64T, Float64T) \ 515 V(Int32GreaterThan, BoolT, Word32T, Word32T) \ 516 V(Int32GreaterThanOrEqual, BoolT, Word32T, Word32T) \ 517 V(Int32LessThan, BoolT, Word32T, Word32T) \ 518 V(Int32LessThanOrEqual, BoolT, Word32T, Word32T) \ 520 V(IntPtrLessThan, BoolT, WordT, WordT) \ 521 V(IntPtrLessThanOrEqual, BoolT, WordT, WordT) \ 522 V(IntPtrGreaterThan, BoolT, WordT, WordT) \ 523 V(IntPtrGreaterThanOrEqual, BoolT, WordT, WordT) \ 525 V(Uint32LessThan, BoolT, Word32T, Word32T) \ 526 V(Uint32LessThanOrEqual, BoolT, Word32T, Word32T) \ 527 V(Uint32GreaterThan, BoolT, Word32T, Word32T) \ 528 V(Uint32GreaterThanOrEqual, BoolT, Word32T, Word32T) \ 530 V(UintPtrLessThan, BoolT, WordT, WordT) \ 531 V(UintPtrLessThanOrEqual, BoolT, WordT, WordT) \ 532 V(UintPtrGreaterThan, BoolT, WordT, WordT) \ 533 V(UintPtrGreaterThanOrEqual, BoolT, WordT, WordT) 535 #define CODE_ASSEMBLER_BINARY_OP_LIST(V) \ 536 CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \ 537 V(Float64Add, Float64T, Float64T, Float64T) \ 538 V(Float64Sub, Float64T, Float64T, Float64T) \ 539 V(Float64Mul, Float64T, Float64T, Float64T) \ 540 V(Float64Div, Float64T, Float64T, Float64T) \ 541 V(Float64Mod, Float64T, Float64T, Float64T) \ 542 V(Float64Atan2, Float64T, Float64T, Float64T) \ 543 V(Float64Pow, Float64T, Float64T, Float64T) \ 544 V(Float64Max, Float64T, Float64T, Float64T) \ 545 V(Float64Min, Float64T, Float64T, Float64T) \ 546 V(Float64InsertLowWord32, Float64T, Float64T, Word32T) \ 547 V(Float64InsertHighWord32, Float64T, Float64T, Word32T) \ 548 V(IntPtrAddWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT, IntPtrT) \ 549 V(IntPtrSubWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT, IntPtrT) \ 550 V(Int32Add, Word32T, Word32T, Word32T) \ 551 V(Int32AddWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T, Int32T) \ 552 V(Int32Sub, Word32T, Word32T, Word32T) \ 553 V(Int32SubWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T, Int32T) \ 554 V(Int32Mul, Word32T, Word32T, Word32T) \ 555 V(Int32MulWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T, Int32T) \ 556 V(Int32Div, Int32T, Int32T, Int32T) \ 557 V(Int32Mod, Int32T, Int32T, Int32T) \ 558 V(WordRor, WordT, WordT, IntegralT) \ 559 V(Word32Ror, Word32T, Word32T, Word32T) \ 560 V(Word64Ror, Word64T, Word64T, Word64T) 564 #define CODE_ASSEMBLER_UNARY_OP_LIST(V) \ 565 V(Float64Abs, Float64T, Float64T) \ 566 V(Float64Acos, Float64T, Float64T) \ 567 V(Float64Acosh, Float64T, Float64T) \ 568 V(Float64Asin, Float64T, Float64T) \ 569 V(Float64Asinh, Float64T, Float64T) \ 570 V(Float64Atan, Float64T, Float64T) \ 571 V(Float64Atanh, Float64T, Float64T) \ 572 V(Float64Cos, Float64T, Float64T) \ 573 V(Float64Cosh, Float64T, Float64T) \ 574 V(Float64Exp, Float64T, Float64T) \ 575 V(Float64Expm1, Float64T, Float64T) \ 576 V(Float64Log, Float64T, Float64T) \ 577 V(Float64Log1p, Float64T, Float64T) \ 578 V(Float64Log2, Float64T, Float64T) \ 579 V(Float64Log10, Float64T, Float64T) \ 580 V(Float64Cbrt, Float64T, Float64T) \ 581 V(Float64Neg, Float64T, Float64T) \ 582 V(Float64Sin, Float64T, Float64T) \ 583 V(Float64Sinh, Float64T, Float64T) \ 584 V(Float64Sqrt, Float64T, Float64T) \ 585 V(Float64Tan, Float64T, Float64T) \ 586 V(Float64Tanh, Float64T, Float64T) \ 587 V(Float64ExtractLowWord32, Word32T, Float64T) \ 588 V(Float64ExtractHighWord32, Word32T, Float64T) \ 589 V(BitcastTaggedToWord, IntPtrT, Object) \ 590 V(BitcastMaybeObjectToWord, IntPtrT, MaybeObject) \ 591 V(BitcastWordToTagged, Object, WordT) \ 592 V(BitcastWordToTaggedSigned, Smi, WordT) \ 593 V(TruncateFloat64ToFloat32, Float32T, Float64T) \ 594 V(TruncateFloat64ToWord32, Word32T, Float64T) \ 595 V(TruncateInt64ToInt32, Int32T, Int64T) \ 596 V(ChangeFloat32ToFloat64, Float64T, Float32T) \ 597 V(ChangeFloat64ToUint32, Uint32T, Float64T) \ 598 V(ChangeFloat64ToUint64, Uint64T, Float64T) \ 599 V(ChangeInt32ToFloat64, Float64T, Int32T) \ 600 V(ChangeInt32ToInt64, Int64T, Int32T) \ 601 V(ChangeUint32ToFloat64, Float64T, Word32T) \ 602 V(ChangeUint32ToUint64, Uint64T, Word32T) \ 603 V(BitcastInt32ToFloat32, Float32T, Word32T) \ 604 V(BitcastFloat32ToInt32, Word32T, Float32T) \ 605 V(RoundFloat64ToInt32, Int32T, Float64T) \ 606 V(RoundInt32ToFloat32, Int32T, Float32T) \ 607 V(Float64SilenceNaN, Float64T, Float64T) \ 608 V(Float64RoundDown, Float64T, Float64T) \ 609 V(Float64RoundUp, Float64T, Float64T) \ 610 V(Float64RoundTiesEven, Float64T, Float64T) \ 611 V(Float64RoundTruncate, Float64T, Float64T) \ 612 V(Word32Clz, Int32T, Word32T) \ 613 V(Word32BitwiseNot, Word32T, Word32T) \ 614 V(WordNot, WordT, WordT) \ 615 V(Int32AbsWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T) \ 616 V(Int64AbsWithOverflow, PAIR_TYPE(Int64T, BoolT), Int64T) \ 617 V(IntPtrAbsWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT) \ 618 V(Word32BinaryNot, BoolT, Word32T) 649 bool IsFloat64RoundUpSupported()
const;
650 bool IsFloat64RoundDownSupported()
const;
651 bool IsFloat64RoundTiesEvenSupported()
const;
652 bool IsFloat64RoundTruncateSupported()
const;
653 bool IsInt32AbsWithOverflowSupported()
const;
654 bool IsInt64AbsWithOverflowSupported()
const;
655 bool IsIntPtrAbsWithOverflowSupported()
const;
668 template <
class PreviousType,
bool FromTyped>
673 : node_(node), code_assembler_(code_assembler), location_(location) {}
682 !std::is_same<A, MaybeObject>::value,
683 "Can't cast to MaybeObject, use explicit conversion functions. ");
686 "Incompatible types: this cast can never succeed.");
689 "Coercion to untagged values cannot be " 694 "Unnecessary CAST: types are convertible.");
696 if (FLAG_debug_code) {
697 if (std::is_same<PreviousType, MaybeObject>::value) {
698 code_assembler_->GenerateCheckMaybeObjectIsObject(node_, location_);
700 Node*
function = code_assembler_->ExternalConstant(
701 ExternalReference::check_object_type());
702 code_assembler_->CallCFunction3(
703 MachineType::AnyTagged(), MachineType::AnyTagged(),
704 MachineType::TaggedSigned(), MachineType::AnyTagged(),
function,
706 code_assembler_->SmiConstant(
708 code_assembler_->StringConstant(location_));
716 return implicit_cast<
TNode<A>>(*this);
719 Node* node()
const {
return node_; }
725 const char* location_;
733 template <
class T,
class U>
736 "Incompatible types: this cast can never succeed.");
747 CheckedNode<Object, false> Cast(Node* value,
const char* location =
"") {
748 return {value,
this, location};
752 CheckedNode<T, true> Cast(TNode<T> value,
const char* location =
"") {
753 return {value,
this, location};
757 #define STRINGIFY(x) #x 758 #define TO_STRING_LITERAL(x) STRINGIFY(x) 760 Cast(x, "CAST(" #x ") at " __FILE__ ":" TO_STRING_LITERAL(__LINE__)) 761 #define TORQUE_CAST(x) \ 762 ca_.Cast(x, "CAST(" #x ") at " __FILE__ ":" TO_STRING_LITERAL(__LINE__)) 764 #define CAST(x) Cast(x) 765 #define TORQUE_CAST(x) ca_.Cast(x) 769 void GenerateCheckMaybeObjectIsObject(Node* node,
const char* location);
773 TNode<Int32T> Int32Constant(int32_t value);
774 TNode<Int64T> Int64Constant(
int64_t value);
775 TNode<IntPtrT> IntPtrConstant(intptr_t value);
776 TNode<Uint32T> Uint32Constant(
uint32_t value) {
777 return Unsigned(Int32Constant(bit_cast<int32_t>(value)));
779 TNode<UintPtrT> UintPtrConstant(
uintptr_t value) {
780 return Unsigned(IntPtrConstant(bit_cast<intptr_t>(value)));
782 TNode<Number> NumberConstant(
double value);
783 TNode<Smi> SmiConstant(Smi value);
784 TNode<Smi> SmiConstant(
int value);
785 template <
typename E,
786 typename =
typename std::enable_if<std::is_enum<E>::value>::type>
787 TNode<Smi> SmiConstant(E value) {
788 STATIC_ASSERT(
sizeof(E) <=
sizeof(
int));
789 return SmiConstant(static_cast<int>(value));
791 TNode<HeapObject> UntypedHeapConstant(Handle<HeapObject>
object);
792 template <
class Type>
793 TNode<Type> HeapConstant(Handle<Type>
object) {
794 return UncheckedCast<Type>(UntypedHeapConstant(
object));
796 TNode<String> StringConstant(
const char* str);
797 TNode<Oddball> BooleanConstant(
bool value);
798 TNode<ExternalReference> ExternalConstant(ExternalReference address);
799 TNode<Float64T> Float64Constant(
double value);
800 TNode<HeapNumber> NaNConstant();
801 TNode<BoolT> Int32TrueConstant() {
802 return ReinterpretCast<BoolT>(Int32Constant(1));
804 TNode<BoolT> Int32FalseConstant() {
805 return ReinterpretCast<BoolT>(Int32Constant(0));
807 TNode<BoolT> BoolConstant(
bool value) {
808 return value ? Int32TrueConstant() : Int32FalseConstant();
813 bool ToInt32Constant(Node* node, int32_t& out_value);
814 bool ToInt64Constant(Node* node,
int64_t& out_value);
815 bool ToSmiConstant(Node* node, Smi* out_value);
816 bool ToIntPtrConstant(Node* node, intptr_t& out_value);
818 bool IsUndefinedConstant(TNode<Object> node);
819 bool IsNullConstant(TNode<Object> node);
821 TNode<Int32T> Signed(TNode<Word32T> x) {
return UncheckedCast<Int32T>(x); }
822 TNode<IntPtrT> Signed(TNode<WordT> x) {
return UncheckedCast<IntPtrT>(x); }
823 TNode<Uint32T> Unsigned(TNode<Word32T> x) {
824 return UncheckedCast<Uint32T>(x);
826 TNode<UintPtrT> Unsigned(TNode<WordT> x) {
827 return UncheckedCast<UintPtrT>(x);
830 static constexpr
int kTargetParameterIndex = -1;
832 Node* Parameter(
int value);
834 TNode<Context> GetJSContextParameter();
835 void Return(SloppyTNode<Object> value);
836 void Return(SloppyTNode<Object> value1, SloppyTNode<Object> value2);
837 void Return(SloppyTNode<Object> value1, SloppyTNode<Object> value2,
838 SloppyTNode<Object> value3);
839 void PopAndReturn(Node* pop, Node* value);
841 void ReturnIf(Node* condition, Node* value);
843 void ReturnRaw(Node* value);
845 void DebugAbort(Node* message);
848 void Comment(
const char* format, ...);
850 void Bind(Label* label);
852 void Bind(Label* label, AssemblerDebugInfo debug_info);
854 void Goto(Label* label);
855 void GotoIf(SloppyTNode<IntegralT> condition, Label* true_label);
856 void GotoIfNot(SloppyTNode<IntegralT> condition, Label* false_label);
857 void Branch(SloppyTNode<IntegralT> condition, Label* true_label,
861 TNode<T> Uninitialized() {
865 template <
class... T>
866 void Bind(CodeAssemblerParameterizedLabel<T...>* label, TNode<T>*... phis) {
867 Bind(label->plain_label());
868 label->CreatePhis(phis...);
870 template <
class... T,
class... Args>
871 void Branch(TNode<BoolT> condition,
872 CodeAssemblerParameterizedLabel<T...>* if_true,
873 CodeAssemblerParameterizedLabel<T...>* if_false, Args... args) {
874 if_true->AddInputs(args...);
875 if_false->AddInputs(args...);
876 Branch(condition, if_true->plain_label(), if_false->plain_label());
879 template <
class... T,
class... Args>
880 void Goto(CodeAssemblerParameterizedLabel<T...>* label, Args... args) {
881 label->AddInputs(args...);
882 Goto(label->plain_label());
885 void Branch(TNode<BoolT> condition,
const std::function<
void()>& true_body,
886 const std::function<
void()>& false_body);
887 void Branch(TNode<BoolT> condition, Label* true_label,
888 const std::function<
void()>& false_body);
889 void Branch(TNode<BoolT> condition,
const std::function<
void()>& true_body,
892 void Switch(Node* index, Label* default_label,
const int32_t* case_values,
893 Label** case_labels,
size_t case_count);
896 Node* LoadFramePointer();
897 Node* LoadParentFramePointer();
900 Node* LoadStackPointer();
903 TNode<Object> TaggedPoisonOnSpeculation(SloppyTNode<Object> value);
904 TNode<WordT> WordPoisonOnSpeculation(SloppyTNode<WordT> value);
907 Node* Load(MachineType rep, Node* base,
908 LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
909 template <
class Type>
910 TNode<Type> Load(MachineType rep, TNode<RawPtr<Type>> base) {
912 IsSubtype(rep.representation(), MachineRepresentationOf<Type>::value));
913 return UncheckedCast<Type>(Load(rep, static_cast<Node*>(base)));
915 Node* Load(MachineType rep, Node* base, Node* offset,
916 LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
917 Node* AtomicLoad(MachineType rep, Node* base, Node* offset);
920 TNode<Object> LoadRoot(RootIndex root_index);
923 Node* Store(Node* base, Node* value);
924 Node* Store(Node* base, Node* offset, Node* value);
925 Node* StoreWithMapWriteBarrier(Node* base, Node* offset, Node* value);
926 Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
927 Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* offset,
931 Node* AtomicStore(MachineRepresentation rep, Node* base, Node* offset,
932 Node* value, Node* value_high =
nullptr);
935 Node* AtomicExchange(MachineType type, Node* base, Node* offset, Node* value,
936 Node* value_high =
nullptr);
939 Node* AtomicCompareExchange(MachineType type, Node* base, Node* offset,
940 Node* old_value, Node* new_value,
941 Node* old_value_high =
nullptr,
942 Node* new_value_high =
nullptr);
944 Node* AtomicAdd(MachineType type, Node* base, Node* offset, Node* value,
945 Node* value_high =
nullptr);
947 Node* AtomicSub(MachineType type, Node* base, Node* offset, Node* value,
948 Node* value_high =
nullptr);
950 Node* AtomicAnd(MachineType type, Node* base, Node* offset, Node* value,
951 Node* value_high =
nullptr);
953 Node* AtomicOr(MachineType type, Node* base, Node* offset, Node* value,
954 Node* value_high =
nullptr);
956 Node* AtomicXor(MachineType type, Node* base, Node* offset, Node* value,
957 Node* value_high =
nullptr);
960 Node* StoreRoot(RootIndex root_index, Node* value);
963 #define DECLARE_CODE_ASSEMBLER_BINARY_OP(name, ResType, Arg1Type, Arg2Type) \ 964 TNode<ResType> name(SloppyTNode<Arg1Type> a, SloppyTNode<Arg2Type> b); 965 CODE_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_ASSEMBLER_BINARY_OP)
966 #undef DECLARE_CODE_ASSEMBLER_BINARY_OP 968 TNode<IntPtrT> WordShr(TNode<IntPtrT> left, TNode<IntegralT> right) {
969 return UncheckedCast<IntPtrT>(
970 WordShr(static_cast<Node*>(left), static_cast<Node*>(right)));
972 TNode<IntPtrT> WordSar(TNode<IntPtrT> left, TNode<IntegralT> right) {
973 return UncheckedCast<IntPtrT>(
974 WordSar(static_cast<Node*>(left), static_cast<Node*>(right)));
977 TNode<IntPtrT> WordAnd(TNode<IntPtrT> left, TNode<IntPtrT> right) {
978 return UncheckedCast<IntPtrT>(
979 WordAnd(static_cast<Node*>(left), static_cast<Node*>(right)));
983 template <
class Left,
class Right,
984 class =
typename std::enable_if<
985 (std::is_base_of<Object, Left>::value ||
986 std::is_base_of<ObjectPtr, Left>::value) &&
987 (std::is_base_of<Object, Right>::value ||
988 std::is_base_of<ObjectPtr, Right>::value)>::type>
989 TNode<BoolT> WordEqual(TNode<Left> left, TNode<Right> right) {
990 return WordEqual(ReinterpretCast<WordT>(left),
991 ReinterpretCast<WordT>(right));
993 TNode<BoolT> WordEqual(TNode<Object> left, Node* right) {
994 return WordEqual(ReinterpretCast<WordT>(left),
995 ReinterpretCast<WordT>(right));
997 TNode<BoolT> WordEqual(Node* left, TNode<Object> right) {
998 return WordEqual(ReinterpretCast<WordT>(left),
999 ReinterpretCast<WordT>(right));
1001 template <
class Left,
class Right,
1002 class =
typename std::enable_if<
1003 (std::is_base_of<Object, Left>::value ||
1004 std::is_base_of<ObjectPtr, Left>::value) &&
1005 (std::is_base_of<Object, Right>::value ||
1006 std::is_base_of<ObjectPtr, Right>::value)>::type>
1007 TNode<BoolT> WordNotEqual(TNode<Left> left, TNode<Right> right) {
1008 return WordNotEqual(ReinterpretCast<WordT>(left),
1009 ReinterpretCast<WordT>(right));
1011 TNode<BoolT> WordNotEqual(TNode<Object> left, Node* right) {
1012 return WordNotEqual(ReinterpretCast<WordT>(left),
1013 ReinterpretCast<WordT>(right));
1015 TNode<BoolT> WordNotEqual(Node* left, TNode<Object> right) {
1016 return WordNotEqual(ReinterpretCast<WordT>(left),
1017 ReinterpretCast<WordT>(right));
1020 TNode<BoolT> IntPtrEqual(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
1021 TNode<BoolT> WordEqual(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
1022 TNode<BoolT> WordNotEqual(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
1023 TNode<BoolT> Word32Equal(SloppyTNode<Word32T> left,
1024 SloppyTNode<Word32T> right);
1025 TNode<BoolT> Word32NotEqual(SloppyTNode<Word32T> left,
1026 SloppyTNode<Word32T> right);
1027 TNode<BoolT> Word64Equal(SloppyTNode<Word64T> left,
1028 SloppyTNode<Word64T> right);
1029 TNode<BoolT> Word64NotEqual(SloppyTNode<Word64T> left,
1030 SloppyTNode<Word64T> right);
1032 TNode<Int32T> Int32Add(TNode<Int32T> left, TNode<Int32T> right) {
1034 Int32Add(static_cast<Node*>(left), static_cast<Node*>(right)));
1037 TNode<Uint32T> Uint32Add(TNode<Uint32T> left, TNode<Uint32T> right) {
1039 Int32Add(static_cast<Node*>(left), static_cast<Node*>(right)));
1042 TNode<WordT> IntPtrAdd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
1043 TNode<IntPtrT> IntPtrDiv(TNode<IntPtrT> left, TNode<IntPtrT> right);
1044 TNode<WordT> IntPtrSub(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
1045 TNode<WordT> IntPtrMul(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
1046 TNode<IntPtrT> IntPtrAdd(TNode<IntPtrT> left, TNode<IntPtrT> right) {
1048 IntPtrAdd(static_cast<Node*>(left), static_cast<Node*>(right)));
1050 TNode<IntPtrT> IntPtrSub(TNode<IntPtrT> left, TNode<IntPtrT> right) {
1052 IntPtrSub(static_cast<Node*>(left), static_cast<Node*>(right)));
1054 TNode<IntPtrT> IntPtrMul(TNode<IntPtrT> left, TNode<IntPtrT> right) {
1056 IntPtrMul(static_cast<Node*>(left), static_cast<Node*>(right)));
1058 TNode<UintPtrT> UintPtrAdd(TNode<UintPtrT> left, TNode<UintPtrT> right) {
1060 IntPtrAdd(static_cast<Node*>(left), static_cast<Node*>(right)));
1062 TNode<UintPtrT> UintPtrSub(TNode<UintPtrT> left, TNode<UintPtrT> right) {
1064 IntPtrSub(static_cast<Node*>(left), static_cast<Node*>(right)));
1067 TNode<WordT> WordShl(SloppyTNode<WordT> value,
int shift);
1068 TNode<WordT> WordShr(SloppyTNode<WordT> value,
int shift);
1069 TNode<WordT> WordSar(SloppyTNode<WordT> value,
int shift);
1070 TNode<IntPtrT> WordShr(TNode<IntPtrT> value,
int shift) {
1071 return UncheckedCast<IntPtrT>(WordShr(static_cast<Node*>(value), shift));
1073 TNode<IntPtrT> WordSar(TNode<IntPtrT> value,
int shift) {
1074 return UncheckedCast<IntPtrT>(WordSar(static_cast<Node*>(value), shift));
1076 TNode<Word32T> Word32Shr(SloppyTNode<Word32T> value,
int shift);
1078 TNode<WordT> WordOr(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
1079 TNode<WordT> WordAnd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
1080 TNode<WordT> WordXor(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
1081 TNode<WordT> WordShl(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
1082 TNode<WordT> WordShr(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
1083 TNode<WordT> WordSar(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
1084 TNode<Word32T> Word32Or(SloppyTNode<Word32T> left,
1085 SloppyTNode<Word32T> right);
1086 TNode<Word32T> Word32And(SloppyTNode<Word32T> left,
1087 SloppyTNode<Word32T> right);
1088 TNode<Word32T> Word32Xor(SloppyTNode<Word32T> left,
1089 SloppyTNode<Word32T> right);
1090 TNode<Word32T> Word32Shl(SloppyTNode<Word32T> left,
1091 SloppyTNode<Word32T> right);
1092 TNode<Word32T> Word32Shr(SloppyTNode<Word32T> left,
1093 SloppyTNode<Word32T> right);
1094 TNode<Word32T> Word32Sar(SloppyTNode<Word32T> left,
1095 SloppyTNode<Word32T> right);
1096 TNode<Word64T> Word64Or(SloppyTNode<Word64T> left,
1097 SloppyTNode<Word64T> right);
1098 TNode<Word64T> Word64And(SloppyTNode<Word64T> left,
1099 SloppyTNode<Word64T> right);
1100 TNode<Word64T> Word64Xor(SloppyTNode<Word64T> left,
1101 SloppyTNode<Word64T> right);
1102 TNode<Word64T> Word64Shl(SloppyTNode<Word64T> left,
1103 SloppyTNode<Word64T> right);
1104 TNode<Word64T> Word64Shr(SloppyTNode<Word64T> left,
1105 SloppyTNode<Word64T> right);
1106 TNode<Word64T> Word64Sar(SloppyTNode<Word64T> left,
1107 SloppyTNode<Word64T> right);
1110 #define DECLARE_CODE_ASSEMBLER_UNARY_OP(name, ResType, ArgType) \ 1111 TNode<ResType> name(SloppyTNode<ArgType> a); 1112 CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP)
1113 #undef DECLARE_CODE_ASSEMBLER_UNARY_OP 1117 TNode<UintPtrT> ChangeFloat64ToUintPtr(SloppyTNode<Float64T> value);
1119 TNode<Float64T> ChangeUintPtrToFloat64(TNode<UintPtrT> value);
1124 Node* RoundIntPtrToFloat64(Node* value);
1126 TNode<UintPtrT> ChangeUint32ToWord(SloppyTNode<Word32T> value);
1128 TNode<IntPtrT> ChangeInt32ToIntPtr(SloppyTNode<Word32T> value);
1132 Node* Retain(Node* value);
1135 Node* Projection(
int index, Node* value);
1137 template <
int index,
class T1,
class T2>
1138 TNode<typename std::tuple_element<index, std::tuple<T1, T2>>::type>
1139 Projection(TNode<PairT<T1, T2>> value) {
1140 return UncheckedCast<
1141 typename std::tuple_element<index, std::tuple<T1, T2>>::type>(
1142 Projection(index, value));
1146 template <
class... TArgs>
1147 TNode<Object> CallRuntime(Runtime::FunctionId
function,
1148 SloppyTNode<Object> context, TArgs... args) {
1149 return CallRuntimeImpl(
function, context,
1150 {implicit_cast<SloppyTNode<Object>>(args)...});
1153 template <
class... TArgs>
1154 TNode<Object> CallRuntimeWithCEntry(Runtime::FunctionId
function,
1156 SloppyTNode<Object> context,
1158 return CallRuntimeWithCEntryImpl(
function, centry, context, {args...});
1161 template <
class... TArgs>
1162 void TailCallRuntime(Runtime::FunctionId
function,
1163 SloppyTNode<Object> context, TArgs... args) {
1164 int argc =
static_cast<int>(
sizeof...(args));
1165 TNode<Int32T> arity = Int32Constant(argc);
1166 return TailCallRuntimeImpl(
function, arity, context,
1167 {implicit_cast<SloppyTNode<Object>>(args)...});
1170 template <
class... TArgs>
1171 void TailCallRuntime(Runtime::FunctionId
function, TNode<Int32T> arity,
1172 SloppyTNode<Object> context, TArgs... args) {
1173 return TailCallRuntimeImpl(
function, arity, context,
1174 {implicit_cast<SloppyTNode<Object>>(args)...});
1177 template <
class... TArgs>
1178 void TailCallRuntimeWithCEntry(Runtime::FunctionId
function,
1179 TNode<Code> centry, TNode<Object> context,
1181 int argc =
sizeof...(args);
1182 TNode<Int32T> arity = Int32Constant(argc);
1183 return TailCallRuntimeWithCEntryImpl(
1184 function, arity, centry, context,
1185 {implicit_cast<SloppyTNode<Object>>(args)...});
1192 template <
class T = Object,
class... TArgs>
1193 TNode<T> CallStub(Callable
const& callable, SloppyTNode<Object> context,
1195 TNode<Code> target = HeapConstant(callable.code());
1196 return CallStub<T>(callable.descriptor(), target, context, args...);
1199 template <
class T = Object,
class... TArgs>
1200 TNode<T> CallStub(
const CallInterfaceDescriptor& descriptor,
1201 SloppyTNode<Code> target, SloppyTNode<Object> context,
1203 return UncheckedCast<T>(CallStubR(descriptor, 1, target, context, args...));
1206 template <
class... TArgs>
1207 Node* CallStubR(
const CallInterfaceDescriptor& descriptor,
size_t result_size,
1208 SloppyTNode<Code> target, SloppyTNode<Object> context,
1210 return CallStubRImpl(descriptor, result_size, target, context, {args...});
1213 Node* CallStubN(
const CallInterfaceDescriptor& descriptor,
size_t result_size,
1214 int input_count, Node*
const* inputs);
1216 template <
class... TArgs>
1217 void TailCallStub(Callable
const& callable, SloppyTNode<Object> context,
1219 TNode<Code> target = HeapConstant(callable.code());
1220 return TailCallStub(callable.descriptor(), target, context, args...);
1223 template <
class... TArgs>
1224 void TailCallStub(
const CallInterfaceDescriptor& descriptor,
1225 SloppyTNode<Code> target, SloppyTNode<Object> context,
1227 return TailCallStubImpl(descriptor, target, context, {args...});
1230 template <
class... TArgs>
1231 Node* TailCallBytecodeDispatch(
const CallInterfaceDescriptor& descriptor,
1232 Node* target, TArgs... args);
1234 template <
class... TArgs>
1235 Node* TailCallStubThenBytecodeDispatch(
1236 const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
1238 return TailCallStubThenBytecodeDispatchImpl(descriptor, target, context,
1249 TNode<Object> TailCallJSCode(TNode<Code> code, TNode<Context> context,
1250 TNode<JSFunction>
function,
1251 TNode<Object> new_target,
1252 TNode<Int32T> arg_count);
1254 template <
class... TArgs>
1255 Node* CallJS(Callable
const& callable, Node* context, Node*
function,
1256 Node* receiver, TArgs... args) {
1257 int argc =
static_cast<int>(
sizeof...(args));
1258 Node* arity = Int32Constant(argc);
1259 return CallStub(callable, context,
function, arity, receiver, args...);
1262 template <
class... TArgs>
1263 Node* ConstructJS(Callable
const& callable, Node* context, Node* new_target,
1265 int argc =
static_cast<int>(
sizeof...(args));
1266 Node* arity = Int32Constant(argc);
1267 Node* receiver = LoadRoot(RootIndex::kUndefinedValue);
1270 return CallStub(callable, context, new_target, new_target, arity, receiver,
1274 Node* CallCFunctionN(Signature<MachineType>* signature,
int input_count,
1275 Node*
const* inputs);
1278 Node* CallCFunction1(MachineType return_type, MachineType arg0_type,
1279 Node*
function, Node* arg0);
1283 Node* CallCFunction1WithCallerSavedRegisters(MachineType return_type,
1284 MachineType arg0_type,
1285 Node*
function, Node* arg0,
1286 SaveFPRegsMode mode);
1289 Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
1290 MachineType arg1_type, Node*
function, Node* arg0,
1294 Node* CallCFunction3(MachineType return_type, MachineType arg0_type,
1295 MachineType arg1_type, MachineType arg2_type,
1296 Node*
function, Node* arg0, Node* arg1, Node* arg2);
1300 Node* CallCFunction3WithCallerSavedRegisters(
1301 MachineType return_type, MachineType arg0_type, MachineType arg1_type,
1302 MachineType arg2_type, Node*
function, Node* arg0, Node* arg1, Node* arg2,
1303 SaveFPRegsMode mode);
1306 Node* CallCFunction4(MachineType return_type, MachineType arg0_type,
1307 MachineType arg1_type, MachineType arg2_type,
1308 MachineType arg3_type, Node*
function, Node* arg0,
1309 Node* arg1, Node* arg2, Node* arg3);
1312 Node* CallCFunction5(MachineType return_type, MachineType arg0_type,
1313 MachineType arg1_type, MachineType arg2_type,
1314 MachineType arg3_type, MachineType arg4_type,
1315 Node*
function, Node* arg0, Node* arg1, Node* arg2,
1316 Node* arg3, Node* arg4);
1319 Node* CallCFunction6(MachineType return_type, MachineType arg0_type,
1320 MachineType arg1_type, MachineType arg2_type,
1321 MachineType arg3_type, MachineType arg4_type,
1322 MachineType arg5_type, Node*
function, Node* arg0,
1323 Node* arg1, Node* arg2, Node* arg3, Node* arg4,
1327 Node* CallCFunction9(MachineType return_type, MachineType arg0_type,
1328 MachineType arg1_type, MachineType arg2_type,
1329 MachineType arg3_type, MachineType arg4_type,
1330 MachineType arg5_type, MachineType arg6_type,
1331 MachineType arg7_type, MachineType arg8_type,
1332 Node*
function, Node* arg0, Node* arg1, Node* arg2,
1333 Node* arg3, Node* arg4, Node* arg5, Node* arg6,
1334 Node* arg7, Node* arg8);
1337 void GotoIfException(Node* node, Label* if_exception,
1338 Variable* exception_var =
nullptr);
1341 Factory* factory()
const;
1342 Isolate* isolate()
const;
1345 CodeAssemblerState* state() {
return state_; }
1347 void BreakOnNode(
int node_id);
1349 bool UnalignedLoadSupported(MachineRepresentation rep)
const;
1350 bool UnalignedStoreSupported(MachineRepresentation rep)
const;
1352 bool IsExceptionHandlerActive()
const;
1355 void RegisterCallGenerationCallbacks(
1356 const CodeAssemblerCallback& call_prologue,
1357 const CodeAssemblerCallback& call_epilogue);
1358 void UnregisterCallGenerationCallbacks();
1360 bool Word32ShiftIsSafe()
const;
1361 PoisoningMitigationLevel poisoning_level()
const;
1363 bool IsJSFunctionCall()
const;
1366 void HandleException(Node* result);
1368 TNode<Object> CallRuntimeImpl(Runtime::FunctionId
function,
1369 TNode<Object> context,
1370 std::initializer_list<TNode<Object>> args);
1372 TNode<Object> CallRuntimeWithCEntryImpl(
1373 Runtime::FunctionId
function, TNode<Code> centry, TNode<Object> context,
1374 std::initializer_list<TNode<Object>> args);
1376 void TailCallRuntimeImpl(Runtime::FunctionId
function, TNode<Int32T> arity,
1377 TNode<Object> context,
1378 std::initializer_list<TNode<Object>> args);
1380 void TailCallRuntimeWithCEntryImpl(Runtime::FunctionId
function,
1381 TNode<Int32T> arity, TNode<Code> centry,
1382 TNode<Object> context,
1383 std::initializer_list<TNode<Object>> args);
1385 void TailCallStubImpl(
const CallInterfaceDescriptor& descriptor,
1386 TNode<Code> target, TNode<Object> context,
1387 std::initializer_list<Node*> args);
1389 Node* TailCallStubThenBytecodeDispatchImpl(
1390 const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
1391 std::initializer_list<Node*> args);
1393 Node* CallStubRImpl(
const CallInterfaceDescriptor& descriptor,
1394 size_t result_size, SloppyTNode<Code> target,
1395 SloppyTNode<Object> context,
1396 std::initializer_list<Node*> args);
1400 TNode<Int32T> Signed(TNode<Int32T> x);
1401 TNode<Uint32T> Unsigned(TNode<Uint32T> x);
1403 RawMachineAssembler* raw_assembler()
const;
1406 void CallPrologue();
1407 void CallEpilogue();
1409 CodeAssemblerState* state_;
1411 DISALLOW_COPY_AND_ASSIGN(CodeAssembler);
1417 MachineRepresentation rep);
1419 Node* initial_value);
1422 MachineRepresentation rep);
1424 MachineRepresentation rep,
Node* initial_value);
1428 void Bind(
Node* value);
1429 Node* value()
const;
1430 MachineRepresentation rep()
const;
1431 bool IsBound()
const;
1437 friend std::ostream& operator<<(std::ostream&,
const Impl&);
1439 struct ImplComparator {
1457 explicit TypedCodeAssemblerVariable(CodeAssembler* assembler)
1460 TypedCodeAssemblerVariable(AssemblerDebugInfo debug_info,
1461 CodeAssembler* assembler)
1462 : CodeAssemblerVariable(assembler, debug_info,
1463 MachineRepresentationOf<
T>::value) {}
1464 TypedCodeAssemblerVariable(AssemblerDebugInfo debug_info,
1465 TNode<T> initial_value, CodeAssembler* assembler)
1466 : CodeAssemblerVariable(assembler, debug_info,
1467 MachineRepresentationOf<T>::value,
1471 TNode<T> value()
const {
1472 return TNode<T>::UncheckedCast(CodeAssemblerVariable::value());
1475 void operator=(TNode<T> value) { Bind(value); }
1476 void operator=(
const TypedCodeAssemblerVariable<T>& variable) {
1477 Bind(variable.value());
1481 using CodeAssemblerVariable::Bind;
1486 enum Type { kDeferred, kNonDeferred };
1490 CodeAssemblerLabel::Type
type = CodeAssemblerLabel::kNonDeferred)
1495 CodeAssemblerLabel::Type
type = CodeAssemblerLabel::kNonDeferred)
1497 &(merged_variables[0]),
type) {}
1501 CodeAssemblerLabel::Type
type = CodeAssemblerLabel::kNonDeferred);
1504 std::initializer_list<CodeAssemblerVariable*> vars,
1505 CodeAssemblerLabel::Type
type = CodeAssemblerLabel::kNonDeferred)
1509 CodeAssemblerLabel::Type
type = CodeAssemblerLabel::kNonDeferred)
1513 inline bool is_bound()
const {
return bound_; }
1514 inline bool is_used()
const {
return merge_count_ != 0; }
1523 void UpdateVariablesAfterBind();
1524 void MergeVariables();
1527 size_t merge_count_;
1533 CodeAssemblerVariable::ImplComparator>
1537 std::map<CodeAssemblerVariable::Impl*, std::vector<Node*>,
1538 CodeAssemblerVariable::ImplComparator>
1544 bool is_used()
const {
return plain_label_.is_used(); }
1547 CodeAssemblerLabel::Type
type)
1548 : state_(assembler->state()),
1550 plain_label_(assembler,
type) {}
1554 void AddInputs(std::vector<Node*> inputs);
1555 Node* CreatePhi(MachineRepresentation rep,
const std::vector<Node*>& inputs);
1556 const std::vector<Node*>& CreatePhis(
1557 std::vector<MachineRepresentation> representations);
1561 std::vector<std::vector<Node*>> phi_inputs_;
1562 std::vector<Node*> phi_nodes_;
1566 template <
class... Types>
1570 static constexpr
size_t kArity =
sizeof...(Types);
1572 CodeAssemblerLabel::Type
type)
1576 friend class CodeAssembler;
1579 CodeAssemblerParameterizedLabelBase::AddInputs(
1580 std::vector<Node*>{inputs...});
1582 void CreatePhis(TNode<Types>*... results) {
1583 const std::vector<Node*>& phi_nodes =
1584 CodeAssemblerParameterizedLabelBase::CreatePhis(
1585 {MachineRepresentationOf<Types>::value...});
1586 auto it = phi_nodes.begin();
1588 ITERATE_PACK(AssignPhi(results, *(it++)));
1591 static void AssignPhi(TNode<T>* result, Node* phi) {
1592 if (phi !=
nullptr) *result = TNode<T>::UncheckedCast(phi);
1596 typedef CodeAssemblerParameterizedLabel<Object>
1597 CodeAssemblerExceptionHandlerLabel;
1606 const char* name, PoisoningMitigationLevel poisoning_level,
1608 int32_t builtin_index = Builtins::kNoBuiltinId);
1612 Code::Kind kind,
const char* name,
1613 PoisoningMitigationLevel poisoning_level,
1614 int32_t builtin_index = Builtins::kNoBuiltinId);
1618 const char* name()
const {
return name_; }
1619 int parameter_count()
const;
1622 void PrintCurrentBlock(std::ostream& os);
1625 void SetInitialDebugInformation(
const char* msg,
const char* file,
int line);
1631 friend class CodeAssemblerTester;
1637 const char* name, PoisoningMitigationLevel poisoning_level,
1638 uint32_t stub_key, int32_t builtin_index);
1641 void PopExceptionHandler();
1643 std::unique_ptr<RawMachineAssembler> raw_assembler_;
1647 int32_t builtin_index_;
1648 bool code_generated_;
1651 CodeAssemblerCallback call_prologue_;
1652 CodeAssemblerCallback call_epilogue_;
1653 std::vector<CodeAssemblerExceptionHandlerLabel*> exception_handler_labels_;
1656 VariableId NextVariableId() {
return next_variable_id_++; }
1678 std::unique_ptr<CodeAssemblerExceptionHandlerLabel> label_;
1686 #endif // V8_COMPILER_CODE_ASSEMBLER_H_