<!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>[160295] trunk/Source/JavaScriptCore</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/160295">160295</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2013-12-08 17:08:53 -0800 (Sun, 08 Dec 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add the notion of ConstantStoragePointer to DFG IR
https://bugs.webkit.org/show_bug.cgi?id=125395

Reviewed by Oliver Hunt.
        
This pushes more typed array folding into StrengthReductionPhase, and enables CSE on
storage pointers. Previously, you might have separate nodes for the same storage
pointer and this would cause some bad register pressure in the DFG. Note that this
was really a theoretical problem and not, to my knowledge a practical one - so this
patch is basically just a clean-up.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::::executeEffects):
* dfg/DFGCSEPhase.cpp:
(JSC::DFG::CSEPhase::constantStoragePointerCSE):
(JSC::DFG::CSEPhase::performNodeCSE):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGNode.h:
(JSC::DFG::Node::convertToConstantStoragePointer):
(JSC::DFG::Node::hasStoragePointer):
(JSC::DFG::Node::storagePointer):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileConstantStoragePointer):
(JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
(JSC::DFG::StrengthReductionPhase::foldTypedArrayPropertyToConstant):
(JSC::DFG::StrengthReductionPhase::prepareToFoldTypedArray):
* dfg/DFGWatchpointCollectionPhase.cpp:
(JSC::DFG::WatchpointCollectionPhase::handle):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileConstantStoragePointer):
(JSC::FTL::LowerDFGToLLVM::compileGetIndexedPropertyStorage):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCSEPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/ChangeLog        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -1,5 +1,57 @@
</span><span class="cx"> 2013-12-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Add the notion of ConstantStoragePointer to DFG IR
+        https://bugs.webkit.org/show_bug.cgi?id=125395
+
+        Reviewed by Oliver Hunt.
+        
+        This pushes more typed array folding into StrengthReductionPhase, and enables CSE on
+        storage pointers. Previously, you might have separate nodes for the same storage
+        pointer and this would cause some bad register pressure in the DFG. Note that this
+        was really a theoretical problem and not, to my knowledge a practical one - so this
+        patch is basically just a clean-up.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::::executeEffects):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::constantStoragePointerCSE):
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToConstantStoragePointer):
+        (JSC::DFG::Node::hasStoragePointer):
+        (JSC::DFG::Node::storagePointer):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileConstantStoragePointer):
+        (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        (JSC::DFG::StrengthReductionPhase::foldTypedArrayPropertyToConstant):
+        (JSC::DFG::StrengthReductionPhase::prepareToFoldTypedArray):
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileConstantStoragePointer):
+        (JSC::FTL::LowerDFGToLLVM::compileGetIndexedPropertyStorage):
+
+2013-12-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
</ins><span class="cx">         FTL should support UntypedUse versions of Compare nodes
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=125426
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -1440,7 +1440,8 @@
</span><span class="cx">         m_state.setHaveStructures(true);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><del>-    case GetIndexedPropertyStorage: {
</del><ins>+    case GetIndexedPropertyStorage:
+    case ConstantStoragePointer: {
</ins><span class="cx">         forNode(node).clear();
</span><span class="cx">         break; 
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCSEPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -162,6 +162,21 @@
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    Node* constantStoragePointerCSE(Node* node)
+    {
+        for (unsigned i = endIndexForPureCSE(); i--;) {
+            Node* otherNode = m_currentBlock-&gt;at(i);
+            if (otherNode-&gt;op() != ConstantStoragePointer)
+                continue;
+            
+            if (otherNode-&gt;storagePointer() != node-&gt;storagePointer())
+                continue;
+            
+            return otherNode;
+        }
+        return 0;
+    }
+    
</ins><span class="cx">     Node* getCalleeLoadElimination()
</span><span class="cx">     {
</span><span class="cx">         for (unsigned i = m_indexInBlock; i--;) {
</span><span class="lines">@@ -1154,6 +1169,12 @@
</span><span class="cx">             setReplacement(weakConstantCSE(node));
</span><span class="cx">             break;
</span><span class="cx">             
</span><ins>+        case ConstantStoragePointer:
+            if (cseMode == StoreElimination)
+                break;
+            setReplacement(constantStoragePointerCSE(node));
+            break;
+            
</ins><span class="cx">         case GetArrayLength:
</span><span class="cx">             if (cseMode == StoreElimination)
</span><span class="cx">                 break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -116,6 +116,7 @@
</span><span class="cx">     case ExtractOSREntryLocal:
</span><span class="cx">     case Int52ToDouble:
</span><span class="cx">     case Int52ToValue:
</span><ins>+    case ConstantStoragePointer:
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case MovHintAndCheck:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -877,6 +877,10 @@
</span><span class="cx">         case Int52ToValue:
</span><span class="cx">         case InvalidationPoint:
</span><span class="cx">         case CheckArray:
</span><ins>+        case ConstantStoragePointer:
+            // These are just nodes that we don't currently expect to see during fixup.
+            // If we ever wanted to insert them prior to fixup, then we just have to create
+            // fixup rules for them.
</ins><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -290,6 +290,12 @@
</span><span class="cx">         out.print(comma, &quot;^&quot;, node-&gt;phi()-&gt;index());
</span><span class="cx">     if (node-&gt;hasExecutionCounter())
</span><span class="cx">         out.print(comma, RawPointer(node-&gt;executionCounter()));
</span><ins>+    if (node-&gt;hasVariableWatchpointSet())
+        out.print(comma, RawPointer(node-&gt;variableWatchpointSet()));
+    if (node-&gt;hasTypedArray())
+        out.print(comma, inContext(JSValue(node-&gt;typedArray()), context));
+    if (node-&gt;hasStoragePointer())
+        out.print(comma, RawPointer(node-&gt;storagePointer()));
</ins><span class="cx">     if (op == JSConstant) {
</span><span class="cx">         out.print(comma, &quot;$&quot;, node-&gt;constantNumber());
</span><span class="cx">         JSValue value = valueOfJSConstant(node);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -407,6 +407,13 @@
</span><span class="cx">         children.reset();
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void convertToConstantStoragePointer(void* pointer)
+    {
+        ASSERT(op() == GetIndexedPropertyStorage);
+        m_op = ConstantStoragePointer;
+        m_opInfo = bitwise_cast&lt;uintptr_t&gt;(pointer);
+    }
+    
</ins><span class="cx">     void convertToGetLocalUnlinked(VirtualRegister local)
</span><span class="cx">     {
</span><span class="cx">         m_op = GetLocalUnlinked;
</span><span class="lines">@@ -982,6 +989,16 @@
</span><span class="cx">     {
</span><span class="cx">         return reinterpret_cast&lt;JSArrayBufferView*&gt;(m_opInfo);
</span><span class="cx">     }
</span><ins>+    
+    bool hasStoragePointer()
+    {
+        return op() == ConstantStoragePointer;
+    }
+    
+    void* storagePointer()
+    {
+        return reinterpret_cast&lt;void*&gt;(m_opInfo);
+    }
</ins><span class="cx"> 
</span><span class="cx">     bool hasStructureTransitionData()
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -171,6 +171,7 @@
</span><span class="cx">     macro(Arrayify, NodeMustGenerate) \
</span><span class="cx">     macro(ArrayifyToStructure, NodeMustGenerate) \
</span><span class="cx">     macro(GetIndexedPropertyStorage, NodeResultStorage) \
</span><ins>+    macro(ConstantStoragePointer, NodeResultStorage) \
</ins><span class="cx">     macro(TypedArrayWatchpoint, NodeMustGenerate) \
</span><span class="cx">     macro(GetByOffset, NodeResultJS) \
</span><span class="cx">     macro(PutByOffset, NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -578,6 +578,7 @@
</span><span class="cx">         case NotifyWrite:
</span><span class="cx">         case FunctionReentryWatchpoint:
</span><span class="cx">         case TypedArrayWatchpoint:
</span><ins>+        case ConstantStoragePointer:
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         // This gets ignored because it already has a prediction.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -245,6 +245,7 @@
</span><span class="cx">     case NotifyWrite:
</span><span class="cx">     case FunctionReentryWatchpoint:
</span><span class="cx">     case TypedArrayWatchpoint:
</span><ins>+    case ConstantStoragePointer:
</ins><span class="cx">         return true;
</span><span class="cx">         
</span><span class="cx">     case GetByVal:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -4042,26 +4042,16 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool SpeculativeJIT::compileConstantIndexedPropertyStorage(Node* node)
</del><ins>+void SpeculativeJIT::compileConstantStoragePointer(Node* node)
</ins><span class="cx"> {
</span><del>-    JSArrayBufferView* view = m_jit.graph().tryGetFoldableViewForChild1(node);
-    if (!view)
-        return false;
-    if (view-&gt;mode() == FastTypedArray)
-        return false;
-    
</del><span class="cx">     GPRTemporary storage(this);
</span><span class="cx">     GPRReg storageGPR = storage.gpr();
</span><del>-    m_jit.move(TrustedImmPtr(view-&gt;vector()), storageGPR);
</del><ins>+    m_jit.move(TrustedImmPtr(node-&gt;storagePointer()), storageGPR);
</ins><span class="cx">     storageResult(storageGPR, node);
</span><del>-    return true;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compileGetIndexedPropertyStorage(Node* node)
</span><span class="cx"> {
</span><del>-    if (compileConstantIndexedPropertyStorage(node))
-        return;
-    
</del><span class="cx">     SpeculateCellOperand base(this, node-&gt;child1());
</span><span class="cx">     GPRReg baseReg = base.gpr();
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -2027,7 +2027,7 @@
</span><span class="cx">     void compileArithIMul(Node*);
</span><span class="cx">     void compileArithDiv(Node*);
</span><span class="cx">     void compileArithMod(Node*);
</span><del>-    bool compileConstantIndexedPropertyStorage(Node*);
</del><ins>+    void compileConstantStoragePointer(Node*);
</ins><span class="cx">     void compileGetIndexedPropertyStorage(Node*);
</span><span class="cx">     JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
</span><span class="cx">     void emitTypedArrayBoundsCheck(Node*, GPRReg baseGPR, GPRReg indexGPR);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -3946,6 +3946,11 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case ConstantStoragePointer: {
+        compileConstantStoragePointer(node);
+        break;
+    }
+        
</ins><span class="cx">     case GetTypedArrayByteOffset: {
</span><span class="cx">         compileGetTypedArrayByteOffset(node);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -4243,6 +4243,11 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><ins>+    case ConstantStoragePointer: {
+        compileConstantStoragePointer(node);
+        break;
+    }
+        
</ins><span class="cx">     case GetTypedArrayByteOffset: {
</span><span class="cx">         compileGetTypedArrayByteOffset(node);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -95,9 +95,22 @@
</span><span class="cx">                 foldTypedArrayPropertyToConstant(view, jsNumber(view-&gt;byteOffset()));
</span><span class="cx">             break;
</span><span class="cx">             
</span><del>-        // FIXME: The constant-folding of GetIndexedPropertyStorage should be expressed
-        // as an IR transformation in this phase.
-        // https://bugs.webkit.org/show_bug.cgi?id=125395
</del><ins>+        case GetIndexedPropertyStorage:
+            if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node)) {
+                if (view-&gt;mode() != FastTypedArray) {
+                    prepareToFoldTypedArray(view);
+                    m_node-&gt;convertToConstantStoragePointer(view-&gt;vector());
+                    m_changed = true;
+                    break;
+                } else {
+                    // FIXME: It would be awesome to be able to fold the property storage for
+                    // these GC-allocated typed arrays. For now it doesn't matter because the
+                    // most common use-cases for constant typed arrays involve large arrays with
+                    // aliased buffer views.
+                    // https://bugs.webkit.org/show_bug.cgi?id=125425
+                }
+            }
+            break;
</ins><span class="cx">             
</span><span class="cx">         default:
</span><span class="cx">             break;
</span><span class="lines">@@ -106,11 +119,18 @@
</span><span class="cx">     
</span><span class="cx">     void foldTypedArrayPropertyToConstant(JSArrayBufferView* view, JSValue constant)
</span><span class="cx">     {
</span><ins>+        prepareToFoldTypedArray(view);
+        m_graph.convertToConstant(m_node, constant);
+        m_changed = true;
+    }
+    
+    void prepareToFoldTypedArray(JSArrayBufferView* view)
+    {
</ins><span class="cx">         m_insertionSet.insertNode(
</span><span class="cx">             m_nodeIndex, SpecNone, TypedArrayWatchpoint, m_node-&gt;codeOrigin,
</span><span class="cx">             OpInfo(view));
</span><del>-        m_graph.convertToConstant(m_node, constant);
-        m_changed = true;
</del><ins>+        m_insertionSet.insertNode(
+            m_nodeIndex, SpecNone, Phantom, m_node-&gt;codeOrigin, m_node-&gt;children);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     InsertionSet m_insertionSet;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -138,18 +138,6 @@
</span><span class="cx">             addLazily(m_node-&gt;symbolTable()-&gt;m_functionEnteredOnce);
</span><span class="cx">             break;
</span><span class="cx">             
</span><del>-        case GetIndexedPropertyStorage:
-            if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node)) {
-                // FIXME: It would be awesome to be able to fold the property storage for
-                // these GC-allocated typed arrays. For now it doesn't matter because the
-                // most common use-cases for constant typed arrays involve large arrays with
-                // aliased buffer views.
-                if (view-&gt;mode() == FastTypedArray)
-                    break;
-                addLazily(view);
-            }
-            break;
-            
</del><span class="cx">         case TypedArrayWatchpoint:
</span><span class="cx">             addLazily(m_node-&gt;typedArray());
</span><span class="cx">             break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (160294 => 160295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2013-12-09 01:08:53 UTC (rev 160295)
</span><span class="lines">@@ -343,6 +343,9 @@
</span><span class="cx">         case GetButterfly:
</span><span class="cx">             compileGetButterfly();
</span><span class="cx">             break;
</span><ins>+        case ConstantStoragePointer:
+            compileConstantStoragePointer();
+            break;
</ins><span class="cx">         case GetIndexedPropertyStorage:
</span><span class="cx">             compileGetIndexedPropertyStorage();
</span><span class="cx">             break;
</span><span class="lines">@@ -1397,6 +1400,11 @@
</span><span class="cx">         setStorage(m_out.loadPtr(lowCell(m_node-&gt;child1()), m_heaps.JSObject_butterfly));
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void compileConstantStoragePointer()
+    {
+        setStorage(m_out.constIntPtr(m_node-&gt;storagePointer()));
+    }
+    
</ins><span class="cx">     void compileGetIndexedPropertyStorage()
</span><span class="cx">     {
</span><span class="cx">         LValue cell = lowCell(m_node-&gt;child1());
</span><span class="lines">@@ -1423,13 +1431,6 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        if (JSArrayBufferView* view = m_graph.tryGetFoldableView(m_node)) {
-            if (view-&gt;mode() != FastTypedArray) {
-                setStorage(m_out.constIntPtr(view-&gt;vector()));
-                return;
-            }
-        }
-        
</del><span class="cx">         setStorage(m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector));
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre>
</div>
</div>

</body>
</html>