diff options
Diffstat (limited to 'src/qml/memory')
-rw-r--r-- | src/qml/memory/qv4heap_p.h | 5 | ||||
-rw-r--r-- | src/qml/memory/qv4mm.cpp | 15 | ||||
-rw-r--r-- | src/qml/memory/qv4mm_p.h | 54 |
3 files changed, 52 insertions, 22 deletions
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h index 1ca37fe95f..f327388355 100644 --- a/src/qml/memory/qv4heap_p.h +++ b/src/qml/memory/qv4heap_p.h @@ -113,9 +113,9 @@ Q_STATIC_ASSERT(std::is_trivial< V4PointerCheck >::value); struct Q_QML_EXPORT Base { void *operator new(size_t) = delete; - static void markObjects(Base *, MarkStack *) {} + static void markObjects(Base *, MarkStack *); - InternalClass *internalClass; + Pointer<InternalClass *, 0> internalClass; inline ReturnedValue asReturnedValue() const; inline void mark(QV4::MarkStack *markStack); @@ -195,7 +195,6 @@ Q_STATIC_ASSERT(std::is_standard_layout<Base>::value); Q_STATIC_ASSERT(offsetof(Base, internalClass) == 0); Q_STATIC_ASSERT(sizeof(Base) == QT_POINTER_SIZE); - inline void Base::mark(QV4::MarkStack *markStack) { diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index fcc00ff331..06313c3d30 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -643,8 +643,9 @@ void BlockAllocator::sweep() void BlockAllocator::freeAll() { - for (auto c : chunks) { + for (auto c : chunks) c->freeAll(engine); + for (auto c : chunks) { Q_V4_PROFILE_DEALLOC(engine, Chunk::DataSize, Profiling::HeapPage); chunkAllocator->free(c); } @@ -758,6 +759,7 @@ MemoryManager::MemoryManager(ExecutionEngine *engine) : engine(engine) , chunkAllocator(new ChunkAllocator) , blockAllocator(chunkAllocator, engine) + , icAllocator(chunkAllocator, engine) , hugeItemAllocator(chunkAllocator, engine) , m_persistentValues(new PersistentValueStorage(engine)) , m_weakValues(new PersistentValueStorage(engine)) @@ -884,7 +886,7 @@ Heap::Object *MemoryManager::allocObjectWithMemberData(const QV4::VTable *vtable Chunk::clearBit(c->extendsBitmap, index); } o->memberData.set(engine, m); - m->internalClass = engine->internalClasses(EngineBase::Class_MemberData); + m->internalClass.set(engine, engine->internalClasses(EngineBase::Class_MemberData)); Q_ASSERT(o->memberData->internalClass); m->values.alloc = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value)); m->values.size = o->memberData->values.alloc; @@ -1017,8 +1019,11 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt } } - blockAllocator.sweep(); - hugeItemAllocator.sweep(classCountPtr); + if (!lastSweep) { + blockAllocator.sweep(/*classCountPtr*/); + hugeItemAllocator.sweep(classCountPtr); + icAllocator.sweep(/*classCountPtr*/); + } } bool MemoryManager::shouldRunGC() const @@ -1167,6 +1172,7 @@ void MemoryManager::runGC() // reset all black bits blockAllocator.resetBlackBits(); hugeItemAllocator.resetBlackBits(); + icAllocator.resetBlackBits(); } size_t MemoryManager::getUsedMem() const @@ -1193,6 +1199,7 @@ MemoryManager::~MemoryManager() sweep(/*lastSweep*/true); blockAllocator.freeAll(); hugeItemAllocator.freeAll(); + icAllocator.freeAll(); delete m_weakValues; #ifdef V4_USE_VALGRIND diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h index ae2153e7c4..bc9b7130c7 100644 --- a/src/qml/memory/qv4mm_p.h +++ b/src/qml/memory/qv4mm_p.h @@ -160,37 +160,52 @@ public: { return (size + Chunk::SlotSize - 1) & ~(Chunk::SlotSize - 1); } template<typename ManagedType> - inline typename ManagedType::Data *allocManaged(std::size_t size, InternalClass *ic) + inline typename ManagedType::Data *allocManaged(std::size_t size, Heap::InternalClass *ic) { Q_STATIC_ASSERT(std::is_trivial< typename ManagedType::Data >::value); size = align(size); - Heap::Base *o = allocData(size); - o->internalClass = ic; - Q_ASSERT(o->internalClass && o->internalClass->vtable); + typename ManagedType::Data *d = static_cast<typename ManagedType::Data *>(allocData(size)); + d->internalClass.set(engine, ic); + Q_ASSERT(d->internalClass && d->internalClass->vtable); Q_ASSERT(ic->vtable == ManagedType::staticVTable()); - return static_cast<typename ManagedType::Data *>(o); + return d; + } + + template<typename ManagedType> + inline typename ManagedType::Data *allocManaged(std::size_t size, InternalClass *ic) + { + return allocManaged<ManagedType>(size, ic->d()); } template<typename ManagedType> inline typename ManagedType::Data *allocManaged(std::size_t size) { - return allocManaged<ManagedType>(size, ManagedType::defaultInternalClass(engine)); + Scope scope(engine); + Scoped<InternalClass> ic(scope, ManagedType::defaultInternalClass(engine)); + return allocManaged<ManagedType>(size, ic); } template <typename ObjectType> - typename ObjectType::Data *allocateObject(InternalClass *ic) + typename ObjectType::Data *allocateObject(Heap::InternalClass *ic) { Heap::Object *o = allocObjectWithMemberData(ObjectType::staticVTable(), ic->size); - o->internalClass = ic; - Q_ASSERT(o->internalClass && o->internalClass->vtable); - Q_ASSERT(ic->vtable == ObjectType::staticVTable()); + o->internalClass.set(engine, ic); + Q_ASSERT(o->internalClass.get() && o->vtable()); + Q_ASSERT(o->vtable() == ObjectType::staticVTable()); return static_cast<typename ObjectType::Data *>(o); } template <typename ObjectType> + typename ObjectType::Data *allocateObject(InternalClass *ic) + { + return allocateObject<ObjectType>(ic->d()); + } + + template <typename ObjectType> typename ObjectType::Data *allocateObject() { - InternalClass *ic = ObjectType::defaultInternalClass(engine); + Scope scope(engine); + Scoped<InternalClass> ic(scope, ObjectType::defaultInternalClass(engine)); ic = ic->changeVTable(ObjectType::staticVTable()); ic = ic->changePrototype(ObjectType::defaultPrototype(engine)->d()); return allocateObject<ObjectType>(ic); @@ -200,18 +215,18 @@ public: typename ManagedType::Data *allocWithStringData(std::size_t unmanagedSize, Arg1 arg1) { typename ManagedType::Data *o = reinterpret_cast<typename ManagedType::Data *>(allocString(unmanagedSize)); - o->internalClass = ManagedType::defaultInternalClass(engine); + o->internalClass.set(engine, ManagedType::defaultInternalClass(engine)); Q_ASSERT(o->internalClass && o->internalClass->vtable); o->init(arg1); return o; } - template <typename ObjectType> - typename ObjectType::Data *allocObject(InternalClass *ic) + template <typename ObjectType, typename... Args> + typename ObjectType::Data *allocObject(Heap::InternalClass *ic, Args... args) { Scope scope(engine); Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic)); - t->d_unchecked()->init(); + t->d_unchecked()->init(args...); return t->d(); } @@ -253,6 +268,14 @@ public: // called when a JS object grows itself. Specifically: Heap::String::append void changeUnmanagedHeapSizeUsage(qptrdiff delta) { unmanagedHeapSize += delta; } + template<typename ManagedType> + typename ManagedType::Data *allocIC() + { + size_t size = align(sizeof(typename ManagedType::Data)); + Heap::Base *b = *icAllocator.allocate(size, true); + return static_cast<typename ManagedType::Data *>(b); + } + protected: /// expects size to be aligned Heap::Base *allocString(std::size_t unmanagedSize); @@ -270,6 +293,7 @@ public: QV4::ExecutionEngine *engine; ChunkAllocator *chunkAllocator; BlockAllocator blockAllocator; + BlockAllocator icAllocator; HugeItemAllocator hugeItemAllocator; PersistentValueStorage *m_persistentValues; PersistentValueStorage *m_weakValues; |