cppgc: Add PostConstructionCallbackTrait
This adds PostConstructionCallbackTrait which can be used to get a callback that is executed right after an object instance is created. This can be useful for hooks that require to be able to call into virtual methods. Bug: chromium:1074061 Change-Id: Idd5ef677fed291bcba81b9a47f2932c9bb5832b4 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2179385 Commit-Queue: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Anton Bikineev <bikineev@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Cr-Commit-Position: refs/heads/master@{#67557}
This commit is contained in:
parent
849b2239e8
commit
69110a7758
@ -106,6 +106,17 @@ class MakeGarbageCollectedTrait : public MakeGarbageCollectedTraitBase<T> {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Allows users to specify a post-construction callback for specific types. The
|
||||
* callback is invoked on the instance of type T right after it has been
|
||||
* constructed. This can be useful when the callback requires a
|
||||
* fully-constructed object to be able to dispatch to virtual methods.
|
||||
*/
|
||||
template <typename T, typename = void>
|
||||
struct PostConstructionCallbackTrait {
|
||||
static void Call(T*) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a managed object of type T where T transitively inherits from
|
||||
* GarbageCollected.
|
||||
@ -116,7 +127,10 @@ class MakeGarbageCollectedTrait : public MakeGarbageCollectedTraitBase<T> {
|
||||
*/
|
||||
template <typename T, typename... Args>
|
||||
T* MakeGarbageCollected(Heap* heap, Args&&... args) {
|
||||
return MakeGarbageCollectedTrait<T>::Call(heap, std::forward<Args>(args)...);
|
||||
T* object =
|
||||
MakeGarbageCollectedTrait<T>::Call(heap, std::forward<Args>(args)...);
|
||||
PostConstructionCallbackTrait<T>::Call(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
} // namespace cppgc
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "include/cppgc/garbage-collected.h"
|
||||
|
||||
#include "include/cppgc/allocation.h"
|
||||
#include "include/cppgc/type-traits.h"
|
||||
#include "src/heap/cppgc/heap-object-header-inl.h"
|
||||
#include "src/heap/cppgc/heap.h"
|
||||
#include "test/unittests/heap/cppgc/tests.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
@ -76,5 +78,66 @@ TEST_F(GarbageCollectedTestWithHeap, GetObjectStartReturnsCorrentAddress) {
|
||||
.base_object_payload);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class GCedWithPostConstructionCallback final : public GCed {
|
||||
public:
|
||||
static size_t cb_callcount;
|
||||
GCedWithPostConstructionCallback() { cb_callcount = 0; }
|
||||
};
|
||||
size_t GCedWithPostConstructionCallback::cb_callcount;
|
||||
|
||||
class MixinWithPostConstructionCallback {
|
||||
public:
|
||||
static size_t cb_callcount;
|
||||
MixinWithPostConstructionCallback() { cb_callcount = 0; }
|
||||
using MarkerForMixinWithPostConstructionCallback = int;
|
||||
};
|
||||
size_t MixinWithPostConstructionCallback::cb_callcount;
|
||||
|
||||
class GCedWithMixinWithPostConstructionCallback final
|
||||
: public GCed,
|
||||
public MixinWithPostConstructionCallback {};
|
||||
|
||||
} // namespace
|
||||
} // namespace internal
|
||||
|
||||
template <>
|
||||
struct PostConstructionCallbackTrait<
|
||||
internal::GCedWithPostConstructionCallback> {
|
||||
static void Call(internal::GCedWithPostConstructionCallback* object) {
|
||||
EXPECT_FALSE(
|
||||
internal::HeapObjectHeader::FromPayload(object).IsInConstruction());
|
||||
internal::GCedWithPostConstructionCallback::cb_callcount++;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct PostConstructionCallbackTrait<
|
||||
T,
|
||||
internal::void_t<typename T::MarkerForMixinWithPostConstructionCallback>> {
|
||||
// The parameter could just be T*.
|
||||
static void Call(
|
||||
internal::GCedWithMixinWithPostConstructionCallback* object) {
|
||||
EXPECT_FALSE(
|
||||
internal::HeapObjectHeader::FromPayload(object).IsInConstruction());
|
||||
internal::GCedWithMixinWithPostConstructionCallback::cb_callcount++;
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
TEST_F(GarbageCollectedTestWithHeap, PostConstructionCallback) {
|
||||
EXPECT_EQ(0u, GCedWithPostConstructionCallback::cb_callcount);
|
||||
MakeGarbageCollected<GCedWithPostConstructionCallback>(GetHeap());
|
||||
EXPECT_EQ(1u, GCedWithPostConstructionCallback::cb_callcount);
|
||||
}
|
||||
|
||||
TEST_F(GarbageCollectedTestWithHeap, PostConstructionCallbackForMixin) {
|
||||
EXPECT_EQ(0u, MixinWithPostConstructionCallback::cb_callcount);
|
||||
MakeGarbageCollected<GCedWithMixinWithPostConstructionCallback>(GetHeap());
|
||||
EXPECT_EQ(1u, MixinWithPostConstructionCallback::cb_callcount);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace cppgc
|
||||
|
Loading…
Reference in New Issue
Block a user