summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/code-assembler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/code-assembler.cc')
-rw-r--r--deps/v8/src/compiler/code-assembler.cc414
1 files changed, 201 insertions, 213 deletions
diff --git a/deps/v8/src/compiler/code-assembler.cc b/deps/v8/src/compiler/code-assembler.cc
index c9f323615a..0b77d10072 100644
--- a/deps/v8/src/compiler/code-assembler.cc
+++ b/deps/v8/src/compiler/code-assembler.cc
@@ -6,7 +6,6 @@
#include <ostream>
-#include "src/builtins/constants-table-builder.h"
#include "src/code-factory.h"
#include "src/compiler/graph.h"
#include "src/compiler/instruction-selector.h"
@@ -22,24 +21,9 @@
#include "src/machine-type.h"
#include "src/macro-assembler.h"
#include "src/objects-inl.h"
-#include "src/snapshot/serializer-common.h"
#include "src/utils.h"
#include "src/zone/zone.h"
-#define REPEAT_1_TO_2(V, T) V(T) V(T, T)
-#define REPEAT_1_TO_3(V, T) REPEAT_1_TO_2(V, T) V(T, T, T)
-#define REPEAT_1_TO_4(V, T) REPEAT_1_TO_3(V, T) V(T, T, T, T)
-#define REPEAT_1_TO_5(V, T) REPEAT_1_TO_4(V, T) V(T, T, T, T, T)
-#define REPEAT_1_TO_6(V, T) REPEAT_1_TO_5(V, T) V(T, T, T, T, T, T)
-#define REPEAT_1_TO_7(V, T) REPEAT_1_TO_6(V, T) V(T, T, T, T, T, T, T)
-#define REPEAT_1_TO_8(V, T) REPEAT_1_TO_7(V, T) V(T, T, T, T, T, T, T, T)
-#define REPEAT_1_TO_9(V, T) REPEAT_1_TO_8(V, T) V(T, T, T, T, T, T, T, T, T)
-#define REPEAT_1_TO_10(V, T) REPEAT_1_TO_9(V, T) V(T, T, T, T, T, T, T, T, T, T)
-#define REPEAT_1_TO_11(V, T) \
- REPEAT_1_TO_10(V, T) V(T, T, T, T, T, T, T, T, T, T, T)
-#define REPEAT_1_TO_12(V, T) \
- REPEAT_1_TO_11(V, T) V(T, T, T, T, T, T, T, T, T, T, T, T)
-
namespace v8 {
namespace internal {
@@ -60,15 +44,14 @@ static_assert(
CodeAssemblerState::CodeAssemblerState(
Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
Code::Kind kind, const char* name, PoisoningMitigationLevel poisoning_level,
- size_t result_size, uint32_t stub_key, int32_t builtin_index)
+ uint32_t stub_key, int32_t builtin_index)
// TODO(rmcilroy): Should we use Linkage::GetBytecodeDispatchDescriptor for
// bytecode handlers?
: CodeAssemblerState(
isolate, zone,
Linkage::GetStubCallDescriptor(
- isolate, zone, descriptor, descriptor.GetStackParameterCount(),
- CallDescriptor::kNoFlags, Operator::kNoProperties,
- MachineType::AnyTagged(), result_size),
+ zone, descriptor, descriptor.GetStackParameterCount(),
+ CallDescriptor::kNoFlags, Operator::kNoProperties),
kind, name, poisoning_level, stub_key, builtin_index) {}
CodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone,
@@ -184,7 +167,8 @@ PoisoningMitigationLevel CodeAssembler::poisoning_level() const {
}
// static
-Handle<Code> CodeAssembler::GenerateCode(CodeAssemblerState* state) {
+Handle<Code> CodeAssembler::GenerateCode(CodeAssemblerState* state,
+ const AssemblerOptions& options) {
DCHECK(!state->code_generated_);
RawMachineAssembler* rasm = state->raw_assembler_.get();
@@ -194,19 +178,24 @@ Handle<Code> CodeAssembler::GenerateCode(CodeAssemblerState* state) {
bool should_optimize_jumps =
rasm->isolate()->serializer_enabled() && FLAG_turbo_rewrite_far_jumps;
- Handle<Code> code = Pipeline::GenerateCodeForCodeStub(
- rasm->isolate(), rasm->call_descriptor(), rasm->graph(), schedule,
- state->kind_, state->name_, state->stub_key_, state->builtin_index_,
- should_optimize_jumps ? &jump_opt : nullptr, rasm->poisoning_level());
+ Handle<Code> code =
+ Pipeline::GenerateCodeForCodeStub(
+ rasm->isolate(), rasm->call_descriptor(), rasm->graph(), schedule,
+ state->kind_, state->name_, state->stub_key_, state->builtin_index_,
+ should_optimize_jumps ? &jump_opt : nullptr, rasm->poisoning_level(),
+ options)
+ .ToHandleChecked();
if (jump_opt.is_optimizable()) {
jump_opt.set_optimizing();
// Regenerate machine code
- code = Pipeline::GenerateCodeForCodeStub(
- rasm->isolate(), rasm->call_descriptor(), rasm->graph(), schedule,
- state->kind_, state->name_, state->stub_key_, state->builtin_index_,
- &jump_opt, rasm->poisoning_level());
+ code =
+ Pipeline::GenerateCodeForCodeStub(
+ rasm->isolate(), rasm->call_descriptor(), rasm->graph(), schedule,
+ state->kind_, state->name_, state->stub_key_, state->builtin_index_,
+ &jump_opt, rasm->poisoning_level(), options)
+ .ToHandleChecked();
}
state->code_generated_ = true;
@@ -244,58 +233,20 @@ bool CodeAssembler::IsIntPtrAbsWithOverflowSupported() const {
: IsInt32AbsWithOverflowSupported();
}
-#ifdef V8_EMBEDDED_BUILTINS
-TNode<HeapObject> CodeAssembler::LookupConstant(Handle<HeapObject> object) {
- DCHECK(isolate()->ShouldLoadConstantsFromRootList());
-
- // Ensure the given object is in the builtins constants table and fetch its
- // index.
- BuiltinsConstantsTableBuilder* builder =
- isolate()->builtins_constants_table_builder();
- uint32_t index = builder->AddObject(object);
-
- // The builtins constants table is loaded through the root register on all
- // supported platforms. This is checked by the
- // VerifyBuiltinsIsolateIndependence cctest, which disallows embedded objects
- // in isolate-independent builtins.
- DCHECK(isolate()->heap()->RootCanBeTreatedAsConstant(
- Heap::kBuiltinsConstantsTableRootIndex));
- TNode<FixedArray> builtins_constants_table = UncheckedCast<FixedArray>(
- LoadRoot(Heap::kBuiltinsConstantsTableRootIndex));
-
- // Generate the lookup.
- const int32_t header_size = FixedArray::kHeaderSize - kHeapObjectTag;
- TNode<IntPtrT> offset = IntPtrConstant(header_size + kPointerSize * index);
- return UncheckedCast<HeapObject>(
- Load(MachineType::AnyTagged(), builtins_constants_table, offset));
+#ifdef DEBUG
+void CodeAssembler::GenerateCheckMaybeObjectIsObject(Node* node,
+ const char* location) {
+ Label ok(this);
+ GotoIf(WordNotEqual(WordAnd(BitcastMaybeObjectToWord(node),
+ IntPtrConstant(kHeapObjectTagMask)),
+ IntPtrConstant(kWeakHeapObjectTag)),
+ &ok);
+ Node* message_node = StringConstant(location);
+ DebugAbort(message_node);
+ Unreachable();
+ Bind(&ok);
}
-
-// External references are stored in the external reference table.
-TNode<ExternalReference> CodeAssembler::LookupExternalReference(
- ExternalReference reference) {
- DCHECK(isolate()->ShouldLoadConstantsFromRootList());
-
- // Encode as an index into the external reference table stored on the isolate.
-
- ExternalReferenceEncoder encoder(isolate());
- ExternalReferenceEncoder::Value v = encoder.Encode(reference.address());
- CHECK(!v.is_from_api());
- uint32_t index = v.index();
-
- // Generate code to load from the external reference table.
-
- const intptr_t roots_to_external_reference_offset =
- Heap::roots_to_external_reference_table_offset()
-#ifdef V8_TARGET_ARCH_X64
- - kRootRegisterBias
#endif
- + ExternalReferenceTable::OffsetOfEntry(index);
-
- return UncheckedCast<ExternalReference>(
- Load(MachineType::Pointer(), LoadRootsPointer(),
- IntPtrConstant(roots_to_external_reference_offset)));
-}
-#endif // V8_EMBEDDED_BUILTINS
TNode<Int32T> CodeAssembler::Int32Constant(int32_t value) {
return UncheckedCast<Int32T>(raw_assembler()->Int32Constant(value));
@@ -318,8 +269,8 @@ TNode<Number> CodeAssembler::NumberConstant(double value) {
// deferring allocation to code generation
// (see AllocateAndInstallRequestedHeapObjects) since that makes it easier
// to generate constant lookups for embedded builtins.
- return UncheckedCast<Number>(HeapConstant(
- isolate()->factory()->NewHeapNumber(value, IMMUTABLE, TENURED)));
+ return UncheckedCast<Number>(
+ HeapConstant(isolate()->factory()->NewHeapNumber(value, TENURED)));
}
}
@@ -334,16 +285,6 @@ TNode<Smi> CodeAssembler::SmiConstant(int value) {
TNode<HeapObject> CodeAssembler::UntypedHeapConstant(
Handle<HeapObject> object) {
-#ifdef V8_EMBEDDED_BUILTINS
- // Root constants are simply loaded from the root list, while non-root
- // constants must be looked up from the builtins constants table.
- if (isolate()->ShouldLoadConstantsFromRootList()) {
- Heap::RootListIndex root_index;
- if (!isolate()->heap()->IsRootHandle(object, &root_index)) {
- return LookupConstant(object);
- }
- }
-#endif // V8_EMBEDDED_BUILTINS
return UncheckedCast<HeapObject>(raw_assembler()->HeapConstant(object));
}
@@ -359,11 +300,6 @@ TNode<Oddball> CodeAssembler::BooleanConstant(bool value) {
TNode<ExternalReference> CodeAssembler::ExternalConstant(
ExternalReference address) {
-#ifdef V8_EMBEDDED_BUILTINS
- if (isolate()->ShouldLoadConstantsFromRootList()) {
- return LookupExternalReference(address);
- }
-#endif // V8_EMBEDDED_BUILTINS
return UncheckedCast<ExternalReference>(
raw_assembler()->ExternalConstant(address));
}
@@ -438,8 +374,14 @@ bool CodeAssembler::IsNullConstant(TNode<Object> node) {
return m.Is(isolate()->factory()->null_value());
}
-Node* CodeAssembler::Parameter(int value) {
- return raw_assembler()->Parameter(value);
+Node* CodeAssembler::Parameter(int index) {
+ if (index == kTargetParameterIndex) return raw_assembler()->TargetParameter();
+ return raw_assembler()->Parameter(index);
+}
+
+bool CodeAssembler::IsJSFunctionCall() const {
+ auto call_descriptor = raw_assembler()->call_descriptor();
+ return call_descriptor->IsJSFunctionCall();
}
TNode<Context> CodeAssembler::GetJSContextParameter() {
@@ -476,6 +418,10 @@ void CodeAssembler::ReturnIf(Node* condition, Node* value) {
Bind(&if_continue);
}
+void CodeAssembler::ReturnRaw(Node* value) {
+ return raw_assembler()->Return(value);
+}
+
void CodeAssembler::DebugAbort(Node* message) {
raw_assembler()->DebugAbort(message);
}
@@ -524,10 +470,6 @@ Node* CodeAssembler::LoadParentFramePointer() {
return raw_assembler()->LoadParentFramePointer();
}
-TNode<IntPtrT> CodeAssembler::LoadRootsPointer() {
- return UncheckedCast<IntPtrT>(raw_assembler()->LoadRootsPointer());
-}
-
Node* CodeAssembler::LoadStackPointer() {
return raw_assembler()->LoadStackPointer();
}
@@ -938,6 +880,25 @@ TNode<Word64T> CodeAssembler::Word64Sar(SloppyTNode<Word64T> left,
return UncheckedCast<Word64T>(raw_assembler()->Word64Sar(left, right));
}
+#define CODE_ASSEMBLER_COMPARE(Name, ArgT, VarT, ToConstant, op) \
+ TNode<BoolT> CodeAssembler::Name(SloppyTNode<ArgT> left, \
+ SloppyTNode<ArgT> right) { \
+ VarT lhs, rhs; \
+ if (ToConstant(left, lhs) && ToConstant(right, rhs)) { \
+ return BoolConstant(lhs op rhs); \
+ } \
+ return UncheckedCast<BoolT>(raw_assembler()->Name(left, right)); \
+ }
+
+CODE_ASSEMBLER_COMPARE(IntPtrEqual, WordT, intptr_t, ToIntPtrConstant, ==)
+CODE_ASSEMBLER_COMPARE(WordEqual, WordT, intptr_t, ToIntPtrConstant, ==)
+CODE_ASSEMBLER_COMPARE(WordNotEqual, WordT, intptr_t, ToIntPtrConstant, !=)
+CODE_ASSEMBLER_COMPARE(Word32Equal, Word32T, int32_t, ToInt32Constant, ==)
+CODE_ASSEMBLER_COMPARE(Word32NotEqual, Word32T, int32_t, ToInt32Constant, !=)
+CODE_ASSEMBLER_COMPARE(Word64Equal, Word64T, int64_t, ToInt64Constant, ==)
+CODE_ASSEMBLER_COMPARE(Word64NotEqual, Word64T, int64_t, ToInt64Constant, !=)
+#undef CODE_ASSEMBLER_COMPARE
+
TNode<UintPtrT> CodeAssembler::ChangeUint32ToWord(SloppyTNode<Word32T> value) {
if (raw_assembler()->machine()->Is64()) {
return UncheckedCast<UintPtrT>(
@@ -1001,6 +962,9 @@ TNode<Object> CodeAssembler::LoadRoot(Heap::RootListIndex root_index) {
}
}
+ // TODO(jgruber): In theory we could generate better code for this by
+ // letting the macro assembler decide how to load from the roots list. In most
+ // cases, it would boil down to loading from a fixed kRootRegister offset.
Node* roots_array_start =
ExternalConstant(ExternalReference::roots_array_start(isolate()));
return UncheckedCast<Object>(Load(MachineType::AnyTagged(), roots_array_start,
@@ -1100,99 +1064,107 @@ void CodeAssembler::GotoIfException(Node* node, Label* if_exception,
Bind(&success);
}
-template <class... TArgs>
-TNode<Object> CodeAssembler::CallRuntimeImpl(Runtime::FunctionId function,
- SloppyTNode<Object> context,
- TArgs... args) {
- int argc = static_cast<int>(sizeof...(args));
+namespace {
+template <size_t kMaxSize>
+class NodeArray {
+ public:
+ 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) {
+ int result_size = Runtime::FunctionForId(function)->result_size;
+ TNode<Code> centry =
+ HeapConstant(CodeFactory::RuntimeCEntry(isolate(), result_size));
+ return CallRuntimeWithCEntryImpl(function, centry, context, args);
+}
+
+TNode<Object> CodeAssembler::CallRuntimeWithCEntryImpl(
+ Runtime::FunctionId function, TNode<Code> centry, 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(
zone(), function, argc, Operator::kNoProperties,
CallDescriptor::kNoFlags);
- int return_count = static_cast<int>(call_descriptor->ReturnCount());
- Node* centry =
- HeapConstant(CodeFactory::RuntimeCEntry(isolate(), return_count));
Node* ref = ExternalConstant(ExternalReference::Create(function));
Node* arity = Int32Constant(argc);
- 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);
CallPrologue();
Node* return_value =
- raw_assembler()->CallN(call_descriptor, arraysize(nodes), nodes);
+ raw_assembler()->CallN(call_descriptor, inputs.size(), inputs.data());
CallEpilogue();
return UncheckedCast<Object>(return_value);
}
-// Instantiate CallRuntime() for argument counts used by CSA-generated code
-#define INSTANTIATE(...) \
- template V8_EXPORT_PRIVATE TNode<Object> CodeAssembler::CallRuntimeImpl( \
- Runtime::FunctionId, __VA_ARGS__);
-REPEAT_1_TO_7(INSTANTIATE, SloppyTNode<Object>)
-#undef INSTANTIATE
+void CodeAssembler::TailCallRuntimeImpl(
+ Runtime::FunctionId function, TNode<Int32T> arity, TNode<Object> context,
+ std::initializer_list<TNode<Object>> args) {
+ int result_size = Runtime::FunctionForId(function)->result_size;
+ TNode<Code> centry =
+ HeapConstant(CodeFactory::RuntimeCEntry(isolate(), result_size));
+ return TailCallRuntimeWithCEntryImpl(function, arity, centry, context, args);
+}
-template <class... TArgs>
-TNode<Object> CodeAssembler::TailCallRuntimeImpl(Runtime::FunctionId function,
- SloppyTNode<Object> context,
- TArgs... args) {
- int argc = static_cast<int>(sizeof...(args));
+void CodeAssembler::TailCallRuntimeWithCEntryImpl(
+ Runtime::FunctionId function, TNode<Int32T> arity, TNode<Code> centry,
+ 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(
zone(), function, argc, Operator::kNoProperties,
CallDescriptor::kNoFlags);
- int return_count = static_cast<int>(call_descriptor->ReturnCount());
- Node* centry =
- HeapConstant(CodeFactory::RuntimeCEntry(isolate(), return_count));
Node* ref = ExternalConstant(ExternalReference::Create(function));
- Node* arity = Int32Constant(argc);
- 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);
- return UncheckedCast<Object>(
- raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes));
+ raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data());
}
-// Instantiate TailCallRuntime() for argument counts used by CSA-generated code
-#define INSTANTIATE(...) \
- template V8_EXPORT_PRIVATE TNode<Object> CodeAssembler::TailCallRuntimeImpl( \
- Runtime::FunctionId, __VA_ARGS__);
-REPEAT_1_TO_7(INSTANTIATE, SloppyTNode<Object>)
-#undef INSTANTIATE
-
-template <class... TArgs>
-Node* CodeAssembler::CallStubR(const CallInterfaceDescriptor& descriptor,
- size_t result_size, Node* target, Node* 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, Node*, __VA_ARGS__);
-REPEAT_1_TO_11(INSTANTIATE, Node*)
-#undef INSTANTIATE
-
Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
size_t result_size, int input_count,
- Node* const* inputs, bool pass_context) {
+ Node* const* inputs) {
// implicit nodes are target and optionally context.
- int implicit_nodes = pass_context ? 2 : 1;
+ int implicit_nodes = descriptor.HasContextParameter() ? 2 : 1;
DCHECK_LE(implicit_nodes, input_count);
int argc = input_count - implicit_nodes;
DCHECK_LE(descriptor.GetParameterCount(), argc);
// Extra arguments not mentioned in the descriptor are passed on the stack.
int stack_parameter_count = argc - descriptor.GetRegisterParameterCount();
DCHECK_LE(descriptor.GetStackParameterCount(), stack_parameter_count);
+ DCHECK_EQ(result_size, descriptor.GetReturnCount());
+
auto call_descriptor = Linkage::GetStubCallDescriptor(
- isolate(), zone(), descriptor, stack_parameter_count,
- CallDescriptor::kNoFlags, Operator::kNoProperties,
- MachineType::AnyTagged(), result_size,
- pass_context ? Linkage::kPassContext : Linkage::kNoContext);
+ zone(), descriptor, stack_parameter_count, CallDescriptor::kNoFlags,
+ Operator::kNoProperties);
CallPrologue();
Node* return_value =
@@ -1201,62 +1173,73 @@ Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
return return_value;
}
-template <class... TArgs>
-Node* CodeAssembler::TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
- Node* target, Node* context,
- TArgs... args) {
- DCHECK_EQ(descriptor.GetParameterCount(), sizeof...(args));
- size_t result_size = 1;
+void CodeAssembler::TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
+ TNode<Code> target, TNode<Object> context,
+ std::initializer_list<Node*> args) {
+ constexpr size_t kMaxNumArgs = 11;
+ DCHECK_GE(kMaxNumArgs, args.size());
+ DCHECK_EQ(descriptor.GetParameterCount(), args.size());
auto call_descriptor = Linkage::GetStubCallDescriptor(
- isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
- CallDescriptor::kNoFlags, Operator::kNoProperties,
- MachineType::AnyTagged(), result_size);
+ zone(), descriptor, descriptor.GetStackParameterCount(),
+ CallDescriptor::kNoFlags, Operator::kNoProperties);
+
+ NodeArray<kMaxNumArgs + 2> inputs;
+ inputs.Add(target);
+ for (auto arg : args) inputs.Add(arg);
+ if (descriptor.HasContextParameter()) {
+ inputs.Add(context);
+ }
- Node* nodes[] = {target, args..., context};
- CHECK_EQ(descriptor.GetParameterCount() + 2, arraysize(nodes));
- return raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes);
+ raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data());
}
-// Instantiate TailCallStub() for argument counts used by CSA-generated code
-#define INSTANTIATE(...) \
- template V8_EXPORT_PRIVATE Node* CodeAssembler::TailCallStubImpl( \
- const CallInterfaceDescriptor& descriptor, Node*, __VA_ARGS__);
-REPEAT_1_TO_12(INSTANTIATE, Node*)
-#undef INSTANTIATE
+Node* CodeAssembler::CallStubRImpl(const CallInterfaceDescriptor& descriptor,
+ size_t result_size, SloppyTNode<Code> target,
+ SloppyTNode<Object> context,
+ std::initializer_list<Node*> args) {
+ constexpr size_t kMaxNumArgs = 10;
+ DCHECK_GE(kMaxNumArgs, args.size());
-template <class... TArgs>
-Node* CodeAssembler::TailCallStubThenBytecodeDispatch(
+ NodeArray<kMaxNumArgs + 2> inputs;
+ inputs.Add(target);
+ for (auto arg : args) inputs.Add(arg);
+ if (descriptor.HasContextParameter()) {
+ inputs.Add(context);
+ }
+
+ return CallStubN(descriptor, result_size, inputs.size(), inputs.data());
+}
+
+Node* CodeAssembler::TailCallStubThenBytecodeDispatchImpl(
const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
- TArgs... args) {
- DCHECK_LE(descriptor.GetParameterCount(), sizeof...(args));
+ std::initializer_list<Node*> 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.
- int stack_parameter_count =
- sizeof...(args) - descriptor.GetRegisterParameterCount();
+ int stack_parameter_count = argc - descriptor.GetRegisterParameterCount();
DCHECK_LE(descriptor.GetStackParameterCount(), stack_parameter_count);
auto call_descriptor = Linkage::GetStubCallDescriptor(
- isolate(), zone(), descriptor, stack_parameter_count,
- CallDescriptor::kNoFlags, Operator::kNoProperties,
- MachineType::AnyTagged(), 0);
+ zone(), descriptor, stack_parameter_count, CallDescriptor::kNoFlags,
+ Operator::kNoProperties);
- Node* nodes[] = {target, args..., context};
- return raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes);
-}
+ NodeArray<kMaxNumArgs + 2> inputs;
+ inputs.Add(target);
+ for (auto arg : args) inputs.Add(arg);
+ inputs.Add(context);
-// Instantiate TailCallJSAndBytecodeDispatch() for argument counts used by
-// CSA-generated code
-#define INSTANTIATE(...) \
- template V8_EXPORT_PRIVATE Node* \
- CodeAssembler::TailCallStubThenBytecodeDispatch( \
- const CallInterfaceDescriptor&, Node*, Node*, Node*, __VA_ARGS__);
-REPEAT_1_TO_7(INSTANTIATE, Node*)
-#undef INSTANTIATE
+ return raw_assembler()->TailCallN(call_descriptor, inputs.size(),
+ inputs.data());
+}
template <class... TArgs>
Node* CodeAssembler::TailCallBytecodeDispatch(
const CallInterfaceDescriptor& descriptor, Node* target, TArgs... args) {
DCHECK_EQ(descriptor.GetParameterCount(), sizeof...(args));
auto call_descriptor = Linkage::GetBytecodeDispatchCallDescriptor(
- isolate(), zone(), descriptor, descriptor.GetStackParameterCount());
+ zone(), descriptor, descriptor.GetStackParameterCount());
Node* nodes[] = {target, args...};
CHECK_EQ(descriptor.GetParameterCount() + 1, arraysize(nodes));
@@ -1269,6 +1252,22 @@ template V8_EXPORT_PRIVATE Node* CodeAssembler::TailCallBytecodeDispatch(
const CallInterfaceDescriptor& descriptor, Node* target, Node*, Node*,
Node*, Node*);
+TNode<Object> CodeAssembler::TailCallJSCode(TNode<Code> code,
+ TNode<Context> context,
+ TNode<JSFunction> function,
+ TNode<Object> new_target,
+ TNode<Int32T> arg_count) {
+ JSTrampolineDescriptor descriptor;
+ auto call_descriptor = Linkage::GetStubCallDescriptor(
+ zone(), descriptor, descriptor.GetStackParameterCount(),
+ CallDescriptor::kFixedTargetRegister, Operator::kNoProperties);
+
+ Node* nodes[] = {code, function, new_target, arg_count, context};
+ CHECK_EQ(descriptor.GetParameterCount() + 2, arraysize(nodes));
+ return UncheckedCast<Object>(
+ raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes));
+}
+
Node* CodeAssembler::CallCFunctionN(Signature<MachineType>* signature,
int input_count, Node* const* inputs) {
auto call_descriptor = Linkage::GetSimplifiedCDescriptor(zone(), signature);
@@ -1686,7 +1685,8 @@ void CodeAssemblerLabel::UpdateVariablesAfterBind() {
} // namespace compiler
-Smi* CheckObjectType(Object* value, Smi* type, String* location) {
+Smi* CheckObjectType(Isolate* isolate, Object* value, Smi* type,
+ String* location) {
#ifdef DEBUG
const char* expected;
switch (static_cast<ObjectType>(type->value())) {
@@ -1721,15 +1721,3 @@ Smi* CheckObjectType(Object* value, Smi* type, String* location) {
} // namespace internal
} // namespace v8
-
-#undef REPEAT_1_TO_2
-#undef REPEAT_1_TO_3
-#undef REPEAT_1_TO_4
-#undef REPEAT_1_TO_5
-#undef REPEAT_1_TO_6
-#undef REPEAT_1_TO_7
-#undef REPEAT_1_TO_8
-#undef REPEAT_1_TO_9
-#undef REPEAT_1_TO_10
-#undef REPEAT_1_TO_11
-#undef REPEAT_1_TO_12