Commit ea177a6b authored by Milad Fa's avatar Milad Fa Committed by Commit Bot

PPC/s390: Reland "[codegen] Add static interface descriptors"

Port 2871e05c

Original Commit Message:

    This is a reland of ae0752df

    Reland fixes:

      * Remove UNREACHABLE() from constexpr switch, since we don't have a
        CONSTEXPR_UNREACHABLE() (it's ok, the switch is exhaustive for the
        enum anyway).
      * Fix IsRegisterArray trait to use public inheritance and size_t for
        std::array size.

    Original change's description:
    > [codegen] Add static interface descriptors
    >
    > Add a new CRTP StaticCallInterfaceDescriptor class, which provides
    > static constexpr getters for a descriptor's registers, parameter counts,
    > and so on. Each CallInterfaceDescriptor subclass is changed to extend
    > StaticCallInterfaceDescriptor, with StaticCallInterfaceDescriptor itself
    > extending CallInterfaceDescriptor to still provide a dynamic lookup
    > where needed.
    >
    > StaticCallInterfaceDescriptor provides a couple of customisation points,
    > where it reads its CRTP derived descriptor's static fields and
    > functions, with default fallbacks where appropriate. With these
    > customisation points, the definition of CallInterfaceDescriptor
    > subclasses is simplified to:
    >
    >     a) Providing parameter names (as before)
    >     b) Providing parameter types (as before)
    >     c) Optionally setting flags (like kNoContext or kAllowVarArgs) as
    >        static booleans on the class.
    >     d) Optionally providing a `registers()` method that returns a
    >        std::array<Register, N> of registers that may be used for
    >        parameters (if not provided, this defaults to the implementation
    >        specific default register set).
    >
    > Parameter registers (and register count) are automagically set based on
    > the number of parameters and number of given registers, with extra magic
    > to ignore no_reg registers (to reduce ia32 special casing). The
    > CallInterfaceDescriptorData is initialized based on these static
    > functions, rather than manual per-descriptor initializers.
    >
    > This allows us to skip loading descriptors dynamically for CallBuiltin
    > in Sparkplug, and instead lets us use a bit of template magic to
    > statically set up arguments for the calls. Any other users of statically
    > known descriptors will also benefit, thanks to C++ picking the static
    > methods over the dynamic methods on the base class when available.
    >
    > Because we can remove various virtual functions and trigger heavier
    > inlining of constantly known values, binary size slightly decreases with
    > this change.
    >
    > Note that torque-generated descriptors are changed to use the same magic,
    > rather than having Torque-specific magic, for consistency.
    >
    > Bug: v8:11420
    > Change-Id: Icc5e238b6313a08734feb564204a13226b450c22
    > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2814518
    > Auto-Submit: Leszek Swirski <leszeks@chromium.org>
    > Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
    > Reviewed-by: Clemens Backes <clemensb@chromium.org>
    > Reviewed-by: Igor Sheludko <ishell@chromium.org>
    > Reviewed-by: Jakob Gruber <jgruber@chromium.org>
    > Commit-Queue: Clemens Backes <clemensb@chromium.org>
    > Cr-Commit-Position: refs/heads/master@{#73996}

R=leszeks@chromium.org, joransiu@ca.ibm.com, junyan@redhat.com, midawson@redhat.com
BUG=
LOG=N

Change-Id: Id854bb901df72787ed225fc8790c3f626121ab3a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2830897Reviewed-by: 's avatarJunliang Yan <junyan@redhat.com>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#74034}
parent 798fbcb0
......@@ -4202,7 +4202,7 @@ v8_source_set("v8_base_without_compiler") {
"src/codegen/ppc/assembler-ppc.cc",
"src/codegen/ppc/constants-ppc.cc",
"src/codegen/ppc/cpu-ppc.cc",
"src/codegen/ppc/interface-descriptors-ppc.cc",
"src/codegen/ppc/interface-descriptors-ppc-inl.h",
"src/codegen/ppc/macro-assembler-ppc.cc",
"src/compiler/backend/ppc/code-generator-ppc.cc",
"src/compiler/backend/ppc/instruction-scheduler-ppc.cc",
......@@ -4222,7 +4222,7 @@ v8_source_set("v8_base_without_compiler") {
"src/codegen/ppc/assembler-ppc.cc",
"src/codegen/ppc/constants-ppc.cc",
"src/codegen/ppc/cpu-ppc.cc",
"src/codegen/ppc/interface-descriptors-ppc.cc",
"src/codegen/ppc/interface-descriptors-ppc-inl.h",
"src/codegen/ppc/macro-assembler-ppc.cc",
"src/compiler/backend/ppc/code-generator-ppc.cc",
"src/compiler/backend/ppc/instruction-scheduler-ppc.cc",
......@@ -4242,7 +4242,7 @@ v8_source_set("v8_base_without_compiler") {
"src/codegen/s390/assembler-s390.cc",
"src/codegen/s390/constants-s390.cc",
"src/codegen/s390/cpu-s390.cc",
"src/codegen/s390/interface-descriptors-s390.cc",
"src/codegen/s390/interface-descriptors-s390-inl.h",
"src/codegen/s390/macro-assembler-s390.cc",
"src/compiler/backend/s390/code-generator-s390.cc",
"src/compiler/backend/s390/instruction-scheduler-s390.cc",
......
......@@ -6,6 +6,7 @@
#include "src/api/api-arguments.h"
#include "src/codegen/code-factory.h"
#include "src/codegen/interface-descriptors-inl.h"
// For interpreter_entry_return_pc_offset. TODO(jkummerow): Drop.
#include "src/codegen/macro-assembler-inl.h"
#include "src/codegen/register-configuration.h"
......
......@@ -6,6 +6,7 @@
#include "src/api/api-arguments.h"
#include "src/codegen/code-factory.h"
#include "src/codegen/interface-descriptors-inl.h"
// For interpreter_entry_return_pc_offset. TODO(jkummerow): Drop.
#include "src/codegen/macro-assembler-inl.h"
#include "src/codegen/register-configuration.h"
......
......@@ -18,6 +18,10 @@
#include "src/codegen/ia32/interface-descriptors-ia32-inl.h"
#elif V8_TARGET_ARCH_ARM
#include "src/codegen/arm/interface-descriptors-arm-inl.h"
#elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
#include "src/codegen/ppc/interface-descriptors-ppc-inl.h"
#elif V8_TARGET_ARCH_S390
#include "src/codegen/s390/interface-descriptors-s390-inl.h"
#else
#error Unsupported target architecture.
#endif
......@@ -261,7 +265,8 @@ constexpr auto LoadWithReceiverBaselineDescriptor::registers() {
constexpr auto BaselineOutOfLinePrologueDescriptor::registers() {
// TODO(v8:11421): Implement on other platforms.
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 || \
V8_TARGET_ARCH_ARM
V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64 || \
V8_TARGET_ARCH_S390
return RegisterArray(
kContextRegister, kJSFunctionRegister, kJavaScriptCallArgCountRegister,
kJavaScriptCallExtraArg1Register, kJavaScriptCallNewTargetRegister,
......@@ -275,7 +280,8 @@ constexpr auto BaselineOutOfLinePrologueDescriptor::registers() {
constexpr auto BaselineLeaveFrameDescriptor::registers() {
// TODO(v8:11421): Implement on other platforms.
#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || \
V8_TARGET_ARCH_ARM
V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64 || \
V8_TARGET_ARCH_S390
return RegisterArray(ParamsSizeRegister(), WeightRegister());
#else
return DefaultRegisterArray();
......
// Copyright 2021 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_PPC_INTERFACE_DESCRIPTORS_PPC_INL_H_
#define V8_CODEGEN_PPC_INTERFACE_DESCRIPTORS_PPC_INL_H_
#if V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
#include "src/codegen/interface-descriptors.h"
#include "src/execution/frames.h"
namespace v8 {
namespace internal {
constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
auto registers = RegisterArray(r3, r4, r5, r6, r7);
STATIC_ASSERT(registers.size() == kMaxBuiltinRegisterParams);
return registers;
}
// static
constexpr auto RecordWriteDescriptor::registers() {
return RegisterArray(r3, r4, r5, r6, r7, kReturnRegister0);
}
// static
constexpr auto DynamicCheckMapsDescriptor::registers() {
return RegisterArray(r3, r4, r5, r6, cp);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(r3, r4, r5, r6, r7, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return r4; }
// static
constexpr Register LoadDescriptor::NameRegister() { return r5; }
// static
constexpr Register LoadDescriptor::SlotRegister() { return r3; }
// static
constexpr Register LoadWithVectorDescriptor::VectorRegister() { return r6; }
// static
constexpr Register
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
return r7;
}
// static
constexpr Register StoreDescriptor::ReceiverRegister() { return r4; }
// static
constexpr Register StoreDescriptor::NameRegister() { return r5; }
// static
constexpr Register StoreDescriptor::ValueRegister() { return r3; }
// static
constexpr Register StoreDescriptor::SlotRegister() { return r7; }
// static
constexpr Register StoreWithVectorDescriptor::VectorRegister() { return r6; }
// static
constexpr Register StoreTransitionDescriptor::MapRegister() { return r8; }
// static
constexpr Register ApiGetterDescriptor::HolderRegister() { return r3; }
// static
constexpr Register ApiGetterDescriptor::CallbackRegister() { return r6; }
// static
constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return r3; }
// static
constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return r6; }
// static
constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
// TODO(v8:11421): Implement on this platform.
return no_reg;
}
// static
constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() {
// TODO(v8:11421): Implement on this platform.
return no_reg;
}
// static
// static
constexpr Register TypeConversionDescriptor::ArgumentRegister() { return r3; }
// static
constexpr auto TypeofDescriptor::registers() { return RegisterArray(r6); }
// static
constexpr auto CallTrampolineDescriptor::registers() {
// r3 : number of arguments
// r4 : the target to call
return RegisterArray(r4, r3);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// r3 : number of arguments (on the stack, not including receiver)
// r4 : the target to call
// r7 : arguments list length (untagged)
// r5 : arguments list (FixedArray)
return RegisterArray(r4, r3, r7, r5);
}
// static
constexpr auto CallForwardVarargsDescriptor::registers() {
// r3 : number of arguments
// r5 : start index (to support rest parameters)
// r4 : the target to call
return RegisterArray(r4, r3, r5);
}
// static
constexpr auto CallFunctionTemplateDescriptor::registers() {
// r4 : function template info
// r5 : number of arguments (on the stack, not including receiver)
return RegisterArray(r4, r5);
}
// static
constexpr auto CallWithSpreadDescriptor::registers() {
// r3 : number of arguments (on the stack, not including receiver)
// r4 : the target to call
// r5 : the object to spread
return RegisterArray(r4, r3, r5);
}
// static
constexpr auto CallWithArrayLikeDescriptor::registers() {
// r4 : the target to call
// r5 : the arguments list
return RegisterArray(r4, r5);
}
// static
constexpr auto ConstructVarargsDescriptor::registers() {
// r3 : number of arguments (on the stack, not including receiver)
// r4 : the target to call
// r6 : the new target
// r7 : arguments list length (untagged)
// r5 : arguments list (FixedArray)
return RegisterArray(r4, r6, r3, r7, r5);
}
// static
constexpr auto ConstructForwardVarargsDescriptor::registers() {
// r3 : number of arguments
// r6 : the new target
// r5 : start index (to support rest parameters)
// r4 : the target to call
return RegisterArray(r4, r6, r3, r5);
}
// static
constexpr auto ConstructWithSpreadDescriptor::registers() {
// r3 : number of arguments (on the stack, not including receiver)
// r4 : the target to call
// r6 : the new target
// r5 : the object to spread
return RegisterArray(r4, r6, r3, r5);
}
// static
constexpr auto ConstructWithArrayLikeDescriptor::registers() {
// r4 : the target to call
// r6 : the new target
// r5 : the arguments list
return RegisterArray(r4, r6, r5);
}
// static
constexpr auto ConstructStubDescriptor::registers() {
// r3 : number of arguments
// r4 : the target to call
// r6 : the new target
// r5 : allocation site or undefined
return RegisterArray(r4, r6, r3, r5);
}
// static
constexpr auto AbortDescriptor::registers() { return RegisterArray(r4); }
// static
constexpr auto CompareDescriptor::registers() { return RegisterArray(r4, r3); }
// static
constexpr auto Compare_BaselineDescriptor::registers() {
// TODO(v8:11421): Implement on this platform.
return RegisterArray();
}
// static
constexpr auto BinaryOpDescriptor::registers() { return RegisterArray(r4, r3); }
// static
constexpr auto BinaryOp_BaselineDescriptor::registers() {
// TODO(v8:11421): Implement on this platform.
return RegisterArray();
}
// static
constexpr auto ApiCallbackDescriptor::registers() {
return RegisterArray(r4, // kApiFunctionAddress
r5, // kArgc
r6, // kCallData
r3); // kHolder
}
// static
constexpr auto InterpreterDispatchDescriptor::registers() {
return RegisterArray(
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister);
}
// static
constexpr auto InterpreterPushArgsThenCallDescriptor::registers() {
return RegisterArray(r3, // argument count (not including receiver)
r5, // address of first argument
r4); // the target callable to be call
}
// static
constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() {
return RegisterArray(
r3, // argument count (not including receiver)
r7, // address of the first argument
r4, // constructor to call
r6, // new target
r5); // allocation site feedback if available, undefined otherwise
}
// static
constexpr auto ResumeGeneratorDescriptor::registers() {
return RegisterArray(r3, // the value to pass to the generator
r4); // the JSGeneratorObject to resume
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
return RegisterArray(r4); // loaded new FP
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(r3, r4);
}
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
#endif // V8_CODEGEN_PPC_INTERFACE_DESCRIPTORS_PPC_INL_H_
This diff is collapsed.
......@@ -12,6 +12,7 @@
#include "src/codegen/callable.h"
#include "src/codegen/code-factory.h"
#include "src/codegen/external-reference-table.h"
#include "src/codegen/interface-descriptors-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/codegen/register-configuration.h"
#include "src/debug/debug.h"
......
// Copyright 2021 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_S390_INTERFACE_DESCRIPTORS_S390_INL_H_
#define V8_CODEGEN_S390_INTERFACE_DESCRIPTORS_S390_INL_H_
#if V8_TARGET_ARCH_S390
#include "src/codegen/interface-descriptors.h"
#include "src/execution/frames.h"
namespace v8 {
namespace internal {
constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
auto registers = RegisterArray(r2, r3, r4, r5, r6);
STATIC_ASSERT(registers.size() == kMaxBuiltinRegisterParams);
return registers;
}
// static
constexpr auto RecordWriteDescriptor::registers() {
return RegisterArray(r2, r3, r4, r5, r6, kReturnRegister0);
}
// static
constexpr auto DynamicCheckMapsDescriptor::registers() {
return RegisterArray(r2, r3, r4, r5, cp);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(r2, r3, r4, r5, r6, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return r3; }
// static
constexpr Register LoadDescriptor::NameRegister() { return r4; }
// static
constexpr Register LoadDescriptor::SlotRegister() { return r2; }
// static
constexpr Register LoadWithVectorDescriptor::VectorRegister() { return r5; }
// static
constexpr Register
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
return r6;
}
// static
constexpr Register StoreDescriptor::ReceiverRegister() { return r3; }
// static
constexpr Register StoreDescriptor::NameRegister() { return r4; }
// static
constexpr Register StoreDescriptor::ValueRegister() { return r2; }
// static
constexpr Register StoreDescriptor::SlotRegister() { return r6; }
// static
constexpr Register StoreWithVectorDescriptor::VectorRegister() { return r5; }
// static
constexpr Register StoreTransitionDescriptor::MapRegister() { return r7; }
// static
constexpr Register ApiGetterDescriptor::HolderRegister() { return r2; }
// static
constexpr Register ApiGetterDescriptor::CallbackRegister() { return r5; }
// static
constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return r2; }
// static
constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return r5; }
// static
constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
// TODO(v8:11421): Implement on this platform.
return no_reg;
}
// static
constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() {
// TODO(v8:11421): Implement on this platform.
return no_reg;
}
// static
// static
constexpr Register TypeConversionDescriptor::ArgumentRegister() { return r2; }
// static
constexpr auto TypeofDescriptor::registers() { return RegisterArray(r5); }
// static
constexpr auto CallTrampolineDescriptor::registers() {
// r2 : number of arguments
// r3 : the target to call
return RegisterArray(r3, r2);
}
// static
constexpr auto CallVarargsDescriptor::registers() {
// r2 : number of arguments (on the stack, not including receiver)
// r3 : the target to call
// r6 : arguments list length (untagged)
// r4 : arguments list (FixedArray)
return RegisterArray(r3, r2, r6, r4);
}
// static
constexpr auto CallForwardVarargsDescriptor::registers() {
// r2 : number of arguments
// r4 : start index (to support rest parameters)
// r3 : the target to call
return RegisterArray(r3, r2, r4);
}
// static
constexpr auto CallFunctionTemplateDescriptor::registers() {
// r3 : function template info
// r4 : number of arguments (on the stack, not including receiver)
return RegisterArray(r3, r4);
}
// static
constexpr auto CallWithSpreadDescriptor::registers() {
// r2: number of arguments (on the stack, not including receiver)
// r3 : the target to call
// r4 : the object to spread
return RegisterArray(r3, r2, r4);
}
// static
constexpr auto CallWithArrayLikeDescriptor::registers() {
// r3 : the target to call
// r4 : the arguments list
return RegisterArray(r3, r4);
}
// static
constexpr auto ConstructVarargsDescriptor::registers() {
// r2 : number of arguments (on the stack, not including receiver)
// r3 : the target to call
// r5 : the new target
// r6 : arguments list length (untagged)
// r4 : arguments list (FixedArray)
return RegisterArray(r3, r5, r2, r6, r4);
}
// static
constexpr auto ConstructForwardVarargsDescriptor::registers() {
// r2 : number of arguments
// r5 : the new target
// r4 : start index (to support rest parameters)
// r3 : the target to call
return RegisterArray(r3, r5, r2, r4);
}
// static
constexpr auto ConstructWithSpreadDescriptor::registers() {
// r2 : number of arguments (on the stack, not including receiver)
// r3 : the target to call
// r5 : the new target
// r4 : the object to spread
return RegisterArray(r3, r5, r2, r4);
}
// static
constexpr auto ConstructWithArrayLikeDescriptor::registers() {
// r3 : the target to call
// r5 : the new target
// r4 : the arguments list
return RegisterArray(r3, r5, r4);
}
// static
constexpr auto ConstructStubDescriptor::registers() {
// r2 : number of arguments
// r3 : the target to call
// r5 : the new target
// r4 : allocation site or undefined
return RegisterArray(r3, r5, r2, r4);
}
// static
constexpr auto AbortDescriptor::registers() { return RegisterArray(r3); }
// static
constexpr auto CompareDescriptor::registers() { return RegisterArray(r3, r2); }
// static
constexpr auto Compare_BaselineDescriptor::registers() {
// TODO(v8:11421): Implement on this platform.
return RegisterArray();
}
// static
constexpr auto BinaryOpDescriptor::registers() { return RegisterArray(r3, r2); }
// static
constexpr auto BinaryOp_BaselineDescriptor::registers() {
// TODO(v8:11421): Implement on this platform.
return RegisterArray();
}
// static
constexpr auto ApiCallbackDescriptor::registers() {
return RegisterArray(r3, // kApiFunctionAddress
r4, // kArgc
r5, // kCallData
r2); // kHolder
}
// static
constexpr auto InterpreterDispatchDescriptor::registers() {
return RegisterArray(
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister);
}
// static
constexpr auto InterpreterPushArgsThenCallDescriptor::registers() {
return RegisterArray(r2, // argument count (not including receiver)
r4, // address of first argument
r3); // the target callable to be call
}
// static
constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() {
return RegisterArray(
r2, // argument count (not including receiver)
r6, // address of the first argument
r3, // constructor to call
r5, // new target
r4); // allocation site feedback if available, undefined otherwise
}
// static
constexpr auto ResumeGeneratorDescriptor::registers() {
return RegisterArray(r2, // the value to pass to the generator
r3); // the JSGeneratorObject to resume
}
// static
constexpr auto FrameDropperTrampolineDescriptor::registers() {
return RegisterArray(r3); // loaded new FP
}
// static
constexpr auto RunMicrotasksEntryDescriptor::registers() {
return RegisterArray(r2, r3);
}
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_S390
#endif // V8_CODEGEN_S390_INTERFACE_DESCRIPTORS_S390_INL_H_
This diff is collapsed.
......@@ -12,6 +12,7 @@
#include "src/codegen/callable.h"
#include "src/codegen/code-factory.h"
#include "src/codegen/external-reference-table.h"
#include "src/codegen/interface-descriptors-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/codegen/register-configuration.h"
#include "src/debug/debug.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment