cppgc: Introduce subtle::UncompressedMember

Some very hot getters in Blink can spend many cycles on decompression.
We're planning to optimize such paths by selectively using uncompressed
pointers.

Change-Id: I78af751c423c56010a794448450032c66f8fa244
Bug: chromium:1410145
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4191778
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85508}
This commit is contained in:
Anton Bikineev 2023-01-26 22:48:21 +01:00 committed by V8 LUCI CQ
parent fa303fcd0b
commit 02afcd6b05
12 changed files with 230 additions and 165 deletions

View File

@ -148,10 +148,11 @@ class BasicCrossThreadPersistent final : public CrossThreadPersistentBase,
template <typename U, typename MemberBarrierPolicy, template <typename U, typename MemberBarrierPolicy,
typename MemberWeaknessTag, typename MemberCheckingPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy,
typename MemberStorageType,
typename = std::enable_if_t<std::is_base_of<T, U>::value>> typename = std::enable_if_t<std::is_base_of<T, U>::value>>
BasicCrossThreadPersistent( BasicCrossThreadPersistent(
internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag, internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
MemberCheckingPolicy> MemberCheckingPolicy, MemberStorageType>
member, member,
const SourceLocation& loc = SourceLocation::Current()) const SourceLocation& loc = SourceLocation::Current())
: BasicCrossThreadPersistent(member.Get(), loc) {} : BasicCrossThreadPersistent(member.Get(), loc) {}
@ -230,10 +231,11 @@ class BasicCrossThreadPersistent final : public CrossThreadPersistentBase,
// Assignment from member. // Assignment from member.
template <typename U, typename MemberBarrierPolicy, template <typename U, typename MemberBarrierPolicy,
typename MemberWeaknessTag, typename MemberCheckingPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy,
typename MemberStorageType,
typename = std::enable_if_t<std::is_base_of<T, U>::value>> typename = std::enable_if_t<std::is_base_of<T, U>::value>>
BasicCrossThreadPersistent& operator=( BasicCrossThreadPersistent& operator=(
internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag, internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
MemberCheckingPolicy> MemberCheckingPolicy, MemberStorageType>
member) { member) {
return operator=(member.Get()); return operator=(member.Get());
} }

View File

@ -62,10 +62,10 @@ class HeapConsistency final {
* \returns whether a write barrier is needed and which barrier to invoke. * \returns whether a write barrier is needed and which barrier to invoke.
*/ */
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
static V8_INLINE WriteBarrierType GetWriteBarrierType( static V8_INLINE WriteBarrierType GetWriteBarrierType(
const internal::BasicMember<T, WeaknessTag, WriteBarrierPolicy, const internal::BasicMember<T, WeaknessTag, WriteBarrierPolicy,
CheckingPolicy>& value, CheckingPolicy, StorageType>& value,
WriteBarrierParams& params) { WriteBarrierParams& params) {
return internal::WriteBarrier::GetWriteBarrierType( return internal::WriteBarrier::GetWriteBarrierType(
value.GetRawSlot(), value.GetRawStorage(), params); value.GetRawSlot(), value.GetRawStorage(), params);

View File

@ -225,9 +225,9 @@ class V8_TRIVIAL_ABI RawPointer final {
}; };
#if defined(CPPGC_POINTER_COMPRESSION) #if defined(CPPGC_POINTER_COMPRESSION)
using MemberStorage = CompressedPointer; using DefaultMemberStorage = CompressedPointer;
#else // !defined(CPPGC_POINTER_COMPRESSION) #else // !defined(CPPGC_POINTER_COMPRESSION)
using MemberStorage = RawPointer; using DefaultMemberStorage = RawPointer;
#endif // !defined(CPPGC_POINTER_COMPRESSION) #endif // !defined(CPPGC_POINTER_COMPRESSION)
} // namespace internal } // namespace internal

View File

@ -45,6 +45,7 @@ struct DijkstraWriteBarrierPolicy {
#endif // !CPPGC_SLIM_WRITE_BARRIER #endif // !CPPGC_SLIM_WRITE_BARRIER
} }
template <typename MemberStorage>
V8_INLINE static void AssigningBarrier(const void* slot, V8_INLINE static void AssigningBarrier(const void* slot,
MemberStorage storage) { MemberStorage storage) {
#ifdef CPPGC_SLIM_WRITE_BARRIER #ifdef CPPGC_SLIM_WRITE_BARRIER
@ -79,6 +80,7 @@ struct DijkstraWriteBarrierPolicy {
struct NoWriteBarrierPolicy { struct NoWriteBarrierPolicy {
V8_INLINE static void InitializingBarrier(const void*, const void*) {} V8_INLINE static void InitializingBarrier(const void*, const void*) {}
V8_INLINE static void AssigningBarrier(const void*, const void*) {} V8_INLINE static void AssigningBarrier(const void*, const void*) {}
template <typename MemberStorage>
V8_INLINE static void AssigningBarrier(const void*, MemberStorage) {} V8_INLINE static void AssigningBarrier(const void*, MemberStorage) {}
}; };
@ -207,7 +209,8 @@ template <typename T, typename WeaknessPolicy,
typename CheckingPolicy = DefaultPersistentCheckingPolicy> typename CheckingPolicy = DefaultPersistentCheckingPolicy>
class BasicPersistent; class BasicPersistent;
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy = DefaultMemberCheckingPolicy> typename CheckingPolicy = DefaultMemberCheckingPolicy,
typename StorageType = DefaultMemberStorage>
class BasicMember; class BasicMember;
} // namespace internal } // namespace internal

View File

@ -70,6 +70,7 @@ class V8_EXPORT WriteBarrier final {
static V8_INLINE Type GetWriteBarrierType(const void* slot, const void* value, static V8_INLINE Type GetWriteBarrierType(const void* slot, const void* value,
Params& params); Params& params);
// Returns the required write barrier for a given `slot` and `value`. // Returns the required write barrier for a given `slot` and `value`.
template <typename MemberStorage>
static V8_INLINE Type GetWriteBarrierType(const void* slot, MemberStorage, static V8_INLINE Type GetWriteBarrierType(const void* slot, MemberStorage,
Params& params); Params& params);
// Returns the required write barrier for a given `slot`. // Returns the required write barrier for a given `slot`.
@ -171,7 +172,8 @@ class V8_EXPORT WriteBarrierTypeForCagedHeapPolicy final {
return ValueModeDispatch<value_mode>::Get(slot, value, params, callback); return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
} }
template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback> template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback,
typename MemberStorage>
static V8_INLINE WriteBarrier::Type Get(const void* slot, MemberStorage value, static V8_INLINE WriteBarrier::Type Get(const void* slot, MemberStorage value,
WriteBarrier::Params& params, WriteBarrier::Params& params,
HeapHandleCallback callback) { HeapHandleCallback callback) {
@ -215,7 +217,7 @@ class V8_EXPORT WriteBarrierTypeForCagedHeapPolicy final {
template <> template <>
struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch< struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
WriteBarrier::ValueMode::kValuePresent> { WriteBarrier::ValueMode::kValuePresent> {
template <typename HeapHandleCallback> template <typename HeapHandleCallback, typename MemberStorage>
static V8_INLINE WriteBarrier::Type Get(const void* slot, static V8_INLINE WriteBarrier::Type Get(const void* slot,
MemberStorage storage, MemberStorage storage,
WriteBarrier::Params& params, WriteBarrier::Params& params,
@ -313,11 +315,9 @@ class V8_EXPORT WriteBarrierTypeForNonCagedHeapPolicy final {
} }
template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback> template <WriteBarrier::ValueMode value_mode, typename HeapHandleCallback>
static V8_INLINE WriteBarrier::Type Get(const void* slot, MemberStorage value, static V8_INLINE WriteBarrier::Type Get(const void* slot, RawPointer value,
WriteBarrier::Params& params, WriteBarrier::Params& params,
HeapHandleCallback callback) { HeapHandleCallback callback) {
// `MemberStorage` will always be `RawPointer` for non-caged heap builds.
// Just convert to `void*` in this case.
return ValueModeDispatch<value_mode>::Get(slot, value.Load(), params, return ValueModeDispatch<value_mode>::Get(slot, value.Load(), params,
callback); callback);
} }
@ -391,6 +391,7 @@ WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
} }
// static // static
template <typename MemberStorage>
WriteBarrier::Type WriteBarrier::GetWriteBarrierType( WriteBarrier::Type WriteBarrier::GetWriteBarrierType(
const void* slot, MemberStorage value, WriteBarrier::Params& params) { const void* slot, MemberStorage value, WriteBarrier::Params& params) {
return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(slot, value, return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(slot, value,

View File

@ -28,13 +28,11 @@ namespace internal {
// MemberBase always refers to the object as const object and defers to // MemberBase always refers to the object as const object and defers to
// BasicMember on casting to the right type as needed. // BasicMember on casting to the right type as needed.
template <typename StorageType>
class V8_TRIVIAL_ABI MemberBase { class V8_TRIVIAL_ABI MemberBase {
public: public:
#if defined(CPPGC_POINTER_COMPRESSION) using RawStorage = StorageType;
using RawStorage = CompressedPointer;
#else // !defined(CPPGC_POINTER_COMPRESSION)
using RawStorage = RawPointer;
#endif // !defined(CPPGC_POINTER_COMPRESSION)
protected: protected:
struct AtomicInitializerTag {}; struct AtomicInitializerTag {};
@ -75,16 +73,19 @@ class V8_TRIVIAL_ABI MemberBase {
// The basic class from which all Member classes are 'generated'. // The basic class from which all Member classes are 'generated'.
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
class V8_TRIVIAL_ABI BasicMember final : private MemberBase, class V8_TRIVIAL_ABI BasicMember final : private MemberBase<StorageType>,
private CheckingPolicy { private CheckingPolicy {
using Base = MemberBase<StorageType>;
public: public:
using PointeeType = T; using PointeeType = T;
using RawStorage = typename Base::RawStorage;
V8_INLINE constexpr BasicMember() = default; V8_INLINE constexpr BasicMember() = default;
V8_INLINE constexpr BasicMember(std::nullptr_t) {} // NOLINT V8_INLINE constexpr BasicMember(std::nullptr_t) {} // NOLINT
V8_INLINE BasicMember(SentinelPointer s) : MemberBase(s) {} // NOLINT V8_INLINE BasicMember(SentinelPointer s) : Base(s) {} // NOLINT
V8_INLINE BasicMember(T* raw) : MemberBase(raw) { // NOLINT V8_INLINE BasicMember(T* raw) : Base(raw) { // NOLINT
InitializingWriteBarrier(raw); InitializingWriteBarrier(raw);
this->CheckPointer(Get()); this->CheckPointer(Get());
} }
@ -94,13 +95,13 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
// Atomic ctor. Using the AtomicInitializerTag forces BasicMember to // Atomic ctor. Using the AtomicInitializerTag forces BasicMember to
// initialize using atomic assignments. This is required for preventing // initialize using atomic assignments. This is required for preventing
// data races with concurrent marking. // data races with concurrent marking.
using AtomicInitializerTag = MemberBase::AtomicInitializerTag; using AtomicInitializerTag = typename Base::AtomicInitializerTag;
V8_INLINE BasicMember(std::nullptr_t, AtomicInitializerTag atomic) V8_INLINE BasicMember(std::nullptr_t, AtomicInitializerTag atomic)
: MemberBase(nullptr, atomic) {} : Base(nullptr, atomic) {}
V8_INLINE BasicMember(SentinelPointer s, AtomicInitializerTag atomic) V8_INLINE BasicMember(SentinelPointer s, AtomicInitializerTag atomic)
: MemberBase(s, atomic) {} : Base(s, atomic) {}
V8_INLINE BasicMember(T* raw, AtomicInitializerTag atomic) V8_INLINE BasicMember(T* raw, AtomicInitializerTag atomic)
: MemberBase(raw, atomic) { : Base(raw, atomic) {
InitializingWriteBarrier(raw); InitializingWriteBarrier(raw);
this->CheckPointer(Get()); this->CheckPointer(Get());
} }
@ -119,7 +120,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
std::enable_if_t<internal::IsDecayedSameV<T, U>>* = nullptr> std::enable_if_t<internal::IsDecayedSameV<T, U>>* = nullptr>
V8_INLINE BasicMember( // NOLINT V8_INLINE BasicMember( // NOLINT
const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
OtherCheckingPolicy>& other) OtherCheckingPolicy, StorageType>& other)
: BasicMember(other.GetRawStorage()) {} : BasicMember(other.GetRawStorage()) {}
template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag, template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
@ -127,7 +128,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
std::enable_if_t<internal::IsStrictlyBaseOfV<T, U>>* = nullptr> std::enable_if_t<internal::IsStrictlyBaseOfV<T, U>>* = nullptr>
V8_INLINE BasicMember( // NOLINT V8_INLINE BasicMember( // NOLINT
const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
OtherCheckingPolicy>& other) OtherCheckingPolicy, StorageType>& other)
: BasicMember(other.Get()) {} : BasicMember(other.Get()) {}
// Move ctor. // Move ctor.
@ -142,8 +143,9 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag, template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
typename OtherCheckingPolicy, typename OtherCheckingPolicy,
std::enable_if_t<internal::IsDecayedSameV<T, U>>* = nullptr> std::enable_if_t<internal::IsDecayedSameV<T, U>>* = nullptr>
V8_INLINE BasicMember(BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, V8_INLINE BasicMember(
OtherCheckingPolicy>&& other) noexcept BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
StorageType>&& other) noexcept
: BasicMember(other.GetRawStorage()) { : BasicMember(other.GetRawStorage()) {
other.Clear(); other.Clear();
} }
@ -151,8 +153,9 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag, template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag,
typename OtherCheckingPolicy, typename OtherCheckingPolicy,
std::enable_if_t<internal::IsStrictlyBaseOfV<T, U>>* = nullptr> std::enable_if_t<internal::IsStrictlyBaseOfV<T, U>>* = nullptr>
V8_INLINE BasicMember(BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, V8_INLINE BasicMember(
OtherCheckingPolicy>&& other) noexcept BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
StorageType>&& other) noexcept
: BasicMember(other.Get()) { : BasicMember(other.Get()) {
other.Clear(); other.Clear();
} }
@ -179,7 +182,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
typename OtherCheckingPolicy> typename OtherCheckingPolicy>
V8_INLINE BasicMember& operator=( V8_INLINE BasicMember& operator=(
const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy,
OtherCheckingPolicy>& other) { OtherCheckingPolicy, StorageType>& other) {
if constexpr (internal::IsDecayedSameV<T, U>) { if constexpr (internal::IsDecayedSameV<T, U>) {
return operator=(other.GetRawStorage()); return operator=(other.GetRawStorage());
} else { } else {
@ -201,8 +204,8 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy, template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy,
typename OtherCheckingPolicy> typename OtherCheckingPolicy>
V8_INLINE BasicMember& operator=( V8_INLINE BasicMember& operator=(
BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, OtherCheckingPolicy,
OtherCheckingPolicy>&& other) noexcept { StorageType>&& other) noexcept {
if constexpr (internal::IsDecayedSameV<T, U>) { if constexpr (internal::IsDecayedSameV<T, U>) {
operator=(other.GetRawStorage()); operator=(other.GetRawStorage());
} else { } else {
@ -226,7 +229,7 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
} }
V8_INLINE BasicMember& operator=(T* other) { V8_INLINE BasicMember& operator=(T* other) {
SetRawAtomic(other); Base::SetRawAtomic(other);
AssigningWriteBarrier(other); AssigningWriteBarrier(other);
this->CheckPointer(Get()); this->CheckPointer(Get());
return *this; return *this;
@ -237,20 +240,20 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
return *this; return *this;
} }
V8_INLINE BasicMember& operator=(SentinelPointer s) { V8_INLINE BasicMember& operator=(SentinelPointer s) {
SetRawAtomic(s); Base::SetRawAtomic(s);
return *this; return *this;
} }
template <typename OtherWeaknessTag, typename OtherBarrierPolicy, template <typename OtherWeaknessTag, typename OtherBarrierPolicy,
typename OtherCheckingPolicy> typename OtherCheckingPolicy>
V8_INLINE void Swap(BasicMember<T, OtherWeaknessTag, OtherBarrierPolicy, V8_INLINE void Swap(BasicMember<T, OtherWeaknessTag, OtherBarrierPolicy,
OtherCheckingPolicy>& other) { OtherCheckingPolicy, StorageType>& other) {
auto tmp = GetRawStorage(); auto tmp = GetRawStorage();
*this = other; *this = other;
other = tmp; other = tmp;
} }
V8_INLINE explicit operator bool() const { return !IsCleared(); } V8_INLINE explicit operator bool() const { return !Base::IsCleared(); }
V8_INLINE operator T*() const { return Get(); } V8_INLINE operator T*() const { return Get(); }
V8_INLINE T* operator->() const { return Get(); } V8_INLINE T* operator->() const { return Get(); }
V8_INLINE T& operator*() const { return *Get(); } V8_INLINE T& operator*() const { return *Get(); }
@ -264,10 +267,12 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
// The const_cast below removes the constness from MemberBase storage. The // The const_cast below removes the constness from MemberBase storage. The
// following static_cast re-adds any constness if specified through the // following static_cast re-adds any constness if specified through the
// user-visible template parameter T. // user-visible template parameter T.
return static_cast<T*>(const_cast<void*>(MemberBase::GetRaw())); return static_cast<T*>(const_cast<void*>(Base::GetRaw()));
} }
V8_INLINE void Clear() { SetRawStorageAtomic(RawStorage{}); } V8_INLINE void Clear() {
Base::SetRawStorageAtomic(RawStorage{});
}
V8_INLINE T* Release() { V8_INLINE T* Release() {
T* result = Get(); T* result = Get();
@ -276,41 +281,42 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
} }
V8_INLINE const T** GetSlotForTesting() const { V8_INLINE const T** GetSlotForTesting() const {
return reinterpret_cast<const T**>(GetRawSlot()); return reinterpret_cast<const T**>(Base::GetRawSlot());
} }
V8_INLINE RawStorage GetRawStorage() const { V8_INLINE RawStorage GetRawStorage() const {
return MemberBase::GetRawStorage(); return Base::GetRawStorage();
} }
private: private:
V8_INLINE explicit BasicMember(RawStorage raw) : MemberBase(raw) { V8_INLINE explicit BasicMember(RawStorage raw) : Base(raw) {
InitializingWriteBarrier(Get()); InitializingWriteBarrier(Get());
this->CheckPointer(Get()); this->CheckPointer(Get());
} }
V8_INLINE BasicMember& operator=(RawStorage other) { V8_INLINE BasicMember& operator=(RawStorage other) {
SetRawStorageAtomic(other); Base::SetRawStorageAtomic(other);
AssigningWriteBarrier(); AssigningWriteBarrier();
this->CheckPointer(Get()); this->CheckPointer(Get());
return *this; return *this;
} }
V8_INLINE const T* GetRawAtomic() const { V8_INLINE const T* GetRawAtomic() const {
return static_cast<const T*>(MemberBase::GetRawAtomic()); return static_cast<const T*>(Base::GetRawAtomic());
} }
V8_INLINE void InitializingWriteBarrier(T* value) const { V8_INLINE void InitializingWriteBarrier(T* value) const {
WriteBarrierPolicy::InitializingBarrier(GetRawSlot(), value); WriteBarrierPolicy::InitializingBarrier(Base::GetRawSlot(), value);
} }
V8_INLINE void AssigningWriteBarrier(T* value) const { V8_INLINE void AssigningWriteBarrier(T* value) const {
WriteBarrierPolicy::AssigningBarrier(GetRawSlot(), value); WriteBarrierPolicy::AssigningBarrier(Base::GetRawSlot(), value);
} }
V8_INLINE void AssigningWriteBarrier() const { V8_INLINE void AssigningWriteBarrier() const {
WriteBarrierPolicy::AssigningBarrier(GetRawSlot(), GetRawStorage()); WriteBarrierPolicy::AssigningBarrier(Base::GetRawSlot(),
Base::GetRawStorage());
} }
V8_INLINE void ClearFromGC() const { MemberBase::ClearFromGC(); } V8_INLINE void ClearFromGC() const { Base::ClearFromGC(); }
V8_INLINE T* GetFromGC() const { return Get(); } V8_INLINE T* GetFromGC() const { return Get(); }
@ -319,19 +325,20 @@ class V8_TRIVIAL_ABI BasicMember final : private MemberBase,
template <typename U> template <typename U>
friend struct cppgc::TraceTrait; friend struct cppgc::TraceTrait;
template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1, template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
typename CheckingPolicy1> typename CheckingPolicy1, typename StorageType1>
friend class BasicMember; friend class BasicMember;
}; };
// Member equality operators. // Member equality operators.
template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1, template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
typename CheckingPolicy1, typename T2, typename WeaknessTag2, typename CheckingPolicy1, typename T2, typename WeaknessTag2,
typename WriteBarrierPolicy2, typename CheckingPolicy2> typename WriteBarrierPolicy2, typename CheckingPolicy2,
typename StorageType>
V8_INLINE bool operator==( V8_INLINE bool operator==(
const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1>& const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
member1, StorageType>& member1,
const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2>& const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
member2) { StorageType>& member2) {
if constexpr (internal::IsDecayedSameV<T1, T2>) { if constexpr (internal::IsDecayedSameV<T1, T2>) {
// Check compressed pointers if types are the same. // Check compressed pointers if types are the same.
return member1.GetRawStorage() == member2.GetRawStorage(); return member1.GetRawStorage() == member2.GetRawStorage();
@ -345,31 +352,32 @@ V8_INLINE bool operator==(
template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1, template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
typename CheckingPolicy1, typename T2, typename WeaknessTag2, typename CheckingPolicy1, typename T2, typename WeaknessTag2,
typename WriteBarrierPolicy2, typename CheckingPolicy2> typename WriteBarrierPolicy2, typename CheckingPolicy2,
typename StorageType>
V8_INLINE bool operator!=( V8_INLINE bool operator!=(
const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1>& const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
member1, StorageType>& member1,
const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2>& const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
member2) { StorageType>& member2) {
return !(member1 == member2); return !(member1 == member2);
} }
// Equality with raw pointers. // Equality with raw pointers.
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy, typename U> typename CheckingPolicy, typename StorageType, typename U>
V8_INLINE bool operator==(const BasicMember<T, WeaknessTag, WriteBarrierPolicy, V8_INLINE bool operator==(
CheckingPolicy>& member, const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
U* raw) { StorageType>& member,
U* raw) {
// Never allow comparison with erased pointers. // Never allow comparison with erased pointers.
static_assert(!internal::IsDecayedSameV<void, U>); static_assert(!internal::IsDecayedSameV<void, U>);
if constexpr (internal::IsDecayedSameV<T, U>) { if constexpr (internal::IsDecayedSameV<T, U>) {
// Check compressed pointers if types are the same. // Check compressed pointers if types are the same.
return member.GetRawStorage() == MemberBase::RawStorage(raw); return member.GetRawStorage() == StorageType(raw);
} else if constexpr (internal::IsStrictlyBaseOfV<T, U>) { } else if constexpr (internal::IsStrictlyBaseOfV<T, U>) {
// Cast the raw pointer to T, which may adjust the pointer. // Cast the raw pointer to T, which may adjust the pointer.
return member.GetRawStorage() == return member.GetRawStorage() == StorageType(static_cast<T*>(raw));
MemberBase::RawStorage(static_cast<T*>(raw));
} else { } else {
// Otherwise, decompressed the member. // Otherwise, decompressed the member.
return member.Get() == raw; return member.Get() == raw;
@ -377,104 +385,112 @@ V8_INLINE bool operator==(const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
} }
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy, typename U> typename CheckingPolicy, typename StorageType, typename U>
V8_INLINE bool operator!=(const BasicMember<T, WeaknessTag, WriteBarrierPolicy, V8_INLINE bool operator!=(
CheckingPolicy>& member, const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
U* raw) { StorageType>& member,
U* raw) {
return !(member == raw); return !(member == raw);
} }
template <typename T, typename U, typename WeaknessTag, template <typename T, typename U, typename WeaknessTag,
typename WriteBarrierPolicy, typename CheckingPolicy> typename WriteBarrierPolicy, typename CheckingPolicy,
V8_INLINE bool operator==(T* raw, typename StorageType>
const BasicMember<U, WeaknessTag, WriteBarrierPolicy, V8_INLINE bool operator==(
CheckingPolicy>& member) { T* raw, const BasicMember<U, WeaknessTag, WriteBarrierPolicy,
CheckingPolicy, StorageType>& member) {
return member == raw; return member == raw;
} }
template <typename T, typename U, typename WeaknessTag, template <typename T, typename U, typename WeaknessTag,
typename WriteBarrierPolicy, typename CheckingPolicy> typename WriteBarrierPolicy, typename CheckingPolicy,
V8_INLINE bool operator!=(T* raw, typename StorageType>
const BasicMember<U, WeaknessTag, WriteBarrierPolicy, V8_INLINE bool operator!=(
CheckingPolicy>& member) { T* raw, const BasicMember<U, WeaknessTag, WriteBarrierPolicy,
CheckingPolicy, StorageType>& member) {
return !(raw == member); return !(raw == member);
} }
// Equality with sentinel. // Equality with sentinel.
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator==(const BasicMember<T, WeaknessTag, WriteBarrierPolicy, V8_INLINE bool operator==(
CheckingPolicy>& member, const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
SentinelPointer) { StorageType>& member,
SentinelPointer) {
return member.GetRawStorage().IsSentinel(); return member.GetRawStorage().IsSentinel();
} }
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator!=(const BasicMember<T, WeaknessTag, WriteBarrierPolicy, V8_INLINE bool operator!=(
CheckingPolicy>& member, const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
SentinelPointer s) { StorageType>& member,
SentinelPointer s) {
return !(member == s); return !(member == s);
} }
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator==(SentinelPointer s, V8_INLINE bool operator==(
const BasicMember<T, WeaknessTag, WriteBarrierPolicy, SentinelPointer s, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
CheckingPolicy>& member) { CheckingPolicy, StorageType>& member) {
return member == s; return member == s;
} }
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator!=(SentinelPointer s, V8_INLINE bool operator!=(
const BasicMember<T, WeaknessTag, WriteBarrierPolicy, SentinelPointer s, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
CheckingPolicy>& member) { CheckingPolicy, StorageType>& member) {
return !(s == member); return !(s == member);
} }
// Equality with nullptr. // Equality with nullptr.
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator==(const BasicMember<T, WeaknessTag, WriteBarrierPolicy, V8_INLINE bool operator==(
CheckingPolicy>& member, const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
std::nullptr_t) { StorageType>& member,
std::nullptr_t) {
return !static_cast<bool>(member); return !static_cast<bool>(member);
} }
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator!=(const BasicMember<T, WeaknessTag, WriteBarrierPolicy, V8_INLINE bool operator!=(
CheckingPolicy>& member, const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
std::nullptr_t n) { StorageType>& member,
std::nullptr_t n) {
return !(member == n); return !(member == n);
} }
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator==(std::nullptr_t n, V8_INLINE bool operator==(
const BasicMember<T, WeaknessTag, WriteBarrierPolicy, std::nullptr_t n, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
CheckingPolicy>& member) { CheckingPolicy, StorageType>& member) {
return member == n; return member == n;
} }
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
V8_INLINE bool operator!=(std::nullptr_t n, V8_INLINE bool operator!=(
const BasicMember<T, WeaknessTag, WriteBarrierPolicy, std::nullptr_t n, const BasicMember<T, WeaknessTag, WriteBarrierPolicy,
CheckingPolicy>& member) { CheckingPolicy, StorageType>& member) {
return !(n == member); return !(n == member);
} }
// Relational operators. // Relational operators.
template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1, template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
typename CheckingPolicy1, typename T2, typename WeaknessTag2, typename CheckingPolicy1, typename T2, typename WeaknessTag2,
typename WriteBarrierPolicy2, typename CheckingPolicy2> typename WriteBarrierPolicy2, typename CheckingPolicy2,
typename StorageType>
V8_INLINE bool operator<( V8_INLINE bool operator<(
const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1>& const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
member1, StorageType>& member1,
const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2>& const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
member2) { StorageType>& member2) {
static_assert( static_assert(
internal::IsDecayedSameV<T1, T2>, internal::IsDecayedSameV<T1, T2>,
"Comparison works only for same pointer type modulo cv-qualifiers"); "Comparison works only for same pointer type modulo cv-qualifiers");
@ -483,12 +499,13 @@ V8_INLINE bool operator<(
template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1, template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
typename CheckingPolicy1, typename T2, typename WeaknessTag2, typename CheckingPolicy1, typename T2, typename WeaknessTag2,
typename WriteBarrierPolicy2, typename CheckingPolicy2> typename WriteBarrierPolicy2, typename CheckingPolicy2,
typename StorageType>
V8_INLINE bool operator<=( V8_INLINE bool operator<=(
const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1>& const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
member1, StorageType>& member1,
const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2>& const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
member2) { StorageType>& member2) {
static_assert( static_assert(
internal::IsDecayedSameV<T1, T2>, internal::IsDecayedSameV<T1, T2>,
"Comparison works only for same pointer type modulo cv-qualifiers"); "Comparison works only for same pointer type modulo cv-qualifiers");
@ -497,12 +514,13 @@ V8_INLINE bool operator<=(
template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1, template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
typename CheckingPolicy1, typename T2, typename WeaknessTag2, typename CheckingPolicy1, typename T2, typename WeaknessTag2,
typename WriteBarrierPolicy2, typename CheckingPolicy2> typename WriteBarrierPolicy2, typename CheckingPolicy2,
typename StorageType>
V8_INLINE bool operator>( V8_INLINE bool operator>(
const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1>& const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
member1, StorageType>& member1,
const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2>& const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
member2) { StorageType>& member2) {
static_assert( static_assert(
internal::IsDecayedSameV<T1, T2>, internal::IsDecayedSameV<T1, T2>,
"Comparison works only for same pointer type modulo cv-qualifiers"); "Comparison works only for same pointer type modulo cv-qualifiers");
@ -511,21 +529,23 @@ V8_INLINE bool operator>(
template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1, template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
typename CheckingPolicy1, typename T2, typename WeaknessTag2, typename CheckingPolicy1, typename T2, typename WeaknessTag2,
typename WriteBarrierPolicy2, typename CheckingPolicy2> typename WriteBarrierPolicy2, typename CheckingPolicy2,
typename StorageType>
V8_INLINE bool operator>=( V8_INLINE bool operator>=(
const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1>& const BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1,
member1, StorageType>& member1,
const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2>& const BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2,
member2) { StorageType>& member2) {
static_assert( static_assert(
internal::IsDecayedSameV<T1, T2>, internal::IsDecayedSameV<T1, T2>,
"Comparison works only for same pointer type modulo cv-qualifiers"); "Comparison works only for same pointer type modulo cv-qualifiers");
return member1.GetRawStorage() >= member2.GetRawStorage(); return member1.GetRawStorage() >= member2.GetRawStorage();
} }
template <typename T, typename WriteBarrierPolicy, typename CheckingPolicy> template <typename T, typename WriteBarrierPolicy, typename CheckingPolicy,
struct IsWeak< typename StorageType>
internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy, CheckingPolicy>> struct IsWeak<internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy,
CheckingPolicy, StorageType>>
: std::true_type {}; : std::true_type {};
} // namespace internal } // namespace internal
@ -536,8 +556,9 @@ struct IsWeak<
* trace method. * trace method.
*/ */
template <typename T> template <typename T>
using Member = internal::BasicMember<T, internal::StrongMemberTag, using Member = internal::BasicMember<
internal::DijkstraWriteBarrierPolicy>; T, internal::StrongMemberTag, internal::DijkstraWriteBarrierPolicy,
internal::DefaultMemberCheckingPolicy, internal::DefaultMemberStorage>;
/** /**
* WeakMember is similar to Member in that it is used to point to other garbage * WeakMember is similar to Member in that it is used to point to other garbage
@ -548,8 +569,9 @@ using Member = internal::BasicMember<T, internal::StrongMemberTag,
* will automatically be set to null. * will automatically be set to null.
*/ */
template <typename T> template <typename T>
using WeakMember = internal::BasicMember<T, internal::WeakMemberTag, using WeakMember = internal::BasicMember<
internal::DijkstraWriteBarrierPolicy>; T, internal::WeakMemberTag, internal::DijkstraWriteBarrierPolicy,
internal::DefaultMemberCheckingPolicy, internal::DefaultMemberStorage>;
/** /**
* UntracedMember is a pointer to an on-heap object that is not traced for some * UntracedMember is a pointer to an on-heap object that is not traced for some
@ -558,8 +580,22 @@ using WeakMember = internal::BasicMember<T, internal::WeakMemberTag,
* must be kept alive through other means. * must be kept alive through other means.
*/ */
template <typename T> template <typename T>
using UntracedMember = internal::BasicMember<T, internal::UntracedMemberTag, using UntracedMember = internal::BasicMember<
internal::NoWriteBarrierPolicy>; T, internal::UntracedMemberTag, internal::NoWriteBarrierPolicy,
internal::DefaultMemberCheckingPolicy, internal::DefaultMemberStorage>;
namespace subtle {
/**
* UncompressedMember. Use with care in hot paths that would otherwise cause
* many decompression cycles.
*/
template <typename T>
using UncompressedMember = internal::BasicMember<
T, internal::StrongMemberTag, internal::DijkstraWriteBarrierPolicy,
internal::DefaultMemberCheckingPolicy, internal::RawPointer>;
} // namespace subtle
} // namespace cppgc } // namespace cppgc

View File

@ -114,11 +114,12 @@ class BasicPersistent final : public PersistentBase,
// Constructor from member. // Constructor from member.
template <typename U, typename MemberBarrierPolicy, template <typename U, typename MemberBarrierPolicy,
typename MemberWeaknessTag, typename MemberCheckingPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy,
typename MemberStorageType,
typename = std::enable_if_t<std::is_base_of<T, U>::value>> typename = std::enable_if_t<std::is_base_of<T, U>::value>>
BasicPersistent( BasicPersistent(const internal::BasicMember<
const internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag, U, MemberBarrierPolicy, MemberWeaknessTag,
MemberCheckingPolicy>& member, MemberCheckingPolicy, MemberStorageType>& member,
const SourceLocation& loc = SourceLocation::Current()) const SourceLocation& loc = SourceLocation::Current())
: BasicPersistent(member.Get(), loc) {} : BasicPersistent(member.Get(), loc) {}
~BasicPersistent() { Clear(); } ~BasicPersistent() { Clear(); }
@ -154,10 +155,12 @@ class BasicPersistent final : public PersistentBase,
// Assignment from member. // Assignment from member.
template <typename U, typename MemberBarrierPolicy, template <typename U, typename MemberBarrierPolicy,
typename MemberWeaknessTag, typename MemberCheckingPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy,
typename MemberStorageType,
typename = std::enable_if_t<std::is_base_of<T, U>::value>> typename = std::enable_if_t<std::is_base_of<T, U>::value>>
BasicPersistent& operator=( BasicPersistent& operator=(
const internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag, const internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag,
MemberCheckingPolicy>& member) { MemberCheckingPolicy, MemberStorageType>&
member) {
return operator=(member.Get()); return operator=(member.Get());
} }
@ -286,36 +289,39 @@ bool operator!=(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1,
template <typename T1, typename PersistentWeaknessPolicy, template <typename T1, typename PersistentWeaknessPolicy,
typename PersistentLocationPolicy, typename PersistentCheckingPolicy, typename PersistentLocationPolicy, typename PersistentCheckingPolicy,
typename T2, typename MemberWriteBarrierPolicy, typename T2, typename MemberWriteBarrierPolicy,
typename MemberWeaknessTag, typename MemberCheckingPolicy> typename MemberWeaknessTag, typename MemberCheckingPolicy,
typename MemberStorageType>
bool operator==( bool operator==(
const BasicPersistent<T1, PersistentWeaknessPolicy, const BasicPersistent<T1, PersistentWeaknessPolicy,
PersistentLocationPolicy, PersistentCheckingPolicy>& PersistentLocationPolicy, PersistentCheckingPolicy>&
p, p,
const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
MemberCheckingPolicy>& m) { MemberCheckingPolicy, MemberStorageType>& m) {
return p.Get() == m.Get(); return p.Get() == m.Get();
} }
template <typename T1, typename PersistentWeaknessPolicy, template <typename T1, typename PersistentWeaknessPolicy,
typename PersistentLocationPolicy, typename PersistentCheckingPolicy, typename PersistentLocationPolicy, typename PersistentCheckingPolicy,
typename T2, typename MemberWriteBarrierPolicy, typename T2, typename MemberWriteBarrierPolicy,
typename MemberWeaknessTag, typename MemberCheckingPolicy> typename MemberWeaknessTag, typename MemberCheckingPolicy,
typename MemberStorageType>
bool operator!=( bool operator!=(
const BasicPersistent<T1, PersistentWeaknessPolicy, const BasicPersistent<T1, PersistentWeaknessPolicy,
PersistentLocationPolicy, PersistentCheckingPolicy>& PersistentLocationPolicy, PersistentCheckingPolicy>&
p, p,
const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
MemberCheckingPolicy>& m) { MemberCheckingPolicy, MemberStorageType>& m) {
return !(p == m); return !(p == m);
} }
template <typename T1, typename MemberWriteBarrierPolicy, template <typename T1, typename MemberWriteBarrierPolicy,
typename MemberWeaknessTag, typename MemberCheckingPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy,
typename T2, typename PersistentWeaknessPolicy, typename MemberStorageType, typename T2,
typename PersistentLocationPolicy, typename PersistentCheckingPolicy> typename PersistentWeaknessPolicy, typename PersistentLocationPolicy,
typename PersistentCheckingPolicy>
bool operator==( bool operator==(
const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
MemberCheckingPolicy>& m, MemberCheckingPolicy, MemberStorageType>& m,
const BasicPersistent<T1, PersistentWeaknessPolicy, const BasicPersistent<T1, PersistentWeaknessPolicy,
PersistentLocationPolicy, PersistentCheckingPolicy>& PersistentLocationPolicy, PersistentCheckingPolicy>&
p) { p) {
@ -324,11 +330,12 @@ bool operator==(
template <typename T1, typename MemberWriteBarrierPolicy, template <typename T1, typename MemberWriteBarrierPolicy,
typename MemberWeaknessTag, typename MemberCheckingPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy,
typename T2, typename PersistentWeaknessPolicy, typename MemberStorageType, typename T2,
typename PersistentLocationPolicy, typename PersistentCheckingPolicy> typename PersistentWeaknessPolicy, typename PersistentLocationPolicy,
typename PersistentCheckingPolicy>
bool operator!=( bool operator!=(
const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy,
MemberCheckingPolicy>& m, MemberCheckingPolicy, MemberStorageType>& m,
const BasicPersistent<T1, PersistentWeaknessPolicy, const BasicPersistent<T1, PersistentWeaknessPolicy,
PersistentLocationPolicy, PersistentCheckingPolicy>& PersistentLocationPolicy, PersistentCheckingPolicy>&
p) { p) {

View File

@ -16,7 +16,7 @@ class Visitor;
namespace internal { namespace internal {
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy> typename CheckingPolicy, typename StorageType>
class BasicMember; class BasicMember;
struct DijkstraWriteBarrierPolicy; struct DijkstraWriteBarrierPolicy;
struct NoWriteBarrierPolicy; struct NoWriteBarrierPolicy;
@ -126,9 +126,10 @@ template <typename BasicMemberCandidate, typename WeaknessTag,
typename WriteBarrierPolicy> typename WriteBarrierPolicy>
struct IsSubclassOfBasicMemberTemplate { struct IsSubclassOfBasicMemberTemplate {
private: private:
template <typename T, typename CheckingPolicy> template <typename T, typename CheckingPolicy, typename StorageType>
static std::true_type SubclassCheck( static std::true_type SubclassCheck(
BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy>*); BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
StorageType>*);
static std::false_type SubclassCheck(...); static std::false_type SubclassCheck(...);
public: public:

View File

@ -99,6 +99,20 @@ class V8_EXPORT Visitor {
&HandleWeak<WeakMember<T>>, &weak_member); &HandleWeak<WeakMember<T>>, &weak_member);
} }
#if defined(CPPGC_POINTER_COMPRESSION)
/**
* Trace method for UncompressedMember.
*
* \param member UncompressedMember reference retaining an object.
*/
template <typename T>
void Trace(const subtle::UncompressedMember<T>& member) {
const T* value = member.GetRawAtomic();
CPPGC_DCHECK(value != kSentinelPointer);
TraceImpl(value);
}
#endif // defined(CPPGC_POINTER_COMPRESSION)
/** /**
* Trace method for inlined objects that are not allocated themselves but * Trace method for inlined objects that are not allocated themselves but
* otherwise follow managed heap layout and have a Trace() method. * otherwise follow managed heap layout and have a Trace() method.

View File

@ -21,20 +21,21 @@ uintptr_t CageBaseGlobal::g_base_ = CageBaseGlobal::kLowerHalfWordMask;
#if defined(CPPGC_POINTER_COMPRESSION) #if defined(CPPGC_POINTER_COMPRESSION)
extern "C" V8_DONT_STRIP_SYMBOL V8_EXPORT_PRIVATE void* extern "C" V8_DONT_STRIP_SYMBOL V8_EXPORT_PRIVATE void*
_cppgc_internal_Decompress_Compressed_Pointer(uint32_t cmprsd) { _cppgc_internal_Decompress_Compressed_Pointer(uint32_t cmprsd) {
return MemberStorage::Decompress(cmprsd); return CompressedPointer::Decompress(cmprsd);
} }
#endif // !defined(CPPGC_POINTER_COMPRESSION) #endif // !defined(CPPGC_POINTER_COMPRESSION)
class MemberDebugHelper final { class MemberDebugHelper final {
public: public:
static void* PrintUncompressed(MemberBase* m) { static void* Uncompress(MemberBase<DefaultMemberStorage>* m) {
return const_cast<void*>(m->GetRaw()); return const_cast<void*>(m->GetRaw());
} }
}; };
extern "C" V8_DONT_STRIP_SYMBOL V8_EXPORT_PRIVATE void* extern "C" V8_DONT_STRIP_SYMBOL V8_EXPORT_PRIVATE void*
_cppgc_internal_Print_Member(MemberBase* m) { _cppgc_internal_Uncompress_Member(void* m) {
return MemberDebugHelper::PrintUncompressed(m); return MemberDebugHelper::Uncompress(
static_cast<MemberBase<DefaultMemberStorage>*>(m));
} }
} // namespace internal } // namespace internal

View File

@ -68,7 +68,7 @@ struct CustomWriteBarrierPolicy {
static void AssigningBarrier(const void* slot, const void* value) { static void AssigningBarrier(const void* slot, const void* value) {
++AssigningWriteBarriersTriggered; ++AssigningWriteBarriersTriggered;
} }
static void AssigningBarrier(const void* slot, MemberStorage) { static void AssigningBarrier(const void* slot, DefaultMemberStorage) {
++AssigningWriteBarriersTriggered; ++AssigningWriteBarriersTriggered;
} }
}; };

View File

@ -297,7 +297,7 @@ class CppGCMemberPrinter(object):
def to_string(self): def to_string(self):
pointer = gdb.parse_and_eval( pointer = gdb.parse_and_eval(
"_cppgc_internal_Print_Member((cppgc::internal::MemberBase*){})".format( "_cppgc_internal_Uncompress_Member((void*){})".format(
self.val.address)) self.val.address))
return "{}Member<{}> pointing to {}".format( return "{}Member<{}> pointing to {}".format(
'' if self.category is None else self.category, self.pointee_type, '' if self.category is None else self.category, self.pointee_type,