From fffb997e192a72b4dcd66edc2fbad5473dd359f3 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 6 Jan 2017 09:22:27 +0100 Subject: Fix incorrect JavaScript evaluation with the JIT This is a regression from commit 7e14b531b294650733a61a9365eb9ef74f8a7a90, that replaced a QHash 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 Reviewed-by: Robin Burchell --- src/qml/jit/qv4regalloc.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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(); -- cgit v1.2.3