diff options
authorSimon Hausmann <simon.hausmann@qt.io>2017-01-06 09:22:27 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2017-01-06 10:09:42 +0000
commitfffb997e192a72b4dcd66edc2fbad5473dd359f3 (patch)
parent884d06db09bc6179baa3add42ff4ef5f3cd0e523 (diff)
Fix incorrect JavaScript evaluation with the JITv5.8.0
This is a regression from commit 7e14b531b294650733a61a9365eb9ef74f8a7a90, that replaced a QHash<temp, liveInterval> with a vector of intervals. When an interval is split, it may happen that during one interval a temp is stored in a register and in the second interval it ends up in a different register or the stack. The _liveIntervals variable, formerly the _intervalForTemp hash, tracked the intervals per temp when going through the basic blocks and statements during the renumbering phase. Indexing uniquely by temp is important therefore for _liveIntervals and addNewIntervals violated that by replacing the QHash replacement _intervalForTemp[i->temp()] = i; with _liveIntervals.push_back(i); This is how we may end up with multiple intervals for the same temp (in different locations), and when doing the linear lookup we'd only find the first. Restoring the replacement behavior and thus ensuring uniqueness by temp fixes the miscompilations. Task-number: QTBUG-57779 Change-Id: Ib8f53672b66750f68e16e47794dbc5f39989e1a2 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
1 files changed, 9 insertions, 1 deletions
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
index 406b9096ea..b168a1e2ba 100644
--- a/src/qml/jit/qv4regalloc.cpp
+++ b/src/qml/jit/qv4regalloc.cpp
@@ -969,7 +969,15 @@ private:
- _liveIntervals.push_back(i);
+ auto it = _liveIntervals.begin();
+ for (; it != _liveIntervals.end(); ++it) {
+ if ((*it)->temp() == i->temp()) {
+ *it = i;
+ break;
+ }
+ }
+ if (it == _liveIntervals.end())
+ _liveIntervals.push_back(i);
// qDebug() << "-- Activating interval for temp" << i->temp().index;