| 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    43 #include "public/platform/WebTraceLocation.h" |    43 #include "public/platform/WebTraceLocation.h" | 
|    44 #include "wtf/HashTraits.h" |    44 #include "wtf/HashTraits.h" | 
|    45 #include "wtf/LinkedHashSet.h" |    45 #include "wtf/LinkedHashSet.h" | 
|    46  |    46  | 
|    47 #include <gtest/gtest.h> |    47 #include <gtest/gtest.h> | 
|    48  |    48  | 
|    49 namespace blink { |    49 namespace blink { | 
|    50  |    50  | 
|    51 static void preciselyCollectGarbage() |    51 static void preciselyCollectGarbage() | 
|    52 { |    52 { | 
|    53     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
      Sweep, Heap::ForcedGC); |    53     Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, H
      eap::ForcedGC); | 
|    54 } |    54 } | 
|    55  |    55  | 
|    56 static void conservativelyCollectGarbage() |    56 static void conservativelyCollectGarbage() | 
|    57 { |    57 { | 
|    58     Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
      eep, Heap::ForcedGC); |    58     Heap::collectGarbage(BlinkGC::HeapPointersOnStack, BlinkGC::GCWithSweep, Hea
      p::ForcedGC); | 
|    59 } |    59 } | 
|    60  |    60  | 
|    61 class IntWrapper : public GarbageCollectedFinalized<IntWrapper> { |    61 class IntWrapper : public GarbageCollectedFinalized<IntWrapper> { | 
|    62 public: |    62 public: | 
|    63     static IntWrapper* create(int x) |    63     static IntWrapper* create(int x) | 
|    64     { |    64     { | 
|    65         return new IntWrapper(x); |    65         return new IntWrapper(x); | 
|    66     } |    66     } | 
|    67  |    67  | 
|    68     virtual ~IntWrapper() |    68     virtual ~IntWrapper() | 
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   235     static void constructDeletedValue(blink::PairWithWeakHandling& slot, bool) {
       new (NotNull, &slot) blink::PairWithWeakHandling(HashTableDeletedValue); } |   235     static void constructDeletedValue(blink::PairWithWeakHandling& slot, bool) {
       new (NotNull, &slot) blink::PairWithWeakHandling(HashTableDeletedValue); } | 
|   236     static bool isDeletedValue(const blink::PairWithWeakHandling& value) { retur
      n value.isHashTableDeletedValue(); } |   236     static bool isDeletedValue(const blink::PairWithWeakHandling& value) { retur
      n value.isHashTableDeletedValue(); } | 
|   237 }; |   237 }; | 
|   238  |   238  | 
|   239 } |   239 } | 
|   240  |   240  | 
|   241 namespace blink { |   241 namespace blink { | 
|   242  |   242  | 
|   243 class TestGCScope { |   243 class TestGCScope { | 
|   244 public: |   244 public: | 
|   245     explicit TestGCScope(ThreadState::StackState state) |   245     explicit TestGCScope(BlinkGC::StackState state) | 
|   246         : m_state(ThreadState::current()) |   246         : m_state(ThreadState::current()) | 
|   247         , m_safePointScope(state) |   247         , m_safePointScope(state) | 
|   248         , m_parkedAllThreads(false) |   248         , m_parkedAllThreads(false) | 
|   249     { |   249     { | 
|   250         ASSERT(m_state->checkThread()); |   250         ASSERT(m_state->checkThread()); | 
|   251         if (LIKELY(ThreadState::stopThreads())) { |   251         if (LIKELY(ThreadState::stopThreads())) { | 
|   252             Heap::preGC(); |   252             Heap::preGC(); | 
|   253             m_parkedAllThreads = true; |   253             m_parkedAllThreads = true; | 
|   254         } |   254         } | 
|   255     } |   255     } | 
|   256  |   256  | 
|   257     bool allThreadsParked() { return m_parkedAllThreads; } |   257     bool allThreadsParked() { return m_parkedAllThreads; } | 
|   258  |   258  | 
|   259     ~TestGCScope() |   259     ~TestGCScope() | 
|   260     { |   260     { | 
|   261         // Only cleanup if we parked all threads in which case the GC happened |   261         // Only cleanup if we parked all threads in which case the GC happened | 
|   262         // and we need to resume the other threads. |   262         // and we need to resume the other threads. | 
|   263         if (LIKELY(m_parkedAllThreads)) { |   263         if (LIKELY(m_parkedAllThreads)) { | 
|   264             Heap::postGC(ThreadState::GCWithSweep); |   264             Heap::postGC(BlinkGC::GCWithSweep); | 
|   265             ThreadState::resumeThreads(); |   265             ThreadState::resumeThreads(); | 
|   266         } |   266         } | 
|   267     } |   267     } | 
|   268  |   268  | 
|   269 private: |   269 private: | 
|   270     ThreadState* m_state; |   270     ThreadState* m_state; | 
|   271     SafePointScope m_safePointScope; |   271     SafePointScope m_safePointScope; | 
|   272     bool m_parkedAllThreads; // False if we fail to park all threads |   272     bool m_parkedAllThreads; // False if we fail to park all threads | 
|   273 }; |   273 }; | 
|   274  |   274  | 
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   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()->taskRunner()->postTask(FROM_HERE, new Task(threadS
      afeBind(threadFunc, AllowCrossThreadAccess(tester)))); |   468             m_threads.last()->taskRunner()->postTask(FROM_HERE, new Task(threadS
      afeBind(threadFunc, AllowCrossThreadAccess(tester)))); | 
|   469         } |   469         } | 
|   470         while (tester->m_threadsToFinish) { |   470         while (tester->m_threadsToFinish) { | 
|   471             SafePointScope scope(ThreadState::NoHeapPointersOnStack); |   471             SafePointScope scope(BlinkGC::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  | 
|   479 protected: |   479 protected: | 
|   480     static const int numberOfThreads = 10; |   480     static const int numberOfThreads = 10; | 
|   481     static const int gcPerThread = 5; |   481     static const int gcPerThread = 5; | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   517     } |   517     } | 
|   518  |   518  | 
|   519     void runThread() override |   519     void runThread() override | 
|   520     { |   520     { | 
|   521         OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent; |   521         OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent; | 
|   522         ThreadState::attach(); |   522         ThreadState::attach(); | 
|   523  |   523  | 
|   524         longLivingPersistent = createGlobalPersistent(0x2a2a2a2a); |   524         longLivingPersistent = createGlobalPersistent(0x2a2a2a2a); | 
|   525         int gcCount = 0; |   525         int gcCount = 0; | 
|   526         while (!done()) { |   526         while (!done()) { | 
|   527             ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack
      ); |   527             ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 
|   528             { |   528             { | 
|   529                 Persistent<IntWrapper> wrapper; |   529                 Persistent<IntWrapper> wrapper; | 
|   530  |   530  | 
|   531                 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob
      alPersistent(0x0ed0cabb); |   531                 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob
      alPersistent(0x0ed0cabb); | 
|   532  |   532  | 
|   533                 for (int i = 0; i < numberOfAllocations; i++) { |   533                 for (int i = 0; i < numberOfAllocations; i++) { | 
|   534                     wrapper = IntWrapper::create(0x0bbac0de); |   534                     wrapper = IntWrapper::create(0x0bbac0de); | 
|   535                     if (!(i % 10)) { |   535                     if (!(i % 10)) { | 
|   536                         globalPersistent = createGlobalPersistent(0x0ed0cabb); |   536                         globalPersistent = createGlobalPersistent(0x0ed0cabb); | 
|   537                     } |   537                     } | 
|   538                     SafePointScope scope(ThreadState::NoHeapPointersOnStack); |   538                     SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 
|   539                     Platform::current()->yieldCurrentThread(); |   539                     Platform::current()->yieldCurrentThread(); | 
|   540                 } |   540                 } | 
|   541  |   541  | 
|   542                 if (gcCount < gcPerThread) { |   542                 if (gcCount < gcPerThread) { | 
|   543                     preciselyCollectGarbage(); |   543                     preciselyCollectGarbage(); | 
|   544                     gcCount++; |   544                     gcCount++; | 
|   545                     atomicIncrement(&m_gcCount); |   545                     atomicIncrement(&m_gcCount); | 
|   546                 } |   546                 } | 
|   547  |   547  | 
|   548                 // Taking snapshot shouldn't have any bad side effect. |   548                 // Taking snapshot shouldn't have any bad side effect. | 
|   549                 // TODO(haraken): This snapshot GC causes crashes, so disable |   549                 // TODO(haraken): This snapshot GC causes crashes, so disable | 
|   550                 // it at the moment. Fix the crash and enable it. |   550                 // it at the moment. Fix the crash and enable it. | 
|   551                 // Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thre
      adState::TakeSnapshot, Heap::ForcedGC); |   551                 // Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC:
      :TakeSnapshot, Heap::ForcedGC); | 
|   552                 preciselyCollectGarbage(); |   552                 preciselyCollectGarbage(); | 
|   553                 EXPECT_EQ(wrapper->value(), 0x0bbac0de); |   553                 EXPECT_EQ(wrapper->value(), 0x0bbac0de); | 
|   554                 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); |   554                 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); | 
|   555             } |   555             } | 
|   556             SafePointScope scope(ThreadState::NoHeapPointersOnStack); |   556             SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 
|   557             Platform::current()->yieldCurrentThread(); |   557             Platform::current()->yieldCurrentThread(); | 
|   558         } |   558         } | 
|   559  |   559  | 
|   560         // Intentionally leak the cross-thread persistent so as to verify |   560         // Intentionally leak the cross-thread persistent so as to verify | 
|   561         // that later GCs correctly handle cross-thread persistents that |   561         // that later GCs correctly handle cross-thread persistents that | 
|   562         // refer to finalized objects after their heaps have been detached |   562         // refer to finalized objects after their heaps have been detached | 
|   563         // and freed. |   563         // and freed. | 
|   564         EXPECT_TRUE(longLivingPersistent.leakPtr()); |   564         EXPECT_TRUE(longLivingPersistent.leakPtr()); | 
|   565  |   565  | 
|   566         ThreadState::detach(); |   566         ThreadState::detach(); | 
|   567         atomicDecrement(&m_threadsToFinish); |   567         atomicDecrement(&m_threadsToFinish); | 
|   568     } |   568     } | 
|   569 }; |   569 }; | 
|   570  |   570  | 
|   571 class ThreadedWeaknessTester : public ThreadedTesterBase { |   571 class ThreadedWeaknessTester : public ThreadedTesterBase { | 
|   572 public: |   572 public: | 
|   573     static void test() |   573     static void test() | 
|   574     { |   574     { | 
|   575         ThreadedTesterBase::test(new ThreadedWeaknessTester); |   575         ThreadedTesterBase::test(new ThreadedWeaknessTester); | 
|   576     } |   576     } | 
|   577  |   577  | 
|   578 private: |   578 private: | 
|   579     void runThread() override |   579     void runThread() override | 
|   580     { |   580     { | 
|   581         ThreadState::attach(); |   581         ThreadState::attach(); | 
|   582  |   582  | 
|   583         int gcCount = 0; |   583         int gcCount = 0; | 
|   584         while (!done()) { |   584         while (!done()) { | 
|   585             ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack
      ); |   585             ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 
|   586             { |   586             { | 
|   587                 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we
      akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; |   587                 Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> we
      akMap = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; | 
|   588                 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
      Map2; |   588                 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
      Map2; | 
|   589  |   589  | 
|   590                 for (int i = 0; i < numberOfAllocations; i++) { |   590                 for (int i = 0; i < numberOfAllocations; i++) { | 
|   591                     weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
      ); |   591                     weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
      ); | 
|   592                     weakMap2.add(static_cast<unsigned>(i), IntWrapper::create(0)
      ); |   592                     weakMap2.add(static_cast<unsigned>(i), IntWrapper::create(0)
      ); | 
|   593                     SafePointScope scope(ThreadState::NoHeapPointersOnStack); |   593                     SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 
|   594                     Platform::current()->yieldCurrentThread(); |   594                     Platform::current()->yieldCurrentThread(); | 
|   595                 } |   595                 } | 
|   596  |   596  | 
|   597                 if (gcCount < gcPerThread) { |   597                 if (gcCount < gcPerThread) { | 
|   598                     preciselyCollectGarbage(); |   598                     preciselyCollectGarbage(); | 
|   599                     gcCount++; |   599                     gcCount++; | 
|   600                     atomicIncrement(&m_gcCount); |   600                     atomicIncrement(&m_gcCount); | 
|   601                 } |   601                 } | 
|   602  |   602  | 
|   603                 // Taking snapshot shouldn't have any bad side effect. |   603                 // Taking snapshot shouldn't have any bad side effect. | 
|   604                 // TODO(haraken): This snapshot GC causes crashes, so disable |   604                 // TODO(haraken): This snapshot GC causes crashes, so disable | 
|   605                 // it at the moment. Fix the crash and enable it. |   605                 // it at the moment. Fix the crash and enable it. | 
|   606                 // Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thre
      adState::TakeSnapshot, Heap::ForcedGC); |   606                 // Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC:
      :TakeSnapshot, Heap::ForcedGC); | 
|   607                 preciselyCollectGarbage(); |   607                 preciselyCollectGarbage(); | 
|   608                 EXPECT_TRUE(weakMap->isEmpty()); |   608                 EXPECT_TRUE(weakMap->isEmpty()); | 
|   609                 EXPECT_TRUE(weakMap2.isEmpty()); |   609                 EXPECT_TRUE(weakMap2.isEmpty()); | 
|   610             } |   610             } | 
|   611             SafePointScope scope(ThreadState::NoHeapPointersOnStack); |   611             SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 
|   612             Platform::current()->yieldCurrentThread(); |   612             Platform::current()->yieldCurrentThread(); | 
|   613         } |   613         } | 
|   614         ThreadState::detach(); |   614         ThreadState::detach(); | 
|   615         atomicDecrement(&m_threadsToFinish); |   615         atomicDecrement(&m_threadsToFinish); | 
|   616     } |   616     } | 
|   617 }; |   617 }; | 
|   618  |   618  | 
|   619 class ThreadPersistentHeapTester : public ThreadedTesterBase { |   619 class ThreadPersistentHeapTester : public ThreadedTesterBase { | 
|   620 public: |   620 public: | 
|   621     static void test() |   621     static void test() | 
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   772     // so as to avoid possible warnings about linker duplicates. |   772     // so as to avoid possible warnings about linker duplicates. | 
|   773     // Override operator new to allocate IntNode subtype objects onto |   773     // Override operator new to allocate IntNode subtype objects onto | 
|   774     // the dedicated heap for blink::Node. |   774     // the dedicated heap for blink::Node. | 
|   775     // |   775     // | 
|   776     // TODO(haraken): untangling the heap unit tests from Blink would |   776     // TODO(haraken): untangling the heap unit tests from Blink would | 
|   777     // simplify and avoid running into this problem - http://crbug.com/425381 |   777     // simplify and avoid running into this problem - http://crbug.com/425381 | 
|   778     GC_PLUGIN_IGNORE("crbug.com/443854") |   778     GC_PLUGIN_IGNORE("crbug.com/443854") | 
|   779     void* operator new(size_t size) |   779     void* operator new(size_t size) | 
|   780     { |   780     { | 
|   781         ThreadState* state = ThreadState::current(); |   781         ThreadState* state = ThreadState::current(); | 
|   782         return Heap::allocateOnHeapIndex(state, size, ThreadState::NodeHeapIndex
      , GCInfoTrait<IntNode>::index()); |   782         return Heap::allocateOnHeapIndex(state, size, BlinkGC::NodeHeapIndex, GC
      InfoTrait<IntNode>::index()); | 
|   783     } |   783     } | 
|   784  |   784  | 
|   785     static IntNode* create(int i) |   785     static IntNode* create(int i) | 
|   786     { |   786     { | 
|   787         return new IntNode(i); |   787         return new IntNode(i); | 
|   788     } |   788     } | 
|   789  |   789  | 
|   790     DEFINE_INLINE_TRACE() { } |   790     DEFINE_INLINE_TRACE() { } | 
|   791  |   791  | 
|   792     int value() { return m_value; } |   792     int value() { return m_value; } | 
| (...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1964 #endif |  1964 #endif | 
|  1965  |  1965  | 
|  1966 TEST(HeapTest, LazySweepingPages) |  1966 TEST(HeapTest, LazySweepingPages) | 
|  1967 { |  1967 { | 
|  1968     clearOutOldGarbage(); |  1968     clearOutOldGarbage(); | 
|  1969  |  1969  | 
|  1970     SimpleFinalizedObject::s_destructorCalls = 0; |  1970     SimpleFinalizedObject::s_destructorCalls = 0; | 
|  1971     EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |  1971     EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 
|  1972     for (int i = 0; i < 1000; i++) |  1972     for (int i = 0; i < 1000; i++) | 
|  1973         SimpleFinalizedObject::create(); |  1973         SimpleFinalizedObject::create(); | 
|  1974     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
      outSweep, Heap::ForcedGC); |  1974     Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithoutSweep
      , Heap::ForcedGC); | 
|  1975     EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |  1975     EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 
|  1976     for (int i = 0; i < 10000; i++) |  1976     for (int i = 0; i < 10000; i++) | 
|  1977         SimpleFinalizedObject::create(); |  1977         SimpleFinalizedObject::create(); | 
|  1978     EXPECT_EQ(1000, SimpleFinalizedObject::s_destructorCalls); |  1978     EXPECT_EQ(1000, SimpleFinalizedObject::s_destructorCalls); | 
|  1979     preciselyCollectGarbage(); |  1979     preciselyCollectGarbage(); | 
|  1980     EXPECT_EQ(11000, SimpleFinalizedObject::s_destructorCalls); |  1980     EXPECT_EQ(11000, SimpleFinalizedObject::s_destructorCalls); | 
|  1981 } |  1981 } | 
|  1982  |  1982  | 
|  1983 TEST(HeapTest, LazySweepingLargeObjectPages) |  1983 TEST(HeapTest, LazySweepingLargeObjectPages) | 
|  1984 { |  1984 { | 
|  1985     clearOutOldGarbage(); |  1985     clearOutOldGarbage(); | 
|  1986  |  1986  | 
|  1987     // Create free lists that can be reused for IntWrappers created in |  1987     // Create free lists that can be reused for IntWrappers created in | 
|  1988     // LargeHeapObject::create(). |  1988     // LargeHeapObject::create(). | 
|  1989     Persistent<IntWrapper> p1 = new IntWrapper(1); |  1989     Persistent<IntWrapper> p1 = new IntWrapper(1); | 
|  1990     for (int i = 0; i < 100; i++) { |  1990     for (int i = 0; i < 100; i++) { | 
|  1991         new IntWrapper(i); |  1991         new IntWrapper(i); | 
|  1992     } |  1992     } | 
|  1993     Persistent<IntWrapper> p2 = new IntWrapper(2); |  1993     Persistent<IntWrapper> p2 = new IntWrapper(2); | 
|  1994     preciselyCollectGarbage(); |  1994     preciselyCollectGarbage(); | 
|  1995     preciselyCollectGarbage(); |  1995     preciselyCollectGarbage(); | 
|  1996  |  1996  | 
|  1997     LargeHeapObject::s_destructorCalls = 0; |  1997     LargeHeapObject::s_destructorCalls = 0; | 
|  1998     EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |  1998     EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 
|  1999     for (int i = 0; i < 10; i++) |  1999     for (int i = 0; i < 10; i++) | 
|  2000         LargeHeapObject::create(); |  2000         LargeHeapObject::create(); | 
|  2001     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
      outSweep, Heap::ForcedGC); |  2001     Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithoutSweep
      , Heap::ForcedGC); | 
|  2002     EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |  2002     EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 
|  2003     for (int i = 0; i < 10; i++) { |  2003     for (int i = 0; i < 10; i++) { | 
|  2004         LargeHeapObject::create(); |  2004         LargeHeapObject::create(); | 
|  2005         EXPECT_EQ(i + 1, LargeHeapObject::s_destructorCalls); |  2005         EXPECT_EQ(i + 1, LargeHeapObject::s_destructorCalls); | 
|  2006     } |  2006     } | 
|  2007     LargeHeapObject::create(); |  2007     LargeHeapObject::create(); | 
|  2008     LargeHeapObject::create(); |  2008     LargeHeapObject::create(); | 
|  2009     EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |  2009     EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 
|  2010     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
      outSweep, Heap::ForcedGC); |  2010     Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithoutSweep
      , Heap::ForcedGC); | 
|  2011     EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |  2011     EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 
|  2012     preciselyCollectGarbage(); |  2012     preciselyCollectGarbage(); | 
|  2013     EXPECT_EQ(22, LargeHeapObject::s_destructorCalls); |  2013     EXPECT_EQ(22, LargeHeapObject::s_destructorCalls); | 
|  2014 } |  2014 } | 
|  2015  |  2015  | 
|  2016 class SimpleFinalizedEagerObjectBase : public GarbageCollectedFinalized<SimpleFi
      nalizedEagerObjectBase> { |  2016 class SimpleFinalizedEagerObjectBase : public GarbageCollectedFinalized<SimpleFi
      nalizedEagerObjectBase> { | 
|  2017 public: |  2017 public: | 
|  2018     virtual ~SimpleFinalizedEagerObjectBase() { } |  2018     virtual ~SimpleFinalizedEagerObjectBase() { } | 
|  2019     DEFINE_INLINE_TRACE() { } |  2019     DEFINE_INLINE_TRACE() { } | 
|  2020  |  2020  | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2075     SimpleFinalizedEagerObject::s_destructorCalls = 0; |  2075     SimpleFinalizedEagerObject::s_destructorCalls = 0; | 
|  2076     SimpleFinalizedObjectInstanceOfTemplate::s_destructorCalls = 0; |  2076     SimpleFinalizedObjectInstanceOfTemplate::s_destructorCalls = 0; | 
|  2077     EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |  2077     EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 
|  2078     EXPECT_EQ(0, SimpleFinalizedEagerObject::s_destructorCalls); |  2078     EXPECT_EQ(0, SimpleFinalizedEagerObject::s_destructorCalls); | 
|  2079     for (int i = 0; i < 1000; i++) |  2079     for (int i = 0; i < 1000; i++) | 
|  2080         SimpleFinalizedObject::create(); |  2080         SimpleFinalizedObject::create(); | 
|  2081     for (int i = 0; i < 100; i++) |  2081     for (int i = 0; i < 100; i++) | 
|  2082         SimpleFinalizedEagerObject::create(); |  2082         SimpleFinalizedEagerObject::create(); | 
|  2083     for (int i = 0; i < 100; i++) |  2083     for (int i = 0; i < 100; i++) | 
|  2084         SimpleFinalizedObjectInstanceOfTemplate::create(); |  2084         SimpleFinalizedObjectInstanceOfTemplate::create(); | 
|  2085     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
      outSweep, Heap::ForcedGC); |  2085     Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithoutSweep
      , Heap::ForcedGC); | 
|  2086     EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |  2086     EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 
|  2087     EXPECT_EQ(100, SimpleFinalizedEagerObject::s_destructorCalls); |  2087     EXPECT_EQ(100, SimpleFinalizedEagerObject::s_destructorCalls); | 
|  2088     EXPECT_EQ(100, SimpleFinalizedObjectInstanceOfTemplate::s_destructorCalls); |  2088     EXPECT_EQ(100, SimpleFinalizedObjectInstanceOfTemplate::s_destructorCalls); | 
|  2089 } |  2089 } | 
|  2090  |  2090  | 
|  2091 TEST(HeapTest, Finalization) |  2091 TEST(HeapTest, Finalization) | 
|  2092 { |  2092 { | 
|  2093     { |  2093     { | 
|  2094         HeapTestSubClass* t1 = HeapTestSubClass::create(); |  2094         HeapTestSubClass* t1 = HeapTestSubClass::create(); | 
|  2095         HeapTestSubClass* t2 = HeapTestSubClass::create(); |  2095         HeapTestSubClass* t2 = HeapTestSubClass::create(); | 
| (...skipping 1696 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3792     largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1; |  3792     largeObjectEndAddress = largeObjectAddress + sizeof(LargeHeapObject) - 1; | 
|  3793  |  3793  | 
|  3794     // This is a low-level test where we call checkAndMarkPointer. This method |  3794     // This is a low-level test where we call checkAndMarkPointer. This method | 
|  3795     // causes the object start bitmap to be computed which requires the heap |  3795     // causes the object start bitmap to be computed which requires the heap | 
|  3796     // to be in a consistent state (e.g. the free allocation area must be put |  3796     // to be in a consistent state (e.g. the free allocation area must be put | 
|  3797     // into a free list header). However when we call makeConsistentForGC it |  3797     // into a free list header). However when we call makeConsistentForGC it | 
|  3798     // also clears out the freelists so we have to rebuild those before trying |  3798     // also clears out the freelists so we have to rebuild those before trying | 
|  3799     // to allocate anything again. We do this by forcing a GC after doing the |  3799     // to allocate anything again. We do this by forcing a GC after doing the | 
|  3800     // checkAndMarkPointer tests. |  3800     // checkAndMarkPointer tests. | 
|  3801     { |  3801     { | 
|  3802         TestGCScope scope(ThreadState::HeapPointersOnStack); |  3802         TestGCScope scope(BlinkGC::HeapPointersOnStack); | 
|  3803         EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not 
      park all threads. |  3803         EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not 
      park all threads. | 
|  3804         Heap::flushHeapDoesNotContainCache(); |  3804         Heap::flushHeapDoesNotContainCache(); | 
|  3805         for (size_t i = 0; i < objectAddresses.size(); i++) { |  3805         for (size_t i = 0; i < objectAddresses.size(); i++) { | 
|  3806             EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]))
      ; |  3806             EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]))
      ; | 
|  3807             EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i])); |  3807             EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i])); | 
|  3808         } |  3808         } | 
|  3809         EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); |  3809         EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); | 
|  3810         visitor.reset(); |  3810         visitor.reset(); | 
|  3811         EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress)); |  3811         EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress)); | 
|  3812         EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress)); |  3812         EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress)); | 
|  3813         EXPECT_EQ(2ul, visitor.count()); |  3813         EXPECT_EQ(2ul, visitor.count()); | 
|  3814         visitor.reset(); |  3814         visitor.reset(); | 
|  3815     } |  3815     } | 
|  3816     // This forces a GC without stack scanning which results in the objects |  3816     // This forces a GC without stack scanning which results in the objects | 
|  3817     // being collected. This will also rebuild the above mentioned freelists, |  3817     // being collected. This will also rebuild the above mentioned freelists, | 
|  3818     // however we don't rely on that below since we don't have any allocations. |  3818     // however we don't rely on that below since we don't have any allocations. | 
|  3819     clearOutOldGarbage(); |  3819     clearOutOldGarbage(); | 
|  3820     { |  3820     { | 
|  3821         TestGCScope scope(ThreadState::HeapPointersOnStack); |  3821         TestGCScope scope(BlinkGC::HeapPointersOnStack); | 
|  3822         EXPECT_TRUE(scope.allThreadsParked()); |  3822         EXPECT_TRUE(scope.allThreadsParked()); | 
|  3823         Heap::flushHeapDoesNotContainCache(); |  3823         Heap::flushHeapDoesNotContainCache(); | 
|  3824         for (size_t i = 0; i < objectAddresses.size(); i++) { |  3824         for (size_t i = 0; i < objectAddresses.size(); i++) { | 
|  3825             // We would like to assert that checkAndMarkPointer returned false |  3825             // We would like to assert that checkAndMarkPointer returned false | 
|  3826             // here because the pointers no longer point into a valid object |  3826             // here because the pointers no longer point into a valid object | 
|  3827             // (it's been freed by the GCs. But checkAndMarkPointer will return |  3827             // (it's been freed by the GCs. But checkAndMarkPointer will return | 
|  3828             // true for any pointer that points into a heap page, regardless of |  3828             // true for any pointer that points into a heap page, regardless of | 
|  3829             // whether it points at a valid object (this ensures the |  3829             // whether it points at a valid object (this ensures the | 
|  3830             // correctness of the page-based on-heap address caches), so we |  3830             // correctness of the page-based on-heap address caches), so we | 
|  3831             // can't make that assert. |  3831             // can't make that assert. | 
| (...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4638         OwnPtr<WebThread> sleepingThread = adoptPtr(Platform::current()->createT
      hread("SleepingThread")); |  4638         OwnPtr<WebThread> sleepingThread = adoptPtr(Platform::current()->createT
      hread("SleepingThread")); | 
|  4639         sleepingThread->taskRunner()->postTask(FROM_HERE, new Task(threadSafeBin
      d(sleeperMainFunc))); |  4639         sleepingThread->taskRunner()->postTask(FROM_HERE, new Task(threadSafeBin
      d(sleeperMainFunc))); | 
|  4640  |  4640  | 
|  4641         // Wait for the sleeper to run. |  4641         // Wait for the sleeper to run. | 
|  4642         while (!s_sleeperRunning) { |  4642         while (!s_sleeperRunning) { | 
|  4643             Platform::current()->yieldCurrentThread(); |  4643             Platform::current()->yieldCurrentThread(); | 
|  4644         } |  4644         } | 
|  4645  |  4645  | 
|  4646         { |  4646         { | 
|  4647             // Expect the first attempt to park the sleeping thread to fail |  4647             // Expect the first attempt to park the sleeping thread to fail | 
|  4648             TestGCScope scope(ThreadState::NoHeapPointersOnStack); |  4648             TestGCScope scope(BlinkGC::NoHeapPointersOnStack); | 
|  4649             EXPECT_FALSE(scope.allThreadsParked()); |  4649             EXPECT_FALSE(scope.allThreadsParked()); | 
|  4650         } |  4650         } | 
|  4651  |  4651  | 
|  4652         s_sleeperDone = true; |  4652         s_sleeperDone = true; | 
|  4653  |  4653  | 
|  4654         // Wait for the sleeper to finish. |  4654         // Wait for the sleeper to finish. | 
|  4655         while (s_sleeperRunning) { |  4655         while (s_sleeperRunning) { | 
|  4656             // We enter the safepoint here since the sleeper thread will detach |  4656             // We enter the safepoint here since the sleeper thread will detach | 
|  4657             // causing it to GC. |  4657             // causing it to GC. | 
|  4658             ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack
      ); |  4658             ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 
|  4659             Platform::current()->yieldCurrentThread(); |  4659             Platform::current()->yieldCurrentThread(); | 
|  4660         } |  4660         } | 
|  4661  |  4661  | 
|  4662         { |  4662         { | 
|  4663             // Since the sleeper thread has detached this is the only thread. |  4663             // Since the sleeper thread has detached this is the only thread. | 
|  4664             TestGCScope scope(ThreadState::NoHeapPointersOnStack); |  4664             TestGCScope scope(BlinkGC::NoHeapPointersOnStack); | 
|  4665             EXPECT_TRUE(scope.allThreadsParked()); |  4665             EXPECT_TRUE(scope.allThreadsParked()); | 
|  4666         } |  4666         } | 
|  4667     } |  4667     } | 
|  4668  |  4668  | 
|  4669 private: |  4669 private: | 
|  4670     static void sleeperMainFunc() |  4670     static void sleeperMainFunc() | 
|  4671     { |  4671     { | 
|  4672         ThreadState::attach(); |  4672         ThreadState::attach(); | 
|  4673         s_sleeperRunning = true; |  4673         s_sleeperRunning = true; | 
|  4674  |  4674  | 
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5368             s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); |  5368             s_workerObjectPointer = reinterpret_cast<uintptr_t>(workerObject); | 
|  5369         } |  5369         } | 
|  5370  |  5370  | 
|  5371         // Signal the main thread that the worker is done with its allocation. |  5371         // Signal the main thread that the worker is done with its allocation. | 
|  5372         wakeMainThread(); |  5372         wakeMainThread(); | 
|  5373  |  5373  | 
|  5374         { |  5374         { | 
|  5375             // Wait for the main thread to do two GCs without sweeping this thre
      ad |  5375             // Wait for the main thread to do two GCs without sweeping this thre
      ad | 
|  5376             // heap. The worker waits within a safepoint, but there is no sweepi
      ng |  5376             // heap. The worker waits within a safepoint, but there is no sweepi
      ng | 
|  5377             // until leaving the safepoint scope. |  5377             // until leaving the safepoint scope. | 
|  5378             SafePointScope scope(ThreadState::NoHeapPointersOnStack); |  5378             SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 
|  5379             parkWorkerThread(); |  5379             parkWorkerThread(); | 
|  5380         } |  5380         } | 
|  5381  |  5381  | 
|  5382         // Wake up the main thread when done sweeping. |  5382         // Wake up the main thread when done sweeping. | 
|  5383         wakeMainThread(); |  5383         wakeMainThread(); | 
|  5384  |  5384  | 
|  5385         // Wait with detach until the main thread says so. This is not strictly |  5385         // Wait with detach until the main thread says so. This is not strictly | 
|  5386         // necessary, but it means the worker thread will not do its thread loca
      l |  5386         // necessary, but it means the worker thread will not do its thread loca
      l | 
|  5387         // GCs just yet, making it easier to reason about that no new GC has occ
      urred |  5387         // GCs just yet, making it easier to reason about that no new GC has occ
      urred | 
|  5388         // and the above sweep was the one finalizing the worker object. |  5388         // and the above sweep was the one finalizing the worker object. | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5424         preciselyCollectGarbage(); |  5424         preciselyCollectGarbage(); | 
|  5425         preciselyCollectGarbage(); |  5425         preciselyCollectGarbage(); | 
|  5426  |  5426  | 
|  5427         // Wake up the worker thread so it can continue. It will sweep |  5427         // Wake up the worker thread so it can continue. It will sweep | 
|  5428         // and perform another GC where the backing store of its |  5428         // and perform another GC where the backing store of its | 
|  5429         // collection should be strongified. |  5429         // collection should be strongified. | 
|  5430         wakeWorkerThread(); |  5430         wakeWorkerThread(); | 
|  5431  |  5431  | 
|  5432         // Wait for the worker thread to sweep its heaps before checking. |  5432         // Wait for the worker thread to sweep its heaps before checking. | 
|  5433         { |  5433         { | 
|  5434             SafePointScope scope(ThreadState::NoHeapPointersOnStack); |  5434             SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 
|  5435             parkMainThread(); |  5435             parkMainThread(); | 
|  5436         } |  5436         } | 
|  5437     } |  5437     } | 
|  5438  |  5438  | 
|  5439 private: |  5439 private: | 
|  5440  |  5440  | 
|  5441     using WeakCollectionType = HeapHashMap<WeakMember<IntWrapper>, Member<IntWra
      pper>>; |  5441     using WeakCollectionType = HeapHashMap<WeakMember<IntWrapper>, Member<IntWra
      pper>>; | 
|  5442  |  5442  | 
|  5443     static WeakCollectionType* allocateCollection() |  5443     static WeakCollectionType* allocateCollection() | 
|  5444     { |  5444     { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|  5462         // Signal the main thread that the worker is done with its allocation. |  5462         // Signal the main thread that the worker is done with its allocation. | 
|  5463         wakeMainThread(); |  5463         wakeMainThread(); | 
|  5464  |  5464  | 
|  5465         { |  5465         { | 
|  5466             // Wait for the main thread to do two GCs without sweeping |  5466             // Wait for the main thread to do two GCs without sweeping | 
|  5467             // this thread heap. The worker waits within a safepoint, |  5467             // this thread heap. The worker waits within a safepoint, | 
|  5468             // but there is no sweeping until leaving the safepoint |  5468             // but there is no sweeping until leaving the safepoint | 
|  5469             // scope. If the weak collection backing is marked dead |  5469             // scope. If the weak collection backing is marked dead | 
|  5470             // because of this we will not get strongification in the |  5470             // because of this we will not get strongification in the | 
|  5471             // GC we force when we continue. |  5471             // GC we force when we continue. | 
|  5472             SafePointScope scope(ThreadState::NoHeapPointersOnStack); |  5472             SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 
|  5473             parkWorkerThread(); |  5473             parkWorkerThread(); | 
|  5474         } |  5474         } | 
|  5475  |  5475  | 
|  5476         return weakCollection; |  5476         return weakCollection; | 
|  5477     } |  5477     } | 
|  5478  |  5478  | 
|  5479     static void workerThreadMain() |  5479     static void workerThreadMain() | 
|  5480     { |  5480     { | 
|  5481         MutexLocker locker(workerThreadMutex()); |  5481         MutexLocker locker(workerThreadMutex()); | 
|  5482  |  5482  | 
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5653         // Wait for the main thread to get the global lock to ensure it has |  5653         // Wait for the main thread to get the global lock to ensure it has | 
|  5654         // it before the worker tries to acquire it. We want the worker to |  5654         // it before the worker tries to acquire it. We want the worker to | 
|  5655         // block in the SafePointAwareMutexLocker until the main thread |  5655         // block in the SafePointAwareMutexLocker until the main thread | 
|  5656         // has done a GC. The GC will not mark the "dlo" object since the worker |  5656         // has done a GC. The GC will not mark the "dlo" object since the worker | 
|  5657         // is entering the safepoint with NoHeapPointersOnStack. When the worker |  5657         // is entering the safepoint with NoHeapPointersOnStack. When the worker | 
|  5658         // subsequently gets the global lock and leaves the safepoint it will |  5658         // subsequently gets the global lock and leaves the safepoint it will | 
|  5659         // sweep its heap and finalize "dlo". The destructor of "dlo" will try |  5659         // sweep its heap and finalize "dlo". The destructor of "dlo" will try | 
|  5660         // to acquire the same global lock that the thread just got and deadlock |  5660         // to acquire the same global lock that the thread just got and deadlock | 
|  5661         // unless the global lock is recursive. |  5661         // unless the global lock is recursive. | 
|  5662         parkWorkerThread(); |  5662         parkWorkerThread(); | 
|  5663         SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), ThreadState:
      :NoHeapPointersOnStack); |  5663         SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), BlinkGC::NoH
      eapPointersOnStack); | 
|  5664  |  5664  | 
|  5665         // We won't get here unless the lock is recursive since the sweep done |  5665         // We won't get here unless the lock is recursive since the sweep done | 
|  5666         // in the constructor of SafePointAwareMutexLocker after |  5666         // in the constructor of SafePointAwareMutexLocker after | 
|  5667         // getting the lock will not complete given the "dlo" destructor is |  5667         // getting the lock will not complete given the "dlo" destructor is | 
|  5668         // waiting to get the same lock. |  5668         // waiting to get the same lock. | 
|  5669         // Tell the main thread the worker has done its sweep. |  5669         // Tell the main thread the worker has done its sweep. | 
|  5670         wakeMainThread(); |  5670         wakeMainThread(); | 
|  5671  |  5671  | 
|  5672         ThreadState::detach(); |  5672         ThreadState::detach(); | 
|  5673     } |  5673     } | 
| (...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  6374 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject** 
      object) |  6374 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject** 
      object) | 
|  6375 { |  6375 { | 
|  6376     // Step 2: Create an object and store the pointer. |  6376     // Step 2: Create an object and store the pointer. | 
|  6377     MutexLocker locker(workerThreadMutex()); |  6377     MutexLocker locker(workerThreadMutex()); | 
|  6378     ThreadState::attach(); |  6378     ThreadState::attach(); | 
|  6379     *object = DestructorLockingObject::create(); |  6379     *object = DestructorLockingObject::create(); | 
|  6380     wakeMainThread(); |  6380     wakeMainThread(); | 
|  6381     parkWorkerThread(); |  6381     parkWorkerThread(); | 
|  6382  |  6382  | 
|  6383     // Step 4: Run a GC. |  6383     // Step 4: Run a GC. | 
|  6384     Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
      Sweep, Heap::ForcedGC); |  6384     Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, H
      eap::ForcedGC); | 
|  6385     wakeMainThread(); |  6385     wakeMainThread(); | 
|  6386     parkWorkerThread(); |  6386     parkWorkerThread(); | 
|  6387  |  6387  | 
|  6388     // Step 6: Finish. |  6388     // Step 6: Finish. | 
|  6389     ThreadState::detach(); |  6389     ThreadState::detach(); | 
|  6390     wakeMainThread(); |  6390     wakeMainThread(); | 
|  6391 } |  6391 } | 
|  6392  |  6392  | 
|  6393 } // anonymous namespace |  6393 } // anonymous namespace | 
|  6394  |  6394  | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  6411     ASSERT_TRUE(object); |  6411     ASSERT_TRUE(object); | 
|  6412     CrossThreadWeakPersistent<DestructorLockingObject> crossThreadWeakPersistent
      (object); |  6412     CrossThreadWeakPersistent<DestructorLockingObject> crossThreadWeakPersistent
      (object); | 
|  6413     object = nullptr; |  6413     object = nullptr; | 
|  6414     { |  6414     { | 
|  6415         SafePointAwareMutexLocker recursiveMutexLocker(recursiveMutex()); |  6415         SafePointAwareMutexLocker recursiveMutexLocker(recursiveMutex()); | 
|  6416         EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); |  6416         EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); | 
|  6417     } |  6417     } | 
|  6418  |  6418  | 
|  6419     { |  6419     { | 
|  6420         // Pretend we have no pointers on stack during the step 4. |  6420         // Pretend we have no pointers on stack during the step 4. | 
|  6421         SafePointScope scope(ThreadState::NoHeapPointersOnStack); |  6421         SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 
|  6422         wakeWorkerThread(); |  6422         wakeWorkerThread(); | 
|  6423         parkMainThread(); |  6423         parkMainThread(); | 
|  6424     } |  6424     } | 
|  6425  |  6425  | 
|  6426     // Step 5: Make sure the weak persistent is cleared. |  6426     // Step 5: Make sure the weak persistent is cleared. | 
|  6427     EXPECT_FALSE(crossThreadWeakPersistent.get()); |  6427     EXPECT_FALSE(crossThreadWeakPersistent.get()); | 
|  6428     { |  6428     { | 
|  6429         SafePointAwareMutexLocker recursiveMutexLocker(recursiveMutex()); |  6429         SafePointAwareMutexLocker recursiveMutexLocker(recursiveMutex()); | 
|  6430         EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); |  6430         EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); | 
|  6431     } |  6431     } | 
|  6432  |  6432  | 
|  6433     wakeWorkerThread(); |  6433     wakeWorkerThread(); | 
|  6434     parkMainThread(); |  6434     parkMainThread(); | 
|  6435 } |  6435 } | 
|  6436  |  6436  | 
|  6437 } // namespace blink |  6437 } // namespace blink | 
| OLD | NEW |