diff options
author | Lars Knoll <lars.knoll@theqtcompany.com> | 2015-08-07 13:56:31 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@theqtcompany.com> | 2015-08-10 07:24:32 +0000 |
commit | 415f55d1400f6abdd3a8e3edaf5ff208ecdad216 (patch) | |
tree | 88e75e6c2b5d3b757ac59b644f71410158201354 /src/qml/memory | |
parent | f21e8c641af6b2d10f0d7e7e0fc6a755dab3673c (diff) |
Encapsulate and protect all accesses to the vtable of Heap objects
This is required, so we can safely access the vtable even while
we're marking objects during GC.
Change-Id: I34f56b61b4bca0d0742faf607eb5ab8b2c30685e
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/qml/memory')
-rw-r--r-- | src/qml/memory/qv4heap_p.h | 11 | ||||
-rw-r--r-- | src/qml/memory/qv4mm.cpp | 14 | ||||
-rw-r--r-- | src/qml/memory/qv4mm_p.h | 2 |
3 files changed, 14 insertions, 13 deletions
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h index 606fd47cbb..a93e4191b0 100644 --- a/src/qml/memory/qv4heap_p.h +++ b/src/qml/memory/qv4heap_p.h @@ -60,10 +60,7 @@ struct VTable namespace Heap { struct Q_QML_EXPORT Base { - union { - const VTable *vtable; - quintptr mm_data; - }; + quintptr mm_data; // vtable and markbit inline ReturnedValue asReturnedValue() const; inline void mark(QV4::ExecutionEngine *engine); @@ -74,7 +71,11 @@ struct Q_QML_EXPORT Base { PointerMask = ~0x3 }; - VTable *gcGetVtable() const { + void setVtable(const VTable *v) { + Q_ASSERT(!(mm_data & MarkBit)); + mm_data = reinterpret_cast<quintptr>(v); + } + VTable *vtable() const { return reinterpret_cast<VTable *>(mm_data & PointerMask); } inline bool isMarked() const { diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 7dbf12ff11..7e75570af3 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -183,8 +183,8 @@ bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, Exec #ifdef V4_USE_VALGRIND VALGRIND_ENABLE_ERROR_REPORTING; #endif - if (m->gcGetVtable()->destroy) - m->gcGetVtable()->destroy(m); + if (m->vtable()->destroy) + m->vtable()->destroy(m); memset(m, 0, header->itemSize); #ifdef V4_USE_VALGRIND @@ -324,8 +324,8 @@ static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase) { while (engine->jsStackTop > markBase) { Heap::Base *h = engine->popForGC(); - Q_ASSERT (h->gcGetVtable()->markObjects); - h->gcGetVtable()->markObjects(h, engine); + Q_ASSERT (h->vtable()->markObjects); + h->vtable()->markObjects(h, engine); } } @@ -348,7 +348,7 @@ void MemoryManager::mark() for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) { if (!(*it).isManaged()) continue; - if ((*it).managed()->d()->gcGetVtable() != QObjectWrapper::staticVTable()) + if ((*it).managed()->d()->vtable() != QObjectWrapper::staticVTable()) continue; QObjectWrapper *qobjectWrapper = static_cast<QObjectWrapper*>((*it).managed()); if (!qobjectWrapper) @@ -444,8 +444,8 @@ void MemoryManager::sweep(bool lastSweep) i = i->next; continue; } - if (m->gcGetVtable()->destroy) - m->gcGetVtable()->destroy(m); + if (m->vtable()->destroy) + m->vtable()->destroy(m); *last = i->next; free(Q_V4_PROFILE_DEALLOC(m_d->engine, i, i->size + sizeof(Data::LargeItem), diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h index 422809ba54..a7b4e6ef4e 100644 --- a/src/qml/memory/qv4mm_p.h +++ b/src/qml/memory/qv4mm_p.h @@ -87,7 +87,7 @@ public: { size = align(size); Heap::Base *o = allocData(size); - o->vtable = ManagedType::staticVTable(); + o->setVtable(ManagedType::staticVTable()); return static_cast<typename ManagedType::Data *>(o); } |