diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2017-01-06 09:22:27 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2017-01-06 10:09:42 +0000 |
commit | fffb997e192a72b4dcd66edc2fbad5473dd359f3 (patch) | |
tree | f6b465e797e7977d26cdb8902178dcb5f1787141 | |
parent | 884d06db09bc6179baa3add42ff4ef5f3cd0e523 (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>
-rw-r--r-- | src/qml/jit/qv4regalloc.cpp | 10 |
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: break; Q_ASSERT(!i->isFixedInterval()); - _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; _unprocessedReverseOrder.removeLast(); |