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

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

Issue 1085023002: patch from issue 1063083002 at patchset 20001 (http://crrev.com/1063083002#ps20001) (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 8 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
« no previous file with comments | « Source/platform/heap/Heap.cpp ('k') | no next file » | 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 24 matching lines...) Expand all
35 #include "platform/TraceEvent.h" 35 #include "platform/TraceEvent.h"
36 #include "platform/heap/AddressSanitizer.h" 36 #include "platform/heap/AddressSanitizer.h"
37 #include "platform/heap/CallbackStack.h" 37 #include "platform/heap/CallbackStack.h"
38 #include "platform/heap/Handle.h" 38 #include "platform/heap/Handle.h"
39 #include "platform/heap/Heap.h" 39 #include "platform/heap/Heap.h"
40 #include "platform/heap/SafePoint.h" 40 #include "platform/heap/SafePoint.h"
41 #include "platform/scheduler/Scheduler.h" 41 #include "platform/scheduler/Scheduler.h"
42 #include "public/platform/Platform.h" 42 #include "public/platform/Platform.h"
43 #include "public/platform/WebThread.h" 43 #include "public/platform/WebThread.h"
44 #include "public/platform/WebTraceLocation.h" 44 #include "public/platform/WebTraceLocation.h"
45 #include "wtf/Partitions.h"
45 #include "wtf/ThreadingPrimitives.h" 46 #include "wtf/ThreadingPrimitives.h"
46 #if ENABLE(GC_PROFILING) 47 #if ENABLE(GC_PROFILING)
47 #include "platform/TracedValue.h" 48 #include "platform/TracedValue.h"
48 #include "wtf/text/StringHash.h" 49 #include "wtf/text/StringHash.h"
49 #endif 50 #endif
50 51
51 #if OS(WIN) 52 #if OS(WIN)
52 #include <stddef.h> 53 #include <stddef.h>
53 #include <windows.h> 54 #include <windows.h>
54 #include <winnt.h> 55 #include <winnt.h>
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 AtomicallyInitializedStaticReference(PersistentNode, anchor, new PersistentA nchor); 494 AtomicallyInitializedStaticReference(PersistentNode, anchor, new PersistentA nchor);
494 return anchor; 495 return anchor;
495 } 496 }
496 497
497 Mutex& ThreadState::globalRootsMutex() 498 Mutex& ThreadState::globalRootsMutex()
498 { 499 {
499 AtomicallyInitializedStaticReference(Mutex, mutex, new Mutex); 500 AtomicallyInitializedStaticReference(Mutex, mutex, new Mutex);
500 return mutex; 501 return mutex;
501 } 502 }
502 503
503 // FIXME: We should improve the GC heuristics. 504 // TODO(haraken): We should improve the GC heuristics.
504 // These heuristics affect performance significantly. 505 // These heuristics affect performance significantly.
505 bool ThreadState::shouldScheduleIdleGC() 506 bool ThreadState::shouldScheduleIdleGC()
506 { 507 {
507 if (gcState() != NoGCScheduled) 508 if (gcState() != NoGCScheduled)
508 return false; 509 return false;
509 #if ENABLE(OILPAN) 510 #if ENABLE(OILPAN)
510 // The estimated size is updated when the main thread finishes lazy 511 // The estimated size is updated when the main thread finishes lazy
511 // sweeping. If this thread reaches here before the main thread finishes 512 // sweeping. If this thread reaches here before the main thread finishes
512 // lazy sweeping, the thread will use the estimated size of the last GC. 513 // lazy sweeping, the thread will use the estimated size of the last GC.
513 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize(); 514 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize();
514 // Schedule an idle GC if more than 512 KB has been allocated since 515 // Schedule an idle GC if more than 1Mb has been allocated since
515 // the last GC and the current memory usage (=allocated + estimated) 516 // the last GC and the current memory usage (=allocated + estimated)
516 // is >50% larger than the estimated live memory usage. 517 // is >50% larger than the estimated live memory usage.
517 size_t allocatedObjectSize = Heap::allocatedObjectSize(); 518 size_t currentObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectS ize();
518 return allocatedObjectSize >= 512 * 1024 && allocatedObjectSize > estimatedL iveObjectSize / 2; 519 return currentObjectSize >= 1024 * 1024 && currentObjectSize > estimatedLive ObjectSize / 2;
519 #else 520 #else
520 return false; 521 return false;
521 #endif 522 #endif
522 } 523 }
523 524
524 // FIXME: We should improve the GC heuristics. 525 // TODO(haraken): We should improve the GC heuristics.
525 // These heuristics affect performance significantly. 526 // These heuristics affect performance significantly.
526 bool ThreadState::shouldSchedulePreciseGC() 527 bool ThreadState::shouldSchedulePreciseGC()
527 { 528 {
528 if (gcState() != NoGCScheduled) 529 if (gcState() != NoGCScheduled)
529 return false; 530 return false;
530 #if ENABLE(OILPAN) 531 #if ENABLE(OILPAN)
531 return false; 532 return false;
532 #else 533 #else
533 // The estimated size is updated when the main thread finishes lazy 534 // The estimated size is updated when the main thread finishes lazy
534 // sweeping. If this thread reaches here before the main thread finishes 535 // sweeping. If this thread reaches here before the main thread finishes
535 // lazy sweeping, the thread will use the estimated size of the last GC. 536 // lazy sweeping, the thread will use the estimated size of the last GC.
536 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize(); 537 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize();
537 // Schedule a precise GC if more than 512 KB has been allocated since 538 // Schedule a precise GC if more than 1Mb has been allocated since
538 // the last GC and the current memory usage (=allocated + estimated) 539 // the last GC and the current memory usage (=allocated + estimated)
539 // is >50% larger than the estimated live memory usage. 540 // is >50% larger than the estimated live memory usage.
540 size_t allocatedObjectSize = Heap::allocatedObjectSize(); 541 size_t currentObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectS ize();
541 return allocatedObjectSize >= 512 * 1024 && allocatedObjectSize > estimatedL iveObjectSize / 2; 542 return currentObjectSize >= 1024 * 1024 && currentObjectSize > estimatedLive ObjectSize / 2;
542 #endif 543 #endif
543 } 544 }
544 545
545 // FIXME: We should improve the GC heuristics. 546 // TODO(haraken): We should improve the GC heuristics.
546 // These heuristics affect performance significantly. 547 // These heuristics affect performance significantly.
547 bool ThreadState::shouldForceConservativeGC() 548 bool ThreadState::shouldForceConservativeGC()
548 { 549 {
549 if (UNLIKELY(m_gcForbiddenCount)) 550 if (UNLIKELY(m_gcForbiddenCount))
550 return false; 551 return false;
551 552
552 if (Heap::isUrgentGCRequested())
553 return true;
554
555 // The estimated size is updated when the main thread finishes lazy 553 // The estimated size is updated when the main thread finishes lazy
556 // sweeping. If this thread reaches here before the main thread finishes 554 // sweeping. If this thread reaches here before the main thread finishes
557 // lazy sweeping, the thread will use the estimated size of the last GC. 555 // lazy sweeping, the thread will use the estimated size of the last GC.
558 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize(); 556 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize();
559 size_t allocatedObjectSize = Heap::allocatedObjectSize(); 557 size_t allocatedObjectSize = Heap::allocatedObjectSize();
560 if (Heap::markedObjectSize() + allocatedObjectSize >= 300 * 1024 * 1024) { 558 // Heap::markedObjectSize() may be underestimated if any thread has not
559 // finished completeSweep().
560 size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages();
561 if (currentObjectSize >= 300 * 1024 * 1024) {
561 // If we're consuming too much memory, trigger a conservative GC 562 // If we're consuming too much memory, trigger a conservative GC
562 // aggressively. This is a safe guard to avoid OOM. 563 // aggressively. This is a safe guard to avoid OOM.
563 return allocatedObjectSize > estimatedLiveObjectSize / 2; 564 return allocatedObjectSize > estimatedLiveObjectSize / 2;
564 } 565 }
565 // Schedule a conservative GC if more than 32 MB has been allocated since 566 // Schedule a conservative GC if more than 32 MB has been allocated since
566 // the last GC and the current memory usage (=allocated + estimated) 567 // the last GC and the current memory usage (=allocated + estimated)
567 // is >500% larger than the estimated live memory usage. 568 // is >500% larger than the estimated live memory usage.
568 return allocatedObjectSize >= 32 * 1024 * 1024 && allocatedObjectSize > 4 * estimatedLiveObjectSize; 569 return allocatedObjectSize >= 32 * 1024 * 1024 && allocatedObjectSize > 4 * estimatedLiveObjectSize;
569 } 570 }
570 571
571 void ThreadState::scheduleGCIfNeeded() 572 void ThreadState::scheduleGCIfNeeded()
572 { 573 {
573 checkThread(); 574 checkThread();
574 // Allocation is allowed during sweeping, but those allocations should not 575 // Allocation is allowed during sweeping, but those allocations should not
575 // trigger nested GCs. Does not apply if an urgent GC has been requested. 576 // trigger nested GCs.
576 if (isSweepingInProgress() && UNLIKELY(!Heap::isUrgentGCRequested())) 577 if (isSweepingInProgress())
577 return; 578 return;
578 ASSERT(!sweepForbidden()); 579 ASSERT(!sweepForbidden());
579 580
580 if (shouldForceConservativeGC()) { 581 if (shouldForceConservativeGC()) {
581 if (Heap::isUrgentGCRequested()) { 582 Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::Conserva tiveGC);
582 // If GC is deemed urgent, eagerly sweep and finalize any external a llocations right away.
583 Heap::collectGarbage(HeapPointersOnStack, GCWithSweep, Heap::Conserv ativeGC);
584 } else {
585 // Otherwise, schedule a lazy sweeping in an idle task.
586 Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::Cons ervativeGC);
587 }
588 return; 583 return;
589 } 584 }
590 if (shouldSchedulePreciseGC()) 585 if (shouldSchedulePreciseGC())
591 schedulePreciseGC(); 586 schedulePreciseGC();
592 else if (shouldScheduleIdleGC()) 587 else if (shouldScheduleIdleGC())
593 scheduleIdleGC(); 588 scheduleIdleGC();
594 } 589 }
595 590
596 void ThreadState::performIdleGC(double deadlineSeconds) 591 void ThreadState::performIdleGC(double deadlineSeconds)
597 { 592 {
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 834
840 if (isMainThread()) 835 if (isMainThread())
841 ScriptForbiddenScope::exit(); 836 ScriptForbiddenScope::exit();
842 } 837 }
843 838
844 postSweep(); 839 postSweep();
845 } 840 }
846 841
847 void ThreadState::postSweep() 842 void ThreadState::postSweep()
848 { 843 {
849 if (isMainThread()) 844 if (isMainThread()) {
845 // At the point where the main thread finishes lazy sweeping,
846 // we estimate the live object size. Heap::markedObjectSize()
847 // may be underestimated if any other thread has not finished
848 // lazy sweeping.
850 Heap::setEstimatedLiveObjectSize(Heap::markedObjectSize()); 849 Heap::setEstimatedLiveObjectSize(Heap::markedObjectSize());
850 }
851 851
852 switch (gcState()) { 852 switch (gcState()) {
853 case Sweeping: 853 case Sweeping:
854 setGCState(NoGCScheduled); 854 setGCState(NoGCScheduled);
855 break; 855 break;
856 case SweepingAndPreciseGCScheduled: 856 case SweepingAndPreciseGCScheduled:
857 setGCState(PreciseGCScheduled); 857 setGCState(PreciseGCScheduled);
858 break; 858 break;
859 case SweepingAndIdleGCScheduled: 859 case SweepingAndIdleGCScheduled:
860 setGCState(NoGCScheduled); 860 setGCState(NoGCScheduled);
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 json->beginArray(it->key.ascii().data()); 1292 json->beginArray(it->key.ascii().data());
1293 for (size_t age = 0; age <= maxHeapObjectAge; ++age) 1293 for (size_t age = 0; age <= maxHeapObjectAge; ++age)
1294 json->pushInteger(it->value.ages[age]); 1294 json->pushInteger(it->value.ages[age]);
1295 json->endArray(); 1295 json->endArray();
1296 } 1296 }
1297 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s tatsName, this, json.release()); 1297 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s tatsName, this, json.release());
1298 } 1298 }
1299 #endif 1299 #endif
1300 1300
1301 } // namespace blink 1301 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/heap/Heap.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698