summaryrefslogtreecommitdiffstats
path: root/chromium/v8/include/cppgc/member.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/include/cppgc/member.h')
-rw-r--r--chromium/v8/include/cppgc/member.h54
1 files changed, 37 insertions, 17 deletions
diff --git a/chromium/v8/include/cppgc/member.h b/chromium/v8/include/cppgc/member.h
index a183edb96fd..22c1adc0af7 100644
--- a/chromium/v8/include/cppgc/member.h
+++ b/chromium/v8/include/cppgc/member.h
@@ -19,19 +19,43 @@ class Visitor;
namespace internal {
+class MemberBase {
+ protected:
+ MemberBase() = default;
+ explicit MemberBase(void* value) : raw_(value) {}
+
+ void* const* GetRawSlot() const { return &raw_; }
+ void* GetRaw() const { return raw_; }
+ void SetRaw(void* value) { raw_ = value; }
+
+ void* GetRawAtomic() const {
+ return reinterpret_cast<const std::atomic<void*>*>(&raw_)->load(
+ std::memory_order_relaxed);
+ }
+ void SetRawAtomic(void* value) {
+ reinterpret_cast<std::atomic<void*>*>(&raw_)->store(
+ value, std::memory_order_relaxed);
+ }
+
+ void ClearFromGC() const { raw_ = nullptr; }
+
+ private:
+ mutable void* raw_ = nullptr;
+};
+
// The basic class from which all Member classes are 'generated'.
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy>
-class BasicMember : private CheckingPolicy {
+class BasicMember final : private MemberBase, private CheckingPolicy {
public:
using PointeeType = T;
constexpr BasicMember() = default;
constexpr BasicMember(std::nullptr_t) {} // NOLINT
- BasicMember(SentinelPointer s) : raw_(s) {} // NOLINT
- BasicMember(T* raw) : raw_(raw) { // NOLINT
+ BasicMember(SentinelPointer s) : MemberBase(s) {} // NOLINT
+ BasicMember(T* raw) : MemberBase(raw) { // NOLINT
InitializingWriteBarrier();
- this->CheckPointer(raw_);
+ this->CheckPointer(Get());
}
BasicMember(T& raw) : BasicMember(&raw) {} // NOLINT
BasicMember(const BasicMember& other) : BasicMember(other.Get()) {}
@@ -106,9 +130,12 @@ class BasicMember : private CheckingPolicy {
T* operator->() const { return Get(); }
T& operator*() const { return *Get(); }
- T* Get() const {
+ // CFI cast exemption to allow passing SentinelPointer through T* and support
+ // heterogeneous assignments between different Member and Persistent handles
+ // based on their actual types.
+ V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const {
// Executed by the mutator, hence non atomic load.
- return raw_;
+ return static_cast<T*>(MemberBase::GetRaw());
}
void Clear() { SetRawAtomic(nullptr); }
@@ -120,25 +147,18 @@ class BasicMember : private CheckingPolicy {
}
private:
- void SetRawAtomic(T* raw) {
- reinterpret_cast<std::atomic<T*>*>(&raw_)->store(raw,
- std::memory_order_relaxed);
- }
T* GetRawAtomic() const {
- return reinterpret_cast<const std::atomic<T*>*>(&raw_)->load(
- std::memory_order_relaxed);
+ return static_cast<T*>(MemberBase::GetRawAtomic());
}
void InitializingWriteBarrier() const {
- WriteBarrierPolicy::InitializingBarrier(
- reinterpret_cast<const void*>(&raw_), static_cast<const void*>(raw_));
+ WriteBarrierPolicy::InitializingBarrier(GetRawSlot(), GetRaw());
}
void AssigningWriteBarrier() const {
- WriteBarrierPolicy::AssigningBarrier(reinterpret_cast<const void*>(&raw_),
- static_cast<const void*>(raw_));
+ WriteBarrierPolicy::AssigningBarrier(GetRawSlot(), GetRaw());
}
- T* raw_ = nullptr;
+ void ClearFromGC() const { MemberBase::ClearFromGC(); }
friend class cppgc::Visitor;
};