[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:
parent
475f194b07
commit
afd83c074f
1
BUILD.gn
1
BUILD.gn
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -18,9 +18,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
template <typename T>
|
||||
using TNode = compiler::TNode<T>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Stack checks.
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
@ -11,8 +11,6 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
using compiler::Node;
|
||||
template <typename T>
|
||||
using TNode = compiler::TNode<T>;
|
||||
|
||||
class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler {
|
||||
public:
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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()) {
|
||||
|
@ -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
372
src/codegen/tnode.h
Normal 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_
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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) {}
|
||||
|
@ -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,
|
||||
|
@ -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 };
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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, \
|
||||
|
@ -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
|
||||
|
@ -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()) << "}";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -18,8 +18,6 @@ namespace internal {
|
||||
using compiler::CodeAssemblerTester;
|
||||
using compiler::FunctionTester;
|
||||
using compiler::Node;
|
||||
template <typename T>
|
||||
using TNode = compiler::TNode<T>;
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
using ::testing::_;
|
||||
using v8::internal::compiler::Node;
|
||||
using v8::internal::compiler::TNode;
|
||||
|
||||
namespace c = v8::internal::compiler;
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
using ::testing::_;
|
||||
using ::testing::Eq;
|
||||
using v8::internal::compiler::Node;
|
||||
using v8::internal::compiler::TNode;
|
||||
|
||||
namespace c = v8::internal::compiler;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user