summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/code-assembler.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/code-assembler.h')
-rw-r--r--deps/v8/src/compiler/code-assembler.h390
1 files changed, 27 insertions, 363 deletions
diff --git a/deps/v8/src/compiler/code-assembler.h b/deps/v8/src/compiler/code-assembler.h
index c9adb1601d..036b00b14d 100644
--- a/deps/v8/src/compiler/code-assembler.h
+++ b/deps/v8/src/compiler/code-assembler.h
@@ -17,6 +17,7 @@
#include "src/codegen/code-factory.h"
#include "src/codegen/machine-type.h"
#include "src/codegen/source-position.h"
+#include "src/codegen/tnode.h"
#include "src/heap/heap.h"
#include "src/objects/arguments.h"
#include "src/objects/data-handler.h"
@@ -79,210 +80,6 @@ TORQUE_STRUCT_LIST_GENERATOR(MAKE_FORWARD_DECLARATION, UNUSED)
template <typename T>
class Signature;
-struct UntaggedT {};
-
-struct IntegralT : UntaggedT {};
-
-struct WordT : IntegralT {
- static const MachineRepresentation kMachineRepresentation =
- (kSystemPointerSize == 4) ? MachineRepresentation::kWord32
- : MachineRepresentation::kWord64;
-};
-
-struct RawPtrT : WordT {
- static constexpr MachineType kMachineType = MachineType::Pointer();
-};
-
-template <class To>
-struct RawPtr : RawPtrT {};
-
-struct Word32T : IntegralT {
- static const MachineRepresentation kMachineRepresentation =
- MachineRepresentation::kWord32;
-};
-struct Int32T : Word32T {
- static constexpr MachineType kMachineType = MachineType::Int32();
-};
-struct Uint32T : Word32T {
- static constexpr MachineType kMachineType = MachineType::Uint32();
-};
-struct Int16T : Int32T {
- static constexpr MachineType kMachineType = MachineType::Int16();
-};
-struct Uint16T : Uint32T, Int32T {
- static constexpr MachineType kMachineType = MachineType::Uint16();
-};
-struct Int8T : Int16T {
- static constexpr MachineType kMachineType = MachineType::Int8();
-};
-struct Uint8T : Uint16T, Int16T {
- static constexpr MachineType kMachineType = MachineType::Uint8();
-};
-
-struct Word64T : IntegralT {
- static const MachineRepresentation kMachineRepresentation =
- MachineRepresentation::kWord64;
-};
-struct Int64T : Word64T {
- static constexpr MachineType kMachineType = MachineType::Int64();
-};
-struct Uint64T : Word64T {
- static constexpr MachineType kMachineType = MachineType::Uint64();
-};
-
-struct IntPtrT : WordT {
- static constexpr MachineType kMachineType = MachineType::IntPtr();
-};
-struct UintPtrT : WordT {
- static constexpr MachineType kMachineType = MachineType::UintPtr();
-};
-
-struct Float32T : UntaggedT {
- static const MachineRepresentation kMachineRepresentation =
- MachineRepresentation::kFloat32;
- static constexpr MachineType kMachineType = MachineType::Float32();
-};
-
-struct Float64T : UntaggedT {
- static const MachineRepresentation kMachineRepresentation =
- MachineRepresentation::kFloat64;
- static constexpr MachineType kMachineType = MachineType::Float64();
-};
-
-#ifdef V8_COMPRESS_POINTERS
-using TaggedT = Int32T;
-#else
-using TaggedT = IntPtrT;
-#endif
-
-// Result of a comparison operation.
-struct BoolT : Word32T {};
-
-// Value type of a Turbofan node with two results.
-template <class T1, class T2>
-struct PairT {};
-
-inline constexpr MachineType CommonMachineType(MachineType type1,
- MachineType type2) {
- return (type1 == type2) ? type1
- : ((type1.IsTagged() && type2.IsTagged())
- ? MachineType::AnyTagged()
- : MachineType::None());
-}
-
-template <class Type, class Enable = void>
-struct MachineTypeOf {
- static constexpr MachineType value = Type::kMachineType;
-};
-
-template <class Type, class Enable>
-constexpr MachineType MachineTypeOf<Type, Enable>::value;
-
-template <>
-struct MachineTypeOf<Object> {
- static constexpr MachineType value = MachineType::AnyTagged();
-};
-template <>
-struct MachineTypeOf<MaybeObject> {
- static constexpr MachineType value = MachineType::AnyTagged();
-};
-template <>
-struct MachineTypeOf<Smi> {
- static constexpr MachineType value = MachineType::TaggedSigned();
-};
-template <class HeapObjectSubtype>
-struct MachineTypeOf<HeapObjectSubtype,
- typename std::enable_if<std::is_base_of<
- HeapObject, HeapObjectSubtype>::value>::type> {
- static constexpr MachineType value = MachineType::TaggedPointer();
-};
-
-template <class HeapObjectSubtype>
-constexpr MachineType MachineTypeOf<
- HeapObjectSubtype, typename std::enable_if<std::is_base_of<
- HeapObject, HeapObjectSubtype>::value>::type>::value;
-
-template <class Type, class Enable = void>
-struct MachineRepresentationOf {
- static const MachineRepresentation value = Type::kMachineRepresentation;
-};
-template <class T>
-struct MachineRepresentationOf<
- T, typename std::enable_if<std::is_base_of<Object, T>::value>::type> {
- static const MachineRepresentation value =
- MachineTypeOf<T>::value.representation();
-};
-template <class T>
-struct MachineRepresentationOf<
- T, typename std::enable_if<std::is_base_of<MaybeObject, T>::value>::type> {
- static const MachineRepresentation value =
- MachineTypeOf<T>::value.representation();
-};
-
-template <class T>
-struct is_valid_type_tag {
- static const bool value = std::is_base_of<Object, T>::value ||
- std::is_base_of<UntaggedT, T>::value ||
- std::is_base_of<MaybeObject, T>::value ||
- std::is_same<ExternalReference, T>::value;
- static const bool is_tagged = std::is_base_of<Object, T>::value ||
- std::is_base_of<MaybeObject, T>::value;
-};
-
-template <class T1, class T2>
-struct is_valid_type_tag<PairT<T1, T2>> {
- static const bool value =
- is_valid_type_tag<T1>::value && is_valid_type_tag<T2>::value;
- static const bool is_tagged = false;
-};
-
-template <class T1, class T2>
-struct UnionT;
-
-template <class T1, class T2>
-struct is_valid_type_tag<UnionT<T1, T2>> {
- static const bool is_tagged =
- is_valid_type_tag<T1>::is_tagged && is_valid_type_tag<T2>::is_tagged;
- static const bool value = is_tagged;
-};
-
-template <class T1, class T2>
-struct UnionT {
- static constexpr MachineType kMachineType =
- CommonMachineType(MachineTypeOf<T1>::value, MachineTypeOf<T2>::value);
- static const MachineRepresentation kMachineRepresentation =
- kMachineType.representation();
- static_assert(kMachineRepresentation != MachineRepresentation::kNone,
- "no common representation");
- static_assert(is_valid_type_tag<T1>::is_tagged &&
- is_valid_type_tag<T2>::is_tagged,
- "union types are only possible for tagged values");
-};
-
-using Number = UnionT<Smi, HeapNumber>;
-using Numeric = UnionT<Number, BigInt>;
-
-// A pointer to a builtin function, used by Torque's function pointers.
-using BuiltinPtr = Smi;
-
-class int31_t {
- public:
- int31_t() : value_(0) {}
- int31_t(int value) : value_(value) { // NOLINT(runtime/explicit)
- DCHECK_EQ((value & 0x80000000) != 0, (value & 0x40000000) != 0);
- }
- int31_t& operator=(int value) {
- DCHECK_EQ((value & 0x80000000) != 0, (value & 0x40000000) != 0);
- value_ = value;
- return *this;
- }
- int32_t value() const { return value_; }
- operator int32_t() const { return value_; }
-
- private:
- int32_t value_;
-};
-
#define ENUM_ELEMENT(Name) k##Name,
#define ENUM_STRUCT_ELEMENT(NAME, Name, name) k##Name,
enum class ObjectType {
@@ -334,6 +131,7 @@ class Undetectable;
class UniqueName;
class WasmCapiFunctionData;
class WasmExceptionObject;
+class WasmExceptionPackage;
class WasmExceptionTag;
class WasmExportedFunctionData;
class WasmGlobalObject;
@@ -396,143 +194,6 @@ using CodeAssemblerVariableList = ZoneVector<CodeAssemblerVariable*>;
using CodeAssemblerCallback = std::function<void()>;
-template <class T, class U>
-struct is_subtype {
- static const bool value = std::is_base_of<U, T>::value;
-};
-template <class T1, class T2, class U>
-struct is_subtype<UnionT<T1, T2>, U> {
- static const bool value =
- is_subtype<T1, U>::value && is_subtype<T2, U>::value;
-};
-template <class T, class U1, class U2>
-struct is_subtype<T, UnionT<U1, U2>> {
- static const bool value =
- is_subtype<T, U1>::value || is_subtype<T, U2>::value;
-};
-template <class T1, class T2, class U1, class U2>
-struct is_subtype<UnionT<T1, T2>, UnionT<U1, U2>> {
- static const bool value =
- (is_subtype<T1, U1>::value || is_subtype<T1, U2>::value) &&
- (is_subtype<T2, U1>::value || is_subtype<T2, U2>::value);
-};
-
-template <class T, class U>
-struct types_have_common_values {
- static const bool value = is_subtype<T, U>::value || is_subtype<U, T>::value;
-};
-template <class U>
-struct types_have_common_values<BoolT, U> {
- static const bool value = types_have_common_values<Word32T, U>::value;
-};
-template <class U>
-struct types_have_common_values<Uint32T, U> {
- static const bool value = types_have_common_values<Word32T, U>::value;
-};
-template <class U>
-struct types_have_common_values<Int32T, U> {
- static const bool value = types_have_common_values<Word32T, U>::value;
-};
-template <class U>
-struct types_have_common_values<Uint64T, U> {
- static const bool value = types_have_common_values<Word64T, U>::value;
-};
-template <class U>
-struct types_have_common_values<Int64T, U> {
- static const bool value = types_have_common_values<Word64T, U>::value;
-};
-template <class U>
-struct types_have_common_values<IntPtrT, U> {
- static const bool value = types_have_common_values<WordT, U>::value;
-};
-template <class U>
-struct types_have_common_values<UintPtrT, U> {
- static const bool value = types_have_common_values<WordT, U>::value;
-};
-template <class T1, class T2, class U>
-struct types_have_common_values<UnionT<T1, T2>, U> {
- static const bool value = types_have_common_values<T1, U>::value ||
- types_have_common_values<T2, U>::value;
-};
-
-template <class T, class U1, class U2>
-struct types_have_common_values<T, UnionT<U1, U2>> {
- static const bool value = types_have_common_values<T, U1>::value ||
- types_have_common_values<T, U2>::value;
-};
-template <class T1, class T2, class U1, class U2>
-struct types_have_common_values<UnionT<T1, T2>, UnionT<U1, U2>> {
- static const bool value = types_have_common_values<T1, U1>::value ||
- types_have_common_values<T1, U2>::value ||
- types_have_common_values<T2, U1>::value ||
- types_have_common_values<T2, U2>::value;
-};
-
-template <class T>
-struct types_have_common_values<T, MaybeObject> {
- static const bool value = types_have_common_values<T, Object>::value;
-};
-
-template <class T>
-struct types_have_common_values<MaybeObject, T> {
- static const bool value = types_have_common_values<Object, T>::value;
-};
-
-// TNode<T> is an SSA value with the static type tag T, which is one of the
-// following:
-// - a subclass of internal::Object represents a tagged type
-// - a subclass of internal::UntaggedT represents an untagged type
-// - ExternalReference
-// - PairT<T1, T2> for an operation returning two values, with types T1
-// and T2
-// - UnionT<T1, T2> represents either a value of type T1 or of type T2.
-template <class T>
-class TNode {
- public:
- template <class U,
- typename std::enable_if<is_subtype<U, T>::value, int>::type = 0>
- TNode(const TNode<U>& other) : node_(other) {
- LazyTemplateChecks();
- }
- TNode() : TNode(nullptr) {}
-
- TNode operator=(TNode other) {
- DCHECK_NOT_NULL(other.node_);
- node_ = other.node_;
- return *this;
- }
-
- operator compiler::Node*() const { return node_; }
-
- static TNode UncheckedCast(compiler::Node* node) { return TNode(node); }
-
- protected:
- explicit TNode(compiler::Node* node) : node_(node) { LazyTemplateChecks(); }
-
- private:
- // These checks shouldn't be checked before TNode is actually used.
- void LazyTemplateChecks() {
- static_assert(is_valid_type_tag<T>::value, "invalid type tag");
- }
-
- compiler::Node* node_;
-};
-
-// SloppyTNode<T> is a variant of TNode<T> and allows implicit casts from
-// Node*. It is intended for function arguments as long as some call sites
-// still use untyped Node* arguments.
-// TODO(tebbi): Delete this class once transition is finished.
-template <class T>
-class SloppyTNode : public TNode<T> {
- public:
- SloppyTNode(compiler::Node* node) // NOLINT(runtime/explicit)
- : TNode<T>(node) {}
- template <class U, typename std::enable_if<is_subtype<U, T>::value,
- int>::type = 0>
- SloppyTNode(const TNode<U>& other) // NOLINT(runtime/explicit)
- : TNode<T>(other) {}
-};
-
template <class... Types>
class CodeAssemblerParameterizedLabel;
@@ -627,7 +288,7 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
V(Float64ExtractLowWord32, Uint32T, Float64T) \
V(Float64ExtractHighWord32, Uint32T, Float64T) \
V(BitcastTaggedToWord, IntPtrT, Object) \
- V(BitcastTaggedSignedToWord, IntPtrT, Smi) \
+ V(BitcastTaggedToWordForTagAndSmiBits, IntPtrT, AnyTaggedT) \
V(BitcastMaybeObjectToWord, IntPtrT, MaybeObject) \
V(BitcastWordToTagged, Object, WordT) \
V(BitcastWordToTaggedSigned, Smi, WordT) \
@@ -641,6 +302,7 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
V(ChangeInt32ToInt64, Int64T, Int32T) \
V(ChangeUint32ToFloat64, Float64T, Word32T) \
V(ChangeUint32ToUint64, Uint64T, Word32T) \
+ V(ChangeTaggedToCompressed, TaggedT, AnyTaggedT) \
V(BitcastInt32ToFloat32, Float32T, Word32T) \
V(BitcastFloat32ToInt32, Uint32T, Float32T) \
V(RoundFloat64ToInt32, Int32T, Float64T) \
@@ -1187,8 +849,12 @@ class V8_EXPORT_PRIVATE CodeAssembler {
TNode<RawPtrT> RawPtrAdd(TNode<RawPtrT> left, TNode<IntPtrT> right) {
return ReinterpretCast<RawPtrT>(IntPtrAdd(left, right));
}
- TNode<RawPtrT> RawPtrAdd(TNode<IntPtrT> left, TNode<RawPtrT> right) {
- return ReinterpretCast<RawPtrT>(IntPtrAdd(left, right));
+ TNode<RawPtrT> RawPtrSub(TNode<RawPtrT> left, TNode<IntPtrT> right) {
+ return ReinterpretCast<RawPtrT>(IntPtrSub(left, right));
+ }
+ TNode<IntPtrT> RawPtrSub(TNode<RawPtrT> left, TNode<RawPtrT> right) {
+ return Signed(
+ IntPtrSub(static_cast<Node*>(left), static_cast<Node*>(right)));
}
TNode<WordT> WordShl(SloppyTNode<WordT> value, int shift);
@@ -1243,7 +909,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
template <class Dummy = void>
TNode<IntPtrT> BitcastTaggedToWord(TNode<Smi> node) {
static_assert(sizeof(Dummy) < 0,
- "Should use BitcastTaggedSignedToWord instead.");
+ "Should use BitcastTaggedToWordForTagAndSmiBits instead.");
}
// Changes a double to an inptr_t for pointer arithmetic outside of Smi range.
@@ -1363,26 +1029,26 @@ class V8_EXPORT_PRIVATE CodeAssembler {
void TailCallStub(Callable const& callable, SloppyTNode<Object> context,
TArgs... args) {
TNode<Code> target = HeapConstant(callable.code());
- return TailCallStub(callable.descriptor(), target, context, args...);
+ TailCallStub(callable.descriptor(), target, context, args...);
}
template <class... TArgs>
void TailCallStub(const CallInterfaceDescriptor& descriptor,
SloppyTNode<Code> target, SloppyTNode<Object> context,
TArgs... args) {
- return TailCallStubImpl(descriptor, target, context, {args...});
+ TailCallStubImpl(descriptor, target, context, {args...});
}
template <class... TArgs>
- Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
- Node* target, TArgs... args);
+ void TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
+ TNode<RawPtrT> target, TArgs... args);
template <class... TArgs>
- Node* TailCallStubThenBytecodeDispatch(
+ void TailCallStubThenBytecodeDispatch(
const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
TArgs... args) {
- return TailCallStubThenBytecodeDispatchImpl(descriptor, target, context,
- {args...});
+ TailCallStubThenBytecodeDispatchImpl(descriptor, target, context,
+ {args...});
}
// Tailcalls to the given code object with JSCall linkage. The JS arguments
@@ -1392,14 +1058,13 @@ class V8_EXPORT_PRIVATE CodeAssembler {
// Note that no arguments adaption is going on here - all the JavaScript
// arguments are left on the stack unmodified. Therefore, this tail call can
// only be used after arguments adaptation has been performed already.
- TNode<Object> TailCallJSCode(TNode<Code> code, TNode<Context> context,
- TNode<JSFunction> function,
- TNode<Object> new_target,
- TNode<Int32T> arg_count);
+ void TailCallJSCode(TNode<Code> code, TNode<Context> context,
+ TNode<JSFunction> function, TNode<Object> new_target,
+ TNode<Int32T> arg_count);
template <class... TArgs>
- Node* CallJS(Callable const& callable, Node* context, Node* function,
- Node* receiver, TArgs... args) {
+ TNode<Object> CallJS(Callable const& callable, Node* context, Node* function,
+ Node* receiver, TArgs... args) {
int argc = static_cast<int>(sizeof...(args));
TNode<Int32T> arity = Int32Constant(argc);
return CallStub(callable, context, function, arity, receiver, args...);
@@ -1511,15 +1176,14 @@ class V8_EXPORT_PRIVATE CodeAssembler {
TNode<Code> target, TNode<Object> context,
std::initializer_list<Node*> args);
- Node* TailCallStubThenBytecodeDispatchImpl(
+ void TailCallStubThenBytecodeDispatchImpl(
const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
std::initializer_list<Node*> args);
Node* CallStubRImpl(StubCallMode call_mode,
const CallInterfaceDescriptor& descriptor,
- size_t result_size, Node* target,
- SloppyTNode<Object> context,
- std::initializer_list<Node*> args);
+ size_t result_size, TNode<Object> target,
+ TNode<Object> context, std::initializer_list<Node*> args);
// These two don't have definitions and are here only for catching use cases
// where the cast is not necessary.
@@ -1810,7 +1474,7 @@ class V8_EXPORT_PRIVATE CodeAssemblerScopedExceptionHandler {
} // namespace compiler
-#if defined(V8_HOST_ARCH_32_BIT) || defined(V8_COMPRESS_POINTERS)
+#if defined(V8_HOST_ARCH_32_BIT)
#define BINT_IS_SMI
using BInt = Smi;
#elif defined(V8_HOST_ARCH_64_BIT)