| 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 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; | 518 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; |
| 519 | 519 |
| 520 PassOwnPtr<GlobalIntWrapperPersistent> createGlobalPersistent(int value) | 520 PassOwnPtr<GlobalIntWrapperPersistent> createGlobalPersistent(int value) |
| 521 { | 521 { |
| 522 return adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(value)
)); | 522 return adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(value)
)); |
| 523 } | 523 } |
| 524 | 524 |
| 525 void runThread() override | 525 void runThread() override |
| 526 { | 526 { |
| 527 OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent; | 527 OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent; |
| 528 ThreadState::attachCurrentThread(); | 528 ThreadState::attachCurrentThread(false); |
| 529 | 529 |
| 530 longLivingPersistent = createGlobalPersistent(0x2a2a2a2a); | 530 longLivingPersistent = createGlobalPersistent(0x2a2a2a2a); |
| 531 int gcCount = 0; | 531 int gcCount = 0; |
| 532 while (!done()) { | 532 while (!done()) { |
| 533 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 533 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
| 534 { | 534 { |
| 535 Persistent<IntWrapper> wrapper; | 535 Persistent<IntWrapper> wrapper; |
| 536 | 536 |
| 537 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob
alPersistent(0x0ed0cabb); | 537 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob
alPersistent(0x0ed0cabb); |
| 538 | 538 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 class ThreadedWeaknessTester : public ThreadedTesterBase { | 577 class ThreadedWeaknessTester : public ThreadedTesterBase { |
| 578 public: | 578 public: |
| 579 static void test() | 579 static void test() |
| 580 { | 580 { |
| 581 ThreadedTesterBase::test(new ThreadedWeaknessTester); | 581 ThreadedTesterBase::test(new ThreadedWeaknessTester); |
| 582 } | 582 } |
| 583 | 583 |
| 584 private: | 584 private: |
| 585 void runThread() override | 585 void runThread() override |
| 586 { | 586 { |
| 587 ThreadState::attachCurrentThread(); | 587 ThreadState::attachCurrentThread(false); |
| 588 | 588 |
| 589 int gcCount = 0; | 589 int gcCount = 0; |
| 590 while (!done()) { | 590 while (!done()) { |
| 591 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 591 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
| 592 { | 592 { |
| 593 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we
akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; | 593 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we
akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; |
| 594 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; | 594 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; |
| 595 | 595 |
| 596 for (int i = 0; i < numberOfAllocations; i++) { | 596 for (int i = 0; i < numberOfAllocations; i++) { |
| 597 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); | 597 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 explicit PersistentChain(int count) | 671 explicit PersistentChain(int count) |
| 672 { | 672 { |
| 673 m_refCountedChain = adoptRef(RefCountedChain::create(count)); | 673 m_refCountedChain = adoptRef(RefCountedChain::create(count)); |
| 674 } | 674 } |
| 675 | 675 |
| 676 RefPtr<RefCountedChain> m_refCountedChain; | 676 RefPtr<RefCountedChain> m_refCountedChain; |
| 677 }; | 677 }; |
| 678 | 678 |
| 679 void runThread() override | 679 void runThread() override |
| 680 { | 680 { |
| 681 ThreadState::attachCurrentThread(); | 681 ThreadState::attachCurrentThread(false); |
| 682 | 682 |
| 683 PersistentChain::create(100); | 683 PersistentChain::create(100); |
| 684 | 684 |
| 685 // Upon thread detach, GCs will run until all persistents have been | 685 // Upon thread detach, GCs will run until all persistents have been |
| 686 // released. We verify that the draining of persistents proceeds | 686 // released. We verify that the draining of persistents proceeds |
| 687 // as expected by dropping one Persistent<> per GC until there | 687 // as expected by dropping one Persistent<> per GC until there |
| 688 // are none left. | 688 // are none left. |
| 689 ThreadState::detachCurrentThread(); | 689 ThreadState::detachCurrentThread(); |
| 690 atomicDecrement(&m_threadsToFinish); | 690 atomicDecrement(&m_threadsToFinish); |
| 691 } | 691 } |
| (...skipping 4021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4713 { | 4713 { |
| 4714 // Since the sleeper thread has detached this is the only thread. | 4714 // Since the sleeper thread has detached this is the only thread. |
| 4715 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); | 4715 TestGCScope scope(BlinkGC::NoHeapPointersOnStack); |
| 4716 EXPECT_TRUE(scope.allThreadsParked()); | 4716 EXPECT_TRUE(scope.allThreadsParked()); |
| 4717 } | 4717 } |
| 4718 } | 4718 } |
| 4719 | 4719 |
| 4720 private: | 4720 private: |
| 4721 static void sleeperMainFunc() | 4721 static void sleeperMainFunc() |
| 4722 { | 4722 { |
| 4723 ThreadState::attachCurrentThread(); | 4723 ThreadState::attachCurrentThread(false); |
| 4724 s_sleeperRunning = true; | 4724 s_sleeperRunning = true; |
| 4725 | 4725 |
| 4726 // Simulate a long running op that is not entering a safepoint. | 4726 // Simulate a long running op that is not entering a safepoint. |
| 4727 while (!s_sleeperDone) { | 4727 while (!s_sleeperDone) { |
| 4728 testing::yieldCurrentThread(); | 4728 testing::yieldCurrentThread(); |
| 4729 } | 4729 } |
| 4730 | 4730 |
| 4731 ThreadState::detachCurrentThread(); | 4731 ThreadState::detachCurrentThread(); |
| 4732 s_sleeperRunning = false; | 4732 s_sleeperRunning = false; |
| 4733 } | 4733 } |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5398 // shutdown. | 5398 // shutdown. |
| 5399 wakeWorkerThread(); | 5399 wakeWorkerThread(); |
| 5400 } | 5400 } |
| 5401 | 5401 |
| 5402 private: | 5402 private: |
| 5403 | 5403 |
| 5404 static void workerThreadMain() | 5404 static void workerThreadMain() |
| 5405 { | 5405 { |
| 5406 MutexLocker locker(workerThreadMutex()); | 5406 MutexLocker locker(workerThreadMutex()); |
| 5407 | 5407 |
| 5408 ThreadState::attachCurrentThread(); | 5408 ThreadState::attachCurrentThread(false); |
| 5409 | 5409 |
| 5410 { | 5410 { |
| 5411 // Create a worker object that is not kept alive except the | 5411 // Create a worker object that is not kept alive except the |
| 5412 // main thread will keep it as an integer value on its stack. | 5412 // main thread will keep it as an integer value on its stack. |
| 5413 IntWrapper* workerObject = IntWrapper::create(42); | 5413 IntWrapper* workerObject = IntWrapper::create(42); |
| 5414 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); | 5414 s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); |
| 5415 } | 5415 } |
| 5416 | 5416 |
| 5417 // Signal the main thread that the worker is done with its allocation. | 5417 // Signal the main thread that the worker is done with its allocation. |
| 5418 wakeMainThread(); | 5418 wakeMainThread(); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5519 parkWorkerThread(); | 5519 parkWorkerThread(); |
| 5520 } | 5520 } |
| 5521 | 5521 |
| 5522 return weakCollection; | 5522 return weakCollection; |
| 5523 } | 5523 } |
| 5524 | 5524 |
| 5525 static void workerThreadMain() | 5525 static void workerThreadMain() |
| 5526 { | 5526 { |
| 5527 MutexLocker locker(workerThreadMutex()); | 5527 MutexLocker locker(workerThreadMutex()); |
| 5528 | 5528 |
| 5529 ThreadState::attachCurrentThread(); | 5529 ThreadState::attachCurrentThread(false); |
| 5530 | 5530 |
| 5531 { | 5531 { |
| 5532 Persistent<WeakCollectionType> collection = allocateCollection(); | 5532 Persistent<WeakCollectionType> collection = allocateCollection(); |
| 5533 { | 5533 { |
| 5534 // Prevent weak processing with an iterator and GC. | 5534 // Prevent weak processing with an iterator and GC. |
| 5535 WeakCollectionType::iterator it = collection->begin(); | 5535 WeakCollectionType::iterator it = collection->begin(); |
| 5536 conservativelyCollectGarbage(); | 5536 conservativelyCollectGarbage(); |
| 5537 | 5537 |
| 5538 // The backing should be strongified because of the iterator. | 5538 // The backing should be strongified because of the iterator. |
| 5539 EXPECT_EQ(6u, collection->size()); | 5539 EXPECT_EQ(6u, collection->size()); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5680 // can acquire it and do its sweep of its arenas. Just wait for the work
er | 5680 // can acquire it and do its sweep of its arenas. Just wait for the work
er |
| 5681 // to complete its sweep and check the result. | 5681 // to complete its sweep and check the result. |
| 5682 parkMainThread(); | 5682 parkMainThread(); |
| 5683 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); | 5683 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); |
| 5684 } | 5684 } |
| 5685 | 5685 |
| 5686 private: | 5686 private: |
| 5687 static void workerThreadMain() | 5687 static void workerThreadMain() |
| 5688 { | 5688 { |
| 5689 MutexLocker locker(workerThreadMutex()); | 5689 MutexLocker locker(workerThreadMutex()); |
| 5690 ThreadState::attachCurrentThread(); | 5690 ThreadState::attachCurrentThread(false); |
| 5691 | 5691 |
| 5692 DestructorLockingObject* dlo = DestructorLockingObject::create(); | 5692 DestructorLockingObject* dlo = DestructorLockingObject::create(); |
| 5693 ASSERT_UNUSED(dlo, dlo); | 5693 ASSERT_UNUSED(dlo, dlo); |
| 5694 | 5694 |
| 5695 // Wake up the main thread which is waiting for the worker to do its | 5695 // Wake up the main thread which is waiting for the worker to do its |
| 5696 // allocation. | 5696 // allocation. |
| 5697 wakeMainThread(); | 5697 wakeMainThread(); |
| 5698 | 5698 |
| 5699 // Wait for the main thread to get the global lock to ensure it has | 5699 // Wait for the main thread to get the global lock to ensure it has |
| 5700 // it before the worker tries to acquire it. We want the worker to | 5700 // it before the worker tries to acquire it. We want the worker to |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6369 preciselyCollectGarbage(); | 6369 preciselyCollectGarbage(); |
| 6370 EXPECT_FALSE(holder->object()); | 6370 EXPECT_FALSE(holder->object()); |
| 6371 } | 6371 } |
| 6372 | 6372 |
| 6373 namespace { | 6373 namespace { |
| 6374 | 6374 |
| 6375 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject**
object) | 6375 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject**
object) |
| 6376 { | 6376 { |
| 6377 // Step 2: Create an object and store the pointer. | 6377 // Step 2: Create an object and store the pointer. |
| 6378 MutexLocker locker(workerThreadMutex()); | 6378 MutexLocker locker(workerThreadMutex()); |
| 6379 ThreadState::attachCurrentThread(); | 6379 ThreadState::attachCurrentThread(false); |
| 6380 *object = DestructorLockingObject::create(); | 6380 *object = DestructorLockingObject::create(); |
| 6381 wakeMainThread(); | 6381 wakeMainThread(); |
| 6382 parkWorkerThread(); | 6382 parkWorkerThread(); |
| 6383 | 6383 |
| 6384 // Step 4: Run a GC. | 6384 // Step 4: Run a GC. |
| 6385 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw
eep, BlinkGC::ForcedGC); | 6385 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw
eep, BlinkGC::ForcedGC); |
| 6386 wakeMainThread(); | 6386 wakeMainThread(); |
| 6387 parkWorkerThread(); | 6387 parkWorkerThread(); |
| 6388 | 6388 |
| 6389 // Step 6: Finish. | 6389 // Step 6: Finish. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6493 static void test() | 6493 static void test() |
| 6494 { | 6494 { |
| 6495 IntWrapper::s_destructorCalls = 0; | 6495 IntWrapper::s_destructorCalls = 0; |
| 6496 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester); | 6496 ThreadedTesterBase::test(new ThreadedClearOnShutdownTester); |
| 6497 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls); | 6497 EXPECT_EQ(numberOfThreads, IntWrapper::s_destructorCalls); |
| 6498 } | 6498 } |
| 6499 | 6499 |
| 6500 private: | 6500 private: |
| 6501 void runThread() override | 6501 void runThread() override |
| 6502 { | 6502 { |
| 6503 ThreadState::attachCurrentThread(); | 6503 ThreadState::attachCurrentThread(false); |
| 6504 EXPECT_EQ(42, threadSpecificIntWrapper().value()); | 6504 EXPECT_EQ(42, threadSpecificIntWrapper().value()); |
| 6505 ThreadState::detachCurrentThread(); | 6505 ThreadState::detachCurrentThread(); |
| 6506 atomicDecrement(&m_threadsToFinish); | 6506 atomicDecrement(&m_threadsToFinish); |
| 6507 } | 6507 } |
| 6508 | 6508 |
| 6509 static IntWrapper& threadSpecificIntWrapper() | 6509 static IntWrapper& threadSpecificIntWrapper() |
| 6510 { | 6510 { |
| 6511 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 6511 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 6512 ThreadSpecific<Persistent<IntWrapper>>, intWrapper, | 6512 ThreadSpecific<Persistent<IntWrapper>>, intWrapper, |
| 6513 new ThreadSpecific<Persistent<IntWrapper>>); | 6513 new ThreadSpecific<Persistent<IntWrapper>>); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6560 conservativelyCollectGarbage(); | 6560 conservativelyCollectGarbage(); |
| 6561 EXPECT_EQ(wrapper, weakWrapper->value()); | 6561 EXPECT_EQ(wrapper, weakWrapper->value()); |
| 6562 // Stub out any stack reference. | 6562 // Stub out any stack reference. |
| 6563 wrapper = nullptr; | 6563 wrapper = nullptr; |
| 6564 } | 6564 } |
| 6565 preciselyCollectGarbage(); | 6565 preciselyCollectGarbage(); |
| 6566 EXPECT_EQ(nullptr, weakWrapper->value()); | 6566 EXPECT_EQ(nullptr, weakWrapper->value()); |
| 6567 } | 6567 } |
| 6568 | 6568 |
| 6569 } // namespace blink | 6569 } // namespace blink |
| OLD | NEW |