cppgc: Add more basic type traits

Adds traits for checking for Member,WeakMember, and UntracedMember
types.

This allows the embedder to specify its own traits and restrictions
around cppgc types.

Bug: chromium:1056170
Change-Id: Ibe60b774128f72f1398267edd81233c50fca6eb7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2532299
Reviewed-by: Omer Katz <omerkatz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71121}
This commit is contained in:
Michael Lippautz 2020-11-11 15:08:48 +01:00 committed by Commit Bot
parent 30ae0d768f
commit 0d827da34d
4 changed files with 78 additions and 19 deletions

View File

@ -34,7 +34,7 @@ class PrefinalizerRegistration final {
public: \
static bool InvokePreFinalizer(const cppgc::LivenessBroker& liveness_broker, \
void* object) { \
static_assert(cppgc::internal::IsGarbageCollectedTypeV<Class>, \
static_assert(cppgc::IsGarbageCollectedTypeV<Class>, \
"Only garbage collected objects can have prefinalizers"); \
Class* self = static_cast<Class*>(object); \
if (liveness_broker.IsHeapObjectAlive(self)) return false; \

View File

@ -5,6 +5,8 @@
#ifndef INCLUDE_CPPGC_TYPE_TRAITS_H_
#define INCLUDE_CPPGC_TYPE_TRAITS_H_
// This file should stay with minimal dependencies to allow embedder to check
// against Oilpan types without including any other parts.
#include <type_traits>
namespace cppgc {
@ -12,6 +14,14 @@ namespace cppgc {
class Visitor;
namespace internal {
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy>
class BasicMember;
struct DijkstraWriteBarrierPolicy;
struct NoWriteBarrierPolicy;
class StrongMemberTag;
class UntracedMemberTag;
class WeakMemberTag;
// Pre-C++17 custom implementation of std::void_t.
template <typename... Ts>
@ -25,18 +35,6 @@ using void_t = typename make_void<Ts...>::type;
template <typename T>
struct IsWeak : std::false_type {};
template <typename T, template <typename... V> class U>
struct IsSubclassOfTemplate {
private:
template <typename... W>
static std::true_type SubclassCheck(U<W...>*);
static std::false_type SubclassCheck(...);
public:
static constexpr bool value =
decltype(SubclassCheck(std::declval<T*>()))::value;
};
// IsTraceMethodConst is used to verify that all Trace methods are marked as
// const. It is equivalent to IsTraceable but for a non-const object.
template <typename T, typename = void>
@ -91,16 +89,56 @@ struct IsGarbageCollectedType<
static_assert(sizeof(T), "T must be fully defined");
};
template <typename BasicMemberCandidate, typename WeaknessTag,
typename WriteBarrierPolicy>
struct IsSubclassOfBasicMemberTemplate {
private:
template <typename T, typename CheckingPolicy>
static std::true_type SubclassCheck(
BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy>*);
static std::false_type SubclassCheck(...);
public:
static constexpr bool value =
decltype(SubclassCheck(std::declval<BasicMemberCandidate*>()))::value;
};
template <typename T,
bool = IsSubclassOfBasicMemberTemplate<
T, StrongMemberTag, DijkstraWriteBarrierPolicy>::value>
struct IsMemberType : std::false_type {};
template <typename T>
constexpr bool IsGarbageCollectedTypeV =
internal::IsGarbageCollectedType<T>::value;
struct IsMemberType<T, true> : std::true_type {};
template <typename T, bool = IsSubclassOfBasicMemberTemplate<
T, WeakMemberTag, DijkstraWriteBarrierPolicy>::value>
struct IsWeakMemberType : std::false_type {};
template <typename T>
struct IsWeakMemberType<T, true> : std::true_type {};
template <typename T, bool = IsSubclassOfBasicMemberTemplate<
T, UntracedMemberTag, NoWriteBarrierPolicy>::value>
struct IsUntracedMemberType : std::false_type {};
template <typename T>
struct IsUntracedMemberType<T, true> : std::true_type {};
} // namespace internal
template <typename T>
constexpr bool IsGarbageCollectedMixinTypeV =
internal::IsGarbageCollectedMixinType<T>::value;
} // namespace internal
template <typename T>
constexpr bool IsGarbageCollectedTypeV =
internal::IsGarbageCollectedType<T>::value;
template <typename T>
constexpr bool IsMemberTypeV = internal::IsMemberType<T>::value;
template <typename T>
constexpr bool IsUntracedMemberTypeV = internal::IsUntracedMemberType<T>::value;
template <typename T>
constexpr bool IsWeakMemberTypeV = internal::IsWeakMemberType<T>::value;
template <typename T>
constexpr bool IsWeakV = internal::IsWeak<T>::value;

View File

@ -190,7 +190,7 @@ class V8_EXPORT Visitor {
static_assert(internal::IsAllocatedOnCompactableSpace<T>::value,
"Only references to objects allocated on compactable spaces "
"should be registered as movable slots.");
static_assert(!internal::IsGarbageCollectedMixinTypeV<T>,
static_assert(!IsGarbageCollectedMixinTypeV<T>,
"Mixin types do not support compaction.");
HandleMovableReference(reinterpret_cast<const void**>(slot));
}

View File

@ -30,6 +30,27 @@ struct DerivedGCed : GCed {
static_assert(!IsWeakV<Member<GCed>>, "Member is always strong.");
static_assert(IsWeakV<WeakMember<GCed>>, "WeakMember is always weak.");
static_assert(IsMemberTypeV<Member<GCed>>, "Member must be Member.");
static_assert(!IsMemberTypeV<WeakMember<GCed>>,
"WeakMember must not be Member.");
static_assert(!IsMemberTypeV<UntracedMember<GCed>>,
"UntracedMember must not be Member.");
static_assert(!IsMemberTypeV<int>, "int must not be Member.");
static_assert(!IsWeakMemberTypeV<Member<GCed>>,
"Member must not be WeakMember.");
static_assert(IsWeakMemberTypeV<WeakMember<GCed>>,
"WeakMember must be WeakMember.");
static_assert(!IsWeakMemberTypeV<UntracedMember<GCed>>,
"UntracedMember must not be WeakMember.");
static_assert(!IsWeakMemberTypeV<int>, "int must not be WeakMember.");
static_assert(!IsUntracedMemberTypeV<Member<GCed>>,
"Member must not be UntracedMember.");
static_assert(!IsUntracedMemberTypeV<WeakMember<GCed>>,
"WeakMember must not be UntracedMember.");
static_assert(IsUntracedMemberTypeV<UntracedMember<GCed>>,
"UntracedMember must be UntracedMember.");
static_assert(!IsUntracedMemberTypeV<int>, "int must not be UntracedMember.");
struct CustomWriteBarrierPolicy {
static size_t InitializingWriteBarriersTriggered;
static size_t AssigningWriteBarriersTriggered;