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:
parent
fa303fcd0b
commit
02afcd6b05
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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:
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user