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 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 554 return WTF::wrapUnique( | 554 return WTF::wrapUnique( |
| 555 new GlobalIntWrapperPersistent(IntWrapper::create(value))); | 555 new GlobalIntWrapperPersistent(IntWrapper::create(value))); |
| 556 } | 556 } |
| 557 | 557 |
| 558 void addGlobalPersistent() { | 558 void addGlobalPersistent() { |
| 559 MutexLocker lock(m_mutex); | 559 MutexLocker lock(m_mutex); |
| 560 m_crossPersistents.push_back(createGlobalPersistent(0x2a2a2a2a)); | 560 m_crossPersistents.push_back(createGlobalPersistent(0x2a2a2a2a)); |
| 561 } | 561 } |
| 562 | 562 |
| 563 void runThread() override { | 563 void runThread() override { |
| 564 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); | 564 ThreadState::attachCurrentThread(); |
| 565 | 565 |
| 566 // Add a cross-thread persistent from this thread; the test object | 566 // Add a cross-thread persistent from this thread; the test object |
| 567 // verifies that it will have been cleared out after the threads | 567 // verifies that it will have been cleared out after the threads |
| 568 // have all detached, running their termination GCs while doing so. | 568 // have all detached, running their termination GCs while doing so. |
| 569 addGlobalPersistent(); | 569 addGlobalPersistent(); |
| 570 | 570 |
| 571 int gcCount = 0; | 571 int gcCount = 0; |
| 572 while (!done()) { | 572 while (!done()) { |
| 573 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 573 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
| 574 { | 574 { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 609 atomicDecrement(&m_threadsToFinish); | 609 atomicDecrement(&m_threadsToFinish); |
| 610 } | 610 } |
| 611 }; | 611 }; |
| 612 | 612 |
| 613 class ThreadedWeaknessTester : public ThreadedTesterBase { | 613 class ThreadedWeaknessTester : public ThreadedTesterBase { |
| 614 public: | 614 public: |
| 615 static void test() { ThreadedTesterBase::test(new ThreadedWeaknessTester); } | 615 static void test() { ThreadedTesterBase::test(new ThreadedWeaknessTester); } |
| 616 | 616 |
| 617 private: | 617 private: |
| 618 void runThread() override { | 618 void runThread() override { |
| 619 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); | 619 ThreadState::attachCurrentThread(); |
| 620 | 620 |
| 621 int gcCount = 0; | 621 int gcCount = 0; |
| 622 while (!done()) { | 622 while (!done()) { |
| 623 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 623 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
| 624 { | 624 { |
| 625 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> weakMap = | 625 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> weakMap = |
| 626 new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; | 626 new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; |
| 627 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weakMap2; | 627 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weakMap2; |
| 628 | 628 |
| 629 for (int i = 0; i < numberOfAllocations; i++) { | 629 for (int i = 0; i < numberOfAllocations; i++) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 | 699 |
| 700 private: | 700 private: |
| 701 explicit PersistentChain(int count) { | 701 explicit PersistentChain(int count) { |
| 702 m_refCountedChain = adoptRef(RefCountedChain::create(count)); | 702 m_refCountedChain = adoptRef(RefCountedChain::create(count)); |
| 703 } | 703 } |
| 704 | 704 |
| 705 RefPtr<RefCountedChain> m_refCountedChain; | 705 RefPtr<RefCountedChain> m_refCountedChain; |
| 706 }; | 706 }; |
| 707 | 707 |
| 708 void runThread() override { | 708 void runThread() override { |
| 709 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); | 709 ThreadState::attachCurrentThread(); |
| 710 | 710 |
| 711 PersistentChain::create(100); | 711 PersistentChain::create(100); |
| 712 | 712 |
| 713 // Upon thread detach, GCs will run until all persistents have been | 713 // Upon thread detach, GCs will run until all persistents have been |
| 714 // released. We verify that the draining of persistents proceeds | 714 // released. We verify that the draining of persistents proceeds |
| 715 // as expected by dropping one Persistent<> per GC until there | 715 // as expected by dropping one Persistent<> per GC until there |
| 716 // are none left. | 716 // are none left. |
| 717 ThreadState::detachCurrentThread(); | 717 ThreadState::detachCurrentThread(); |
| 718 atomicDecrement(&m_threadsToFinish); | 718 atomicDecrement(&m_threadsToFinish); |
| 719 } | 719 } |
| (...skipping 4053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4773 } | 4773 } |
| 4774 { | 4774 { |
| 4775 Persistent<MixinInstanceWithoutTrace> b = obj; | 4775 Persistent<MixinInstanceWithoutTrace> b = obj; |
| 4776 preciselyCollectGarbage(); | 4776 preciselyCollectGarbage(); |
| 4777 EXPECT_EQ(2, MixinA::s_traceCount); | 4777 EXPECT_EQ(2, MixinA::s_traceCount); |
| 4778 } | 4778 } |
| 4779 preciselyCollectGarbage(); | 4779 preciselyCollectGarbage(); |
| 4780 EXPECT_EQ(2, MixinA::s_traceCount); | 4780 EXPECT_EQ(2, MixinA::s_traceCount); |
| 4781 } | 4781 } |
| 4782 | 4782 |
| 4783 class GCParkingThreadTester { | |
| 4784 public: | |
| 4785 static void test() { | |
| 4786 std::unique_ptr<WebThread> sleepingThread = | |
| 4787 WTF::wrapUnique(Platform::current()->createThread("SleepingThread")); | |
| 4788 sleepingThread->getWebTaskRunner()->postTask( | |
| 4789 BLINK_FROM_HERE, crossThreadBind(sleeperMainFunc)); | |
| 4790 | |
| 4791 // Wait for the sleeper to run. | |
| 4792 while (!s_sleeperRunning) { | |
| 4793 testing::yieldCurrentThread(); | |
| 4794 } | |
| 4795 | |
| 4796 { | |
| 4797 // Expect the first attempt to park the sleeping thread to fail | |
| 4798 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 4799 EXPECT_FALSE(scope.allThreadsParked()); | |
| 4800 } | |
| 4801 | |
| 4802 s_sleeperDone = true; | |
| 4803 | |
| 4804 // Wait for the sleeper to finish. | |
| 4805 while (s_sleeperRunning) { | |
| 4806 // We enter the safepoint here since the sleeper thread will detach | |
| 4807 // causing it to GC. | |
| 4808 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | |
| 4809 testing::yieldCurrentThread(); | |
| 4810 } | |
| 4811 | |
| 4812 { | |
| 4813 // Since the sleeper thread has detached this is the only thread. | |
| 4814 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 4815 EXPECT_TRUE(scope.allThreadsParked()); | |
| 4816 } | |
| 4817 } | |
| 4818 | |
| 4819 private: | |
| 4820 static void sleeperMainFunc() { | |
| 4821 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); | |
| 4822 s_sleeperRunning = true; | |
| 4823 | |
| 4824 // Simulate a long running op that is not entering a safepoint. | |
| 4825 while (!s_sleeperDone) { | |
| 4826 testing::yieldCurrentThread(); | |
| 4827 } | |
| 4828 | |
| 4829 ThreadState::detachCurrentThread(); | |
| 4830 s_sleeperRunning = false; | |
| 4831 } | |
| 4832 | |
| 4833 static volatile bool s_sleeperRunning; | |
| 4834 static volatile bool s_sleeperDone; | |
| 4835 }; | |
| 4836 | |
| 4837 volatile bool GCParkingThreadTester::s_sleeperRunning = false; | |
| 4838 volatile bool GCParkingThreadTester::s_sleeperDone = false; | |
| 4839 | |
| 4840 TEST(HeapTest, GCParkingTimeout) { | |
| 4841 GCParkingThreadTester::test(); | |
| 4842 } | |
| 4843 | |
| 4844 TEST(HeapTest, NeedsAdjustAndMark) { | 4783 TEST(HeapTest, NeedsAdjustAndMark) { |
| 4845 // class Mixin : public GarbageCollectedMixin {}; | 4784 // class Mixin : public GarbageCollectedMixin {}; |
| 4846 static_assert(NeedsAdjustAndMark<Mixin>::value, | 4785 static_assert(NeedsAdjustAndMark<Mixin>::value, |
| 4847 "A Mixin pointer needs adjustment"); | 4786 "A Mixin pointer needs adjustment"); |
| 4848 static_assert(NeedsAdjustAndMark<Mixin>::value, | 4787 static_assert(NeedsAdjustAndMark<Mixin>::value, |
| 4849 "A const Mixin pointer needs adjustment"); | 4788 "A const Mixin pointer needs adjustment"); |
| 4850 | 4789 |
| 4851 // class SimpleObject : public GarbageCollected<SimpleObject> {}; | 4790 // class SimpleObject : public GarbageCollected<SimpleObject> {}; |
| 4852 static_assert(!NeedsAdjustAndMark<SimpleObject>::value, | 4791 static_assert(!NeedsAdjustAndMark<SimpleObject>::value, |
| 4853 "A SimpleObject pointer does not need adjustment"); | 4792 "A SimpleObject pointer does not need adjustment"); |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5462 | 5401 |
| 5463 static void parkWorkerThread() { | 5402 static void parkWorkerThread() { |
| 5464 workerThreadCondition().wait(workerThreadMutex()); | 5403 workerThreadCondition().wait(workerThreadMutex()); |
| 5465 } | 5404 } |
| 5466 | 5405 |
| 5467 static void wakeWorkerThread() { | 5406 static void wakeWorkerThread() { |
| 5468 MutexLocker locker(workerThreadMutex()); | 5407 MutexLocker locker(workerThreadMutex()); |
| 5469 workerThreadCondition().signal(); | 5408 workerThreadCondition().signal(); |
| 5470 } | 5409 } |
| 5471 | 5410 |
| 5472 class DeadBitTester { | |
|
haraken
2017/01/12 04:26:33
Yeah, removing this test makes sense.
Sigbjorn: I
sof
2017/01/12 08:29:30
I think that's correct also. completeSweep() will
| |
| 5473 public: | |
| 5474 static void test() { | |
| 5475 IntWrapper::s_destructorCalls = 0; | |
| 5476 | |
| 5477 MutexLocker locker(mainThreadMutex()); | |
| 5478 std::unique_ptr<WebThread> workerThread = WTF::wrapUnique( | |
| 5479 Platform::current()->createThread("Test Worker Thread")); | |
| 5480 workerThread->getWebTaskRunner()->postTask( | |
| 5481 BLINK_FROM_HERE, crossThreadBind(workerThreadMain)); | |
| 5482 | |
| 5483 // Wait for the worker thread to have done its initialization, | |
| 5484 // IE. the worker allocates an object and then throw aways any | |
| 5485 // pointers to it. | |
| 5486 parkMainThread(); | |
| 5487 | |
| 5488 // Now do a GC. This will not find the worker threads object since it | |
| 5489 // is not referred from any of the threads. Even a conservative | |
| 5490 // GC will not find it. | |
| 5491 // Also at this point the worker is waiting for the main thread | |
| 5492 // to be parked and will not do any sweep of its heap. | |
| 5493 preciselyCollectGarbage(); | |
| 5494 | |
| 5495 // Since the worker thread is not sweeping the worker object should | |
| 5496 // not have been finalized. | |
| 5497 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | |
| 5498 | |
| 5499 // Put the worker thread's object address on the stack and do a | |
| 5500 // conservative GC. This should find the worker object, but since | |
| 5501 // it was dead in the previous GC it should not be traced in this | |
| 5502 // GC. | |
| 5503 uintptr_t stackPtrValue = s_workerObjectPointer; | |
| 5504 s_workerObjectPointer = 0; | |
| 5505 DCHECK(stackPtrValue); | |
| 5506 conservativelyCollectGarbage(); | |
| 5507 | |
| 5508 // Since the worker thread is not sweeping the worker object should | |
| 5509 // not have been finalized. | |
| 5510 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | |
| 5511 | |
| 5512 // Wake up the worker thread so it can continue with its sweeping. | |
| 5513 // This should finalized the worker object which we test below. | |
| 5514 // The worker thread will go back to sleep once sweeping to ensure | |
| 5515 // we don't have thread local GCs until after validating the destructor | |
| 5516 // was called. | |
| 5517 wakeWorkerThread(); | |
| 5518 | |
| 5519 // Wait for the worker thread to sweep its heaps before checking. | |
| 5520 parkMainThread(); | |
| 5521 EXPECT_EQ(1, IntWrapper::s_destructorCalls); | |
| 5522 | |
| 5523 // Wake up the worker to allow it thread to continue with thread | |
| 5524 // shutdown. | |
| 5525 wakeWorkerThread(); | |
| 5526 } | |
| 5527 | |
| 5528 private: | |
| 5529 static void workerThreadMain() { | |
| 5530 MutexLocker locker(workerThreadMutex()); | |
| 5531 | |
| 5532 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); | |
| 5533 | |
| 5534 { | |
| 5535 // Create a worker object that is not kept alive except the | |
| 5536 // main thread will keep it as an integer value on its stack. | |
| 5537 IntWrapper* workerObject = IntWrapper::create(42); | |
| 5538 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); | |
| 5539 } | |
| 5540 | |
| 5541 // Signal the main thread that the worker is done with its allocation. | |
| 5542 wakeMainThread(); | |
| 5543 | |
| 5544 { | |
| 5545 // Wait for the main thread to do two GCs without sweeping this thread | |
| 5546 // heap. The worker waits within a safepoint, but there is no sweeping | |
| 5547 // until leaving the safepoint scope. | |
| 5548 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 5549 parkWorkerThread(); | |
| 5550 } | |
| 5551 | |
| 5552 // Wake up the main thread when done sweeping. | |
| 5553 wakeMainThread(); | |
| 5554 | |
| 5555 // Wait with detach until the main thread says so. This is not strictly | |
| 5556 // necessary, but it means the worker thread will not do its thread local | |
| 5557 // GCs just yet, making it easier to reason about that no new GC has | |
| 5558 // occurred and the above sweep was the one finalizing the worker object. | |
| 5559 parkWorkerThread(); | |
| 5560 | |
| 5561 ThreadState::detachCurrentThread(); | |
| 5562 } | |
| 5563 | |
| 5564 static volatile uintptr_t s_workerObjectPointer; | |
| 5565 }; | |
| 5566 | |
| 5567 volatile uintptr_t DeadBitTester::s_workerObjectPointer = 0; | |
| 5568 | |
| 5569 TEST(HeapTest, ObjectDeadBit) { | |
| 5570 DeadBitTester::test(); | |
| 5571 } | |
| 5572 | |
| 5573 class ThreadedStrongificationTester { | 5411 class ThreadedStrongificationTester { |
| 5574 public: | 5412 public: |
| 5575 static void test() { | 5413 static void test() { |
| 5576 IntWrapper::s_destructorCalls = 0; | 5414 IntWrapper::s_destructorCalls = 0; |
| 5577 | 5415 |
| 5578 MutexLocker locker(mainThreadMutex()); | 5416 MutexLocker locker(mainThreadMutex()); |
| 5579 std::unique_ptr<WebThread> workerThread = WTF::wrapUnique( | 5417 std::unique_ptr<WebThread> workerThread = WTF::wrapUnique( |
| 5580 Platform::current()->createThread("Test Worker Thread")); | 5418 Platform::current()->createThread("Test Worker Thread")); |
| 5581 workerThread->getWebTaskRunner()->postTask( | 5419 workerThread->getWebTaskRunner()->postTask( |
| 5582 BLINK_FROM_HERE, crossThreadBind(workerThreadMain)); | 5420 BLINK_FROM_HERE, crossThreadBind(workerThreadMain)); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5641 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 5479 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); |
| 5642 parkWorkerThread(); | 5480 parkWorkerThread(); |
| 5643 } | 5481 } |
| 5644 | 5482 |
| 5645 return weakCollection; | 5483 return weakCollection; |
| 5646 } | 5484 } |
| 5647 | 5485 |
| 5648 static void workerThreadMain() { | 5486 static void workerThreadMain() { |
| 5649 MutexLocker locker(workerThreadMutex()); | 5487 MutexLocker locker(workerThreadMutex()); |
| 5650 | 5488 |
| 5651 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); | 5489 ThreadState::attachCurrentThread(); |
| 5652 | 5490 |
| 5653 { | 5491 { |
| 5654 Persistent<WeakCollectionType> collection = allocateCollection(); | 5492 Persistent<WeakCollectionType> collection = allocateCollection(); |
| 5655 { | 5493 { |
| 5656 // Prevent weak processing with an iterator and GC. | 5494 // Prevent weak processing with an iterator and GC. |
| 5657 WeakCollectionType::iterator it = collection->begin(); | 5495 WeakCollectionType::iterator it = collection->begin(); |
| 5658 conservativelyCollectGarbage(); | 5496 conservativelyCollectGarbage(); |
| 5659 | 5497 |
| 5660 // The backing should be strongified because of the iterator. | 5498 // The backing should be strongified because of the iterator. |
| 5661 EXPECT_EQ(6u, collection->size()); | 5499 EXPECT_EQ(6u, collection->size()); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5756 | 5594 |
| 5757 static int s_destructorCalls; | 5595 static int s_destructorCalls; |
| 5758 DEFINE_INLINE_TRACE() {} | 5596 DEFINE_INLINE_TRACE() {} |
| 5759 | 5597 |
| 5760 private: | 5598 private: |
| 5761 DestructorLockingObject() {} | 5599 DestructorLockingObject() {} |
| 5762 }; | 5600 }; |
| 5763 | 5601 |
| 5764 int DestructorLockingObject::s_destructorCalls = 0; | 5602 int DestructorLockingObject::s_destructorCalls = 0; |
| 5765 | 5603 |
| 5766 class RecursiveLockingTester { | |
| 5767 public: | |
| 5768 static void test() { | |
| 5769 DestructorLockingObject::s_destructorCalls = 0; | |
| 5770 | |
| 5771 MutexLocker locker(mainThreadMutex()); | |
| 5772 std::unique_ptr<WebThread> workerThread = WTF::wrapUnique( | |
| 5773 Platform::current()->createThread("Test Worker Thread")); | |
| 5774 workerThread->getWebTaskRunner()->postTask( | |
| 5775 BLINK_FROM_HERE, crossThreadBind(workerThreadMain)); | |
| 5776 | |
| 5777 // Park the main thread until the worker thread has initialized. | |
| 5778 parkMainThread(); | |
| 5779 | |
| 5780 { | |
| 5781 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); | |
| 5782 | |
| 5783 // Let the worker try to acquire the above mutex. It won't get it | |
| 5784 // until the main thread has done its GC. | |
| 5785 wakeWorkerThread(); | |
| 5786 | |
| 5787 preciselyCollectGarbage(); | |
| 5788 | |
| 5789 // The worker thread should not have swept yet since it is waiting | |
| 5790 // to get the global mutex. | |
| 5791 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); | |
| 5792 } | |
| 5793 // At this point the main thread releases the global lock and the worker | |
| 5794 // can acquire it and do its sweep of its arenas. Just wait for the worker | |
| 5795 // to complete its sweep and check the result. | |
| 5796 parkMainThread(); | |
| 5797 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); | |
| 5798 } | |
| 5799 | |
| 5800 private: | |
| 5801 static void workerThreadMain() { | |
| 5802 MutexLocker locker(workerThreadMutex()); | |
| 5803 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); | |
| 5804 | |
| 5805 DestructorLockingObject* dlo = DestructorLockingObject::create(); | |
| 5806 DCHECK(dlo); | |
| 5807 | |
| 5808 // Wake up the main thread which is waiting for the worker to do its | |
| 5809 // allocation. | |
| 5810 wakeMainThread(); | |
| 5811 | |
| 5812 // Wait for the main thread to get the global lock to ensure it has | |
| 5813 // it before the worker tries to acquire it. We want the worker to | |
| 5814 // block in the SafePointAwareMutexLocker until the main thread | |
| 5815 // has done a GC. The GC will not mark the "dlo" object since the worker | |
| 5816 // is entering the safepoint with NoHeapPointersOnStack. When the worker | |
| 5817 // subsequently gets the global lock and leaves the safepoint it will | |
| 5818 // sweep its heap and finalize "dlo". The destructor of "dlo" will try | |
| 5819 // to acquire the same global lock that the thread just got and deadlock | |
| 5820 // unless the global lock is recursive. | |
| 5821 parkWorkerThread(); | |
| 5822 SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), | |
| 5823 BlinkGC::NoHeapPointersOnStack); | |
| 5824 | |
| 5825 // We won't get here unless the lock is recursive since the sweep done | |
| 5826 // in the constructor of SafePointAwareMutexLocker after | |
| 5827 // getting the lock will not complete given the "dlo" destructor is | |
| 5828 // waiting to get the same lock. | |
| 5829 // Tell the main thread the worker has done its sweep. | |
| 5830 wakeMainThread(); | |
| 5831 | |
| 5832 ThreadState::detachCurrentThread(); | |
| 5833 } | |
| 5834 | |
| 5835 static volatile IntWrapper* s_workerObjectPointer; | |
| 5836 }; | |
| 5837 | |
| 5838 TEST(HeapTest, RecursiveMutex) { | |
| 5839 RecursiveLockingTester::test(); | |
| 5840 } | |
| 5841 | |
| 5842 template <typename T> | 5604 template <typename T> |
| 5843 class TraceIfNeededTester | 5605 class TraceIfNeededTester |
| 5844 : public GarbageCollectedFinalized<TraceIfNeededTester<T>> { | 5606 : public GarbageCollectedFinalized<TraceIfNeededTester<T>> { |
| 5845 public: | 5607 public: |
| 5846 static TraceIfNeededTester<T>* create() { | 5608 static TraceIfNeededTester<T>* create() { |
| 5847 return new TraceIfNeededTester<T>(); | 5609 return new TraceIfNeededTester<T>(); |
| 5848 } | 5610 } |
| 5849 static TraceIfNeededTester<T>* create(const T& obj) { | 5611 static TraceIfNeededTester<T>* create(const T& obj) { |
| 5850 return new TraceIfNeededTester<T>(obj); | 5612 return new TraceIfNeededTester<T>(obj); |
| 5851 } | 5613 } |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6494 preciselyCollectGarbage(); | 6256 preciselyCollectGarbage(); |
| 6495 EXPECT_FALSE(holder->object()); | 6257 EXPECT_FALSE(holder->object()); |
| 6496 } | 6258 } |
| 6497 | 6259 |
| 6498 namespace { | 6260 namespace { |
| 6499 | 6261 |
| 6500 void workerThreadMainForCrossThreadWeakPersistentTest( | 6262 void workerThreadMainForCrossThreadWeakPersistentTest( |
| 6501 DestructorLockingObject** object) { | 6263 DestructorLockingObject** object) { |
| 6502 // Step 2: Create an object and store the pointer. | 6264 // Step 2: Create an object and store the pointer. |
| 6503 MutexLocker locker(workerThreadMutex()); | 6265 MutexLocker locker(workerThreadMutex()); |
| 6504 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); | 6266 ThreadState::attachCurrentThread(); |
| 6505 *object = DestructorLockingObject::create(); | 6267 *object = DestructorLockingObject::create(); |
| 6506 wakeMainThread(); | 6268 wakeMainThread(); |
| 6507 parkWorkerThread(); | 6269 parkWorkerThread(); |
| 6508 | 6270 |
| 6509 // Step 4: Run a GC. | 6271 // Step 4: Run a GC. |
| 6510 ThreadState::current()->collectGarbage( | 6272 ThreadState::current()->collectGarbage( |
| 6511 BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, BlinkGC::ForcedGC); | 6273 BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, BlinkGC::ForcedGC); |
| 6512 wakeMainThread(); | 6274 wakeMainThread(); |
| 6513 parkWorkerThread(); | 6275 parkWorkerThread(); |
| 6514 | 6276 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6624 static void test() { | 6386 static void test() { |
| 6625 IntWrapper::s_destructorCalls = 0; | 6387 IntWrapper::s_destructorCalls = 0; |
| 6626 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester); | 6388 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester); |
| 6627 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls); | 6389 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls); |
| 6628 } | 6390 } |
| 6629 | 6391 |
| 6630 private: | 6392 private: |
| 6631 void runWhileAttached(); | 6393 void runWhileAttached(); |
| 6632 | 6394 |
| 6633 void runThread() override { | 6395 void runThread() override { |
| 6634 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); | 6396 ThreadState::attachCurrentThread(); |
| 6635 EXPECT_EQ(42, threadSpecificIntWrapper().value()); | 6397 EXPECT_EQ(42, threadSpecificIntWrapper().value()); |
| 6636 runWhileAttached(); | 6398 runWhileAttached(); |
| 6637 ThreadState::detachCurrentThread(); | 6399 ThreadState::detachCurrentThread(); |
| 6638 atomicDecrement(&m_threadsToFinish); | 6400 atomicDecrement(&m_threadsToFinish); |
| 6639 } | 6401 } |
| 6640 | 6402 |
| 6641 class HeapObject; | 6403 class HeapObject; |
| 6642 friend class HeapObject; | 6404 friend class HeapObject; |
| 6643 | 6405 |
| 6644 using WeakHeapObjectSet = PersistentHeapHashSet<WeakMember<HeapObject>>; | 6406 using WeakHeapObjectSet = PersistentHeapHashSet<WeakMember<HeapObject>>; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6805 "HeapVector"); | 6567 "HeapVector"); |
| 6806 static_assert( | 6568 static_assert( |
| 6807 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, | 6569 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, |
| 6808 "HeapDeque"); | 6570 "HeapDeque"); |
| 6809 static_assert(WTF::IsGarbageCollectedType< | 6571 static_assert(WTF::IsGarbageCollectedType< |
| 6810 HeapTerminatedArray<Member<IntWrapper>>>::value, | 6572 HeapTerminatedArray<Member<IntWrapper>>>::value, |
| 6811 "HeapTerminatedArray"); | 6573 "HeapTerminatedArray"); |
| 6812 } | 6574 } |
| 6813 | 6575 |
| 6814 } // namespace blink | 6576 } // namespace blink |
| OLD | NEW |