diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-04-04 10:35:45 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-04-07 12:47:04 +0000 |
commit | fdb1a7da37e2482a22ca32d52e2833bf67d90bc9 (patch) | |
tree | 796ab2b16a4fe42c9fb114c8e6fc3872bd929ccb | |
parent | b361a59c699fca02379c149cf0b9c59490a1ba62 (diff) |
Cleanups: Remove Steele barrier code
Remove the code related to the Steele write barrier and incremental
garbage collection.
This is in preparation for a fully concurrent GC, that will not have
and incremental mode and will use a Yuasa write barrier.
Change-Id: I155a85211c5be61e792e056321fbceaee47c0d87
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 10 | ||||
-rw-r--r-- | src/qml/jit/qv4assembler_p.h | 26 | ||||
-rw-r--r-- | src/qml/jsapi/qjsengine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4identifiertable.cpp | 1 | ||||
-rw-r--r-- | src/qml/memory/qv4mm.cpp | 62 | ||||
-rw-r--r-- | src/qml/memory/qv4mm_p.h | 3 | ||||
-rw-r--r-- | src/qml/memory/qv4writebarrier_p.h | 38 | ||||
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 2 |
8 files changed, 13 insertions, 131 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 7940e5715e..adc36ff1dd 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -125,10 +125,8 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine) runtimeStrings = (QV4::Heap::String **)malloc(data->stringTableSize * sizeof(QV4::Heap::String*)); // memset the strings to 0 in case a GC run happens while we're within the loop below memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::Heap::String*)); - for (uint i = 0; i < data->stringTableSize; ++i) { + for (uint i = 0; i < data->stringTableSize; ++i) runtimeStrings[i] = engine->newIdentifier(data->stringAt(i)); - runtimeStrings[i]->setMarkBit(); - } runtimeRegularExpressions = new QV4::Value[data->regexpTableSize]; // memset the regexps to 0 in case a GC run happens while we're within the loop below @@ -144,12 +142,6 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine) flags |= IR::RegExp::RegExp_Multiline; QV4::Heap::RegExpObject *ro = engine->newRegExpObject(data->stringAt(re->stringIndex), flags); runtimeRegularExpressions[i] = ro; -#if WRITEBARRIER(steele) - if (engine->memoryManager->nextGCIsIncremental) { - ro->setMarkBit(); - ro->setGrayBit(); - } -#endif } if (data->lookupTableSize) { diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index d4a18ae886..8aa9d81ba2 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -189,18 +189,7 @@ struct RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatfo as->pop(TargetPlatform::EngineRegister); } -#if WRITEBARRIER(steele) - static void emitWriteBarrier(JITAssembler *as, Address addr) - { -// RegisterID test = addr.base == TargetPlatform::ReturnValueRegister ? TargetPlatform::ScratchRegister : TargetPlatform::ReturnValueRegister; - // if (engine->writeBarrier) -// as->load8(Address(TargetPlatform::EngineRegister, offsetof(EngineBase, writeBarrierActive)), test); -// typename JITAssembler::Jump jump = as->branch32(JITAssembler::Equal, test, TrustedImm32(0)); - // ### emit fence - emitSetGrayBit(as, addr.base); -// jump.link(as); - } -#elif WRITEBARRIER(none) +#if WRITEBARRIER(none) static Q_ALWAYS_INLINE void emitWriteBarrier(JITAssembler *, Address) {} #endif @@ -487,18 +476,7 @@ struct RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatfo as->pop(TargetPlatform::EngineRegister); } -#if WRITEBARRIER(steele) - static void emitWriteBarrier(JITAssembler *as, Address addr) - { -// RegisterID test = addr.base == TargetPlatform::ReturnValueRegister ? TargetPlatform::ScratchRegister : TargetPlatform::ReturnValueRegister; - // if (engine->writeBarrier) -// as->load8(Address(TargetPlatform::EngineRegister, offsetof(EngineBase, writeBarrierActive)), test); -// typename JITAssembler::Jump jump = as->branch32(JITAssembler::Equal, test, TrustedImm32(0)); - // ### emit fence - emitSetGrayBit(as, addr.base); -// jump.link(as); - } -#elif WRITEBARRIER(none) +#if WRITEBARRIER(none) static Q_ALWAYS_INLINE void emitWriteBarrier(JITAssembler *, Address) {} #endif diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index b52c859ecb..e4c150057a 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -333,7 +333,7 @@ QJSEngine::~QJSEngine() */ void QJSEngine::collectGarbage() { - d->m_v4Engine->memoryManager->runGC(/* forceFullCollection = */ true); + d->m_v4Engine->memoryManager->runGC(); } #if QT_DEPRECATED_SINCE(5, 6) diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp index d3ef238716..3def6defbf 100644 --- a/src/qml/jsruntime/qv4identifiertable.cpp +++ b/src/qml/jsruntime/qv4identifiertable.cpp @@ -81,7 +81,6 @@ void IdentifierTable::addEntry(Heap::String *str) str->identifier = new Identifier; str->identifier->string = str->toQString(); str->identifier->hashValue = hash; - str->setMarkBit(); bool grow = (alloc <= size*2); diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index aebbc07826..7c57b93d9b 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -931,8 +931,7 @@ void MarkStack::drain() void MemoryManager::collectRoots(MarkStack *markStack) { - if (!nextGCIsIncremental) - engine->markObjects(markStack); + engine->markObjects(markStack); // qDebug() << " mark stack after engine->mark" << (engine->jsStackTop - markBase); @@ -982,23 +981,11 @@ void MemoryManager::mark() MarkStack markStack(engine); collectRoots(&markStack); - if (nextGCIsIncremental) { - // need to collect all gray items and push them onto the mark stack - blockAllocator.collectGrayItems(&markStack); - hugeItemAllocator.collectGrayItems(&markStack); - } - markStack.drain(); } void MemoryManager::sweep(bool lastSweep) { - if (lastSweep && nextGCIsIncremental) { - // ensure we properly clean up on destruction even if the GC is in incremental mode - blockAllocator.resetBlackBits(); - hugeItemAllocator.resetBlackBits(); - } - for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) { Managed *m = (*it).managed(); if (!m || m->markBit()) @@ -1077,20 +1064,13 @@ size_t dumpBins(BlockAllocator *b, bool printOutput = true) return totalSlotMem*Chunk::SlotSize; } -void MemoryManager::runGC(bool forceFullCollection) +void MemoryManager::runGC() { if (gcBlocked) { // qDebug() << "Not running GC."; return; } - if (forceFullCollection) { - // do a full GC - blockAllocator.resetBlackBits(); - hugeItemAllocator.resetBlackBits(); - nextGCIsIncremental = false; - } - QScopedValueRollback<bool> gcBlocker(gcBlocked, true); // qDebug() << "runGC"; @@ -1112,7 +1092,6 @@ void MemoryManager::runGC(bool forceFullCollection) qDebug() << " Allocations since last GC" << allocationCount; allocationCount = 0; #endif - qDebug() << "Incremental:" << nextGCIsIncremental; qDebug() << "Allocated" << totalMem << "bytes in" << blockAllocator.chunks.size() << "chunks"; qDebug() << "Fragmented memory before GC" << (totalMem - usedBefore); dumpBins(&blockAllocator); @@ -1138,10 +1117,6 @@ void MemoryManager::runGC(bool forceFullCollection) qDebug() << " unmanaged heap limit:" << unmanagedHeapSizeGCLimit; } size_t memInBins = dumpBins(&blockAllocator); -#ifdef MM_STATS - if (nextGCIsIncremental) - qDebug() << " number of gray items:" << nGrayItems; -#endif qDebug() << "Marked object in" << markTime << "us."; qDebug() << " " << markStackSize << "objects marked"; qDebug() << "Sweeped object in" << sweepTime << "us."; @@ -1164,36 +1139,11 @@ void MemoryManager::runGC(bool forceFullCollection) Q_ASSERT(blockAllocator.allocatedMem() == getUsedMem() + dumpBins(&blockAllocator, false)); } - if (!nextGCIsIncremental) - usedSlotsAfterLastFullSweep = blockAllocator.usedSlotsAfterLastSweep; + usedSlotsAfterLastFullSweep = blockAllocator.usedSlotsAfterLastSweep; -#if WRITEBARRIER(steele) - static int count = 0; - ++count; - if (aggressiveGC) { - nextGCIsIncremental = (count % 256); - } else { - size_t total = blockAllocator.totalSlots(); - size_t usedSlots = blockAllocator.usedSlotsAfterLastSweep; - if (!nextGCIsIncremental) { - // always try an incremental GC after a full one, unless there is anyway lots of memory pressure - nextGCIsIncremental = usedSlots * 4 < total * 3; - count = 0; - } else { - if (count > 16) - nextGCIsIncremental = false; - else - nextGCIsIncremental = usedSlots * 4 < total * 3; // less than 75% full - } - } -#else - nextGCIsIncremental = false; -#endif - if (!nextGCIsIncremental) { - // do a full GC - blockAllocator.resetBlackBits(); - hugeItemAllocator.resetBlackBits(); - } + // reset all black bits + blockAllocator.resetBlackBits(); + hugeItemAllocator.resetBlackBits(); } size_t MemoryManager::getUsedMem() const diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h index 1335ea59b6..76ffec42de 100644 --- a/src/qml/memory/qv4mm_p.h +++ b/src/qml/memory/qv4mm_p.h @@ -422,7 +422,7 @@ public: return t->d(); } - void runGC(bool forceFullCollection = false); + void runGC(); void dumpStats() const; @@ -467,7 +467,6 @@ public: bool gcBlocked = false; bool aggressiveGC = false; bool gcStats = false; - bool nextGCIsIncremental = false; }; } diff --git a/src/qml/memory/qv4writebarrier_p.h b/src/qml/memory/qv4writebarrier_p.h index a2f85822ca..e36ea0749a 100644 --- a/src/qml/memory/qv4writebarrier_p.h +++ b/src/qml/memory/qv4writebarrier_p.h @@ -55,7 +55,6 @@ QT_BEGIN_NAMESPACE -#define WRITEBARRIER_steele -1 #define WRITEBARRIER_none 1 #define WRITEBARRIER(x) (1/WRITEBARRIER_##x == 1) @@ -78,42 +77,7 @@ enum NewValueType { // ### this needs to be filled with a real memory fence once marking is concurrent Q_ALWAYS_INLINE void fence() {} -#if WRITEBARRIER(steele) - -template <NewValueType type> -static Q_CONSTEXPR inline bool isRequired() { - return type != Primitive; -} - -inline void write(EngineBase *engine, Heap::Base *base, Value *slot, Value value) -{ - Q_UNUSED(engine); - *slot = value; - if (isRequired<Unknown>()) { - fence(); - base->setGrayBit(); - } -} - -inline void write(EngineBase *engine, Heap::Base *base, Value *slot, Heap::Base *value) -{ - Q_UNUSED(engine); - *slot = value; - if (isRequired<Object>()) { - fence(); - base->setGrayBit(); - } -} - -inline void write(EngineBase *engine, Heap::Base *base, Heap::Base **slot, Heap::Base *value) -{ - Q_UNUSED(engine); - *slot = value; - fence(); - base->setGrayBit(); -} - -#elif WRITEBARRIER(none) +#if WRITEBARRIER(none) template <NewValueType type> static Q_CONSTEXPR inline bool isRequired() { diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 68a64a28f0..8cc0b32168 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -2019,7 +2019,7 @@ void GlobalExtensions::method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, void GlobalExtensions::method_gc(const BuiltinFunction *, Scope &scope, CallData *) { - scope.engine->memoryManager->runGC(/* forceFullCollection = */ true); + scope.engine->memoryManager->runGC(); scope.result = QV4::Encode::undefined(); } |