diff options
Diffstat (limited to 'src/qml/memory')
-rw-r--r-- | src/qml/memory/qv4mm.cpp | 14 |
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() |