aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2020-04-21 12:01:29 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-05-22 15:30:47 +0200
commit1ec8e51159d2c76dc55ab4d79369d174bfecf665 (patch)
treec79634696319a40ac868b30369ef19dd2c98b1f4
parent9029fdcaa69d498c9607d794df41cbcbf1d1c767 (diff)
Fix failing assertion in the GC with the JIT
Commit db3dd029d7cd911712102efd5ea71868494f9f6f introduced the saving of the accumulator register on the JS stack in more situations. This unveiled another bug: When the physical ACC register contains garbage, we may end up saving it on the stack and thus making it visible to the GC. That one may trip with the infamous Q_ASSERT(m->inUse()) assertion failing when the value looks like a managed pointer but in fact isn't. So the question is: How can garbage end up in the physical ACC register? Thanks to a detailed bug report from David Faure, KDE's ktexteditor kateindenttest (testCstyle:comma6 in particular) triggered this situation when run with aggressive GC, where the prologue of a generated constructor function started with two instructions CreateCallContext ConvertThisToObject The first instruction is a call into the run-time with CallResultDestination::Ignore - it's a "void" call. The second instruction starts with STORE_ACC and also ends up allocating memory, triggering the GC when run with aggressive mode enabled. The problem here is the ::Ignore option for the return value. It means that the ReturnValueRegister is clobbered and may contain anything. If the ReturnValueRegister is the same as the AccumulatorRegister, then the STORE_ACC call later will end up writing "garbage" into the JS stack. As a remedy, this patch treats the ::Ignore case special and loads undefined into the ACC when the return value register and the ACC register are the same. Change-Id: I82c7a3456125f9c87e83abb9eb54465106873560 Task-number: QTBUG-83384 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit d4edf441257b7e5782a6c25802d821647ffcba45)
-rw-r--r--src/qml/jit/qv4baselineassembler.cpp4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp
index 3a46500423..c64f1406b5 100644
--- a/src/qml/jit/qv4baselineassembler.cpp
+++ b/src/qml/jit/qv4baselineassembler.cpp
@@ -91,6 +91,8 @@ public:
PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
if (dest == CallResultDestination::InAccumulator)
saveReturnValueInAccumulator();
+ else if (AccumulatorRegister == ReturnValueRegister)
+ loadUndefined();
}
void saveReturnValueInAccumulator()
@@ -391,6 +393,8 @@ public:
PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
if (dest == CallResultDestination::InAccumulator)
saveReturnValueInAccumulator();
+ else if (AccumulatorRegisterValue == ReturnValueRegisterValue)
+ loadUndefined();
}
void saveReturnValueInAccumulator()