| // Copyright 2020 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_ |
| #define INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_ |
| |
| #include <cstdint> |
| #include <type_traits> |
| |
| #include "cppgc/internal/write-barrier.h" |
| #include "cppgc/source-location.h" |
| #include "v8config.h" // NOLINT(build/include_directory) |
| |
| namespace cppgc { |
| namespace internal { |
| |
| class PersistentRegion; |
| |
| // Tags to distinguish between strong and weak member types. |
| class StrongMemberTag; |
| class WeakMemberTag; |
| class UntracedMemberTag; |
| |
| struct DijkstraWriteBarrierPolicy { |
| static void InitializingBarrier(const void*, const void*) { |
| // Since in initializing writes the source object is always white, having no |
| // barrier doesn't break the tri-color invariant. |
| } |
| static void AssigningBarrier(const void* slot, const void* value) { |
| WriteBarrier::MarkingBarrier(slot, value); |
| } |
| }; |
| |
| struct NoWriteBarrierPolicy { |
| static void InitializingBarrier(const void*, const void*) {} |
| static void AssigningBarrier(const void*, const void*) {} |
| }; |
| |
| class V8_EXPORT EnabledCheckingPolicy { |
| protected: |
| EnabledCheckingPolicy(); |
| void CheckPointer(const void* ptr); |
| |
| private: |
| void* impl_; |
| }; |
| |
| class DisabledCheckingPolicy { |
| protected: |
| void CheckPointer(const void* raw) {} |
| }; |
| |
| #if V8_ENABLE_CHECKS |
| using DefaultCheckingPolicy = EnabledCheckingPolicy; |
| #else |
| using DefaultCheckingPolicy = DisabledCheckingPolicy; |
| #endif |
| |
| class KeepLocationPolicy { |
| public: |
| constexpr const SourceLocation& Location() const { return location_; } |
| |
| protected: |
| constexpr KeepLocationPolicy() = default; |
| constexpr explicit KeepLocationPolicy(const SourceLocation& location) |
| : location_(location) {} |
| |
| // KeepLocationPolicy must not copy underlying source locations. |
| KeepLocationPolicy(const KeepLocationPolicy&) = delete; |
| KeepLocationPolicy& operator=(const KeepLocationPolicy&) = delete; |
| |
| // Location of the original moved from object should be preserved. |
| KeepLocationPolicy(KeepLocationPolicy&&) = default; |
| KeepLocationPolicy& operator=(KeepLocationPolicy&&) = default; |
| |
| private: |
| SourceLocation location_; |
| }; |
| |
| class IgnoreLocationPolicy { |
| public: |
| constexpr SourceLocation Location() const { return {}; } |
| |
| protected: |
| constexpr IgnoreLocationPolicy() = default; |
| constexpr explicit IgnoreLocationPolicy(const SourceLocation&) {} |
| }; |
| |
| #if CPPGC_SUPPORTS_OBJECT_NAMES |
| using DefaultLocationPolicy = KeepLocationPolicy; |
| #else |
| using DefaultLocationPolicy = IgnoreLocationPolicy; |
| #endif |
| |
| struct StrongPersistentPolicy { |
| using IsStrongPersistent = std::true_type; |
| static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object); |
| }; |
| |
| struct WeakPersistentPolicy { |
| using IsStrongPersistent = std::false_type; |
| static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object); |
| }; |
| |
| struct StrongCrossThreadPersistentPolicy { |
| using IsStrongPersistent = std::true_type; |
| static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object); |
| }; |
| |
| struct WeakCrossThreadPersistentPolicy { |
| using IsStrongPersistent = std::false_type; |
| static V8_EXPORT PersistentRegion& GetPersistentRegion(void* object); |
| }; |
| |
| // Forward declarations setting up the default policies. |
| template <typename T, typename WeaknessPolicy, |
| typename LocationPolicy = DefaultLocationPolicy, |
| typename CheckingPolicy = DisabledCheckingPolicy> |
| class BasicCrossThreadPersistent; |
| template <typename T, typename WeaknessPolicy, |
| typename LocationPolicy = DefaultLocationPolicy, |
| typename CheckingPolicy = DefaultCheckingPolicy> |
| class BasicPersistent; |
| template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, |
| typename CheckingPolicy = DefaultCheckingPolicy> |
| class BasicMember; |
| |
| // Special tag type used to denote some sentinel member. The semantics of the |
| // sentinel is defined by the embedder. |
| struct SentinelPointer { |
| template <typename T> |
| operator T*() const { // NOLINT |
| static constexpr intptr_t kSentinelValue = 1; |
| return reinterpret_cast<T*>(kSentinelValue); |
| } |
| // Hidden friends. |
| friend bool operator==(SentinelPointer, SentinelPointer) { return true; } |
| friend bool operator!=(SentinelPointer, SentinelPointer) { return false; } |
| }; |
| |
| } // namespace internal |
| |
| constexpr internal::SentinelPointer kSentinelPointer{}; |
| |
| } // namespace cppgc |
| |
| #endif // INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_ |