| 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. Does not apply if an urgent GC has been requested. |
| 701 if (isSweepingInProgress()) | 704 if (isSweepingInProgress() && UNLIKELY(!Heap::isUrgentGCRequested())) |
| 702 return; | 705 return; |
| 703 ASSERT(!sweepForbidden()); | 706 ASSERT(!sweepForbidden()); |
| 704 | 707 |
| 705 if (shouldForceConservativeGC()) | 708 if (shouldForceConservativeGC()) { |
| 706 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thoutSweep); | 709 // If GC is deemed urgent, eagerly sweep and finalize any external alloc
ations right away. |
| 707 else if (shouldSchedulePreciseGC()) | 710 GCType gcType = Heap::isUrgentGCRequested() ? GCWithSweep : GCWithoutSwe
ep; |
| 711 Heap::collectGarbage(HeapPointersOnStack, gcType); |
| 712 return; |
| 713 } |
| 714 if (shouldSchedulePreciseGC()) |
| 708 schedulePreciseGC(); | 715 schedulePreciseGC(); |
| 709 else if (shouldScheduleIdleGC()) | 716 else if (shouldScheduleIdleGC()) |
| 710 scheduleIdleGC(); | 717 scheduleIdleGC(); |
| 711 } | 718 } |
| 712 | 719 |
| 713 void ThreadState::performIdleGC(double deadlineSeconds) | 720 void ThreadState::performIdleGC(double deadlineSeconds) |
| 714 { | 721 { |
| 715 ASSERT(isMainThread()); | 722 ASSERT(isMainThread()); |
| 716 | 723 |
| 717 m_hasPendingIdleTask = false; | 724 m_hasPendingIdleTask = false; |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1271 json->beginArray(it->key.ascii().data()); | 1278 json->beginArray(it->key.ascii().data()); |
| 1272 for (size_t age = 0; age <= maxHeapObjectAge; ++age) | 1279 for (size_t age = 0; age <= maxHeapObjectAge; ++age) |
| 1273 json->pushInteger(it->value.ages[age]); | 1280 json->pushInteger(it->value.ages[age]); |
| 1274 json->endArray(); | 1281 json->endArray(); |
| 1275 } | 1282 } |
| 1276 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s
tatsName, this, json.release()); | 1283 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s
tatsName, this, json.release()); |
| 1277 } | 1284 } |
| 1278 #endif | 1285 #endif |
| 1279 | 1286 |
| 1280 } // namespace blink | 1287 } // namespace blink |
| OLD | NEW |