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

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

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

Powered by Google App Engine
This is Rietveld 408576698