aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/memory
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-01-09 14:32:32 +0100
committerLiang Qi <liang.qi@qt.io>2018-01-09 14:32:32 +0100
commite3f7da72ac5b4540f88bb5cbd91a4917ba84334a (patch)
tree3f05c1cf965fe291685c383f04b0bec87b05095b /src/qml/memory
parent4cc883452b37dbe3148064150dc2f6b282b6b816 (diff)
parent2e8a45d99f94cbd2c805dd3de56d60d9baa9bd4e (diff)
Merge remote-tracking branch 'origin/5.10' into dev
Conflicts: .qmake.conf src/qml/memory/qv4mm.cpp src/qml/qml/qqmlbinding.cpp Change-Id: I98e51ef5af12691196da5772a07d3d53d213efcc
Diffstat (limited to 'src/qml/memory')
-rw-r--r--src/qml/memory/qv4mm.cpp39
-rw-r--r--src/qml/memory/qv4mm_p.h12
-rw-r--r--src/qml/memory/qv4mmdefs_p.h2
3 files changed, 36 insertions, 17 deletions
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 3ea7908e9d..08d7228ee9 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -290,7 +290,8 @@ static void increaseFreedCountForClass(const char *className)
(*freedObjectStatsGlobal())[className]++;
}
-bool Chunk::sweep(ClassDestroyStatsCallback classCountPtr)
+//bool Chunk::sweep(ClassDestroyStatsCallback classCountPtr)
+bool Chunk::sweep(ExecutionEngine *engine)
{
bool hasUsedSlots = false;
SDUMP() << "sweeping chunk" << this;
@@ -329,13 +330,16 @@ bool Chunk::sweep(ClassDestroyStatsCallback classCountPtr)
HeapItem *itemToFree = o + index;
Heap::Base *b = *itemToFree;
const VTable *v = b->vtable();
- if (Q_UNLIKELY(classCountPtr))
- classCountPtr(v->className);
+// if (Q_UNLIKELY(classCountPtr))
+// classCountPtr(v->className);
if (v->destroy) {
v->destroy(b);
b->_checkIsDestroyed();
}
}
+ Q_V4_PROFILE_DEALLOC(engine, qPopulationCount((objectBitmap[i] | extendsBitmap[i])
+ - (blackBitmap[i] | e)) * Chunk::SlotSize,
+ Profiling::SmallItem);
objectBitmap[i] = blackBitmap[i];
grayBitmap[i] = 0;
hasUsedSlots |= (blackBitmap[i] != 0);
@@ -350,7 +354,7 @@ bool Chunk::sweep(ClassDestroyStatsCallback classCountPtr)
return hasUsedSlots;
}
-void Chunk::freeAll()
+void Chunk::freeAll(ExecutionEngine *engine)
{
// DEBUG << "sweeping chunk" << this << (*freeList);
HeapItem *o = realBase();
@@ -381,6 +385,8 @@ void Chunk::freeAll()
b->_checkIsDestroyed();
}
}
+ Q_V4_PROFILE_DEALLOC(engine, (qPopulationCount(objectBitmap[i]|extendsBitmap[i])
+ - qPopulationCount(e)) * Chunk::SlotSize, Profiling::SmallItem);
objectBitmap[i] = 0;
grayBitmap[i] = 0;
extendsBitmap[i] = e;
@@ -578,6 +584,7 @@ HeapItem *BlockAllocator::allocate(size_t size, bool forceAllocation) {
if (!forceAllocation)
return 0;
Chunk *newChunk = chunkAllocator->allocate();
+ Q_V4_PROFILE_ALLOC(engine, Chunk::DataSize, Profiling::HeapPage);
chunks.push_back(newChunk);
nextFree = newChunk->first();
nFree = Chunk::AvailableSlots;
@@ -588,11 +595,12 @@ HeapItem *BlockAllocator::allocate(size_t size, bool forceAllocation) {
done:
m->setAllocatedSlots(slotsRequired);
+ Q_V4_PROFILE_ALLOC(engine, slotsRequired * Chunk::SlotSize, Profiling::SmallItem);
// DEBUG << " " << hex << m->chunk() << m->chunk()->objectBitmap[0] << m->chunk()->extendsBitmap[0] << (m - m->chunk()->realBase());
return m;
}
-void BlockAllocator::sweep(ClassDestroyStatsCallback classCountPtr)
+void BlockAllocator::sweep()
{
nextFree = 0;
nFree = 0;
@@ -601,13 +609,14 @@ void BlockAllocator::sweep(ClassDestroyStatsCallback classCountPtr)
// qDebug() << "BlockAlloc: sweep";
usedSlotsAfterLastSweep = 0;
- auto isFree = [this, classCountPtr] (Chunk *c) {
- bool isUsed = c->sweep(classCountPtr);
+ auto isFree = [this] (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);
}
return !isUsed;
@@ -620,7 +629,8 @@ void BlockAllocator::sweep(ClassDestroyStatsCallback classCountPtr)
void BlockAllocator::freeAll()
{
for (auto c : chunks) {
- c->freeAll();
+ c->freeAll(engine);
+ Q_V4_PROFILE_DEALLOC(engine, Chunk::DataSize, Profiling::HeapPage);
chunkAllocator->free(c);
}
}
@@ -673,6 +683,7 @@ HeapItem *HugeItemAllocator::allocate(size_t size) {
Chunk *c = chunkAllocator->allocate(size);
chunks.push_back(HugeChunk{c, size});
Chunk::setBit(c->objectBitmap, c->first() - c->realBase());
+ Q_V4_PROFILE_ALLOC(engine, size, Profiling::LargeItem);
return c->first();
}
@@ -695,8 +706,11 @@ void HugeItemAllocator::sweep(ClassDestroyStatsCallback classCountPtr)
{
auto isBlack = [this, classCountPtr] (const HugeChunk &c) {
bool b = c.chunk->first()->isBlack();
- if (!b)
+ Chunk::clearBit(c.chunk->blackBitmap, c.chunk->first() - c.chunk->realBase());
+ if (!b) {
+ Q_V4_PROFILE_DEALLOC(engine, c.size, Profiling::LargeItem);
freeHugeChunk(chunkAllocator, c, classCountPtr);
+ }
return !b;
};
@@ -725,6 +739,7 @@ void HugeItemAllocator::collectGrayItems(MarkStack *markStack)
void HugeItemAllocator::freeAll()
{
for (auto &c : chunks) {
+ Q_V4_PROFILE_DEALLOC(engine, c.size, Profiling::LargeItem);
freeHugeChunk(chunkAllocator, c, nullptr);
}
}
@@ -733,8 +748,8 @@ void HugeItemAllocator::freeAll()
MemoryManager::MemoryManager(ExecutionEngine *engine)
: engine(engine)
, chunkAllocator(new ChunkAllocator)
- , blockAllocator(chunkAllocator)
- , hugeItemAllocator(chunkAllocator)
+ , blockAllocator(chunkAllocator, engine)
+ , hugeItemAllocator(chunkAllocator, engine)
, m_persistentValues(new PersistentValueStorage(engine))
, m_weakValues(new PersistentValueStorage(engine))
, unmanagedHeapSizeGCLimit(MIN_UNMANAGED_HEAPSIZE_GC_LIMIT)
@@ -992,7 +1007,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
}
}
- blockAllocator.sweep(classCountPtr);
+ blockAllocator.sweep();
hugeItemAllocator.sweep(classCountPtr);
}
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index f7c50ff3cf..058cbe28cc 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -73,8 +73,8 @@ namespace QV4 {
struct ChunkAllocator;
struct BlockAllocator {
- BlockAllocator(ChunkAllocator *chunkAllocator)
- : chunkAllocator(chunkAllocator)
+ BlockAllocator(ChunkAllocator *chunkAllocator, ExecutionEngine *engine)
+ : chunkAllocator(chunkAllocator), engine(engine)
{
memset(freeBins, 0, sizeof(freeBins));
#if MM_DEBUG
@@ -108,7 +108,7 @@ struct BlockAllocator {
return used;
}
- void sweep(ClassDestroyStatsCallback classCountPtr);
+ void sweep();
void freeAll();
void resetBlackBits();
void collectGrayItems(MarkStack *markStack);
@@ -119,6 +119,7 @@ struct BlockAllocator {
size_t usedSlotsAfterLastSweep = 0;
HeapItem *freeBins[NumBins];
ChunkAllocator *chunkAllocator;
+ ExecutionEngine *engine;
std::vector<Chunk *> chunks;
#if MM_DEBUG
uint allocations[NumBins];
@@ -126,8 +127,8 @@ struct BlockAllocator {
};
struct HugeItemAllocator {
- HugeItemAllocator(ChunkAllocator *chunkAllocator)
- : chunkAllocator(chunkAllocator)
+ HugeItemAllocator(ChunkAllocator *chunkAllocator, ExecutionEngine *engine)
+ : chunkAllocator(chunkAllocator), engine(engine)
{}
HeapItem *allocate(size_t size);
@@ -144,6 +145,7 @@ struct HugeItemAllocator {
}
ChunkAllocator *chunkAllocator;
+ ExecutionEngine *engine;
struct HugeChunk {
Chunk *chunk;
size_t size;
diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h
index 6d911e69f6..12d71364e1 100644
--- a/src/qml/memory/qv4mmdefs_p.h
+++ b/src/qml/memory/qv4mmdefs_p.h
@@ -190,6 +190,8 @@ struct Chunk {
void freeAll();
void resetBlackBits();
void collectGrayItems(QV4::MarkStack *markStack);
+ bool sweep(ExecutionEngine *engine);
+ void freeAll(ExecutionEngine *engine);
void sortIntoBins(HeapItem **bins, uint nBins);
};