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 |