Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1821)

Unified Diff: Source/heap/HeapTest.cpp

Issue 198563002: Experimental: How to implement willFinalize()? (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/heap/HeapTest.cpp
diff --git a/Source/heap/HeapTest.cpp b/Source/heap/HeapTest.cpp
index 9cd048780a643d7955f177fcf0db06f2ac18d55e..bbbb821ea9ff267b008f0ea18c8427f4f3dca0d7 100644
--- a/Source/heap/HeapTest.cpp
+++ b/Source/heap/HeapTest.cpp
@@ -531,6 +531,7 @@ public:
m_magic = 0;
s_live--;
}
+ bool isLive() const { return m_magic; }
virtual void trace(Visitor* visitor) { }
static unsigned s_live;
@@ -562,6 +563,13 @@ public:
void clear() { m_bar.release(); }
+ // willFinalize is called before finalize()/destructor.
+ void willFinalize()
+ {
+ EXPECT_TRUE(m_bar->isLive());
+ EXPECT_EQ(1u, Bar::s_live);
+ }
+
private:
explicit Baz(Bar* bar)
: m_bar(bar)
@@ -865,6 +873,65 @@ private:
WeakMember<Bar> m_weakBar;
};
+// FIXME: This should be moved to heap/Handle.h.
+template <typename T> class Observer : public GarbageCollected<Observer<T> > {
+public:
+ static Observer* create(T* data) { return new Observer(data); }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->registerWeakMembers(this, zapWeakMembers);
+ }
+
+ static void zapWeakMembers(Visitor* visitor, void* self)
+ {
+ Observer* o = reinterpret_cast<Observer*>(self);
+ if (o->m_data && !visitor->isAlive(o->m_data)) {
+ o->m_data->willFinalize();
+ o->m_data = 0;
+ }
+ }
+
+private:
+ Observer(T* data) : m_data(data) { }
+ T* m_data;
zerny-chromium 2014/03/13 06:41:47 Nit: WeakMember<T> m_data;
+};
+
+// This demonstrates how to use Observer<T> as a part object of the target.
+class WillFinalized : public GarbageCollectedFinalized<WillFinalized> {
+public:
+ WillFinalized(Bar* bar)
+ : m_data(2014)
+ , m_bar(bar)
+ , m_observer(Observer<WillFinalized>::create(this))
+ {
+ }
+
+ // willFinalize is called before finalize()/destructor.
+ void willFinalize()
+ {
+ EXPECT_NE(0, m_data);
+ EXPECT_TRUE(m_bar->isLive());
+ m_data = 0;
+ }
+
+ ~WillFinalized()
+ {
+ EXPECT_EQ(0, m_data);
+ }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_bar);
+ }
+
+private:
+ int m_data;
+ Member<Bar> m_bar;
+ // This is a trick. Use Persistent for Observer<T> to avoid it is collected
zerny-chromium 2014/03/13 06:41:47 it is collected -> it from being collected
Mads Ager (chromium) 2014/03/13 07:33:28 Instead of embedding the Persistent in the object
+ // with the target.
+ Persistent<Observer<WillFinalized> > m_observer;
+};
class SuperClass;
@@ -2481,6 +2548,28 @@ TEST(HeapTest, WeakMembers)
EXPECT_EQ(0u, Bar::s_live); // All gone.
}
+TEST(HeapTest, WillFinalize)
+{
+ // |o| observes |baz|.
+ Persistent<Observer<Baz> > o;
+ {
+ Baz* baz = Baz::create(Bar::create());
+ o = Observer<Baz>::create(baz);
+ }
+ // Observer doesn't have a strong reference to baz. So baz and its member
+ // will be collected.
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ EXPECT_EQ(0u, Bar::s_live);
+
+ // |wf| observes itself, and calls willFinalize().
+ {
+ WillFinalized* wf = new WillFinalized(Bar::create());
+ wf = 0;
+ }
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+ EXPECT_EQ(0u, Bar::s_live);
+}
+
TEST(HeapTest, Comparisons)
{
Persistent<Bar> barPersistent = Bar::create();
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698