<!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>[180993] 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/180993">180993</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-03-03 22:55:52 -0800 (Tue, 03 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>DFG IR should refer to FunctionExecutables directly and not via the CodeBlock
https://bugs.webkit.org/show_bug.cgi?id=142229

Reviewed by Mark Lam and Benjamin Poulain.
        
Anytime a DFG IR node refers to something in CodeBlock, it has three effects:

- Cumbersome API for accessing the thing that the node refers to.
        
- Not obvious how to create a new such node after bytecode parsing, especially if the
  thing it refers to isn't already in the CodeBlock. We have done this in the past, but
  it usually involves subtle changes to CodeBlock.
        
- Not obvious how to inline code that ends up using such nodes. Again, when we have done
  this, it involved subtle changes to CodeBlock.
        
Prior to this change, the NewFunction* node types used an index into tables in CodeBlock.
For this reason, those operations were not inlineable. But the functin tables in CodeBlock
just point to FunctionExecutables, which are cells; this means that we can just abstract
these operands in DFG IR as cellOperands. cellOperands use DFG::FrozenValue, which means
that GC registration happens automagically. Even better, our dumping for cellOperand
already did FunctionExecutable dumping - so that functionality gets to be deduplicated.
        
Because this change increases the number of users of cellOperand, it also adds some
convenience methods for using it. For example, whereas before you'd say things like:
        
    jsCast&lt;Foo*&gt;(node-&gt;cellOperand()-&gt;value())
        
you can now just say:
        
    node-&gt;castOperand&lt;Foo*&gt;()
        
This change also changes existing cellOperand users to use the new conveniance API when
applicable.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::jettisonFunctionDeclsAndExprs):
* bytecode/CodeBlock.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGFrozenValue.h:
(JSC::DFG::FrozenValue::cell):
(JSC::DFG::FrozenValue::dynamicCast):
(JSC::DFG::FrozenValue::cast):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::registerFrozenValues):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasCellOperand):
(JSC::DFG::Node::castOperand):
(JSC::DFG::Node::hasFunctionDeclIndex): Deleted.
(JSC::DFG::Node::functionDeclIndex): Deleted.
(JSC::DFG::Node::hasFunctionExprIndex): Deleted.
(JSC::DFG::Node::functionExprIndex): Deleted.
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck):
(JSC::DFG::SpeculativeJIT::compileNewFunctionExpression):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGWatchpointCollectionPhase.cpp:
(JSC::DFG::WatchpointCollectionPhase::handle):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileCheckCell):
(JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFrozenValueh">trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.h</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="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</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="#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 (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -1,3 +1,74 @@
</span><ins>+2015-03-03  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        DFG IR should refer to FunctionExecutables directly and not via the CodeBlock
+        https://bugs.webkit.org/show_bug.cgi?id=142229
+
+        Reviewed by Mark Lam and Benjamin Poulain.
+        
+        Anytime a DFG IR node refers to something in CodeBlock, it has three effects:
+
+        - Cumbersome API for accessing the thing that the node refers to.
+        
+        - Not obvious how to create a new such node after bytecode parsing, especially if the
+          thing it refers to isn't already in the CodeBlock. We have done this in the past, but
+          it usually involves subtle changes to CodeBlock.
+        
+        - Not obvious how to inline code that ends up using such nodes. Again, when we have done
+          this, it involved subtle changes to CodeBlock.
+        
+        Prior to this change, the NewFunction* node types used an index into tables in CodeBlock.
+        For this reason, those operations were not inlineable. But the functin tables in CodeBlock
+        just point to FunctionExecutables, which are cells; this means that we can just abstract
+        these operands in DFG IR as cellOperands. cellOperands use DFG::FrozenValue, which means
+        that GC registration happens automagically. Even better, our dumping for cellOperand
+        already did FunctionExecutable dumping - so that functionality gets to be deduplicated.
+        
+        Because this change increases the number of users of cellOperand, it also adds some
+        convenience methods for using it. For example, whereas before you'd say things like:
+        
+            jsCast&lt;Foo*&gt;(node-&gt;cellOperand()-&gt;value())
+        
+        you can now just say:
+        
+            node-&gt;castOperand&lt;Foo*&gt;()
+        
+        This change also changes existing cellOperand users to use the new conveniance API when
+        applicable.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::jettisonFunctionDeclsAndExprs):
+        * bytecode/CodeBlock.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGFrozenValue.h:
+        (JSC::DFG::FrozenValue::cell):
+        (JSC::DFG::FrozenValue::dynamicCast):
+        (JSC::DFG::FrozenValue::cast):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::registerFrozenValues):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasCellOperand):
+        (JSC::DFG::Node::castOperand):
+        (JSC::DFG::Node::hasFunctionDeclIndex): Deleted.
+        (JSC::DFG::Node::functionDeclIndex): Deleted.
+        (JSC::DFG::Node::hasFunctionExprIndex): Deleted.
+        (JSC::DFG::Node::functionExprIndex): Deleted.
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck):
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileCheckCell):
+        (JSC::FTL::LowerDFGToLLVM::compileNativeCallOrConstruct):
+
</ins><span class="cx"> 2015-03-03  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         DelayedReleaseScope drops locks during GC which can cause a thread switch and code reentry
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -3008,6 +3008,12 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void CodeBlock::jettisonFunctionDeclsAndExprs()
+{
+    m_functionDecls.clear();
+    m_functionExprs.clear();
+}
+
</ins><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> void CodeBlock::unlinkCalls()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -657,6 +657,8 @@
</span><span class="cx">     FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
</span><span class="cx">     int numberOfFunctionDecls() { return m_functionDecls.size(); }
</span><span class="cx">     FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
</span><ins>+    
+    void jettisonFunctionDeclsAndExprs();
</ins><span class="cx"> 
</span><span class="cx">     RegExp* regexp(int index) const { return m_unlinkedCode-&gt;regexp(index); }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -3665,22 +3665,26 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         case op_new_func: {
</span><ins>+            FunctionExecutable* decl = m_inlineStackTop-&gt;m_profiledBlock-&gt;functionDecl(currentInstruction[3].u.operand);
+            FrozenValue* frozen = m_graph.freezeStrong(decl);
</ins><span class="cx">             if (!currentInstruction[4].u.operand) {
</span><span class="cx">                 set(VirtualRegister(currentInstruction[1].u.operand),
</span><del>-                    addToGraph(NewFunctionNoCheck, OpInfo(currentInstruction[3].u.operand), get(VirtualRegister(currentInstruction[2].u.operand))));
</del><ins>+                    addToGraph(NewFunctionNoCheck, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
</ins><span class="cx">             } else {
</span><span class="cx">                 set(VirtualRegister(currentInstruction[1].u.operand),
</span><span class="cx">                     addToGraph(
</span><span class="cx">                         NewFunction,
</span><del>-                        OpInfo(currentInstruction[3].u.operand),
</del><ins>+                        OpInfo(frozen),
</ins><span class="cx">                         get(VirtualRegister(currentInstruction[1].u.operand)), get(VirtualRegister(currentInstruction[2].u.operand))));
</span><span class="cx">             }
</span><span class="cx">             NEXT_OPCODE(op_new_func);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case op_new_func_exp: {
</span><ins>+            FunctionExecutable* expr = m_inlineStackTop-&gt;m_profiledBlock-&gt;functionExpr(currentInstruction[3].u.operand);
+            FrozenValue* frozen = m_graph.freezeStrong(expr);
</ins><span class="cx">             set(VirtualRegister(currentInstruction[1].u.operand),
</span><del>-                addToGraph(NewFunctionExpression, OpInfo(currentInstruction[3].u.operand), get(VirtualRegister(currentInstruction[2].u.operand))));
</del><ins>+                addToGraph(NewFunctionExpression, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
</ins><span class="cx">             NEXT_OPCODE(op_new_func_exp);
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -205,6 +205,8 @@
</span><span class="cx">     case op_get_generic_property_enumerator:
</span><span class="cx">     case op_next_enumerator_pname:
</span><span class="cx">     case op_to_index_string:
</span><ins>+    case op_new_func:
+    case op_new_func_exp:
</ins><span class="cx">         return CanCompileAndInline;
</span><span class="cx"> 
</span><span class="cx">     case op_put_to_scope: {
</span><span class="lines">@@ -226,8 +228,6 @@
</span><span class="cx"> 
</span><span class="cx">     case op_new_regexp: 
</span><span class="cx">     case op_create_lexical_environment:
</span><del>-    case op_new_func:
-    case op_new_func_exp:
</del><span class="cx">     case op_switch_string: // Don't inline because we don't want to copy string tables in the concurrent JIT.
</span><span class="cx">         return CanCompile;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFrozenValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.h (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.h        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.h        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -68,6 +68,19 @@
</span><span class="cx">     bool operator!() const { return !m_value; }
</span><span class="cx">     
</span><span class="cx">     JSValue value() const { return m_value; }
</span><ins>+    JSCell* cell() const { return m_value.asCell(); }
+    
+    template&lt;typename T&gt;
+    T dynamicCast()
+    {
+        return jsDynamicCast&lt;T&gt;(value());
+    }
+    template&lt;typename T&gt;
+    T cast()
+    {
+        return jsCast&lt;T&gt;(value());
+    }
+    
</ins><span class="cx">     Structure* structure() const { return m_structure; }
</span><span class="cx">     
</span><span class="cx">     void strengthenTo(ValueStrength strength)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -246,14 +246,6 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-    if (node-&gt;hasFunctionDeclIndex()) {
-        FunctionExecutable* executable = m_codeBlock-&gt;functionDecl(node-&gt;functionDeclIndex());
-        out.print(comma, FunctionExecutableDump(executable));
-    }
-    if (node-&gt;hasFunctionExprIndex()) {
-        FunctionExecutable* executable = m_codeBlock-&gt;functionExpr(node-&gt;functionExprIndex());
-        out.print(comma, FunctionExecutableDump(executable));
-    }
</del><span class="cx">     if (node-&gt;hasStorageAccessData()) {
</span><span class="cx">         StorageAccessData&amp; storageAccessData = node-&gt;storageAccessData();
</span><span class="cx">         out.print(comma, &quot;id&quot;, storageAccessData.identifierNumber, &quot;{&quot;, identifiers()[storageAccessData.identifierNumber], &quot;}&quot;);
</span><span class="lines">@@ -1120,6 +1112,10 @@
</span><span class="cx">     }
</span><span class="cx">     m_codeBlock-&gt;constants().shrinkToFit();
</span><span class="cx">     m_codeBlock-&gt;constantsSourceCodeRepresentation().shrinkToFit();
</span><ins>+    
+    // We have no use DFG IR have no need for FunctionExecutable*'s in the CodeBlock, since we
+    // use frozen values to refer to them.
+    m_codeBlock-&gt;jettisonFunctionDeclsAndExprs();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Graph::visitChildren(SlotVisitor&amp; visitor)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -1183,6 +1183,9 @@
</span><span class="cx">         case CheckCell:
</span><span class="cx">         case NativeConstruct:
</span><span class="cx">         case NativeCall:
</span><ins>+        case NewFunctionNoCheck:
+        case NewFunction:
+        case NewFunctionExpression:
</ins><span class="cx">             return true;
</span><span class="cx">         default:
</span><span class="cx">             return false;
</span><span class="lines">@@ -1195,6 +1198,12 @@
</span><span class="cx">         return reinterpret_cast&lt;FrozenValue*&gt;(m_opInfo);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    template&lt;typename T&gt;
+    T castOperand()
+    {
+        return cellOperand()-&gt;cast&lt;T&gt;();
+    }
+    
</ins><span class="cx">     void setCellOperand(FrozenValue* value)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(hasCellOperand());
</span><span class="lines">@@ -1341,29 +1350,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool hasFunctionDeclIndex()
-    {
-        return op() == NewFunction
-            || op() == NewFunctionNoCheck;
-    }
-    
-    unsigned functionDeclIndex()
-    {
-        ASSERT(hasFunctionDeclIndex());
-        return m_opInfo;
-    }
-    
-    bool hasFunctionExprIndex()
-    {
-        return op() == NewFunctionExpression;
-    }
-    
-    unsigned functionExprIndex()
-    {
-        ASSERT(hasFunctionExprIndex());
-        return m_opInfo;
-    }
-    
</del><span class="cx">     bool hasArrayMode()
</span><span class="cx">     {
</span><span class="cx">         switch (op()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -4256,7 +4256,8 @@
</span><span class="cx">     GPRReg scopeGPR = scope.gpr();
</span><span class="cx">     flushRegisters();
</span><span class="cx">     callOperation(
</span><del>-        operationNewFunctionNoCheck, resultGPR, scopeGPR, m_jit.codeBlock()-&gt;functionDecl(node-&gt;functionDeclIndex()));
</del><ins>+        operationNewFunctionNoCheck, resultGPR, scopeGPR,
+        node-&gt;castOperand&lt;FunctionExecutable*&gt;());
</ins><span class="cx">     cellResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -4269,8 +4270,7 @@
</span><span class="cx">     flushRegisters();
</span><span class="cx">     callOperation(
</span><span class="cx">         operationNewFunctionNoCheck,
</span><del>-        resultGPR, scopeGPR, 
-        m_jit.codeBlock()-&gt;functionExpr(node-&gt;functionExprIndex()));
</del><ins>+        resultGPR, scopeGPR,  node-&gt;castOperand&lt;FunctionExecutable*&gt;());
</ins><span class="cx">     cellResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -3749,7 +3749,7 @@
</span><span class="cx">         
</span><span class="cx">     case CheckCell: {
</span><span class="cx">         SpeculateCellOperand cell(this, node-&gt;child1());
</span><del>-        speculationCheck(BadCell, JSValueSource::unboxedCell(cell.gpr()), node-&gt;child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, cell.gpr(), node-&gt;cellOperand()-&gt;value().asCell()));
</del><ins>+        speculationCheck(BadCell, JSValueSource::unboxedCell(cell.gpr()), node-&gt;child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, cell.gpr(), node-&gt;cellOperand()-&gt;cell()));
</ins><span class="cx">         noResult(node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -4682,7 +4682,7 @@
</span><span class="cx">         addSlowPathGenerator(
</span><span class="cx">             slowPathCall(
</span><span class="cx">                 notCreated, this, operationNewFunction, JSValueRegs(resultTagGPR, resultPayloadGPR), scopeGPR,
</span><del>-                m_jit.codeBlock()-&gt;functionDecl(node-&gt;functionDeclIndex())));
</del><ins>+                node-&gt;castOperand&lt;FunctionExecutable*&gt;()));
</ins><span class="cx">         
</span><span class="cx">         jsValueResult(resultTagGPR, resultPayloadGPR, 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 (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -3834,7 +3834,7 @@
</span><span class="cx">         
</span><span class="cx">     case CheckCell: {
</span><span class="cx">         SpeculateCellOperand cell(this, node-&gt;child1());
</span><del>-        speculationCheck(BadCell, JSValueSource::unboxedCell(cell.gpr()), node-&gt;child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, cell.gpr(), node-&gt;cellOperand()-&gt;value().asCell()));
</del><ins>+        speculationCheck(BadCell, JSValueSource::unboxedCell(cell.gpr()), node-&gt;child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, cell.gpr(), node-&gt;cellOperand()-&gt;cell()));
</ins><span class="cx">         noResult(node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -4697,7 +4697,7 @@
</span><span class="cx">         addSlowPathGenerator(
</span><span class="cx">             slowPathCall(
</span><span class="cx">                 notCreated, this, operationNewFunction,
</span><del>-                resultGPR, scopeGPR, m_jit.codeBlock()-&gt;functionDecl(node-&gt;functionDeclIndex())));
</del><ins>+                resultGPR, scopeGPR, node-&gt;castOperand&lt;FunctionExecutable*&gt;()));
</ins><span class="cx">         
</span><span class="cx">         jsValueResult(resultGPR, node);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -114,7 +114,7 @@
</span><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case AllocationProfileWatchpoint:
</span><del>-            addLazily(jsCast&lt;JSFunction*&gt;(m_node-&gt;cellOperand()-&gt;value())-&gt;allocationProfileWatchpointSet());
</del><ins>+            addLazily(m_node-&gt;castOperand&lt;JSFunction*&gt;()-&gt;allocationProfileWatchpointSet());
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case VarInjectionWatchpoint:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (180992 => 180993)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-03-04 05:33:37 UTC (rev 180992)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-03-04 06:55:52 UTC (rev 180993)
</span><span class="lines">@@ -1850,7 +1850,7 @@
</span><span class="cx">         
</span><span class="cx">         speculate(
</span><span class="cx">             BadCell, jsValueValue(cell), m_node-&gt;child1().node(),
</span><del>-            m_out.notEqual(cell, weakPointer(m_node-&gt;cellOperand()-&gt;value().asCell())));
</del><ins>+            m_out.notEqual(cell, weakPointer(m_node-&gt;cellOperand()-&gt;cell())));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileCheckBadCell()
</span><span class="lines">@@ -3770,7 +3770,7 @@
</span><span class="cx">         int numPassedArgs = m_node-&gt;numChildren() - 1;
</span><span class="cx">         int numArgs = numPassedArgs;
</span><span class="cx"> 
</span><del>-        JSFunction* knownFunction = jsCast&lt;JSFunction*&gt;(m_node-&gt;cellOperand()-&gt;value().asCell());
</del><ins>+        JSFunction* knownFunction = m_node-&gt;castOperand&lt;JSFunction*&gt;();
</ins><span class="cx">         NativeFunction function = knownFunction-&gt;nativeFunction();
</span><span class="cx"> 
</span><span class="cx">         Dl_info info;
</span></span></pre>
</div>
</div>

</body>
</html>