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 |