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

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

Issue 1402103004: Oilpan: Factor out GC-related enum definitions to BlinkGC.h (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 { 74 {
75 m_state->leaveGCForbiddenScope(); 75 m_state->leaveGCForbiddenScope();
76 } 76 }
77 77
78 private: 78 private:
79 ThreadState* m_state; 79 ThreadState* m_state;
80 }; 80 };
81 81
82 class GCScope final { 82 class GCScope final {
83 public: 83 public:
84 GCScope(ThreadState* state, ThreadState::StackState stackState, ThreadState: :GCType gcType) 84 GCScope(ThreadState* state, BlinkGC::StackState stackState, BlinkGC::GCType gcType)
85 : m_state(state) 85 : m_state(state)
86 , m_gcForbiddenScope(state) 86 , m_gcForbiddenScope(state)
87 // See collectGarbageForTerminatingThread() comment on why a 87 // See collectGarbageForTerminatingThread() comment on why a
88 // safepoint scope isn't entered for its GCScope. 88 // safepoint scope isn't entered for its GCScope.
89 , m_safePointScope(stackState, gcType != ThreadState::ThreadTerminationG C ? state : nullptr) 89 , m_safePointScope(stackState, gcType != BlinkGC::ThreadTerminationGC ? state : nullptr)
90 , m_gcType(gcType) 90 , m_gcType(gcType)
91 , m_parkedAllThreads(false) 91 , m_parkedAllThreads(false)
92 { 92 {
93 TRACE_EVENT0("blink_gc", "Heap::GCScope"); 93 TRACE_EVENT0("blink_gc", "Heap::GCScope");
94 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); 94 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE();
95 if (m_state->isMainThread()) 95 if (m_state->isMainThread())
96 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting"); 96 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting");
97 97
98 ASSERT(m_state->checkThread()); 98 ASSERT(m_state->checkThread());
99 99
100 // TODO(haraken): In an unlikely coincidence that two threads decide 100 // TODO(haraken): In an unlikely coincidence that two threads decide
101 // to collect garbage at the same time, avoid doing two GCs in 101 // to collect garbage at the same time, avoid doing two GCs in
102 // a row. 102 // a row.
103 if (LIKELY(gcType != ThreadState::ThreadTerminationGC && ThreadState::st opThreads())) 103 if (LIKELY(gcType != BlinkGC::ThreadTerminationGC && ThreadState::stopTh reads()))
104 m_parkedAllThreads = true; 104 m_parkedAllThreads = true;
105 105
106 switch (gcType) { 106 switch (gcType) {
107 case ThreadState::GCWithSweep: 107 case BlinkGC::GCWithSweep:
108 case ThreadState::GCWithoutSweep: 108 case BlinkGC::GCWithoutSweep:
109 m_visitor = adoptPtr(new MarkingVisitor<Visitor::GlobalMarking>()); 109 m_visitor = adoptPtr(new MarkingVisitor<Visitor::GlobalMarking>());
110 break; 110 break;
111 case ThreadState::TakeSnapshot: 111 case BlinkGC::TakeSnapshot:
112 m_visitor = adoptPtr(new MarkingVisitor<Visitor::SnapshotMarking>()) ; 112 m_visitor = adoptPtr(new MarkingVisitor<Visitor::SnapshotMarking>()) ;
113 break; 113 break;
114 case ThreadState::ThreadTerminationGC: 114 case BlinkGC::ThreadTerminationGC:
115 m_visitor = adoptPtr(new MarkingVisitor<Visitor::ThreadLocalMarking> ()); 115 m_visitor = adoptPtr(new MarkingVisitor<Visitor::ThreadLocalMarking> ());
116 break; 116 break;
117 default: 117 default:
118 ASSERT_NOT_REACHED(); 118 ASSERT_NOT_REACHED();
119 } 119 }
120 120
121 if (m_state->isMainThread()) 121 if (m_state->isMainThread())
122 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); 122 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState);
123 } 123 }
124 124
125 bool allThreadsParked() const { return m_parkedAllThreads; } 125 bool allThreadsParked() const { return m_parkedAllThreads; }
126 Visitor* visitor() const { return m_visitor.get(); } 126 Visitor* visitor() const { return m_visitor.get(); }
127 127
128 ~GCScope() 128 ~GCScope()
129 { 129 {
130 // Only cleanup if we parked all threads in which case the GC happened 130 // Only cleanup if we parked all threads in which case the GC happened
131 // and we need to resume the other threads. 131 // and we need to resume the other threads.
132 if (LIKELY(m_gcType != ThreadState::ThreadTerminationGC && m_parkedAllTh reads)) 132 if (LIKELY(m_gcType != BlinkGC::ThreadTerminationGC && m_parkedAllThread s))
133 ThreadState::resumeThreads(); 133 ThreadState::resumeThreads();
134 } 134 }
135 135
136 private: 136 private:
137 ThreadState* m_state; 137 ThreadState* m_state;
138 // The ordering of the two scope objects matters: GCs must first be forbidde n 138 // The ordering of the two scope objects matters: GCs must first be forbidde n
139 // before entering the safe point scope. Prior to reaching the safe point, 139 // before entering the safe point scope. Prior to reaching the safe point,
140 // ThreadState::runScheduledGC() is called. See its comment why we need 140 // ThreadState::runScheduledGC() is called. See its comment why we need
141 // to be in a GC forbidden scope when doing so. 141 // to be in a GC forbidden scope when doing so.
142 GCForbiddenScope m_gcForbiddenScope; 142 GCForbiddenScope m_gcForbiddenScope;
143 SafePointScope m_safePointScope; 143 SafePointScope m_safePointScope;
144 ThreadState::GCType m_gcType; 144 BlinkGC::GCType m_gcType;
145 OwnPtr<Visitor> m_visitor; 145 OwnPtr<Visitor> m_visitor;
146 bool m_parkedAllThreads; // False if we fail to park all threads 146 bool m_parkedAllThreads; // False if we fail to park all threads
147 }; 147 };
148 148
149 void Heap::flushHeapDoesNotContainCache() 149 void Heap::flushHeapDoesNotContainCache()
150 { 150 {
151 s_heapDoesNotContainCache->flush(); 151 s_heapDoesNotContainCache->flush();
152 } 152 }
153 153
154 void Heap::init() 154 void Heap::init()
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 } 385 }
386 #endif 386 #endif
387 387
388 void Heap::preGC() 388 void Heap::preGC()
389 { 389 {
390 ASSERT(!ThreadState::current()->isInGC()); 390 ASSERT(!ThreadState::current()->isInGC());
391 for (ThreadState* state : ThreadState::attachedThreads()) 391 for (ThreadState* state : ThreadState::attachedThreads())
392 state->preGC(); 392 state->preGC();
393 } 393 }
394 394
395 void Heap::postGC(ThreadState::GCType gcType) 395 void Heap::postGC(BlinkGC::GCType gcType)
396 { 396 {
397 ASSERT(ThreadState::current()->isInGC()); 397 ASSERT(ThreadState::current()->isInGC());
398 for (ThreadState* state : ThreadState::attachedThreads()) 398 for (ThreadState* state : ThreadState::attachedThreads())
399 state->postGC(gcType); 399 state->postGC(gcType);
400 } 400 }
401 401
402 const char* Heap::gcReasonString(GCReason reason) 402 const char* Heap::gcReasonString(GCReason reason)
403 { 403 {
404 switch (reason) { 404 switch (reason) {
405 #define STRINGIFY_REASON(reason) case reason: return #reason; 405 #define STRINGIFY_REASON(reason) case reason: return #reason;
406 STRINGIFY_REASON(IdleGC); 406 STRINGIFY_REASON(IdleGC);
407 STRINGIFY_REASON(PreciseGC); 407 STRINGIFY_REASON(PreciseGC);
408 STRINGIFY_REASON(ConservativeGC); 408 STRINGIFY_REASON(ConservativeGC);
409 STRINGIFY_REASON(ForcedGC); 409 STRINGIFY_REASON(ForcedGC);
410 STRINGIFY_REASON(MemoryPressureGC); 410 STRINGIFY_REASON(MemoryPressureGC);
411 STRINGIFY_REASON(PageNavigationGC); 411 STRINGIFY_REASON(PageNavigationGC);
412 #undef STRINGIFY_REASON 412 #undef STRINGIFY_REASON
413 case NumberOfGCReason: ASSERT_NOT_REACHED(); 413 case NumberOfGCReason: ASSERT_NOT_REACHED();
414 } 414 }
415 return "<Unknown>"; 415 return "<Unknown>";
416 } 416 }
417 417
418 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::GCTyp e gcType, GCReason reason) 418 void Heap::collectGarbage(BlinkGC::StackState stackState, BlinkGC::GCType gcType , GCReason reason)
419 { 419 {
420 ThreadState* state = ThreadState::current(); 420 ThreadState* state = ThreadState::current();
421 // Nested collectGarbage() invocations aren't supported. 421 // Nested collectGarbage() invocations aren't supported.
422 RELEASE_ASSERT(!state->isGCForbidden()); 422 RELEASE_ASSERT(!state->isGCForbidden());
423 state->completeSweep(); 423 state->completeSweep();
424 424
425 GCScope gcScope(state, stackState, gcType); 425 GCScope gcScope(state, stackState, gcType);
426 // Check if we successfully parked the other threads. If not we bail out of 426 // Check if we successfully parked the other threads. If not we bail out of
427 // the GC. 427 // the GC.
428 if (!gcScope.allThreadsParked()) 428 if (!gcScope.allThreadsParked())
429 return; 429 return;
430 430
431 if (state->isMainThread()) 431 if (state->isMainThread())
432 ScriptForbiddenScope::enter(); 432 ScriptForbiddenScope::enter();
433 433
434 TRACE_EVENT2("blink_gc", "Heap::collectGarbage", 434 TRACE_EVENT2("blink_gc", "Heap::collectGarbage",
435 "lazySweeping", gcType == ThreadState::GCWithoutSweep, 435 "lazySweeping", gcType == BlinkGC::GCWithoutSweep,
436 "gcReason", gcReasonString(reason)); 436 "gcReason", gcReasonString(reason));
437 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); 437 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC");
438 double timeStamp = WTF::currentTimeMS(); 438 double timeStamp = WTF::currentTimeMS();
439 439
440 if (gcType == ThreadState::TakeSnapshot) 440 if (gcType == BlinkGC::TakeSnapshot)
441 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); 441 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC();
442 442
443 // Disallow allocation during garbage collection (but not during the 443 // Disallow allocation during garbage collection (but not during the
444 // finalization that happens when the gcScope is torn down). 444 // finalization that happens when the gcScope is torn down).
445 ThreadState::NoAllocationScope noAllocationScope(state); 445 ThreadState::NoAllocationScope noAllocationScope(state);
446 446
447 preGC(); 447 preGC();
448 448
449 StackFrameDepthScope stackDepthScope; 449 StackFrameDepthScope stackDepthScope;
450 450
451 size_t totalObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectSiz e(); 451 size_t totalObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectSiz e();
452 if (gcType != ThreadState::TakeSnapshot) 452 if (gcType != BlinkGC::TakeSnapshot)
453 Heap::resetHeapCounters(); 453 Heap::resetHeapCounters();
454 454
455 // 1. Trace persistent roots. 455 // 1. Trace persistent roots.
456 ThreadState::visitPersistentRoots(gcScope.visitor()); 456 ThreadState::visitPersistentRoots(gcScope.visitor());
457 457
458 // 2. Trace objects reachable from the stack. We do this independent of the 458 // 2. Trace objects reachable from the stack. We do this independent of the
459 // given stackState since other threads might have a different stack state. 459 // given stackState since other threads might have a different stack state.
460 ThreadState::visitStackRoots(gcScope.visitor()); 460 ThreadState::visitStackRoots(gcScope.visitor());
461 461
462 // 3. Transitive closure to trace objects including ephemerons. 462 // 3. Transitive closure to trace objects including ephemerons.
463 processMarkingStack(gcScope.visitor()); 463 processMarkingStack(gcScope.visitor());
464 464
465 postMarkingProcessing(gcScope.visitor()); 465 postMarkingProcessing(gcScope.visitor());
466 globalWeakProcessing(gcScope.visitor()); 466 globalWeakProcessing(gcScope.visitor());
467 467
468 // Now we can delete all orphaned pages because there are no dangling 468 // Now we can delete all orphaned pages because there are no dangling
469 // pointers to the orphaned pages. (If we have such dangling pointers, 469 // pointers to the orphaned pages. (If we have such dangling pointers,
470 // we should have crashed during marking before getting here.) 470 // we should have crashed during marking before getting here.)
471 orphanedPagePool()->decommitOrphanedPages(); 471 orphanedPagePool()->decommitOrphanedPages();
472 472
473 double markingTimeInMilliseconds = WTF::currentTimeMS() - timeStamp; 473 double markingTimeInMilliseconds = WTF::currentTimeMS() - timeStamp;
474 s_estimatedMarkingTimePerByte = totalObjectSize ? (markingTimeInMilliseconds / 1000 / totalObjectSize) : 0; 474 s_estimatedMarkingTimePerByte = totalObjectSize ? (markingTimeInMilliseconds / 1000 / totalObjectSize) : 0;
475 475
476 #if PRINT_HEAP_STATS 476 #if PRINT_HEAP_STATS
477 dataLogF("Heap::collectGarbage (gcReason=%s, lazySweeping=%d, time=%.1lfms)\ n", gcReasonString(reason), gcType == ThreadState::GCWithoutSweep, markingTimeIn Milliseconds); 477 dataLogF("Heap::collectGarbage (gcReason=%s, lazySweeping=%d, time=%.1lfms)\ n", gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, markingTimeInMill iseconds);
478 #endif 478 #endif
479 479
480 Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbage", marking TimeInMilliseconds, 0, 10 * 1000, 50); 480 Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbage", marking TimeInMilliseconds, 0, 10 * 1000, 50);
481 Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSpace", Heap: :allocatedObjectSize() / 1024, 0, 4 * 1024 * 1024, 50); 481 Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSpace", Heap: :allocatedObjectSize() / 1024, 0, 4 * 1024 * 1024, 50);
482 Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocatedSpace", He ap::allocatedSpace() / 1024, 0, 4 * 1024 * 1024, 50); 482 Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocatedSpace", He ap::allocatedSpace() / 1024, 0, 4 * 1024 * 1024, 50);
483 Platform::current()->histogramEnumeration("BlinkGC.GCReason", reason, Number OfGCReason); 483 Platform::current()->histogramEnumeration("BlinkGC.GCReason", reason, Number OfGCReason);
484 Heap::reportMemoryUsageHistogram(); 484 Heap::reportMemoryUsageHistogram();
485 WTF::Partitions::reportMemoryUsageHistogram(); 485 WTF::Partitions::reportMemoryUsageHistogram();
486 486
487 postGC(gcType); 487 postGC(gcType);
488 488
489 if (state->isMainThread()) 489 if (state->isMainThread())
490 ScriptForbiddenScope::exit(); 490 ScriptForbiddenScope::exit();
491 } 491 }
492 492
493 void Heap::collectGarbageForTerminatingThread(ThreadState* state) 493 void Heap::collectGarbageForTerminatingThread(ThreadState* state)
494 { 494 {
495 { 495 {
496 // A thread-specific termination GC must not allow other global GCs to g o 496 // A thread-specific termination GC must not allow other global GCs to g o
497 // ahead while it is running, hence the termination GC does not enter a 497 // ahead while it is running, hence the termination GC does not enter a
498 // safepoint. GCScope will not enter also a safepoint scope for 498 // safepoint. GCScope will not enter also a safepoint scope for
499 // ThreadTerminationGC. 499 // ThreadTerminationGC.
500 GCScope gcScope(state, ThreadState::NoHeapPointersOnStack, ThreadState:: ThreadTerminationGC); 500 GCScope gcScope(state, BlinkGC::NoHeapPointersOnStack, BlinkGC::ThreadTe rminationGC);
501 501
502 ThreadState::NoAllocationScope noAllocationScope(state); 502 ThreadState::NoAllocationScope noAllocationScope(state);
503 503
504 state->preGC(); 504 state->preGC();
505 StackFrameDepthScope stackDepthScope; 505 StackFrameDepthScope stackDepthScope;
506 506
507 // 1. Trace the thread local persistent roots. For thread local GCs we 507 // 1. Trace the thread local persistent roots. For thread local GCs we
508 // don't trace the stack (ie. no conservative scanning) since this is 508 // don't trace the stack (ie. no conservative scanning) since this is
509 // only called during thread shutdown where there should be no objects 509 // only called during thread shutdown where there should be no objects
510 // on the stack. 510 // on the stack.
511 // We also assume that orphaned pages have no objects reachable from 511 // We also assume that orphaned pages have no objects reachable from
512 // persistent handles on other threads or CrossThreadPersistents. The 512 // persistent handles on other threads or CrossThreadPersistents. The
513 // only cases where this could happen is if a subsequent conservative 513 // only cases where this could happen is if a subsequent conservative
514 // global GC finds a "pointer" on the stack or due to a programming 514 // global GC finds a "pointer" on the stack or due to a programming
515 // error where an object has a dangling cross-thread pointer to an 515 // error where an object has a dangling cross-thread pointer to an
516 // object on this heap. 516 // object on this heap.
517 state->visitPersistents(gcScope.visitor()); 517 state->visitPersistents(gcScope.visitor());
518 518
519 // 2. Trace objects reachable from the thread's persistent roots 519 // 2. Trace objects reachable from the thread's persistent roots
520 // including ephemerons. 520 // including ephemerons.
521 processMarkingStack(gcScope.visitor()); 521 processMarkingStack(gcScope.visitor());
522 522
523 postMarkingProcessing(gcScope.visitor()); 523 postMarkingProcessing(gcScope.visitor());
524 globalWeakProcessing(gcScope.visitor()); 524 globalWeakProcessing(gcScope.visitor());
525 525
526 state->postGC(ThreadState::GCWithSweep); 526 state->postGC(BlinkGC::GCWithSweep);
527 } 527 }
528 state->preSweep(); 528 state->preSweep();
529 } 529 }
530 530
531 void Heap::processMarkingStack(Visitor* visitor) 531 void Heap::processMarkingStack(Visitor* visitor)
532 { 532 {
533 // Ephemeron fixed point loop. 533 // Ephemeron fixed point loop.
534 do { 534 do {
535 { 535 {
536 // Iteratively mark all objects that are reachable from the objects 536 // Iteratively mark all objects that are reachable from the objects
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 // It is not permitted to trace pointers of live objects in the weak 577 // It is not permitted to trace pointers of live objects in the weak
578 // callback phase, so the marking stack should still be empty here. 578 // callback phase, so the marking stack should still be empty here.
579 ASSERT(s_markingStack->isEmpty()); 579 ASSERT(s_markingStack->isEmpty());
580 } 580 }
581 581
582 void Heap::collectAllGarbage() 582 void Heap::collectAllGarbage()
583 { 583 {
584 // We need to run multiple GCs to collect a chain of persistent handles. 584 // We need to run multiple GCs to collect a chain of persistent handles.
585 size_t previousLiveObjects = 0; 585 size_t previousLiveObjects = 0;
586 for (int i = 0; i < 5; ++i) { 586 for (int i = 0; i < 5; ++i) {
587 collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWithSw eep, ForcedGC); 587 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, For cedGC);
588 size_t liveObjects = Heap::markedObjectSize(); 588 size_t liveObjects = Heap::markedObjectSize();
589 if (liveObjects == previousLiveObjects) 589 if (liveObjects == previousLiveObjects)
590 break; 590 break;
591 previousLiveObjects = liveObjects; 591 previousLiveObjects = liveObjects;
592 } 592 }
593 } 593 }
594 594
595 double Heap::estimatedMarkingTime() 595 double Heap::estimatedMarkingTime()
596 { 596 {
597 ASSERT(ThreadState::current()->isMainThread()); 597 ASSERT(ThreadState::current()->isMainThread());
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 size_t Heap::s_objectSizeAtLastGC = 0; 786 size_t Heap::s_objectSizeAtLastGC = 0;
787 size_t Heap::s_markedObjectSize = 0; 787 size_t Heap::s_markedObjectSize = 0;
788 size_t Heap::s_markedObjectSizeAtLastCompleteSweep = 0; 788 size_t Heap::s_markedObjectSizeAtLastCompleteSweep = 0;
789 size_t Heap::s_wrapperCount = 0; 789 size_t Heap::s_wrapperCount = 0;
790 size_t Heap::s_wrapperCountAtLastGC = 0; 790 size_t Heap::s_wrapperCountAtLastGC = 0;
791 size_t Heap::s_collectedWrapperCount = 0; 791 size_t Heap::s_collectedWrapperCount = 0;
792 size_t Heap::s_partitionAllocSizeAtLastGC = 0; 792 size_t Heap::s_partitionAllocSizeAtLastGC = 0;
793 double Heap::s_estimatedMarkingTimePerByte = 0.0; 793 double Heap::s_estimatedMarkingTimePerByte = 0.0;
794 794
795 } // namespace blink 795 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/heap/Heap.h ('k') | third_party/WebKit/Source/platform/heap/HeapAllocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698