OLD | NEW |
---|---|
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 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
666 #endif | 666 #endif |
667 } | 667 } |
668 | 668 |
669 // FIXME: We should improve the GC heuristics. | 669 // FIXME: We should improve the GC heuristics. |
670 // These heuristics affect performance significantly. | 670 // These heuristics affect performance significantly. |
671 bool ThreadState::shouldForceConservativeGC() | 671 bool ThreadState::shouldForceConservativeGC() |
672 { | 672 { |
673 if (UNLIKELY(m_gcForbiddenCount)) | 673 if (UNLIKELY(m_gcForbiddenCount)) |
674 return false; | 674 return false; |
675 | 675 |
676 if (Heap::isUrgentGCRequested()) | |
677 return true; | |
678 | |
676 size_t newSize = Heap::allocatedObjectSize(); | 679 size_t newSize = Heap::allocatedObjectSize(); |
677 if (newSize >= 300 * 1024 * 1024) { | 680 if (newSize >= 300 * 1024 * 1024) { |
678 // If we consume too much memory, trigger a conservative GC | 681 // If we consume too much memory, trigger a conservative GC |
679 // on a 50% increase in size since the last GC. This is a safe guard | 682 // on a 50% increase in size since the last GC. This is a safe guard |
680 // to avoid OOM. | 683 // to avoid OOM. |
681 return newSize > Heap::markedObjectSize() / 2; | 684 return newSize > Heap::markedObjectSize() / 2; |
682 } | 685 } |
683 if (m_didV8GCAfterLastGC && m_collectionRate > 0.5) { | 686 if (m_didV8GCAfterLastGC && m_collectionRate > 0.5) { |
684 // If we had a V8 GC after the last Oilpan GC and the last collection | 687 // If we had a V8 GC after the last Oilpan GC and the last collection |
685 // rate was higher than 50%, trigger a conservative GC on a 200% | 688 // rate was higher than 50%, trigger a conservative GC on a 200% |
686 // increase in size since the last GC, but not for less than 4 MB. | 689 // increase in size since the last GC, but not for less than 4 MB. |
687 return newSize >= 4 * 1024 * 1024 && newSize > 2 * Heap::markedObjectSiz e(); | 690 return newSize >= 4 * 1024 * 1024 && newSize > 2 * Heap::markedObjectSiz e(); |
688 } | 691 } |
689 // Otherwise, trigger a conservative GC on a 400% increase in size since | 692 // Otherwise, trigger a conservative GC on a 400% increase in size since |
690 // the last GC, but not for less than 32 MB. We set the higher limit in | 693 // the last GC, but not for less than 32 MB. We set the higher limit in |
691 // this case because Oilpan GC is unlikely to collect a lot of objects | 694 // this case because Oilpan GC is unlikely to collect a lot of objects |
692 // without having a V8 GC. | 695 // without having a V8 GC. |
693 return newSize >= 32 * 1024 * 1024 && newSize > 4 * Heap::markedObjectSize() ; | 696 return newSize >= 32 * 1024 * 1024 && newSize > 4 * Heap::markedObjectSize() ; |
694 } | 697 } |
695 | 698 |
696 void ThreadState::scheduleGCIfNeeded() | 699 void ThreadState::scheduleGCIfNeeded() |
697 { | 700 { |
698 checkThread(); | 701 checkThread(); |
699 // Allocation is allowed during sweeping, but those allocations should not | 702 // Allocation is allowed during sweeping, but those allocations should not |
700 // trigger nested GCs | 703 // trigger nested GCs |
701 if (isSweepingInProgress()) | 704 if (isSweepingInProgress()) { |
702 return; | 705 if (!Heap::isUrgentGCRequested() || !isSweepingScheduled()) |
haraken
2015/02/23 16:40:29
Sorry to bug you a lot of times on this... I recon
sof
2015/02/23 20:47:05
Yes, we don't want to make a distinction between t
| |
706 return; | |
707 // Urgent GC requested with only a GC scheduled; fall through | |
708 // and have it be serviced by a conservative GC. | |
709 } | |
703 ASSERT(!sweepForbidden()); | 710 ASSERT(!sweepForbidden()); |
704 | 711 |
705 if (shouldForceConservativeGC()) | 712 if (shouldForceConservativeGC()) { |
706 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi thoutSweep); | 713 // If GC is deemed urgent, eagerly sweep and finalize any external alloc ations right away. |
707 else if (shouldSchedulePreciseGC()) | 714 GCType gcType = Heap::isUrgentGCRequested() ? GCWithSweep : GCWithoutSwe ep; |
715 Heap::collectGarbage(HeapPointersOnStack, gcType); | |
716 return; | |
717 } | |
718 if (shouldSchedulePreciseGC()) | |
708 schedulePreciseGC(); | 719 schedulePreciseGC(); |
709 else if (shouldScheduleIdleGC()) | 720 else if (shouldScheduleIdleGC()) |
710 scheduleIdleGC(); | 721 scheduleIdleGC(); |
711 } | 722 } |
712 | 723 |
713 void ThreadState::performIdleGC(double deadlineSeconds) | 724 void ThreadState::performIdleGC(double deadlineSeconds) |
714 { | 725 { |
715 ASSERT(isMainThread()); | 726 ASSERT(isMainThread()); |
716 | 727 |
717 m_hasPendingIdleTask = false; | 728 m_hasPendingIdleTask = false; |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1271 json->beginArray(it->key.ascii().data()); | 1282 json->beginArray(it->key.ascii().data()); |
1272 for (size_t age = 0; age <= maxHeapObjectAge; ++age) | 1283 for (size_t age = 0; age <= maxHeapObjectAge; ++age) |
1273 json->pushInteger(it->value.ages[age]); | 1284 json->pushInteger(it->value.ages[age]); |
1274 json->endArray(); | 1285 json->endArray(); |
1275 } | 1286 } |
1276 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s tatsName, this, json.release()); | 1287 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s tatsName, this, json.release()); |
1277 } | 1288 } |
1278 #endif | 1289 #endif |
1279 | 1290 |
1280 } // namespace blink | 1291 } // namespace blink |
OLD | NEW |