aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/memory
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/memory')
-rw-r--r--src/qml/memory/qv4mm.cpp30
-rw-r--r--src/qml/memory/qv4mmdefs_p.h6
2 files changed, 27 insertions, 9 deletions
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 0a6dfb9170..ef36e62373 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -275,8 +275,9 @@ QString binary(quintptr) { return QString(); }
#define SDUMP if (1) ; else qDebug
#endif
-void Chunk::sweep()
+bool Chunk::sweep()
{
+ bool hasUsedSlots = false;
SDUMP() << "sweeping chunk" << this;
HeapItem *o = realBase();
bool lastSlotFree = false;
@@ -316,6 +317,7 @@ void Chunk::sweep()
}
}
objectBitmap[i] = blackBitmap[i];
+ hasUsedSlots |= (blackBitmap[i] != 0);
blackBitmap[i] = 0;
extendsBitmap[i] = e;
lastSlotFree = !((objectBitmap[i]|extendsBitmap[i]) >> (sizeof(quintptr)*8 - 1));
@@ -325,6 +327,7 @@ void Chunk::sweep()
o += Chunk::Bits;
}
// DEBUG << "swept chunk" << this << "freed" << slotsFreed << "slots.";
+ return hasUsedSlots;
}
void Chunk::freeAll()
@@ -579,12 +582,21 @@ void BlockAllocator::sweep()
// qDebug() << "BlockAlloc: sweep";
usedSlotsAfterLastSweep = 0;
- for (auto c : chunks) {
- c->sweep();
- c->sortIntoBins(freeBins, NumBins);
-// qDebug() << "used slots in chunk" << c << ":" << c->nUsedSlots();
- usedSlotsAfterLastSweep += c->nUsedSlots();
- }
+
+ auto isFree = [this] (Chunk *c) {
+ bool isUsed = c->sweep();
+
+ if (isUsed) {
+ c->sortIntoBins(freeBins, NumBins);
+ usedSlotsAfterLastSweep += c->nUsedSlots();
+ } else {
+ chunkAllocator->free(c);
+ }
+ return !isUsed;
+ };
+
+ auto newEnd = std::remove_if(chunks.begin(), chunks.end(), isFree);
+ chunks.erase(newEnd, chunks.end());
}
void BlockAllocator::freeAll()
@@ -950,7 +962,8 @@ void MemoryManager::runGC()
#ifndef QT_NO_DEBUG
qDebug() << " Triggered by alloc request of" << lastAllocRequestedSlots << "slots.";
#endif
- qDebug() << "Allocated" << totalMem << "bytes in" << blockAllocator.chunks.size() << "chunks";
+ size_t oldChunks = blockAllocator.chunks.size();
+ qDebug() << "Allocated" << totalMem << "bytes in" << oldChunks << "chunks";
qDebug() << "Fragmented memory before GC" << (totalMem - usedBefore);
dumpBins(&blockAllocator);
@@ -975,6 +988,7 @@ void MemoryManager::runGC()
qDebug() << "Used memory before GC:" << usedBefore;
qDebug() << "Used memory after GC:" << usedAfter;
qDebug() << "Freed up bytes:" << (usedBefore - usedAfter);
+ qDebug() << "Freed up chunks:" << (oldChunks - blockAllocator.chunks.size());
size_t lost = blockAllocator.allocatedMem() - memInBins - usedAfter;
if (lost)
qDebug() << "!!!!!!!!!!!!!!!!!!!!! LOST MEM:" << lost << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h
index db0ffe11a2..6e820dfc0f 100644
--- a/src/qml/memory/qv4mmdefs_p.h
+++ b/src/qml/memory/qv4mmdefs_p.h
@@ -59,6 +59,10 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+struct MarkStack;
+
+typedef void(*ClassDestroyStatsCallback)(const char *);
+
/*
* Chunks are the basic structure containing GC managed objects.
*
@@ -175,7 +179,7 @@ struct Chunk {
return usedSlots;
}
- void sweep();
+ bool sweep();
void freeAll();
void sortIntoBins(HeapItem **bins, uint nBins);