aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/memory
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/memory')
-rw-r--r--src/qml/memory/qv4mm.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index d9772e608e..451e7c485d 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -617,21 +617,29 @@ void BlockAllocator::sweep()
// qDebug() << "BlockAlloc: sweep";
usedSlotsAfterLastSweep = 0;
- auto isFree = [this] (Chunk *c) {
+ std::vector<Chunk *> chunksToFree;
+
+ auto isFree = [this, &chunksToFree] (Chunk *c) {
bool isUsed = c->sweep(engine);
if (isUsed) {
c->sortIntoBins(freeBins, NumBins);
usedSlotsAfterLastSweep += c->nUsedSlots();
} else {
- Q_V4_PROFILE_DEALLOC(engine, Chunk::DataSize, Profiling::HeapPage);
- chunkAllocator->free(c);
+ chunksToFree.push_back(c);
}
return !isUsed;
};
auto newEnd = std::remove_if(chunks.begin(), chunks.end(), isFree);
chunks.erase(newEnd, chunks.end());
+
+ // only free the chunks at the end to avoid that the sweep() calls indirectly
+ // access freed memory
+ for (auto c : chunksToFree) {
+ Q_V4_PROFILE_DEALLOC(engine, Chunk::DataSize, Profiling::HeapPage);
+ chunkAllocator->free(c);
+ }
}
void BlockAllocator::freeAll()