diff options
Diffstat (limited to 'deps/v8/src/compiler/code-assembler.cc')
-rw-r--r-- | deps/v8/src/compiler/code-assembler.cc | 414 |
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 |