<!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>[164417] 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/164417">164417</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-02-20 00:00:28 -0800 (Thu, 20 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>DFG should have a way of carrying and preserving conditional branch weights
https://bugs.webkit.org/show_bug.cgi?id=129083

Reviewed by Michael Saboff.
        
Branch and Switch now have branch counts/weights for each target. This is encapsulated
behind DFG::BranchTarget. We carry this data all the way to the FTL, and the DFG
backend ignores it.
        
We don't set this data yet; that's for https://bugs.webkit.org/show_bug.cgi?id=129055.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::branchData):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::linkBlock):
* dfg/DFGCFGSimplificationPhase.cpp:
(JSC::DFG::CFGSimplificationPhase::run):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGGraph.h:
* dfg/DFGInPlaceAbstractState.cpp:
(JSC::DFG::InPlaceAbstractState::mergeToSuccessors):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGNode.cpp:
(JSC::DFG::BranchTarget::dump):
* dfg/DFGNode.h:
(JSC::DFG::BranchTarget::BranchTarget):
(JSC::DFG::BranchTarget::setBytecodeIndex):
(JSC::DFG::BranchTarget::bytecodeIndex):
(JSC::DFG::BranchData::withBytecodeIndices):
(JSC::DFG::BranchData::takenBytecodeIndex):
(JSC::DFG::BranchData::notTakenBytecodeIndex):
(JSC::DFG::BranchData::forCondition):
(JSC::DFG::SwitchCase::SwitchCase):
(JSC::DFG::SwitchCase::withBytecodeIndex):
(JSC::DFG::SwitchData::SwitchData):
(JSC::DFG::Node::targetBytecodeOffsetDuringParsing):
(JSC::DFG::Node::targetBlock):
(JSC::DFG::Node::branchData):
(JSC::DFG::Node::successor):
(JSC::DFG::Node::successorForCondition):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleBooleanBranch):
(JSC::DFG::SpeculativeJIT::compilePeepHoleInt32Branch):
(JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
(JSC::DFG::SpeculativeJIT::compileRegExpExec):
(JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
(JSC::DFG::SpeculativeJIT::emitSwitchImm):
(JSC::DFG::SpeculativeJIT::emitSwitchCharStringJump):
(JSC::DFG::SpeculativeJIT::emitSwitchChar):
(JSC::DFG::SpeculativeJIT::emitBinarySwitchStringRecurse):
(JSC::DFG::SpeculativeJIT::emitSwitchStringOnString):
(JSC::DFG::SpeculativeJIT::emitSwitchString):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleInt52Branch):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileJump):
(JSC::FTL::LowerDFGToLLVM::compileBranch):
(JSC::FTL::LowerDFGToLLVM::compileSwitch):
(JSC::FTL::LowerDFGToLLVM::buildSwitch):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCFGSimplificationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp</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="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGInPlaceAbstractStatecpp">trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITCompilercpp">trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodecpp">trunk/Source/JavaScriptCore/dfg/DFGNode.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="#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 (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -1,3 +1,85 @@
</span><ins>+2014-02-19  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        DFG should have a way of carrying and preserving conditional branch weights
+        https://bugs.webkit.org/show_bug.cgi?id=129083
+
+        Reviewed by Michael Saboff.
+        
+        Branch and Switch now have branch counts/weights for each target. This is encapsulated
+        behind DFG::BranchTarget. We carry this data all the way to the FTL, and the DFG
+        backend ignores it.
+        
+        We don't set this data yet; that's for https://bugs.webkit.org/show_bug.cgi?id=129055.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::branchData):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::linkBlock):
+        * dfg/DFGCFGSimplificationPhase.cpp:
+        (JSC::DFG::CFGSimplificationPhase::run):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGGraph.h:
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::mergeToSuccessors):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::BranchTarget::dump):
+        * dfg/DFGNode.h:
+        (JSC::DFG::BranchTarget::BranchTarget):
+        (JSC::DFG::BranchTarget::setBytecodeIndex):
+        (JSC::DFG::BranchTarget::bytecodeIndex):
+        (JSC::DFG::BranchData::withBytecodeIndices):
+        (JSC::DFG::BranchData::takenBytecodeIndex):
+        (JSC::DFG::BranchData::notTakenBytecodeIndex):
+        (JSC::DFG::BranchData::forCondition):
+        (JSC::DFG::SwitchCase::SwitchCase):
+        (JSC::DFG::SwitchCase::withBytecodeIndex):
+        (JSC::DFG::SwitchData::SwitchData):
+        (JSC::DFG::Node::targetBytecodeOffsetDuringParsing):
+        (JSC::DFG::Node::targetBlock):
+        (JSC::DFG::Node::branchData):
+        (JSC::DFG::Node::successor):
+        (JSC::DFG::Node::successorForCondition):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleBooleanBranch):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleInt32Branch):
+        (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
+        (JSC::DFG::SpeculativeJIT::compileRegExpExec):
+        (JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
+        (JSC::DFG::SpeculativeJIT::emitSwitchImm):
+        (JSC::DFG::SpeculativeJIT::emitSwitchCharStringJump):
+        (JSC::DFG::SpeculativeJIT::emitSwitchChar):
+        (JSC::DFG::SpeculativeJIT::emitBinarySwitchStringRecurse):
+        (JSC::DFG::SpeculativeJIT::emitSwitchStringOnString):
+        (JSC::DFG::SpeculativeJIT::emitSwitchString):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleInt52Branch):
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileJump):
+        (JSC::FTL::LowerDFGToLLVM::compileBranch):
+        (JSC::FTL::LowerDFGToLLVM::compileSwitch):
+        (JSC::FTL::LowerDFGToLLVM::buildSwitch):
+
</ins><span class="cx"> 2014-02-19  ChangSeok Oh  &lt;changseok.oh@collabora.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed build fix after r164396
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -723,6 +723,13 @@
</span><span class="cx">         return value.isBoolean() || value.isUndefinedOrNull();
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    BranchData* branchData(unsigned taken, unsigned notTaken)
+    {
+        BranchData* data = m_graph.m_branchData.add();
+        *data = BranchData::withBytecodeIndices(taken, notTaken);
+        return data;
+    }
+    
</ins><span class="cx">     Node* addToGraph(NodeType op, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
</span><span class="cx">     {
</span><span class="cx">         Node* result = m_graph.addNode(
</span><span class="lines">@@ -1458,8 +1465,8 @@
</span><span class="cx">         ASSERT(!blockToLink-&gt;isLinked);
</span><span class="cx">         Node* node = blockToLink-&gt;last();
</span><span class="cx">         ASSERT(node-&gt;op() == Jump);
</span><del>-        ASSERT(node-&gt;takenBlock() == 0);
-        node-&gt;setTakenBlock(block.get());
</del><ins>+        ASSERT(!node-&gt;targetBlock());
+        node-&gt;targetBlock() = block.get();
</ins><span class="cx">         inlineStackEntry.m_unlinkedBlocks[i].m_needsEarlyReturnLinking = false;
</span><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">         blockToLink-&gt;isLinked = true;
</span><span class="lines">@@ -2697,7 +2704,7 @@
</span><span class="cx">                     NEXT_OPCODE(op_jtrue);
</span><span class="cx">                 }
</span><span class="cx">             }
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jtrue)), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jtrue))), condition);
</ins><span class="cx">             LAST_OPCODE(op_jtrue);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2716,7 +2723,7 @@
</span><span class="cx">                     NEXT_OPCODE(op_jfalse);
</span><span class="cx">                 }
</span><span class="cx">             }
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jfalse)), OpInfo(m_currentIndex + relativeOffset), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jfalse), m_currentIndex + relativeOffset)), condition);
</ins><span class="cx">             LAST_OPCODE(op_jfalse);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2724,7 +2731,7 @@
</span><span class="cx">             unsigned relativeOffset = currentInstruction[2].u.operand;
</span><span class="cx">             Node* value = get(VirtualRegister(currentInstruction[1].u.operand));
</span><span class="cx">             Node* condition = addToGraph(CompareEqConstant, value, constantNull());
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jeq_null)), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jeq_null))), condition);
</ins><span class="cx">             LAST_OPCODE(op_jeq_null);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2732,7 +2739,7 @@
</span><span class="cx">             unsigned relativeOffset = currentInstruction[2].u.operand;
</span><span class="cx">             Node* value = get(VirtualRegister(currentInstruction[1].u.operand));
</span><span class="cx">             Node* condition = addToGraph(CompareEqConstant, value, constantNull());
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jneq_null)), OpInfo(m_currentIndex + relativeOffset), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jneq_null), m_currentIndex + relativeOffset)), condition);
</ins><span class="cx">             LAST_OPCODE(op_jneq_null);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2758,7 +2765,7 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             Node* condition = addToGraph(CompareLess, op1, op2);
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jless)), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jless))), condition);
</ins><span class="cx">             LAST_OPCODE(op_jless);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2784,7 +2791,7 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             Node* condition = addToGraph(CompareLessEq, op1, op2);
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jlesseq)), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jlesseq))), condition);
</ins><span class="cx">             LAST_OPCODE(op_jlesseq);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2810,7 +2817,7 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             Node* condition = addToGraph(CompareGreater, op1, op2);
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jgreater)), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jgreater))), condition);
</ins><span class="cx">             LAST_OPCODE(op_jgreater);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2836,7 +2843,7 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             Node* condition = addToGraph(CompareGreaterEq, op1, op2);
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jgreatereq)), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jgreatereq))), condition);
</ins><span class="cx">             LAST_OPCODE(op_jgreatereq);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2862,7 +2869,7 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             Node* condition = addToGraph(CompareLess, op1, op2);
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jnless)), OpInfo(m_currentIndex + relativeOffset), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jnless), m_currentIndex + relativeOffset)), condition);
</ins><span class="cx">             LAST_OPCODE(op_jnless);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2888,7 +2895,7 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             Node* condition = addToGraph(CompareLessEq, op1, op2);
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jnlesseq)), OpInfo(m_currentIndex + relativeOffset), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jnlesseq), m_currentIndex + relativeOffset)), condition);
</ins><span class="cx">             LAST_OPCODE(op_jnlesseq);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2914,7 +2921,7 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             Node* condition = addToGraph(CompareGreater, op1, op2);
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jngreater)), OpInfo(m_currentIndex + relativeOffset), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jngreater), m_currentIndex + relativeOffset)), condition);
</ins><span class="cx">             LAST_OPCODE(op_jngreater);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2940,66 +2947,63 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             Node* condition = addToGraph(CompareGreaterEq, op1, op2);
</span><del>-            addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jngreatereq)), OpInfo(m_currentIndex + relativeOffset), condition);
</del><ins>+            addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jngreatereq), m_currentIndex + relativeOffset)), condition);
</ins><span class="cx">             LAST_OPCODE(op_jngreatereq);
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         case op_switch_imm: {
</span><del>-            SwitchData data;
</del><ins>+            SwitchData&amp; data = *m_graph.m_switchData.add();
</ins><span class="cx">             data.kind = SwitchImm;
</span><span class="cx">             data.switchTableIndex = m_inlineStackTop-&gt;m_switchRemap[currentInstruction[1].u.operand];
</span><del>-            data.setFallThroughBytecodeIndex(m_currentIndex + currentInstruction[2].u.operand);
</del><ins>+            data.fallThrough.setBytecodeIndex(m_currentIndex + currentInstruction[2].u.operand);
</ins><span class="cx">             SimpleJumpTable&amp; table = m_codeBlock-&gt;switchJumpTable(data.switchTableIndex);
</span><span class="cx">             for (unsigned i = 0; i &lt; table.branchOffsets.size(); ++i) {
</span><span class="cx">                 if (!table.branchOffsets[i])
</span><span class="cx">                     continue;
</span><span class="cx">                 unsigned target = m_currentIndex + table.branchOffsets[i];
</span><del>-                if (target == data.fallThroughBytecodeIndex())
</del><ins>+                if (target == data.fallThrough.bytecodeIndex())
</ins><span class="cx">                     continue;
</span><span class="cx">                 data.cases.append(SwitchCase::withBytecodeIndex(jsNumber(static_cast&lt;int32_t&gt;(table.min + i)), target));
</span><span class="cx">             }
</span><del>-            m_graph.m_switchData.append(data);
-            addToGraph(Switch, OpInfo(&amp;m_graph.m_switchData.last()), get(VirtualRegister(currentInstruction[3].u.operand)));
</del><ins>+            addToGraph(Switch, OpInfo(&amp;data), get(VirtualRegister(currentInstruction[3].u.operand)));
</ins><span class="cx">             LAST_OPCODE(op_switch_imm);
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         case op_switch_char: {
</span><del>-            SwitchData data;
</del><ins>+            SwitchData&amp; data = *m_graph.m_switchData.add();
</ins><span class="cx">             data.kind = SwitchChar;
</span><span class="cx">             data.switchTableIndex = m_inlineStackTop-&gt;m_switchRemap[currentInstruction[1].u.operand];
</span><del>-            data.setFallThroughBytecodeIndex(m_currentIndex + currentInstruction[2].u.operand);
</del><ins>+            data.fallThrough.setBytecodeIndex(m_currentIndex + currentInstruction[2].u.operand);
</ins><span class="cx">             SimpleJumpTable&amp; table = m_codeBlock-&gt;switchJumpTable(data.switchTableIndex);
</span><span class="cx">             for (unsigned i = 0; i &lt; table.branchOffsets.size(); ++i) {
</span><span class="cx">                 if (!table.branchOffsets[i])
</span><span class="cx">                     continue;
</span><span class="cx">                 unsigned target = m_currentIndex + table.branchOffsets[i];
</span><del>-                if (target == data.fallThroughBytecodeIndex())
</del><ins>+                if (target == data.fallThrough.bytecodeIndex())
</ins><span class="cx">                     continue;
</span><span class="cx">                 data.cases.append(
</span><span class="cx">                     SwitchCase::withBytecodeIndex(LazyJSValue::singleCharacterString(table.min + i), target));
</span><span class="cx">             }
</span><del>-            m_graph.m_switchData.append(data);
-            addToGraph(Switch, OpInfo(&amp;m_graph.m_switchData.last()), get(VirtualRegister(currentInstruction[3].u.operand)));
</del><ins>+            addToGraph(Switch, OpInfo(&amp;data), get(VirtualRegister(currentInstruction[3].u.operand)));
</ins><span class="cx">             LAST_OPCODE(op_switch_char);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case op_switch_string: {
</span><del>-            SwitchData data;
</del><ins>+            SwitchData&amp; data = *m_graph.m_switchData.add();
</ins><span class="cx">             data.kind = SwitchString;
</span><span class="cx">             data.switchTableIndex = currentInstruction[1].u.operand;
</span><del>-            data.setFallThroughBytecodeIndex(m_currentIndex + currentInstruction[2].u.operand);
</del><ins>+            data.fallThrough.setBytecodeIndex(m_currentIndex + currentInstruction[2].u.operand);
</ins><span class="cx">             StringJumpTable&amp; table = m_codeBlock-&gt;stringSwitchJumpTable(data.switchTableIndex);
</span><span class="cx">             StringJumpTable::StringOffsetTable::iterator iter;
</span><span class="cx">             StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
</span><span class="cx">             for (iter = table.offsetTable.begin(); iter != end; ++iter) {
</span><span class="cx">                 unsigned target = m_currentIndex + iter-&gt;value.branchOffset;
</span><del>-                if (target == data.fallThroughBytecodeIndex())
</del><ins>+                if (target == data.fallThrough.bytecodeIndex())
</ins><span class="cx">                     continue;
</span><span class="cx">                 data.cases.append(
</span><span class="cx">                     SwitchCase::withBytecodeIndex(LazyJSValue::knownStringImpl(iter-&gt;key.get()), target));
</span><span class="cx">             }
</span><del>-            m_graph.m_switchData.append(data);
-            addToGraph(Switch, OpInfo(&amp;m_graph.m_switchData.last()), get(VirtualRegister(currentInstruction[3].u.operand)));
</del><ins>+            addToGraph(Switch, OpInfo(&amp;data), get(VirtualRegister(currentInstruction[3].u.operand)));
</ins><span class="cx">             LAST_OPCODE(op_switch_string);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -3423,19 +3427,23 @@
</span><span class="cx">     
</span><span class="cx">     switch (node-&gt;op()) {
</span><span class="cx">     case Jump:
</span><del>-        node-&gt;setTakenBlock(blockForBytecodeOffset(possibleTargets, node-&gt;takenBytecodeOffsetDuringParsing()));
</del><ins>+        node-&gt;targetBlock() = blockForBytecodeOffset(possibleTargets, node-&gt;targetBytecodeOffsetDuringParsing());
</ins><span class="cx">         break;
</span><span class="cx">         
</span><del>-    case Branch:
-        node-&gt;setTakenBlock(blockForBytecodeOffset(possibleTargets, node-&gt;takenBytecodeOffsetDuringParsing()));
-        node-&gt;setNotTakenBlock(blockForBytecodeOffset(possibleTargets, node-&gt;notTakenBytecodeOffsetDuringParsing()));
</del><ins>+    case Branch: {
+        BranchData* data = node-&gt;branchData();
+        data-&gt;taken.block = blockForBytecodeOffset(possibleTargets, data-&gt;takenBytecodeIndex());
+        data-&gt;notTaken.block = blockForBytecodeOffset(possibleTargets, data-&gt;notTakenBytecodeIndex());
</ins><span class="cx">         break;
</span><ins>+    }
</ins><span class="cx">         
</span><del>-    case Switch:
</del><ins>+    case Switch: {
+        SwitchData* data = node-&gt;switchData();
</ins><span class="cx">         for (unsigned i = node-&gt;switchData()-&gt;cases.size(); i--;)
</span><del>-            node-&gt;switchData()-&gt;cases[i].target = blockForBytecodeOffset(possibleTargets, node-&gt;switchData()-&gt;cases[i].targetBytecodeIndex());
-        node-&gt;switchData()-&gt;fallThrough = blockForBytecodeOffset(possibleTargets, node-&gt;switchData()-&gt;fallThroughBytecodeIndex());
</del><ins>+            data-&gt;cases[i].target.block = blockForBytecodeOffset(possibleTargets, data-&gt;cases[i].target.bytecodeIndex());
+        data-&gt;fallThrough.block = blockForBytecodeOffset(possibleTargets, data-&gt;fallThrough.bytecodeIndex());
</ins><span class="cx">         break;
</span><ins>+    }
</ins><span class="cx">         
</span><span class="cx">     default:
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCFGSimplificationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2013, 2014 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">@@ -133,14 +133,17 @@
</span><span class="cx">                     
</span><span class="cx">                     // Prune out cases that end up jumping to default.
</span><span class="cx">                     for (unsigned i = 0; i &lt; data-&gt;cases.size(); ++i) {
</span><del>-                        if (data-&gt;cases[i].target == data-&gt;fallThrough)
-                            data-&gt;cases[i--] = data-&gt;cases.takeLast();
</del><ins>+                        if (data-&gt;cases[i].target.block == data-&gt;fallThrough.block) {
+                            data-&gt;fallThrough.count += data-&gt;cases[i].target.count;
+                            data-&gt;cases[i--] = data-&gt;cases.last();
+                            data-&gt;cases.removeLast();
+                        }
</ins><span class="cx">                     }
</span><span class="cx">                     
</span><span class="cx">                     // If there are no cases other than default then this turns
</span><span class="cx">                     // into a jump.
</span><span class="cx">                     if (data-&gt;cases.isEmpty()) {
</span><del>-                        convertToJump(block, data-&gt;fallThrough);
</del><ins>+                        convertToJump(block, data-&gt;fallThrough.block);
</ins><span class="cx">                         innerChanged = outerChanged = true;
</span><span class="cx">                         break;
</span><span class="cx">                     }
</span><span class="lines">@@ -153,13 +156,13 @@
</span><span class="cx">                         for (unsigned i = data-&gt;cases.size(); found == FalseTriState &amp;&amp; i--;) {
</span><span class="cx">                             found = data-&gt;cases[i].value.strictEqual(value);
</span><span class="cx">                             if (found == TrueTriState)
</span><del>-                                targetBlock = data-&gt;cases[i].target;
</del><ins>+                                targetBlock = data-&gt;cases[i].target.block;
</ins><span class="cx">                         }
</span><span class="cx">                         
</span><span class="cx">                         if (found == MixedTriState)
</span><span class="cx">                             break;
</span><span class="cx">                         if (found == FalseTriState)
</span><del>-                            targetBlock = data-&gt;fallThrough;
</del><ins>+                            targetBlock = data-&gt;fallThrough.block;
</ins><span class="cx">                         ASSERT(targetBlock);
</span><span class="cx">                         
</span><span class="cx">                         Vector&lt;BasicBlock*, 1&gt; jettisonedBlocks;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -669,10 +669,8 @@
</span><span class="cx">                     if (newChildEdge-&gt;hasBooleanResult()) {
</span><span class="cx">                         node-&gt;children.setChild1(newChildEdge);
</span><span class="cx">                         
</span><del>-                        BasicBlock* toBeTaken = node-&gt;notTakenBlock();
-                        BasicBlock* toBeNotTaken = node-&gt;takenBlock();
-                        node-&gt;setTakenBlock(toBeTaken);
-                        node-&gt;setNotTakenBlock(toBeNotTaken);
</del><ins>+                        BranchData* data = node-&gt;branchData();
+                        std::swap(data-&gt;taken, data-&gt;notTaken);
</ins><span class="cx">                     }
</span><span class="cx">                 }
</span><span class="cx">             }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -315,16 +315,16 @@
</span><span class="cx">     }
</span><span class="cx">     if (op == WeakJSConstant)
</span><span class="cx">         out.print(comma, RawPointer(node-&gt;weakConstant()), &quot; (&quot;, inContext(*node-&gt;weakConstant()-&gt;structure(), context), &quot;)&quot;);
</span><del>-    if (node-&gt;isBranch() || node-&gt;isJump())
-        out.print(comma, &quot;T:&quot;, *node-&gt;takenBlock());
</del><ins>+    if (node-&gt;isJump())
+        out.print(comma, &quot;T:&quot;, *node-&gt;targetBlock());
</ins><span class="cx">     if (node-&gt;isBranch())
</span><del>-        out.print(comma, &quot;F:&quot;, *node-&gt;notTakenBlock());
</del><ins>+        out.print(comma, &quot;T:&quot;, node-&gt;branchData()-&gt;taken, &quot;, F:&quot;, node-&gt;branchData()-&gt;notTaken);
</ins><span class="cx">     if (node-&gt;isSwitch()) {
</span><span class="cx">         SwitchData* data = node-&gt;switchData();
</span><span class="cx">         out.print(comma, data-&gt;kind);
</span><span class="cx">         for (unsigned i = 0; i &lt; data-&gt;cases.size(); ++i)
</span><del>-            out.print(comma, inContext(data-&gt;cases[i].value, context), &quot;:&quot;, *data-&gt;cases[i].target);
-        out.print(comma, &quot;default:&quot;, *data-&gt;fallThrough);
</del><ins>+            out.print(comma, inContext(data-&gt;cases[i].value, context), &quot;:&quot;, data-&gt;cases[i].target);
+        out.print(comma, &quot;default:&quot;, data-&gt;fallThrough);
</ins><span class="cx">     }
</span><span class="cx">     ClobberSet reads;
</span><span class="cx">     ClobberSet writes;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -829,7 +829,8 @@
</span><span class="cx">     SegmentedVector&lt;StructureSet, 16&gt; m_structureSet;
</span><span class="cx">     SegmentedVector&lt;StructureTransitionData, 8&gt; m_structureTransitionData;
</span><span class="cx">     SegmentedVector&lt;NewArrayBufferData, 4&gt; m_newArrayBufferData;
</span><del>-    SegmentedVector&lt;SwitchData, 4&gt; m_switchData;
</del><ins>+    Bag&lt;BranchData&gt; m_branchData;
+    Bag&lt;SwitchData&gt; m_switchData;
</ins><span class="cx">     Bag&lt;MultiGetByOffsetData&gt; m_multiGetByOffsetData;
</span><span class="cx">     Vector&lt;InlineVariableData, 4&gt; m_inlineVariableData;
</span><span class="cx">     OwnPtr&lt;InlineCallFrameSet&gt; m_inlineCallFrames;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGInPlaceAbstractStatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 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">@@ -363,16 +363,16 @@
</span><span class="cx">     switch (terminal-&gt;op()) {
</span><span class="cx">     case Jump: {
</span><span class="cx">         ASSERT(basicBlock-&gt;cfaBranchDirection == InvalidBranchDirection);
</span><del>-        return merge(basicBlock, terminal-&gt;takenBlock());
</del><ins>+        return merge(basicBlock, terminal-&gt;targetBlock());
</ins><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case Branch: {
</span><span class="cx">         ASSERT(basicBlock-&gt;cfaBranchDirection != InvalidBranchDirection);
</span><span class="cx">         bool changed = false;
</span><span class="cx">         if (basicBlock-&gt;cfaBranchDirection != TakeFalse)
</span><del>-            changed |= merge(basicBlock, terminal-&gt;takenBlock());
</del><ins>+            changed |= merge(basicBlock, terminal-&gt;branchData()-&gt;taken.block);
</ins><span class="cx">         if (basicBlock-&gt;cfaBranchDirection != TakeTrue)
</span><del>-            changed |= merge(basicBlock, terminal-&gt;notTakenBlock());
</del><ins>+            changed |= merge(basicBlock, terminal-&gt;branchData()-&gt;notTaken.block);
</ins><span class="cx">         return changed;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -381,9 +381,9 @@
</span><span class="cx">         // we're not. However I somehow doubt that this will ever be a big deal.
</span><span class="cx">         ASSERT(basicBlock-&gt;cfaBranchDirection == InvalidBranchDirection);
</span><span class="cx">         SwitchData* data = terminal-&gt;switchData();
</span><del>-        bool changed = merge(basicBlock, data-&gt;fallThrough);
</del><ins>+        bool changed = merge(basicBlock, data-&gt;fallThrough.block);
</ins><span class="cx">         for (unsigned i = data-&gt;cases.size(); i--;)
</span><del>-            changed |= merge(basicBlock, data-&gt;cases[i].target);
</del><ins>+            changed |= merge(basicBlock, data-&gt;cases[i].target.block);
</ins><span class="cx">         return changed;
</span><span class="cx">     }
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2013, 2014 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">@@ -160,8 +160,8 @@
</span><span class="cx">     m_jitCode-&gt;common.slowArguments = std::move(m_graph.m_slowArguments);
</span><span class="cx"> 
</span><span class="cx">     BitVector usedJumpTables;
</span><del>-    for (unsigned i = m_graph.m_switchData.size(); i--;) {
-        SwitchData&amp; data = m_graph.m_switchData[i];
</del><ins>+    for (Bag&lt;SwitchData&gt;::iterator iter = m_graph.m_switchData.begin(); !!iter; ++iter) {
+        SwitchData&amp; data = **iter;
</ins><span class="cx">         if (!data.didUseJumpTable)
</span><span class="cx">             continue;
</span><span class="cx">         
</span><span class="lines">@@ -172,14 +172,14 @@
</span><span class="cx">         
</span><span class="cx">         usedJumpTables.set(data.switchTableIndex);
</span><span class="cx">         SimpleJumpTable&amp; table = m_codeBlock-&gt;switchJumpTable(data.switchTableIndex);
</span><del>-        table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough-&gt;index]);
</del><ins>+        table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough.block-&gt;index]);
</ins><span class="cx">         table.ctiOffsets.grow(table.branchOffsets.size());
</span><span class="cx">         for (unsigned j = table.ctiOffsets.size(); j--;)
</span><span class="cx">             table.ctiOffsets[j] = table.ctiDefault;
</span><span class="cx">         for (unsigned j = data.cases.size(); j--;) {
</span><span class="cx">             SwitchCase&amp; myCase = data.cases[j];
</span><span class="cx">             table.ctiOffsets[myCase.value.switchLookupValue() - table.min] =
</span><del>-                linkBuffer.locationOf(m_blockHeads[myCase.target-&gt;index]);
</del><ins>+                linkBuffer.locationOf(m_blockHeads[myCase.target.block-&gt;index]);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -193,8 +193,8 @@
</span><span class="cx">     // NOTE: we cannot clear string switch tables because (1) we're running concurrently
</span><span class="cx">     // and we cannot deref StringImpl's and (2) it would be weird to deref those
</span><span class="cx">     // StringImpl's since we refer to them.
</span><del>-    for (unsigned i = m_graph.m_switchData.size(); i--;) {
-        SwitchData&amp; data = m_graph.m_switchData[i];
</del><ins>+    for (Bag&lt;SwitchData&gt;::iterator switchDataIter = m_graph.m_switchData.begin(); !!switchDataIter; ++switchDataIter) {
+        SwitchData&amp; data = **switchDataIter;
</ins><span class="cx">         if (!data.didUseJumpTable)
</span><span class="cx">             continue;
</span><span class="cx">         
</span><span class="lines">@@ -202,7 +202,7 @@
</span><span class="cx">             continue;
</span><span class="cx">         
</span><span class="cx">         StringJumpTable&amp; table = m_codeBlock-&gt;stringSwitchJumpTable(data.switchTableIndex);
</span><del>-        table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough-&gt;index]);
</del><ins>+        table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough.block-&gt;index]);
</ins><span class="cx">         StringJumpTable::StringOffsetTable::iterator iter;
</span><span class="cx">         StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
</span><span class="cx">         for (iter = table.offsetTable.begin(); iter != end; ++iter)
</span><span class="lines">@@ -211,7 +211,7 @@
</span><span class="cx">             SwitchCase&amp; myCase = data.cases[j];
</span><span class="cx">             iter = table.offsetTable.find(myCase.value.stringImpl());
</span><span class="cx">             RELEASE_ASSERT(iter != end);
</span><del>-            iter-&gt;value.ctiOffset = linkBuffer.locationOf(m_blockHeads[myCase.target-&gt;index]);
</del><ins>+            iter-&gt;value.ctiOffset = linkBuffer.locationOf(m_blockHeads[myCase.target.block-&gt;index]);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 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">@@ -34,6 +34,17 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><ins>+void BranchTarget::dump(PrintStream&amp; out) const
+{
+    if (!block)
+        return;
+    
+    out.print(*block);
+    
+    if (count == count) // If the count is not NaN, then print it.
+        out.print(&quot;/w:&quot;, count);
+}
+
</ins><span class="cx"> unsigned Node::index() const
</span><span class="cx"> {
</span><span class="cx">     return NodeAllocator::allocatorOf(this)-&gt;indexOf(this);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -78,6 +78,55 @@
</span><span class="cx">     IndexingType indexingType;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct BranchTarget {
+    BranchTarget()
+        : block(0)
+        , count(QNaN)
+    {
+    }
+    
+    explicit BranchTarget(BasicBlock* block)
+        : block(block)
+        , count(QNaN)
+    {
+    }
+    
+    void setBytecodeIndex(unsigned bytecodeIndex)
+    {
+        block = bitwise_cast&lt;BasicBlock*&gt;(static_cast&lt;uintptr_t&gt;(bytecodeIndex));
+    }
+    unsigned bytecodeIndex() const { return bitwise_cast&lt;uintptr_t&gt;(block); }
+    
+    void dump(PrintStream&amp;) const;
+    
+    BasicBlock* block;
+    float count;
+};
+
+struct BranchData {
+    static BranchData withBytecodeIndices(
+        unsigned takenBytecodeIndex, unsigned notTakenBytecodeIndex)
+    {
+        BranchData result;
+        result.taken.block = bitwise_cast&lt;BasicBlock*&gt;(static_cast&lt;uintptr_t&gt;(takenBytecodeIndex));
+        result.notTaken.block = bitwise_cast&lt;BasicBlock*&gt;(static_cast&lt;uintptr_t&gt;(notTakenBytecodeIndex));
+        return result;
+    }
+    
+    unsigned takenBytecodeIndex() const { return taken.bytecodeIndex(); }
+    unsigned notTakenBytecodeIndex() const { return notTaken.bytecodeIndex(); }
+    
+    BasicBlock*&amp; forCondition(bool condition)
+    {
+        if (condition)
+            return taken.block;
+        return notTaken.block;
+    }
+    
+    BranchTarget taken;
+    BranchTarget notTaken;
+};
+
</ins><span class="cx"> // The SwitchData and associated data structures duplicate the information in
</span><span class="cx"> // JumpTable. The DFG may ultimately end up using the JumpTable, though it may
</span><span class="cx"> // instead decide to do something different - this is entirely up to the DFG.
</span><span class="lines">@@ -91,7 +140,6 @@
</span><span class="cx"> // values.
</span><span class="cx"> struct SwitchCase {
</span><span class="cx">     SwitchCase()
</span><del>-        : target(0)
</del><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -105,14 +153,12 @@
</span><span class="cx">     {
</span><span class="cx">         SwitchCase result;
</span><span class="cx">         result.value = value;
</span><del>-        result.target = bitwise_cast&lt;BasicBlock*&gt;(static_cast&lt;uintptr_t&gt;(bytecodeIndex));
</del><ins>+        result.target.setBytecodeIndex(bytecodeIndex);
</ins><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    unsigned targetBytecodeIndex() const { return bitwise_cast&lt;uintptr_t&gt;(target); }
-    
</del><span class="cx">     LazyJSValue value;
</span><del>-    BasicBlock* target;
</del><ins>+    BranchTarget target;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> enum SwitchKind {
</span><span class="lines">@@ -126,21 +172,14 @@
</span><span class="cx">     // constructing this should make sure to initialize everything they
</span><span class="cx">     // care about manually.
</span><span class="cx">     SwitchData()
</span><del>-        : fallThrough(0)
-        , kind(static_cast&lt;SwitchKind&gt;(-1))
</del><ins>+        : kind(static_cast&lt;SwitchKind&gt;(-1))
</ins><span class="cx">         , switchTableIndex(UINT_MAX)
</span><span class="cx">         , didUseJumpTable(false)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void setFallThroughBytecodeIndex(unsigned bytecodeIndex)
-    {
-        fallThrough = bitwise_cast&lt;BasicBlock*&gt;(static_cast&lt;uintptr_t&gt;(bytecodeIndex));
-    }
-    unsigned fallThroughBytecodeIndex() const { return bitwise_cast&lt;uintptr_t&gt;(fallThrough); }
-    
</del><span class="cx">     Vector&lt;SwitchCase&gt; cases;
</span><del>-    BasicBlock* fallThrough;
</del><ins>+    BranchTarget fallThrough;
</ins><span class="cx">     SwitchKind kind;
</span><span class="cx">     unsigned switchTableIndex;
</span><span class="cx">     bool didUseJumpTable;
</span><span class="lines">@@ -819,40 +858,22 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    unsigned takenBytecodeOffsetDuringParsing()
</del><ins>+    unsigned targetBytecodeOffsetDuringParsing()
</ins><span class="cx">     {
</span><del>-        ASSERT(isBranch() || isJump());
</del><ins>+        ASSERT(isJump());
</ins><span class="cx">         return m_opInfo;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    unsigned notTakenBytecodeOffsetDuringParsing()
</del><ins>+    BasicBlock*&amp; targetBlock()
</ins><span class="cx">     {
</span><del>-        ASSERT(isBranch());
-        return m_opInfo2;
-    }
-    
-    void setTakenBlock(BasicBlock* block)
-    {
-        ASSERT(isBranch() || isJump());
-        m_opInfo = bitwise_cast&lt;uintptr_t&gt;(block);
-    }
-    
-    void setNotTakenBlock(BasicBlock* block)
-    {
-        ASSERT(isBranch());
-        m_opInfo2 = bitwise_cast&lt;uintptr_t&gt;(block);
-    }
-    
-    BasicBlock*&amp; takenBlock()
-    {
-        ASSERT(isBranch() || isJump());
</del><ins>+        ASSERT(isJump());
</ins><span class="cx">         return *bitwise_cast&lt;BasicBlock**&gt;(&amp;m_opInfo);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    BasicBlock*&amp; notTakenBlock()
</del><ins>+    BranchData* branchData()
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(isBranch());
</span><del>-        return *bitwise_cast&lt;BasicBlock**&gt;(&amp;m_opInfo2);
</del><ins>+        return bitwise_cast&lt;BranchData*&gt;(m_opInfo);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     SwitchData* switchData()
</span><span class="lines">@@ -879,25 +900,26 @@
</span><span class="cx">     {
</span><span class="cx">         if (isSwitch()) {
</span><span class="cx">             if (index &lt; switchData()-&gt;cases.size())
</span><del>-                return switchData()-&gt;cases[index].target;
</del><ins>+                return switchData()-&gt;cases[index].target.block;
</ins><span class="cx">             RELEASE_ASSERT(index == switchData()-&gt;cases.size());
</span><del>-            return switchData()-&gt;fallThrough;
</del><ins>+            return switchData()-&gt;fallThrough.block;
</ins><span class="cx">         }
</span><span class="cx">         switch (index) {
</span><span class="cx">         case 0:
</span><del>-            return takenBlock();
</del><ins>+            if (isJump())
+                return targetBlock();
+            return branchData()-&gt;taken.block;
</ins><span class="cx">         case 1:
</span><del>-            return notTakenBlock();
</del><ins>+            return branchData()-&gt;notTaken.block;
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><del>-            return takenBlock();
</del><ins>+            return targetBlock();
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     BasicBlock*&amp; successorForCondition(bool condition)
</span><span class="cx">     {
</span><del>-        ASSERT(isBranch());
-        return condition ? takenBlock() : notTakenBlock();
</del><ins>+        return branchData()-&gt;forCondition(condition);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool hasHeapPrediction()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2012, 2013, 2014 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">@@ -1097,8 +1097,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compilePeepHoleDoubleBranch(Node* node, Node* branchNode, JITCompiler::DoubleCondition condition)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx">     
</span><span class="cx">     SpeculateDoubleOperand op1(this, node-&gt;child1());
</span><span class="cx">     SpeculateDoubleOperand op2(this, node-&gt;child2());
</span><span class="lines">@@ -1109,8 +1109,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compilePeepHoleObjectEquality(Node* node, Node* branchNode)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx"> 
</span><span class="cx">     MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
</span><span class="cx">     
</span><span class="lines">@@ -1185,8 +1185,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compilePeepHoleBooleanBranch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx"> 
</span><span class="cx">     // The branch instruction will branch to the taken block.
</span><span class="cx">     // If taken is next, switch taken with notTaken &amp; invert the branch condition so we can fall through.
</span><span class="lines">@@ -1216,8 +1216,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compilePeepHoleInt32Branch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx"> 
</span><span class="cx">     // The branch instruction will branch to the taken block.
</span><span class="cx">     // If taken is next, switch taken with notTaken &amp; invert the branch condition so we can fall through.
</span><span class="lines">@@ -3637,8 +3637,8 @@
</span><span class="cx">     unsigned branchIndexInBlock = detectPeepHoleBranch();
</span><span class="cx">     if (branchIndexInBlock != UINT_MAX) {
</span><span class="cx">         Node* branchNode = m_block-&gt;at(branchIndexInBlock);
</span><del>-        BasicBlock* taken = branchNode-&gt;takenBlock();
-        BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+        BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+        BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx">         MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
</span><span class="cx">         
</span><span class="cx">         // The branch instruction will branch to the taken block.
</span><span class="lines">@@ -4213,8 +4213,8 @@
</span><span class="cx">     Node* branchNode = m_block-&gt;at(branchIndexInBlock);
</span><span class="cx">     ASSERT(node-&gt;adjustedRefCount() == 1);
</span><span class="cx"> 
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx">     
</span><span class="cx">     bool invert = false;
</span><span class="cx">     if (taken == nextBlock()) {
</span><span class="lines">@@ -4895,7 +4895,7 @@
</span><span class="cx">     m_jit.sub32(Imm32(table.min), value);
</span><span class="cx">     addBranch(
</span><span class="cx">         m_jit.branch32(JITCompiler::AboveOrEqual, value, Imm32(table.ctiOffsets.size())),
</span><del>-        data-&gt;fallThrough);
</del><ins>+        data-&gt;fallThrough.block);
</ins><span class="cx">     m_jit.move(TrustedImmPtr(table.ctiOffsets.begin()), scratch);
</span><span class="cx">     m_jit.loadPtr(JITCompiler::BaseIndex(scratch, value, JITCompiler::timesPtr()), scratch);
</span><span class="cx">     m_jit.jump(scratch);
</span><span class="lines">@@ -4929,7 +4929,7 @@
</span><span class="cx">         addBranch(
</span><span class="cx">             m_jit.branchTest64(
</span><span class="cx">                 JITCompiler::Zero, valueRegs.gpr(), GPRInfo::tagTypeNumberRegister),
</span><del>-            data-&gt;fallThrough);
</del><ins>+            data-&gt;fallThrough.block);
</ins><span class="cx">         silentSpillAllRegisters(scratch);
</span><span class="cx">         callOperation(operationFindSwitchImmTargetForDouble, scratch, valueRegs.gpr(), data-&gt;switchTableIndex);
</span><span class="cx">         silentFillAllRegisters(scratch);
</span><span class="lines">@@ -4943,7 +4943,7 @@
</span><span class="cx">             m_jit.branch32(
</span><span class="cx">                 JITCompiler::AboveOrEqual, valueRegs.tagGPR(),
</span><span class="cx">                 TrustedImm32(JSValue::LowestTag)),
</span><del>-            data-&gt;fallThrough);
</del><ins>+            data-&gt;fallThrough.block);
</ins><span class="cx">         silentSpillAllRegisters(scratch);
</span><span class="cx">         callOperation(operationFindSwitchImmTargetForDouble, scratch, valueRegs, data-&gt;switchTableIndex);
</span><span class="cx">         silentFillAllRegisters(scratch);
</span><span class="lines">@@ -4967,7 +4967,7 @@
</span><span class="cx">             MacroAssembler::NotEqual,
</span><span class="cx">             MacroAssembler::Address(value, JSString::offsetOfLength()),
</span><span class="cx">             TrustedImm32(1)),
</span><del>-        data-&gt;fallThrough);
</del><ins>+        data-&gt;fallThrough.block);
</ins><span class="cx">     
</span><span class="cx">     m_jit.loadPtr(MacroAssembler::Address(value, JSString::offsetOfValue()), scratch);
</span><span class="cx">     
</span><span class="lines">@@ -5025,12 +5025,12 @@
</span><span class="cx">         addBranch(
</span><span class="cx">             m_jit.branchTest64(
</span><span class="cx">                 MacroAssembler::NonZero, op1Regs.gpr(), GPRInfo::tagMaskRegister),
</span><del>-            data-&gt;fallThrough);
</del><ins>+            data-&gt;fallThrough.block);
</ins><span class="cx"> #else
</span><span class="cx">         addBranch(
</span><span class="cx">             m_jit.branch32(
</span><span class="cx">                 MacroAssembler::NotEqual, op1Regs.tagGPR(), TrustedImm32(JSValue::CellTag)),
</span><del>-            data-&gt;fallThrough);
</del><ins>+            data-&gt;fallThrough.block);
</ins><span class="cx"> #endif
</span><span class="cx">         
</span><span class="cx">         addBranch(
</span><span class="lines">@@ -5038,7 +5038,7 @@
</span><span class="cx">                 MacroAssembler::NotEqual,
</span><span class="cx">                 MacroAssembler::Address(op1Regs.payloadGPR(), JSCell::structureOffset()),
</span><span class="cx">                 MacroAssembler::TrustedImmPtr(m_jit.vm()-&gt;stringStructure.get())),
</span><del>-            data-&gt;fallThrough);
</del><ins>+            data-&gt;fallThrough.block);
</ins><span class="cx">         
</span><span class="cx">         emitSwitchCharStringJump(data, op1Regs.payloadGPR(), tempGPR);
</span><span class="cx">         noResult(node, UseChildrenCalledExplicitly);
</span><span class="lines">@@ -5093,7 +5093,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     if (begin == end) {
</span><del>-        jump(data-&gt;fallThrough, ForceJump);
</del><ins>+        jump(data-&gt;fallThrough.block, ForceJump);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -5129,14 +5129,14 @@
</span><span class="cx">         dataLog(&quot;length = &quot;, minLength, &quot;, commonChars = &quot;, commonChars, &quot;, allLengthsEqual = &quot;, allLengthsEqual, &quot;\n&quot;);
</span><span class="cx">     
</span><span class="cx">     if (!allLengthsEqual &amp;&amp; alreadyCheckedLength &lt; minLength)
</span><del>-        branch32(MacroAssembler::Below, length, Imm32(minLength), data-&gt;fallThrough);
</del><ins>+        branch32(MacroAssembler::Below, length, Imm32(minLength), data-&gt;fallThrough.block);
</ins><span class="cx">     if (allLengthsEqual &amp;&amp; (alreadyCheckedLength &lt; minLength || !checkedExactLength))
</span><del>-        branch32(MacroAssembler::NotEqual, length, Imm32(minLength), data-&gt;fallThrough);
</del><ins>+        branch32(MacroAssembler::NotEqual, length, Imm32(minLength), data-&gt;fallThrough.block);
</ins><span class="cx">     
</span><span class="cx">     for (unsigned i = numChecked; i &lt; commonChars; ++i) {
</span><span class="cx">         branch8(
</span><span class="cx">             MacroAssembler::NotEqual, MacroAssembler::Address(buffer, i),
</span><del>-            TrustedImm32(cases[begin].string-&gt;at(i)), data-&gt;fallThrough);
</del><ins>+            TrustedImm32(cases[begin].string-&gt;at(i)), data-&gt;fallThrough.block);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     if (minLength == commonChars) {
</span><span class="lines">@@ -5206,7 +5206,7 @@
</span><span class="cx">             temp, minLength, allLengthsEqual);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    addBranch(binarySwitch.fallThrough(), data-&gt;fallThrough);
</del><ins>+    addBranch(binarySwitch.fallThrough(), data-&gt;fallThrough.block);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::emitSwitchStringOnString(SwitchData* data, GPRReg string)
</span><span class="lines">@@ -5258,7 +5258,7 @@
</span><span class="cx">     Vector&lt;StringSwitchCase&gt; cases;
</span><span class="cx">     for (unsigned i = 0; i &lt; data-&gt;cases.size(); ++i) {
</span><span class="cx">         cases.append(
</span><del>-            StringSwitchCase(data-&gt;cases[i].value.stringImpl(), data-&gt;cases[i].target));
</del><ins>+            StringSwitchCase(data-&gt;cases[i].value.stringImpl(), data-&gt;cases[i].target.block));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     std::sort(cases.begin(), cases.end());
</span><span class="lines">@@ -5294,8 +5294,8 @@
</span><span class="cx">         
</span><span class="cx">         BinarySwitch binarySwitch(tempGPR, identifierCaseValues, BinarySwitch::IntPtr);
</span><span class="cx">         while (binarySwitch.advance(m_jit))
</span><del>-            jump(data-&gt;cases[binarySwitch.caseIndex()].target, ForceJump);
-        addBranch(binarySwitch.fallThrough(), data-&gt;fallThrough);
</del><ins>+            jump(data-&gt;cases[binarySwitch.caseIndex()].target.block, ForceJump);
+        addBranch(binarySwitch.fallThrough(), data-&gt;fallThrough.block);
</ins><span class="cx">         
</span><span class="cx">         noResult(node);
</span><span class="cx">         break;
</span><span class="lines">@@ -5325,12 +5325,12 @@
</span><span class="cx">         addBranch(
</span><span class="cx">             m_jit.branchTest64(
</span><span class="cx">                 MacroAssembler::NonZero, op1Regs.gpr(), GPRInfo::tagMaskRegister),
</span><del>-            data-&gt;fallThrough);
</del><ins>+            data-&gt;fallThrough.block);
</ins><span class="cx"> #else
</span><span class="cx">         addBranch(
</span><span class="cx">             m_jit.branch32(
</span><span class="cx">                 MacroAssembler::NotEqual, op1Regs.tagGPR(), TrustedImm32(JSValue::CellTag)),
</span><del>-            data-&gt;fallThrough);
</del><ins>+            data-&gt;fallThrough.block);
</ins><span class="cx"> #endif
</span><span class="cx">         
</span><span class="cx">         addBranch(
</span><span class="lines">@@ -5338,7 +5338,7 @@
</span><span class="cx">                 MacroAssembler::NotEqual,
</span><span class="cx">                 MacroAssembler::Address(op1Regs.payloadGPR(), JSCell::structureOffset()),
</span><span class="cx">                 MacroAssembler::TrustedImmPtr(m_jit.vm()-&gt;stringStructure.get())),
</span><del>-            data-&gt;fallThrough);
</del><ins>+            data-&gt;fallThrough.block);
</ins><span class="cx">         
</span><span class="cx">         emitSwitchStringOnString(data, op1Regs.payloadGPR());
</span><span class="cx">         noResult(node, UseChildrenCalledExplicitly);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -281,8 +281,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branchNode, bool invert)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx">     
</span><span class="cx">     if (taken == nextBlock()) {
</span><span class="cx">         invert = !invert;
</span><span class="lines">@@ -361,8 +361,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::nonSpeculativePeepholeBranch(Node* node, Node* branchNode, MacroAssembler::RelationalCondition cond, S_JITOperation_EJJ helperFunction)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx"> 
</span><span class="cx">     JITCompiler::ResultCondition callResultCondition = JITCompiler::NonZero;
</span><span class="cx"> 
</span><span class="lines">@@ -514,8 +514,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node* node, Node* branchNode, bool invert)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx"> 
</span><span class="cx">     // The branch instruction will branch to the taken block.
</span><span class="cx">     // If taken is next, switch taken with notTaken &amp; invert the branch condition so we can fall through.
</span><span class="lines">@@ -1291,8 +1291,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx">     
</span><span class="cx">     SpeculateCellOperand op1(this, leftChild);
</span><span class="cx">     JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
</span><span class="lines">@@ -1615,8 +1615,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::emitBranch(Node* node)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = node-&gt;takenBlock();
-    BasicBlock* notTaken = node-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = node-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = node-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx"> 
</span><span class="cx">     switch (node-&gt;child1().useKind()) {
</span><span class="cx">     case BooleanUse: {
</span><span class="lines">@@ -3009,7 +3009,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case DFG::Jump: {
</span><del>-        jump(node-&gt;takenBlock());
</del><ins>+        jump(node-&gt;branchData()-&gt;taken.block);
</ins><span class="cx">         noResult(node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -285,8 +285,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branchNode, bool invert)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx">     
</span><span class="cx">     if (taken == nextBlock()) {
</span><span class="cx">         invert = !invert;
</span><span class="lines">@@ -363,8 +363,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::nonSpeculativePeepholeBranch(Node* node, Node* branchNode, MacroAssembler::RelationalCondition cond, S_JITOperation_EJJ helperFunction)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx"> 
</span><span class="cx">     JITCompiler::ResultCondition callResultCondition = JITCompiler::NonZero;
</span><span class="cx"> 
</span><span class="lines">@@ -507,8 +507,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node* node, Node* branchNode, bool invert)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx"> 
</span><span class="cx">     // The branch instruction will branch to the taken block.
</span><span class="cx">     // If taken is next, switch taken with notTaken &amp; invert the branch condition so we can fall through.
</span><span class="lines">@@ -1669,8 +1669,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx">     
</span><span class="cx">     SpeculateCellOperand op1(this, leftChild);
</span><span class="cx">     JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
</span><span class="lines">@@ -1792,8 +1792,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compilePeepHoleInt52Branch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = branchNode-&gt;takenBlock();
-    BasicBlock* notTaken = branchNode-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = branchNode-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = branchNode-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx"> 
</span><span class="cx">     // The branch instruction will branch to the taken block.
</span><span class="cx">     // If taken is next, switch taken with notTaken &amp; invert the branch condition so we can fall through.
</span><span class="lines">@@ -2032,8 +2032,8 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::emitBranch(Node* node)
</span><span class="cx"> {
</span><del>-    BasicBlock* taken = node-&gt;takenBlock();
-    BasicBlock* notTaken = node-&gt;notTakenBlock();
</del><ins>+    BasicBlock* taken = node-&gt;branchData()-&gt;taken.block;
+    BasicBlock* notTaken = node-&gt;branchData()-&gt;notTaken.block;
</ins><span class="cx">     
</span><span class="cx">     switch (node-&gt;child1().useKind()) {
</span><span class="cx">     case ObjectOrOtherUse: {
</span><span class="lines">@@ -3369,7 +3369,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case DFG::Jump: {
</span><del>-        jump(node-&gt;takenBlock());
</del><ins>+        jump(node-&gt;targetBlock());
</ins><span class="cx">         noResult(node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (164416 => 164417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-02-20 07:12:08 UTC (rev 164416)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-02-20 08:00:28 UTC (rev 164417)
</span><span class="lines">@@ -3487,25 +3487,23 @@
</span><span class="cx">     
</span><span class="cx">     void compileJump()
</span><span class="cx">     {
</span><del>-        m_out.jump(lowBlock(m_node-&gt;takenBlock()));
</del><ins>+        m_out.jump(lowBlock(m_node-&gt;targetBlock()));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileBranch()
</span><span class="cx">     {
</span><del>-        // FIXME: DFG should be able to tell us branch weights here.
-        // https://bugs.webkit.org/show_bug.cgi?id=129055
-        
</del><span class="cx">         m_out.branch(
</span><span class="cx">             boolify(m_node-&gt;child1()),
</span><del>-            unsure(lowBlock(m_node-&gt;takenBlock())),
-            unsure(lowBlock(m_node-&gt;notTakenBlock())));
</del><ins>+            WeightedTarget(
+                lowBlock(m_node-&gt;branchData()-&gt;taken.block),
+                m_node-&gt;branchData()-&gt;taken.count),
+            WeightedTarget(
+                lowBlock(m_node-&gt;branchData()-&gt;notTaken.block),
+                m_node-&gt;branchData()-&gt;notTaken.count));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileSwitch()
</span><span class="cx">     {
</span><del>-        // FIXME: DFG should be able to tell us branch weights here.
-        // https://bugs.webkit.org/show_bug.cgi?id=129055
-        
</del><span class="cx">         SwitchData* data = m_node-&gt;switchData();
</span><span class="cx">         switch (data-&gt;kind) {
</span><span class="cx">         case SwitchImm: {
</span><span class="lines">@@ -3537,7 +3535,7 @@
</span><span class="cx">                 m_out.appendTo(isNotInt, isDouble);
</span><span class="cx">                 m_out.branch(
</span><span class="cx">                     isCellOrMisc(boxedValue),
</span><del>-                    usually(lowBlock(data-&gt;fallThrough)), rarely(isDouble));
</del><ins>+                    usually(lowBlock(data-&gt;fallThrough.block)), rarely(isDouble));
</ins><span class="cx">                 
</span><span class="cx">                 m_out.appendTo(isDouble, innerLastNext);
</span><span class="cx">                 LValue doubleValue = unboxDouble(boxedValue);
</span><span class="lines">@@ -3545,7 +3543,7 @@
</span><span class="cx">                 intValues.append(m_out.anchor(intInDouble));
</span><span class="cx">                 m_out.branch(
</span><span class="cx">                     m_out.doubleEqual(m_out.intToDouble(intInDouble), doubleValue),
</span><del>-                    unsure(switchOnInts), unsure(lowBlock(data-&gt;fallThrough)));
</del><ins>+                    unsure(switchOnInts), unsure(lowBlock(data-&gt;fallThrough.block)));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">                 
</span><span class="lines">@@ -3562,6 +3560,12 @@
</span><span class="cx">         case SwitchChar: {
</span><span class="cx">             LValue stringValue;
</span><span class="cx">             
</span><ins>+            // FIXME: We should use something other than unsure() for the branch weight
+            // of the fallThrough block. The main challenge is just that we have multiple
+            // branches to fallThrough but a single count, so we would need to divvy it up
+            // among the different lowered branches.
+            // https://bugs.webkit.org/show_bug.cgi?id=129082
+            
</ins><span class="cx">             switch (m_node-&gt;child1().useKind()) {
</span><span class="cx">             case StringUse: {
</span><span class="cx">                 stringValue = lowString(m_node-&gt;child1());
</span><span class="lines">@@ -3576,13 +3580,13 @@
</span><span class="cx">                 
</span><span class="cx">                 m_out.branch(
</span><span class="cx">                     isNotCell(unboxedValue),
</span><del>-                    unsure(lowBlock(data-&gt;fallThrough)), unsure(isCellCase));
</del><ins>+                    unsure(lowBlock(data-&gt;fallThrough.block)), unsure(isCellCase));
</ins><span class="cx">                 
</span><span class="cx">                 LBasicBlock lastNext = m_out.appendTo(isCellCase, isStringCase);
</span><span class="cx">                 LValue cellValue = unboxedValue;
</span><span class="cx">                 m_out.branch(
</span><span class="cx">                     isNotString(cellValue),
</span><del>-                    unsure(lowBlock(data-&gt;fallThrough)), unsure(isStringCase));
</del><ins>+                    unsure(lowBlock(data-&gt;fallThrough.block)), unsure(isStringCase));
</ins><span class="cx">                 
</span><span class="cx">                 m_out.appendTo(isStringCase, lastNext);
</span><span class="cx">                 stringValue = cellValue;
</span><span class="lines">@@ -3605,7 +3609,7 @@
</span><span class="cx">                 m_out.notEqual(
</span><span class="cx">                     m_out.load32NonNegative(stringValue, m_heaps.JSString_length),
</span><span class="cx">                     m_out.int32One),
</span><del>-                unsure(lowBlock(data-&gt;fallThrough)), unsure(lengthIs1));
</del><ins>+                unsure(lowBlock(data-&gt;fallThrough.block)), unsure(lengthIs1));
</ins><span class="cx">             
</span><span class="cx">             LBasicBlock lastNext = m_out.appendTo(lengthIs1, needResolution);
</span><span class="cx">             Vector&lt;ValueFromBlock, 2&gt; values;
</span><span class="lines">@@ -4188,10 +4192,12 @@
</span><span class="cx">         for (unsigned i = 0; i &lt; data-&gt;cases.size(); ++i) {
</span><span class="cx">             cases.append(SwitchCase(
</span><span class="cx">                 constInt(type, data-&gt;cases[i].value.switchLookupValue()),
</span><del>-                lowBlock(data-&gt;cases[i].target), Weight()));
</del><ins>+                lowBlock(data-&gt;cases[i].target.block), Weight(data-&gt;cases[i].target.count)));
</ins><span class="cx">         }
</span><span class="cx">         
</span><del>-        m_out.switchInstruction(switchValue, cases, lowBlock(data-&gt;fallThrough), Weight());
</del><ins>+        m_out.switchInstruction(
+            switchValue, cases,
+            lowBlock(data-&gt;fallThrough.block), Weight(data-&gt;fallThrough.count));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     LValue doubleToInt32(LValue doubleValue, double low, double high, bool isSigned = true)
</span></span></pre>
</div>
</div>

</body>
</html>