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:
parent
0e51ac4d87
commit
fb11343a07
31
qv4mm.cpp
31
qv4mm.cpp
|
@ -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;
|
||||
|
|
9
qv4mm.h
9
qv4mm.h
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue