aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-03-25 09:46:43 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-25 10:01:43 +0100
commit7526cb1c9507b4718ca63aa0d708b1421cfaa051 (patch)
treeef7baf77b7ec22b648c122b0f0611378b87b4e1f /src/qml/jsruntime
parenta1fdf173ebcbc30f0d3f0ef6a0488d203c2691ec (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.cpp58
-rw-r--r--src/qml/jsruntime/qv4mm_p.h1
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;