| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/heap/HeapCompact.h" | 5 #include "platform/heap/HeapCompact.h" |
| 6 | 6 |
| 7 #include "platform/Histogram.h" | 7 #include "platform/Histogram.h" |
| 8 #include "platform/RuntimeEnabledFeatures.h" | 8 #include "platform/RuntimeEnabledFeatures.h" |
| 9 #include "platform/heap/Heap.h" | 9 #include "platform/heap/Heap.h" |
| 10 #include "platform/heap/SparseHeapBitmap.h" | 10 #include "platform/heap/SparseHeapBitmap.h" |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 | 246 |
| 247 // All pages that are being compacted. | 247 // All pages that are being compacted. |
| 248 HashSet<BasePage*> m_relocatablePages; | 248 HashSet<BasePage*> m_relocatablePages; |
| 249 | 249 |
| 250 std::unique_ptr<SparseHeapBitmap> m_interiors; | 250 std::unique_ptr<SparseHeapBitmap> m_interiors; |
| 251 }; | 251 }; |
| 252 | 252 |
| 253 HeapCompact::HeapCompact() | 253 HeapCompact::HeapCompact() |
| 254 : m_doCompact(false), | 254 : m_doCompact(false), |
| 255 m_gcCountSinceLastCompaction(0), | 255 m_gcCountSinceLastCompaction(0), |
| 256 m_threadCount(0), | |
| 257 m_freeListSize(0), | 256 m_freeListSize(0), |
| 258 m_compactableArenas(0u), | 257 m_compactableArenas(0u), |
| 259 m_freedPages(0), | 258 m_freedPages(0), |
| 260 m_freedSize(0), | 259 m_freedSize(0), |
| 261 m_startCompactionTimeMS(0) { | 260 m_startCompactionTimeMS(0) { |
| 262 // The heap compaction implementation assumes the contiguous range, | 261 // The heap compaction implementation assumes the contiguous range, |
| 263 // | 262 // |
| 264 // [Vector1ArenaIndex, HashTableArenaIndex] | 263 // [Vector1ArenaIndex, HashTableArenaIndex] |
| 265 // | 264 // |
| 266 // in a few places. Use static asserts here to not have that assumption | 265 // in a few places. Use static asserts here to not have that assumption |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 #endif | 338 #endif |
| 340 #endif | 339 #endif |
| 341 } | 340 } |
| 342 | 341 |
| 343 void HeapCompact::initialize(ThreadState* state) { | 342 void HeapCompact::initialize(ThreadState* state) { |
| 344 DCHECK(RuntimeEnabledFeatures::heapCompactionEnabled()); | 343 DCHECK(RuntimeEnabledFeatures::heapCompactionEnabled()); |
| 345 LOG_HEAP_COMPACTION("Compacting: free=%zu\n", m_freeListSize); | 344 LOG_HEAP_COMPACTION("Compacting: free=%zu\n", m_freeListSize); |
| 346 m_doCompact = true; | 345 m_doCompact = true; |
| 347 m_freedPages = 0; | 346 m_freedPages = 0; |
| 348 m_freedSize = 0; | 347 m_freedSize = 0; |
| 349 m_threadCount = state->heap().threads().size(); | |
| 350 m_fixups.reset(); | 348 m_fixups.reset(); |
| 351 m_gcCountSinceLastCompaction = 0; | 349 m_gcCountSinceLastCompaction = 0; |
| 352 s_forceCompactionGC = false; | 350 s_forceCompactionGC = false; |
| 353 } | 351 } |
| 354 | 352 |
| 355 void HeapCompact::registerMovingObjectReference(MovableReference* slot) { | 353 void HeapCompact::registerMovingObjectReference(MovableReference* slot) { |
| 356 if (!m_doCompact) | 354 if (!m_doCompact) |
| 357 return; | 355 return; |
| 358 | 356 |
| 359 fixups().add(slot); | 357 fixups().add(slot); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 | 409 |
| 412 void HeapCompact::relocate(Address from, Address to) { | 410 void HeapCompact::relocate(Address from, Address to) { |
| 413 DCHECK(m_fixups); | 411 DCHECK(m_fixups); |
| 414 m_fixups->relocate(from, to); | 412 m_fixups->relocate(from, to); |
| 415 } | 413 } |
| 416 | 414 |
| 417 void HeapCompact::startThreadCompaction() { | 415 void HeapCompact::startThreadCompaction() { |
| 418 if (!m_doCompact) | 416 if (!m_doCompact) |
| 419 return; | 417 return; |
| 420 | 418 |
| 421 MutexLocker locker(m_mutex); | |
| 422 if (!m_startCompactionTimeMS) | 419 if (!m_startCompactionTimeMS) |
| 423 m_startCompactionTimeMS = WTF::currentTimeMS(); | 420 m_startCompactionTimeMS = WTF::currentTimeMS(); |
| 424 } | 421 } |
| 425 | 422 |
| 426 void HeapCompact::finishThreadCompaction() { | 423 void HeapCompact::finishThreadCompaction() { |
| 427 if (!m_doCompact) | 424 if (!m_doCompact) |
| 428 return; | 425 return; |
| 429 | 426 |
| 430 MutexLocker locker(m_mutex); | |
| 431 // Final one clears out. | |
| 432 if (!--m_threadCount) { | |
| 433 #if DEBUG_HEAP_COMPACTION | 427 #if DEBUG_HEAP_COMPACTION |
| 434 if (m_fixups) | 428 if (m_fixups) |
| 435 m_fixups->dumpDebugStats(); | 429 m_fixups->dumpDebugStats(); |
| 436 #endif | 430 #endif |
| 437 m_fixups.reset(); | 431 m_fixups.reset(); |
| 438 m_doCompact = false; | 432 m_doCompact = false; |
| 439 | 433 |
| 440 double timeForHeapCompaction = | 434 double timeForHeapCompaction = WTF::currentTimeMS() - m_startCompactionTimeMS; |
| 441 WTF::currentTimeMS() - m_startCompactionTimeMS; | 435 DEFINE_STATIC_LOCAL(CustomCountHistogram, timeForHeapCompactionHistogram, |
| 442 DEFINE_STATIC_LOCAL(CustomCountHistogram, timeForHeapCompactionHistogram, | 436 ("BlinkGC.TimeForHeapCompaction", 1, 10 * 1000, 50)); |
| 443 ("BlinkGC.TimeForHeapCompaction", 1, 10 * 1000, 50)); | 437 timeForHeapCompactionHistogram.count(timeForHeapCompaction); |
| 444 timeForHeapCompactionHistogram.count(timeForHeapCompaction); | 438 m_startCompactionTimeMS = 0; |
| 445 m_startCompactionTimeMS = 0; | |
| 446 | 439 |
| 447 DEFINE_STATIC_LOCAL( | 440 DEFINE_STATIC_LOCAL( |
| 448 CustomCountHistogram, objectSizeFreedByHeapCompaction, | 441 CustomCountHistogram, objectSizeFreedByHeapCompaction, |
| 449 ("BlinkGC.ObjectSizeFreedByHeapCompaction", 1, 4 * 1024 * 1024, 50)); | 442 ("BlinkGC.ObjectSizeFreedByHeapCompaction", 1, 4 * 1024 * 1024, 50)); |
| 450 objectSizeFreedByHeapCompaction.count(m_freedSize / 1024); | 443 objectSizeFreedByHeapCompaction.count(m_freedSize / 1024); |
| 451 | 444 |
| 452 #if DEBUG_LOG_HEAP_COMPACTION_RUNNING_TIME | 445 #if DEBUG_LOG_HEAP_COMPACTION_RUNNING_TIME |
| 453 LOG_HEAP_COMPACTION_INTERNAL( | 446 LOG_HEAP_COMPACTION_INTERNAL( |
| 454 "Compaction stats: time=%gms, pages freed=%zu, size=%zu\n", | 447 "Compaction stats: time=%gms, pages freed=%zu, size=%zu\n", |
| 455 timeForHeapCompaction, m_freedPages, m_freedSize); | 448 timeForHeapCompaction, m_freedPages, m_freedSize); |
| 456 #else | 449 #else |
| 457 LOG_HEAP_COMPACTION("Compaction stats: freed pages=%zu size=%zu\n", | 450 LOG_HEAP_COMPACTION("Compaction stats: freed pages=%zu size=%zu\n", |
| 458 m_freedPages, m_freedSize); | 451 m_freedPages, m_freedSize); |
| 459 #endif | 452 #endif |
| 460 | |
| 461 // Compaction has been completed by all participating threads, unblock | |
| 462 // them all. | |
| 463 m_finished.broadcast(); | |
| 464 } else { | |
| 465 // Letting a thread return here and let it exit its safe point opens up | |
| 466 // the possibility of it accessing heaps of other threads that are | |
| 467 // still being compacted. It is not in a valid state until objects have | |
| 468 // all been moved together, hence all GC-participating threads must | |
| 469 // complete compaction together. Grab the condition variable and wait. | |
| 470 m_finished.wait(m_mutex); | |
| 471 } | |
| 472 } | 453 } |
| 473 | 454 |
| 474 void HeapCompact::addCompactingPage(BasePage* page) { | 455 void HeapCompact::addCompactingPage(BasePage* page) { |
| 475 DCHECK(m_doCompact); | 456 DCHECK(m_doCompact); |
| 476 DCHECK(isCompactingArena(page->arena()->arenaIndex())); | 457 DCHECK(isCompactingArena(page->arena()->arenaIndex())); |
| 477 fixups().addCompactingPage(page); | 458 fixups().addCompactingPage(page); |
| 478 } | 459 } |
| 479 | 460 |
| 480 bool HeapCompact::scheduleCompactionGCForTesting(bool value) { | 461 bool HeapCompact::scheduleCompactionGCForTesting(bool value) { |
| 481 bool current = s_forceCompactionGC; | 462 bool current = s_forceCompactionGC; |
| 482 s_forceCompactionGC = value; | 463 s_forceCompactionGC = value; |
| 483 return current; | 464 return current; |
| 484 } | 465 } |
| 485 | 466 |
| 486 } // namespace blink | 467 } // namespace blink |
| OLD | NEW |