From fb11343a072ddc67518df0946ff58a6c4d9e8041 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 28 Jan 2013 13:32:08 +0100 Subject: [PATCH] Add a mechanism to protect managed objects from deletion MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I6700dc94ad481e12ee7f00c04c0c37261e22a715 Reviewed-by: Jędrzej Nowacki --- qv4mm.cpp | 31 +++++++++++++++++++++++-------- qv4mm.h | 9 ++++++--- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/qv4mm.cpp b/qv4mm.cpp index e4f1fbe..71e6def 100644 --- a/qv4mm.cpp +++ b/qv4mm.cpp @@ -64,6 +64,7 @@ struct MemoryManager::Data }; QVector heapChunks; + QHash 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 &objects) +void MemoryManager::mark(const QVector &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 roots; + QVector 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 &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 &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 &roots) const +void MemoryManager::collectRoots(QVector &roots) const { add(roots, m_d->engine->globalObject); add(roots, m_d->engine->exception); @@ -342,9 +354,12 @@ void MemoryManager::collectRoots(QVector &roots) const } collectRootsOnStack(roots); + + for (QHash::const_iterator it = m_d->protectedObject.begin(); it != m_d->protectedObject.constEnd(); ++it) + roots.append(it.key()); } -void MemoryManager::collectRootsOnStack(QVector &roots) const +void MemoryManager::collectRootsOnStack(QVector &roots) const { if (!m_d->heapChunks.count()) return; diff --git a/qv4mm.h b/qv4mm.h index 0dd3e61..07c6e95 100644 --- a/qv4mm.h +++ b/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 &roots) const; + void collectRootsOnStack(QVector &roots) const; ExecutionEngine *engine() const; @@ -110,8 +113,8 @@ protected: #endif // DETAILED_MM_STATS private: - void collectRoots(QVector &roots) const; - static void mark(const QVector &objects); + void collectRoots(QVector &roots) const; + static void mark(const QVector &objects); std::size_t sweep(); std::size_t sweep(char *chunkStart, std::size_t chunkSize, size_t size); -- 2.7.4