diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-02-08 16:21:02 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-03-09 08:59:20 +0000 |
commit | 2a554434a571dcefd26cf10ef8c5ae8b3b7d66db (patch) | |
tree | 5532f0a0206fbbde0a3099ff1e0ee58188a97275 /src/qml/jit/qv4assembler.cpp | |
parent | 05de4e044f92dd278a00e410be8f070bc4d66e6f (diff) |
Implement a real write barrier
Implement a Steel write barrier for our objects. The barrier is
interesting as it can also be used for incremental GC runs by
simply turning the barrier on and leaving old objects marked as
black.
Change-Id: I0b273974d94a990dee3cd9298089b8b202c75bf2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jit/qv4assembler.cpp')
-rw-r--r-- | src/qml/jit/qv4assembler.cpp | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index 59470aeea2..687c35adfa 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -271,22 +271,28 @@ template <typename TargetConfiguration> typename Assembler<TargetConfiguration>::Pointer Assembler<TargetConfiguration>::loadArgLocalAddressForWriting(RegisterID baseReg, IR::ArgLocal *al, WriteBarrier::Type *barrier) { + if (barrier) + *barrier = _function->argLocalRequiresWriteBarrier(al) ? WriteBarrier::Barrier : WriteBarrier::NoBarrier; + int32_t offset = 0; int scope = al->scope; loadPtr(Address(EngineRegister, qOffsetOf(ExecutionEngine, current)), baseReg); - if (scope) { + while (scope) { loadPtr(Address(baseReg, qOffsetOf(ExecutionContext::Data, outer)), baseReg); --scope; - while (scope) { - loadPtr(Address(baseReg, qOffsetOf(ExecutionContext::Data, outer)), baseReg); - --scope; - } } switch (al->kind) { case IR::ArgLocal::Formal: case IR::ArgLocal::ScopedFormal: { - loadPtr(Address(baseReg, qOffsetOf(ExecutionContext::Data, callData)), baseReg); - offset = sizeof(CallData) + (al->index - 1) * sizeof(Value); + if (barrier && *barrier == WriteBarrier::Barrier) { + // if we need a barrier, the baseReg has to point to the ExecutionContext + // callData comes directly after locals, calculate the offset using that + offset = qOffsetOf(CallContext::Data, locals.values) + _function->localsCountForScope(al) * sizeof(Value); + offset += sizeof(CallData) + (al->index - 1) * sizeof(Value); + } else { + loadPtr(Address(baseReg, qOffsetOf(ExecutionContext::Data, callData)), baseReg); + offset = sizeof(CallData) + (al->index - 1) * sizeof(Value); + } } break; case IR::ArgLocal::Local: case IR::ArgLocal::ScopedLocal: { @@ -295,8 +301,6 @@ Assembler<TargetConfiguration>::loadArgLocalAddressForWriting(RegisterID baseReg default: Q_UNREACHABLE(); } - if (barrier) - *barrier = _function->argLocalRequiresWriteBarrier(al) ? WriteBarrier::Barrier : WriteBarrier::NoBarrier; return Pointer(baseReg, offset); } |