<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[212596] branches/safari-603-branch</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/212596">212596</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2017-02-17 16:28:03 -0800 (Fri, 17 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/212177">r212177</a>. rdar://problem/30205880</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari603branchJSTestsChangeLog">branches/safari-603-branch/JSTests/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreChangeLog">branches/safari-603-branch/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhasecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreftlFTLOperationscpp">branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLOperations.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari603branchJSTestsstressallocationsinkingputhintcontrolflowjs">branches/safari-603-branch/JSTests/stress/allocation-sinking-puthint-control-flow.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari603branchJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/JSTests/ChangeLog (212595 => 212596)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/ChangeLog        2017-02-18 00:10:01 UTC (rev 212595)
+++ branches/safari-603-branch/JSTests/ChangeLog        2017-02-18 00:28:03 UTC (rev 212596)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2017-02-17  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
+        Merge r212177. rdar://problem/30205880
+
+    2017-02-10  Saam Barati  &lt;sbarati@apple.com&gt;
+
+            Object allocation sinking phase doesn't properly handle control flow when emitting a PutHint of a materialized object into a PromotedHeapLocation of a still sunken object
+            https://bugs.webkit.org/show_bug.cgi?id=168140
+            &lt;rdar://problem/30205880&gt;
+
+            Reviewed by Filip Pizlo.
+
+            * stress/allocation-sinking-puthint-control-flow.js: Added.
+            (e):
+            (bar):
+            (let.y):
+            (else.let.y):
+            (baz):
+            (foo):
+            (catch):
+
</ins><span class="cx"> 2017-02-09  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Merge r212022. rdar://problem/30198083
</span></span></pre></div>
<a id="branchessafari603branchJSTestsstressallocationsinkingputhintcontrolflowjs"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/JSTests/stress/allocation-sinking-puthint-control-flow.js (0 => 212596)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/stress/allocation-sinking-puthint-control-flow.js                                (rev 0)
+++ branches/safari-603-branch/JSTests/stress/allocation-sinking-puthint-control-flow.js        2017-02-18 00:28:03 UTC (rev 212596)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+function e() { }
+noInline(e);
+
+function foo(b, c, d) {
+    let x;
+    function bar() { return x; }
+    if (b) {
+        let y = function() { return x; }
+    } else {
+        let y = function() { return x; }
+    }
+
+    if (c) {
+        function baz() { }
+        if (b) {
+            let y = function() { return x; }
+            e(y);
+        } else {
+            let y = function() { return x; }
+            e(y);
+        }
+        if (d)
+            d();
+        e(baz);
+    }
+
+}
+noInline(foo);
+
+for (let i = 0; i &lt; 100000; i++) {
+    foo(!!(i % 2), true, false);
+}
+
+let threw = false;
+try {
+    foo(true, true, true);
+} catch(e) {
+    threw = true;
+}
+if (!threw)
+    throw new Error(&quot;Bad test&quot;)
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/ChangeLog (212595 => 212596)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/ChangeLog        2017-02-18 00:10:01 UTC (rev 212595)
+++ branches/safari-603-branch/Source/JavaScriptCore/ChangeLog        2017-02-18 00:28:03 UTC (rev 212596)
</span><span class="lines">@@ -1,5 +1,89 @@
</span><span class="cx"> 2017-02-17  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r212177. rdar://problem/30205880
+
+    2017-02-10  Saam Barati  &lt;sbarati@apple.com&gt;
+
+            Object allocation sinking phase doesn't properly handle control flow when emitting a PutHint of a materialized object into a PromotedHeapLocation of a still sunken object
+            https://bugs.webkit.org/show_bug.cgi?id=168140
+            &lt;rdar://problem/30205880&gt;
+
+            Reviewed by Filip Pizlo.
+
+            This patch fixes a bug in allocation sinking phase where
+            we don't properly handle control flow when materializing
+            an object and also PutHinting that materialization into
+            a still sunken object. We were performing the PutHint
+            for the materialization at the point of materialization,
+            however, we may have materialized along both edges
+            of a control flow diamond, in which case, we need to
+            also PutHint at the join point. Consider this program:
+
+            ```
+            bb#0:
+            b: PhantomActivation()
+            a: PhantomNewFunction()
+            c: PutHint(@a, @b, ActivationLoc)
+            Branch(#1, #2)
+
+            bb#1:
+            d: MaterializeActivation()
+            e: PutHint(@a, @d, ActivationLoc)
+            f: Upsilon(@d, ^p)
+            Jump(#3)
+
+            bb#2:
+            g: MaterializeActivation()
+            h: PutHint(@a, @g, ActivationLoc)
+            i: Upsilon(@d, ^p)
+            Jump(#3)
+
+            bb#3:
+            p: Phi()
+            // What is PromotedHeapLocation(@a, ActivationLoc) here?
+            // What would we do if we exited?
+            ```
+            Before this patch, we didn't perform a PutHint of the Phi.
+            However, we need to, otherwise when exit, we won't know
+            the value of PromotedHeapLocation(@a, ActivationLoc)
+
+            The program we need then, for correctness, is this:
+            ```
+            bb#0:
+            b: PhantomActivation()
+            a: PhantomNewFunction()
+            c: PutHint(@a, @b, ActivationLoc)
+            Branch(#1, #2)
+
+            bb#1:
+            d: MaterializeActivation()
+            e: PutHint(@a, @d, ActivationLoc)
+            f: Upsilon(@d, ^p)
+            Jump(#3)
+
+            bb#2:
+            g: MaterializeActivation()
+            h: PutHint(@a, @g, ActivationLoc)
+            i: Upsilon(@d, ^p)
+            Jump(#3)
+
+            bb#3:
+            p: Phi()
+            j: PutHint(@a, @p, ActivationLoc)
+            ```
+
+            This patch makes it so that we emit the necessary PutHint at node `j`.
+            I've also added more validation to the OSRAvailabilityAnalysisPhase
+            to catch this problem during validation.
+
+            * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+            (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
+            * dfg/DFGObjectAllocationSinkingPhase.cpp:
+            * ftl/FTLOperations.cpp:
+            (JSC::FTL::operationMaterializeObjectInOSR):
+
+2017-02-17  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r212035. rdar://problem/30433204
</span><span class="cx"> 
</span><span class="cx">     2017-02-09  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp (212595 => 212596)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp        2017-02-18 00:10:01 UTC (rev 212595)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp        2017-02-18 00:28:03 UTC (rev 212596)
</span><span class="lines">@@ -95,9 +95,55 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">         } while (changed);
</span><ins>+
+        if (validationEnabled()) {
+
+            for (BlockIndex blockIndex = 0; blockIndex &lt; m_graph.numBlocks(); ++blockIndex) {
+                BasicBlock* block = m_graph.block(blockIndex);
+                if (!block)
+                    continue;
+                
+                calculator.beginBlock(block);
+                
+                for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
+                    if (block-&gt;at(nodeIndex)-&gt;origin.exitOK) {
+                        // If we're allowed to exit here, the heap must be in a state
+                        // where exiting wouldn't crash. These particular fields are
+                        // required for correctness because we use them during OSR exit
+                        // to do meaningful things. It would be wrong for any of them
+                        // to be dead.
+
+                        AvailabilityMap availabilityMap = calculator.m_availability;
+                        availabilityMap.pruneByLiveness(m_graph, block-&gt;at(nodeIndex)-&gt;origin.forExit);
+
+                        for (auto heapPair : availabilityMap.m_heap) {
+                            switch (heapPair.key.kind()) {
+                            case ActivationScopePLoc:
+                            case ActivationSymbolTablePLoc:
+                            case FunctionActivationPLoc:
+                            case FunctionExecutablePLoc:
+                            case StructurePLoc:
+                                if (heapPair.value.isDead()) {
+                                    dataLogLn(&quot;PromotedHeapLocation is dead, but should not be: &quot;, heapPair.key);
+                                    availabilityMap.dump(WTF::dataFile());
+                                    CRASH();
+                                }
+                                break;
+
+                            default:
+                                break;
+                            }
+                        }
+                    }
+
+                    calculator.executeNode(block-&gt;at(nodeIndex));
+                }
+            }
+        }
</ins><span class="cx">         
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><ins>+
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> bool performOSRAvailabilityAnalysis(Graph&amp; graph)
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp (212595 => 212596)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2017-02-18 00:10:01 UTC (rev 212595)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2017-02-18 00:28:03 UTC (rev 212596)
</span><span class="lines">@@ -1087,6 +1087,7 @@
</span><span class="cx">         m_materializationToEscapee.clear();
</span><span class="cx">         m_materializationSiteToMaterializations.clear();
</span><span class="cx">         m_materializationSiteToRecoveries.clear();
</span><ins>+        m_materializationSiteToHints.clear();
</ins><span class="cx"> 
</span><span class="cx">         // Logically we wish to consider every allocation and sink
</span><span class="cx">         // it. However, it is probably not profitable to sink an
</span><span class="lines">@@ -1242,8 +1243,24 @@
</span><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         // First collect the hints that will be needed when the node
</span><del>-        // we materialize is still stored into other unescaped sink candidates
-        Vector&lt;PromotedHeapLocation&gt; hints;
</del><ins>+        // we materialize is still stored into other unescaped sink candidates.
+        // The way to interpret this vector is:
+        //
+        // PromotedHeapLocation(NotEscapedAllocation, field) = identifierAllocation
+        //
+        // e.g:
+        // PromotedHeapLocation(@PhantomNewFunction, FunctionActivationPLoc) = IdentifierOf(@MaterializeCreateActivation)
+        // or:
+        // PromotedHeapLocation(@PhantomCreateActivation, ClosureVarPLoc(x)) = IdentifierOf(@NewFunction)
+        //
+        // When the rhs of the `=` is to be materialized at this `where` point in the program
+        // and IdentifierOf(Materialization) is the original sunken allocation of the materialization.
+        //
+        // The reason we need to collect all the `identifiers` here is that
+        // we may materialize multiple versions of the allocation along control
+        // flow edges. We will PutHint these values along those edges. However,
+        // we also need to PutHint them when we join and have a Phi of the allocations.
+        Vector&lt;std::pair&lt;PromotedHeapLocation, Node*&gt;&gt; hints;
</ins><span class="cx">         for (const auto&amp; entry : m_heap.allocations()) {
</span><span class="cx">             if (escapees.contains(entry.key))
</span><span class="cx">                 continue;
</span><span class="lines">@@ -1250,8 +1267,11 @@
</span><span class="cx"> 
</span><span class="cx">             for (const auto&amp; field : entry.value.fields()) {
</span><span class="cx">                 ASSERT(m_sinkCandidates.contains(entry.key) || !escapees.contains(field.value));
</span><del>-                if (escapees.contains(field.value))
-                    hints.append(PromotedHeapLocation(entry.key, field.key));
</del><ins>+                auto iter = escapees.find(field.value);
+                if (iter != escapees.end()) {
+                    ASSERT(m_sinkCandidates.contains(field.value));
+                    hints.append(std::make_pair(PromotedHeapLocation(entry.key, field.key), field.value));
+                }
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1430,10 +1450,8 @@
</span><span class="cx"> 
</span><span class="cx">         // The hints need to be after the &quot;real&quot; recoveries so that we
</span><span class="cx">         // don't hint not-yet-complete objects
</span><del>-        if (!hints.isEmpty()) {
-            m_materializationSiteToRecoveries.add(
-                where, Vector&lt;PromotedHeapLocation&gt;()).iterator-&gt;value.appendVector(hints);
-        }
</del><ins>+        m_materializationSiteToHints.add(
+            where, Vector&lt;std::pair&lt;PromotedHeapLocation, Node*&gt;&gt;()).iterator-&gt;value.appendVector(hints);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Node* createMaterialization(const Allocation&amp; allocation, Node* where)
</span><span class="lines">@@ -1547,6 +1565,9 @@
</span><span class="cx">         HashMap&lt;FrozenValue*, Node*&gt; lazyMapping;
</span><span class="cx">         if (!m_bottom)
</span><span class="cx">             m_bottom = m_insertionSet.insertConstant(0, m_graph.block(0)-&gt;at(0)-&gt;origin, jsNumber(1927));
</span><ins>+
+        Vector&lt;HashSet&lt;PromotedHeapLocation&gt;&gt; hintsForPhi(m_sinkCandidates.size());
+
</ins><span class="cx">         for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
</span><span class="cx">             m_heap = m_heapAtHead[block];
</span><span class="cx"> 
</span><span class="lines">@@ -1568,6 +1589,31 @@
</span><span class="cx">                     m_allocationSSA.newDef(m_nodeToVariable.get(escapee), block, materialization);
</span><span class="cx">                 }
</span><span class="cx"> 
</span><ins>+                for (std::pair&lt;PromotedHeapLocation, Node*&gt; pair : m_materializationSiteToHints.get(node)) {
+                    PromotedHeapLocation location = pair.first;
+                    Node* identifier = pair.second;
+                    // We're materializing `identifier` at this point, and the unmaterialized
+                    // version is inside `location`. We track which SSA variable this belongs
+                    // to in case we also need a PutHint for the Phi.
+                    if (UNLIKELY(validationEnabled())) {
+                        RELEASE_ASSERT(m_sinkCandidates.contains(location.base()));
+                        RELEASE_ASSERT(m_sinkCandidates.contains(identifier));
+
+                        bool found = false;
+                        for (Node* materialization : m_materializationSiteToMaterializations.get(node)) {
+                            // We're materializing `identifier` here. This asserts that this is indeed the case.
+                            if (m_materializationToEscapee.get(materialization) == identifier) {
+                                found = true;
+                                break;
+                            }
+                        }
+                        RELEASE_ASSERT(found);
+                    }
+
+                    SSACalculator::Variable* variable = m_nodeToVariable.get(identifier);
+                    hintsForPhi[variable-&gt;index()].add(location);
+                }
+
</ins><span class="cx">                 if (m_sinkCandidates.contains(node))
</span><span class="cx">                     m_allocationSSA.newDef(m_nodeToVariable.get(node), block, node);
</span><span class="cx"> 
</span><span class="lines">@@ -1683,6 +1729,12 @@
</span><span class="cx">                 insertOSRHintsForUpdate(
</span><span class="cx">                     0, block-&gt;at(0)-&gt;origin, canExit,
</span><span class="cx">                     availabilityCalculator.m_availability, identifier, phiDef-&gt;value());
</span><ins>+
+                for (PromotedHeapLocation location : hintsForPhi[variable-&gt;index()]) {
+                    m_insertionSet.insert(0,
+                        location.createHint(m_graph, block-&gt;at(0)-&gt;origin.withInvalidExit(), phiDef-&gt;value()));
+                    m_localMapping.set(location, phiDef-&gt;value());
+                }
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             if (verbose) {
</span><span class="lines">@@ -1722,6 +1774,8 @@
</span><span class="cx"> 
</span><span class="cx">                 for (PromotedHeapLocation location : m_materializationSiteToRecoveries.get(node))
</span><span class="cx">                     m_insertionSet.insert(nodeIndex, createRecovery(block, location, node, canExit));
</span><ins>+                for (std::pair&lt;PromotedHeapLocation, Node*&gt; pair : m_materializationSiteToHints.get(node))
+                    m_insertionSet.insert(nodeIndex, createRecovery(block, pair.first, node, canExit));
</ins><span class="cx"> 
</span><span class="cx">                 // We need to put the OSR hints after the recoveries,
</span><span class="cx">                 // because we only want the hints once the object is
</span><span class="lines">@@ -2209,6 +2263,7 @@
</span><span class="cx">     HashMap&lt;Node*, Node*&gt; m_materializationToEscapee;
</span><span class="cx">     HashMap&lt;Node*, Vector&lt;Node*&gt;&gt; m_materializationSiteToMaterializations;
</span><span class="cx">     HashMap&lt;Node*, Vector&lt;PromotedHeapLocation&gt;&gt; m_materializationSiteToRecoveries;
</span><ins>+    HashMap&lt;Node*, Vector&lt;std::pair&lt;PromotedHeapLocation, Node*&gt;&gt;&gt; m_materializationSiteToHints;
</ins><span class="cx"> 
</span><span class="cx">     HashMap&lt;Node*, Vector&lt;PromotedHeapLocation&gt;&gt; m_locationsForAllocation;
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreftlFTLOperationscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLOperations.cpp (212595 => 212596)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLOperations.cpp        2017-02-18 00:10:01 UTC (rev 212595)
+++ branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLOperations.cpp        2017-02-18 00:28:03 UTC (rev 212596)
</span><span class="lines">@@ -132,6 +132,7 @@
</span><span class="cx">             if (property.location() != PromotedLocationDescriptor(StructurePLoc))
</span><span class="cx">                 continue;
</span><span class="cx"> 
</span><ins>+            RELEASE_ASSERT(JSValue::decode(values[i]).asCell()-&gt;inherits(Structure::info()));
</ins><span class="cx">             structure = jsCast&lt;Structure*&gt;(JSValue::decode(values[i]));
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -163,10 +164,14 @@
</span><span class="cx">         JSScope* activation = nullptr;
</span><span class="cx">         for (unsigned i = materialization-&gt;properties().size(); i--;) {
</span><span class="cx">             const ExitPropertyValue&amp; property = materialization-&gt;properties()[i];
</span><del>-            if (property.location() == PromotedLocationDescriptor(FunctionExecutablePLoc))
</del><ins>+            if (property.location() == PromotedLocationDescriptor(FunctionExecutablePLoc)) {
+                RELEASE_ASSERT(JSValue::decode(values[i]).asCell()-&gt;inherits(FunctionExecutable::info()));
</ins><span class="cx">                 executable = jsCast&lt;FunctionExecutable*&gt;(JSValue::decode(values[i]));
</span><del>-            if (property.location() == PromotedLocationDescriptor(FunctionActivationPLoc))
</del><ins>+            }
+            if (property.location() == PromotedLocationDescriptor(FunctionActivationPLoc)) {
+                RELEASE_ASSERT(JSValue::decode(values[i]).asCell()-&gt;inherits(JSScope::info()));
</ins><span class="cx">                 activation = jsCast&lt;JSScope*&gt;(JSValue::decode(values[i]));
</span><ins>+            }
</ins><span class="cx">         }
</span><span class="cx">         RELEASE_ASSERT(executable &amp;&amp; activation);
</span><span class="cx"> 
</span><span class="lines">@@ -184,10 +189,13 @@
</span><span class="cx">         SymbolTable* table = nullptr;
</span><span class="cx">         for (unsigned i = materialization-&gt;properties().size(); i--;) {
</span><span class="cx">             const ExitPropertyValue&amp; property = materialization-&gt;properties()[i];
</span><del>-            if (property.location() == PromotedLocationDescriptor(ActivationScopePLoc))
</del><ins>+            if (property.location() == PromotedLocationDescriptor(ActivationScopePLoc)) {
+                RELEASE_ASSERT(JSValue::decode(values[i]).asCell()-&gt;inherits(JSScope::info()));
</ins><span class="cx">                 scope = jsCast&lt;JSScope*&gt;(JSValue::decode(values[i]));
</span><del>-            else if (property.location() == PromotedLocationDescriptor(ActivationSymbolTablePLoc))
</del><ins>+            } else if (property.location() == PromotedLocationDescriptor(ActivationSymbolTablePLoc)) {
+                RELEASE_ASSERT(JSValue::decode(values[i]).asCell()-&gt;inherits(SymbolTable::info()));
</ins><span class="cx">                 table = jsCast&lt;SymbolTable*&gt;(JSValue::decode(values[i]));
</span><ins>+            }
</ins><span class="cx">         }
</span><span class="cx">         RELEASE_ASSERT(scope);
</span><span class="cx">         RELEASE_ASSERT(table);
</span></span></pre>
</div>
</div>

</body>
</html>