<!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 <fpizlo@apple.com>
+
+ 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 <changseok.oh@collabora.com>
</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->isLinked);
</span><span class="cx"> Node* node = blockToLink->last();
</span><span class="cx"> ASSERT(node->op() == Jump);
</span><del>- ASSERT(node->takenBlock() == 0);
- node->setTakenBlock(block.get());
</del><ins>+ ASSERT(!node->targetBlock());
+ node->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->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& data = *m_graph.m_switchData.add();
</ins><span class="cx"> data.kind = SwitchImm;
</span><span class="cx"> data.switchTableIndex = m_inlineStackTop->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& table = m_codeBlock->switchJumpTable(data.switchTableIndex);
</span><span class="cx"> for (unsigned i = 0; i < 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<int32_t>(table.min + i)), target));
</span><span class="cx"> }
</span><del>- m_graph.m_switchData.append(data);
- addToGraph(Switch, OpInfo(&m_graph.m_switchData.last()), get(VirtualRegister(currentInstruction[3].u.operand)));
</del><ins>+ addToGraph(Switch, OpInfo(&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& data = *m_graph.m_switchData.add();
</ins><span class="cx"> data.kind = SwitchChar;
</span><span class="cx"> data.switchTableIndex = m_inlineStackTop->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& table = m_codeBlock->switchJumpTable(data.switchTableIndex);
</span><span class="cx"> for (unsigned i = 0; i < 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(&m_graph.m_switchData.last()), get(VirtualRegister(currentInstruction[3].u.operand)));
</del><ins>+ addToGraph(Switch, OpInfo(&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& 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& table = m_codeBlock->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->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->key.get()), target));
</span><span class="cx"> }
</span><del>- m_graph.m_switchData.append(data);
- addToGraph(Switch, OpInfo(&m_graph.m_switchData.last()), get(VirtualRegister(currentInstruction[3].u.operand)));
</del><ins>+ addToGraph(Switch, OpInfo(&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->op()) {
</span><span class="cx"> case Jump:
</span><del>- node->setTakenBlock(blockForBytecodeOffset(possibleTargets, node->takenBytecodeOffsetDuringParsing()));
</del><ins>+ node->targetBlock() = blockForBytecodeOffset(possibleTargets, node->targetBytecodeOffsetDuringParsing());
</ins><span class="cx"> break;
</span><span class="cx">
</span><del>- case Branch:
- node->setTakenBlock(blockForBytecodeOffset(possibleTargets, node->takenBytecodeOffsetDuringParsing()));
- node->setNotTakenBlock(blockForBytecodeOffset(possibleTargets, node->notTakenBytecodeOffsetDuringParsing()));
</del><ins>+ case Branch: {
+ BranchData* data = node->branchData();
+ data->taken.block = blockForBytecodeOffset(possibleTargets, data->takenBytecodeIndex());
+ data->notTaken.block = blockForBytecodeOffset(possibleTargets, data->notTakenBytecodeIndex());
</ins><span class="cx"> break;
</span><ins>+ }
</ins><span class="cx">
</span><del>- case Switch:
</del><ins>+ case Switch: {
+ SwitchData* data = node->switchData();
</ins><span class="cx"> for (unsigned i = node->switchData()->cases.size(); i--;)
</span><del>- node->switchData()->cases[i].target = blockForBytecodeOffset(possibleTargets, node->switchData()->cases[i].targetBytecodeIndex());
- node->switchData()->fallThrough = blockForBytecodeOffset(possibleTargets, node->switchData()->fallThroughBytecodeIndex());
</del><ins>+ data->cases[i].target.block = blockForBytecodeOffset(possibleTargets, data->cases[i].target.bytecodeIndex());
+ data->fallThrough.block = blockForBytecodeOffset(possibleTargets, data->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 < data->cases.size(); ++i) {
</span><del>- if (data->cases[i].target == data->fallThrough)
- data->cases[i--] = data->cases.takeLast();
</del><ins>+ if (data->cases[i].target.block == data->fallThrough.block) {
+ data->fallThrough.count += data->cases[i].target.count;
+ data->cases[i--] = data->cases.last();
+ data->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->cases.isEmpty()) {
</span><del>- convertToJump(block, data->fallThrough);
</del><ins>+ convertToJump(block, data->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->cases.size(); found == FalseTriState && i--;) {
</span><span class="cx"> found = data->cases[i].value.strictEqual(value);
</span><span class="cx"> if (found == TrueTriState)
</span><del>- targetBlock = data->cases[i].target;
</del><ins>+ targetBlock = data->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->fallThrough;
</del><ins>+ targetBlock = data->fallThrough.block;
</ins><span class="cx"> ASSERT(targetBlock);
</span><span class="cx">
</span><span class="cx"> Vector<BasicBlock*, 1> 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->hasBooleanResult()) {
</span><span class="cx"> node->children.setChild1(newChildEdge);
</span><span class="cx">
</span><del>- BasicBlock* toBeTaken = node->notTakenBlock();
- BasicBlock* toBeNotTaken = node->takenBlock();
- node->setTakenBlock(toBeTaken);
- node->setNotTakenBlock(toBeNotTaken);
</del><ins>+ BranchData* data = node->branchData();
+ std::swap(data->taken, data->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->weakConstant()), " (", inContext(*node->weakConstant()->structure(), context), ")");
</span><del>- if (node->isBranch() || node->isJump())
- out.print(comma, "T:", *node->takenBlock());
</del><ins>+ if (node->isJump())
+ out.print(comma, "T:", *node->targetBlock());
</ins><span class="cx"> if (node->isBranch())
</span><del>- out.print(comma, "F:", *node->notTakenBlock());
</del><ins>+ out.print(comma, "T:", node->branchData()->taken, ", F:", node->branchData()->notTaken);
</ins><span class="cx"> if (node->isSwitch()) {
</span><span class="cx"> SwitchData* data = node->switchData();
</span><span class="cx"> out.print(comma, data->kind);
</span><span class="cx"> for (unsigned i = 0; i < data->cases.size(); ++i)
</span><del>- out.print(comma, inContext(data->cases[i].value, context), ":", *data->cases[i].target);
- out.print(comma, "default:", *data->fallThrough);
</del><ins>+ out.print(comma, inContext(data->cases[i].value, context), ":", data->cases[i].target);
+ out.print(comma, "default:", data->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<StructureSet, 16> m_structureSet;
</span><span class="cx"> SegmentedVector<StructureTransitionData, 8> m_structureTransitionData;
</span><span class="cx"> SegmentedVector<NewArrayBufferData, 4> m_newArrayBufferData;
</span><del>- SegmentedVector<SwitchData, 4> m_switchData;
</del><ins>+ Bag<BranchData> m_branchData;
+ Bag<SwitchData> m_switchData;
</ins><span class="cx"> Bag<MultiGetByOffsetData> m_multiGetByOffsetData;
</span><span class="cx"> Vector<InlineVariableData, 4> m_inlineVariableData;
</span><span class="cx"> OwnPtr<InlineCallFrameSet> 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->op()) {
</span><span class="cx"> case Jump: {
</span><span class="cx"> ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
</span><del>- return merge(basicBlock, terminal->takenBlock());
</del><ins>+ return merge(basicBlock, terminal->targetBlock());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case Branch: {
</span><span class="cx"> ASSERT(basicBlock->cfaBranchDirection != InvalidBranchDirection);
</span><span class="cx"> bool changed = false;
</span><span class="cx"> if (basicBlock->cfaBranchDirection != TakeFalse)
</span><del>- changed |= merge(basicBlock, terminal->takenBlock());
</del><ins>+ changed |= merge(basicBlock, terminal->branchData()->taken.block);
</ins><span class="cx"> if (basicBlock->cfaBranchDirection != TakeTrue)
</span><del>- changed |= merge(basicBlock, terminal->notTakenBlock());
</del><ins>+ changed |= merge(basicBlock, terminal->branchData()->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->cfaBranchDirection == InvalidBranchDirection);
</span><span class="cx"> SwitchData* data = terminal->switchData();
</span><del>- bool changed = merge(basicBlock, data->fallThrough);
</del><ins>+ bool changed = merge(basicBlock, data->fallThrough.block);
</ins><span class="cx"> for (unsigned i = data->cases.size(); i--;)
</span><del>- changed |= merge(basicBlock, data->cases[i].target);
</del><ins>+ changed |= merge(basicBlock, data->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->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& data = m_graph.m_switchData[i];
</del><ins>+ for (Bag<SwitchData>::iterator iter = m_graph.m_switchData.begin(); !!iter; ++iter) {
+ SwitchData& 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& table = m_codeBlock->switchJumpTable(data.switchTableIndex);
</span><del>- table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough->index]);
</del><ins>+ table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough.block->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& myCase = data.cases[j];
</span><span class="cx"> table.ctiOffsets[myCase.value.switchLookupValue() - table.min] =
</span><del>- linkBuffer.locationOf(m_blockHeads[myCase.target->index]);
</del><ins>+ linkBuffer.locationOf(m_blockHeads[myCase.target.block->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& data = m_graph.m_switchData[i];
</del><ins>+ for (Bag<SwitchData>::iterator switchDataIter = m_graph.m_switchData.begin(); !!switchDataIter; ++switchDataIter) {
+ SwitchData& 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& table = m_codeBlock->stringSwitchJumpTable(data.switchTableIndex);
</span><del>- table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough->index]);
</del><ins>+ table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough.block->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& 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->value.ctiOffset = linkBuffer.locationOf(m_blockHeads[myCase.target->index]);
</del><ins>+ iter->value.ctiOffset = linkBuffer.locationOf(m_blockHeads[myCase.target.block->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& out) const
+{
+ if (!block)
+ return;
+
+ out.print(*block);
+
+ if (count == count) // If the count is not NaN, then print it.
+ out.print("/w:", count);
+}
+
</ins><span class="cx"> unsigned Node::index() const
</span><span class="cx"> {
</span><span class="cx"> return NodeAllocator::allocatorOf(this)->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<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
+ }
+ unsigned bytecodeIndex() const { return bitwise_cast<uintptr_t>(block); }
+
+ void dump(PrintStream&) const;
+
+ BasicBlock* block;
+ float count;
+};
+
+struct BranchData {
+ static BranchData withBytecodeIndices(
+ unsigned takenBytecodeIndex, unsigned notTakenBytecodeIndex)
+ {
+ BranchData result;
+ result.taken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(takenBytecodeIndex));
+ result.notTaken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(notTakenBytecodeIndex));
+ return result;
+ }
+
+ unsigned takenBytecodeIndex() const { return taken.bytecodeIndex(); }
+ unsigned notTakenBytecodeIndex() const { return notTaken.bytecodeIndex(); }
+
+ BasicBlock*& 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<BasicBlock*>(static_cast<uintptr_t>(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<uintptr_t>(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<SwitchKind>(-1))
</del><ins>+ : kind(static_cast<SwitchKind>(-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<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
- }
- unsigned fallThroughBytecodeIndex() const { return bitwise_cast<uintptr_t>(fallThrough); }
-
</del><span class="cx"> Vector<SwitchCase> 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*& targetBlock()
</ins><span class="cx"> {
</span><del>- ASSERT(isBranch());
- return m_opInfo2;
- }
-
- void setTakenBlock(BasicBlock* block)
- {
- ASSERT(isBranch() || isJump());
- m_opInfo = bitwise_cast<uintptr_t>(block);
- }
-
- void setNotTakenBlock(BasicBlock* block)
- {
- ASSERT(isBranch());
- m_opInfo2 = bitwise_cast<uintptr_t>(block);
- }
-
- BasicBlock*& takenBlock()
- {
- ASSERT(isBranch() || isJump());
</del><ins>+ ASSERT(isJump());
</ins><span class="cx"> return *bitwise_cast<BasicBlock**>(&m_opInfo);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- BasicBlock*& notTakenBlock()
</del><ins>+ BranchData* branchData()
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(isBranch());
</span><del>- return *bitwise_cast<BasicBlock**>(&m_opInfo2);
</del><ins>+ return bitwise_cast<BranchData*>(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 < switchData()->cases.size())
</span><del>- return switchData()->cases[index].target;
</del><ins>+ return switchData()->cases[index].target.block;
</ins><span class="cx"> RELEASE_ASSERT(index == switchData()->cases.size());
</span><del>- return switchData()->fallThrough;
</del><ins>+ return switchData()->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()->taken.block;
</ins><span class="cx"> case 1:
</span><del>- return notTakenBlock();
</del><ins>+ return branchData()->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*& successorForCondition(bool condition)
</span><span class="cx"> {
</span><del>- ASSERT(isBranch());
- return condition ? takenBlock() : notTakenBlock();
</del><ins>+ return branchData()->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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
</ins><span class="cx">
</span><span class="cx"> SpeculateDoubleOperand op1(this, node->child1());
</span><span class="cx"> SpeculateDoubleOperand op2(this, node->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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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 & 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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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 & 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->at(branchIndexInBlock);
</span><del>- BasicBlock* taken = branchNode->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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->at(branchIndexInBlock);
</span><span class="cx"> ASSERT(node->adjustedRefCount() == 1);
</span><span class="cx">
</span><del>- BasicBlock* taken = branchNode->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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->fallThrough);
</del><ins>+ data->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->fallThrough);
</del><ins>+ data->fallThrough.block);
</ins><span class="cx"> silentSpillAllRegisters(scratch);
</span><span class="cx"> callOperation(operationFindSwitchImmTargetForDouble, scratch, valueRegs.gpr(), data->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->fallThrough);
</del><ins>+ data->fallThrough.block);
</ins><span class="cx"> silentSpillAllRegisters(scratch);
</span><span class="cx"> callOperation(operationFindSwitchImmTargetForDouble, scratch, valueRegs, data->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->fallThrough);
</del><ins>+ data->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->fallThrough);
</del><ins>+ data->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->fallThrough);
</del><ins>+ data->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()->stringStructure.get())),
</span><del>- data->fallThrough);
</del><ins>+ data->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->fallThrough, ForceJump);
</del><ins>+ jump(data->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("length = ", minLength, ", commonChars = ", commonChars, ", allLengthsEqual = ", allLengthsEqual, "\n");
</span><span class="cx">
</span><span class="cx"> if (!allLengthsEqual && alreadyCheckedLength < minLength)
</span><del>- branch32(MacroAssembler::Below, length, Imm32(minLength), data->fallThrough);
</del><ins>+ branch32(MacroAssembler::Below, length, Imm32(minLength), data->fallThrough.block);
</ins><span class="cx"> if (allLengthsEqual && (alreadyCheckedLength < minLength || !checkedExactLength))
</span><del>- branch32(MacroAssembler::NotEqual, length, Imm32(minLength), data->fallThrough);
</del><ins>+ branch32(MacroAssembler::NotEqual, length, Imm32(minLength), data->fallThrough.block);
</ins><span class="cx">
</span><span class="cx"> for (unsigned i = numChecked; i < commonChars; ++i) {
</span><span class="cx"> branch8(
</span><span class="cx"> MacroAssembler::NotEqual, MacroAssembler::Address(buffer, i),
</span><del>- TrustedImm32(cases[begin].string->at(i)), data->fallThrough);
</del><ins>+ TrustedImm32(cases[begin].string->at(i)), data->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->fallThrough);
</del><ins>+ addBranch(binarySwitch.fallThrough(), data->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<StringSwitchCase> cases;
</span><span class="cx"> for (unsigned i = 0; i < data->cases.size(); ++i) {
</span><span class="cx"> cases.append(
</span><del>- StringSwitchCase(data->cases[i].value.stringImpl(), data->cases[i].target));
</del><ins>+ StringSwitchCase(data->cases[i].value.stringImpl(), data->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->cases[binarySwitch.caseIndex()].target, ForceJump);
- addBranch(binarySwitch.fallThrough(), data->fallThrough);
</del><ins>+ jump(data->cases[binarySwitch.caseIndex()].target.block, ForceJump);
+ addBranch(binarySwitch.fallThrough(), data->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->fallThrough);
</del><ins>+ data->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->fallThrough);
</del><ins>+ data->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()->stringStructure.get())),
</span><del>- data->fallThrough);
</del><ins>+ data->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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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 & 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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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->takenBlock();
- BasicBlock* notTaken = node->notTakenBlock();
</del><ins>+ BasicBlock* taken = node->branchData()->taken.block;
+ BasicBlock* notTaken = node->branchData()->notTaken.block;
</ins><span class="cx">
</span><span class="cx"> switch (node->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->takenBlock());
</del><ins>+ jump(node->branchData()->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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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 & 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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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->takenBlock();
- BasicBlock* notTaken = branchNode->notTakenBlock();
</del><ins>+ BasicBlock* taken = branchNode->branchData()->taken.block;
+ BasicBlock* notTaken = branchNode->branchData()->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 & 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->takenBlock();
- BasicBlock* notTaken = node->notTakenBlock();
</del><ins>+ BasicBlock* taken = node->branchData()->taken.block;
+ BasicBlock* notTaken = node->branchData()->notTaken.block;
</ins><span class="cx">
</span><span class="cx"> switch (node->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->takenBlock());
</del><ins>+ jump(node->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->takenBlock()));
</del><ins>+ m_out.jump(lowBlock(m_node->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->child1()),
</span><del>- unsure(lowBlock(m_node->takenBlock())),
- unsure(lowBlock(m_node->notTakenBlock())));
</del><ins>+ WeightedTarget(
+ lowBlock(m_node->branchData()->taken.block),
+ m_node->branchData()->taken.count),
+ WeightedTarget(
+ lowBlock(m_node->branchData()->notTaken.block),
+ m_node->branchData()->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->switchData();
</span><span class="cx"> switch (data->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->fallThrough)), rarely(isDouble));
</del><ins>+ usually(lowBlock(data->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->fallThrough)));
</del><ins>+ unsure(switchOnInts), unsure(lowBlock(data->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->child1().useKind()) {
</span><span class="cx"> case StringUse: {
</span><span class="cx"> stringValue = lowString(m_node->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->fallThrough)), unsure(isCellCase));
</del><ins>+ unsure(lowBlock(data->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->fallThrough)), unsure(isStringCase));
</del><ins>+ unsure(lowBlock(data->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->fallThrough)), unsure(lengthIs1));
</del><ins>+ unsure(lowBlock(data->fallThrough.block)), unsure(lengthIs1));
</ins><span class="cx">
</span><span class="cx"> LBasicBlock lastNext = m_out.appendTo(lengthIs1, needResolution);
</span><span class="cx"> Vector<ValueFromBlock, 2> values;
</span><span class="lines">@@ -4188,10 +4192,12 @@
</span><span class="cx"> for (unsigned i = 0; i < data->cases.size(); ++i) {
</span><span class="cx"> cases.append(SwitchCase(
</span><span class="cx"> constInt(type, data->cases[i].value.switchLookupValue()),
</span><del>- lowBlock(data->cases[i].target), Weight()));
</del><ins>+ lowBlock(data->cases[i].target.block), Weight(data->cases[i].target.count)));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- m_out.switchInstruction(switchValue, cases, lowBlock(data->fallThrough), Weight());
</del><ins>+ m_out.switchInstruction(
+ switchValue, cases,
+ lowBlock(data->fallThrough.block), Weight(data->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>