Commit b246d341 authored by Omer Katz's avatar Omer Katz Committed by Commit Bot

cppgc: Make Trace methods const

Bug: chromium:1056170
Change-Id: Ifc519559868d9c3099d309f75ba8faf2018a1578
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2154951
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Reviewed-by: 's avatarAnton Bikineev <bikineev@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67235}
parent 4dbb4460
...@@ -40,21 +40,21 @@ class GarbageCollectedBase { ...@@ -40,21 +40,21 @@ class GarbageCollectedBase {
} // namespace internal } // namespace internal
/** /**
* Base class for managed objects. Only descendent types of GarbageCollected can * Base class for managed objects. Only descendent types of GarbageCollected
* be constructed using MakeGarbageCollected. Must be inherited from as * can be constructed using MakeGarbageCollected. Must be inherited from as
* left-most base class. * left-most base class.
* *
* Types inheriting from GarbageCollected must provide a method of * Types inheriting from GarbageCollected must provide a method of
* signature `void Trace(cppgc::Visitor*)` that dispatchs all managed pointers * signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
* to the visitor and delegates to garbage-collected base classes. The method * pointers to the visitor and delegates to garbage-collected base classes.
* must be virtual if the type is not directly a child of GarbageCollected and * The method must be virtual if the type is not directly a child of
* marked as final. * GarbageCollected and marked as final.
* *
* \code * \code
* // Example using final class. * // Example using final class.
* class FinalType final : public GarbageCollected<FinalType> { * class FinalType final : public GarbageCollected<FinalType> {
* public: * public:
* void Trace(cppgc::Visitor* visitor) { * void Trace(cppgc::Visitor* visitor) const {
* // Dispatch using visitor->Trace(...); * // Dispatch using visitor->Trace(...);
* } * }
* }; * };
...@@ -62,12 +62,12 @@ class GarbageCollectedBase { ...@@ -62,12 +62,12 @@ class GarbageCollectedBase {
* // Example using non-final base class. * // Example using non-final base class.
* class NonFinalBase : public GarbageCollected<NonFinalBase> { * class NonFinalBase : public GarbageCollected<NonFinalBase> {
* public: * public:
* virtual void Trace(cppgc::Visitor*) {} * virtual void Trace(cppgc::Visitor*) const {}
* }; * };
* *
* class FinalChild final : public NonFinalBase { * class FinalChild final : public NonFinalBase {
* public: * public:
* void Trace(cppgc::Visitor* visitor) final { * void Trace(cppgc::Visitor* visitor) const final {
* // Dispatch using visitor->Trace(...); * // Dispatch using visitor->Trace(...);
* NonFinalBase::Trace(visitor); * NonFinalBase::Trace(visitor);
* } * }
...@@ -88,14 +88,14 @@ class GarbageCollected : public internal::GarbageCollectedBase { ...@@ -88,14 +88,14 @@ class GarbageCollected : public internal::GarbageCollectedBase {
* directly but must be mixed into the inheritance hierarchy of a * directly but must be mixed into the inheritance hierarchy of a
* GarbageCollected object. * GarbageCollected object.
* *
* Types inheriting from GarbageCollectedMixin must override a virtual method of * Types inheriting from GarbageCollectedMixin must override a virtual method
* signature `void Trace(cppgc::Visitor*)` that dispatchs all managed pointers * of signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
* to the visitor and delegates to base classes. * pointers to the visitor and delegates to base classes.
* *
* \code * \code
* class Mixin : public GarbageCollectedMixin { * class Mixin : public GarbageCollectedMixin {
* public: * public:
* void Trace(cppgc::Visitor* visitor) override { * void Trace(cppgc::Visitor* visitor) const override {
* // Dispatch using visitor->Trace(...); * // Dispatch using visitor->Trace(...);
* } * }
* }; * };
...@@ -119,7 +119,7 @@ class GarbageCollectedMixin : public internal::GarbageCollectedBase { ...@@ -119,7 +119,7 @@ class GarbageCollectedMixin : public internal::GarbageCollectedBase {
* This Trace method must be overriden by objects inheriting from * This Trace method must be overriden by objects inheriting from
* GarbageCollectedMixin. * GarbageCollectedMixin.
*/ */
virtual void Trace(cppgc::Visitor*) {} virtual void Trace(cppgc::Visitor*) const {}
}; };
/** /**
...@@ -130,7 +130,7 @@ class GarbageCollectedMixin : public internal::GarbageCollectedBase { ...@@ -130,7 +130,7 @@ class GarbageCollectedMixin : public internal::GarbageCollectedBase {
* \code * \code
* class Mixin : public GarbageCollectedMixin { * class Mixin : public GarbageCollectedMixin {
* public: * public:
* void Trace(cppgc::Visitor* visitor) override { * void Trace(cppgc::Visitor* visitor) const override {
* // Dispatch using visitor->Trace(...); * // Dispatch using visitor->Trace(...);
* } * }
* }; * };
...@@ -138,7 +138,7 @@ class GarbageCollectedMixin : public internal::GarbageCollectedBase { ...@@ -138,7 +138,7 @@ class GarbageCollectedMixin : public internal::GarbageCollectedBase {
* class Foo : public GarbageCollected<Foo>, public Mixin { * class Foo : public GarbageCollected<Foo>, public Mixin {
* USING_GARBAGE_COLLECTED_MIXIN(); * USING_GARBAGE_COLLECTED_MIXIN();
* public: * public:
* void Trace(cppgc::Visitor* visitor) override { * void Trace(cppgc::Visitor* visitor) const override {
* // Dispatch using visitor->Trace(...); * // Dispatch using visitor->Trace(...);
* Mixin::Trace(visitor); * Mixin::Trace(visitor);
* } * }
......
...@@ -41,8 +41,7 @@ struct TraceTrait { ...@@ -41,8 +41,7 @@ struct TraceTrait {
} }
static void Trace(Visitor* visitor, const void* self) { static void Trace(Visitor* visitor, const void* self) {
// TODO(chromium:1056170): Remove const_cast when Trace() methods are const. static_cast<const T*>(self)->Trace(visitor);
static_cast<T*>(const_cast<void*>(self))->Trace(visitor);
} }
}; };
......
...@@ -37,6 +37,16 @@ struct IsSubclassOfTemplate { ...@@ -37,6 +37,16 @@ struct IsSubclassOfTemplate {
decltype(SubclassCheck(std::declval<T*>()))::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>
struct IsTraceMethodConst : std::false_type {};
template <typename T>
struct IsTraceMethodConst<T, void_t<decltype(std::declval<const T>().Trace(
std::declval<Visitor*>()))>> : std::true_type {
};
template <typename T, typename = void> template <typename T, typename = void>
struct IsTraceable : std::false_type { struct IsTraceable : std::false_type {
static_assert(sizeof(T), "T must be fully defined"); static_assert(sizeof(T), "T must be fully defined");
...@@ -45,7 +55,13 @@ struct IsTraceable : std::false_type { ...@@ -45,7 +55,13 @@ struct IsTraceable : std::false_type {
template <typename T> template <typename T>
struct IsTraceable< struct IsTraceable<
T, void_t<decltype(std::declval<T>().Trace(std::declval<Visitor*>()))>> T, void_t<decltype(std::declval<T>().Trace(std::declval<Visitor*>()))>>
: std::true_type {}; : std::true_type {
// All Trace methods should be marked as const. If an object of type
// 'T' is traceable then any object of type 'const T' should also
// be traceable.
static_assert(IsTraceMethodConst<T>(),
"Trace methods should be marked as const.");
};
template <typename T> template <typename T>
constexpr bool IsTraceableV = IsTraceable<T>::value; constexpr bool IsTraceableV = IsTraceable<T>::value;
......
...@@ -25,7 +25,7 @@ class MergedMixins : public Mixin, public OtherMixin { ...@@ -25,7 +25,7 @@ class MergedMixins : public Mixin, public OtherMixin {
MERGE_GARBAGE_COLLECTED_MIXINS(); MERGE_GARBAGE_COLLECTED_MIXINS();
public: public:
void Trace(cppgc::Visitor* visitor) override { void Trace(cppgc::Visitor* visitor) const override {
Mixin::Trace(visitor); Mixin::Trace(visitor);
OtherMixin::Trace(visitor); OtherMixin::Trace(visitor);
} }
...@@ -34,7 +34,9 @@ class GCWithMergedMixins : public GCed, public MergedMixins { ...@@ -34,7 +34,9 @@ class GCWithMergedMixins : public GCed, public MergedMixins {
USING_GARBAGE_COLLECTED_MIXIN(); USING_GARBAGE_COLLECTED_MIXIN();
public: public:
void Trace(cppgc::Visitor* visitor) override { MergedMixins::Trace(visitor); } void Trace(cppgc::Visitor* visitor) const override {
MergedMixins::Trace(visitor);
}
}; };
class GarbageCollectedTestWithHeap class GarbageCollectedTestWithHeap
......
...@@ -20,10 +20,10 @@ namespace internal { ...@@ -20,10 +20,10 @@ namespace internal {
namespace { namespace {
struct GCed : GarbageCollected<GCed> { struct GCed : GarbageCollected<GCed> {
virtual void Trace(cppgc::Visitor*) {} virtual void Trace(cppgc::Visitor*) const {}
}; };
struct DerivedGCed : GCed { struct DerivedGCed : GCed {
void Trace(cppgc::Visitor* v) override { GCed::Trace(v); } void Trace(cppgc::Visitor* v) const override { GCed::Trace(v); }
}; };
// Compile tests. // Compile tests.
......
...@@ -22,12 +22,12 @@ namespace { ...@@ -22,12 +22,12 @@ namespace {
struct GCed : GarbageCollected<GCed> { struct GCed : GarbageCollected<GCed> {
static size_t trace_call_count; static size_t trace_call_count;
virtual void Trace(cppgc::Visitor*) { ++trace_call_count; } virtual void Trace(cppgc::Visitor*) const { ++trace_call_count; }
}; };
size_t GCed::trace_call_count = 0; size_t GCed::trace_call_count = 0;
struct DerivedGCed : GCed { struct DerivedGCed : GCed {
void Trace(cppgc::Visitor* v) override { GCed::Trace(v); } void Trace(cppgc::Visitor* v) const override { GCed::Trace(v); }
}; };
template <template <typename> class PersistentType> template <template <typename> class PersistentType>
......
...@@ -22,7 +22,7 @@ class GCed : public GarbageCollected<GCed> { ...@@ -22,7 +22,7 @@ class GCed : public GarbageCollected<GCed> {
CPPGC_USING_PRE_FINALIZER(GCed, PreFinalizer); CPPGC_USING_PRE_FINALIZER(GCed, PreFinalizer);
public: public:
void Trace(Visitor*) {} void Trace(Visitor*) const {}
void PreFinalizer() { ++prefinalizer_callcount; } void PreFinalizer() { ++prefinalizer_callcount; }
static size_t prefinalizer_callcount; static size_t prefinalizer_callcount;
...@@ -175,7 +175,7 @@ class AllocatingPrefinalizer : public GarbageCollected<AllocatingPrefinalizer> { ...@@ -175,7 +175,7 @@ class AllocatingPrefinalizer : public GarbageCollected<AllocatingPrefinalizer> {
public: public:
explicit AllocatingPrefinalizer(cppgc::Heap* heap) : heap_(heap) {} explicit AllocatingPrefinalizer(cppgc::Heap* heap) : heap_(heap) {}
void Trace(Visitor*) {} void Trace(Visitor*) const {}
void PreFinalizer() { MakeGarbageCollected<GCed>(heap_); } void PreFinalizer() { MakeGarbageCollected<GCed>(heap_); }
private: private:
......
...@@ -26,7 +26,7 @@ class GCed : public GarbageCollected<GCed> { ...@@ -26,7 +26,7 @@ class GCed : public GarbageCollected<GCed> {
GCed() { trace_callcount = 0; } GCed() { trace_callcount = 0; }
virtual void Trace(cppgc::Visitor* visitor) { trace_callcount++; } virtual void Trace(cppgc::Visitor* visitor) const { trace_callcount++; }
}; };
size_t GCed::trace_callcount; size_t GCed::trace_callcount;
...@@ -44,7 +44,7 @@ class GCedMixinApplication : public GCed, ...@@ -44,7 +44,7 @@ class GCedMixinApplication : public GCed,
USING_GARBAGE_COLLECTED_MIXIN(); USING_GARBAGE_COLLECTED_MIXIN();
public: public:
void Trace(cppgc::Visitor* visitor) override { void Trace(cppgc::Visitor* visitor) const override {
GCed::Trace(visitor); GCed::Trace(visitor);
GCedMixin::Trace(visitor); GCedMixin::Trace(visitor);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment