Commit 7e9aa1bd authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

cppgc: Add Persistent capabilitites

- Allow downcasting construciton and assignment;
- Add WeakCrossThreadPersistent::Lock() that safely retrieves a strong
  handle for a weak reference;

Bug: chromium:1056170
Change-Id: I5f8d85a87c9955506dd87723ffb4c80d66770c04
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2663160
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72468}
parent 50fb3e03
......@@ -44,7 +44,6 @@ class BasicCrossThreadPersistent final : public PersistentBase,
T* raw, const SourceLocation& loc = SourceLocation::Current())
: PersistentBase(raw), LocationPolicy(loc) {
if (!IsValid(raw)) return;
PersistentRegionLock guard;
PersistentRegion& region = this->GetPersistentRegion(raw);
SetNode(region.AllocateNode(this, &Trace));
this->CheckPointer(raw);
......@@ -220,6 +219,27 @@ class BasicCrossThreadPersistent final : public PersistentBase,
T* operator->() const { return Get(); }
T& operator*() const { return *Get(); }
template <typename U, typename OtherWeaknessPolicy = WeaknessPolicy,
typename OtherLocationPolicy = LocationPolicy,
typename OtherCheckingPolicy = CheckingPolicy>
BasicCrossThreadPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
OtherCheckingPolicy>
To() const {
PersistentRegionLock guard;
return BasicCrossThreadPersistent<U, OtherWeaknessPolicy,
OtherLocationPolicy, OtherCheckingPolicy>(
static_cast<U*>(Get()));
}
template <typename U = T,
typename = typename std::enable_if<!BasicCrossThreadPersistent<
U, WeaknessPolicy>::IsStrongPersistent::value>::type>
BasicCrossThreadPersistent<U, internal::StrongCrossThreadPersistentPolicy>
Lock() const {
return BasicCrossThreadPersistent<
U, internal::StrongCrossThreadPersistentPolicy>(*this);
}
private:
static bool IsValid(const void* ptr) {
return ptr && ptr != kSentinelPointer;
......
......@@ -210,6 +210,16 @@ class BasicPersistent final : public PersistentBase,
return result;
}
template <typename U, typename OtherWeaknessPolicy = WeaknessPolicy,
typename OtherLocationPolicy = LocationPolicy,
typename OtherCheckingPolicy = CheckingPolicy>
BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
OtherCheckingPolicy>
To() const {
return BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy,
OtherCheckingPolicy>(static_cast<U*>(Get()));
}
private:
static void Trace(Visitor* v, const void* ptr) {
const auto* persistent = static_cast<const BasicPersistent*>(ptr);
......
......@@ -637,6 +637,52 @@ TEST_F(PersistentTest, HeterogeneousConversion) {
HeterogeneousConversion<WeakPersistent, Persistent>(heap);
}
namespace {
class Parent : public GarbageCollected<Parent> {
public:
virtual void Trace(Visitor*) const {}
void ParentFoo() { /* Dummy method to trigger vtable check on UBSan. */
}
};
class Child : public Parent {
public:
void ChildFoo() { /* Dummy method to trigger vtable check on UBSan. */
}
};
template <template <typename> class PersistentType>
void ImplicitUpcast(cppgc::Heap* heap) {
PersistentType<Child> child;
PersistentType<Parent> parent = child;
}
template <template <typename> class PersistentType>
void ExplicitDowncast(cppgc::Heap* heap) {
PersistentType<Parent> parent{
MakeGarbageCollected<Child>(heap->GetAllocationHandle())};
PersistentType<Child> child = parent.template To<Child>();
child->ChildFoo();
}
} // namespace
TEST_F(PersistentTest, ImplicitUpcast) {
auto* heap = GetHeap();
ImplicitUpcast<Persistent>(heap);
ImplicitUpcast<WeakPersistent>(heap);
ImplicitUpcast<subtle::CrossThreadPersistent>(heap);
ImplicitUpcast<subtle::WeakCrossThreadPersistent>(heap);
}
TEST_F(PersistentTest, ExplicitDowncast) {
auto* heap = GetHeap();
ExplicitDowncast<Persistent>(heap);
ExplicitDowncast<WeakPersistent>(heap);
ExplicitDowncast<subtle::CrossThreadPersistent>(heap);
ExplicitDowncast<subtle::WeakCrossThreadPersistent>(heap);
}
TEST_F(PersistentTest, TraceStrong) {
auto* heap = GetHeap();
static constexpr size_t kItems = 512;
......@@ -877,5 +923,10 @@ TEST_F(PersistentTest, EmptyPersistentConstructDestructWithoutCompleteType) {
subtle::WeakCrossThreadPersistent<IncompleteType> p4;
}
TEST_F(PersistentTest, Lock) {
subtle::WeakCrossThreadPersistent<GCed> weak;
auto strong = weak.Lock();
}
} // namespace internal
} // namespace cppgc
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