| 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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 } | 541 } |
| 542 | 542 |
| 543 void addGlobalPersistent() | 543 void addGlobalPersistent() |
| 544 { | 544 { |
| 545 MutexLocker lock(m_mutex); | 545 MutexLocker lock(m_mutex); |
| 546 m_crossPersistents.append(createGlobalPersistent(0x2a2a2a2a)); | 546 m_crossPersistents.append(createGlobalPersistent(0x2a2a2a2a)); |
| 547 } | 547 } |
| 548 | 548 |
| 549 void runThread() override | 549 void runThread() override |
| 550 { | 550 { |
| 551 ThreadState::attachCurrentThread(false); | 551 ThreadState::attachCurrentThread(MainThreadHeapMode); |
| 552 | 552 |
| 553 // Add a cross-thread persistent from this thread; the test object | 553 // Add a cross-thread persistent from this thread; the test object |
| 554 // verifies that it will have been cleared out after the threads | 554 // verifies that it will have been cleared out after the threads |
| 555 // have all detached, running their termination GCs while doing so. | 555 // have all detached, running their termination GCs while doing so. |
| 556 addGlobalPersistent(); | 556 addGlobalPersistent(); |
| 557 | 557 |
| 558 int gcCount = 0; | 558 int gcCount = 0; |
| 559 while (!done()) { | 559 while (!done()) { |
| 560 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 560 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
| 561 { | 561 { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 class ThreadedWeaknessTester : public ThreadedTesterBase { | 598 class ThreadedWeaknessTester : public ThreadedTesterBase { |
| 599 public: | 599 public: |
| 600 static void test() | 600 static void test() |
| 601 { | 601 { |
| 602 ThreadedTesterBase::test(new ThreadedWeaknessTester); | 602 ThreadedTesterBase::test(new ThreadedWeaknessTester); |
| 603 } | 603 } |
| 604 | 604 |
| 605 private: | 605 private: |
| 606 void runThread() override | 606 void runThread() override |
| 607 { | 607 { |
| 608 ThreadState::attachCurrentThread(false); | 608 ThreadState::attachCurrentThread(MainThreadHeapMode); |
| 609 | 609 |
| 610 int gcCount = 0; | 610 int gcCount = 0; |
| 611 while (!done()) { | 611 while (!done()) { |
| 612 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 612 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
| 613 { | 613 { |
| 614 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we
akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; | 614 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we
akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; |
| 615 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; | 615 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; |
| 616 | 616 |
| 617 for (int i = 0; i < numberOfAllocations; i++) { | 617 for (int i = 0; i < numberOfAllocations; i++) { |
| 618 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); | 618 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 explicit PersistentChain(int count) | 692 explicit PersistentChain(int count) |
| 693 { | 693 { |
| 694 m_refCountedChain = adoptRef(RefCountedChain::create(count)); | 694 m_refCountedChain = adoptRef(RefCountedChain::create(count)); |
| 695 } | 695 } |
| 696 | 696 |
| 697 RefPtr<RefCountedChain> m_refCountedChain; | 697 RefPtr<RefCountedChain> m_refCountedChain; |
| 698 }; | 698 }; |
| 699 | 699 |
| 700 void runThread() override | 700 void runThread() override |
| 701 { | 701 { |
| 702 ThreadState::attachCurrentThread(false); | 702 ThreadState::attachCurrentThread(MainThreadHeapMode); |
| 703 | 703 |
| 704 PersistentChain::create(100); | 704 PersistentChain::create(100); |
| 705 | 705 |
| 706 // Upon thread detach, GCs will run until all persistents have been | 706 // Upon thread detach, GCs will run until all persistents have been |
| 707 // released. We verify that the draining of persistents proceeds | 707 // released. We verify that the draining of persistents proceeds |
| 708 // as expected by dropping one Persistent<> per GC until there | 708 // as expected by dropping one Persistent<> per GC until there |
| 709 // are none left. | 709 // are none left. |
| 710 ThreadState::detachCurrentThread(); | 710 ThreadState::detachCurrentThread(); |
| 711 atomicDecrement(&m_threadsToFinish); | 711 atomicDecrement(&m_threadsToFinish); |
| 712 } | 712 } |
| (...skipping 4312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5025 { | 5025 { |
| 5026 // Since the sleeper thread has detached this is the only thread. | 5026 // Since the sleeper thread has detached this is the only thread. |
| 5027 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); | 5027 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); |
| 5028 EXPECT_TRUE(scope.allThreadsParked()); | 5028 EXPECT_TRUE(scope.allThreadsParked()); |
| 5029 } | 5029 } |
| 5030 } | 5030 } |
| 5031 | 5031 |
| 5032 private: | 5032 private: |
| 5033 static void sleeperMainFunc() | 5033 static void sleeperMainFunc() |
| 5034 { | 5034 { |
| 5035 ThreadState::attachCurrentThread(false); | 5035 ThreadState::attachCurrentThread(MainThreadHeapMode); |
| 5036 s_sleeperRunning = true; | 5036 s_sleeperRunning = true; |
| 5037 | 5037 |
| 5038 // Simulate a long running op that is not entering a safepoint. | 5038 // Simulate a long running op that is not entering a safepoint. |
| 5039 while (!s_sleeperDone) { | 5039 while (!s_sleeperDone) { |
| 5040 testing::yieldCurrentThread(); | 5040 testing::yieldCurrentThread(); |
| 5041 } | 5041 } |
| 5042 | 5042 |
| 5043 ThreadState::detachCurrentThread(); | 5043 ThreadState::detachCurrentThread(); |
| 5044 s_sleeperRunning = false; | 5044 s_sleeperRunning = false; |
| 5045 } | 5045 } |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5710 // shutdown. | 5710 // shutdown. |
| 5711 wakeWorkerThread(); | 5711 wakeWorkerThread(); |
| 5712 } | 5712 } |
| 5713 | 5713 |
| 5714 private: | 5714 private: |
| 5715 | 5715 |
| 5716 static void workerThreadMain() | 5716 static void workerThreadMain() |
| 5717 { | 5717 { |
| 5718 MutexLocker locker(workerThreadMutex()); | 5718 MutexLocker locker(workerThreadMutex()); |
| 5719 | 5719 |
| 5720 ThreadState::attachCurrentThread(false); | 5720 ThreadState::attachCurrentThread(MainThreadHeapMode); |
| 5721 | 5721 |
| 5722 { | 5722 { |
| 5723 // Create a worker object that is not kept alive except the | 5723 // Create a worker object that is not kept alive except the |
| 5724 // main thread will keep it as an integer value on its stack. | 5724 // main thread will keep it as an integer value on its stack. |
| 5725 IntWrapper* workerObject = IntWrapper::create(42); | 5725 IntWrapper* workerObject = IntWrapper::create(42); |
| 5726 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); | 5726 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); |
| 5727 } | 5727 } |
| 5728 | 5728 |
| 5729 // Signal the main thread that the worker is done with its allocation. | 5729 // Signal the main thread that the worker is done with its allocation. |
| 5730 wakeMainThread(); | 5730 wakeMainThread(); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5831 parkWorkerThread(); | 5831 parkWorkerThread(); |
| 5832 } | 5832 } |
| 5833 | 5833 |
| 5834 return weakCollection; | 5834 return weakCollection; |
| 5835 } | 5835 } |
| 5836 | 5836 |
| 5837 static void workerThreadMain() | 5837 static void workerThreadMain() |
| 5838 { | 5838 { |
| 5839 MutexLocker locker(workerThreadMutex()); | 5839 MutexLocker locker(workerThreadMutex()); |
| 5840 | 5840 |
| 5841 ThreadState::attachCurrentThread(false); | 5841 ThreadState::attachCurrentThread(MainThreadHeapMode); |
| 5842 | 5842 |
| 5843 { | 5843 { |
| 5844 Persistent<WeakCollectionType> collection = allocateCollection(); | 5844 Persistent<WeakCollectionType> collection = allocateCollection(); |
| 5845 { | 5845 { |
| 5846 // Prevent weak processing with an iterator and GC. | 5846 // Prevent weak processing with an iterator and GC. |
| 5847 WeakCollectionType::iterator it = collection->begin(); | 5847 WeakCollectionType::iterator it = collection->begin(); |
| 5848 conservativelyCollectGarbage(); | 5848 conservativelyCollectGarbage(); |
| 5849 | 5849 |
| 5850 // The backing should be strongified because of the iterator. | 5850 // The backing should be strongified because of the iterator. |
| 5851 EXPECT_EQ(6u, collection->size()); | 5851 EXPECT_EQ(6u, collection->size()); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5992 // can acquire it and do its sweep of its arenas. Just wait for the work
er | 5992 // can acquire it and do its sweep of its arenas. Just wait for the work
er |
| 5993 // to complete its sweep and check the result. | 5993 // to complete its sweep and check the result. |
| 5994 parkMainThread(); | 5994 parkMainThread(); |
| 5995 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); | 5995 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); |
| 5996 } | 5996 } |
| 5997 | 5997 |
| 5998 private: | 5998 private: |
| 5999 static void workerThreadMain() | 5999 static void workerThreadMain() |
| 6000 { | 6000 { |
| 6001 MutexLocker locker(workerThreadMutex()); | 6001 MutexLocker locker(workerThreadMutex()); |
| 6002 ThreadState::attachCurrentThread(false); | 6002 ThreadState::attachCurrentThread(MainThreadHeapMode); |
| 6003 | 6003 |
| 6004 DestructorLockingObject* dlo = DestructorLockingObject::create(); | 6004 DestructorLockingObject* dlo = DestructorLockingObject::create(); |
| 6005 ASSERT_UNUSED(dlo, dlo); | 6005 ASSERT_UNUSED(dlo, dlo); |
| 6006 | 6006 |
| 6007 // Wake up the main thread which is waiting for the worker to do its | 6007 // Wake up the main thread which is waiting for the worker to do its |
| 6008 // allocation. | 6008 // allocation. |
| 6009 wakeMainThread(); | 6009 wakeMainThread(); |
| 6010 | 6010 |
| 6011 // Wait for the main thread to get the global lock to ensure it has | 6011 // Wait for the main thread to get the global lock to ensure it has |
| 6012 // it before the worker tries to acquire it. We want the worker to | 6012 // it before the worker tries to acquire it. We want the worker to |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6684 preciselyCollectGarbage(); | 6684 preciselyCollectGarbage(); |
| 6685 EXPECT_FALSE(holder->object()); | 6685 EXPECT_FALSE(holder->object()); |
| 6686 } | 6686 } |
| 6687 | 6687 |
| 6688 namespace { | 6688 namespace { |
| 6689 | 6689 |
| 6690 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject**
object) | 6690 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject**
object) |
| 6691 { | 6691 { |
| 6692 // Step 2: Create an object and store the pointer. | 6692 // Step 2: Create an object and store the pointer. |
| 6693 MutexLocker locker(workerThreadMutex()); | 6693 MutexLocker locker(workerThreadMutex()); |
| 6694 ThreadState::attachCurrentThread(false); | 6694 ThreadState::attachCurrentThread(MainThreadHeapMode); |
| 6695 *object = DestructorLockingObject::create(); | 6695 *object = DestructorLockingObject::create(); |
| 6696 wakeMainThread(); | 6696 wakeMainThread(); |
| 6697 parkWorkerThread(); | 6697 parkWorkerThread(); |
| 6698 | 6698 |
| 6699 // Step 4: Run a GC. | 6699 // Step 4: Run a GC. |
| 6700 ThreadState::current()->collectGarbage(BlinkGC::NoHeapPointersOnStack, Blink
GC::GCWithSweep, BlinkGC::ForcedGC); | 6700 ThreadState::current()->collectGarbage(BlinkGC::NoHeapPointersOnStack, Blink
GC::GCWithSweep, BlinkGC::ForcedGC); |
| 6701 wakeMainThread(); | 6701 wakeMainThread(); |
| 6702 parkWorkerThread(); | 6702 parkWorkerThread(); |
| 6703 | 6703 |
| 6704 // Step 6: Finish. | 6704 // Step 6: Finish. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6810 IntWrapper::s_destructorCalls = 0; | 6810 IntWrapper::s_destructorCalls = 0; |
| 6811 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester); | 6811 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester); |
| 6812 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls); | 6812 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls); |
| 6813 } | 6813 } |
| 6814 | 6814 |
| 6815 private: | 6815 private: |
| 6816 void runWhileAttached(); | 6816 void runWhileAttached(); |
| 6817 | 6817 |
| 6818 void runThread() override | 6818 void runThread() override |
| 6819 { | 6819 { |
| 6820 ThreadState::attachCurrentThread(false); | 6820 ThreadState::attachCurrentThread(MainThreadHeapMode); |
| 6821 EXPECT_EQ(42, threadSpecificIntWrapper().value()); | 6821 EXPECT_EQ(42, threadSpecificIntWrapper().value()); |
| 6822 runWhileAttached(); | 6822 runWhileAttached(); |
| 6823 ThreadState::detachCurrentThread(); | 6823 ThreadState::detachCurrentThread(); |
| 6824 atomicDecrement(&m_threadsToFinish); | 6824 atomicDecrement(&m_threadsToFinish); |
| 6825 } | 6825 } |
| 6826 | 6826 |
| 6827 class HeapObject; | 6827 class HeapObject; |
| 6828 friend class HeapObject; | 6828 friend class HeapObject; |
| 6829 | 6829 |
| 6830 using WeakHeapObjectSet = PersistentHeapHashSet<WeakMember<HeapObject>>; | 6830 using WeakHeapObjectSet = PersistentHeapHashSet<WeakMember<HeapObject>>; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6982 static_assert(WTF::IsGarbageCollectedType<HeapLinkedHashSet<Member<IntWrappe
r>>>::value, "HeapLinkedHashSet"); | 6982 static_assert(WTF::IsGarbageCollectedType<HeapLinkedHashSet<Member<IntWrappe
r>>>::value, "HeapLinkedHashSet"); |
| 6983 static_assert(WTF::IsGarbageCollectedType<HeapListHashSet<Member<IntWrapper>
>>::value, "HeapListHashSet"); | 6983 static_assert(WTF::IsGarbageCollectedType<HeapListHashSet<Member<IntWrapper>
>>::value, "HeapListHashSet"); |
| 6984 static_assert(WTF::IsGarbageCollectedType<HeapHashCountedSet<Member<IntWrapp
er>>>::value, "HeapHashCountedSet"); | 6984 static_assert(WTF::IsGarbageCollectedType<HeapHashCountedSet<Member<IntWrapp
er>>>::value, "HeapHashCountedSet"); |
| 6985 static_assert(WTF::IsGarbageCollectedType<HeapHashMap<int, Member<IntWrapper
>>>::value, "HeapHashMap"); | 6985 static_assert(WTF::IsGarbageCollectedType<HeapHashMap<int, Member<IntWrapper
>>>::value, "HeapHashMap"); |
| 6986 static_assert(WTF::IsGarbageCollectedType<HeapVector<Member<IntWrapper>>>::v
alue, "HeapVector"); | 6986 static_assert(WTF::IsGarbageCollectedType<HeapVector<Member<IntWrapper>>>::v
alue, "HeapVector"); |
| 6987 static_assert(WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::va
lue, "HeapDeque"); | 6987 static_assert(WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::va
lue, "HeapDeque"); |
| 6988 static_assert(WTF::IsGarbageCollectedType<HeapTerminatedArray<Member<IntWrap
per>>>::value, "HeapTerminatedArray"); | 6988 static_assert(WTF::IsGarbageCollectedType<HeapTerminatedArray<Member<IntWrap
per>>>::value, "HeapTerminatedArray"); |
| 6989 } | 6989 } |
| 6990 | 6990 |
| 6991 } // namespace blink | 6991 } // namespace blink |
| OLD | NEW |