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 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 599 } | 599 } |
| 600 | 600 |
| 601 protected: | 601 protected: |
| 602 class Local final : public GarbageCollected<Local> { | 602 class Local final : public GarbageCollected<Local> { |
| 603 public: | 603 public: |
| 604 Local() { } | 604 Local() { } |
| 605 | 605 |
| 606 DEFINE_INLINE_TRACE() { } | 606 DEFINE_INLINE_TRACE() { } |
| 607 }; | 607 }; |
| 608 | 608 |
| 609 class BookEnd; | 609 class PersistentChain; |
| 610 | 610 |
| 611 class PersistentStore { | 611 class RefCountedChain : public RefCounted<RefCountedChain> { |
| 612 public: | 612 public: |
| 613 static PersistentStore* create(int count, int* gcCount, BookEnd* bookend ) | 613 static RefCountedChain* create(int count) |
| 614 { | 614 { |
| 615 return new PersistentStore(count, gcCount, bookend); | 615 return new RefCountedChain(count); |
| 616 } | |
| 617 | |
| 618 void advance() | |
| 619 { | |
| 620 (*m_gcCount)++; | |
| 621 m_store.removeLast(); | |
| 622 // Remove reference to BookEnd when there are no Persistent<Local>s left. | |
| 623 // The BookEnd object will then be swept out at the next GC, and pre -finalized, | |
| 624 // causing this PersistentStore instance to be destructed, along wit h | |
| 625 // the Persistent<BookEnd>. It being the very last Persistent<>, cau sing the | |
| 626 // GC loop in ThreadState::detach() to terminate. | |
| 627 if (!m_store.size()) | |
| 628 m_bookend = nullptr; | |
| 629 } | 616 } |
| 630 | 617 |
| 631 private: | 618 private: |
| 632 PersistentStore(int count, int* gcCount, BookEnd* bookend) | 619 explicit RefCountedChain(int count) |
| 633 { | 620 { |
| 634 m_gcCount = gcCount; | 621 if (count > 0) { |
| 635 m_bookend = bookend; | 622 --count; |
| 636 for (int i = 0; i < count; ++i) | 623 m_persistentChain = PersistentChain::create(count); |
| 637 m_store.append(Persistent<ThreadPersistentHeapTester::Local>(new ThreadPersistentHeapTester::Local())); | 624 } |
| 638 } | 625 } |
| 639 | 626 |
| 640 Vector<Persistent<Local>> m_store; | 627 Persistent<PersistentChain> m_persistentChain; |
| 641 Persistent<BookEnd> m_bookend; | |
| 642 int* m_gcCount; | |
| 643 }; | 628 }; |
| 644 | 629 |
| 645 class BookEnd final : public GarbageCollected<BookEnd> { | 630 class PersistentChain : public GarbageCollectedFinalized<PersistentChain> { |
| 646 USING_PRE_FINALIZER(BookEnd, dispose); | |
| 647 public: | 631 public: |
| 648 BookEnd() | 632 static PersistentChain* create(int count) |
| 649 : m_store(nullptr) | |
| 650 { | 633 { |
| 651 ThreadState::current()->registerPreFinalizer(this); | 634 return new PersistentChain(count); |
| 652 } | 635 } |
| 653 | 636 |
| 654 void initialize(PersistentStore* store) | 637 DEFINE_INLINE_TRACE() { } |
| 638 | |
| 639 private: | |
| 640 explicit PersistentChain(int count) | |
| 655 { | 641 { |
| 656 m_store = store; | 642 m_refCountedChain = adoptRef(RefCountedChain::create(count)); |
| 657 } | 643 } |
| 658 | 644 |
| 659 void dispose() | 645 RefPtr<RefCountedChain> m_refCountedChain; |
| 660 { | |
| 661 delete m_store; | |
| 662 } | |
| 663 | |
| 664 DEFINE_INLINE_TRACE() | |
|
haraken
2015/07/01 07:43:43
It is invalid to modify the list of persistents in
| |
| 665 { | |
| 666 ASSERT(m_store); | |
| 667 m_store->advance(); | |
| 668 } | |
| 669 | |
| 670 private: | |
| 671 PersistentStore* m_store; | |
| 672 }; | 646 }; |
| 673 | 647 |
| 674 virtual void runThread() override | 648 virtual void runThread() override |
| 675 { | 649 { |
| 676 ThreadState::attach(); | 650 ThreadState::attach(); |
| 677 | 651 |
| 678 const int iterations = 5; | 652 PersistentChain::create(100); |
| 679 int gcCount = 0; | |
| 680 BookEnd* bookend = new BookEnd(); | |
| 681 PersistentStore* store = PersistentStore::create(iterations, &gcCount, b ookend); | |
| 682 bookend->initialize(store); | |
| 683 | |
| 684 bookend = nullptr; | |
| 685 store = nullptr; | |
| 686 | 653 |
| 687 // Upon thread detach, GCs will run until all persistents have been | 654 // Upon thread detach, GCs will run until all persistents have been |
| 688 // released. We verify that the draining of persistents proceeds | 655 // released. We verify that the draining of persistents proceeds |
| 689 // as expected by dropping one Persistent<> per GC until there | 656 // as expected by dropping one Persistent<> per GC until there |
| 690 // are none left. | 657 // are none left. |
| 691 ThreadState::detach(); | 658 ThreadState::detach(); |
| 692 EXPECT_EQ(iterations, gcCount); | |
| 693 atomicDecrement(&m_threadsToFinish); | 659 atomicDecrement(&m_threadsToFinish); |
| 694 } | 660 } |
| 695 }; | 661 }; |
| 696 | 662 |
| 697 // The accounting for memory includes the memory used by rounding up object | 663 // The accounting for memory includes the memory used by rounding up object |
| 698 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to | 664 // sizes. This is done in a different way on 32 bit and 64 bit, so we have to |
| 699 // have some slack in the tests. | 665 // have some slack in the tests. |
| 700 template<typename T> | 666 template<typename T> |
| 701 void CheckWithSlack(T expected, T actual, int slack) | 667 void CheckWithSlack(T expected, T actual, int slack) |
| 702 { | 668 { |
| (...skipping 5560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6263 { | 6229 { |
| 6264 Persistent<ClassWithMember> object = ClassWithMember::create(); | 6230 Persistent<ClassWithMember> object = ClassWithMember::create(); |
| 6265 EXPECT_EQ(0, object->traceCount()); | 6231 EXPECT_EQ(0, object->traceCount()); |
| 6266 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object. get()); | 6232 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object. get()); |
| 6267 EXPECT_TRUE(mixin); | 6233 EXPECT_TRUE(mixin); |
| 6268 EXPECT_GT(object->traceCount(), 0); | 6234 EXPECT_GT(object->traceCount(), 0); |
| 6269 EXPECT_GT(mixin->traceCount(), 0); | 6235 EXPECT_GT(mixin->traceCount(), 0); |
| 6270 } | 6236 } |
| 6271 | 6237 |
| 6272 } // namespace blink | 6238 } // namespace blink |
| OLD | NEW |