diff options
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); } |
