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 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 return false; | 460 return false; |
461 } | 461 } |
462 | 462 |
463 void ThreadState::threadLocalWeakProcessing() | 463 void ThreadState::threadLocalWeakProcessing() |
464 { | 464 { |
465 ASSERT(checkThread()); | 465 ASSERT(checkThread()); |
466 ASSERT(!sweepForbidden()); | 466 ASSERT(!sweepForbidden()); |
467 TRACE_EVENT0("blink_gc", "ThreadState::threadLocalWeakProcessing"); | 467 TRACE_EVENT0("blink_gc", "ThreadState::threadLocalWeakProcessing"); |
468 double startTime = WTF::currentTimeMS(); | 468 double startTime = WTF::currentTimeMS(); |
469 | 469 |
470 SweepForbiddenScope forbiddenScope(this); | 470 SweepForbiddenScope sweepForbiddenScope(this); |
471 if (isMainThread()) | 471 ScriptForbiddenIfMainThreadScope scriptForbiddenScope; |
472 ScriptForbiddenScope::enter(); | |
473 | 472 |
474 // Disallow allocation during weak processing. | 473 // Disallow allocation during weak processing. |
475 // It would be technically safe to allow allocations, but it is unsafe | 474 // It would be technically safe to allow allocations, but it is unsafe |
476 // to mutate an object graph in a way in which a dead object gets | 475 // to mutate an object graph in a way in which a dead object gets |
477 // resurrected or mutate a HashTable (because HashTable's weak processing | 476 // resurrected or mutate a HashTable (because HashTable's weak processing |
478 // assumes that the HashTable hasn't been mutated since the latest marking). | 477 // assumes that the HashTable hasn't been mutated since the latest marking). |
479 // Due to the complexity, we just forbid allocations. | 478 // Due to the complexity, we just forbid allocations. |
480 NoAllocationScope noAllocationScope(this); | 479 NoAllocationScope noAllocationScope(this); |
481 | 480 |
482 MarkingVisitor<Visitor::WeakProcessing> weakProcessingVisitor; | 481 MarkingVisitor<Visitor::WeakProcessing> weakProcessingVisitor; |
483 | 482 |
484 // Perform thread-specific weak processing. | 483 // Perform thread-specific weak processing. |
485 while (popAndInvokeThreadLocalWeakCallback(&weakProcessingVisitor)) { } | 484 while (popAndInvokeThreadLocalWeakCallback(&weakProcessingVisitor)) { } |
486 | 485 |
487 if (isMainThread()) { | 486 if (isMainThread()) { |
488 ScriptForbiddenScope::exit(); | |
489 double timeForThreadLocalWeakProcessing = WTF::currentTimeMS() - startTi
me; | 487 double timeForThreadLocalWeakProcessing = WTF::currentTimeMS() - startTi
me; |
490 Platform::current()->histogramCustomCounts("BlinkGC.timeForThreadLocalWe
akProcessing", timeForThreadLocalWeakProcessing, 1, 10 * 1000, 50); | 488 Platform::current()->histogramCustomCounts("BlinkGC.timeForThreadLocalWe
akProcessing", timeForThreadLocalWeakProcessing, 1, 10 * 1000, 50); |
491 } | 489 } |
492 } | 490 } |
493 | 491 |
494 CrossThreadPersistentRegion& ThreadState::crossThreadPersistentRegion() | 492 CrossThreadPersistentRegion& ThreadState::crossThreadPersistentRegion() |
495 { | 493 { |
496 AtomicallyInitializedStaticReference(CrossThreadPersistentRegion, persistent
Region, new CrossThreadPersistentRegion()); | 494 AtomicallyInitializedStaticReference(CrossThreadPersistentRegion, persistent
Region, new CrossThreadPersistentRegion()); |
497 return persistentRegion; | 495 return persistentRegion; |
498 } | 496 } |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
777 // the check just in case. | 775 // the check just in case. |
778 if (sweepForbidden()) | 776 if (sweepForbidden()) |
779 return; | 777 return; |
780 | 778 |
781 TRACE_EVENT1("blink_gc", "ThreadState::performIdleLazySweep", "idleDeltaInSe
conds", deadlineSeconds - Platform::current()->monotonicallyIncreasingTimeSecond
s()); | 779 TRACE_EVENT1("blink_gc", "ThreadState::performIdleLazySweep", "idleDeltaInSe
conds", deadlineSeconds - Platform::current()->monotonicallyIncreasingTimeSecond
s()); |
782 | 780 |
783 bool sweepCompleted = true; | 781 bool sweepCompleted = true; |
784 SweepForbiddenScope scope(this); | 782 SweepForbiddenScope scope(this); |
785 { | 783 { |
786 double startTime = WTF::currentTimeMS(); | 784 double startTime = WTF::currentTimeMS(); |
787 if (isMainThread()) | 785 ScriptForbiddenIfMainThreadScope scriptForbiddenScope; |
788 ScriptForbiddenScope::enter(); | |
789 | 786 |
790 for (int i = 0; i < BlinkGC::NumberOfHeaps; i++) { | 787 for (int i = 0; i < BlinkGC::NumberOfHeaps; i++) { |
791 // lazySweepWithDeadline() won't check the deadline until it sweeps | 788 // lazySweepWithDeadline() won't check the deadline until it sweeps |
792 // 10 pages. So we give a small slack for safety. | 789 // 10 pages. So we give a small slack for safety. |
793 double slack = 0.001; | 790 double slack = 0.001; |
794 double remainingBudget = deadlineSeconds - slack - Platform::current
()->monotonicallyIncreasingTimeSeconds(); | 791 double remainingBudget = deadlineSeconds - slack - Platform::current
()->monotonicallyIncreasingTimeSeconds(); |
795 if (remainingBudget <= 0 || !m_heaps[i]->lazySweepWithDeadline(deadl
ineSeconds)) { | 792 if (remainingBudget <= 0 || !m_heaps[i]->lazySweepWithDeadline(deadl
ineSeconds)) { |
796 // We couldn't finish the sweeping within the deadline. | 793 // We couldn't finish the sweeping within the deadline. |
797 // We request another idle task for the remaining sweeping. | 794 // We request another idle task for the remaining sweeping. |
798 scheduleIdleLazySweep(); | 795 scheduleIdleLazySweep(); |
799 sweepCompleted = false; | 796 sweepCompleted = false; |
800 break; | 797 break; |
801 } | 798 } |
802 } | 799 } |
803 | 800 |
804 if (isMainThread()) | |
805 ScriptForbiddenScope::exit(); | |
806 accumulateSweepingTime(WTF::currentTimeMS() - startTime); | 801 accumulateSweepingTime(WTF::currentTimeMS() - startTime); |
807 } | 802 } |
808 | 803 |
809 if (sweepCompleted) | 804 if (sweepCompleted) |
810 postSweep(); | 805 postSweep(); |
811 } | 806 } |
812 | 807 |
813 void ThreadState::scheduleIdleGC() | 808 void ThreadState::scheduleIdleGC() |
814 { | 809 { |
815 // TODO(haraken): Idle GC should be supported in worker threads as well. | 810 // TODO(haraken): Idle GC should be supported in worker threads as well. |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1068 // Some objects need to be finalized promptly and cannot be handled | 1063 // Some objects need to be finalized promptly and cannot be handled |
1069 // by lazy sweeping. Keep those in a designated heap and sweep it | 1064 // by lazy sweeping. Keep those in a designated heap and sweep it |
1070 // eagerly. | 1065 // eagerly. |
1071 ASSERT(isSweepingInProgress()); | 1066 ASSERT(isSweepingInProgress()); |
1072 | 1067 |
1073 // Mirroring the completeSweep() condition; see its comment. | 1068 // Mirroring the completeSweep() condition; see its comment. |
1074 if (sweepForbidden()) | 1069 if (sweepForbidden()) |
1075 return; | 1070 return; |
1076 | 1071 |
1077 SweepForbiddenScope scope(this); | 1072 SweepForbiddenScope scope(this); |
1078 { | 1073 ScriptForbiddenIfMainThreadScope scriptForbiddenScope; |
1079 double startTime = WTF::currentTimeMS(); | |
1080 if (isMainThread()) | |
1081 ScriptForbiddenScope::enter(); | |
1082 | 1074 |
1083 m_heaps[BlinkGC::EagerSweepHeapIndex]->completeSweep(); | 1075 double startTime = WTF::currentTimeMS(); |
1084 | 1076 m_heaps[BlinkGC::EagerSweepHeapIndex]->completeSweep(); |
1085 if (isMainThread()) | 1077 accumulateSweepingTime(WTF::currentTimeMS() - startTime); |
1086 ScriptForbiddenScope::exit(); | |
1087 accumulateSweepingTime(WTF::currentTimeMS() - startTime); | |
1088 } | |
1089 } | 1078 } |
1090 | 1079 |
1091 void ThreadState::completeSweep() | 1080 void ThreadState::completeSweep() |
1092 { | 1081 { |
1093 ASSERT(checkThread()); | 1082 ASSERT(checkThread()); |
1094 // If we are not in a sweeping phase, there is nothing to do here. | 1083 // If we are not in a sweeping phase, there is nothing to do here. |
1095 if (!isSweepingInProgress()) | 1084 if (!isSweepingInProgress()) |
1096 return; | 1085 return; |
1097 | 1086 |
1098 // completeSweep() can be called recursively if finalizers can allocate | 1087 // completeSweep() can be called recursively if finalizers can allocate |
1099 // memory and the allocation triggers completeSweep(). This check prevents | 1088 // memory and the allocation triggers completeSweep(). This check prevents |
1100 // the sweeping from being executed recursively. | 1089 // the sweeping from being executed recursively. |
1101 if (sweepForbidden()) | 1090 if (sweepForbidden()) |
1102 return; | 1091 return; |
1103 | 1092 |
1104 SweepForbiddenScope scope(this); | 1093 SweepForbiddenScope scope(this); |
1105 { | 1094 { |
1106 if (isMainThread()) | 1095 ScriptForbiddenIfMainThreadScope scriptForbiddenScope; |
1107 ScriptForbiddenScope::enter(); | |
1108 | 1096 |
1109 TRACE_EVENT0("blink_gc", "ThreadState::completeSweep"); | 1097 TRACE_EVENT0("blink_gc", "ThreadState::completeSweep"); |
1110 double startTime = WTF::currentTimeMS(); | 1098 double startTime = WTF::currentTimeMS(); |
1111 | 1099 |
1112 static_assert(BlinkGC::EagerSweepHeapIndex == 0, "Eagerly swept heaps mu
st be processed first."); | 1100 static_assert(BlinkGC::EagerSweepHeapIndex == 0, "Eagerly swept heaps mu
st be processed first."); |
1113 for (int i = 0; i < BlinkGC::NumberOfHeaps; i++) | 1101 for (int i = 0; i < BlinkGC::NumberOfHeaps; i++) |
1114 m_heaps[i]->completeSweep(); | 1102 m_heaps[i]->completeSweep(); |
1115 | 1103 |
1116 double timeForCompleteSweep = WTF::currentTimeMS() - startTime; | 1104 double timeForCompleteSweep = WTF::currentTimeMS() - startTime; |
1117 accumulateSweepingTime(timeForCompleteSweep); | 1105 accumulateSweepingTime(timeForCompleteSweep); |
1118 | 1106 |
1119 if (isMainThread()) { | 1107 if (isMainThread()) |
1120 ScriptForbiddenScope::exit(); | |
1121 Platform::current()->histogramCustomCounts("BlinkGC.CompleteSweep",
timeForCompleteSweep, 1, 10 * 1000, 50); | 1108 Platform::current()->histogramCustomCounts("BlinkGC.CompleteSweep",
timeForCompleteSweep, 1, 10 * 1000, 50); |
1122 } | |
1123 } | 1109 } |
1124 | 1110 |
1125 postSweep(); | 1111 postSweep(); |
1126 } | 1112 } |
1127 | 1113 |
1128 void ThreadState::postSweep() | 1114 void ThreadState::postSweep() |
1129 { | 1115 { |
1130 ASSERT(checkThread()); | 1116 ASSERT(checkThread()); |
1131 Heap::reportMemoryUsageForTracing(); | 1117 Heap::reportMemoryUsageForTracing(); |
1132 | 1118 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 } | 1320 } |
1335 | 1321 |
1336 void ThreadState::invokePreFinalizers() | 1322 void ThreadState::invokePreFinalizers() |
1337 { | 1323 { |
1338 ASSERT(checkThread()); | 1324 ASSERT(checkThread()); |
1339 ASSERT(!sweepForbidden()); | 1325 ASSERT(!sweepForbidden()); |
1340 TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers"); | 1326 TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers"); |
1341 | 1327 |
1342 double startTime = WTF::currentTimeMS(); | 1328 double startTime = WTF::currentTimeMS(); |
1343 if (!m_orderedPreFinalizers.isEmpty()) { | 1329 if (!m_orderedPreFinalizers.isEmpty()) { |
1344 SweepForbiddenScope forbiddenScope(this); | 1330 SweepForbiddenScope sweepForbidden(this); |
1345 if (isMainThread()) | 1331 ScriptForbiddenIfMainThreadScope scriptForbidden; |
1346 ScriptForbiddenScope::enter(); | |
1347 | 1332 |
1348 // Call the prefinalizers in the opposite order to their registration. | 1333 // Call the prefinalizers in the opposite order to their registration. |
1349 // | 1334 // |
1350 // The prefinalizer callback wrapper returns |true| when its associated | 1335 // The prefinalizer callback wrapper returns |true| when its associated |
1351 // object is unreachable garbage and the prefinalizer callback has run. | 1336 // object is unreachable garbage and the prefinalizer callback has run. |
1352 // The registered prefinalizer entry must then be removed and deleted. | 1337 // The registered prefinalizer entry must then be removed and deleted. |
1353 // | 1338 // |
1354 auto it = --m_orderedPreFinalizers.end(); | 1339 auto it = --m_orderedPreFinalizers.end(); |
1355 bool done; | 1340 bool done; |
1356 do { | 1341 do { |
1357 auto entry = it; | 1342 auto entry = it; |
1358 done = it == m_orderedPreFinalizers.begin(); | 1343 done = it == m_orderedPreFinalizers.begin(); |
1359 if (!done) | 1344 if (!done) |
1360 --it; | 1345 --it; |
1361 if ((entry->second)(entry->first)) | 1346 if ((entry->second)(entry->first)) |
1362 m_orderedPreFinalizers.remove(entry); | 1347 m_orderedPreFinalizers.remove(entry); |
1363 } while (!done); | 1348 } while (!done); |
1364 | |
1365 if (isMainThread()) | |
1366 ScriptForbiddenScope::exit(); | |
1367 } | 1349 } |
1368 if (isMainThread()) { | 1350 if (isMainThread()) { |
1369 double timeForInvokingPreFinalizers = WTF::currentTimeMS() - startTime; | 1351 double timeForInvokingPreFinalizers = WTF::currentTimeMS() - startTime; |
1370 Platform::current()->histogramCustomCounts("BlinkGC.TimeForInvokingPreFi
nalizers", timeForInvokingPreFinalizers, 1, 10 * 1000, 50); | 1352 Platform::current()->histogramCustomCounts("BlinkGC.TimeForInvokingPreFi
nalizers", timeForInvokingPreFinalizers, 1, 10 * 1000, 50); |
1371 } | 1353 } |
1372 } | 1354 } |
1373 | 1355 |
1374 void ThreadState::clearHeapAges() | 1356 void ThreadState::clearHeapAges() |
1375 { | 1357 { |
1376 memset(m_heapAges, 0, sizeof(size_t) * BlinkGC::NumberOfHeaps); | 1358 memset(m_heapAges, 0, sizeof(size_t) * BlinkGC::NumberOfHeaps); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 threadDump->addScalar("dead_count", "objects", totalDeadCount); | 1474 threadDump->addScalar("dead_count", "objects", totalDeadCount); |
1493 threadDump->addScalar("live_size", "bytes", totalLiveSize); | 1475 threadDump->addScalar("live_size", "bytes", totalLiveSize); |
1494 threadDump->addScalar("dead_size", "bytes", totalDeadSize); | 1476 threadDump->addScalar("dead_size", "bytes", totalDeadSize); |
1495 | 1477 |
1496 WebMemoryAllocatorDump* heapsDump = BlinkGCMemoryDumpProvider::instance()->c
reateMemoryAllocatorDumpForCurrentGC(heapsDumpName); | 1478 WebMemoryAllocatorDump* heapsDump = BlinkGCMemoryDumpProvider::instance()->c
reateMemoryAllocatorDumpForCurrentGC(heapsDumpName); |
1497 WebMemoryAllocatorDump* classesDump = BlinkGCMemoryDumpProvider::instance()-
>createMemoryAllocatorDumpForCurrentGC(classesDumpName); | 1479 WebMemoryAllocatorDump* classesDump = BlinkGCMemoryDumpProvider::instance()-
>createMemoryAllocatorDumpForCurrentGC(classesDumpName); |
1498 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->addOwners
hipEdge(classesDump->guid(), heapsDump->guid()); | 1480 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->addOwners
hipEdge(classesDump->guid(), heapsDump->guid()); |
1499 } | 1481 } |
1500 | 1482 |
1501 } // namespace blink | 1483 } // namespace blink |
OLD | NEW |