| 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 10 matching lines...) Expand all Loading... |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "platform/ThreadSafeFunctional.h" | 31 #include "platform/CrossThreadFunctional.h" |
| 32 #include "platform/heap/Handle.h" | 32 #include "platform/heap/Handle.h" |
| 33 #include "platform/heap/Heap.h" | 33 #include "platform/heap/Heap.h" |
| 34 #include "platform/heap/HeapLinkedStack.h" | 34 #include "platform/heap/HeapLinkedStack.h" |
| 35 #include "platform/heap/HeapTerminatedArrayBuilder.h" | 35 #include "platform/heap/HeapTerminatedArrayBuilder.h" |
| 36 #include "platform/heap/SafePoint.h" | 36 #include "platform/heap/SafePoint.h" |
| 37 #include "platform/heap/SelfKeepAlive.h" | 37 #include "platform/heap/SelfKeepAlive.h" |
| 38 #include "platform/heap/ThreadState.h" | 38 #include "platform/heap/ThreadState.h" |
| 39 #include "platform/heap/Visitor.h" | 39 #include "platform/heap/Visitor.h" |
| 40 #include "platform/testing/UnitTestHelpers.h" | 40 #include "platform/testing/UnitTestHelpers.h" |
| 41 #include "public/platform/Platform.h" | 41 #include "public/platform/Platform.h" |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 int IntWrapper::s_destructorCalls = 0; | 463 int IntWrapper::s_destructorCalls = 0; |
| 464 int OffHeapInt::s_destructorCalls = 0; | 464 int OffHeapInt::s_destructorCalls = 0; |
| 465 | 465 |
| 466 class ThreadedTesterBase { | 466 class ThreadedTesterBase { |
| 467 protected: | 467 protected: |
| 468 static void test(ThreadedTesterBase* tester) | 468 static void test(ThreadedTesterBase* tester) |
| 469 { | 469 { |
| 470 Vector<std::unique_ptr<WebThread>, numberOfThreads> m_threads; | 470 Vector<std::unique_ptr<WebThread>, numberOfThreads> m_threads; |
| 471 for (int i = 0; i < numberOfThreads; i++) { | 471 for (int i = 0; i < numberOfThreads; i++) { |
| 472 m_threads.append(wrapUnique(Platform::current()->createThread("blink
gc testing thread"))); | 472 m_threads.append(wrapUnique(Platform::current()->createThread("blink
gc testing thread"))); |
| 473 m_threads.last()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, thre
adSafeBind(threadFunc, crossThreadUnretained(tester))); | 473 m_threads.last()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, cros
sThreadBind(threadFunc, crossThreadUnretained(tester))); |
| 474 } | 474 } |
| 475 while (tester->m_threadsToFinish) { | 475 while (tester->m_threadsToFinish) { |
| 476 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 476 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); |
| 477 testing::yieldCurrentThread(); | 477 testing::yieldCurrentThread(); |
| 478 } | 478 } |
| 479 delete tester; | 479 delete tester; |
| 480 } | 480 } |
| 481 | 481 |
| 482 virtual void runThread() = 0; | 482 virtual void runThread() = 0; |
| 483 | 483 |
| (...skipping 4472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4956 } | 4956 } |
| 4957 preciselyCollectGarbage(); | 4957 preciselyCollectGarbage(); |
| 4958 EXPECT_EQ(2, MixinA::s_traceCount); | 4958 EXPECT_EQ(2, MixinA::s_traceCount); |
| 4959 } | 4959 } |
| 4960 | 4960 |
| 4961 class GCParkingThreadTester { | 4961 class GCParkingThreadTester { |
| 4962 public: | 4962 public: |
| 4963 static void test() | 4963 static void test() |
| 4964 { | 4964 { |
| 4965 std::unique_ptr<WebThread> sleepingThread = wrapUnique(Platform::current
()->createThread("SleepingThread")); | 4965 std::unique_ptr<WebThread> sleepingThread = wrapUnique(Platform::current
()->createThread("SleepingThread")); |
| 4966 sleepingThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafe
Bind(sleeperMainFunc)); | 4966 sleepingThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, crossThrea
dBind(sleeperMainFunc)); |
| 4967 | 4967 |
| 4968 // Wait for the sleeper to run. | 4968 // Wait for the sleeper to run. |
| 4969 while (!s_sleeperRunning) { | 4969 while (!s_sleeperRunning) { |
| 4970 testing::yieldCurrentThread(); | 4970 testing::yieldCurrentThread(); |
| 4971 } | 4971 } |
| 4972 | 4972 |
| 4973 { | 4973 { |
| 4974 // Expect the first attempt to park the sleeping thread to fail | 4974 // Expect the first attempt to park the sleeping thread to fail |
| 4975 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); | 4975 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); |
| 4976 EXPECT_FALSE(scope.allThreadsParked()); | 4976 EXPECT_FALSE(scope.allThreadsParked()); |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5621 } | 5621 } |
| 5622 | 5622 |
| 5623 class DeadBitTester { | 5623 class DeadBitTester { |
| 5624 public: | 5624 public: |
| 5625 static void test() | 5625 static void test() |
| 5626 { | 5626 { |
| 5627 IntWrapper::s_destructorCalls = 0; | 5627 IntWrapper::s_destructorCalls = 0; |
| 5628 | 5628 |
| 5629 MutexLocker locker(mainThreadMutex()); | 5629 MutexLocker locker(mainThreadMutex()); |
| 5630 std::unique_ptr<WebThread> workerThread = wrapUnique(Platform::current()
->createThread("Test Worker Thread")); | 5630 std::unique_ptr<WebThread> workerThread = wrapUnique(Platform::current()
->createThread("Test Worker Thread")); |
| 5631 workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBi
nd(workerThreadMain)); | 5631 workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadB
ind(workerThreadMain)); |
| 5632 | 5632 |
| 5633 // Wait for the worker thread to have done its initialization, | 5633 // Wait for the worker thread to have done its initialization, |
| 5634 // IE. the worker allocates an object and then throw aways any | 5634 // IE. the worker allocates an object and then throw aways any |
| 5635 // pointers to it. | 5635 // pointers to it. |
| 5636 parkMainThread(); | 5636 parkMainThread(); |
| 5637 | 5637 |
| 5638 // Now do a GC. This will not find the worker threads object since it | 5638 // Now do a GC. This will not find the worker threads object since it |
| 5639 // is not referred from any of the threads. Even a conservative | 5639 // is not referred from any of the threads. Even a conservative |
| 5640 // GC will not find it. | 5640 // GC will not find it. |
| 5641 // Also at this point the worker is waiting for the main thread | 5641 // Also at this point the worker is waiting for the main thread |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5724 } | 5724 } |
| 5725 | 5725 |
| 5726 class ThreadedStrongificationTester { | 5726 class ThreadedStrongificationTester { |
| 5727 public: | 5727 public: |
| 5728 static void test() | 5728 static void test() |
| 5729 { | 5729 { |
| 5730 IntWrapper::s_destructorCalls = 0; | 5730 IntWrapper::s_destructorCalls = 0; |
| 5731 | 5731 |
| 5732 MutexLocker locker(mainThreadMutex()); | 5732 MutexLocker locker(mainThreadMutex()); |
| 5733 std::unique_ptr<WebThread> workerThread = wrapUnique(Platform::current()
->createThread("Test Worker Thread")); | 5733 std::unique_ptr<WebThread> workerThread = wrapUnique(Platform::current()
->createThread("Test Worker Thread")); |
| 5734 workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBi
nd(workerThreadMain)); | 5734 workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadB
ind(workerThreadMain)); |
| 5735 | 5735 |
| 5736 // Wait for the worker thread initialization. The worker | 5736 // Wait for the worker thread initialization. The worker |
| 5737 // allocates a weak collection where both collection and | 5737 // allocates a weak collection where both collection and |
| 5738 // contents are kept alive via persistent pointers. | 5738 // contents are kept alive via persistent pointers. |
| 5739 parkMainThread(); | 5739 parkMainThread(); |
| 5740 | 5740 |
| 5741 // Perform two garbage collections where the worker thread does | 5741 // Perform two garbage collections where the worker thread does |
| 5742 // not wake up in between. This will cause us to remove marks | 5742 // not wake up in between. This will cause us to remove marks |
| 5743 // and mark unmarked objects dead. The collection on the worker | 5743 // and mark unmarked objects dead. The collection on the worker |
| 5744 // heap is found through the persistent and the backing should | 5744 // heap is found through the persistent and the backing should |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5927 int DestructorLockingObject::s_destructorCalls = 0; | 5927 int DestructorLockingObject::s_destructorCalls = 0; |
| 5928 | 5928 |
| 5929 class RecursiveLockingTester { | 5929 class RecursiveLockingTester { |
| 5930 public: | 5930 public: |
| 5931 static void test() | 5931 static void test() |
| 5932 { | 5932 { |
| 5933 DestructorLockingObject::s_destructorCalls = 0; | 5933 DestructorLockingObject::s_destructorCalls = 0; |
| 5934 | 5934 |
| 5935 MutexLocker locker(mainThreadMutex()); | 5935 MutexLocker locker(mainThreadMutex()); |
| 5936 std::unique_ptr<WebThread> workerThread = wrapUnique(Platform::current()
->createThread("Test Worker Thread")); | 5936 std::unique_ptr<WebThread> workerThread = wrapUnique(Platform::current()
->createThread("Test Worker Thread")); |
| 5937 workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBi
nd(workerThreadMain)); | 5937 workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadB
ind(workerThreadMain)); |
| 5938 | 5938 |
| 5939 // Park the main thread until the worker thread has initialized. | 5939 // Park the main thread until the worker thread has initialized. |
| 5940 parkMainThread(); | 5940 parkMainThread(); |
| 5941 | 5941 |
| 5942 { | 5942 { |
| 5943 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); | 5943 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); |
| 5944 | 5944 |
| 5945 // Let the worker try to acquire the above mutex. It won't get it | 5945 // Let the worker try to acquire the above mutex. It won't get it |
| 5946 // until the main thread has done its GC. | 5946 // until the main thread has done its GC. |
| 5947 wakeWorkerThread(); | 5947 wakeWorkerThread(); |
| (...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6677 // Create an object in the worker thread, have a CrossThreadWeakPersistent p
ointing to it on the main thread, | 6677 // Create an object in the worker thread, have a CrossThreadWeakPersistent p
ointing to it on the main thread, |
| 6678 // clear the reference in the worker thread, run a GC in the worker thread,
and see if the | 6678 // clear the reference in the worker thread, run a GC in the worker thread,
and see if the |
| 6679 // CrossThreadWeakPersistent is cleared. | 6679 // CrossThreadWeakPersistent is cleared. |
| 6680 | 6680 |
| 6681 DestructorLockingObject::s_destructorCalls = 0; | 6681 DestructorLockingObject::s_destructorCalls = 0; |
| 6682 | 6682 |
| 6683 // Step 1: Initiate a worker thread, and wait for |object| to get allocated
on the worker thread. | 6683 // Step 1: Initiate a worker thread, and wait for |object| to get allocated
on the worker thread. |
| 6684 MutexLocker mainThreadMutexLocker(mainThreadMutex()); | 6684 MutexLocker mainThreadMutexLocker(mainThreadMutex()); |
| 6685 std::unique_ptr<WebThread> workerThread = wrapUnique(Platform::current()->cr
eateThread("Test Worker Thread")); | 6685 std::unique_ptr<WebThread> workerThread = wrapUnique(Platform::current()->cr
eateThread("Test Worker Thread")); |
| 6686 DestructorLockingObject* object = nullptr; | 6686 DestructorLockingObject* object = nullptr; |
| 6687 workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(w
orkerThreadMainForCrossThreadWeakPersistentTest, crossThreadUnretained(&object))
); | 6687 workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, crossThreadBind(
workerThreadMainForCrossThreadWeakPersistentTest, crossThreadUnretained(&object)
)); |
| 6688 parkMainThread(); | 6688 parkMainThread(); |
| 6689 | 6689 |
| 6690 // Step 3: Set up a CrossThreadWeakPersistent. | 6690 // Step 3: Set up a CrossThreadWeakPersistent. |
| 6691 ASSERT_TRUE(object); | 6691 ASSERT_TRUE(object); |
| 6692 CrossThreadWeakPersistent<DestructorLockingObject> crossThreadWeakPersistent
(object); | 6692 CrossThreadWeakPersistent<DestructorLockingObject> crossThreadWeakPersistent
(object); |
| 6693 object = nullptr; | 6693 object = nullptr; |
| 6694 { | 6694 { |
| 6695 SafePointAwareMutexLocker recursiveMutexLocker(recursiveMutex()); | 6695 SafePointAwareMutexLocker recursiveMutexLocker(recursiveMutex()); |
| 6696 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); | 6696 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); |
| 6697 } | 6697 } |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6946 static_assert(WTF::IsGarbageCollectedType<HeapLinkedHashSet<Member<IntWrappe
r>>>::value, "HeapLinkedHashSet"); | 6946 static_assert(WTF::IsGarbageCollectedType<HeapLinkedHashSet<Member<IntWrappe
r>>>::value, "HeapLinkedHashSet"); |
| 6947 static_assert(WTF::IsGarbageCollectedType<HeapListHashSet<Member<IntWrapper>
>>::value, "HeapListHashSet"); | 6947 static_assert(WTF::IsGarbageCollectedType<HeapListHashSet<Member<IntWrapper>
>>::value, "HeapListHashSet"); |
| 6948 static_assert(WTF::IsGarbageCollectedType<HeapHashCountedSet<Member<IntWrapp
er>>>::value, "HeapHashCountedSet"); | 6948 static_assert(WTF::IsGarbageCollectedType<HeapHashCountedSet<Member<IntWrapp
er>>>::value, "HeapHashCountedSet"); |
| 6949 static_assert(WTF::IsGarbageCollectedType<HeapHashMap<int, Member<IntWrapper
>>>::value, "HeapHashMap"); | 6949 static_assert(WTF::IsGarbageCollectedType<HeapHashMap<int, Member<IntWrapper
>>>::value, "HeapHashMap"); |
| 6950 static_assert(WTF::IsGarbageCollectedType<HeapVector<Member<IntWrapper>>>::v
alue, "HeapVector"); | 6950 static_assert(WTF::IsGarbageCollectedType<HeapVector<Member<IntWrapper>>>::v
alue, "HeapVector"); |
| 6951 static_assert(WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::va
lue, "HeapDeque"); | 6951 static_assert(WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::va
lue, "HeapDeque"); |
| 6952 static_assert(WTF::IsGarbageCollectedType<HeapTerminatedArray<Member<IntWrap
per>>>::value, "HeapTerminatedArray"); | 6952 static_assert(WTF::IsGarbageCollectedType<HeapTerminatedArray<Member<IntWrap
per>>>::value, "HeapTerminatedArray"); |
| 6953 } | 6953 } |
| 6954 | 6954 |
| 6955 } // namespace blink | 6955 } // namespace blink |
| OLD | NEW |