Simplify handling of non GC managed heap data
Let the destroy() method in QV4::String clean up the unmanaged heap size instead of having a special hook in the code that sweeps the GC heap. Change-Id: I989ee99604f0cc67b896d3acc94e200dd5e56a60 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
parent
2f16dd7b14
commit
94e6106d35
|
@ -114,6 +114,15 @@ void Heap::String::init(MemoryManager *mm, String *l, String *r)
|
||||||
simplifyString();
|
simplifyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Heap::String::destroy() {
|
||||||
|
if (!largestSubLength) {
|
||||||
|
mm->changeUnmanagedHeapSizeUsage(qptrdiff(-text->size) * (int)sizeof(QChar));
|
||||||
|
if (!text->ref.deref())
|
||||||
|
QStringData::deallocate(text);
|
||||||
|
}
|
||||||
|
Base::destroy();
|
||||||
|
}
|
||||||
|
|
||||||
uint String::toUInt(bool *ok) const
|
uint String::toUInt(bool *ok) const
|
||||||
{
|
{
|
||||||
*ok = true;
|
*ok = true;
|
||||||
|
@ -152,7 +161,7 @@ void Heap::String::simplifyString() const
|
||||||
text->ref.ref();
|
text->ref.ref();
|
||||||
identifier = 0;
|
identifier = 0;
|
||||||
largestSubLength = 0;
|
largestSubLength = 0;
|
||||||
mm->growUnmanagedHeapSizeUsage(size_t(text->size) * sizeof(QChar));
|
mm->changeUnmanagedHeapSizeUsage(qptrdiff(text->size) * (qptrdiff)sizeof(QChar));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heap::String::append(const String *data, QChar *ch)
|
void Heap::String::append(const String *data, QChar *ch)
|
||||||
|
|
|
@ -73,11 +73,7 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
|
||||||
#ifndef V4_BOOTSTRAP
|
#ifndef V4_BOOTSTRAP
|
||||||
void init(MemoryManager *mm, const QString &text);
|
void init(MemoryManager *mm, const QString &text);
|
||||||
void init(MemoryManager *mm, String *l, String *n);
|
void init(MemoryManager *mm, String *l, String *n);
|
||||||
void destroy() {
|
void destroy();
|
||||||
if (!largestSubLength && !text->ref.deref())
|
|
||||||
QStringData::deallocate(text);
|
|
||||||
Base::destroy();
|
|
||||||
}
|
|
||||||
void simplifyString() const;
|
void simplifyString() const;
|
||||||
int length() const {
|
int length() const {
|
||||||
Q_ASSERT((largestSubLength &&
|
Q_ASSERT((largestSubLength &&
|
||||||
|
|
|
@ -194,10 +194,8 @@ struct MemoryManager::Data
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, ExecutionEngine *engine, std::size_t *unmanagedHeapSize)
|
bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, ExecutionEngine *engine)
|
||||||
{
|
{
|
||||||
Q_ASSERT(unmanagedHeapSize);
|
|
||||||
|
|
||||||
bool isEmpty = true;
|
bool isEmpty = true;
|
||||||
Heap::Base *tail = &header->freeItems;
|
Heap::Base *tail = &header->freeItems;
|
||||||
// qDebug("chunkStart @ %p, size=%x, pos=%x", header->itemStart, header->itemSize, header->itemSize>>4);
|
// qDebug("chunkStart @ %p, size=%x, pos=%x", header->itemStart, header->itemSize, header->itemSize>>4);
|
||||||
|
@ -222,13 +220,6 @@ bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, Exec
|
||||||
#ifdef V4_USE_VALGRIND
|
#ifdef V4_USE_VALGRIND
|
||||||
VALGRIND_ENABLE_ERROR_REPORTING;
|
VALGRIND_ENABLE_ERROR_REPORTING;
|
||||||
#endif
|
#endif
|
||||||
if (std::size_t(header->itemSize) == MemoryManager::align(sizeof(Heap::String)) && m->vtable()->isString) {
|
|
||||||
std::size_t heapBytes = static_cast<Heap::String *>(m)->retainedTextSize();
|
|
||||||
Q_ASSERT(*unmanagedHeapSize >= heapBytes);
|
|
||||||
// qDebug() << "-- it's a string holding on to" << heapBytes << "bytes";
|
|
||||||
*unmanagedHeapSize -= heapBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m->vtable()->destroy) {
|
if (m->vtable()->destroy) {
|
||||||
m->vtable()->destroy(m);
|
m->vtable()->destroy(m);
|
||||||
m->_checkIsDestroyed();
|
m->_checkIsDestroyed();
|
||||||
|
@ -502,7 +493,7 @@ void MemoryManager::sweep(bool lastSweep)
|
||||||
|
|
||||||
for (size_t i = 0; i < m_d->heapChunks.size(); ++i) {
|
for (size_t i = 0; i < m_d->heapChunks.size(); ++i) {
|
||||||
Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(m_d->heapChunks[i].base());
|
Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(m_d->heapChunks[i].base());
|
||||||
chunkIsEmpty[i] = sweepChunk(header, &itemsInUse[header->itemSize >> 4], engine, &m_d->unmanagedHeapSize);
|
chunkIsEmpty[i] = sweepChunk(header, &itemsInUse[header->itemSize >> 4], engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PageAllocation>::iterator chunkIter = m_d->heapChunks.begin();
|
std::vector<PageAllocation>::iterator chunkIter = m_d->heapChunks.begin();
|
||||||
|
@ -642,7 +633,7 @@ size_t MemoryManager::getLargeItemsMem() const
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::growUnmanagedHeapSizeUsage(size_t delta)
|
void MemoryManager::changeUnmanagedHeapSizeUsage(qptrdiff delta)
|
||||||
{
|
{
|
||||||
m_d->unmanagedHeapSize += delta;
|
m_d->unmanagedHeapSize += delta;
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,7 +297,7 @@ public:
|
||||||
size_t getAllocatedMem() const;
|
size_t getAllocatedMem() const;
|
||||||
size_t getLargeItemsMem() const;
|
size_t getLargeItemsMem() const;
|
||||||
|
|
||||||
void growUnmanagedHeapSizeUsage(size_t delta); // called when a JS object grows itself. Specifically: Heap::String::append
|
void changeUnmanagedHeapSizeUsage(qptrdiff delta); // called when a JS object grows itself. Specifically: Heap::String::append
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// expects size to be aligned
|
/// expects size to be aligned
|
||||||
|
|
Loading…
Reference in New Issue