[csa] move TNode to separate header

This enables using TNode types without including code-assembler.h,
which is useful when generating CallInterfaceDescriptors.

As a drive-by, this moves TNode from v8::internal::compiler to
v8::internal. It's only used outside of the compiler anyway.

Change-Id: I3d938c22366a3570315041683094f77b0d1096a2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1798425
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Michael Stanton <mvstanton@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63721}
This commit is contained in:
Tobias Tebbi 2019-09-12 16:05:12 +02:00 committed by Commit Bot
parent 475f194b07
commit afd83c074f
35 changed files with 526 additions and 593 deletions

View File

@ -2145,6 +2145,7 @@ v8_source_set("v8_base_without_compiler") {
"src/codegen/string-constants.h",
"src/codegen/tick-counter.cc",
"src/codegen/tick-counter.h",
"src/codegen/tnode.h",
"src/codegen/turbo-assembler.cc",
"src/codegen/turbo-assembler.h",
"src/codegen/unoptimized-compilation-info.cc",

View File

@ -17,9 +17,6 @@
namespace v8 {
namespace internal {
template <typename T>
using TNode = compiler::TNode<T>;
void Builtins::Generate_CallFunction_ReceiverIsNullOrUndefined(
MacroAssembler* masm) {
Generate_CallFunction(masm, ConvertReceiverMode::kNullOrUndefined);

View File

@ -19,8 +19,6 @@ namespace internal {
using compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
template <class T>
using TVariable = compiler::TypedCodeAssemblerVariable<T>;
class BaseCollectionsAssembler : public CodeStubAssembler {

View File

@ -11,13 +11,13 @@ namespace v8 {
namespace internal {
void BranchIfIterableWithOriginalKeyOrValueMapIterator(
compiler::CodeAssemblerState* state, compiler::TNode<Object> iterable,
compiler::TNode<Context> context, compiler::CodeAssemblerLabel* if_true,
compiler::CodeAssemblerState* state, TNode<Object> iterable,
TNode<Context> context, compiler::CodeAssemblerLabel* if_true,
compiler::CodeAssemblerLabel* if_false);
void BranchIfIterableWithOriginalValueSetIterator(
compiler::CodeAssemblerState* state, compiler::TNode<Object> iterable,
compiler::TNode<Context> context, compiler::CodeAssemblerLabel* if_true,
compiler::CodeAssemblerState* state, TNode<Object> iterable,
TNode<Context> context, compiler::CodeAssemblerLabel* if_true,
compiler::CodeAssemblerLabel* if_false);
} // namespace internal

View File

@ -19,9 +19,6 @@
namespace v8 {
namespace internal {
template <typename T>
using TNode = compiler::TNode<T>;
void Builtins::Generate_ConstructVarargs(MacroAssembler* masm) {
Generate_CallOrConstructVarargs(masm,
BUILTIN_CODE(masm->isolate(), Construct));
@ -164,7 +161,7 @@ TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
TailCallRuntime(Runtime::kNewObject, context, target, new_target);
}
compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject(
TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject(
SloppyTNode<Context> context, SloppyTNode<JSFunction> target,
SloppyTNode<JSReceiver> new_target) {
TVARIABLE(JSObject, var_obj);
@ -181,7 +178,7 @@ compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject(
return var_obj.value();
}
compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject(
TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject(
SloppyTNode<Context> context, SloppyTNode<JSFunction> target,
SloppyTNode<JSReceiver> new_target, Label* call_runtime) {
// Verify that the new target is a JSFunction.

View File

@ -18,9 +18,6 @@
namespace v8 {
namespace internal {
template <typename T>
using TNode = compiler::TNode<T>;
// -----------------------------------------------------------------------------
// Stack checks.

View File

@ -17,9 +17,6 @@
namespace v8 {
namespace internal {
template <class T>
using TNode = compiler::TNode<T>;
class IntlBuiltinsAssembler : public CodeStubAssembler {
public:
explicit IntlBuiltinsAssembler(compiler::CodeAssemblerState* state)

View File

@ -14,9 +14,6 @@
namespace v8 {
namespace internal {
template <typename T>
using TNode = compiler::TNode<T>;
class MicrotaskQueueBuiltinsAssembler : public CodeStubAssembler {
public:
explicit MicrotaskQueueBuiltinsAssembler(compiler::CodeAssemblerState* state)

View File

@ -23,8 +23,6 @@ namespace internal {
// ES6 section 19.1 Object Objects
using Node = compiler::Node;
template <class T>
using TNode = CodeStubAssembler::TNode<T>;
class ObjectBuiltinsAssembler : public CodeStubAssembler {
public:

View File

@ -21,8 +21,6 @@ namespace v8 {
namespace internal {
using Node = compiler::Node;
template <class T>
using TNode = CodeStubAssembler::TNode<T>;
using IteratorRecord = TorqueStructIteratorRecord;
Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) {

View File

@ -14,7 +14,7 @@
namespace v8 {
namespace internal {
compiler::TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy(
TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy(
TNode<Context> context, TNode<JSReceiver> target,
TNode<JSReceiver> handler) {
VARIABLE(map, MachineRepresentation::kTagged);
@ -124,9 +124,8 @@ Node* ProxiesCodeStubAssembler::CreateProxyRevokeFunctionContext(
return context;
}
compiler::TNode<JSFunction>
ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(TNode<Context> context,
TNode<JSProxy> proxy) {
TNode<JSFunction> ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(
TNode<Context> context, TNode<JSProxy> proxy) {
TNode<NativeContext> const native_context = LoadNativeContext(context);
Node* const proxy_context =

View File

@ -23,8 +23,6 @@ namespace v8 {
namespace internal {
using compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
// Tail calls the regular expression interpreter.
// static

View File

@ -11,8 +11,6 @@ namespace v8 {
namespace internal {
using compiler::Node;
template <typename T>
using TNode = compiler::TNode<T>;
class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler {
public:

View File

@ -17,8 +17,6 @@ namespace v8 {
namespace internal {
using Node = compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
Node* StringBuiltinsAssembler::DirectStringData(Node* string,
Node* string_instance_type) {

View File

@ -15,8 +15,6 @@ namespace v8 {
namespace internal {
using compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
// -----------------------------------------------------------------------------
// ES6 section 22.2 TypedArray Objects

View File

@ -10,8 +10,6 @@
namespace v8 {
namespace internal {
template <class T>
using TNode = compiler::TNode<T>;
// Utility class implementing a growable fixed array through CSA.
class GrowableFixedArray : public CodeStubAssembler {

View File

@ -26,10 +26,6 @@ namespace v8 {
namespace internal {
using compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
template <class T>
using SloppyTNode = compiler::SloppyTNode<T>;
CodeStubAssembler::CodeStubAssembler(compiler::CodeAssemblerState* state)
: compiler::CodeAssembler(state),
@ -353,7 +349,7 @@ TNode<Object> CodeStubAssembler::NoContextConstant() {
}
#define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \
compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \
TNode<std::remove_pointer<std::remove_reference<decltype( \
std::declval<Heap>().rootAccessorName())>::type>::type> \
CodeStubAssembler::name##Constant() { \
return UncheckedCast<std::remove_pointer<std::remove_reference<decltype( \
@ -364,7 +360,7 @@ HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
#undef HEAP_CONSTANT_ACCESSOR
#define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \
compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \
TNode<std::remove_pointer<std::remove_reference<decltype( \
std::declval<ReadOnlyRoots>().rootAccessorName())>::type>::type> \
CodeStubAssembler::name##Constant() { \
return UncheckedCast<std::remove_pointer<std::remove_reference<decltype( \
@ -374,14 +370,12 @@ HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
#undef HEAP_CONSTANT_ACCESSOR
#define HEAP_CONSTANT_TEST(rootIndexName, rootAccessorName, name) \
compiler::TNode<BoolT> CodeStubAssembler::Is##name( \
SloppyTNode<Object> value) { \
return TaggedEqual(value, name##Constant()); \
} \
compiler::TNode<BoolT> CodeStubAssembler::IsNot##name( \
SloppyTNode<Object> value) { \
return TaggedNotEqual(value, name##Constant()); \
#define HEAP_CONSTANT_TEST(rootIndexName, rootAccessorName, name) \
TNode<BoolT> CodeStubAssembler::Is##name(SloppyTNode<Object> value) { \
return TaggedEqual(value, name##Constant()); \
} \
TNode<BoolT> CodeStubAssembler::IsNot##name(SloppyTNode<Object> value) { \
return TaggedNotEqual(value, name##Constant()); \
}
HEAP_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_TEST)
#undef HEAP_CONSTANT_TEST
@ -2376,8 +2370,7 @@ TNode<BigInt> CodeStubAssembler::BigIntFromInt64(TNode<IntPtrT> value) {
return var_result.value();
}
compiler::TNode<BigInt>
CodeStubAssembler::LoadFixedBigUint64ArrayElementAsTagged(
TNode<BigInt> CodeStubAssembler::LoadFixedBigUint64ArrayElementAsTagged(
SloppyTNode<RawPtrT> data_pointer, SloppyTNode<IntPtrT> offset) {
Label if_zero(this), done(this);
if (Is64()) {

View File

@ -157,11 +157,11 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V)
#ifdef DEBUG
#define CSA_CHECK(csa, x) \
(csa)->Check( \
[&]() -> compiler::Node* { \
return implicit_cast<compiler::SloppyTNode<Word32T>>(x); \
}, \
#define CSA_CHECK(csa, x) \
(csa)->Check( \
[&]() -> compiler::Node* { \
return implicit_cast<SloppyTNode<Word32T>>(x); \
}, \
#x, __FILE__, __LINE__)
#else
#define CSA_CHECK(csa, x) (csa)->FastCheck(x)
@ -255,10 +255,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
public TorqueGeneratedExportedMacrosAssembler {
public:
using Node = compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
template <class T>
using SloppyTNode = compiler::SloppyTNode<T>;
template <typename T>
using LazyNode = std::function<TNode<T>()>;
@ -513,14 +509,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Object> NoContextConstant();
#define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \
compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \
TNode<std::remove_pointer<std::remove_reference<decltype( \
std::declval<ReadOnlyRoots>().rootAccessorName())>::type>::type> \
name##Constant();
HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
#undef HEAP_CONSTANT_ACCESSOR
#define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \
compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \
TNode<std::remove_pointer<std::remove_reference<decltype( \
std::declval<Heap>().rootAccessorName())>::type>::type> \
name##Constant();
HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR)
@ -3819,10 +3815,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
class V8_EXPORT_PRIVATE CodeStubArguments {
public:
using Node = compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
template <class T>
using SloppyTNode = compiler::SloppyTNode<T>;
enum ReceiverMode { kHasReceiver, kNoReceiver };
// |argc| is an intptr value which specifies the number of arguments passed

372
src/codegen/tnode.h Normal file
View File

@ -0,0 +1,372 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_CODEGEN_TNODE_H_
#define V8_CODEGEN_TNODE_H_
#include "src/codegen/machine-type.h"
namespace v8 {
namespace internal {
class HeapNumber;
class BigInt;
class Object;
namespace compiler {
class Node;
}
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 <>
struct MachineRepresentationOf<ExternalReference> {
static const MachineRepresentation value = RawPtrT::kMachineRepresentation;
};
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 AnyTaggedT = UnionT<Object, MaybeObject>;
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_;
};
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) {}
};
} // namespace internal
} // namespace v8
#endif // V8_CODEGEN_TNODE_H_

View File

@ -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,216 +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 <>
struct MachineRepresentationOf<ExternalReference> {
static const MachineRepresentation value = RawPtrT::kMachineRepresentation;
};
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 AnyTaggedT = UnionT<Object, MaybeObject>;
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 {
@ -402,143 +193,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;

View File

@ -25,10 +25,6 @@ namespace internal {
using compiler::CodeAssemblerState;
using compiler::Node;
template <typename T>
using TNode = compiler::TNode<T>;
template <typename T>
using SloppyTNode = compiler::SloppyTNode<T>;
//////////////////// Private helpers.

View File

@ -20,10 +20,6 @@ class ExitPoint;
class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler {
public:
using Node = compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
template <class T>
using SloppyTNode = compiler::SloppyTNode<T>;
explicit AccessorAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}

View File

@ -9,9 +9,6 @@
namespace v8 {
namespace internal {
template <typename T>
using TNode = compiler::TNode<T>;
TNode<Object> BinaryOpAssembler::Generate_AddWithFeedback(
TNode<Context> context, TNode<Object> lhs, TNode<Object> rhs,
TNode<UintPtrT> slot_id, TNode<HeapObject> maybe_feedback_vector,

View File

@ -17,8 +17,6 @@ namespace v8 {
namespace internal {
using Node = compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
enum class StoreMode { kOrdinary, kInLiteral };

View File

@ -13,9 +13,6 @@ namespace internal {
class KeyedStoreGenericGenerator {
public:
template <class T>
using TNode = compiler::TNode<T>;
static void Generate(compiler::CodeAssemblerState* state);
// Building block for fast path of Object.assign implementation.

View File

@ -22,8 +22,6 @@ namespace interpreter {
using compiler::CodeAssemblerState;
using compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
InterpreterAssembler::InterpreterAssembler(CodeAssemblerState* state,
Bytecode bytecode,

View File

@ -25,64 +25,62 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// Returns the 32-bit unsigned count immediate for bytecode operand
// |operand_index| in the current bytecode.
compiler::TNode<Uint32T> BytecodeOperandCount(int operand_index);
TNode<Uint32T> BytecodeOperandCount(int operand_index);
// Returns the 32-bit unsigned flag for bytecode operand |operand_index|
// in the current bytecode.
compiler::TNode<Uint32T> BytecodeOperandFlag(int operand_index);
TNode<Uint32T> BytecodeOperandFlag(int operand_index);
// Returns the 32-bit zero-extended index immediate for bytecode operand
// |operand_index| in the current bytecode.
compiler::TNode<Uint32T> BytecodeOperandIdxInt32(int operand_index);
TNode<Uint32T> BytecodeOperandIdxInt32(int operand_index);
// Returns the word zero-extended index immediate for bytecode operand
// |operand_index| in the current bytecode.
compiler::TNode<UintPtrT> BytecodeOperandIdx(int operand_index);
TNode<UintPtrT> BytecodeOperandIdx(int operand_index);
// Returns the smi index immediate for bytecode operand |operand_index|
// in the current bytecode.
compiler::TNode<Smi> BytecodeOperandIdxSmi(int operand_index);
TNode<Smi> BytecodeOperandIdxSmi(int operand_index);
// Returns the 32-bit unsigned immediate for bytecode operand |operand_index|
// in the current bytecode.
compiler::TNode<Uint32T> BytecodeOperandUImm(int operand_index);
TNode<Uint32T> BytecodeOperandUImm(int operand_index);
// Returns the word-size unsigned immediate for bytecode operand
// |operand_index| in the current bytecode.
compiler::TNode<UintPtrT> BytecodeOperandUImmWord(int operand_index);
TNode<UintPtrT> BytecodeOperandUImmWord(int operand_index);
// Returns the unsigned smi immediate for bytecode operand |operand_index| in
// the current bytecode.
compiler::TNode<Smi> BytecodeOperandUImmSmi(int operand_index);
TNode<Smi> BytecodeOperandUImmSmi(int operand_index);
// Returns the 32-bit signed immediate for bytecode operand |operand_index|
// in the current bytecode.
compiler::TNode<Int32T> BytecodeOperandImm(int operand_index);
TNode<Int32T> BytecodeOperandImm(int operand_index);
// Returns the word-size signed immediate for bytecode operand |operand_index|
// in the current bytecode.
compiler::TNode<IntPtrT> BytecodeOperandImmIntPtr(int operand_index);
TNode<IntPtrT> BytecodeOperandImmIntPtr(int operand_index);
// Returns the smi immediate for bytecode operand |operand_index| in the
// current bytecode.
compiler::TNode<Smi> BytecodeOperandImmSmi(int operand_index);
TNode<Smi> BytecodeOperandImmSmi(int operand_index);
// Returns the 32-bit unsigned runtime id immediate for bytecode operand
// |operand_index| in the current bytecode.
compiler::TNode<Uint32T> BytecodeOperandRuntimeId(int operand_index);
TNode<Uint32T> BytecodeOperandRuntimeId(int operand_index);
// Returns the word zero-extended native context index immediate for bytecode
// operand |operand_index| in the current bytecode.
compiler::TNode<UintPtrT> BytecodeOperandNativeContextIndex(
int operand_index);
TNode<UintPtrT> BytecodeOperandNativeContextIndex(int operand_index);
// Returns the 32-bit unsigned intrinsic id immediate for bytecode operand
// |operand_index| in the current bytecode.
compiler::TNode<Uint32T> BytecodeOperandIntrinsicId(int operand_index);
TNode<Uint32T> BytecodeOperandIntrinsicId(int operand_index);
// Accumulator.
compiler::TNode<Object> GetAccumulator();
TNode<Object> GetAccumulator();
void SetAccumulator(SloppyTNode<Object> value);
// Context.
compiler::TNode<Context> GetContext();
void SetContext(compiler::TNode<Context> value);
TNode<Context> GetContext();
void SetContext(TNode<Context> value);
// Context at |depth| in the context chain starting at |context|.
compiler::TNode<Context> GetContextAtDepth(compiler::TNode<Context> context,
compiler::TNode<Uint32T> depth);
TNode<Context> GetContextAtDepth(TNode<Context> context,
TNode<Uint32T> depth);
// Goto the given |target| if the context chain starting at |context| has any
// extensions up to the given |depth|.
void GotoIfHasContextExtensionUpToDepth(compiler::TNode<Context> context,
compiler::TNode<Uint32T> depth,
Label* target);
void GotoIfHasContextExtensionUpToDepth(TNode<Context> context,
TNode<Uint32T> depth, Label* target);
// A RegListNodePair provides an abstraction over lists of registers.
class RegListNodePair {
@ -90,14 +88,12 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
RegListNodePair(TNode<IntPtrT> base_reg_location, TNode<Word32T> reg_count)
: base_reg_location_(base_reg_location), reg_count_(reg_count) {}
compiler::TNode<Word32T> reg_count() const { return reg_count_; }
compiler::TNode<IntPtrT> base_reg_location() const {
return base_reg_location_;
}
TNode<Word32T> reg_count() const { return reg_count_; }
TNode<IntPtrT> base_reg_location() const { return base_reg_location_; }
private:
compiler::TNode<IntPtrT> base_reg_location_;
compiler::TNode<Word32T> reg_count_;
TNode<IntPtrT> base_reg_location_;
TNode<Word32T> reg_count_;
};
// Backup/restore register file to/from a fixed array of the correct length.
@ -105,28 +101,26 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// - Suspend copies arguments and registers to the generator.
// - Resume copies only the registers from the generator, the arguments
// are copied by the ResumeGenerator trampoline.
compiler::TNode<FixedArray> ExportParametersAndRegisterFile(
TNode<FixedArray> array, const RegListNodePair& registers,
TNode<Int32T> formal_parameter_count);
compiler::TNode<FixedArray> ImportRegisterFile(
TNode<FixedArray> ExportParametersAndRegisterFile(
TNode<FixedArray> array, const RegListNodePair& registers,
TNode<Int32T> formal_parameter_count);
TNode<FixedArray> ImportRegisterFile(TNode<FixedArray> array,
const RegListNodePair& registers,
TNode<Int32T> formal_parameter_count);
// Loads from and stores to the interpreter register file.
compiler::TNode<Object> LoadRegister(Register reg);
compiler::TNode<IntPtrT> LoadAndUntagRegister(Register reg);
compiler::TNode<Object> LoadRegisterAtOperandIndex(int operand_index);
std::pair<compiler::TNode<Object>, compiler::TNode<Object>>
LoadRegisterPairAtOperandIndex(int operand_index);
void StoreRegister(compiler::TNode<Object> value, Register reg);
void StoreRegisterAtOperandIndex(compiler::TNode<Object> value,
int operand_index);
void StoreRegisterPairAtOperandIndex(compiler::TNode<Object> value1,
compiler::TNode<Object> value2,
int operand_index);
void StoreRegisterTripleAtOperandIndex(compiler::TNode<Object> value1,
compiler::TNode<Object> value2,
compiler::TNode<Object> value3,
TNode<Object> LoadRegister(Register reg);
TNode<IntPtrT> LoadAndUntagRegister(Register reg);
TNode<Object> LoadRegisterAtOperandIndex(int operand_index);
std::pair<TNode<Object>, TNode<Object>> LoadRegisterPairAtOperandIndex(
int operand_index);
void StoreRegister(TNode<Object> value, Register reg);
void StoreRegisterAtOperandIndex(TNode<Object> value, int operand_index);
void StoreRegisterPairAtOperandIndex(TNode<Object> value1,
TNode<Object> value2, int operand_index);
void StoreRegisterTripleAtOperandIndex(TNode<Object> value1,
TNode<Object> value2,
TNode<Object> value3,
int operand_index);
RegListNodePair GetRegisterListAtOperandIndex(int operand_index);
@ -137,25 +131,23 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// Load constant at the index specified in operand |operand_index| from the
// constant pool.
compiler::TNode<Object> LoadConstantPoolEntryAtOperandIndex(
int operand_index);
TNode<Object> LoadConstantPoolEntryAtOperandIndex(int operand_index);
// Load and untag constant at the index specified in operand |operand_index|
// from the constant pool.
TNode<IntPtrT> LoadAndUntagConstantPoolEntryAtOperandIndex(int operand_index);
// Load constant at |index| in the constant pool.
compiler::TNode<Object> LoadConstantPoolEntry(compiler::TNode<WordT> index);
TNode<Object> LoadConstantPoolEntry(TNode<WordT> index);
// Load and untag constant at |index| in the constant pool.
TNode<IntPtrT> LoadAndUntagConstantPoolEntry(compiler::TNode<WordT> index);
TNode<IntPtrT> LoadAndUntagConstantPoolEntry(TNode<WordT> index);
// Load the FeedbackVector for the current function. The retuned node could be
// undefined.
compiler::TNode<HeapObject> LoadFeedbackVector();
TNode<HeapObject> LoadFeedbackVector();
// Call JSFunction or Callable |function| with |args| arguments, possibly
// including the receiver depending on |receiver_mode|. After the call returns
// directly dispatches to the next bytecode.
void CallJSAndDispatch(compiler::TNode<Object> function,
compiler::TNode<Context> context,
void CallJSAndDispatch(TNode<Object> function, TNode<Context> context,
const RegListNodePair& args,
ConvertReceiverMode receiver_mode);
@ -164,69 +156,66 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// depending on |receiver_mode|. After the call returns directly dispatches to
// the next bytecode.
template <class... TArgs>
void CallJSAndDispatch(compiler::TNode<Object> function,
TNode<Context> context, TNode<Word32T> arg_count,
void CallJSAndDispatch(TNode<Object> function, TNode<Context> context,
TNode<Word32T> arg_count,
ConvertReceiverMode receiver_mode, TArgs... args);
// Call JSFunction or Callable |function| with |args|
// arguments (not including receiver), and the final argument being spread.
// After the call returns directly dispatches to the next bytecode.
void CallJSWithSpreadAndDispatch(compiler::TNode<Object> function,
compiler::TNode<Context> context,
void CallJSWithSpreadAndDispatch(TNode<Object> function,
TNode<Context> context,
const RegListNodePair& args,
compiler::TNode<UintPtrT> slot_id,
TNode<UintPtrT> slot_id,
TNode<HeapObject> maybe_feedback_vector);
// Call constructor |target| with |args| arguments (not including receiver).
// The |new_target| is the same as the |target| for the new keyword, but
// differs for the super keyword.
compiler::TNode<Object> Construct(compiler::TNode<Object> target,
compiler::TNode<Context> context,
compiler::TNode<Object> new_target,
const RegListNodePair& args,
compiler::TNode<UintPtrT> slot_id,
TNode<HeapObject> maybe_feedback_vector);
TNode<Object> Construct(TNode<Object> target, TNode<Context> context,
TNode<Object> new_target, const RegListNodePair& args,
TNode<UintPtrT> slot_id,
TNode<HeapObject> maybe_feedback_vector);
// Call constructor |target| with |args| arguments (not including
// receiver). The last argument is always a spread. The |new_target| is the
// same as the |target| for the new keyword, but differs for the super
// keyword.
compiler::TNode<Object> ConstructWithSpread(
compiler::TNode<Object> target, compiler::TNode<Context> context,
compiler::TNode<Object> new_target, const RegListNodePair& args,
compiler::TNode<UintPtrT> slot_id,
TNode<HeapObject> maybe_feedback_vector);
TNode<Object> ConstructWithSpread(TNode<Object> target,
TNode<Context> context,
TNode<Object> new_target,
const RegListNodePair& args,
TNode<UintPtrT> slot_id,
TNode<HeapObject> maybe_feedback_vector);
// Call runtime function with |args| arguments which will return |return_size|
// number of values.
compiler::Node* CallRuntimeN(compiler::TNode<Uint32T> function_id,
compiler::TNode<Context> context,
compiler::Node* CallRuntimeN(TNode<Uint32T> function_id,
TNode<Context> context,
const RegListNodePair& args,
int return_size = 1);
// Jump forward relative to the current bytecode by the |jump_offset|.
void Jump(compiler::TNode<IntPtrT> jump_offset);
void Jump(TNode<IntPtrT> jump_offset);
// Jump backward relative to the current bytecode by the |jump_offset|.
void JumpBackward(compiler::TNode<IntPtrT> jump_offset);
void JumpBackward(TNode<IntPtrT> jump_offset);
// Jump forward relative to the current bytecode by |jump_offset| if the
// word values |lhs| and |rhs| are equal.
void JumpIfTaggedEqual(compiler::TNode<Object> lhs,
compiler::TNode<Object> rhs,
compiler::TNode<IntPtrT> jump_offset);
void JumpIfTaggedEqual(TNode<Object> lhs, TNode<Object> rhs,
TNode<IntPtrT> jump_offset);
// Jump forward relative to the current bytecode by |jump_offset| if the
// word values |lhs| and |rhs| are not equal.
void JumpIfTaggedNotEqual(compiler::TNode<Object> lhs,
compiler::TNode<Object> rhs,
compiler::TNode<IntPtrT> jump_offset);
void JumpIfTaggedNotEqual(TNode<Object> lhs, TNode<Object> rhs,
TNode<IntPtrT> jump_offset);
// Updates the profiler interrupt budget for a return.
void UpdateInterruptBudgetOnReturn();
// Returns the OSR nesting level from the bytecode header.
compiler::TNode<Int8T> LoadOsrNestingLevel();
TNode<Int8T> LoadOsrNestingLevel();
// Dispatch to the bytecode.
void Dispatch();
@ -236,22 +225,20 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// Dispatch to |target_bytecode| at |new_bytecode_offset|.
// |target_bytecode| should be equivalent to loading from the offset.
void DispatchToBytecode(compiler::TNode<WordT> target_bytecode,
compiler::TNode<IntPtrT> new_bytecode_offset);
void DispatchToBytecode(TNode<WordT> target_bytecode,
TNode<IntPtrT> new_bytecode_offset);
// Abort with the given abort reason.
void Abort(AbortReason abort_reason);
void AbortIfWordNotEqual(compiler::TNode<WordT> lhs,
compiler::TNode<WordT> rhs,
void AbortIfWordNotEqual(TNode<WordT> lhs, TNode<WordT> rhs,
AbortReason abort_reason);
// Abort if |register_count| is invalid for given register file array.
void AbortIfRegisterCountInvalid(
compiler::TNode<FixedArrayBase> parameters_and_registers,
compiler::TNode<IntPtrT> formal_parameter_count,
compiler::TNode<UintPtrT> register_count);
TNode<FixedArrayBase> parameters_and_registers,
TNode<IntPtrT> formal_parameter_count, TNode<UintPtrT> register_count);
// Dispatch to frame dropper trampoline if necessary.
void MaybeDropFrames(compiler::TNode<Context> context);
void MaybeDropFrames(TNode<Context> context);
// Returns the offset from the BytecodeArrayPointer of the current bytecode.
TNode<IntPtrT> BytecodeOffset();
@ -279,12 +266,11 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
TNode<RawPtrT> GetInterpretedFramePointer();
// Operations on registers.
compiler::TNode<IntPtrT> RegisterLocation(Register reg);
compiler::TNode<IntPtrT> RegisterLocation(compiler::TNode<IntPtrT> reg_index);
compiler::TNode<IntPtrT> NextRegister(compiler::TNode<IntPtrT> reg_index);
compiler::TNode<Object> LoadRegister(compiler::TNode<IntPtrT> reg_index);
void StoreRegister(compiler::TNode<Object> value,
compiler::TNode<IntPtrT> reg_index);
TNode<IntPtrT> RegisterLocation(Register reg);
TNode<IntPtrT> RegisterLocation(TNode<IntPtrT> reg_index);
TNode<IntPtrT> NextRegister(TNode<IntPtrT> reg_index);
TNode<Object> LoadRegister(TNode<IntPtrT> reg_index);
void StoreRegister(TNode<Object> value, TNode<IntPtrT> reg_index);
// Saves and restores interpreter bytecode offset to the interpreter stack
// frame when performing a call.
@ -300,75 +286,74 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// Updates the bytecode array's interrupt budget by a 32-bit unsigned |weight|
// and calls Runtime::kInterrupt if counter reaches zero. If |backward|, then
// the interrupt budget is decremented, otherwise it is incremented.
void UpdateInterruptBudget(compiler::TNode<Int32T> weight, bool backward);
void UpdateInterruptBudget(TNode<Int32T> weight, bool backward);
// Returns the offset of register |index| relative to RegisterFilePointer().
compiler::TNode<IntPtrT> RegisterFrameOffset(compiler::TNode<IntPtrT> index);
TNode<IntPtrT> RegisterFrameOffset(TNode<IntPtrT> index);
// Returns the offset of an operand relative to the current bytecode offset.
compiler::TNode<IntPtrT> OperandOffset(int operand_index);
TNode<IntPtrT> OperandOffset(int operand_index);
// Returns a value built from an sequence of bytes in the bytecode
// array starting at |relative_offset| from the current bytecode.
// The |result_type| determines the size and signedness. of the
// value read. This method should only be used on architectures that
// do not support unaligned memory accesses.
compiler::TNode<Word32T> BytecodeOperandReadUnaligned(
TNode<Word32T> BytecodeOperandReadUnaligned(
int relative_offset, MachineType result_type,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
// Returns zero- or sign-extended to word32 value of the operand.
compiler::TNode<Uint8T> BytecodeOperandUnsignedByte(
TNode<Uint8T> BytecodeOperandUnsignedByte(
int operand_index,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
compiler::TNode<Int8T> BytecodeOperandSignedByte(
TNode<Int8T> BytecodeOperandSignedByte(
int operand_index,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
compiler::TNode<Uint16T> BytecodeOperandUnsignedShort(
TNode<Uint16T> BytecodeOperandUnsignedShort(
int operand_index,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
compiler::TNode<Int16T> BytecodeOperandSignedShort(
TNode<Int16T> BytecodeOperandSignedShort(
int operand_index,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
compiler::TNode<Uint32T> BytecodeOperandUnsignedQuad(
TNode<Uint32T> BytecodeOperandUnsignedQuad(
int operand_index,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
compiler::TNode<Int32T> BytecodeOperandSignedQuad(
TNode<Int32T> BytecodeOperandSignedQuad(
int operand_index,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
// Returns zero- or sign-extended to word32 value of the operand of
// given size.
compiler::TNode<Int32T> BytecodeSignedOperand(
TNode<Int32T> BytecodeSignedOperand(
int operand_index, OperandSize operand_size,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
compiler::TNode<Uint32T> BytecodeUnsignedOperand(
TNode<Uint32T> BytecodeUnsignedOperand(
int operand_index, OperandSize operand_size,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
// Returns the word-size sign-extended register index for bytecode operand
// |operand_index| in the current bytecode. Value is not poisoned on
// speculation since the value loaded from the register is poisoned instead.
compiler::TNode<IntPtrT> BytecodeOperandReg(
TNode<IntPtrT> BytecodeOperandReg(
int operand_index,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
// Returns the word zero-extended index immediate for bytecode operand
// |operand_index| in the current bytecode for use when loading a .
compiler::TNode<UintPtrT> BytecodeOperandConstantPoolIdx(
TNode<UintPtrT> BytecodeOperandConstantPoolIdx(
int operand_index,
LoadSensitivity needs_poisoning = LoadSensitivity::kCritical);
// Jump relative to the current bytecode by the |jump_offset|. If |backward|,
// then jump backward (subtract the offset), otherwise jump forward (add the
// offset). Helper function for Jump and JumpBackward.
void Jump(compiler::TNode<IntPtrT> jump_offset, bool backward);
void Jump(TNode<IntPtrT> jump_offset, bool backward);
// Jump forward relative to the current bytecode by |jump_offset| if the
// |condition| is true. Helper function for JumpIfTaggedEqual and
// JumpIfTaggedNotEqual.
void JumpConditional(compiler::TNode<BoolT> condition,
compiler::TNode<IntPtrT> jump_offset);
void JumpConditional(TNode<BoolT> condition, TNode<IntPtrT> jump_offset);
// Save the bytecode offset to the interpreter frame.
void SaveBytecodeOffset();
@ -385,20 +370,19 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
TNode<IntPtrT> Advance(TNode<IntPtrT> delta, bool backward = false);
// Load the bytecode at |bytecode_offset|.
compiler::TNode<WordT> LoadBytecode(compiler::TNode<IntPtrT> bytecode_offset);
TNode<WordT> LoadBytecode(TNode<IntPtrT> bytecode_offset);
// Look ahead for Star and inline it in a branch. Returns a new target
// bytecode node for dispatch.
compiler::TNode<WordT> StarDispatchLookahead(
compiler::TNode<WordT> target_bytecode);
TNode<WordT> StarDispatchLookahead(TNode<WordT> target_bytecode);
// Build code for Star at the current BytecodeOffset() and Advance() to the
// next dispatch offset.
void InlineStar();
// Dispatch to the bytecode handler with code entry point |handler_entry|.
void DispatchToBytecodeHandlerEntry(compiler::TNode<RawPtrT> handler_entry,
compiler::TNode<IntPtrT> bytecode_offset);
void DispatchToBytecodeHandlerEntry(TNode<RawPtrT> handler_entry,
TNode<IntPtrT> bytecode_offset);
int CurrentBytecodeSize() const;

View File

@ -21,8 +21,6 @@ namespace internal {
namespace interpreter {
using compiler::Node;
template <typename T>
using TNode = compiler::TNode<T>;
class IntrinsicsGenerator {
public:
@ -50,7 +48,7 @@ class IntrinsicsGenerator {
TNode<Object> IntrinsicAsBuiltinCall(
const InterpreterAssembler::RegListNodePair& args, TNode<Context> context,
Builtins::Name name);
void AbortIfArgCountMismatch(int expected, compiler::TNode<Word32T> actual);
void AbortIfArgCountMismatch(int expected, TNode<Word32T> actual);
#define DECLARE_INTRINSIC_HELPER(name, lower_case, count) \
TNode<Object> name(const InterpreterAssembler::RegListNodePair& args, \

View File

@ -16,10 +16,9 @@ class Node;
namespace interpreter {
extern compiler::TNode<Object> GenerateInvokeIntrinsic(
InterpreterAssembler* assembler, compiler::TNode<Uint32T> function_id,
compiler::TNode<Context> context,
const InterpreterAssembler::RegListNodePair& args);
extern TNode<Object> GenerateInvokeIntrinsic(
InterpreterAssembler* assembler, TNode<Uint32T> function_id,
TNode<Context> context, const InterpreterAssembler::RegListNodePair& args);
} // namespace interpreter
} // namespace internal

View File

@ -41,7 +41,7 @@ Stack<std::string> CSAGenerator::EmitBlock(const Block* block) {
Stack<std::string> stack;
for (const Type* t : block->InputTypes()) {
stack.Push(FreshNodeName());
out_ << " compiler::TNode<" << t->GetGeneratedTNodeTypeName() << "> "
out_ << " TNode<" << t->GetGeneratedTNodeTypeName() << "> "
<< stack.Top() << ";\n";
}
out_ << " ca_.Bind(&" << BlockName(block);
@ -119,8 +119,8 @@ void CSAGenerator::EmitInstruction(
for (const Type* lowered : LowerType(type)) {
results.push_back(FreshNodeName());
stack->Push(results.back());
out_ << " compiler::TNode<" << lowered->GetGeneratedTNodeTypeName()
<< "> " << stack->Top() << ";\n";
out_ << " TNode<" << lowered->GetGeneratedTNodeTypeName() << "> "
<< stack->Top() << ";\n";
out_ << " USE(" << stack->Top() << ");\n";
}
out_ << " ";
@ -175,7 +175,7 @@ void CSAGenerator::EmitInstruction(const CallIntrinsicInstruction& instruction,
for (const Type* type : LowerType(return_type)) {
results.push_back(FreshNodeName());
stack->Push(results.back());
out_ << " compiler::TNode<" << type->GetGeneratedTNodeTypeName() << "> "
out_ << " TNode<" << type->GetGeneratedTNodeTypeName() << "> "
<< stack->Top() << ";\n";
out_ << " USE(" << stack->Top() << ");\n";
}
@ -298,7 +298,7 @@ void CSAGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction,
for (const Type* type : LowerType(return_type)) {
results.push_back(FreshNodeName());
stack->Push(results.back());
out_ << " compiler::TNode<" << type->GetGeneratedTNodeTypeName() << "> "
out_ << " TNode<" << type->GetGeneratedTNodeTypeName() << "> "
<< stack->Top() << ";\n";
out_ << " USE(" << stack->Top() << ");\n";
}
@ -350,8 +350,8 @@ void CSAGenerator::EmitInstruction(
for (const Type* type :
LowerType(instruction.macro->signature().return_type)) {
results.push_back(FreshNodeName());
out_ << " compiler::TNode<" << type->GetGeneratedTNodeTypeName()
<< "> " << results.back() << ";\n";
out_ << " TNode<" << type->GetGeneratedTNodeTypeName() << "> "
<< results.back() << ";\n";
out_ << " USE(" << results.back() << ");\n";
}
}
@ -449,9 +449,8 @@ void CSAGenerator::EmitInstruction(const CallBuiltinInstruction& instruction,
} else {
std::string result_name = FreshNodeName();
if (result_types.size() == 1) {
out_ << " compiler::TNode<"
<< result_types[0]->GetGeneratedTNodeTypeName() << "> "
<< result_name << ";\n";
out_ << " TNode<" << result_types[0]->GetGeneratedTNodeTypeName()
<< "> " << result_name << ";\n";
}
std::string catch_name =
PreCallableExceptionPreparation(instruction.catch_block);
@ -499,8 +498,7 @@ void CSAGenerator::EmitInstruction(
stack->Push(FreshNodeName());
std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
out_ << " compiler::TNode<" << generated_type << "> " << stack->Top()
<< " = ";
out_ << " TNode<" << generated_type << "> " << stack->Top() << " = ";
if (generated_type != "Object") out_ << "TORQUE_CAST(";
out_ << "CodeStubAssembler(state_).CallBuiltinPointer(Builtins::"
"CallableFor(ca_."
@ -539,8 +537,7 @@ void CSAGenerator::PostCallableExceptionPreparation(
if (!return_type->IsNever()) {
out_ << " ca_.Goto(&" << catch_name << "_skip);\n";
}
out_ << " compiler::TNode<Object> " << catch_name
<< "_exception_object;\n";
out_ << " TNode<Object> " << catch_name << "_exception_object;\n";
out_ << " ca_.Bind(&" << catch_name << "__label, &" << catch_name
<< "_exception_object);\n";
out_ << " ca_.Goto(&" << block_name;
@ -575,9 +572,8 @@ void CSAGenerator::EmitInstruction(const CallRuntimeInstruction& instruction,
} else {
std::string result_name = FreshNodeName();
if (result_types.size() == 1) {
out_ << " compiler::TNode<"
<< result_types[0]->GetGeneratedTNodeTypeName() << "> "
<< result_name << ";\n";
out_ << " TNode<" << result_types[0]->GetGeneratedTNodeTypeName()
<< "> " << result_name << ";\n";
}
std::string catch_name =
PreCallableExceptionPreparation(instruction.catch_block);
@ -718,10 +714,9 @@ void CSAGenerator::EmitInstruction(
std::string offset_name = FreshNodeName();
stack->Push(offset_name);
out_ << " compiler::TNode<IntPtrT> " << offset_name
<< " = ca_.IntPtrConstant(";
out_ << field.aggregate->GetGeneratedTNodeTypeName() << "::k"
<< CamelifyString(field.name_and_type.name) << "Offset";
out_ << " TNode<IntPtrT> " << offset_name << " = ca_.IntPtrConstant(";
out_ << field.aggregate->GetGeneratedTNodeTypeName() << "::k"
<< CamelifyString(field.name_and_type.name) << "Offset";
out_ << ");\n"
<< " USE(" << stack->Top() << ");\n";
}
@ -772,8 +767,8 @@ void CSAGenerator::EmitCSAValue(VisitResult result,
out << "}";
} else {
DCHECK_EQ(1, result.stack_range().Size());
out << "compiler::TNode<" << result.type()->GetGeneratedTNodeTypeName()
<< ">{" << values.Peek(result.stack_range().begin()) << "}";
out << "TNode<" << result.type()->GetGeneratedTNodeTypeName() << ">{"
<< values.Peek(result.stack_range().begin()) << "}";
}
}

View File

@ -86,7 +86,7 @@ bool Type::IsAbstractName(const std::string& name) const {
std::string Type::GetGeneratedTypeName() const {
std::string result = GetGeneratedTypeNameImpl();
if (result.empty() || result == "compiler::TNode<>") {
if (result.empty() || result == "TNode<>") {
ReportError("Generated type is required for type '", ToString(),
"'. Use 'generates' clause in definition.");
}
@ -382,7 +382,7 @@ std::string ClassType::GetGeneratedTNodeTypeNameImpl() const {
std::string ClassType::GetGeneratedTypeNameImpl() const {
return IsConstexpr() ? GetGeneratedTNodeTypeName()
: "compiler::TNode<" + GetGeneratedTNodeTypeName() + ">";
: "TNode<" + GetGeneratedTNodeTypeName() + ">";
}
std::string ClassType::ToExplicitString() const {

View File

@ -204,8 +204,7 @@ class AbstractType final : public Type {
return "AT" + str;
}
std::string GetGeneratedTypeNameImpl() const override {
return IsConstexpr() ? generated_type_
: "compiler::TNode<" + generated_type_ + ">";
return IsConstexpr() ? generated_type_ : "TNode<" + generated_type_ + ">";
}
std::string GetGeneratedTNodeTypeNameImpl() const override;
bool IsConstexpr() const override {
@ -316,7 +315,7 @@ class V8_EXPORT_PRIVATE UnionType final : public Type {
std::string ToExplicitString() const override;
std::string MangledName() const override;
std::string GetGeneratedTypeNameImpl() const override {
return "compiler::TNode<" + GetGeneratedTNodeTypeName() + ">";
return "TNode<" + GetGeneratedTNodeTypeName() + ">";
}
std::string GetGeneratedTNodeTypeNameImpl() const override;

View File

@ -18,8 +18,6 @@ namespace internal {
using compiler::CodeAssemblerTester;
using compiler::FunctionTester;
using compiler::Node;
template <typename T>
using TNode = compiler::TNode<T>;
namespace {

View File

@ -14,7 +14,6 @@
using ::testing::_;
using v8::internal::compiler::Node;
using v8::internal::compiler::TNode;
namespace c = v8::internal::compiler;

View File

@ -16,7 +16,6 @@
using ::testing::_;
using ::testing::Eq;
using v8::internal::compiler::Node;
using v8::internal::compiler::TNode;
namespace c = v8::internal::compiler;