Add a mechanism to protect managed objects from deletion

Change-Id: I6700dc94ad481e12ee7f00c04c0c37261e22a715
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
This commit is contained in:
Lars Knoll 2013-01-28 13:32:08 +01:00 committed by Jędrzej Nowacki
parent 0e51ac4d87
commit fb11343a07
2 changed files with 29 additions and 11 deletions

View File

@ -64,6 +64,7 @@ struct MemoryManager::Data
};
QVector<Chunk> heapChunks;
QHash<Managed *, uint> protectedObject;
// statistics:
#ifdef DETAILED_MM_STATS
@ -165,12 +166,12 @@ void MemoryManager::scribble(Managed *obj, int c, int size) const
::memset((void *)(obj + 1), c, size - sizeof(Managed));
}
void MemoryManager::mark(const QVector<Object *> &objects)
void MemoryManager::mark(const QVector<Managed *> &objects)
{
foreach (Object *o, objects) {
if (!o)
foreach (Managed *m, objects) {
if (!m)
continue;
o->mark();
m->mark();
}
return;
@ -239,7 +240,7 @@ void MemoryManager::runGC()
// QTime t; t.start();
// qDebug() << ">>>>>>>>runGC";
QVector<Object *> roots;
QVector<Managed *> roots;
collectRoots(roots);
// std::cerr << "GC: found " << roots.size()
// << " roots in " << t.elapsed()
@ -268,7 +269,18 @@ MemoryManager::~MemoryManager()
sweep();
}
static inline void add(QVector<Object *> &values, const Value &v)
void MemoryManager::protect(Managed *m)
{
++m_d->protectedObject[m];
}
void MemoryManager::unprotect(Managed *m)
{
if (!--m_d->protectedObject[m])
m_d->protectedObject.remove(m);
}
static inline void add(QVector<Managed *> &values, const Value &v)
{
if (Object *o = v.asObject())
values.append(o);
@ -310,7 +322,7 @@ void MemoryManager::willAllocate(std::size_t size)
#endif // DETAILED_MM_STATS
void MemoryManager::collectRoots(QVector<VM::Object *> &roots) const
void MemoryManager::collectRoots(QVector<Managed *> &roots) const
{
add(roots, m_d->engine->globalObject);
add(roots, m_d->engine->exception);
@ -342,9 +354,12 @@ void MemoryManager::collectRoots(QVector<VM::Object *> &roots) const
}
collectRootsOnStack(roots);
for (QHash<Managed *, uint>::const_iterator it = m_d->protectedObject.begin(); it != m_d->protectedObject.constEnd(); ++it)
roots.append(it.key());
}
void MemoryManager::collectRootsOnStack(QVector<VM::Object *> &roots) const
void MemoryManager::collectRootsOnStack(QVector<VM::Managed *> &roots) const
{
if (!m_d->heapChunks.count())
return;

View File

@ -73,6 +73,9 @@ public:
MemoryManager();
~MemoryManager();
void protect(Managed *m);
void unprotect(Managed *m);
// TODO: this is only for 64bit (and x86 with SSE/AVX), so exend it for other architectures to be slightly more efficient (meaning, align on 8-byte boundaries).
// Note: all occurances of "16" in alloc/dealloc are also due to the alignment.
static inline std::size_t align(std::size_t size)
@ -101,7 +104,7 @@ protected:
void scribble(Managed *obj, int c, int size) const;
void collectRootsOnStack(QVector<VM::Object *> &roots) const;
void collectRootsOnStack(QVector<Managed *> &roots) const;
ExecutionEngine *engine() const;
@ -110,8 +113,8 @@ protected:
#endif // DETAILED_MM_STATS
private:
void collectRoots(QVector<VM::Object *> &roots) const;
static void mark(const QVector<Object *> &objects);
void collectRoots(QVector<VM::Managed *> &roots) const;
static void mark(const QVector<Managed *> &objects);
std::size_t sweep();
std::size_t sweep(char *chunkStart, std::size_t chunkSize, size_t size);