| 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 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; | 513 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; |
| 514 | 514 |
| 515 PassOwnPtr<GlobalIntWrapperPersistent> createGlobalPersistent(int value) | 515 PassOwnPtr<GlobalIntWrapperPersistent> createGlobalPersistent(int value) |
| 516 { | 516 { |
| 517 return adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(value)
)); | 517 return adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(value)
)); |
| 518 } | 518 } |
| 519 | 519 |
| 520 void runThread() override | 520 void runThread() override |
| 521 { | 521 { |
| 522 OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent; | 522 OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent; |
| 523 ThreadState::attachCurrentThread(false); | 523 ThreadState::attachCurrentThread(); |
| 524 | 524 |
| 525 longLivingPersistent = createGlobalPersistent(0x2a2a2a2a); | 525 longLivingPersistent = createGlobalPersistent(0x2a2a2a2a); |
| 526 int gcCount = 0; | 526 int gcCount = 0; |
| 527 while (!done()) { | 527 while (!done()) { |
| 528 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 528 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
| 529 { | 529 { |
| 530 Persistent<IntWrapper> wrapper; | 530 Persistent<IntWrapper> wrapper; |
| 531 | 531 |
| 532 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob
alPersistent(0x0ed0cabb); | 532 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob
alPersistent(0x0ed0cabb); |
| 533 | 533 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 class ThreadedWeaknessTester : public ThreadedTesterBase { | 572 class ThreadedWeaknessTester : public ThreadedTesterBase { |
| 573 public: | 573 public: |
| 574 static void test() | 574 static void test() |
| 575 { | 575 { |
| 576 ThreadedTesterBase::test(new ThreadedWeaknessTester); | 576 ThreadedTesterBase::test(new ThreadedWeaknessTester); |
| 577 } | 577 } |
| 578 | 578 |
| 579 private: | 579 private: |
| 580 void runThread() override | 580 void runThread() override |
| 581 { | 581 { |
| 582 ThreadState::attachCurrentThread(false); | 582 ThreadState::attachCurrentThread(); |
| 583 | 583 |
| 584 int gcCount = 0; | 584 int gcCount = 0; |
| 585 while (!done()) { | 585 while (!done()) { |
| 586 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 586 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
| 587 { | 587 { |
| 588 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we
akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; | 588 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we
akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; |
| 589 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; | 589 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; |
| 590 | 590 |
| 591 for (int i = 0; i < numberOfAllocations; i++) { | 591 for (int i = 0; i < numberOfAllocations; i++) { |
| 592 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); | 592 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 explicit PersistentChain(int count) | 666 explicit PersistentChain(int count) |
| 667 { | 667 { |
| 668 m_refCountedChain = adoptRef(RefCountedChain::create(count)); | 668 m_refCountedChain = adoptRef(RefCountedChain::create(count)); |
| 669 } | 669 } |
| 670 | 670 |
| 671 RefPtr<RefCountedChain> m_refCountedChain; | 671 RefPtr<RefCountedChain> m_refCountedChain; |
| 672 }; | 672 }; |
| 673 | 673 |
| 674 void runThread() override | 674 void runThread() override |
| 675 { | 675 { |
| 676 ThreadState::attachCurrentThread(false); | 676 ThreadState::attachCurrentThread(); |
| 677 | 677 |
| 678 PersistentChain::create(100); | 678 PersistentChain::create(100); |
| 679 | 679 |
| 680 // Upon thread detach, GCs will run until all persistents have been | 680 // Upon thread detach, GCs will run until all persistents have been |
| 681 // released. We verify that the draining of persistents proceeds | 681 // released. We verify that the draining of persistents proceeds |
| 682 // as expected by dropping one Persistent<> per GC until there | 682 // as expected by dropping one Persistent<> per GC until there |
| 683 // are none left. | 683 // are none left. |
| 684 ThreadState::detachCurrentThread(); | 684 ThreadState::detachCurrentThread(); |
| 685 atomicDecrement(&m_threadsToFinish); | 685 atomicDecrement(&m_threadsToFinish); |
| 686 } | 686 } |
| (...skipping 4036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4723 { | 4723 { |
| 4724 // Since the sleeper thread has detached this is the only thread. | 4724 // Since the sleeper thread has detached this is the only thread. |
| 4725 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); | 4725 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); |
| 4726 EXPECT_TRUE(scope.allThreadsParked()); | 4726 EXPECT_TRUE(scope.allThreadsParked()); |
| 4727 } | 4727 } |
| 4728 } | 4728 } |
| 4729 | 4729 |
| 4730 private: | 4730 private: |
| 4731 static void sleeperMainFunc() | 4731 static void sleeperMainFunc() |
| 4732 { | 4732 { |
| 4733 ThreadState::attachCurrentThread(false); | 4733 ThreadState::attachCurrentThread(); |
| 4734 s_sleeperRunning = true; | 4734 s_sleeperRunning = true; |
| 4735 | 4735 |
| 4736 // Simulate a long running op that is not entering a safepoint. | 4736 // Simulate a long running op that is not entering a safepoint. |
| 4737 while (!s_sleeperDone) { | 4737 while (!s_sleeperDone) { |
| 4738 testing::yieldCurrentThread(); | 4738 testing::yieldCurrentThread(); |
| 4739 } | 4739 } |
| 4740 | 4740 |
| 4741 ThreadState::detachCurrentThread(); | 4741 ThreadState::detachCurrentThread(); |
| 4742 s_sleeperRunning = false; | 4742 s_sleeperRunning = false; |
| 4743 } | 4743 } |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5408 // shutdown. | 5408 // shutdown. |
| 5409 wakeWorkerThread(); | 5409 wakeWorkerThread(); |
| 5410 } | 5410 } |
| 5411 | 5411 |
| 5412 private: | 5412 private: |
| 5413 | 5413 |
| 5414 static void workerThreadMain() | 5414 static void workerThreadMain() |
| 5415 { | 5415 { |
| 5416 MutexLocker locker(workerThreadMutex()); | 5416 MutexLocker locker(workerThreadMutex()); |
| 5417 | 5417 |
| 5418 ThreadState::attachCurrentThread(false); | 5418 ThreadState::attachCurrentThread(); |
| 5419 | 5419 |
| 5420 { | 5420 { |
| 5421 // Create a worker object that is not kept alive except the | 5421 // Create a worker object that is not kept alive except the |
| 5422 // main thread will keep it as an integer value on its stack. | 5422 // main thread will keep it as an integer value on its stack. |
| 5423 IntWrapper* workerObject = IntWrapper::create(42); | 5423 IntWrapper* workerObject = IntWrapper::create(42); |
| 5424 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); | 5424 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); |
| 5425 } | 5425 } |
| 5426 | 5426 |
| 5427 // Signal the main thread that the worker is done with its allocation. | 5427 // Signal the main thread that the worker is done with its allocation. |
| 5428 wakeMainThread(); | 5428 wakeMainThread(); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5529 parkWorkerThread(); | 5529 parkWorkerThread(); |
| 5530 } | 5530 } |
| 5531 | 5531 |
| 5532 return weakCollection; | 5532 return weakCollection; |
| 5533 } | 5533 } |
| 5534 | 5534 |
| 5535 static void workerThreadMain() | 5535 static void workerThreadMain() |
| 5536 { | 5536 { |
| 5537 MutexLocker locker(workerThreadMutex()); | 5537 MutexLocker locker(workerThreadMutex()); |
| 5538 | 5538 |
| 5539 ThreadState::attachCurrentThread(false); | 5539 ThreadState::attachCurrentThread(); |
| 5540 | 5540 |
| 5541 { | 5541 { |
| 5542 Persistent<WeakCollectionType> collection = allocateCollection(); | 5542 Persistent<WeakCollectionType> collection = allocateCollection(); |
| 5543 { | 5543 { |
| 5544 // Prevent weak processing with an iterator and GC. | 5544 // Prevent weak processing with an iterator and GC. |
| 5545 WeakCollectionType::iterator it = collection->begin(); | 5545 WeakCollectionType::iterator it = collection->begin(); |
| 5546 conservativelyCollectGarbage(); | 5546 conservativelyCollectGarbage(); |
| 5547 | 5547 |
| 5548 // The backing should be strongified because of the iterator. | 5548 // The backing should be strongified because of the iterator. |
| 5549 EXPECT_EQ(6u, collection->size()); | 5549 EXPECT_EQ(6u, collection->size()); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5690 // can acquire it and do its sweep of its arenas. Just wait for the work
er | 5690 // can acquire it and do its sweep of its arenas. Just wait for the work
er |
| 5691 // to complete its sweep and check the result. | 5691 // to complete its sweep and check the result. |
| 5692 parkMainThread(); | 5692 parkMainThread(); |
| 5693 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); | 5693 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); |
| 5694 } | 5694 } |
| 5695 | 5695 |
| 5696 private: | 5696 private: |
| 5697 static void workerThreadMain() | 5697 static void workerThreadMain() |
| 5698 { | 5698 { |
| 5699 MutexLocker locker(workerThreadMutex()); | 5699 MutexLocker locker(workerThreadMutex()); |
| 5700 ThreadState::attachCurrentThread(false); | 5700 ThreadState::attachCurrentThread(); |
| 5701 | 5701 |
| 5702 DestructorLockingObject* dlo = DestructorLockingObject::create(); | 5702 DestructorLockingObject* dlo = DestructorLockingObject::create(); |
| 5703 ASSERT_UNUSED(dlo, dlo); | 5703 ASSERT_UNUSED(dlo, dlo); |
| 5704 | 5704 |
| 5705 // Wake up the main thread which is waiting for the worker to do its | 5705 // Wake up the main thread which is waiting for the worker to do its |
| 5706 // allocation. | 5706 // allocation. |
| 5707 wakeMainThread(); | 5707 wakeMainThread(); |
| 5708 | 5708 |
| 5709 // Wait for the main thread to get the global lock to ensure it has | 5709 // Wait for the main thread to get the global lock to ensure it has |
| 5710 // it before the worker tries to acquire it. We want the worker to | 5710 // it before the worker tries to acquire it. We want the worker to |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6377 preciselyCollectGarbage(); | 6377 preciselyCollectGarbage(); |
| 6378 EXPECT_FALSE(holder->object()); | 6378 EXPECT_FALSE(holder->object()); |
| 6379 } | 6379 } |
| 6380 | 6380 |
| 6381 namespace { | 6381 namespace { |
| 6382 | 6382 |
| 6383 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject**
object) | 6383 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject**
object) |
| 6384 { | 6384 { |
| 6385 // Step 2: Create an object and store the pointer. | 6385 // Step 2: Create an object and store the pointer. |
| 6386 MutexLocker locker(workerThreadMutex()); | 6386 MutexLocker locker(workerThreadMutex()); |
| 6387 ThreadState::attachCurrentThread(false); | 6387 ThreadState::attachCurrentThread(); |
| 6388 *object = DestructorLockingObject::create(); | 6388 *object = DestructorLockingObject::create(); |
| 6389 wakeMainThread(); | 6389 wakeMainThread(); |
| 6390 parkWorkerThread(); | 6390 parkWorkerThread(); |
| 6391 | 6391 |
| 6392 // Step 4: Run a GC. | 6392 // Step 4: Run a GC. |
| 6393 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw
eep, BlinkGC::ForcedGC); | 6393 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw
eep, BlinkGC::ForcedGC); |
| 6394 wakeMainThread(); | 6394 wakeMainThread(); |
| 6395 parkWorkerThread(); | 6395 parkWorkerThread(); |
| 6396 | 6396 |
| 6397 // Step 6: Finish. | 6397 // Step 6: Finish. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6501 static void test() | 6501 static void test() |
| 6502 { | 6502 { |
| 6503 IntWrapper::s_destructorCalls = 0; | 6503 IntWrapper::s_destructorCalls = 0; |
| 6504 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester); | 6504 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester); |
| 6505 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls); | 6505 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls); |
| 6506 } | 6506 } |
| 6507 | 6507 |
| 6508 private: | 6508 private: |
| 6509 void runThread() override | 6509 void runThread() override |
| 6510 { | 6510 { |
| 6511 ThreadState::attachCurrentThread(false); | 6511 ThreadState::attachCurrentThread(); |
| 6512 EXPECT_EQ(42, threadSpecificIntWrapper().value()); | 6512 EXPECT_EQ(42, threadSpecificIntWrapper().value()); |
| 6513 ThreadState::detachCurrentThread(); | 6513 ThreadState::detachCurrentThread(); |
| 6514 atomicDecrement(&m_threadsToFinish); | 6514 atomicDecrement(&m_threadsToFinish); |
| 6515 } | 6515 } |
| 6516 | 6516 |
| 6517 static IntWrapper& threadSpecificIntWrapper() | 6517 static IntWrapper& threadSpecificIntWrapper() |
| 6518 { | 6518 { |
| 6519 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 6519 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 6520 ThreadSpecific<Persistent<IntWrapper>>, intWrapper, | 6520 ThreadSpecific<Persistent<IntWrapper>>, intWrapper, |
| 6521 new ThreadSpecific<Persistent<IntWrapper>>); | 6521 new ThreadSpecific<Persistent<IntWrapper>>); |
| 6522 Persistent<IntWrapper>& handle = *intWrapper; | 6522 Persistent<IntWrapper>& handle = *intWrapper; |
| 6523 if (!handle) { | 6523 if (!handle) { |
| 6524 handle = new IntWrapper(42); | 6524 handle = new IntWrapper(42); |
| 6525 handle.clearOnThreadShutdown(); | 6525 handle.clearOnThreadShutdown(); |
| 6526 } | 6526 } |
| 6527 return *handle; | 6527 return *handle; |
| 6528 } | 6528 } |
| 6529 }; | 6529 }; |
| 6530 | 6530 |
| 6531 } // namespace | 6531 } // namespace |
| 6532 | 6532 |
| 6533 TEST(HeapTest, TestClearOnShutdown) | 6533 TEST(HeapTest, TestClearOnShutdown) |
| 6534 { | 6534 { |
| 6535 ThreadedClearOnShutdownTester::test(); | 6535 ThreadedClearOnShutdownTester::test(); |
| 6536 } | 6536 } |
| 6537 | 6537 |
| 6538 } // namespace blink | 6538 } // namespace blink |
| OLD | NEW |