| 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 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 static void test(ThreadedTesterBase* tester) { | 417 static void test(ThreadedTesterBase* tester) { |
| 418 Vector<std::unique_ptr<WebThread>, numberOfThreads> m_threads; | 418 Vector<std::unique_ptr<WebThread>, numberOfThreads> m_threads; |
| 419 for (int i = 0; i < numberOfThreads; i++) { | 419 for (int i = 0; i < numberOfThreads; i++) { |
| 420 m_threads.push_back(WTF::wrapUnique( | 420 m_threads.push_back(WTF::wrapUnique( |
| 421 Platform::current()->createThread("blink gc testing thread"))); | 421 Platform::current()->createThread("blink gc testing thread"))); |
| 422 m_threads.back()->getWebTaskRunner()->postTask( | 422 m_threads.back()->getWebTaskRunner()->postTask( |
| 423 BLINK_FROM_HERE, | 423 BLINK_FROM_HERE, |
| 424 crossThreadBind(threadFunc, crossThreadUnretained(tester))); | 424 crossThreadBind(threadFunc, crossThreadUnretained(tester))); |
| 425 } | 425 } |
| 426 while (tester->m_threadsToFinish) { | 426 while (tester->m_threadsToFinish) { |
| 427 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 428 testing::yieldCurrentThread(); | 427 testing::yieldCurrentThread(); |
| 429 } | 428 } |
| 430 delete tester; | 429 delete tester; |
| 431 } | 430 } |
| 432 | 431 |
| 433 virtual void runThread() = 0; | 432 virtual void runThread() = 0; |
| 434 | 433 |
| 435 protected: | 434 protected: |
| 436 static const int numberOfThreads = 10; | 435 static const int numberOfThreads = 10; |
| 437 static const int gcPerThread = 5; | 436 static const int gcPerThread = 5; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 void runThread() override { | 490 void runThread() override { |
| 492 ThreadState::attachCurrentThread(); | 491 ThreadState::attachCurrentThread(); |
| 493 | 492 |
| 494 // Add a cross-thread persistent from this thread; the test object | 493 // Add a cross-thread persistent from this thread; the test object |
| 495 // verifies that it will have been cleared out after the threads | 494 // verifies that it will have been cleared out after the threads |
| 496 // have all detached, running their termination GCs while doing so. | 495 // have all detached, running their termination GCs while doing so. |
| 497 addGlobalPersistent(); | 496 addGlobalPersistent(); |
| 498 | 497 |
| 499 int gcCount = 0; | 498 int gcCount = 0; |
| 500 while (!done()) { | 499 while (!done()) { |
| 501 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | |
| 502 { | 500 { |
| 503 Persistent<IntWrapper> wrapper; | 501 Persistent<IntWrapper> wrapper; |
| 504 | 502 |
| 505 std::unique_ptr<GlobalIntWrapperPersistent> globalPersistent = | 503 std::unique_ptr<GlobalIntWrapperPersistent> globalPersistent = |
| 506 createGlobalPersistent(0x0ed0cabb); | 504 createGlobalPersistent(0x0ed0cabb); |
| 507 | 505 |
| 508 for (int i = 0; i < numberOfAllocations; i++) { | 506 for (int i = 0; i < numberOfAllocations; i++) { |
| 509 wrapper = IntWrapper::create(0x0bbac0de); | 507 wrapper = IntWrapper::create(0x0bbac0de); |
| 510 if (!(i % 10)) { | 508 if (!(i % 10)) { |
| 511 globalPersistent = createGlobalPersistent(0x0ed0cabb); | 509 globalPersistent = createGlobalPersistent(0x0ed0cabb); |
| 512 } | 510 } |
| 513 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 514 testing::yieldCurrentThread(); | 511 testing::yieldCurrentThread(); |
| 515 } | 512 } |
| 516 | 513 |
| 517 if (gcCount < gcPerThread) { | 514 if (gcCount < gcPerThread) { |
| 518 preciselyCollectGarbage(); | 515 preciselyCollectGarbage(); |
| 519 gcCount++; | 516 gcCount++; |
| 520 atomicIncrement(&m_gcCount); | 517 atomicIncrement(&m_gcCount); |
| 521 } | 518 } |
| 522 | 519 |
| 523 // Taking snapshot shouldn't have any bad side effect. | 520 // Taking snapshot shouldn't have any bad side effect. |
| 524 // TODO(haraken): This snapshot GC causes crashes, so disable | 521 // TODO(haraken): This snapshot GC causes crashes, so disable |
| 525 // it at the moment. Fix the crash and enable it. | 522 // it at the moment. Fix the crash and enable it. |
| 526 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, | 523 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, |
| 527 // BlinkGC::TakeSnapshot, BlinkGC::ForcedGC); | 524 // BlinkGC::TakeSnapshot, BlinkGC::ForcedGC); |
| 528 preciselyCollectGarbage(); | 525 preciselyCollectGarbage(); |
| 529 EXPECT_EQ(wrapper->value(), 0x0bbac0de); | 526 EXPECT_EQ(wrapper->value(), 0x0bbac0de); |
| 530 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); | 527 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); |
| 531 } | 528 } |
| 532 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 533 testing::yieldCurrentThread(); | 529 testing::yieldCurrentThread(); |
| 534 } | 530 } |
| 535 | 531 |
| 536 ThreadState::detachCurrentThread(); | 532 ThreadState::detachCurrentThread(); |
| 537 atomicDecrement(&m_threadsToFinish); | 533 atomicDecrement(&m_threadsToFinish); |
| 538 } | 534 } |
| 539 }; | 535 }; |
| 540 | 536 |
| 541 class ThreadedWeaknessTester : public ThreadedTesterBase { | 537 class ThreadedWeaknessTester : public ThreadedTesterBase { |
| 542 public: | 538 public: |
| 543 static void test() { ThreadedTesterBase::test(new ThreadedWeaknessTester); } | 539 static void test() { ThreadedTesterBase::test(new ThreadedWeaknessTester); } |
| 544 | 540 |
| 545 private: | 541 private: |
| 546 void runThread() override { | 542 void runThread() override { |
| 547 ThreadState::attachCurrentThread(); | 543 ThreadState::attachCurrentThread(); |
| 548 | 544 |
| 549 int gcCount = 0; | 545 int gcCount = 0; |
| 550 while (!done()) { | 546 while (!done()) { |
| 551 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | |
| 552 { | 547 { |
| 553 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> weakMap = | 548 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> weakMap = |
| 554 new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; | 549 new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; |
| 555 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weakMap2; | 550 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weakMap2; |
| 556 | 551 |
| 557 for (int i = 0; i < numberOfAllocations; i++) { | 552 for (int i = 0; i < numberOfAllocations; i++) { |
| 558 weakMap->insert(static_cast<unsigned>(i), IntWrapper::create(0)); | 553 weakMap->insert(static_cast<unsigned>(i), IntWrapper::create(0)); |
| 559 weakMap2.insert(static_cast<unsigned>(i), IntWrapper::create(0)); | 554 weakMap2.insert(static_cast<unsigned>(i), IntWrapper::create(0)); |
| 560 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 561 testing::yieldCurrentThread(); | 555 testing::yieldCurrentThread(); |
| 562 } | 556 } |
| 563 | 557 |
| 564 if (gcCount < gcPerThread) { | 558 if (gcCount < gcPerThread) { |
| 565 preciselyCollectGarbage(); | 559 preciselyCollectGarbage(); |
| 566 gcCount++; | 560 gcCount++; |
| 567 atomicIncrement(&m_gcCount); | 561 atomicIncrement(&m_gcCount); |
| 568 } | 562 } |
| 569 | 563 |
| 570 // Taking snapshot shouldn't have any bad side effect. | 564 // Taking snapshot shouldn't have any bad side effect. |
| 571 // TODO(haraken): This snapshot GC causes crashes, so disable | 565 // TODO(haraken): This snapshot GC causes crashes, so disable |
| 572 // it at the moment. Fix the crash and enable it. | 566 // it at the moment. Fix the crash and enable it. |
| 573 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, | 567 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, |
| 574 // BlinkGC::TakeSnapshot, BlinkGC::ForcedGC); | 568 // BlinkGC::TakeSnapshot, BlinkGC::ForcedGC); |
| 575 preciselyCollectGarbage(); | 569 preciselyCollectGarbage(); |
| 576 EXPECT_TRUE(weakMap->isEmpty()); | 570 EXPECT_TRUE(weakMap->isEmpty()); |
| 577 EXPECT_TRUE(weakMap2.isEmpty()); | 571 EXPECT_TRUE(weakMap2.isEmpty()); |
| 578 } | 572 } |
| 579 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 580 testing::yieldCurrentThread(); | 573 testing::yieldCurrentThread(); |
| 581 } | 574 } |
| 582 ThreadState::detachCurrentThread(); | 575 ThreadState::detachCurrentThread(); |
| 583 atomicDecrement(&m_threadsToFinish); | 576 atomicDecrement(&m_threadsToFinish); |
| 584 } | 577 } |
| 585 }; | 578 }; |
| 586 | 579 |
| 587 class ThreadPersistentHeapTester : public ThreadedTesterBase { | 580 class ThreadPersistentHeapTester : public ThreadedTesterBase { |
| 588 public: | 581 public: |
| 589 static void test() { | 582 static void test() { |
| (...skipping 4675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5265 // be marked. | 5258 // be marked. |
| 5266 preciselyCollectGarbage(); | 5259 preciselyCollectGarbage(); |
| 5267 preciselyCollectGarbage(); | 5260 preciselyCollectGarbage(); |
| 5268 | 5261 |
| 5269 // Wake up the worker thread so it can continue. It will sweep | 5262 // Wake up the worker thread so it can continue. It will sweep |
| 5270 // and perform another GC where the backing store of its | 5263 // and perform another GC where the backing store of its |
| 5271 // collection should be strongified. | 5264 // collection should be strongified. |
| 5272 wakeWorkerThread(); | 5265 wakeWorkerThread(); |
| 5273 | 5266 |
| 5274 // Wait for the worker thread to sweep its heaps before checking. | 5267 // Wait for the worker thread to sweep its heaps before checking. |
| 5275 { | 5268 parkMainThread(); |
| 5276 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 5277 parkMainThread(); | |
| 5278 } | |
| 5279 } | 5269 } |
| 5280 | 5270 |
| 5281 private: | 5271 private: |
| 5282 using WeakCollectionType = | 5272 using WeakCollectionType = |
| 5283 HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>>; | 5273 HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>>; |
| 5284 | 5274 |
| 5285 static WeakCollectionType* allocateCollection() { | 5275 static WeakCollectionType* allocateCollection() { |
| 5286 // Create a weak collection that is kept alive by a persistent | 5276 // Create a weak collection that is kept alive by a persistent |
| 5287 // and keep the contents alive with a persistents as | 5277 // and keep the contents alive with a persistents as |
| 5288 // well. | 5278 // well. |
| 5289 Persistent<IntWrapper> wrapper1 = IntWrapper::create(32); | 5279 Persistent<IntWrapper> wrapper1 = IntWrapper::create(32); |
| 5290 Persistent<IntWrapper> wrapper2 = IntWrapper::create(32); | 5280 Persistent<IntWrapper> wrapper2 = IntWrapper::create(32); |
| 5291 Persistent<IntWrapper> wrapper3 = IntWrapper::create(32); | 5281 Persistent<IntWrapper> wrapper3 = IntWrapper::create(32); |
| 5292 Persistent<IntWrapper> wrapper4 = IntWrapper::create(32); | 5282 Persistent<IntWrapper> wrapper4 = IntWrapper::create(32); |
| 5293 Persistent<IntWrapper> wrapper5 = IntWrapper::create(32); | 5283 Persistent<IntWrapper> wrapper5 = IntWrapper::create(32); |
| 5294 Persistent<IntWrapper> wrapper6 = IntWrapper::create(32); | 5284 Persistent<IntWrapper> wrapper6 = IntWrapper::create(32); |
| 5295 Persistent<WeakCollectionType> weakCollection = new WeakCollectionType; | 5285 Persistent<WeakCollectionType> weakCollection = new WeakCollectionType; |
| 5296 weakCollection->insert(wrapper1, wrapper1); | 5286 weakCollection->insert(wrapper1, wrapper1); |
| 5297 weakCollection->insert(wrapper2, wrapper2); | 5287 weakCollection->insert(wrapper2, wrapper2); |
| 5298 weakCollection->insert(wrapper3, wrapper3); | 5288 weakCollection->insert(wrapper3, wrapper3); |
| 5299 weakCollection->insert(wrapper4, wrapper4); | 5289 weakCollection->insert(wrapper4, wrapper4); |
| 5300 weakCollection->insert(wrapper5, wrapper5); | 5290 weakCollection->insert(wrapper5, wrapper5); |
| 5301 weakCollection->insert(wrapper6, wrapper6); | 5291 weakCollection->insert(wrapper6, wrapper6); |
| 5302 | 5292 |
| 5303 // Signal the main thread that the worker is done with its allocation. | 5293 // Signal the main thread that the worker is done with its allocation. |
| 5304 wakeMainThread(); | 5294 wakeMainThread(); |
| 5305 | 5295 |
| 5306 { | 5296 // Wait for the main thread to do two GCs without sweeping |
| 5307 // Wait for the main thread to do two GCs without sweeping | 5297 // this thread heap. |
| 5308 // this thread heap. The worker waits within a safepoint, | 5298 parkWorkerThread(); |
| 5309 // but there is no sweeping until leaving the safepoint | |
| 5310 // scope. If the weak collection backing is marked dead | |
| 5311 // because of this we will not get strongification in the | |
| 5312 // GC we force when we continue. | |
| 5313 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 5314 parkWorkerThread(); | |
| 5315 } | |
| 5316 | 5299 |
| 5317 return weakCollection; | 5300 return weakCollection; |
| 5318 } | 5301 } |
| 5319 | 5302 |
| 5320 static void workerThreadMain() { | 5303 static void workerThreadMain() { |
| 5321 MutexLocker locker(workerThreadMutex()); | 5304 MutexLocker locker(workerThreadMutex()); |
| 5322 | 5305 |
| 5323 ThreadState::attachCurrentThread(); | 5306 ThreadState::attachCurrentThread(); |
| 5324 | 5307 |
| 5325 { | 5308 { |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6101 CrossThreadWeakPersistent<DestructorLockingObject> crossThreadWeakPersistent( | 6084 CrossThreadWeakPersistent<DestructorLockingObject> crossThreadWeakPersistent( |
| 6102 object); | 6085 object); |
| 6103 object = nullptr; | 6086 object = nullptr; |
| 6104 { | 6087 { |
| 6105 MutexLocker recursiveMutexLocker(recursiveMutex()); | 6088 MutexLocker recursiveMutexLocker(recursiveMutex()); |
| 6106 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); | 6089 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); |
| 6107 } | 6090 } |
| 6108 | 6091 |
| 6109 { | 6092 { |
| 6110 // Pretend we have no pointers on stack during the step 4. | 6093 // Pretend we have no pointers on stack during the step 4. |
| 6111 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | |
| 6112 wakeWorkerThread(); | 6094 wakeWorkerThread(); |
| 6113 parkMainThread(); | 6095 parkMainThread(); |
| 6114 } | 6096 } |
| 6115 | 6097 |
| 6116 // Step 5: Make sure the weak persistent is cleared. | 6098 // Step 5: Make sure the weak persistent is cleared. |
| 6117 EXPECT_FALSE(crossThreadWeakPersistent.get()); | 6099 EXPECT_FALSE(crossThreadWeakPersistent.get()); |
| 6118 { | 6100 { |
| 6119 MutexLocker recursiveMutexLocker(recursiveMutex()); | 6101 MutexLocker recursiveMutexLocker(recursiveMutex()); |
| 6120 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); | 6102 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); |
| 6121 } | 6103 } |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6362 "HeapVector"); | 6344 "HeapVector"); |
| 6363 static_assert( | 6345 static_assert( |
| 6364 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, | 6346 WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value, |
| 6365 "HeapDeque"); | 6347 "HeapDeque"); |
| 6366 static_assert(WTF::IsGarbageCollectedType< | 6348 static_assert(WTF::IsGarbageCollectedType< |
| 6367 HeapTerminatedArray<Member<IntWrapper>>>::value, | 6349 HeapTerminatedArray<Member<IntWrapper>>>::value, |
| 6368 "HeapTerminatedArray"); | 6350 "HeapTerminatedArray"); |
| 6369 } | 6351 } |
| 6370 | 6352 |
| 6371 } // namespace blink | 6353 } // namespace blink |
| OLD | NEW |