Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Side by Side Diff: third_party/WebKit/Source/platform/heap/ThreadState.cpp

Issue 2321223003: Revert of Move collectGarbage* methods to ThreadState (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 21 matching lines...) Expand all
32 32
33 #include "base/trace_event/process_memory_dump.h" 33 #include "base/trace_event/process_memory_dump.h"
34 #include "platform/Histogram.h" 34 #include "platform/Histogram.h"
35 #include "platform/RuntimeEnabledFeatures.h" 35 #include "platform/RuntimeEnabledFeatures.h"
36 #include "platform/ScriptForbiddenScope.h" 36 #include "platform/ScriptForbiddenScope.h"
37 #include "platform/TraceEvent.h" 37 #include "platform/TraceEvent.h"
38 #include "platform/heap/BlinkGCMemoryDumpProvider.h" 38 #include "platform/heap/BlinkGCMemoryDumpProvider.h"
39 #include "platform/heap/CallbackStack.h" 39 #include "platform/heap/CallbackStack.h"
40 #include "platform/heap/Handle.h" 40 #include "platform/heap/Handle.h"
41 #include "platform/heap/Heap.h" 41 #include "platform/heap/Heap.h"
42 #include "platform/heap/PagePool.h"
43 #include "platform/heap/SafePoint.h" 42 #include "platform/heap/SafePoint.h"
44 #include "platform/heap/Visitor.h" 43 #include "platform/heap/Visitor.h"
45 #include "platform/web_memory_allocator_dump.h" 44 #include "platform/web_memory_allocator_dump.h"
46 #include "platform/web_process_memory_dump.h" 45 #include "platform/web_process_memory_dump.h"
47 #include "public/platform/Platform.h" 46 #include "public/platform/Platform.h"
48 #include "public/platform/WebScheduler.h" 47 #include "public/platform/WebScheduler.h"
49 #include "public/platform/WebThread.h" 48 #include "public/platform/WebThread.h"
50 #include "public/platform/WebTraceLocation.h" 49 #include "public/platform/WebTraceLocation.h"
51 #include "wtf/CurrentTime.h" 50 #include "wtf/CurrentTime.h"
52 #include "wtf/DataLog.h" 51 #include "wtf/DataLog.h"
(...skipping 19 matching lines...) Expand all
72 71
73 namespace blink { 72 namespace blink {
74 73
75 WTF::ThreadSpecific<ThreadState*>* ThreadState::s_threadSpecific = nullptr; 74 WTF::ThreadSpecific<ThreadState*>* ThreadState::s_threadSpecific = nullptr;
76 uintptr_t ThreadState::s_mainThreadStackStart = 0; 75 uintptr_t ThreadState::s_mainThreadStackStart = 0;
77 uintptr_t ThreadState::s_mainThreadUnderestimatedStackSize = 0; 76 uintptr_t ThreadState::s_mainThreadUnderestimatedStackSize = 0;
78 uint8_t ThreadState::s_mainThreadStateStorage[sizeof(ThreadState)]; 77 uint8_t ThreadState::s_mainThreadStateStorage[sizeof(ThreadState)];
79 78
80 const size_t defaultAllocatedObjectSizeThreshold = 100 * 1024; 79 const size_t defaultAllocatedObjectSizeThreshold = 100 * 1024;
81 80
82 const char* gcReasonString(BlinkGC::GCReason reason)
83 {
84 switch (reason) {
85 case BlinkGC::IdleGC:
86 return "IdleGC";
87 case BlinkGC::PreciseGC:
88 return "PreciseGC";
89 case BlinkGC::ConservativeGC:
90 return "ConservativeGC";
91 case BlinkGC::ForcedGC:
92 return "ForcedGC";
93 case BlinkGC::MemoryPressureGC:
94 return "MemoryPressureGC";
95 case BlinkGC::PageNavigationGC:
96 return "PageNavigationGC";
97 default:
98 NOTREACHED();
99 }
100 return "<Unknown>";
101 }
102
103 class ParkThreadsScope final {
104 STACK_ALLOCATED();
105 public:
106 explicit ParkThreadsScope(ThreadState* state)
107 : m_state(state)
108 , m_shouldResumeThreads(false)
109 {
110 }
111
112 bool parkThreads()
113 {
114 TRACE_EVENT0("blink_gc", "ThreadHeap::ParkThreadsScope");
115 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE();
116 if (m_state->isMainThread())
117 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting");
118
119 // TODO(haraken): In an unlikely coincidence that two threads decide
120 // to collect garbage at the same time, avoid doing two GCs in
121 // a row and return false.
122 double startTime = WTF::currentTimeMS();
123
124 m_shouldResumeThreads = m_state->heap().park();
125
126 double timeForStoppingThreads = WTF::currentTimeMS() - startTime;
127 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, timeToStopThreadsH istogram, new CustomCountHistogram("BlinkGC.TimeForStoppingThreads", 1, 1000, 50 ));
128 timeToStopThreadsHistogram.count(timeForStoppingThreads);
129
130 if (m_state->isMainThread())
131 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState);
132 return m_shouldResumeThreads;
133 }
134
135 ~ParkThreadsScope()
136 {
137 // Only cleanup if we parked all threads in which case the GC happened
138 // and we need to resume the other threads.
139 if (m_shouldResumeThreads)
140 m_state->heap().resume();
141 }
142
143 private:
144 ThreadState* m_state;
145 bool m_shouldResumeThreads;
146 };
147
148 ThreadState::ThreadState(bool perThreadHeapEnabled) 81 ThreadState::ThreadState(bool perThreadHeapEnabled)
149 : m_thread(currentThread()) 82 : m_thread(currentThread())
150 , m_persistentRegion(wrapUnique(new PersistentRegion())) 83 , m_persistentRegion(wrapUnique(new PersistentRegion()))
151 #if OS(WIN) && COMPILER(MSVC) 84 #if OS(WIN) && COMPILER(MSVC)
152 , m_threadStackSize(0) 85 , m_threadStackSize(0)
153 #endif 86 #endif
154 , m_startOfStack(reinterpret_cast<intptr_t*>(StackFrameDepth::getStackStart( ))) 87 , m_startOfStack(reinterpret_cast<intptr_t*>(StackFrameDepth::getStackStart( )))
155 , m_endOfStack(reinterpret_cast<intptr_t*>(StackFrameDepth::getStackStart()) ) 88 , m_endOfStack(reinterpret_cast<intptr_t*>(StackFrameDepth::getStackStart()) )
156 , m_safePointScopeMarker(nullptr) 89 , m_safePointScopeMarker(nullptr)
157 , m_atSafePoint(false) 90 , m_atSafePoint(false)
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 prepareForThreadStateTermination(); 231 prepareForThreadStateTermination();
299 232
300 ProcessHeap::crossThreadPersistentRegion().prepareForThreadStateTermination( this); 233 ProcessHeap::crossThreadPersistentRegion().prepareForThreadStateTermination( this);
301 234
302 // Do thread local GC's as long as the count of thread local Persistents 235 // Do thread local GC's as long as the count of thread local Persistents
303 // changes and is above zero. 236 // changes and is above zero.
304 int oldCount = -1; 237 int oldCount = -1;
305 int currentCount = getPersistentRegion()->numberOfPersistents(); 238 int currentCount = getPersistentRegion()->numberOfPersistents();
306 ASSERT(currentCount >= 0); 239 ASSERT(currentCount >= 0);
307 while (currentCount != oldCount) { 240 while (currentCount != oldCount) {
308 collectGarbageForTerminatingThread(); 241 ThreadHeap::collectGarbageForTerminatingThread(this);
309 // Release the thread-local static persistents that were 242 // Release the thread-local static persistents that were
310 // instantiated while running the termination GC. 243 // instantiated while running the termination GC.
311 releaseStaticPersistentNodes(); 244 releaseStaticPersistentNodes();
312 oldCount = currentCount; 245 oldCount = currentCount;
313 currentCount = getPersistentRegion()->numberOfPersistents(); 246 currentCount = getPersistentRegion()->numberOfPersistents();
314 } 247 }
315 // We should not have any persistents left when getting to this point, 248 // We should not have any persistents left when getting to this point,
316 // if we have it is probably a bug so adding a debug ASSERT to catch this. 249 // if we have it is probably a bug so adding a debug ASSERT to catch this.
317 ASSERT(!currentCount); 250 ASSERT(!currentCount);
318 // All of pre-finalizers should be consumed. 251 // All of pre-finalizers should be consumed.
319 ASSERT(m_orderedPreFinalizers.isEmpty()); 252 ASSERT(m_orderedPreFinalizers.isEmpty());
320 RELEASE_ASSERT(gcState() == NoGCScheduled); 253 RELEASE_ASSERT(gcState() == NoGCScheduled);
321 254
322 // Add pages to the orphaned page pool to ensure any global GCs from this po int 255 // Add pages to the orphaned page pool to ensure any global GCs from this po int
323 // on will not trace objects on this thread's arenas. 256 // on will not trace objects on this thread's arenas.
324 cleanupPages(); 257 cleanupPages();
325 } 258 }
326 259
327 void ThreadState::cleanupMainThread() 260 void ThreadState::cleanupMainThread()
328 { 261 {
329 ASSERT(isMainThread()); 262 ASSERT(isMainThread());
330 263
331 #if defined(LEAK_SANITIZER) 264 #if defined(LEAK_SANITIZER)
332 // See comment below, clear out most garbage before releasing static 265 // See comment below, clear out most garbage before releasing static
333 // persistents should some of the finalizers depend on touching 266 // persistents should some of the finalizers depend on touching
334 // these persistents. 267 // these persistents.
335 collectAllGarbage(); 268 ThreadHeap::collectAllGarbage();
336 #endif 269 #endif
337 270
338 releaseStaticPersistentNodes(); 271 releaseStaticPersistentNodes();
339 272
340 #if defined(LEAK_SANITIZER) 273 #if defined(LEAK_SANITIZER)
341 // If LSan is about to perform leak detection, after having released all 274 // If LSan is about to perform leak detection, after having released all
342 // the registered static Persistent<> root references to global caches 275 // the registered static Persistent<> root references to global caches
343 // that Blink keeps, follow up with a round of GCs to clear out all 276 // that Blink keeps, follow up with a round of GCs to clear out all
344 // what they referred to. 277 // what they referred to.
345 // 278 //
346 // This is not needed for caches over non-Oilpan objects, as they're 279 // This is not needed for caches over non-Oilpan objects, as they're
347 // not scanned by LSan due to being held in non-global storage 280 // not scanned by LSan due to being held in non-global storage
348 // ("static" references inside functions/methods.) 281 // ("static" references inside functions/methods.)
349 collectAllGarbage(); 282 ThreadHeap::collectAllGarbage();
350 #endif 283 #endif
351 284
352 // Finish sweeping before shutting down V8. Otherwise, some destructor 285 // Finish sweeping before shutting down V8. Otherwise, some destructor
353 // may access V8 and cause crashes. 286 // may access V8 and cause crashes.
354 completeSweep(); 287 completeSweep();
355 288
356 // It is unsafe to trigger GCs after this point because some 289 // It is unsafe to trigger GCs after this point because some
357 // destructor may access already-detached V8 and cause crashes. 290 // destructor may access already-detached V8 and cause crashes.
358 // Also it is useless. So we forbid GCs. 291 // Also it is useless. So we forbid GCs.
359 enterGCForbiddenScope(); 292 enterGCForbiddenScope();
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 // TODO(haraken): It might not make sense to force completeSweep() for all 615 // TODO(haraken): It might not make sense to force completeSweep() for all
683 // page navigations. 616 // page navigations.
684 completeSweep(); 617 completeSweep();
685 ASSERT(!isSweepingInProgress()); 618 ASSERT(!isSweepingInProgress());
686 ASSERT(!sweepForbidden()); 619 ASSERT(!sweepForbidden());
687 620
688 if (shouldForceMemoryPressureGC()) { 621 if (shouldForceMemoryPressureGC()) {
689 #if PRINT_HEAP_STATS 622 #if PRINT_HEAP_STATS
690 dataLogF("Scheduled MemoryPressureGC\n"); 623 dataLogF("Scheduled MemoryPressureGC\n");
691 #endif 624 #endif
692 collectGarbage(BlinkGC::HeapPointersOnStack, BlinkGC::GCWithoutSweep, Bl inkGC::MemoryPressureGC); 625 ThreadHeap::collectGarbage(BlinkGC::HeapPointersOnStack, BlinkGC::GCWith outSweep, BlinkGC::MemoryPressureGC);
693 return; 626 return;
694 } 627 }
695 if (shouldSchedulePageNavigationGC(estimatedRemovalRatio)) { 628 if (shouldSchedulePageNavigationGC(estimatedRemovalRatio)) {
696 #if PRINT_HEAP_STATS 629 #if PRINT_HEAP_STATS
697 dataLogF("Scheduled PageNavigationGC\n"); 630 dataLogF("Scheduled PageNavigationGC\n");
698 #endif 631 #endif
699 schedulePageNavigationGC(); 632 schedulePageNavigationGC();
700 } 633 }
701 } 634 }
702 635
(...skipping 23 matching lines...) Expand all
726 ASSERT(!sweepForbidden()); 659 ASSERT(!sweepForbidden());
727 660
728 reportMemoryToV8(); 661 reportMemoryToV8();
729 662
730 if (shouldForceMemoryPressureGC()) { 663 if (shouldForceMemoryPressureGC()) {
731 completeSweep(); 664 completeSweep();
732 if (shouldForceMemoryPressureGC()) { 665 if (shouldForceMemoryPressureGC()) {
733 #if PRINT_HEAP_STATS 666 #if PRINT_HEAP_STATS
734 dataLogF("Scheduled MemoryPressureGC\n"); 667 dataLogF("Scheduled MemoryPressureGC\n");
735 #endif 668 #endif
736 collectGarbage(BlinkGC::HeapPointersOnStack, BlinkGC::GCWithoutSweep , BlinkGC::MemoryPressureGC); 669 ThreadHeap::collectGarbage(BlinkGC::HeapPointersOnStack, BlinkGC::GC WithoutSweep, BlinkGC::MemoryPressureGC);
737 return; 670 return;
738 } 671 }
739 } 672 }
740 673
741 if (shouldForceConservativeGC()) { 674 if (shouldForceConservativeGC()) {
742 completeSweep(); 675 completeSweep();
743 if (shouldForceConservativeGC()) { 676 if (shouldForceConservativeGC()) {
744 #if PRINT_HEAP_STATS 677 #if PRINT_HEAP_STATS
745 dataLogF("Scheduled ConservativeGC\n"); 678 dataLogF("Scheduled ConservativeGC\n");
746 #endif 679 #endif
747 collectGarbage(BlinkGC::HeapPointersOnStack, BlinkGC::GCWithoutSweep , BlinkGC::ConservativeGC); 680 ThreadHeap::collectGarbage(BlinkGC::HeapPointersOnStack, BlinkGC::GC WithoutSweep, BlinkGC::ConservativeGC);
748 return; 681 return;
749 } 682 }
750 } 683 }
751 if (shouldScheduleIdleGC()) { 684 if (shouldScheduleIdleGC()) {
752 #if PRINT_HEAP_STATS 685 #if PRINT_HEAP_STATS
753 dataLogF("Scheduled IdleGC\n"); 686 dataLogF("Scheduled IdleGC\n");
754 #endif 687 #endif
755 scheduleIdleGC(); 688 scheduleIdleGC();
756 return; 689 return;
757 } 690 }
(...skipping 25 matching lines...) Expand all
783 716
784 double idleDeltaInSeconds = deadlineSeconds - monotonicallyIncreasingTime(); 717 double idleDeltaInSeconds = deadlineSeconds - monotonicallyIncreasingTime();
785 if (idleDeltaInSeconds <= m_heap->heapStats().estimatedMarkingTime() && !Pla tform::current()->currentThread()->scheduler()->canExceedIdleDeadlineIfRequired( )) { 718 if (idleDeltaInSeconds <= m_heap->heapStats().estimatedMarkingTime() && !Pla tform::current()->currentThread()->scheduler()->canExceedIdleDeadlineIfRequired( )) {
786 // If marking is estimated to take longer than the deadline and we can't 719 // If marking is estimated to take longer than the deadline and we can't
787 // exceed the deadline, then reschedule for the next idle period. 720 // exceed the deadline, then reschedule for the next idle period.
788 scheduleIdleGC(); 721 scheduleIdleGC();
789 return; 722 return;
790 } 723 }
791 724
792 TRACE_EVENT2("blink_gc", "ThreadState::performIdleGC", "idleDeltaInSeconds", idleDeltaInSeconds, "estimatedMarkingTime", m_heap->heapStats().estimatedMarkin gTime()); 725 TRACE_EVENT2("blink_gc", "ThreadState::performIdleGC", "idleDeltaInSeconds", idleDeltaInSeconds, "estimatedMarkingTime", m_heap->heapStats().estimatedMarkin gTime());
793 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithoutSweep, Blin kGC::IdleGC); 726 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithou tSweep, BlinkGC::IdleGC);
794 } 727 }
795 728
796 void ThreadState::performIdleLazySweep(double deadlineSeconds) 729 void ThreadState::performIdleLazySweep(double deadlineSeconds)
797 { 730 {
798 ASSERT(checkThread()); 731 ASSERT(checkThread());
799 ASSERT(isMainThread()); 732 ASSERT(isMainThread());
800 733
801 // If we are not in a sweeping phase, there is nothing to do here. 734 // If we are not in a sweeping phase, there is nothing to do here.
802 if (!isSweepingInProgress()) 735 if (!isSweepingInProgress())
803 return; 736 return;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 // If a safe point is entered while initiating a GC, we clearly do 892 // If a safe point is entered while initiating a GC, we clearly do
960 // not want to do another as part that -- the safe point is only 893 // not want to do another as part that -- the safe point is only
961 // entered after checking if a scheduled GC ought to run first. 894 // entered after checking if a scheduled GC ought to run first.
962 // Prevent that from happening by marking GCs as forbidden while 895 // Prevent that from happening by marking GCs as forbidden while
963 // one is initiated and later running. 896 // one is initiated and later running.
964 if (isGCForbidden()) 897 if (isGCForbidden())
965 return; 898 return;
966 899
967 switch (gcState()) { 900 switch (gcState()) {
968 case FullGCScheduled: 901 case FullGCScheduled:
969 collectAllGarbage(); 902 ThreadHeap::collectAllGarbage();
970 break; 903 break;
971 case PreciseGCScheduled: 904 case PreciseGCScheduled:
972 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithoutSweep, BlinkGC::PreciseGC); 905 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWi thoutSweep, BlinkGC::PreciseGC);
973 break; 906 break;
974 case PageNavigationGCScheduled: 907 case PageNavigationGCScheduled:
975 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, Bli nkGC::PageNavigationGC); 908 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWi thSweep, BlinkGC::PageNavigationGC);
976 break; 909 break;
977 case IdleGCScheduled: 910 case IdleGCScheduled:
978 // Idle time GC will be scheduled by Blink Scheduler. 911 // Idle time GC will be scheduled by Blink Scheduler.
979 break; 912 break;
980 default: 913 default:
981 break; 914 break;
982 } 915 }
983 } 916 }
984 917
985 void ThreadState::flushHeapDoesNotContainCacheIfNeeded() 918 void ThreadState::flushHeapDoesNotContainCacheIfNeeded()
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 threadDump->AddScalar("live_count", "objects", totalLiveCount); 1532 threadDump->AddScalar("live_count", "objects", totalLiveCount);
1600 threadDump->AddScalar("dead_count", "objects", totalDeadCount); 1533 threadDump->AddScalar("dead_count", "objects", totalDeadCount);
1601 threadDump->AddScalar("live_size", "bytes", totalLiveSize); 1534 threadDump->AddScalar("live_size", "bytes", totalLiveSize);
1602 threadDump->AddScalar("dead_size", "bytes", totalDeadSize); 1535 threadDump->AddScalar("dead_size", "bytes", totalDeadSize);
1603 1536
1604 base::trace_event::MemoryAllocatorDump* heapsDump = BlinkGCMemoryDumpProvide r::instance()->createMemoryAllocatorDumpForCurrentGC(heapsDumpName); 1537 base::trace_event::MemoryAllocatorDump* heapsDump = BlinkGCMemoryDumpProvide r::instance()->createMemoryAllocatorDumpForCurrentGC(heapsDumpName);
1605 base::trace_event::MemoryAllocatorDump* classesDump = BlinkGCMemoryDumpProvi der::instance()->createMemoryAllocatorDumpForCurrentGC(classesDumpName); 1538 base::trace_event::MemoryAllocatorDump* classesDump = BlinkGCMemoryDumpProvi der::instance()->createMemoryAllocatorDumpForCurrentGC(classesDumpName);
1606 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->AddOwners hipEdge(classesDump->guid(), heapsDump->guid()); 1539 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->AddOwners hipEdge(classesDump->guid(), heapsDump->guid());
1607 } 1540 }
1608 1541
1609 void ThreadState::collectGarbage(BlinkGC::StackState stackState, BlinkGC::GCType gcType, BlinkGC::GCReason reason)
1610 {
1611 DCHECK_NE(gcType, BlinkGC::ThreadTerminationGC);
1612
1613 // Nested collectGarbage() invocations aren't supported.
1614 RELEASE_ASSERT(!isGCForbidden());
1615 completeSweep();
1616
1617 std::unique_ptr<Visitor> visitor = Visitor::create(this, gcType);
1618
1619 SafePointScope safePointScope(stackState, this);
1620
1621 // Resume all parked threads upon leaving this scope.
1622 ParkThreadsScope parkThreadsScope(this);
1623
1624 // Try to park the other threads. If we're unable to, bail out of the GC.
1625 if (!parkThreadsScope.parkThreads())
1626 return;
1627
1628 ScriptForbiddenIfMainThreadScope scriptForbidden;
1629
1630 TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking",
1631 "lazySweeping", gcType == BlinkGC::GCWithoutSweep,
1632 "gcReason", gcReasonString(reason));
1633 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC");
1634 double startTime = WTF::currentTimeMS();
1635
1636 if (gcType == BlinkGC::TakeSnapshot)
1637 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC();
1638
1639 // Disallow allocation during garbage collection (but not during the
1640 // finalization that happens when the visitorScope is torn down).
1641 ThreadState::NoAllocationScope noAllocationScope(this);
1642
1643 heap().commitCallbackStacks();
1644 heap().preGC();
1645
1646 StackFrameDepthScope stackDepthScope(&heap().stackFrameDepth());
1647
1648 size_t totalObjectSize = heap().heapStats().allocatedObjectSize() + heap().h eapStats().markedObjectSize();
1649 if (gcType != BlinkGC::TakeSnapshot)
1650 heap().resetHeapCounters();
1651
1652 {
1653 // Access to the CrossThreadPersistentRegion has to be prevented while
1654 // marking and global weak processing is in progress. If not, threads
1655 // not attached to Oilpan and participating in this GC are able
1656 // to allocate & free PersistentNodes, something the marking phase isn't
1657 // capable of handling.
1658 CrossThreadPersistentRegion::LockScope persistentLock(ProcessHeap::cross ThreadPersistentRegion());
1659
1660 // 1. Trace persistent roots.
1661 heap().visitPersistentRoots(visitor.get());
1662
1663 // 2. Trace objects reachable from the stack. We do this independent of the
1664 // given stackState since other threads might have a different stack sta te.
1665 heap().visitStackRoots(visitor.get());
1666
1667 // 3. Transitive closure to trace objects including ephemerons.
1668 heap().processMarkingStack(visitor.get());
1669
1670 heap().postMarkingProcessing(visitor.get());
1671 heap().globalWeakProcessing(visitor.get());
1672 }
1673
1674 // Now we can delete all orphaned pages because there are no dangling
1675 // pointers to the orphaned pages. (If we have such dangling pointers,
1676 // we should have crashed during marking before getting here.)
1677 heap().getOrphanedPagePool()->decommitOrphanedPages();
1678
1679 double markingTimeInMilliseconds = WTF::currentTimeMS() - startTime;
1680 heap().heapStats().setEstimatedMarkingTimePerByte(totalObjectSize ? (marking TimeInMilliseconds / 1000 / totalObjectSize) : 0);
1681
1682 #if PRINT_HEAP_STATS
1683 dataLogF("ThreadHeap::collectGarbage (gcReason=%s, lazySweeping=%d, time=%.1 lfms)\n", gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, markingTime InMilliseconds);
1684 #endif
1685
1686 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, markingTimeHistogram, new CustomCountHistogram("BlinkGC.CollectGarbage", 0, 10 * 1000, 50));
1687 markingTimeHistogram.count(markingTimeInMilliseconds);
1688 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, totalObjectSpaceHistog ram, new CustomCountHistogram("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 1024, 50 ));
1689 totalObjectSpaceHistogram.count(ProcessHeap::totalAllocatedObjectSize() / 10 24);
1690 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, totalAllocatedSpaceHis togram, new CustomCountHistogram("BlinkGC.TotalAllocatedSpace", 0, 4 * 1024 * 10 24, 50));
1691 totalAllocatedSpaceHistogram.count(ProcessHeap::totalAllocatedSpace() / 1024 );
1692 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, gcReasonHistogram, new EnumerationHistogram("BlinkGC.GCReason", BlinkGC::NumberOfGCReason));
1693 gcReasonHistogram.count(reason);
1694
1695 heap().m_lastGCReason = reason;
1696
1697 ThreadHeap::reportMemoryUsageHistogram();
1698 WTF::Partitions::reportMemoryUsageHistogram();
1699
1700 heap().postGC(gcType);
1701 heap().decommitCallbackStacks();
1702 }
1703
1704 void ThreadState::collectGarbageForTerminatingThread()
1705 {
1706 {
1707 // A thread-specific termination GC must not allow other global GCs to g o
1708 // ahead while it is running, hence the termination GC does not enter a
1709 // safepoint. VisitorScope will not enter also a safepoint scope for
1710 // ThreadTerminationGC.
1711 std::unique_ptr<Visitor> visitor = Visitor::create(this, BlinkGC::Thread TerminationGC);
1712
1713 ThreadState::NoAllocationScope noAllocationScope(this);
1714
1715 heap().commitCallbackStacks();
1716 preGC();
1717
1718 // 1. Trace the thread local persistent roots. For thread local GCs we
1719 // don't trace the stack (ie. no conservative scanning) since this is
1720 // only called during thread shutdown where there should be no objects
1721 // on the stack.
1722 // We also assume that orphaned pages have no objects reachable from
1723 // persistent handles on other threads or CrossThreadPersistents. The
1724 // only cases where this could happen is if a subsequent conservative
1725 // global GC finds a "pointer" on the stack or due to a programming
1726 // error where an object has a dangling cross-thread pointer to an
1727 // object on this heap.
1728 visitPersistents(visitor.get());
1729
1730 // 2. Trace objects reachable from the thread's persistent roots
1731 // including ephemerons.
1732 heap().processMarkingStack(visitor.get());
1733
1734 heap().postMarkingProcessing(visitor.get());
1735 heap().globalWeakProcessing(visitor.get());
1736
1737 postGC(BlinkGC::GCWithSweep);
1738 heap().decommitCallbackStacks();
1739 }
1740 preSweep();
1741 }
1742
1743 void ThreadState::collectAllGarbage()
1744 {
1745 // We need to run multiple GCs to collect a chain of persistent handles.
1746 size_t previousLiveObjects = 0;
1747 for (int i = 0; i < 5; ++i) {
1748 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, Bli nkGC::ForcedGC);
1749 size_t liveObjects = heap().heapStats().markedObjectSize();
1750 if (liveObjects == previousLiveObjects)
1751 break;
1752 previousLiveObjects = liveObjects;
1753 }
1754 }
1755
1756 } // namespace blink 1542 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/heap/ThreadState.h ('k') | third_party/WebKit/Source/platform/mhtml/MHTMLFuzzer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698