[JSC] The register allocator can use a dangling pointer when selecting a spill candidate
https://bugs.webkit.org/show_bug.cgi?id=153287

Reviewed by Mark Lam.

A tricky bug I discovered while experimenting with live range breaking.

We have the following initial conditions:
-UseCounts is slow, so we only compute it once for all the iterations
 of the allocator.
-The only new Tmps we create are for spills and refills. They are unspillable
 by definition so it is fine to not update UseCounts accordingly.

But, in selectSpill(), we go over all the spill candidates and select the best
one based on its score. The score() lambda uses useCounts, it cannot be used
with a new Tmps created for something we already spilled.

The first time we use score is correct, we started by skipping all the unspillable
Tmps from the candidate. The next use was incorrect: we were checking unspillableTmps
*after* calling score().

The existing tests did not catch this due to back luck. I added an assertion
to find similar problems in the future.

* b3/air/AirIteratedRegisterCoalescing.cpp:
* b3/air/AirUseCounts.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@195387 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/b3/air/AirUseCounts.h b/Source/JavaScriptCore/b3/air/AirUseCounts.h
index 9bc493b..8218fde 100644
--- a/Source/JavaScriptCore/b3/air/AirUseCounts.h
+++ b/Source/JavaScriptCore/b3/air/AirUseCounts.h
@@ -97,7 +97,12 @@
         }
     }
 
-    const Counts& operator[](const Thing& arg) const { return m_counts.find(arg)->value; }
+    const Counts& operator[](const Thing& arg) const
+    {
+        auto iterator = m_counts.find(arg);
+        ASSERT(iterator != m_counts.end());
+        return iterator->value;
+    }
 
     void dump(PrintStream& out) const
     {