Avoid massive template instantiation in CodeAssembler
Instead of instantiating each function multiple times, just call out to a common function, passing the variadic number of arguments in an initializer list. R=tebbi@chromium.org Bug: v8:7754 Change-Id: Idb2d77cef7cf8e590de6aa3cea02c0e0773da45f Reviewed-on: https://chromium-review.googlesource.com/1101689 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#53785}
This commit is contained in:
parent
f67e424d7c
commit
38be8e067a
@ -24,23 +24,6 @@
|
|||||||
#include "src/utils.h"
|
#include "src/utils.h"
|
||||||
#include "src/zone/zone.h"
|
#include "src/zone/zone.h"
|
||||||
|
|
||||||
#define REPEAT_0_TO_1(V, T0, T) V(T0) V(T0, T)
|
|
||||||
#define REPEAT_0_TO_2(V, T0, T) REPEAT_0_TO_1(V, T0, T) V(T0, T, T)
|
|
||||||
#define REPEAT_0_TO_3(V, T0, T) REPEAT_0_TO_2(V, T0, T) V(T0, T, T, T)
|
|
||||||
#define REPEAT_0_TO_4(V, T0, T) REPEAT_0_TO_3(V, T0, T) V(T0, T, T, T, T)
|
|
||||||
#define REPEAT_0_TO_5(V, T0, T) REPEAT_0_TO_4(V, T0, T) V(T0, T, T, T, T, T)
|
|
||||||
#define REPEAT_0_TO_6(V, T0, T) REPEAT_0_TO_5(V, T0, T) V(T0, T, T, T, T, T, T)
|
|
||||||
#define REPEAT_0_TO_7(V, T0, T) \
|
|
||||||
REPEAT_0_TO_6(V, T0, T) V(T0, T, T, T, T, T, T, T)
|
|
||||||
#define REPEAT_0_TO_8(V, T0, T) \
|
|
||||||
REPEAT_0_TO_7(V, T0, T) V(T0, T, T, T, T, T, T, T, T)
|
|
||||||
#define REPEAT_0_TO_9(V, T0, T) \
|
|
||||||
REPEAT_0_TO_8(V, T0, T) V(T0, T, T, T, T, T, T, T, T, T)
|
|
||||||
#define REPEAT_0_TO_10(V, T0, T) \
|
|
||||||
REPEAT_0_TO_9(V, T0, T) V(T0, T, T, T, T, T, T, T, T, T, T)
|
|
||||||
#define REPEAT_0_TO_11(V, T0, T) \
|
|
||||||
REPEAT_0_TO_10(V, T0, T) V(T0, T, T, T, T, T, T, T, T, T, T, T)
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@ -1066,11 +1049,30 @@ void CodeAssembler::GotoIfException(Node* node, Label* if_exception,
|
|||||||
Bind(&success);
|
Bind(&success);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... TArgs>
|
namespace {
|
||||||
TNode<Object> CodeAssembler::CallRuntimeImpl(Runtime::FunctionId function,
|
template <size_t kMaxSize>
|
||||||
TNode<Object> context,
|
class NodeArray {
|
||||||
TArgs... args) {
|
public:
|
||||||
int argc = static_cast<int>(sizeof...(args));
|
void Add(Node* node) {
|
||||||
|
DCHECK_GT(kMaxSize, size());
|
||||||
|
*ptr_++ = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* const* data() const { return arr_; }
|
||||||
|
int size() const { return static_cast<int>(ptr_ - arr_); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Node* arr_[kMaxSize];
|
||||||
|
Node** ptr_ = arr_;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TNode<Object> CodeAssembler::CallRuntimeImpl(
|
||||||
|
Runtime::FunctionId function, TNode<Object> context,
|
||||||
|
std::initializer_list<TNode<Object>> args) {
|
||||||
|
constexpr size_t kMaxNumArgs = 6;
|
||||||
|
DCHECK_GE(kMaxNumArgs, args.size());
|
||||||
|
int argc = static_cast<int>(args.size());
|
||||||
auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
|
auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
|
||||||
zone(), function, argc, Operator::kNoProperties,
|
zone(), function, argc, Operator::kNoProperties,
|
||||||
CallDescriptor::kNoFlags);
|
CallDescriptor::kNoFlags);
|
||||||
@ -1081,87 +1083,51 @@ TNode<Object> CodeAssembler::CallRuntimeImpl(Runtime::FunctionId function,
|
|||||||
Node* ref = ExternalConstant(ExternalReference::Create(function));
|
Node* ref = ExternalConstant(ExternalReference::Create(function));
|
||||||
Node* arity = Int32Constant(argc);
|
Node* arity = Int32Constant(argc);
|
||||||
|
|
||||||
Node* nodes[] = {centry, implicit_cast<TNode<Object>>(args)..., ref, arity,
|
NodeArray<kMaxNumArgs + 4> inputs;
|
||||||
context};
|
inputs.Add(centry);
|
||||||
|
for (auto arg : args) inputs.Add(arg);
|
||||||
|
inputs.Add(ref);
|
||||||
|
inputs.Add(arity);
|
||||||
|
inputs.Add(context);
|
||||||
|
|
||||||
CallPrologue();
|
CallPrologue();
|
||||||
Node* return_value =
|
Node* return_value =
|
||||||
raw_assembler()->CallN(call_descriptor, arraysize(nodes), nodes);
|
raw_assembler()->CallN(call_descriptor, inputs.size(), inputs.data());
|
||||||
CallEpilogue();
|
CallEpilogue();
|
||||||
return UncheckedCast<Object>(return_value);
|
return UncheckedCast<Object>(return_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate CallRuntime() for argument counts used by CSA-generated code
|
void CodeAssembler::TailCallRuntimeImpl(
|
||||||
#define INSTANTIATE(...) \
|
Runtime::FunctionId function, TNode<Int32T> arity, TNode<Object> context,
|
||||||
template V8_EXPORT_PRIVATE TNode<Object> CodeAssembler::CallRuntimeImpl( \
|
std::initializer_list<TNode<Object>> args) {
|
||||||
Runtime::FunctionId, __VA_ARGS__);
|
|
||||||
REPEAT_0_TO_6(INSTANTIATE, TNode<Object>, SloppyTNode<Object>)
|
|
||||||
#undef INSTANTIATE
|
|
||||||
|
|
||||||
template <class... TArgs>
|
|
||||||
void CodeAssembler::TailCallRuntimeImpl(Runtime::FunctionId function,
|
|
||||||
TNode<Int32T> arity,
|
|
||||||
TNode<Object> context, TArgs... args) {
|
|
||||||
int result_size = Runtime::FunctionForId(function)->result_size;
|
int result_size = Runtime::FunctionForId(function)->result_size;
|
||||||
TNode<Code> centry =
|
TNode<Code> centry =
|
||||||
HeapConstant(CodeFactory::RuntimeCEntry(isolate(), result_size));
|
HeapConstant(CodeFactory::RuntimeCEntry(isolate(), result_size));
|
||||||
return TailCallRuntimeWithCEntryImpl(function, arity, centry, context,
|
return TailCallRuntimeWithCEntryImpl(function, arity, centry, context, args);
|
||||||
implicit_cast<TNode<Object>>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate TailCallRuntime() for argument counts used by CSA-generated code
|
void CodeAssembler::TailCallRuntimeWithCEntryImpl(
|
||||||
#define INSTANTIATE(...) \
|
Runtime::FunctionId function, TNode<Int32T> arity, TNode<Code> centry,
|
||||||
template V8_EXPORT_PRIVATE void CodeAssembler::TailCallRuntimeImpl( \
|
TNode<Object> context, std::initializer_list<TNode<Object>> args) {
|
||||||
Runtime::FunctionId, TNode<Int32T>, __VA_ARGS__);
|
constexpr size_t kMaxNumArgs = 6;
|
||||||
REPEAT_0_TO_6(INSTANTIATE, TNode<Object>, SloppyTNode<Object>)
|
DCHECK_GE(kMaxNumArgs, args.size());
|
||||||
#undef INSTANTIATE
|
int argc = static_cast<int>(args.size());
|
||||||
|
|
||||||
template <class... TArgs>
|
|
||||||
void CodeAssembler::TailCallRuntimeWithCEntryImpl(Runtime::FunctionId function,
|
|
||||||
TNode<Int32T> arity,
|
|
||||||
TNode<Code> centry,
|
|
||||||
TNode<Object> context,
|
|
||||||
TArgs... args) {
|
|
||||||
int argc = static_cast<int>(sizeof...(args));
|
|
||||||
auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
|
auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
|
||||||
zone(), function, argc, Operator::kNoProperties,
|
zone(), function, argc, Operator::kNoProperties,
|
||||||
CallDescriptor::kNoFlags);
|
CallDescriptor::kNoFlags);
|
||||||
|
|
||||||
Node* ref = ExternalConstant(ExternalReference::Create(function));
|
Node* ref = ExternalConstant(ExternalReference::Create(function));
|
||||||
|
|
||||||
Node* nodes[] = {centry, args..., ref, arity, context};
|
NodeArray<kMaxNumArgs + 4> inputs;
|
||||||
|
inputs.Add(centry);
|
||||||
|
for (auto arg : args) inputs.Add(arg);
|
||||||
|
inputs.Add(ref);
|
||||||
|
inputs.Add(arity);
|
||||||
|
inputs.Add(context);
|
||||||
|
|
||||||
raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes);
|
raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate TailCallRuntimeWithCEntryImpl() for argument counts used by
|
|
||||||
// CSA-generated code.
|
|
||||||
#define INSTANTIATE(...) \
|
|
||||||
template V8_EXPORT_PRIVATE void \
|
|
||||||
CodeAssembler::TailCallRuntimeWithCEntryImpl( \
|
|
||||||
Runtime::FunctionId, TNode<Int32T>, TNode<Code>, __VA_ARGS__);
|
|
||||||
REPEAT_0_TO_6(INSTANTIATE, TNode<Object>, SloppyTNode<Object>)
|
|
||||||
#undef INSTANTIATE
|
|
||||||
|
|
||||||
template <class... TArgs>
|
|
||||||
Node* CodeAssembler::CallStubR(const CallInterfaceDescriptor& descriptor,
|
|
||||||
size_t result_size, SloppyTNode<Code> target,
|
|
||||||
SloppyTNode<Object> context, TArgs... args) {
|
|
||||||
Node* nodes[] = {target, args..., context};
|
|
||||||
int input_count = arraysize(nodes);
|
|
||||||
if (context == nullptr) --input_count;
|
|
||||||
return CallStubN(descriptor, result_size, input_count, nodes,
|
|
||||||
context != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instantiate CallStubR() for argument counts used by CSA-generated code.
|
|
||||||
#define INSTANTIATE(...) \
|
|
||||||
template V8_EXPORT_PRIVATE Node* CodeAssembler::CallStubR( \
|
|
||||||
const CallInterfaceDescriptor& descriptor, size_t, SloppyTNode<Code>, \
|
|
||||||
__VA_ARGS__);
|
|
||||||
REPEAT_0_TO_10(INSTANTIATE, SloppyTNode<Object>, Node*)
|
|
||||||
#undef INSTANTIATE
|
|
||||||
|
|
||||||
Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
|
Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
|
||||||
size_t result_size, int input_count,
|
size_t result_size, int input_count,
|
||||||
Node* const* inputs, bool pass_context) {
|
Node* const* inputs, bool pass_context) {
|
||||||
@ -1186,55 +1152,66 @@ Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
|
|||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... TArgs>
|
|
||||||
void CodeAssembler::TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
|
void CodeAssembler::TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
|
||||||
TNode<Code> target, TNode<Object> context,
|
TNode<Code> target, TNode<Object> context,
|
||||||
TArgs... args) {
|
std::initializer_list<Node*> args) {
|
||||||
DCHECK_EQ(descriptor.GetParameterCount(), sizeof...(args));
|
constexpr size_t kMaxNumArgs = 11;
|
||||||
|
DCHECK_GE(kMaxNumArgs, args.size());
|
||||||
|
DCHECK_EQ(descriptor.GetParameterCount(), args.size());
|
||||||
size_t result_size = 1;
|
size_t result_size = 1;
|
||||||
auto call_descriptor = Linkage::GetStubCallDescriptor(
|
auto call_descriptor = Linkage::GetStubCallDescriptor(
|
||||||
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
|
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
|
||||||
CallDescriptor::kNoFlags, Operator::kNoProperties,
|
CallDescriptor::kNoFlags, Operator::kNoProperties,
|
||||||
MachineType::AnyTagged(), result_size);
|
MachineType::AnyTagged(), result_size);
|
||||||
|
|
||||||
Node* nodes[] = {target, args..., context};
|
NodeArray<kMaxNumArgs + 2> inputs;
|
||||||
CHECK_EQ(descriptor.GetParameterCount() + 2, arraysize(nodes));
|
inputs.Add(target);
|
||||||
raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes);
|
for (auto arg : args) inputs.Add(arg);
|
||||||
|
inputs.Add(context);
|
||||||
|
|
||||||
|
raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate TailCallStub() for argument counts used by CSA-generated code
|
Node* CodeAssembler::CallStubRImpl(const CallInterfaceDescriptor& descriptor,
|
||||||
#define INSTANTIATE(...) \
|
size_t result_size, SloppyTNode<Code> target,
|
||||||
template V8_EXPORT_PRIVATE void CodeAssembler::TailCallStubImpl( \
|
SloppyTNode<Object> context,
|
||||||
const CallInterfaceDescriptor& descriptor, TNode<Code>, __VA_ARGS__);
|
std::initializer_list<Node*> args) {
|
||||||
REPEAT_0_TO_11(INSTANTIATE, TNode<Object>, Node*)
|
constexpr size_t kMaxNumArgs = 10;
|
||||||
#undef INSTANTIATE
|
DCHECK_GE(kMaxNumArgs, args.size());
|
||||||
|
|
||||||
template <class... TArgs>
|
NodeArray<kMaxNumArgs + 2> inputs;
|
||||||
Node* CodeAssembler::TailCallStubThenBytecodeDispatch(
|
inputs.Add(target);
|
||||||
|
for (auto arg : args) inputs.Add(arg);
|
||||||
|
if (context) inputs.Add(context);
|
||||||
|
|
||||||
|
return CallStubN(descriptor, result_size, inputs.size(), inputs.data(),
|
||||||
|
context != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* CodeAssembler::TailCallStubThenBytecodeDispatchImpl(
|
||||||
const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
|
const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
|
||||||
TArgs... args) {
|
std::initializer_list<Node*> args) {
|
||||||
DCHECK_LE(descriptor.GetParameterCount(), sizeof...(args));
|
constexpr size_t kMaxNumArgs = 6;
|
||||||
|
DCHECK_GE(kMaxNumArgs, args.size());
|
||||||
|
|
||||||
|
DCHECK_LE(descriptor.GetParameterCount(), args.size());
|
||||||
|
int argc = static_cast<int>(args.size());
|
||||||
// Extra arguments not mentioned in the descriptor are passed on the stack.
|
// Extra arguments not mentioned in the descriptor are passed on the stack.
|
||||||
int stack_parameter_count =
|
int stack_parameter_count = argc - descriptor.GetRegisterParameterCount();
|
||||||
sizeof...(args) - descriptor.GetRegisterParameterCount();
|
|
||||||
DCHECK_LE(descriptor.GetStackParameterCount(), stack_parameter_count);
|
DCHECK_LE(descriptor.GetStackParameterCount(), stack_parameter_count);
|
||||||
auto call_descriptor = Linkage::GetStubCallDescriptor(
|
auto call_descriptor = Linkage::GetStubCallDescriptor(
|
||||||
isolate(), zone(), descriptor, stack_parameter_count,
|
isolate(), zone(), descriptor, stack_parameter_count,
|
||||||
CallDescriptor::kNoFlags, Operator::kNoProperties,
|
CallDescriptor::kNoFlags, Operator::kNoProperties,
|
||||||
MachineType::AnyTagged(), 0);
|
MachineType::AnyTagged(), 0);
|
||||||
|
|
||||||
Node* nodes[] = {target, args..., context};
|
NodeArray<kMaxNumArgs + 2> inputs;
|
||||||
return raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes);
|
inputs.Add(target);
|
||||||
}
|
for (auto arg : args) inputs.Add(arg);
|
||||||
|
inputs.Add(context);
|
||||||
|
|
||||||
// Instantiate TailCallStubThenBytecodeDispatch() for argument counts used by
|
return raw_assembler()->TailCallN(call_descriptor, inputs.size(),
|
||||||
// CSA-generated code
|
inputs.data());
|
||||||
#define INSTANTIATE(...) \
|
}
|
||||||
template V8_EXPORT_PRIVATE Node* \
|
|
||||||
CodeAssembler::TailCallStubThenBytecodeDispatch( \
|
|
||||||
const CallInterfaceDescriptor&, Node*, Node*, Node*, __VA_ARGS__);
|
|
||||||
REPEAT_0_TO_6(INSTANTIATE, Node*, Node*)
|
|
||||||
#undef INSTANTIATE
|
|
||||||
|
|
||||||
template <class... TArgs>
|
template <class... TArgs>
|
||||||
Node* CodeAssembler::TailCallBytecodeDispatch(
|
Node* CodeAssembler::TailCallBytecodeDispatch(
|
||||||
@ -1726,15 +1703,3 @@ Smi* CheckObjectType(Object* value, Smi* type, String* location) {
|
|||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
|
||||||
#undef REPEAT_0_TO_1
|
|
||||||
#undef REPEAT_0_TO_2
|
|
||||||
#undef REPEAT_0_TO_3
|
|
||||||
#undef REPEAT_0_TO_4
|
|
||||||
#undef REPEAT_0_TO_5
|
|
||||||
#undef REPEAT_0_TO_6
|
|
||||||
#undef REPEAT_0_TO_7
|
|
||||||
#undef REPEAT_0_TO_8
|
|
||||||
#undef REPEAT_0_TO_9
|
|
||||||
#undef REPEAT_0_TO_10
|
|
||||||
#undef REPEAT_0_TO_11
|
|
||||||
|
@ -983,7 +983,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
|||||||
TNode<Object> CallRuntime(Runtime::FunctionId function,
|
TNode<Object> CallRuntime(Runtime::FunctionId function,
|
||||||
SloppyTNode<Object> context, TArgs... args) {
|
SloppyTNode<Object> context, TArgs... args) {
|
||||||
return CallRuntimeImpl(function, context,
|
return CallRuntimeImpl(function, context,
|
||||||
implicit_cast<SloppyTNode<Object>>(args)...);
|
{implicit_cast<SloppyTNode<Object>>(args)...});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... TArgs>
|
template <class... TArgs>
|
||||||
@ -992,14 +992,14 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
|||||||
int argc = static_cast<int>(sizeof...(args));
|
int argc = static_cast<int>(sizeof...(args));
|
||||||
TNode<Int32T> arity = Int32Constant(argc);
|
TNode<Int32T> arity = Int32Constant(argc);
|
||||||
return TailCallRuntimeImpl(function, arity, context,
|
return TailCallRuntimeImpl(function, arity, context,
|
||||||
implicit_cast<SloppyTNode<Object>>(args)...);
|
{implicit_cast<SloppyTNode<Object>>(args)...});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... TArgs>
|
template <class... TArgs>
|
||||||
void TailCallRuntime(Runtime::FunctionId function, TNode<Int32T> arity,
|
void TailCallRuntime(Runtime::FunctionId function, TNode<Int32T> arity,
|
||||||
SloppyTNode<Object> context, TArgs... args) {
|
SloppyTNode<Object> context, TArgs... args) {
|
||||||
return TailCallRuntimeImpl(function, arity, context,
|
return TailCallRuntimeImpl(function, arity, context,
|
||||||
implicit_cast<SloppyTNode<Object>>(args)...);
|
{implicit_cast<SloppyTNode<Object>>(args)...});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... TArgs>
|
template <class... TArgs>
|
||||||
@ -1010,7 +1010,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
|||||||
TNode<Int32T> arity = Int32Constant(argc);
|
TNode<Int32T> arity = Int32Constant(argc);
|
||||||
return TailCallRuntimeWithCEntryImpl(
|
return TailCallRuntimeWithCEntryImpl(
|
||||||
function, arity, centry, context,
|
function, arity, centry, context,
|
||||||
implicit_cast<SloppyTNode<Object>>(args)...);
|
{implicit_cast<SloppyTNode<Object>>(args)...});
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1021,22 +1021,22 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
|||||||
TNode<T> CallStub(Callable const& callable, SloppyTNode<Object> context,
|
TNode<T> CallStub(Callable const& callable, SloppyTNode<Object> context,
|
||||||
TArgs... args) {
|
TArgs... args) {
|
||||||
TNode<Code> target = HeapConstant(callable.code());
|
TNode<Code> target = HeapConstant(callable.code());
|
||||||
return CallStub<T>(callable.descriptor(), target, context,
|
return CallStub<T>(callable.descriptor(), target, context, args...);
|
||||||
implicit_cast<Node*>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T = Object, class... TArgs>
|
template <class T = Object, class... TArgs>
|
||||||
TNode<T> CallStub(const CallInterfaceDescriptor& descriptor,
|
TNode<T> CallStub(const CallInterfaceDescriptor& descriptor,
|
||||||
SloppyTNode<Code> target, SloppyTNode<Object> context,
|
SloppyTNode<Code> target, SloppyTNode<Object> context,
|
||||||
TArgs... args) {
|
TArgs... args) {
|
||||||
return UncheckedCast<T>(CallStubR(descriptor, 1, target, context,
|
return UncheckedCast<T>(CallStubR(descriptor, 1, target, context, args...));
|
||||||
implicit_cast<Node*>(args)...));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... TArgs>
|
template <class... TArgs>
|
||||||
Node* CallStubR(const CallInterfaceDescriptor& descriptor, size_t result_size,
|
Node* CallStubR(const CallInterfaceDescriptor& descriptor, size_t result_size,
|
||||||
SloppyTNode<Code> target, SloppyTNode<Object> context,
|
SloppyTNode<Code> target, SloppyTNode<Object> context,
|
||||||
TArgs... args);
|
TArgs... args) {
|
||||||
|
return CallStubRImpl(descriptor, result_size, target, context, {args...});
|
||||||
|
}
|
||||||
|
|
||||||
Node* CallStubN(const CallInterfaceDescriptor& descriptor, size_t result_size,
|
Node* CallStubN(const CallInterfaceDescriptor& descriptor, size_t result_size,
|
||||||
int input_count, Node* const* inputs,
|
int input_count, Node* const* inputs,
|
||||||
@ -1053,8 +1053,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
|||||||
void TailCallStub(const CallInterfaceDescriptor& descriptor,
|
void TailCallStub(const CallInterfaceDescriptor& descriptor,
|
||||||
SloppyTNode<Code> target, SloppyTNode<Object> context,
|
SloppyTNode<Code> target, SloppyTNode<Object> context,
|
||||||
TArgs... args) {
|
TArgs... args) {
|
||||||
return TailCallStubImpl(descriptor, target, context,
|
return TailCallStubImpl(descriptor, target, context, {args...});
|
||||||
implicit_cast<Node*>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... TArgs>
|
template <class... TArgs>
|
||||||
@ -1063,8 +1062,11 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
|||||||
|
|
||||||
template <class... TArgs>
|
template <class... TArgs>
|
||||||
Node* TailCallStubThenBytecodeDispatch(
|
Node* TailCallStubThenBytecodeDispatch(
|
||||||
const CallInterfaceDescriptor& descriptor, Node* context, Node* target,
|
const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
|
||||||
TArgs... args);
|
TArgs... args) {
|
||||||
|
return TailCallStubThenBytecodeDispatchImpl(descriptor, target, context,
|
||||||
|
{args...});
|
||||||
|
}
|
||||||
|
|
||||||
// Tailcalls to the given code object with JSCall linkage. The JS arguments
|
// Tailcalls to the given code object with JSCall linkage. The JS arguments
|
||||||
// (including receiver) are supposed to be already on the stack.
|
// (including receiver) are supposed to be already on the stack.
|
||||||
@ -1186,23 +1188,32 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
|||||||
PoisoningMitigationLevel poisoning_level() const;
|
PoisoningMitigationLevel poisoning_level() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class... TArgs>
|
|
||||||
TNode<Object> CallRuntimeImpl(Runtime::FunctionId function,
|
TNode<Object> CallRuntimeImpl(Runtime::FunctionId function,
|
||||||
TNode<Object> context, TArgs... args);
|
TNode<Object> context,
|
||||||
|
std::initializer_list<TNode<Object>> args);
|
||||||
|
|
||||||
template <class... TArgs>
|
|
||||||
void TailCallRuntimeImpl(Runtime::FunctionId function, TNode<Int32T> arity,
|
void TailCallRuntimeImpl(Runtime::FunctionId function, TNode<Int32T> arity,
|
||||||
TNode<Object> context, TArgs... args);
|
TNode<Object> context,
|
||||||
|
std::initializer_list<TNode<Object>> args);
|
||||||
|
|
||||||
template <class... TArgs>
|
|
||||||
void TailCallRuntimeWithCEntryImpl(Runtime::FunctionId function,
|
void TailCallRuntimeWithCEntryImpl(Runtime::FunctionId function,
|
||||||
TNode<Int32T> arity, TNode<Code> centry,
|
TNode<Int32T> arity, TNode<Code> centry,
|
||||||
TNode<Object> context, TArgs... args);
|
TNode<Object> context,
|
||||||
|
std::initializer_list<TNode<Object>> args);
|
||||||
|
|
||||||
template <class... TArgs>
|
|
||||||
void TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
|
void TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
|
||||||
TNode<Code> target, TNode<Object> context,
|
TNode<Code> target, TNode<Object> context,
|
||||||
TArgs... args);
|
std::initializer_list<Node*> args);
|
||||||
|
|
||||||
|
Node* TailCallStubThenBytecodeDispatchImpl(
|
||||||
|
const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
|
||||||
|
std::initializer_list<Node*> args);
|
||||||
|
|
||||||
|
Node* CallStubRImpl(const CallInterfaceDescriptor& descriptor,
|
||||||
|
size_t result_size, SloppyTNode<Code> target,
|
||||||
|
SloppyTNode<Object> context,
|
||||||
|
std::initializer_list<Node*> args);
|
||||||
|
|
||||||
// These two don't have definitions and are here only for catching use cases
|
// These two don't have definitions and are here only for catching use cases
|
||||||
// where the cast is not necessary.
|
// where the cast is not necessary.
|
||||||
TNode<Int32T> Signed(TNode<Int32T> x);
|
TNode<Int32T> Signed(TNode<Int32T> x);
|
||||||
|
Loading…
Reference in New Issue
Block a user