Chromium Code Reviews| 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 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 613 // This check is here to prevent performIdleLazySweep() from being called | 613 // This check is here to prevent performIdleLazySweep() from being called |
| 614 // recursively. I'm not sure if it can happen but it would be safer to have | 614 // recursively. I'm not sure if it can happen but it would be safer to have |
| 615 // the check just in case. | 615 // the check just in case. |
| 616 if (sweepForbidden()) | 616 if (sweepForbidden()) |
| 617 return; | 617 return; |
| 618 | 618 |
| 619 TRACE_EVENT1("blink_gc,devtools.timeline", | 619 TRACE_EVENT1("blink_gc,devtools.timeline", |
| 620 "ThreadState::performIdleLazySweep", "idleDeltaInSeconds", | 620 "ThreadState::performIdleLazySweep", "idleDeltaInSeconds", |
| 621 deadlineSeconds - monotonicallyIncreasingTime()); | 621 deadlineSeconds - monotonicallyIncreasingTime()); |
| 622 | 622 |
| 623 SweepForbiddenScope scope(this); | |
| 624 ScriptForbiddenIfMainThreadScope scriptForbiddenScope; | |
| 625 | |
| 626 double startTime = WTF::currentTimeMS(); | |
| 623 bool sweepCompleted = true; | 627 bool sweepCompleted = true; |
| 624 SweepForbiddenScope scope(this); | 628 for (int i = 0; i < BlinkGC::NumberOfArenas; i++) { |
| 625 { | 629 // lazySweepWithDeadline() won't check the deadline until it sweeps |
| 626 double startTime = WTF::currentTimeMS(); | 630 // 10 pages. So we give a small slack for safety. |
| 627 ScriptForbiddenIfMainThreadScope scriptForbiddenScope; | 631 double slack = 0.001; |
| 628 | 632 double remainingBudget = |
| 629 for (int i = 0; i < BlinkGC::NumberOfArenas; i++) { | 633 deadlineSeconds - slack - monotonicallyIncreasingTime(); |
| 630 // lazySweepWithDeadline() won't check the deadline until it sweeps | 634 if (remainingBudget <= 0 || |
| 631 // 10 pages. So we give a small slack for safety. | 635 !m_arenas[i]->lazySweepWithDeadline(deadlineSeconds)) { |
| 632 double slack = 0.001; | 636 // We couldn't finish the sweeping within the deadline. |
| 633 double remainingBudget = | 637 // We request another idle task for the remaining sweeping. |
| 634 deadlineSeconds - slack - monotonicallyIncreasingTime(); | 638 scheduleIdleLazySweep(); |
| 635 if (remainingBudget <= 0 || | 639 sweepCompleted = false; |
| 636 !m_arenas[i]->lazySweepWithDeadline(deadlineSeconds)) { | 640 break; |
| 637 // We couldn't finish the sweeping within the deadline. | |
| 638 // We request another idle task for the remaining sweeping. | |
| 639 scheduleIdleLazySweep(); | |
| 640 sweepCompleted = false; | |
| 641 break; | |
| 642 } | |
| 643 } | 641 } |
| 644 | |
| 645 accumulateSweepingTime(WTF::currentTimeMS() - startTime); | |
| 646 } | 642 } |
| 643 accumulateSweepingTime(WTF::currentTimeMS() - startTime); | |
| 647 | 644 |
| 648 if (sweepCompleted) | 645 if (sweepCompleted) |
| 649 postSweep(); | 646 postSweep(); |
| 650 } | 647 } |
| 651 | 648 |
| 652 void ThreadState::scheduleIdleGC() { | 649 void ThreadState::scheduleIdleGC() { |
| 653 // TODO(haraken): Idle GC should be supported in worker threads as well. | 650 // TODO(haraken): Idle GC should be supported in worker threads as well. |
| 654 if (!isMainThread()) | 651 if (!isMainThread()) |
| 655 return; | 652 return; |
| 656 | 653 |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 975 if (!isSweepingInProgress()) | 972 if (!isSweepingInProgress()) |
| 976 return; | 973 return; |
| 977 | 974 |
| 978 // completeSweep() can be called recursively if finalizers can allocate | 975 // completeSweep() can be called recursively if finalizers can allocate |
| 979 // memory and the allocation triggers completeSweep(). This check prevents | 976 // memory and the allocation triggers completeSweep(). This check prevents |
| 980 // the sweeping from being executed recursively. | 977 // the sweeping from being executed recursively. |
| 981 if (sweepForbidden()) | 978 if (sweepForbidden()) |
| 982 return; | 979 return; |
| 983 | 980 |
| 984 SweepForbiddenScope scope(this); | 981 SweepForbiddenScope scope(this); |
| 985 { | 982 ScriptForbiddenIfMainThreadScope scriptForbiddenScope; |
| 986 ScriptForbiddenIfMainThreadScope scriptForbiddenScope; | |
| 987 | 983 |
| 988 TRACE_EVENT0("blink_gc,devtools.timeline", "ThreadState::completeSweep"); | 984 TRACE_EVENT0("blink_gc,devtools.timeline", "ThreadState::completeSweep"); |
| 989 double startTime = WTF::currentTimeMS(); | 985 double startTime = WTF::currentTimeMS(); |
| 990 | 986 |
| 991 static_assert(BlinkGC::EagerSweepArenaIndex == 0, | 987 static_assert(BlinkGC::EagerSweepArenaIndex == 0, |
| 992 "Eagerly swept arenas must be processed first."); | 988 "Eagerly swept arenas must be processed first."); |
| 993 for (int i = 0; i < BlinkGC::NumberOfArenas; i++) | 989 for (int i = 0; i < BlinkGC::NumberOfArenas; i++) |
| 994 m_arenas[i]->completeSweep(); | 990 m_arenas[i]->completeSweep(); |
| 995 | 991 |
| 996 double timeForCompleteSweep = WTF::currentTimeMS() - startTime; | 992 double timeForCompleteSweep = WTF::currentTimeMS() - startTime; |
| 997 accumulateSweepingTime(timeForCompleteSweep); | 993 accumulateSweepingTime(timeForCompleteSweep); |
| 998 | 994 |
| 999 if (isMainThread()) { | 995 if (isMainThread()) { |
| 1000 DEFINE_STATIC_LOCAL(CustomCountHistogram, completeSweepHistogram, | 996 DEFINE_STATIC_LOCAL(CustomCountHistogram, completeSweepHistogram, |
| 1001 ("BlinkGC.CompleteSweep", 1, 10 * 1000, 50)); | 997 ("BlinkGC.CompleteSweep", 1, 10 * 1000, 50)); |
| 1002 completeSweepHistogram.count(timeForCompleteSweep); | 998 completeSweepHistogram.count(timeForCompleteSweep); |
| 1003 } | |
| 1004 } | 999 } |
| 1005 | 1000 |
| 1006 postSweep(); | 1001 postSweep(); |
| 1007 } | 1002 } |
| 1008 | 1003 |
| 1009 void ThreadState::postSweep() { | 1004 void ThreadState::postSweep() { |
| 1010 ASSERT(checkThread()); | 1005 ASSERT(checkThread()); |
| 1011 ThreadHeap::reportMemoryUsageForTracing(); | 1006 ThreadHeap::reportMemoryUsageForTracing(); |
| 1012 | 1007 |
| 1013 if (isMainThread()) { | 1008 if (isMainThread()) { |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1274 | 1269 |
| 1275 void ThreadState::unlockThreadAttachMutex() { | 1270 void ThreadState::unlockThreadAttachMutex() { |
| 1276 m_heap->threadAttachMutex().unlock(); | 1271 m_heap->threadAttachMutex().unlock(); |
| 1277 } | 1272 } |
| 1278 | 1273 |
| 1279 void ThreadState::invokePreFinalizers() { | 1274 void ThreadState::invokePreFinalizers() { |
| 1280 ASSERT(checkThread()); | 1275 ASSERT(checkThread()); |
| 1281 ASSERT(!sweepForbidden()); | 1276 ASSERT(!sweepForbidden()); |
| 1282 TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers"); | 1277 TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers"); |
| 1283 | 1278 |
| 1279 SweepForbiddenScope sweepForbidden(this); | |
|
haraken
2017/02/15 09:37:15
Actually this is not needed though.
| |
| 1280 ScriptForbiddenIfMainThreadScope scriptForbidden; | |
| 1281 | |
| 1284 double startTime = WTF::currentTimeMS(); | 1282 double startTime = WTF::currentTimeMS(); |
| 1285 if (!m_orderedPreFinalizers.isEmpty()) { | 1283 if (!m_orderedPreFinalizers.isEmpty()) { |
| 1286 SweepForbiddenScope sweepForbidden(this); | |
| 1287 ScriptForbiddenIfMainThreadScope scriptForbidden; | |
| 1288 | |
| 1289 // Call the prefinalizers in the opposite order to their registration. | 1284 // Call the prefinalizers in the opposite order to their registration. |
| 1290 // | 1285 // |
| 1291 // The prefinalizer callback wrapper returns |true| when its associated | 1286 // The prefinalizer callback wrapper returns |true| when its associated |
| 1292 // object is unreachable garbage and the prefinalizer callback has run. | 1287 // object is unreachable garbage and the prefinalizer callback has run. |
| 1293 // The registered prefinalizer entry must then be removed and deleted. | 1288 // The registered prefinalizer entry must then be removed and deleted. |
| 1294 // | 1289 // |
| 1295 auto it = --m_orderedPreFinalizers.end(); | 1290 auto it = --m_orderedPreFinalizers.end(); |
| 1296 bool done; | 1291 bool done; |
| 1297 do { | 1292 do { |
| 1298 auto entry = it; | 1293 auto entry = it; |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1568 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, | 1563 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, |
| 1569 BlinkGC::ForcedGC); | 1564 BlinkGC::ForcedGC); |
| 1570 size_t liveObjects = heap().heapStats().markedObjectSize(); | 1565 size_t liveObjects = heap().heapStats().markedObjectSize(); |
| 1571 if (liveObjects == previousLiveObjects) | 1566 if (liveObjects == previousLiveObjects) |
| 1572 break; | 1567 break; |
| 1573 previousLiveObjects = liveObjects; | 1568 previousLiveObjects = liveObjects; |
| 1574 } | 1569 } |
| 1575 } | 1570 } |
| 1576 | 1571 |
| 1577 } // namespace blink | 1572 } // namespace blink |
| OLD | NEW |