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

Side by Side Diff: Source/platform/heap/Heap.cpp

Issue 559383002: Oilpan: Add trace events for the GC marking and sweeping phases. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | Source/platform/heap/ThreadState.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) 1239 for (HeapPage<Header>* page = m_firstPage; page; page = page->next())
1240 page->getStats(scannedStats); 1240 page->getStats(scannedStats);
1241 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; cur rent = current->next()) 1241 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; cur rent = current->next())
1242 current->getStats(scannedStats); 1242 current->getStats(scannedStats);
1243 } 1243 }
1244 #endif 1244 #endif
1245 1245
1246 template<typename Header> 1246 template<typename Header>
1247 void ThreadHeap<Header>::sweepNormalPages(HeapStats* stats) 1247 void ThreadHeap<Header>::sweepNormalPages(HeapStats* stats)
1248 { 1248 {
1249 TRACE_EVENT0("blink_gc", "ThreadHeap::sweepNormalPages");
1249 HeapPage<Header>* page = m_firstPage; 1250 HeapPage<Header>* page = m_firstPage;
1250 HeapPage<Header>** previousNext = &m_firstPage; 1251 HeapPage<Header>** previousNext = &m_firstPage;
1251 HeapPage<Header>* previous = 0; 1252 HeapPage<Header>* previous = 0;
1252 while (page) { 1253 while (page) {
1253 page->resetPromptlyFreedSize(); 1254 page->resetPromptlyFreedSize();
1254 if (page->isEmpty()) { 1255 if (page->isEmpty()) {
1255 HeapPage<Header>* unused = page; 1256 HeapPage<Header>* unused = page;
1256 if (unused == m_mergePoint) 1257 if (unused == m_mergePoint)
1257 m_mergePoint = previous; 1258 m_mergePoint = previous;
1258 page = page->next(); 1259 page = page->next();
1259 HeapPage<Header>::unlink(this, unused, previousNext); 1260 HeapPage<Header>::unlink(this, unused, previousNext);
1260 --m_numberOfNormalPages; 1261 --m_numberOfNormalPages;
1261 } else { 1262 } else {
1262 page->sweep(stats, this); 1263 page->sweep(stats, this);
1263 previousNext = &page->m_next; 1264 previousNext = &page->m_next;
1264 previous = page; 1265 previous = page;
1265 page = page->next(); 1266 page = page->next();
1266 } 1267 }
1267 } 1268 }
1268 } 1269 }
1269 1270
1270 template<typename Header> 1271 template<typename Header>
1271 void ThreadHeap<Header>::sweepLargePages(HeapStats* stats) 1272 void ThreadHeap<Header>::sweepLargePages(HeapStats* stats)
1272 { 1273 {
1274 TRACE_EVENT0("blink_gc", "ThreadHeap::sweepLargePages");
1273 LargeHeapObject<Header>** previousNext = &m_firstLargeHeapObject; 1275 LargeHeapObject<Header>** previousNext = &m_firstLargeHeapObject;
1274 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current;) { 1276 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current;) {
1275 if (current->isMarked()) { 1277 if (current->isMarked()) {
1276 stats->increaseAllocatedSpace(current->size()); 1278 stats->increaseAllocatedSpace(current->size());
1277 stats->increaseObjectSpace(current->payloadSize()); 1279 stats->increaseObjectSpace(current->payloadSize());
1278 current->unmark(); 1280 current->unmark();
1279 previousNext = &current->m_next; 1281 previousNext = &current->m_next;
1280 current = current->next(); 1282 current = current->next();
1281 } else { 1283 } else {
1282 LargeHeapObject<Header>* next = current->next(); 1284 LargeHeapObject<Header>* next = current->next();
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2454 #endif 2456 #endif
2455 2457
2456 void Heap::prepareForGC() 2458 void Heap::prepareForGC()
2457 { 2459 {
2458 ASSERT(ThreadState::isAnyThreadInGC()); 2460 ASSERT(ThreadState::isAnyThreadInGC());
2459 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads( ); 2461 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads( );
2460 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) 2462 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it)
2461 (*it)->prepareForGC(); 2463 (*it)->prepareForGC();
2462 } 2464 }
2463 2465
2464 void Heap::collectGarbage(ThreadState::StackState stackState) 2466 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::Cause OfGC cause)
2465 { 2467 {
2466 ThreadState* state = ThreadState::current(); 2468 ThreadState* state = ThreadState::current();
2467 state->clearGCRequested(); 2469 state->clearGCRequested();
2468 2470
2469 GCScope gcScope(stackState); 2471 GCScope gcScope(stackState);
2470 // Check if we successfully parked the other threads. If not we bail out of the GC. 2472 // Check if we successfully parked the other threads. If not we bail out of the GC.
2471 if (!gcScope.allThreadsParked()) { 2473 if (!gcScope.allThreadsParked()) {
2472 ThreadState::current()->setGCRequested(); 2474 ThreadState::current()->setGCRequested();
2473 return; 2475 return;
2474 } 2476 }
2475 2477
2476 if (state->isMainThread()) 2478 if (state->isMainThread())
2477 ScriptForbiddenScope::enter(); 2479 ScriptForbiddenScope::enter();
2478 2480
2479 s_lastGCWasConservative = false; 2481 s_lastGCWasConservative = false;
2480 2482
2481 TRACE_EVENT0("blink_gc", "Heap::collectGarbage"); 2483 TRACE_EVENT2("blink_gc", "Heap::collectGarbage",
2484 "precise", stackState == ThreadState::NoHeapPointersOnStack,
2485 "forced", cause == ThreadState::ForcedGC);
2482 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); 2486 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC");
2483 double timeStamp = WTF::currentTimeMS(); 2487 double timeStamp = WTF::currentTimeMS();
2484 #if ENABLE(GC_PROFILE_MARKING) 2488 #if ENABLE(GC_PROFILE_MARKING)
2485 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear(); 2489 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear();
2486 #endif 2490 #endif
2487 2491
2488 // Disallow allocation during garbage collection (but not 2492 // Disallow allocation during garbage collection (but not
2489 // during the finalization that happens when the gcScope is 2493 // during the finalization that happens when the gcScope is
2490 // torn down). 2494 // torn down).
2491 NoAllocationScope<AnyThread> noAllocationScope; 2495 NoAllocationScope<AnyThread> noAllocationScope;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 postMarkingProcessing(); 2572 postMarkingProcessing();
2569 globalWeakProcessing(); 2573 globalWeakProcessing();
2570 2574
2571 state->leaveGC(); 2575 state->leaveGC();
2572 } 2576 }
2573 state->performPendingSweep(); 2577 state->performPendingSweep();
2574 } 2578 }
2575 2579
2576 void Heap::processMarkingStackEntries(int* runningMarkingThreads) 2580 void Heap::processMarkingStackEntries(int* runningMarkingThreads)
2577 { 2581 {
2582 TRACE_EVENT0("blink_gc", "Heap::processMarkingStackEntries");
2578 CallbackStack* stack = 0; 2583 CallbackStack* stack = 0;
2579 MarkingVisitor visitor(&stack); 2584 MarkingVisitor visitor(&stack);
2580 { 2585 {
2581 MutexLocker locker(markingMutex()); 2586 MutexLocker locker(markingMutex());
2582 stack = s_markingStack->takeCallbacks(&s_markingStack); 2587 stack = s_markingStack->takeCallbacks(&s_markingStack);
2583 } 2588 }
2584 while (stack) { 2589 while (stack) {
2585 while (stack->popAndInvokeCallback<GlobalMarking>(&stack, &visitor)) { } 2590 while (stack->popAndInvokeCallback<GlobalMarking>(&stack, &visitor)) { }
2586 delete stack; 2591 delete stack;
2587 { 2592 {
(...skipping 27 matching lines...) Expand all
2615 { 2620 {
2616 static const int numberOfBlocksForParallelMarking = 2; 2621 static const int numberOfBlocksForParallelMarking = 2;
2617 // Ephemeron fixed point loop run on the garbage collecting thread. 2622 // Ephemeron fixed point loop run on the garbage collecting thread.
2618 do { 2623 do {
2619 // Iteratively mark all objects that are reachable from the objects 2624 // Iteratively mark all objects that are reachable from the objects
2620 // currently pushed onto the marking stack. Do so in parallel if there 2625 // currently pushed onto the marking stack. Do so in parallel if there
2621 // are multiple blocks on the global marking stack. 2626 // are multiple blocks on the global marking stack.
2622 if (s_markingStack->numberOfBlocksExceeds(numberOfBlocksForParallelMarki ng)) { 2627 if (s_markingStack->numberOfBlocksExceeds(numberOfBlocksForParallelMarki ng)) {
2623 processMarkingStackOnMultipleThreads(); 2628 processMarkingStackOnMultipleThreads();
2624 } else { 2629 } else {
2630 TRACE_EVENT0("blink_gc", "Heap::processMarkingStackSingleThreaded");
2625 while (popAndInvokeTraceCallback<GlobalMarking>(s_markingVisitor)) { } 2631 while (popAndInvokeTraceCallback<GlobalMarking>(s_markingVisitor)) { }
2626 } 2632 }
2627 2633
2628 // Mark any strong pointers that have now become reachable in ephemeron 2634 // Mark any strong pointers that have now become reachable in ephemeron
2629 // maps. 2635 // maps.
2636 TRACE_EVENT0("blink_gc", "Heap::processEphemeronStack");
2630 CallbackStack::invokeCallbacks(&s_ephemeronStack, s_markingVisitor); 2637 CallbackStack::invokeCallbacks(&s_ephemeronStack, s_markingVisitor);
2631 2638
2632 // Rerun loop if ephemeron processing queued more objects for tracing. 2639 // Rerun loop if ephemeron processing queued more objects for tracing.
2633 } while (!s_markingStack->isEmpty()); 2640 } while (!s_markingStack->isEmpty());
2634 } 2641 }
2635 2642
2636 template<CallbackInvocationMode Mode> 2643 template<CallbackInvocationMode Mode>
2637 void Heap::processMarkingStack() 2644 void Heap::processMarkingStack()
2638 { 2645 {
2639 // Ephemeron fixed point loop. 2646 // Ephemeron fixed point loop.
2640 do { 2647 do {
2641 // Iteratively mark all objects that are reachable from the objects 2648 // Iteratively mark all objects that are reachable from the objects
2642 // currently pushed onto the marking stack. If Mode is ThreadLocalMarkin g 2649 // currently pushed onto the marking stack. If Mode is ThreadLocalMarkin g
2643 // don't continue tracing if the trace hits an object on another thread' s 2650 // don't continue tracing if the trace hits an object on another thread' s
2644 // heap. 2651 // heap.
2652 TRACE_EVENT0("blink_gc", "Heap::processMarkingStackSingleThreaded");
2645 while (popAndInvokeTraceCallback<Mode>(s_markingVisitor)) { } 2653 while (popAndInvokeTraceCallback<Mode>(s_markingVisitor)) { }
2646 2654
2647 // Mark any strong pointers that have now become reachable in ephemeron 2655 // Mark any strong pointers that have now become reachable in ephemeron
2648 // maps. 2656 // maps.
2657 TRACE_EVENT0("blink_gc", "Heap::processEphemeronStack");
2649 CallbackStack::invokeCallbacks(&s_ephemeronStack, s_markingVisitor); 2658 CallbackStack::invokeCallbacks(&s_ephemeronStack, s_markingVisitor);
2650 2659
2651 // Rerun loop if ephemeron processing queued more objects for tracing. 2660 // Rerun loop if ephemeron processing queued more objects for tracing.
2652 } while (!s_markingStack->isEmpty()); 2661 } while (!s_markingStack->isEmpty());
2653 } 2662 }
2654 2663
2655 void Heap::postMarkingProcessing() 2664 void Heap::postMarkingProcessing()
2656 { 2665 {
2666 TRACE_EVENT0("blink_gc", "Heap::postMarkingProcessing");
2657 // Call post-marking callbacks including: 2667 // Call post-marking callbacks including:
2658 // 1. the ephemeronIterationDone callbacks on weak tables to do cleanup 2668 // 1. the ephemeronIterationDone callbacks on weak tables to do cleanup
2659 // (specifically to clear the queued bits for weak hash tables), and 2669 // (specifically to clear the queued bits for weak hash tables), and
2660 // 2. the markNoTracing callbacks on collection backings to mark them 2670 // 2. the markNoTracing callbacks on collection backings to mark them
2661 // if they are only reachable from their front objects. 2671 // if they are only reachable from their front objects.
2662 while (popAndInvokePostMarkingCallback(s_markingVisitor)) { } 2672 while (popAndInvokePostMarkingCallback(s_markingVisitor)) { }
2663 2673
2664 CallbackStack::clear(&s_ephemeronStack); 2674 CallbackStack::clear(&s_ephemeronStack);
2665 2675
2666 // Post-marking callbacks should not trace any objects and 2676 // Post-marking callbacks should not trace any objects and
2667 // therefore the marking stack should be empty after the 2677 // therefore the marking stack should be empty after the
2668 // post-marking callbacks. 2678 // post-marking callbacks.
2669 ASSERT(s_markingStack->isEmpty()); 2679 ASSERT(s_markingStack->isEmpty());
2670 } 2680 }
2671 2681
2672 void Heap::globalWeakProcessing() 2682 void Heap::globalWeakProcessing()
2673 { 2683 {
2684 TRACE_EVENT0("blink_gc", "Heap::globalWeakProcessing");
2674 // Call weak callbacks on objects that may now be pointing to dead 2685 // Call weak callbacks on objects that may now be pointing to dead
2675 // objects. 2686 // objects.
2676 while (popAndInvokeWeakPointerCallback(s_markingVisitor)) { } 2687 while (popAndInvokeWeakPointerCallback(s_markingVisitor)) { }
2677 2688
2678 // It is not permitted to trace pointers of live objects in the weak 2689 // It is not permitted to trace pointers of live objects in the weak
2679 // callback phase, so the marking stack should still be empty here. 2690 // callback phase, so the marking stack should still be empty here.
2680 ASSERT(s_markingStack->isEmpty()); 2691 ASSERT(s_markingStack->isEmpty());
2681 } 2692 }
2682 2693
2683 void Heap::collectAllGarbage() 2694 void Heap::collectAllGarbage()
2684 { 2695 {
2685 // FIXME: oilpan: we should perform a single GC and everything 2696 // FIXME: oilpan: we should perform a single GC and everything
2686 // should die. Unfortunately it is not the case for all objects 2697 // should die. Unfortunately it is not the case for all objects
2687 // because the hierarchy was not completely moved to the heap and 2698 // because the hierarchy was not completely moved to the heap and
2688 // some heap allocated objects own objects that contain persistents 2699 // some heap allocated objects own objects that contain persistents
2689 // pointing to other heap allocated objects. 2700 // pointing to other heap allocated objects.
2690 for (int i = 0; i < 5; i++) 2701 for (int i = 0; i < 5; i++)
2691 collectGarbage(ThreadState::NoHeapPointersOnStack); 2702 collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::ForcedGC );
2692 } 2703 }
2693 2704
2694 void Heap::setForcePreciseGCForTesting() 2705 void Heap::setForcePreciseGCForTesting()
2695 { 2706 {
2696 ThreadState::current()->setForcePreciseGCForTesting(true); 2707 ThreadState::current()->setForcePreciseGCForTesting(true);
2697 } 2708 }
2698 2709
2699 template<typename Header> 2710 template<typename Header>
2700 void ThreadHeap<Header>::prepareHeapForTermination() 2711 void ThreadHeap<Header>::prepareHeapForTermination()
2701 { 2712 {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
2845 CallbackStack* Heap::s_markingStack; 2856 CallbackStack* Heap::s_markingStack;
2846 CallbackStack* Heap::s_postMarkingCallbackStack; 2857 CallbackStack* Heap::s_postMarkingCallbackStack;
2847 CallbackStack* Heap::s_weakCallbackStack; 2858 CallbackStack* Heap::s_weakCallbackStack;
2848 CallbackStack* Heap::s_ephemeronStack; 2859 CallbackStack* Heap::s_ephemeronStack;
2849 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache; 2860 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache;
2850 bool Heap::s_shutdownCalled = false; 2861 bool Heap::s_shutdownCalled = false;
2851 bool Heap::s_lastGCWasConservative = false; 2862 bool Heap::s_lastGCWasConservative = false;
2852 FreePagePool* Heap::s_freePagePool; 2863 FreePagePool* Heap::s_freePagePool;
2853 OrphanedPagePool* Heap::s_orphanedPagePool; 2864 OrphanedPagePool* Heap::s_orphanedPagePool;
2854 } 2865 }
OLDNEW
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | Source/platform/heap/ThreadState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698