| 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 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 }; | 476 }; |
| 477 | 477 |
| 478 int IntWrapper::s_destructorCalls = 0; | 478 int IntWrapper::s_destructorCalls = 0; |
| 479 int OffHeapInt::s_destructorCalls = 0; | 479 int OffHeapInt::s_destructorCalls = 0; |
| 480 | 480 |
| 481 class ThreadedTesterBase { | 481 class ThreadedTesterBase { |
| 482 protected: | 482 protected: |
| 483 static void test(ThreadedTesterBase* tester) { | 483 static void test(ThreadedTesterBase* tester) { |
| 484 Vector<std::unique_ptr<WebThread>, numberOfThreads> m_threads; | 484 Vector<std::unique_ptr<WebThread>, numberOfThreads> m_threads; |
| 485 for (int i = 0; i < numberOfThreads; i++) { | 485 for (int i = 0; i < numberOfThreads; i++) { |
| 486 m_threads.append(wrapUnique( | 486 m_threads.append(WTF::wrapUnique( |
| 487 Platform::current()->createThread("blink gc testing thread"))); | 487 Platform::current()->createThread("blink gc testing thread"))); |
| 488 m_threads.back()->getWebTaskRunner()->postTask( | 488 m_threads.back()->getWebTaskRunner()->postTask( |
| 489 BLINK_FROM_HERE, | 489 BLINK_FROM_HERE, |
| 490 crossThreadBind(threadFunc, crossThreadUnretained(tester))); | 490 crossThreadBind(threadFunc, crossThreadUnretained(tester))); |
| 491 } | 491 } |
| 492 while (tester->m_threadsToFinish) { | 492 while (tester->m_threadsToFinish) { |
| 493 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 493 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); |
| 494 testing::yieldCurrentThread(); | 494 testing::yieldCurrentThread(); |
| 495 } | 495 } |
| 496 delete tester; | 496 delete tester; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 } | 538 } |
| 539 | 539 |
| 540 protected: | 540 protected: |
| 541 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; | 541 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; |
| 542 | 542 |
| 543 Mutex m_mutex; | 543 Mutex m_mutex; |
| 544 Vector<std::unique_ptr<GlobalIntWrapperPersistent>> m_crossPersistents; | 544 Vector<std::unique_ptr<GlobalIntWrapperPersistent>> m_crossPersistents; |
| 545 | 545 |
| 546 std::unique_ptr<GlobalIntWrapperPersistent> createGlobalPersistent( | 546 std::unique_ptr<GlobalIntWrapperPersistent> createGlobalPersistent( |
| 547 int value) { | 547 int value) { |
| 548 return wrapUnique( | 548 return WTF::wrapUnique( |
| 549 new GlobalIntWrapperPersistent(IntWrapper::create(value))); | 549 new GlobalIntWrapperPersistent(IntWrapper::create(value))); |
| 550 } | 550 } |
| 551 | 551 |
| 552 void addGlobalPersistent() { | 552 void addGlobalPersistent() { |
| 553 MutexLocker lock(m_mutex); | 553 MutexLocker lock(m_mutex); |
| 554 m_crossPersistents.append(createGlobalPersistent(0x2a2a2a2a)); | 554 m_crossPersistents.append(createGlobalPersistent(0x2a2a2a2a)); |
| 555 } | 555 } |
| 556 | 556 |
| 557 void runThread() override { | 557 void runThread() override { |
| 558 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); | 558 ThreadState::attachCurrentThread(BlinkGC::MainThreadHeapMode); |
| (...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 ~FinalizationObserverWithHashMap() { | 1286 ~FinalizationObserverWithHashMap() { |
| 1287 m_target.willFinalize(); | 1287 m_target.willFinalize(); |
| 1288 s_didCallWillFinalize = true; | 1288 s_didCallWillFinalize = true; |
| 1289 } | 1289 } |
| 1290 | 1290 |
| 1291 static ObserverMap& observe(Observable& target) { | 1291 static ObserverMap& observe(Observable& target) { |
| 1292 ObserverMap& map = observers(); | 1292 ObserverMap& map = observers(); |
| 1293 ObserverMap::AddResult result = map.add(&target, nullptr); | 1293 ObserverMap::AddResult result = map.add(&target, nullptr); |
| 1294 if (result.isNewEntry) { | 1294 if (result.isNewEntry) { |
| 1295 result.storedValue->value = | 1295 result.storedValue->value = |
| 1296 makeUnique<FinalizationObserverWithHashMap>(target); | 1296 WTF::makeUnique<FinalizationObserverWithHashMap>(target); |
| 1297 } else { | 1297 } else { |
| 1298 ASSERT(result.storedValue->value); | 1298 ASSERT(result.storedValue->value); |
| 1299 } | 1299 } |
| 1300 return map; | 1300 return map; |
| 1301 } | 1301 } |
| 1302 | 1302 |
| 1303 static void clearObservers() { | 1303 static void clearObservers() { |
| 1304 delete s_observerMap; | 1304 delete s_observerMap; |
| 1305 s_observerMap = nullptr; | 1305 s_observerMap = nullptr; |
| 1306 } | 1306 } |
| (...skipping 3338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4645 | 4645 |
| 4646 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); | 4646 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); |
| 4647 set.clear(); | 4647 set.clear(); |
| 4648 EXPECT_TRUE(RefCountedWithDestructor::s_wasDestructed); | 4648 EXPECT_TRUE(RefCountedWithDestructor::s_wasDestructed); |
| 4649 } | 4649 } |
| 4650 | 4650 |
| 4651 TEST(HeapTest, DestructorsCalled) { | 4651 TEST(HeapTest, DestructorsCalled) { |
| 4652 HeapHashMap<Member<IntWrapper>, std::unique_ptr<SimpleClassWithDestructor>> | 4652 HeapHashMap<Member<IntWrapper>, std::unique_ptr<SimpleClassWithDestructor>> |
| 4653 map; | 4653 map; |
| 4654 SimpleClassWithDestructor* hasDestructor = new SimpleClassWithDestructor(); | 4654 SimpleClassWithDestructor* hasDestructor = new SimpleClassWithDestructor(); |
| 4655 map.add(IntWrapper::create(1), wrapUnique(hasDestructor)); | 4655 map.add(IntWrapper::create(1), WTF::wrapUnique(hasDestructor)); |
| 4656 SimpleClassWithDestructor::s_wasDestructed = false; | 4656 SimpleClassWithDestructor::s_wasDestructed = false; |
| 4657 map.clear(); | 4657 map.clear(); |
| 4658 EXPECT_TRUE(SimpleClassWithDestructor::s_wasDestructed); | 4658 EXPECT_TRUE(SimpleClassWithDestructor::s_wasDestructed); |
| 4659 } | 4659 } |
| 4660 | 4660 |
| 4661 class MixinA : public GarbageCollectedMixin { | 4661 class MixinA : public GarbageCollectedMixin { |
| 4662 public: | 4662 public: |
| 4663 MixinA() : m_obj(IntWrapper::create(100)) {} | 4663 MixinA() : m_obj(IntWrapper::create(100)) {} |
| 4664 DEFINE_INLINE_VIRTUAL_TRACE() { | 4664 DEFINE_INLINE_VIRTUAL_TRACE() { |
| 4665 s_traceCount++; | 4665 s_traceCount++; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4786 EXPECT_EQ(2, MixinA::s_traceCount); | 4786 EXPECT_EQ(2, MixinA::s_traceCount); |
| 4787 } | 4787 } |
| 4788 preciselyCollectGarbage(); | 4788 preciselyCollectGarbage(); |
| 4789 EXPECT_EQ(2, MixinA::s_traceCount); | 4789 EXPECT_EQ(2, MixinA::s_traceCount); |
| 4790 } | 4790 } |
| 4791 | 4791 |
| 4792 class GCParkingThreadTester { | 4792 class GCParkingThreadTester { |
| 4793 public: | 4793 public: |
| 4794 static void test() { | 4794 static void test() { |
| 4795 std::unique_ptr<WebThread> sleepingThread = | 4795 std::unique_ptr<WebThread> sleepingThread = |
| 4796 wrapUnique(Platform::current()->createThread("SleepingThread")); | 4796 WTF::wrapUnique(Platform::current()->createThread("SleepingThread")); |
| 4797 sleepingThread->getWebTaskRunner()->postTask( | 4797 sleepingThread->getWebTaskRunner()->postTask( |
| 4798 BLINK_FROM_HERE, crossThreadBind(sleeperMainFunc)); | 4798 BLINK_FROM_HERE, crossThreadBind(sleeperMainFunc)); |
| 4799 | 4799 |
| 4800 // Wait for the sleeper to run. | 4800 // Wait for the sleeper to run. |
| 4801 while (!s_sleeperRunning) { | 4801 while (!s_sleeperRunning) { |
| 4802 testing::yieldCurrentThread(); | 4802 testing::yieldCurrentThread(); |
| 4803 } | 4803 } |
| 4804 | 4804 |
| 4805 { | 4805 { |
| 4806 // Expect the first attempt to park the sleeping thread to fail | 4806 // Expect the first attempt to park the sleeping thread to fail |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5471 MutexLocker locker(workerThreadMutex()); | 5471 MutexLocker locker(workerThreadMutex()); |
| 5472 workerThreadCondition().signal(); | 5472 workerThreadCondition().signal(); |
| 5473 } | 5473 } |
| 5474 | 5474 |
| 5475 class DeadBitTester { | 5475 class DeadBitTester { |
| 5476 public: | 5476 public: |
| 5477 static void test() { | 5477 static void test() { |
| 5478 IntWrapper::s_destructorCalls = 0; | 5478 IntWrapper::s_destructorCalls = 0; |
| 5479 | 5479 |
| 5480 MutexLocker locker(mainThreadMutex()); | 5480 MutexLocker locker(mainThreadMutex()); |
| 5481 std::unique_ptr<WebThread> workerThread = | 5481 std::unique_ptr<WebThread> workerThread = WTF::wrapUnique( |
| 5482 wrapUnique(Platform::current()->createThread("Test Worker Thread")); | 5482 Platform::current()->createThread("Test Worker Thread")); |
| 5483 workerThread->getWebTaskRunner()->postTask( | 5483 workerThread->getWebTaskRunner()->postTask( |
| 5484 BLINK_FROM_HERE, crossThreadBind(workerThreadMain)); | 5484 BLINK_FROM_HERE, crossThreadBind(workerThreadMain)); |
| 5485 | 5485 |
| 5486 // Wait for the worker thread to have done its initialization, | 5486 // Wait for the worker thread to have done its initialization, |
| 5487 // IE. the worker allocates an object and then throw aways any | 5487 // IE. the worker allocates an object and then throw aways any |
| 5488 // pointers to it. | 5488 // pointers to it. |
| 5489 parkMainThread(); | 5489 parkMainThread(); |
| 5490 | 5490 |
| 5491 // Now do a GC. This will not find the worker threads object since it | 5491 // Now do a GC. This will not find the worker threads object since it |
| 5492 // is not referred from any of the threads. Even a conservative | 5492 // is not referred from any of the threads. Even a conservative |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5572 TEST(HeapTest, ObjectDeadBit) { | 5572 TEST(HeapTest, ObjectDeadBit) { |
| 5573 DeadBitTester::test(); | 5573 DeadBitTester::test(); |
| 5574 } | 5574 } |
| 5575 | 5575 |
| 5576 class ThreadedStrongificationTester { | 5576 class ThreadedStrongificationTester { |
| 5577 public: | 5577 public: |
| 5578 static void test() { | 5578 static void test() { |
| 5579 IntWrapper::s_destructorCalls = 0; | 5579 IntWrapper::s_destructorCalls = 0; |
| 5580 | 5580 |
| 5581 MutexLocker locker(mainThreadMutex()); | 5581 MutexLocker locker(mainThreadMutex()); |
| 5582 std::unique_ptr<WebThread> workerThread = | 5582 std::unique_ptr<WebThread> workerThread = WTF::wrapUnique( |
| 5583 wrapUnique(Platform::current()->createThread("Test Worker Thread")); | 5583 Platform::current()->createThread("Test Worker Thread")); |
| 5584 workerThread->getWebTaskRunner()->postTask( | 5584 workerThread->getWebTaskRunner()->postTask( |
| 5585 BLINK_FROM_HERE, crossThreadBind(workerThreadMain)); | 5585 BLINK_FROM_HERE, crossThreadBind(workerThreadMain)); |
| 5586 | 5586 |
| 5587 // Wait for the worker thread initialization. The worker | 5587 // Wait for the worker thread initialization. The worker |
| 5588 // allocates a weak collection where both collection and | 5588 // allocates a weak collection where both collection and |
| 5589 // contents are kept alive via persistent pointers. | 5589 // contents are kept alive via persistent pointers. |
| 5590 parkMainThread(); | 5590 parkMainThread(); |
| 5591 | 5591 |
| 5592 // Perform two garbage collections where the worker thread does | 5592 // Perform two garbage collections where the worker thread does |
| 5593 // not wake up in between. This will cause us to remove marks | 5593 // not wake up in between. This will cause us to remove marks |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5765 }; | 5765 }; |
| 5766 | 5766 |
| 5767 int DestructorLockingObject::s_destructorCalls = 0; | 5767 int DestructorLockingObject::s_destructorCalls = 0; |
| 5768 | 5768 |
| 5769 class RecursiveLockingTester { | 5769 class RecursiveLockingTester { |
| 5770 public: | 5770 public: |
| 5771 static void test() { | 5771 static void test() { |
| 5772 DestructorLockingObject::s_destructorCalls = 0; | 5772 DestructorLockingObject::s_destructorCalls = 0; |
| 5773 | 5773 |
| 5774 MutexLocker locker(mainThreadMutex()); | 5774 MutexLocker locker(mainThreadMutex()); |
| 5775 std::unique_ptr<WebThread> workerThread = | 5775 std::unique_ptr<WebThread> workerThread = WTF::wrapUnique( |
| 5776 wrapUnique(Platform::current()->createThread("Test Worker Thread")); | 5776 Platform::current()->createThread("Test Worker Thread")); |
| 5777 workerThread->getWebTaskRunner()->postTask( | 5777 workerThread->getWebTaskRunner()->postTask( |
| 5778 BLINK_FROM_HERE, crossThreadBind(workerThreadMain)); | 5778 BLINK_FROM_HERE, crossThreadBind(workerThreadMain)); |
| 5779 | 5779 |
| 5780 // Park the main thread until the worker thread has initialized. | 5780 // Park the main thread until the worker thread has initialized. |
| 5781 parkMainThread(); | 5781 parkMainThread(); |
| 5782 | 5782 |
| 5783 { | 5783 { |
| 5784 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); | 5784 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); |
| 5785 | 5785 |
| 5786 // Let the worker try to acquire the above mutex. It won't get it | 5786 // Let the worker try to acquire the above mutex. It won't get it |
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6482 explicit WeakPersistentHolder(IntWrapper* object) : m_object(object) {} | 6482 explicit WeakPersistentHolder(IntWrapper* object) : m_object(object) {} |
| 6483 IntWrapper* object() const { return m_object; } | 6483 IntWrapper* object() const { return m_object; } |
| 6484 | 6484 |
| 6485 private: | 6485 private: |
| 6486 WeakPersistent<IntWrapper> m_object; | 6486 WeakPersistent<IntWrapper> m_object; |
| 6487 }; | 6487 }; |
| 6488 | 6488 |
| 6489 TEST(HeapTest, WeakPersistent) { | 6489 TEST(HeapTest, WeakPersistent) { |
| 6490 Persistent<IntWrapper> object = new IntWrapper(20); | 6490 Persistent<IntWrapper> object = new IntWrapper(20); |
| 6491 std::unique_ptr<WeakPersistentHolder> holder = | 6491 std::unique_ptr<WeakPersistentHolder> holder = |
| 6492 makeUnique<WeakPersistentHolder>(object); | 6492 WTF::makeUnique<WeakPersistentHolder>(object); |
| 6493 preciselyCollectGarbage(); | 6493 preciselyCollectGarbage(); |
| 6494 EXPECT_TRUE(holder->object()); | 6494 EXPECT_TRUE(holder->object()); |
| 6495 object = nullptr; | 6495 object = nullptr; |
| 6496 preciselyCollectGarbage(); | 6496 preciselyCollectGarbage(); |
| 6497 EXPECT_FALSE(holder->object()); | 6497 EXPECT_FALSE(holder->object()); |
| 6498 } | 6498 } |
| 6499 | 6499 |
| 6500 namespace { | 6500 namespace { |
| 6501 | 6501 |
| 6502 void workerThreadMainForCrossThreadWeakPersistentTest( | 6502 void workerThreadMainForCrossThreadWeakPersistentTest( |
| (...skipping 23 matching lines...) Expand all Loading... |
| 6526 // pointing to it on the main thread, clear the reference in the worker | 6526 // pointing to it on the main thread, clear the reference in the worker |
| 6527 // thread, run a GC in the worker thread, and see if the | 6527 // thread, run a GC in the worker thread, and see if the |
| 6528 // CrossThreadWeakPersistent is cleared. | 6528 // CrossThreadWeakPersistent is cleared. |
| 6529 | 6529 |
| 6530 DestructorLockingObject::s_destructorCalls = 0; | 6530 DestructorLockingObject::s_destructorCalls = 0; |
| 6531 | 6531 |
| 6532 // Step 1: Initiate a worker thread, and wait for |object| to get allocated on | 6532 // Step 1: Initiate a worker thread, and wait for |object| to get allocated on |
| 6533 // the worker thread. | 6533 // the worker thread. |
| 6534 MutexLocker mainThreadMutexLocker(mainThreadMutex()); | 6534 MutexLocker mainThreadMutexLocker(mainThreadMutex()); |
| 6535 std::unique_ptr<WebThread> workerThread = | 6535 std::unique_ptr<WebThread> workerThread = |
| 6536 wrapUnique(Platform::current()->createThread("Test Worker Thread")); | 6536 WTF::wrapUnique(Platform::current()->createThread("Test Worker Thread")); |
| 6537 DestructorLockingObject* object = nullptr; | 6537 DestructorLockingObject* object = nullptr; |
| 6538 workerThread->getWebTaskRunner()->postTask( | 6538 workerThread->getWebTaskRunner()->postTask( |
| 6539 BLINK_FROM_HERE, | 6539 BLINK_FROM_HERE, |
| 6540 crossThreadBind(workerThreadMainForCrossThreadWeakPersistentTest, | 6540 crossThreadBind(workerThreadMainForCrossThreadWeakPersistentTest, |
| 6541 crossThreadUnretained(&object))); | 6541 crossThreadUnretained(&object))); |
| 6542 parkMainThread(); | 6542 parkMainThread(); |
| 6543 | 6543 |
| 6544 // Step 3: Set up a CrossThreadWeakPersistent. | 6544 // Step 3: Set up a CrossThreadWeakPersistent. |
| 6545 ASSERT_TRUE(object); | 6545 ASSERT_TRUE(object); |
| 6546 CrossThreadWeakPersistent<DestructorLockingObject> crossThreadWeakPersistent( | 6546 CrossThreadWeakPersistent<DestructorLockingObject> crossThreadWeakPersistent( |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6807 "HeapVector"); | 6807 "HeapVector"); |
| 6808 static_assert( | 6808 static_assert( |
| 6809 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, | 6809 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, |
| 6810 "HeapDeque"); | 6810 "HeapDeque"); |
| 6811 static_assert(WTF::IsGarbageCollectedType< | 6811 static_assert(WTF::IsGarbageCollectedType< |
| 6812 HeapTerminatedArray<Member<IntWrapper>>>::value, | 6812 HeapTerminatedArray<Member<IntWrapper>>>::value, |
| 6813 "HeapTerminatedArray"); | 6813 "HeapTerminatedArray"); |
| 6814 } | 6814 } |
| 6815 | 6815 |
| 6816 } // namespace blink | 6816 } // namespace blink |
| OLD | NEW |