cppgc: Apply [[clang::trivial_abi]] for Member<>

The attribute allows the Member to be passed around in registers. More
in the design dec: https://bit.ly/3e5tsok

Change-Id: I9c46fb2a5813f1f51f291fac6c0753f505009410
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3925708
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83550}
This commit is contained in:
Anton Bikineev 2022-10-05 15:37:50 +02:00 committed by V8 LUCI CQ
parent 2887525597
commit 6b1f085f99
3 changed files with 36 additions and 4 deletions

View File

@ -61,7 +61,7 @@ class CageBaseGlobal final {
#undef CPPGC_REQUIRE_CONSTANT_INIT
#undef CPPGC_CONST
class CompressedPointer final {
class V8_TRIVIAL_ABI CompressedPointer final {
public:
using IntegralType = uint32_t;
@ -170,7 +170,7 @@ class CompressedPointer final {
#endif // defined(CPPGC_POINTER_COMPRESSION)
class RawPointer final {
class V8_TRIVIAL_ABI RawPointer final {
public:
using IntegralType = uintptr_t;

View File

@ -28,7 +28,7 @@ namespace internal {
// MemberBase always refers to the object as const object and defers to
// BasicMember on casting to the right type as needed.
class MemberBase {
class V8_TRIVIAL_ABI MemberBase {
public:
#if defined(CPPGC_POINTER_COMPRESSION)
using RawStorage = CompressedPointer;
@ -74,7 +74,8 @@ class MemberBase {
// The basic class from which all Member classes are 'generated'.
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy>
class BasicMember final : private MemberBase, private CheckingPolicy {
class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
private CheckingPolicy {
public:
using PointeeType = T;

View File

@ -579,6 +579,37 @@ path. Add it with -I<path> to the command line
#define V8_NO_UNIQUE_ADDRESS /* NOT SUPPORTED */
#endif
// Marks a type as being eligible for the "trivial" ABI despite having a
// non-trivial destructor or copy/move constructor. Such types can be relocated
// after construction by simply copying their memory, which makes them eligible
// to be passed in registers. The canonical example is std::unique_ptr.
//
// Use with caution; this has some subtle effects on constructor/destructor
// ordering and will be very incorrect if the type relies on its address
// remaining constant. When used as a function argument (by value), the value
// may be constructed in the caller's stack frame, passed in a register, and
// then used and destructed in the callee's stack frame. A similar thing can
// occur when values are returned.
//
// TRIVIAL_ABI is not needed for types which have a trivial destructor and
// copy/move constructors, since those are automatically trivial by the ABI
// spec.
//
// It is also not likely to be effective on types too large to be passed in one
// or two registers on typical target ABIs.
//
// See also:
// https://clang.llvm.org/docs/AttributeReference.html#trivial-abi
// https://libcxx.llvm.org/docs/DesignDocs/UniquePtrTrivialAbi.html
#if defined(__clang__) && defined(__has_attribute)
#if __has_attribute(trivial_abi)
#define V8_TRIVIAL_ABI [[clang::trivial_abi]]
#endif // __has_attribute(trivial_abi)
#endif // defined(__clang__) && defined(__has_attribute)
#if !defined(V8_TRIVIAL_ABI)
#define V8_TRIVIAL_ABI
#endif //!defined(V8_TRIVIAL_ABI)
// Helper macro to define no_sanitize attributes only with clang.
#if defined(__clang__) && defined(__has_attribute)
#if __has_attribute(no_sanitize)