<!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 <matthew_hanson@apple.com>
+
+ Merge r212177. rdar://problem/30205880
+
+ 2017-02-10 Saam Barati <sbarati@apple.com>
+
+ 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
+ <rdar://problem/30205880>
+
+ 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 <matthew_hanson@apple.com>
</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 < 100000; i++) {
+ foo(!!(i % 2), true, false);
+}
+
+let threw = false;
+try {
+ foo(true, true, true);
+} catch(e) {
+ threw = true;
+}
+if (!threw)
+ throw new Error("Bad test")
</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 <matthew_hanson@apple.com>
</span><span class="cx">
</span><ins>+ Merge r212177. rdar://problem/30205880
+
+ 2017-02-10 Saam Barati <sbarati@apple.com>
+
+ 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
+ <rdar://problem/30205880>
+
+ 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 <matthew_hanson@apple.com>
+
</ins><span class="cx"> Merge r212035. rdar://problem/30433204
</span><span class="cx">
</span><span class="cx"> 2017-02-09 Filip Pizlo <fpizlo@apple.com>
</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 < m_graph.numBlocks(); ++blockIndex) {
+ BasicBlock* block = m_graph.block(blockIndex);
+ if (!block)
+ continue;
+
+ calculator.beginBlock(block);
+
+ for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+ if (block->at(nodeIndex)->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->at(nodeIndex)->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("PromotedHeapLocation is dead, but should not be: ", heapPair.key);
+ availabilityMap.dump(WTF::dataFile());
+ CRASH();
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ calculator.executeNode(block->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& 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<PromotedHeapLocation> 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<std::pair<PromotedHeapLocation, Node*>> hints;
</ins><span class="cx"> for (const auto& 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& 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 "real" 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<PromotedHeapLocation>()).iterator->value.appendVector(hints);
- }
</del><ins>+ m_materializationSiteToHints.add(
+ where, Vector<std::pair<PromotedHeapLocation, Node*>>()).iterator->value.appendVector(hints);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Node* createMaterialization(const Allocation& allocation, Node* where)
</span><span class="lines">@@ -1547,6 +1565,9 @@
</span><span class="cx"> HashMap<FrozenValue*, Node*> lazyMapping;
</span><span class="cx"> if (!m_bottom)
</span><span class="cx"> m_bottom = m_insertionSet.insertConstant(0, m_graph.block(0)->at(0)->origin, jsNumber(1927));
</span><ins>+
+ Vector<HashSet<PromotedHeapLocation>> 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<PromotedHeapLocation, Node*> 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->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->at(0)->origin, canExit,
</span><span class="cx"> availabilityCalculator.m_availability, identifier, phiDef->value());
</span><ins>+
+ for (PromotedHeapLocation location : hintsForPhi[variable->index()]) {
+ m_insertionSet.insert(0,
+ location.createHint(m_graph, block->at(0)->origin.withInvalidExit(), phiDef->value()));
+ m_localMapping.set(location, phiDef->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<PromotedHeapLocation, Node*> 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<Node*, Node*> m_materializationToEscapee;
</span><span class="cx"> HashMap<Node*, Vector<Node*>> m_materializationSiteToMaterializations;
</span><span class="cx"> HashMap<Node*, Vector<PromotedHeapLocation>> m_materializationSiteToRecoveries;
</span><ins>+ HashMap<Node*, Vector<std::pair<PromotedHeapLocation, Node*>>> m_materializationSiteToHints;
</ins><span class="cx">
</span><span class="cx"> HashMap<Node*, Vector<PromotedHeapLocation>> 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()->inherits(Structure::info()));
</ins><span class="cx"> structure = jsCast<Structure*>(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->properties().size(); i--;) {
</span><span class="cx"> const ExitPropertyValue& property = materialization->properties()[i];
</span><del>- if (property.location() == PromotedLocationDescriptor(FunctionExecutablePLoc))
</del><ins>+ if (property.location() == PromotedLocationDescriptor(FunctionExecutablePLoc)) {
+ RELEASE_ASSERT(JSValue::decode(values[i]).asCell()->inherits(FunctionExecutable::info()));
</ins><span class="cx"> executable = jsCast<FunctionExecutable*>(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()->inherits(JSScope::info()));
</ins><span class="cx"> activation = jsCast<JSScope*>(JSValue::decode(values[i]));
</span><ins>+ }
</ins><span class="cx"> }
</span><span class="cx"> RELEASE_ASSERT(executable && 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->properties().size(); i--;) {
</span><span class="cx"> const ExitPropertyValue& property = materialization->properties()[i];
</span><del>- if (property.location() == PromotedLocationDescriptor(ActivationScopePLoc))
</del><ins>+ if (property.location() == PromotedLocationDescriptor(ActivationScopePLoc)) {
+ RELEASE_ASSERT(JSValue::decode(values[i]).asCell()->inherits(JSScope::info()));
</ins><span class="cx"> scope = jsCast<JSScope*>(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()->inherits(SymbolTable::info()));
</ins><span class="cx"> table = jsCast<SymbolTable*>(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>