diff options
author | Lars Knoll <lars.knoll@digia.com> | 2014-03-25 09:46:43 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-25 10:01:43 +0100 |
commit | 7526cb1c9507b4718ca63aa0d708b1421cfaa051 (patch) | |
tree | ef7baf77b7ec22b648c122b0f0611378b87b4e1f /src/qml/jsruntime | |
parent | a1fdf173ebcbc30f0d3f0ef6a0488d203c2691ec (diff) |
Optional reporting of GC statistics to stdout
Use QV4_MM_STATS to get some statistics about each GC run
written to stderr.
Change-Id: Idc30c06e1c3ca8353a2f16615cb26df13a8f23ed
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4mm.cpp | 58 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4mm_p.h | 1 |
2 files changed, 46 insertions, 13 deletions
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp index 92cd5666f0..421cc2cf82 100644 --- a/src/qml/jsruntime/qv4mm.cpp +++ b/src/qml/jsruntime/qv4mm.cpp @@ -84,6 +84,7 @@ struct MemoryManager::Data bool gcBlocked; bool scribble; bool aggressiveGC; + bool gcStats; ExecutionEngine *engine; enum { MaxItemSize = 512 }; @@ -133,6 +134,7 @@ struct MemoryManager::Data memset(allocCount, 0, sizeof(allocCount)); scribble = !qgetenv("QV4_MM_SCRIBBLE").isEmpty(); aggressiveGC = !qgetenv("QV4_MM_AGGRESSIVE_GC").isEmpty(); + gcStats = !qgetenv("QV4_MM_STATS").isEmpty(); QByteArray overrideMaxShift = qgetenv("QV4_MM_MAXBLOCK_SHIFT"); bool ok; @@ -438,24 +440,54 @@ void MemoryManager::runGC() return; } -// QTime t; t.start(); - -// qDebug() << ">>>>>>>>runGC"; - - mark(); -// std::cerr << "GC: marked " << marks -// << " objects in " << t.elapsed() -// << "ms" << std::endl; + if (!m_d->gcStats) { + mark(); + sweep(); + } else { + int totalMem = 0; + for (int i = 0; i < m_d->heapChunks.size(); ++i) + totalMem += m_d->heapChunks.at(i).memory.size(); + + QTime t; + t.start(); + mark(); + int markTime = t.elapsed(); + t.restart(); + int usedBefore = getUsedMem(); + sweep(); + int usedAfter = getUsedMem(); + int sweepTime = t.elapsed(); + + qDebug() << "========== GC =========="; + qDebug() << "Marked object in" << markTime << "ms."; + qDebug() << "Sweeped object in" << sweepTime << "ms."; + qDebug() << "Allocated" << totalMem << "bytes in" << m_d->heapChunks.size() << "chunks."; + qDebug() << "Used memory before GC:" << usedBefore; + qDebug() << "Used memory after GC:" << usedAfter; + qDebug() << "Freed up bytes:" << (usedBefore - usedAfter); + qDebug() << "======== End GC ========"; + } -// t.restart(); - /*std::size_t freedCount =*/ sweep(); -// std::cerr << "GC: sweep freed " << freedCount -// << " objects in " << t.elapsed() -// << "ms" << std::endl; memset(m_d->allocCount, 0, sizeof(m_d->allocCount)); m_d->totalAlloc = 0; } +uint MemoryManager::getUsedMem() +{ + uint usedMem = 0; + for (QVector<Data::Chunk>::iterator i = m_d->heapChunks.begin(), ei = m_d->heapChunks.end(); i != ei; ++i) { + char *chunkStart = reinterpret_cast<char *>(i->memory.base()); + char *chunkEnd = chunkStart + i->memory.size() - i->chunkSize; + for (char *chunk = chunkStart; chunk <= chunkEnd; chunk += i->chunkSize) { + Managed *m = reinterpret_cast<Managed *>(chunk); + Q_ASSERT((qintptr) chunk % 16 == 0); + if (m->inUse) + usedMem += i->chunkSize; + } + } + return usedMem; +} + MemoryManager::~MemoryManager() { PersistentValuePrivate *persistent = m_persistentValues; diff --git a/src/qml/jsruntime/qv4mm_p.h b/src/qml/jsruntime/qv4mm_p.h index b688ee1de0..5ab59b857b 100644 --- a/src/qml/jsruntime/qv4mm_p.h +++ b/src/qml/jsruntime/qv4mm_p.h @@ -127,6 +127,7 @@ private: void mark(); void sweep(bool lastSweep = false); void sweep(char *chunkStart, std::size_t chunkSize, size_t size, GCDeletable **deletable); + uint getUsedMem(); protected: QScopedPointer<Data> m_d; |