aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-04-04 10:35:45 +0200
committerLars Knoll <lars.knoll@qt.io>2017-04-07 12:47:04 +0000
commitfdb1a7da37e2482a22ca32d52e2833bf67d90bc9 (patch)
tree796ab2b16a4fe42c9fb114c8e6fc3872bd929ccb
parentb361a59c699fca02379c149cf0b9c59490a1ba62 (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.cpp10
-rw-r--r--src/qml/jit/qv4assembler_p.h26
-rw-r--r--src/qml/jsapi/qjsengine.cpp2
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp1
-rw-r--r--src/qml/memory/qv4mm.cpp62
-rw-r--r--src/qml/memory/qv4mm_p.h3
-rw-r--r--src/qml/memory/qv4writebarrier_p.h38
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
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();
}