| 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 | 
|---|