Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |