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 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 int IntWrapper::s_destructorCalls = 0; | 458 int IntWrapper::s_destructorCalls = 0; |
459 int OffHeapInt::s_destructorCalls = 0; | 459 int OffHeapInt::s_destructorCalls = 0; |
460 | 460 |
461 class ThreadedTesterBase { | 461 class ThreadedTesterBase { |
462 protected: | 462 protected: |
463 static void test(ThreadedTesterBase* tester) | 463 static void test(ThreadedTesterBase* tester) |
464 { | 464 { |
465 Vector<OwnPtr<WebThread>, numberOfThreads> m_threads; | 465 Vector<OwnPtr<WebThread>, numberOfThreads> m_threads; |
466 for (int i = 0; i < numberOfThreads; i++) { | 466 for (int i = 0; i < numberOfThreads; i++) { |
467 m_threads.append(adoptPtr(Platform::current()->createThread("blink g
c testing thread"))); | 467 m_threads.append(adoptPtr(Platform::current()->createThread("blink g
c testing thread"))); |
468 m_threads.last()->postTask(FROM_HERE, new Task(threadSafeBind(thread
Func, AllowCrossThreadAccess(tester)))); | 468 m_threads.last()->defaultTaskRunner()->postTask(FROM_HERE, new Task(
threadSafeBind(threadFunc, AllowCrossThreadAccess(tester)))); |
469 } | 469 } |
470 while (tester->m_threadsToFinish) { | 470 while (tester->m_threadsToFinish) { |
471 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 471 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
472 Platform::current()->yieldCurrentThread(); | 472 Platform::current()->yieldCurrentThread(); |
473 } | 473 } |
474 delete tester; | 474 delete tester; |
475 } | 475 } |
476 | 476 |
477 virtual void runThread() = 0; | 477 virtual void runThread() = 0; |
478 | 478 |
(...skipping 4152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4631 } | 4631 } |
4632 preciselyCollectGarbage(); | 4632 preciselyCollectGarbage(); |
4633 EXPECT_EQ(3, IntWrapper::s_destructorCalls); | 4633 EXPECT_EQ(3, IntWrapper::s_destructorCalls); |
4634 } | 4634 } |
4635 | 4635 |
4636 class GCParkingThreadTester { | 4636 class GCParkingThreadTester { |
4637 public: | 4637 public: |
4638 static void test() | 4638 static void test() |
4639 { | 4639 { |
4640 OwnPtr<WebThread> sleepingThread = adoptPtr(Platform::current()->createT
hread("SleepingThread")); | 4640 OwnPtr<WebThread> sleepingThread = adoptPtr(Platform::current()->createT
hread("SleepingThread")); |
4641 sleepingThread->postTask(FROM_HERE, new Task(threadSafeBind(sleeperMainF
unc))); | 4641 sleepingThread->defaultTaskRunner()->postTask(FROM_HERE, new Task(thread
SafeBind(sleeperMainFunc))); |
4642 | 4642 |
4643 // Wait for the sleeper to run. | 4643 // Wait for the sleeper to run. |
4644 while (!s_sleeperRunning) { | 4644 while (!s_sleeperRunning) { |
4645 Platform::current()->yieldCurrentThread(); | 4645 Platform::current()->yieldCurrentThread(); |
4646 } | 4646 } |
4647 | 4647 |
4648 { | 4648 { |
4649 // Expect the first attempt to park the sleeping thread to fail | 4649 // Expect the first attempt to park the sleeping thread to fail |
4650 TestGCScope scope(ThreadState::NoHeapPointersOnStack); | 4650 TestGCScope scope(ThreadState::NoHeapPointersOnStack); |
4651 EXPECT_FALSE(scope.allThreadsParked()); | 4651 EXPECT_FALSE(scope.allThreadsParked()); |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5301 } | 5301 } |
5302 | 5302 |
5303 class DeadBitTester { | 5303 class DeadBitTester { |
5304 public: | 5304 public: |
5305 static void test() | 5305 static void test() |
5306 { | 5306 { |
5307 IntWrapper::s_destructorCalls = 0; | 5307 IntWrapper::s_destructorCalls = 0; |
5308 | 5308 |
5309 MutexLocker locker(mainThreadMutex()); | 5309 MutexLocker locker(mainThreadMutex()); |
5310 OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThr
ead("Test Worker Thread")); | 5310 OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThr
ead("Test Worker Thread")); |
5311 workerThread->postTask(FROM_HERE, new Task(threadSafeBind(workerThreadMa
in))); | 5311 workerThread->defaultTaskRunner()->postTask(FROM_HERE, new Task(threadSa
feBind(workerThreadMain))); |
5312 | 5312 |
5313 // Wait for the worker thread to have done its initialization, | 5313 // Wait for the worker thread to have done its initialization, |
5314 // IE. the worker allocates an object and then throw aways any | 5314 // IE. the worker allocates an object and then throw aways any |
5315 // pointers to it. | 5315 // pointers to it. |
5316 parkMainThread(); | 5316 parkMainThread(); |
5317 | 5317 |
5318 // Now do a GC. This will not find the worker threads object since it | 5318 // Now do a GC. This will not find the worker threads object since it |
5319 // is not referred from any of the threads. Even a conservative | 5319 // is not referred from any of the threads. Even a conservative |
5320 // GC will not find it. | 5320 // GC will not find it. |
5321 // Also at this point the worker is waiting for the main thread | 5321 // 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... |
5404 } | 5404 } |
5405 | 5405 |
5406 class ThreadedStrongificationTester { | 5406 class ThreadedStrongificationTester { |
5407 public: | 5407 public: |
5408 static void test() | 5408 static void test() |
5409 { | 5409 { |
5410 IntWrapper::s_destructorCalls = 0; | 5410 IntWrapper::s_destructorCalls = 0; |
5411 | 5411 |
5412 MutexLocker locker(mainThreadMutex()); | 5412 MutexLocker locker(mainThreadMutex()); |
5413 OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThr
ead("Test Worker Thread")); | 5413 OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThr
ead("Test Worker Thread")); |
5414 workerThread->postTask(FROM_HERE, new Task(threadSafeBind(workerThreadMa
in))); | 5414 workerThread->defaultTaskRunner()->postTask(FROM_HERE, new Task(threadSa
feBind(workerThreadMain))); |
5415 | 5415 |
5416 // Wait for the worker thread initialization. The worker | 5416 // Wait for the worker thread initialization. The worker |
5417 // allocates a weak collection where both collection and | 5417 // allocates a weak collection where both collection and |
5418 // contents are kept alive via persistent pointers. | 5418 // contents are kept alive via persistent pointers. |
5419 parkMainThread(); | 5419 parkMainThread(); |
5420 | 5420 |
5421 // Perform two garbage collections where the worker thread does | 5421 // Perform two garbage collections where the worker thread does |
5422 // not wake up in between. This will cause us to remove marks | 5422 // not wake up in between. This will cause us to remove marks |
5423 // and mark unmarked objects dead. The collection on the worker | 5423 // and mark unmarked objects dead. The collection on the worker |
5424 // heap is found through the persistent and the backing should | 5424 // heap is found through the persistent and the backing should |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5607 int DestructorLockingObject::s_destructorCalls = 0; | 5607 int DestructorLockingObject::s_destructorCalls = 0; |
5608 | 5608 |
5609 class RecursiveLockingTester { | 5609 class RecursiveLockingTester { |
5610 public: | 5610 public: |
5611 static void test() | 5611 static void test() |
5612 { | 5612 { |
5613 DestructorLockingObject::s_destructorCalls = 0; | 5613 DestructorLockingObject::s_destructorCalls = 0; |
5614 | 5614 |
5615 MutexLocker locker(mainThreadMutex()); | 5615 MutexLocker locker(mainThreadMutex()); |
5616 OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThr
ead("Test Worker Thread")); | 5616 OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThr
ead("Test Worker Thread")); |
5617 workerThread->postTask(FROM_HERE, new Task(threadSafeBind(workerThreadMa
in))); | 5617 workerThread->defaultTaskRunner()->postTask(FROM_HERE, new Task(threadSa
feBind(workerThreadMain))); |
5618 | 5618 |
5619 // Park the main thread until the worker thread has initialized. | 5619 // Park the main thread until the worker thread has initialized. |
5620 parkMainThread(); | 5620 parkMainThread(); |
5621 | 5621 |
5622 { | 5622 { |
5623 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); | 5623 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); |
5624 | 5624 |
5625 // Let the worker try to acquire the above mutex. It won't get it | 5625 // Let the worker try to acquire the above mutex. It won't get it |
5626 // until the main thread has done its GC. | 5626 // until the main thread has done its GC. |
5627 wakeWorkerThread(); | 5627 wakeWorkerThread(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5681 { | 5681 { |
5682 RecursiveLockingTester::test(); | 5682 RecursiveLockingTester::test(); |
5683 } | 5683 } |
5684 | 5684 |
5685 class CrossThreadPersistentOnMainThreadTester { | 5685 class CrossThreadPersistentOnMainThreadTester { |
5686 public: | 5686 public: |
5687 static void test() | 5687 static void test() |
5688 { | 5688 { |
5689 MutexLocker locker(mainThreadMutex()); | 5689 MutexLocker locker(mainThreadMutex()); |
5690 OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThr
ead("Test Worker Thread")); | 5690 OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThr
ead("Test Worker Thread")); |
5691 workerThread->postTask(FROM_HERE, new Task(threadSafeBind(workerThreadMa
in))); | 5691 workerThread->defaultTaskRunner()->postTask(FROM_HERE, new Task(threadSa
feBind(workerThreadMain))); |
5692 | 5692 |
5693 parkMainThread(); | 5693 parkMainThread(); |
5694 | 5694 |
5695 // (Temporarily) detach main thread and wake the worker thread, so that
it | 5695 // (Temporarily) detach main thread and wake the worker thread, so that
it |
5696 // can do its detach(). | 5696 // can do its detach(). |
5697 ThreadState::detachMainThread(); | 5697 ThreadState::detachMainThread(); |
5698 wakeWorkerThread(); | 5698 wakeWorkerThread(); |
5699 | 5699 |
5700 parkMainThread(); | 5700 parkMainThread(); |
5701 ThreadState::attachMainThread(); | 5701 ThreadState::attachMainThread(); |
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6399 // Create an object in the worker thread, have a CrossThreadWeakPersistent p
ointing to it on the main thread, | 6399 // Create an object in the worker thread, have a CrossThreadWeakPersistent p
ointing to it on the main thread, |
6400 // clear the reference in the worker thread, run a GC in the worker thread,
and see if the | 6400 // clear the reference in the worker thread, run a GC in the worker thread,
and see if the |
6401 // CrossThreadWeakPersistent is cleared. | 6401 // CrossThreadWeakPersistent is cleared. |
6402 | 6402 |
6403 DestructorLockingObject::s_destructorCalls = 0; | 6403 DestructorLockingObject::s_destructorCalls = 0; |
6404 | 6404 |
6405 // Step 1: Initiate a worker thread, and wait for |object| to get allocated
on the worker thread. | 6405 // Step 1: Initiate a worker thread, and wait for |object| to get allocated
on the worker thread. |
6406 MutexLocker mainThreadMutexLocker(mainThreadMutex()); | 6406 MutexLocker mainThreadMutexLocker(mainThreadMutex()); |
6407 OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThread(
"Test Worker Thread")); | 6407 OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThread(
"Test Worker Thread")); |
6408 DestructorLockingObject* object = nullptr; | 6408 DestructorLockingObject* object = nullptr; |
6409 workerThread->postTask(FROM_HERE, new Task(threadSafeBind(workerThreadMainFo
rCrossThreadWeakPersistentTest, AllowCrossThreadAccessWrapper<DestructorLockingO
bject**>(&object)))); | 6409 workerThread->defaultTaskRunner()->postTask(FROM_HERE, new Task(threadSafeBi
nd(workerThreadMainForCrossThreadWeakPersistentTest, AllowCrossThreadAccessWrapp
er<DestructorLockingObject**>(&object)))); |
6410 parkMainThread(); | 6410 parkMainThread(); |
6411 | 6411 |
6412 // Step 3: Set up a CrossThreadWeakPersistent. | 6412 // Step 3: Set up a CrossThreadWeakPersistent. |
6413 ASSERT_TRUE(object); | 6413 ASSERT_TRUE(object); |
6414 CrossThreadWeakPersistent<DestructorLockingObject> crossThreadWeakPersistent
(object); | 6414 CrossThreadWeakPersistent<DestructorLockingObject> crossThreadWeakPersistent
(object); |
6415 object = nullptr; | 6415 object = nullptr; |
6416 { | 6416 { |
6417 SafePointAwareMutexLocker recursiveMutexLocker(recursiveMutex()); | 6417 SafePointAwareMutexLocker recursiveMutexLocker(recursiveMutex()); |
6418 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); | 6418 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); |
6419 } | 6419 } |
(...skipping 10 matching lines...) Expand all Loading... |
6430 { | 6430 { |
6431 SafePointAwareMutexLocker recursiveMutexLocker(recursiveMutex()); | 6431 SafePointAwareMutexLocker recursiveMutexLocker(recursiveMutex()); |
6432 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); | 6432 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); |
6433 } | 6433 } |
6434 | 6434 |
6435 wakeWorkerThread(); | 6435 wakeWorkerThread(); |
6436 parkMainThread(); | 6436 parkMainThread(); |
6437 } | 6437 } |
6438 | 6438 |
6439 } // namespace blink | 6439 } // namespace blink |
OLD | NEW |