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 |