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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 { 524 {
525 return new Bar(); 525 return new Bar();
526 } 526 }
527 527
528 void finalize() 528 void finalize()
529 { 529 {
530 EXPECT_TRUE(m_magic == magic); 530 EXPECT_TRUE(m_magic == magic);
531 m_magic = 0; 531 m_magic = 0;
532 s_live--; 532 s_live--;
533 } 533 }
534 bool isLive() const { return m_magic; }
534 535
535 virtual void trace(Visitor* visitor) { } 536 virtual void trace(Visitor* visitor) { }
536 static unsigned s_live; 537 static unsigned s_live;
537 538
538 protected: 539 protected:
539 static const int magic = 1337; 540 static const int magic = 1337;
540 int m_magic; 541 int m_magic;
541 542
542 Bar() 543 Bar()
543 : m_magic(magic) 544 : m_magic(magic)
(...skipping 11 matching lines...) Expand all
555 return new Baz(bar); 556 return new Baz(bar);
556 } 557 }
557 558
558 void trace(Visitor* visitor) 559 void trace(Visitor* visitor)
559 { 560 {
560 visitor->trace(m_bar); 561 visitor->trace(m_bar);
561 } 562 }
562 563
563 void clear() { m_bar.release(); } 564 void clear() { m_bar.release(); }
564 565
566 // willFinalize is called before finalize()/destructor.
567 void willFinalize()
568 {
569 EXPECT_TRUE(m_bar->isLive());
570 EXPECT_EQ(1u, Bar::s_live);
571 }
572
565 private: 573 private:
566 explicit Baz(Bar* bar) 574 explicit Baz(Bar* bar)
567 : m_bar(bar) 575 : m_bar(bar)
568 { 576 {
569 } 577 }
570 578
571 Member<Bar> m_bar; 579 Member<Bar> m_bar;
572 }; 580 };
573 581
574 class Foo : public Bar { 582 class Foo : public Bar {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 : Bar() 866 : Bar()
859 , m_strongBar(strongBar) 867 , m_strongBar(strongBar)
860 , m_weakBar(weakBar) 868 , m_weakBar(weakBar)
861 { 869 {
862 } 870 }
863 871
864 Member<Bar> m_strongBar; 872 Member<Bar> m_strongBar;
865 WeakMember<Bar> m_weakBar; 873 WeakMember<Bar> m_weakBar;
866 }; 874 };
867 875
876 // FIXME: This should be moved to heap/Handle.h.
877 template <typename T> class Observer : public GarbageCollected<Observer<T> > {
878 public:
879 static Observer* create(T* data) { return new Observer(data); }
880
881 void trace(Visitor* visitor)
882 {
883 visitor->registerWeakMembers(this, zapWeakMembers);
884 }
885
886 static void zapWeakMembers(Visitor* visitor, void* self)
887 {
888 Observer* o = reinterpret_cast<Observer*>(self);
889 if (o->m_data && !visitor->isAlive(o->m_data)) {
890 o->m_data->willFinalize();
891 o->m_data = 0;
892 }
893 }
894
895 private:
896 Observer(T* data) : m_data(data) { }
897 T* m_data;
zerny-chromium 2014/03/13 06:41:47 Nit: WeakMember<T> m_data;
898 };
899
900 // This demonstrates how to use Observer<T> as a part object of the target.
901 class WillFinalized : public GarbageCollectedFinalized<WillFinalized> {
902 public:
903 WillFinalized(Bar* bar)
904 : m_data(2014)
905 , m_bar(bar)
906 , m_observer(Observer<WillFinalized>::create(this))
907 {
908 }
909
910 // willFinalize is called before finalize()/destructor.
911 void willFinalize()
912 {
913 EXPECT_NE(0, m_data);
914 EXPECT_TRUE(m_bar->isLive());
915 m_data = 0;
916 }
917
918 ~WillFinalized()
919 {
920 EXPECT_EQ(0, m_data);
921 }
922
923 void trace(Visitor* visitor)
924 {
925 visitor->trace(m_bar);
926 }
927
928 private:
929 int m_data;
930 Member<Bar> m_bar;
931 // 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
932 // with the target.
933 Persistent<Observer<WillFinalized> > m_observer;
934 };
868 935
869 class SuperClass; 936 class SuperClass;
870 937
871 class PointsBack : public RefCountedWillBeGarbageCollectedFinalized<PointsBack> { 938 class PointsBack : public RefCountedWillBeGarbageCollectedFinalized<PointsBack> {
872 public: 939 public:
873 static PassRefPtrWillBeRawPtr<PointsBack> create() 940 static PassRefPtrWillBeRawPtr<PointsBack> create()
874 { 941 {
875 return adoptRefWillBeNoop(new PointsBack()); 942 return adoptRefWillBeNoop(new PointsBack());
876 } 943 }
877 944
(...skipping 1596 matching lines...) Expand 10 before | Expand all | Expand 10 after
2474 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack); 2541 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2475 EXPECT_EQ(3u, Bar::s_live); // Only h4, h5 and h2 are left. 2542 EXPECT_EQ(3u, Bar::s_live); // Only h4, h5 and h2 are left.
2476 EXPECT_TRUE(h4->strongIsThere()); // h2 is still pointed to from h4. 2543 EXPECT_TRUE(h4->strongIsThere()); // h2 is still pointed to from h4.
2477 EXPECT_TRUE(h5->strongIsThere()); // h2 is still pointed to from h5. 2544 EXPECT_TRUE(h5->strongIsThere()); // h2 is still pointed to from h5.
2478 } 2545 }
2479 // h4 and h5 have gone out of scope now and they were keeping h2 alive. 2546 // h4 and h5 have gone out of scope now and they were keeping h2 alive.
2480 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack); 2547 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2481 EXPECT_EQ(0u, Bar::s_live); // All gone. 2548 EXPECT_EQ(0u, Bar::s_live); // All gone.
2482 } 2549 }
2483 2550
2551 TEST(HeapTest, WillFinalize)
2552 {
2553 // |o| observes |baz|.
2554 Persistent<Observer<Baz> > o;
2555 {
2556 Baz* baz = Baz::create(Bar::create());
2557 o = Observer<Baz>::create(baz);
2558 }
2559 // Observer doesn't have a strong reference to baz. So baz and its member
2560 // will be collected.
2561 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2562 EXPECT_EQ(0u, Bar::s_live);
2563
2564 // |wf| observes itself, and calls willFinalize().
2565 {
2566 WillFinalized* wf = new WillFinalized(Bar::create());
2567 wf = 0;
2568 }
2569 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2570 EXPECT_EQ(0u, Bar::s_live);
2571 }
2572
2484 TEST(HeapTest, Comparisons) 2573 TEST(HeapTest, Comparisons)
2485 { 2574 {
2486 Persistent<Bar> barPersistent = Bar::create(); 2575 Persistent<Bar> barPersistent = Bar::create();
2487 Persistent<Foo> fooPersistent = Foo::create(barPersistent); 2576 Persistent<Foo> fooPersistent = Foo::create(barPersistent);
2488 EXPECT_TRUE(barPersistent != fooPersistent); 2577 EXPECT_TRUE(barPersistent != fooPersistent);
2489 barPersistent = fooPersistent; 2578 barPersistent = fooPersistent;
2490 EXPECT_TRUE(barPersistent == fooPersistent); 2579 EXPECT_TRUE(barPersistent == fooPersistent);
2491 } 2580 }
2492 2581
2493 TEST(HeapTest, CheckAndMarkPointer) 2582 TEST(HeapTest, CheckAndMarkPointer)
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
2814 2903
2815 namespace WTF { 2904 namespace WTF {
2816 2905
2817 // We need the below vector trait specialization for the above HeapVectors to be have correctly wrt. memset, memcmp etc. 2906 // We need the below vector trait specialization for the above HeapVectors to be have correctly wrt. memset, memcmp etc.
2818 template<> struct VectorTraits<WebCore::VectorObject> : public SimpleClassVector Traits<WebCore::VectorObject> { }; 2907 template<> struct VectorTraits<WebCore::VectorObject> : public SimpleClassVector Traits<WebCore::VectorObject> { };
2819 template<> struct VectorTraits<WebCore::VectorObjectInheritedTrace> : public Sim pleClassVectorTraits<WebCore::VectorObjectInheritedTrace> { }; 2908 template<> struct VectorTraits<WebCore::VectorObjectInheritedTrace> : public Sim pleClassVectorTraits<WebCore::VectorObjectInheritedTrace> { };
2820 template<> struct VectorTraits<WebCore::VectorObjectNoTrace> : public SimpleClas sVectorTraits<WebCore::VectorObjectNoTrace> { }; 2909 template<> struct VectorTraits<WebCore::VectorObjectNoTrace> : public SimpleClas sVectorTraits<WebCore::VectorObjectNoTrace> { };
2821 2910
2822 } // WTF namespace 2911 } // WTF namespace
2823 2912
OLDNEW
« 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