<!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>[172961] trunk</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/172961">172961</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-08-26 09:46:10 -0700 (Tue, 26 Aug 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Unreviewed, rolling out <a href="http://trac.webkit.org/projects/webkit/changeset/172940">r172940</a>.
https://bugs.webkit.org/show_bug.cgi?id=136256
Caused assertions on fast/storage/serialized-script-
value.html, and possibly flakiness on more tests (Requested by
ap on #webkit).
Reverted changeset:
"FTL should be able to do polymorphic call inlining"
https://bugs.webkit.org/show_bug.cgi?id=135145
http://trac.webkit.org/changeset/172940</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallLinkInfocpp">trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallLinkInfoh">trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallLinkStatuscpp">trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallLinkStatush">trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeOriginh">trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeExitKindcpp">trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeExitKindh">trunk/Source/JavaScriptCore/bytecode/ExitKind.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePutByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGBackwardsPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGBasicBlockcpp">trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGBasicBlockh">trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCPSRethreadingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCommonh">trunk/Source/JavaScriptCore/dfg/DFGCommon.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDrivercpp">trunk/Source/JavaScriptCore/dfg/DFGDriver.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="#trunkSourceJavaScriptCoredfgDFGJITCompilercpp">trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGLazyJSValuecpp">trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGLazyJSValueh">trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.h</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="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPhantomCanonicalizationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPhantomRemovalPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#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="#trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGTierUpCheckInjectionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGTierUpCheckInjectionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGValidatecpp">trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelpersh">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitCCallHelpersh">trunk/Source/JavaScriptCore/jit/CCallHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitGPRInfoh">trunk/Source/JavaScriptCore/jit/GPRInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITCallcpp">trunk/Source/JavaScriptCore/jit/JITCall.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITCall32_64cpp">trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfOwnPtrh">trunk/Source/WTF/wtf/OwnPtr.h</a></li>
<li><a href="#trunkSourceWTFwtfSpectrumh">trunk/Source/WTF/wtf/Spectrum.h</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressscripttestssimplepolycallnestedjs">trunk/LayoutTests/js/regress/script-tests/simple-poly-call-nested.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestssimplepolycalljs">trunk/LayoutTests/js/regress/script-tests/simple-poly-call.js</a></li>
<li><a href="#trunkLayoutTestsjsregresssimplepolycallexpectedtxt">trunk/LayoutTests/js/regress/simple-poly-call-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresssimplepolycallnestedexpectedtxt">trunk/LayoutTests/js/regress/simple-poly-call-nested-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresssimplepolycallnestedhtml">trunk/LayoutTests/js/regress/simple-poly-call-nested.html</a></li>
<li><a href="#trunkLayoutTestsjsregresssimplepolycallhtml">trunk/LayoutTests/js/regress/simple-poly-call.html</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallEdgecpp">trunk/Source/JavaScriptCore/bytecode/CallEdge.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallEdgeh">trunk/Source/JavaScriptCore/bytecode/CallEdge.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallEdgeProfilecpp">trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallEdgeProfileh">trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallEdgeProfileInlinesh">trunk/Source/JavaScriptCore/bytecode/CallEdgeProfileInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallVariantcpp">trunk/Source/JavaScriptCore/bytecode/CallVariant.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCallVarianth">trunk/Source/JavaScriptCore/bytecode/CallVariant.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressnewarraythenexitjs">trunk/Source/JavaScriptCore/tests/stress/new-array-then-exit.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresspolycallexitthisjs">trunk/Source/JavaScriptCore/tests/stress/poly-call-exit-this.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresspolycallexitjs">trunk/Source/JavaScriptCore/tests/stress/poly-call-exit.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/LayoutTests/ChangeLog        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2014-08-26 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r172940.
+ https://bugs.webkit.org/show_bug.cgi?id=136256
+
+ Caused assertions on fast/storage/serialized-script-
+ value.html, and possibly flakiness on more tests (Requested by
+ ap on #webkit).
+
+ Reverted changeset:
+
+ "FTL should be able to do polymorphic call inlining"
+ https://bugs.webkit.org/show_bug.cgi?id=135145
+ http://trac.webkit.org/changeset/172940
+
</ins><span class="cx"> 2014-08-23 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> FTL should be able to do polymorphic call inlining
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestssimplepolycallnestedjs"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/regress/script-tests/simple-poly-call-nested.js (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/simple-poly-call-nested.js        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/LayoutTests/js/regress/script-tests/simple-poly-call-nested.js        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,25 +0,0 @@
</span><del>-(function() {
- function foo(x) { return 1; }
- function bar(x) { return x; }
-
- var n = 1000000;
-
- var result = (function() {
- var f = foo;
- var g = bar;
-
- var result = 0;
- for (var i = 0; i < n; ++i) {
- result += f(42);
-
- var tmp = f;
- f = g;
- g = tmp;
- }
-
- return result;
- })();
-
- if (result != n / 2 * 42 + n / 2 * 1)
- throw "Error: bad result: " + result;
-})();
</del></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestssimplepolycalljs"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/regress/script-tests/simple-poly-call.js (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/simple-poly-call.js        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/LayoutTests/js/regress/script-tests/simple-poly-call.js        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,20 +0,0 @@
</span><del>-(function() {
- function foo(x) { return 1; }
- function bar(x) { return x; }
-
- var f = foo;
- var g = bar;
-
- var result = 0;
- var n = 100000;
- for (var i = 0; i < n; ++i) {
- result += f(42);
-
- var tmp = f;
- f = g;
- g = tmp;
- }
-
- if (result != n / 2 * 42 + n / 2 * 1)
- throw "Error: bad result: " + result;
-})();
</del></span></pre></div>
<a id="trunkLayoutTestsjsregresssimplepolycallexpectedtxt"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/regress/simple-poly-call-expected.txt (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/simple-poly-call-expected.txt        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/LayoutTests/js/regress/simple-poly-call-expected.txt        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,10 +0,0 @@
</span><del>-JSRegress/simple-poly-call
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS no exception thrown
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
</del></span></pre></div>
<a id="trunkLayoutTestsjsregresssimplepolycallnestedexpectedtxt"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/regress/simple-poly-call-nested-expected.txt (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/simple-poly-call-nested-expected.txt        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/LayoutTests/js/regress/simple-poly-call-nested-expected.txt        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,10 +0,0 @@
</span><del>-JSRegress/simple-poly-call-nested
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS no exception thrown
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
</del></span></pre></div>
<a id="trunkLayoutTestsjsregresssimplepolycallnestedhtml"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/regress/simple-poly-call-nested.html (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/simple-poly-call-nested.html        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/LayoutTests/js/regress/simple-poly-call-nested.html        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,12 +0,0 @@
</span><del>-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script src="../../resources/regress-pre.js"></script>
-<script src="script-tests/simple-poly-call-nested.js"></script>
-<script src="../../resources/regress-post.js"></script>
-<script src="../../resources/js-test-post.js"></script>
-</body>
-</html>
</del></span></pre></div>
<a id="trunkLayoutTestsjsregresssimplepolycallhtml"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/regress/simple-poly-call.html (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/simple-poly-call.html        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/LayoutTests/js/regress/simple-poly-call.html        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,12 +0,0 @@
</span><del>-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script src="../../resources/regress-pre.js"></script>
-<script src="script-tests/simple-poly-call.js"></script>
-<script src="../../resources/regress-post.js"></script>
-<script src="../../resources/js-test-post.js"></script>
-</body>
-</html>
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -65,11 +65,8 @@
</span><span class="cx"> bytecode/ArrayProfile.cpp
</span><span class="cx"> bytecode/BytecodeBasicBlock.cpp
</span><span class="cx"> bytecode/BytecodeLivenessAnalysis.cpp
</span><del>- bytecode/CallEdge.cpp
- bytecode/CallEdgeProfile.cpp
</del><span class="cx"> bytecode/CallLinkInfo.cpp
</span><span class="cx"> bytecode/CallLinkStatus.cpp
</span><del>- bytecode/CallVariant.cpp
</del><span class="cx"> bytecode/CodeBlock.cpp
</span><span class="cx"> bytecode/CodeBlockHash.cpp
</span><span class="cx"> bytecode/CodeBlockJettisoningWatchpoint.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2014-08-26 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r172940.
+ https://bugs.webkit.org/show_bug.cgi?id=136256
+
+ Caused assertions on fast/storage/serialized-script-
+ value.html, and possibly flakiness on more tests (Requested by
+ ap on #webkit).
+
+ Reverted changeset:
+
+ "FTL should be able to do polymorphic call inlining"
+ https://bugs.webkit.org/show_bug.cgi?id=135145
+ http://trac.webkit.org/changeset/172940
+
</ins><span class="cx"> 2014-08-26 Michael Saboff <msaboff@apple.com>
</span><span class="cx">
</span><span class="cx"> REGRESSION(r172794) + 32Bit build: ASSERT failures in for-in-tests.js tests.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -314,11 +314,8 @@
</span><span class="cx"> <ClCompile Include="..\bytecode\ArrayProfile.cpp" />
</span><span class="cx"> <ClCompile Include="..\bytecode\BytecodeBasicBlock.cpp" />
</span><span class="cx"> <ClCompile Include="..\bytecode\BytecodeLivenessAnalysis.cpp" />
</span><del>- <ClCompile Include="..\bytecode\CallEdge.cpp" />
- <ClCompile Include="..\bytecode\CallEdgeProfile.cpp" />
</del><span class="cx"> <ClCompile Include="..\bytecode\CallLinkInfo.cpp" />
</span><span class="cx"> <ClCompile Include="..\bytecode\CallLinkStatus.cpp" />
</span><del>- <ClCompile Include="..\bytecode\CallVariant.cpp" />
</del><span class="cx"> <ClCompile Include="..\bytecode\CodeBlock.cpp" />
</span><span class="cx"> <ClCompile Include="..\bytecode\CodeBlockHash.cpp" />
</span><span class="cx"> <ClCompile Include="..\bytecode\CodeBlockJettisoningWatchpoint.cpp" />
</span><span class="lines">@@ -908,13 +905,9 @@
</span><span class="cx"> <ClInclude Include="..\bytecode\BytecodeBasicBlock.h" />
</span><span class="cx"> <ClInclude Include="..\bytecode\BytecodeLivenessAnalysis.h" />
</span><span class="cx"> <ClInclude Include="..\bytecode\BytecodeUseDef.h" />
</span><del>- <ClInclude Include="..\bytecode\CallEdge.h" />
- <ClInclude Include="..\bytecode\CallEdgeProfile.h" />
- <ClInclude Include="..\bytecode\CallEdgeProfileInlines.h" />
</del><span class="cx"> <ClInclude Include="..\bytecode\CallLinkInfo.h" />
</span><span class="cx"> <ClInclude Include="..\bytecode\CallLinkStatus.h" />
</span><span class="cx"> <ClInclude Include="..\bytecode\CallReturnOffsetToBytecodeOffset.h" />
</span><del>- <ClInclude Include="..\bytecode\CallVariant.h" />
</del><span class="cx"> <ClInclude Include="..\bytecode\CodeBlock.h" />
</span><span class="cx"> <ClInclude Include="..\bytecode\CodeBlockHash.h" />
</span><span class="cx"> <ClInclude Include="..\bytecode\CodeBlockJettisoningWatchpoint.h" />
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -263,13 +263,6 @@
</span><span class="cx">                 0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */; };
</span><span class="cx">                 0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0F3B7E2619A11B8000D9BC56 /* CallEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B7E2019A11B8000D9BC56 /* CallEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                0F3B7E2719A11B8000D9BC56 /* CallEdgeProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B7E2119A11B8000D9BC56 /* CallEdgeProfile.cpp */; };
-                0F3B7E2819A11B8000D9BC56 /* CallEdgeProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B7E2219A11B8000D9BC56 /* CallEdgeProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                0F3B7E2919A11B8000D9BC56 /* CallEdgeProfileInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B7E2319A11B8000D9BC56 /* CallEdgeProfileInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                0F3B7E2A19A11B8000D9BC56 /* CallVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B7E2419A11B8000D9BC56 /* CallVariant.cpp */; };
-                0F3B7E2B19A11B8000D9BC56 /* CallVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B7E2519A11B8000D9BC56 /* CallVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                0F3B7E2D19A12AAE00D9BC56 /* CallEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B7E2C19A12AAE00D9BC56 /* CallEdge.cpp */; };
</del><span class="cx">                 0F3D0BBC194A414300FC9CF9 /* ConstantStructureCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */; };
</span><span class="cx">                 0F3D0BBD194A414300FC9CF9 /* ConstantStructureCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A451460CBAB00131F8F /* ValueRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2176,13 +2169,6 @@
</span><span class="cx">                 0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFGSimplificationPhase.h; path = dfg/DFGCFGSimplificationPhase.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValidate.cpp; path = dfg/DFGValidate.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGValidate.h; path = dfg/DFGValidate.h; sourceTree = "<group>"; };
</span><del>-                0F3B7E2019A11B8000D9BC56 /* CallEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallEdge.h; sourceTree = "<group>"; };
-                0F3B7E2119A11B8000D9BC56 /* CallEdgeProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallEdgeProfile.cpp; sourceTree = "<group>"; };
-                0F3B7E2219A11B8000D9BC56 /* CallEdgeProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallEdgeProfile.h; sourceTree = "<group>"; };
-                0F3B7E2319A11B8000D9BC56 /* CallEdgeProfileInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallEdgeProfileInlines.h; sourceTree = "<group>"; };
-                0F3B7E2419A11B8000D9BC56 /* CallVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallVariant.cpp; sourceTree = "<group>"; };
-                0F3B7E2519A11B8000D9BC56 /* CallVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallVariant.h; sourceTree = "<group>"; };
-                0F3B7E2C19A12AAE00D9BC56 /* CallEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallEdge.cpp; sourceTree = "<group>"; };
</del><span class="cx">                 0F3D0BBA194A414300FC9CF9 /* ConstantStructureCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantStructureCheck.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F3D0BBB194A414300FC9CF9 /* ConstantStructureCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantStructureCheck.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F426A451460CBAB00131F8F /* ValueRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueRecovery.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -5160,18 +5146,11 @@
</span><span class="cx">                                 0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */,
</span><span class="cx">                                 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */,
</span><span class="cx">                                 0F8023E91613832300A0BA45 /* ByValInfo.h */,
</span><del>-                                0F3B7E2C19A12AAE00D9BC56 /* CallEdge.cpp */,
-                                0F3B7E2019A11B8000D9BC56 /* CallEdge.h */,
-                                0F3B7E2119A11B8000D9BC56 /* CallEdgeProfile.cpp */,
-                                0F3B7E2219A11B8000D9BC56 /* CallEdgeProfile.h */,
-                                0F3B7E2319A11B8000D9BC56 /* CallEdgeProfileInlines.h */,
</del><span class="cx">                                 0F0B83AE14BCF71400885B4F /* CallLinkInfo.cpp */,
</span><span class="cx">                                 0F0B83AF14BCF71400885B4F /* CallLinkInfo.h */,
</span><span class="cx">                                 0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */,
</span><span class="cx">                                 0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */,
</span><span class="cx">                                 0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */,
</span><del>-                                0F3B7E2419A11B8000D9BC56 /* CallVariant.cpp */,
-                                0F3B7E2519A11B8000D9BC56 /* CallVariant.h */,
</del><span class="cx">                                 969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */,
</span><span class="cx">                                 969A07910ED1D3AE00F1F681 /* CodeBlock.h */,
</span><span class="cx">                                 0F8F943D1667632D00D61971 /* CodeBlockHash.cpp */,
</span><span class="lines">@@ -5900,7 +5879,6 @@
</span><span class="cx">                                 0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */,
</span><span class="cx">                                 0F2FC77316E12F740038D976 /* DFGDCEPhase.h in Headers */,
</span><span class="cx">                                 0F8F2B9A172F0501007DBDA5 /* DFGDesiredIdentifiers.h in Headers */,
</span><del>-                                0F3B7E2819A11B8000D9BC56 /* CallEdgeProfile.h in Headers */,
</del><span class="cx">                                 C2C0F7CE17BBFC5B00464FE4 /* DFGDesiredTransitions.h in Headers */,
</span><span class="cx">                                 0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */,
</span><span class="cx">                                 C2981FD917BAEE4B00A3BC98 /* DFGDesiredWeakReferences.h in Headers */,
</span><span class="lines">@@ -6169,7 +6147,6 @@
</span><span class="cx">                                 0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */,
</span><span class="cx">                                 0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */,
</span><span class="cx">                                 14C5242B0F5355E900BA3D04 /* JITStubs.h in Headers */,
</span><del>-                                0F3B7E2B19A11B8000D9BC56 /* CallVariant.h in Headers */,
</del><span class="cx">                                 FEF6835E174343CC00A32E25 /* JITStubsARM.h in Headers */,
</span><span class="cx">                                 FEF6835F174343CC00A32E25 /* JITStubsARMv7.h in Headers */,
</span><span class="cx">                                 FEF68361174343CC00A32E25 /* JITStubsX86.h in Headers */,
</span><span class="lines">@@ -6181,7 +6158,6 @@
</span><span class="cx">                                 A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */,
</span><span class="cx">                                 BC18C4160E16F5CD00B34460 /* JSActivation.h in Headers */,
</span><span class="cx">                                 840480131021A1D9008E7F01 /* JSAPIValueWrapper.h in Headers */,
</span><del>-                                0F3B7E2919A11B8000D9BC56 /* CallEdgeProfileInlines.h in Headers */,
</del><span class="cx">                                 C2CF39C216E15A8100DD69BE /* JSAPIWrapperObject.h in Headers */,
</span><span class="cx">                                 A76140D2182982CB00750624 /* JSArgumentsIterator.h in Headers */,
</span><span class="cx">                                 BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */,
</span><span class="lines">@@ -6497,7 +6473,6 @@
</span><span class="cx">                                 E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */,
</span><span class="cx">                                 E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */,
</span><span class="cx">                                 0FB7F39E15ED8E4600F167B2 /* SparseArrayValueMap.h in Headers */,
</span><del>-                                0F3B7E2619A11B8000D9BC56 /* CallEdge.h in Headers */,
</del><span class="cx">                                 A7386554118697B400540279 /* SpecializedThunkJIT.h in Headers */,
</span><span class="cx">                                 0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */,
</span><span class="cx">                                 0FD82E54141DAEEE00179C94 /* SpeculatedType.h in Headers */,
</span><span class="lines">@@ -7352,7 +7327,6 @@
</span><span class="cx">                                 0F235BD517178E1C00690C7F /* FTLExitArgumentForOperand.cpp in Sources */,
</span><span class="cx">                                 0F235BD817178E1C00690C7F /* FTLExitThunkGenerator.cpp in Sources */,
</span><span class="cx">                                 0F235BDA17178E1C00690C7F /* FTLExitValue.cpp in Sources */,
</span><del>-                                0F3B7E2719A11B8000D9BC56 /* CallEdgeProfile.cpp in Sources */,
</del><span class="cx">                                 A7F2996B17A0BB670010417A /* FTLFail.cpp in Sources */,
</span><span class="cx">                                 0FD8A31917D51F2200CA2C40 /* FTLForOSREntryJITCode.cpp in Sources */,
</span><span class="cx">                                 0F25F1AF181635F300522F39 /* FTLInlineCacheSize.cpp in Sources */,
</span><span class="lines">@@ -7539,7 +7513,6 @@
</span><span class="cx">                                 0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
</span><span class="cx">                                 0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */,
</span><span class="cx">                                 0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
</span><del>-                                0F3B7E2D19A12AAE00D9BC56 /* CallEdge.cpp in Sources */,
</del><span class="cx">                                 0F4680A414BA7F8D00BFE272 /* LLIntSlowPaths.cpp in Sources */,
</span><span class="cx">                                 0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
</span><span class="cx">                                 0FCEFACD1805E75500472CE4 /* LLVMAPI.cpp in Sources */,
</span><span class="lines">@@ -7701,7 +7674,6 @@
</span><span class="cx">                                 14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */,
</span><span class="cx">                                 2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */,
</span><span class="cx">                                 0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
</span><del>-                                0F3B7E2A19A11B8000D9BC56 /* CallVariant.cpp in Sources */,
</del><span class="cx">                                 A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */,
</span><span class="cx">                                 863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */,
</span><span class="cx">                                 86704B8412DBA33700A9FE7B /* YarrInterpreter.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallEdgecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/CallEdge.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallEdge.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallEdge.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,37 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "CallEdge.h"
-
-namespace JSC {
-
-void CallEdge::dump(PrintStream& out) const
-{
- out.print("<", m_callee, ", count: ", m_count, ">");
-}
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallEdgeh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/CallEdge.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallEdge.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallEdge.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,73 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CallEdge_h
-#define CallEdge_h
-
-#include "CallVariant.h"
-
-namespace JSC {
-
-typedef uint16_t CallEdgeCountType;
-
-class CallEdge {
-public:
- CallEdge();
- CallEdge(CallVariant, CallEdgeCountType);
-
- bool operator!() const { return !m_callee; }
-
- CallVariant callee() const { return m_callee; }
- CallEdgeCountType count() const { return m_count; }
-
- CallEdge despecifiedClosure() const
- {
- return CallEdge(m_callee.despecifiedClosure(), m_count);
- }
-
- void dump(PrintStream&) const;
-
-public:
- CallVariant m_callee;
- CallEdgeCountType m_count;
-};
-
-inline CallEdge::CallEdge(CallVariant callee, CallEdgeCountType count)
- : m_callee(callee)
- , m_count(count)
-{
-}
-
-inline CallEdge::CallEdge()
- : CallEdge(CallVariant(), 0)
-{
-}
-
-typedef Vector<CallEdge, 1> CallEdgeList;
-
-} // namespace JSC
-
-#endif // CallEdge_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallEdgeProfilecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,348 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "CallEdgeProfile.h"
-
-#include "CCallHelpers.h"
-#include "CallEdgeProfileInlines.h"
-#include "JITOperations.h"
-#include "JSCInlines.h"
-
-namespace JSC {
-
-CallEdgeList CallEdgeProfile::callEdges() const
-{
- ConcurrentJITLocker locker(m_lock);
-
- CallEdgeList result;
-
- CallVariant primaryCallee = m_primaryCallee;
- CallEdgeCountType numCallsToPrimary = m_numCallsToPrimary;
- // Defend against races. These fields are modified by the log processor without locking.
- if (!!primaryCallee && numCallsToPrimary)
- result.append(CallEdge(primaryCallee, numCallsToPrimary));
-
- if (m_otherCallees) {
- // Make sure that if the primary thread had just created a m_otherCalles while log
- // processing, we see a consistently created one. The lock being held is insufficient for
- // this, since the log processor will only grab the lock when merging the secondary
- // spectrum into the primary one but may still create the data structure without holding
- // locks.
- WTF::loadLoadFence();
- for (CallEdge& entry : m_otherCallees->m_processed) {
- // Defend against the possibility that the primary duplicates an entry in the secondary
- // spectrum. That can happen when the GC removes the primary. We could have the GC fix
- // the situation by changing the primary to be something from the secondary spectrum,
- // but this fix seems simpler to implement and also cheaper.
- if (entry.callee() == result[0].callee()) {
- result[0] = CallEdge(result[0].callee(), entry.count() + result[0].count());
- continue;
- }
-
- result.append(entry);
- }
- }
-
- std::sort(result.begin(), result.end(), [] (const CallEdge& a, const CallEdge& b) -> bool {
- return a.count() > b.count();
- });
-
- if (result.size() >= 2)
- ASSERT(result[0].count() >= result.last().count());
-
- return result;
-}
-
-CallEdgeCountType CallEdgeProfile::numCallsToKnownCells() const
-{
- CallEdgeCountType result = 0;
- for (CallEdge& edge : callEdges())
- result += edge.count();
- return result;
-}
-
-static bool worthDespecifying(const CallVariant& variant)
-{
- return !Heap::isMarked(variant.rawCalleeCell())
- && Heap::isMarked(variant.despecifiedClosure().rawCalleeCell());
-}
-
-bool CallEdgeProfile::worthDespecifying()
-{
- if (m_closuresAreDespecified)
- return false;
-
- if (!!m_primaryCallee && !JSC::worthDespecifying(m_primaryCallee))
- return false;
-
- if (m_otherCallees) {
- for (unsigned i = m_otherCallees->m_processed.size(); i--;) {
- if (!JSC::worthDespecifying(m_otherCallees->m_processed[i].callee()))
- return false;
- }
- }
-
- return true;
-}
-
-void CallEdgeProfile::visitWeak()
-{
- if (!m_primaryCallee && !m_otherCallees)
- return;
-
- ConcurrentJITLocker locker(m_lock);
-
- // See if anything is dead and if that can be rectified by despecifying.
- if (worthDespecifying()) {
- CallSpectrum newSpectrum;
-
- if (!!m_primaryCallee)
- newSpectrum.add(m_primaryCallee.despecifiedClosure(), m_numCallsToPrimary);
-
- if (m_otherCallees) {
- for (unsigned i = m_otherCallees->m_processed.size(); i--;) {
- newSpectrum.add(
- m_otherCallees->m_processed[i].callee().despecifiedClosure(),
- m_otherCallees->m_processed[i].count());
- }
- }
-
- Vector<CallSpectrum::KeyAndCount> list = newSpectrum.buildList();
- ASSERT(list.size());
- m_primaryCallee = list.last().key;
- m_numCallsToPrimary = list.last().count;
-
- ASSERT(!!m_otherCallees == (list.size() >= 2));
- if (m_otherCallees) {
- m_otherCallees->m_processed.clear();
- for (unsigned i = list.size() - 1; i--;)
- m_otherCallees->m_processed.append(CallEdge(list[i].key, list[i].count));
- }
-
- m_closuresAreDespecified = true;
-
- return;
- }
-
- if (!!m_primaryCallee && !Heap::isMarked(m_primaryCallee.rawCalleeCell())) {
- m_numCallsToUnknownCell += m_numCallsToPrimary;
-
- m_primaryCallee = CallVariant();
- m_numCallsToPrimary = 0;
- }
-
- if (m_otherCallees) {
- for (unsigned i = 0; i < m_otherCallees->m_processed.size(); i++) {
- if (Heap::isMarked(m_otherCallees->m_processed[i].callee().rawCalleeCell()))
- continue;
-
- m_numCallsToUnknownCell += m_otherCallees->m_processed[i].count();
- m_otherCallees->m_processed[i--] = m_otherCallees->m_processed.last();
- m_otherCallees->m_processed.removeLast();
- }
-
- // Only exists while we are processing the log.
- RELEASE_ASSERT(!m_otherCallees->m_temporarySpectrum);
- }
-}
-
-void CallEdgeProfile::addSlow(CallVariant callee, CallEdgeProfileVector& mergeBackLog)
-{
- // This exists to handle cases where the spectrum wasn't created yet, or we're storing to a
- // particular spectrum for the first time during a log processing iteration.
-
- if (!m_otherCallees) {
- m_otherCallees = std::make_unique<Secondary>();
- // If a compiler thread notices the m_otherCallees being non-null, we want to make sure
- // that it sees a fully created one.
- WTF::storeStoreFence();
- }
-
- if (!m_otherCallees->m_temporarySpectrum) {
- m_otherCallees->m_temporarySpectrum = std::make_unique<CallSpectrum>();
- for (unsigned i = m_otherCallees->m_processed.size(); i--;) {
- m_otherCallees->m_temporarySpectrum->add(
- m_otherCallees->m_processed[i].callee(),
- m_otherCallees->m_processed[i].count());
- }
-
- // This means that this is the first time we're seeing this profile during this log
- // processing iteration.
- mergeBackLog.append(this);
- }
-
- m_otherCallees->m_temporarySpectrum->add(callee);
-}
-
-void CallEdgeProfile::mergeBack()
-{
- ConcurrentJITLocker locker(m_lock);
-
- ASSERT(m_otherCallees);
- ASSERT(m_otherCallees->m_temporarySpectrum);
-
- if (!!m_primaryCallee)
- m_otherCallees->m_temporarySpectrum->add(m_primaryCallee, m_numCallsToPrimary);
-
- if (!m_closuresAreDespecified) {
- CallSpectrum newSpectrum;
- for (auto& entry : *m_otherCallees->m_temporarySpectrum)
- newSpectrum.add(entry.key.despecifiedClosure(), entry.value);
-
- if (newSpectrum.size() < m_otherCallees->m_temporarySpectrum->size()) {
- *m_otherCallees->m_temporarySpectrum = newSpectrum;
- m_closuresAreDespecified = true;
- }
- }
-
- Vector<CallSpectrum::KeyAndCount> list = m_otherCallees->m_temporarySpectrum->buildList();
- m_otherCallees->m_temporarySpectrum = nullptr;
-
- m_primaryCallee = list.last().key;
- m_numCallsToPrimary = list.last().count;
- list.removeLast();
-
- m_otherCallees->m_processed.clear();
- for (unsigned count = maxKnownCallees; count-- && !list.isEmpty();) {
- m_otherCallees->m_processed.append(CallEdge(list.last().key, list.last().count));
- list.removeLast();
- }
-
- for (unsigned i = list.size(); i--;)
- m_numCallsToUnknownCell += list[i].count;
-}
-
-void CallEdgeProfile::fadeByHalf()
-{
- m_numCallsToPrimary >>= 1;
- m_numCallsToNotCell >>= 1;
- m_numCallsToUnknownCell >>= 1;
- m_totalCount >>= 1;
-
- if (m_otherCallees) {
- for (unsigned i = m_otherCallees->m_processed.size(); i--;) {
- m_otherCallees->m_processed[i] = CallEdge(
- m_otherCallees->m_processed[i].callee(),
- m_otherCallees->m_processed[i].count() >> 1);
- }
-
- if (m_otherCallees->m_temporarySpectrum) {
- for (auto& entry : *m_otherCallees->m_temporarySpectrum)
- entry.value >>= 1;
- }
- }
-}
-
-CallEdgeLog::CallEdgeLog()
- : m_scaledLogIndex(logSize * sizeof(Entry))
-{
- ASSERT(!(m_scaledLogIndex % sizeof(Entry)));
-}
-
-CallEdgeLog::~CallEdgeLog() { }
-
-bool CallEdgeLog::isEnabled()
-{
- return Options::enableCallEdgeProfiling() && Options::useFTLJIT();
-}
-
-#if ENABLE(JIT)
-
-extern "C" JIT_OPERATION void operationProcessCallEdgeLog(CallEdgeLog*) WTF_INTERNAL;
-extern "C" JIT_OPERATION void operationProcessCallEdgeLog(CallEdgeLog* log)
-{
- log->processLog();
-}
-
-void CallEdgeLog::emitLogCode(CCallHelpers& jit, CallEdgeProfile& profile, JSValueRegs calleeRegs)
-{
- const unsigned numberOfArguments = 1;
-
- GPRReg scratchGPR;
- if (!calleeRegs.uses(GPRInfo::regT0))
- scratchGPR = GPRInfo::regT0;
- else if (!calleeRegs.uses(GPRInfo::regT1))
- scratchGPR = GPRInfo::regT1;
- else
- scratchGPR = GPRInfo::regT2;
-
- jit.load32(&m_scaledLogIndex, scratchGPR);
-
- CCallHelpers::Jump ok = jit.branchTest32(CCallHelpers::NonZero, scratchGPR);
-
- ASSERT_UNUSED(numberOfArguments, stackAlignmentRegisters() >= 1 + numberOfArguments);
-
- jit.subPtr(CCallHelpers::TrustedImm32(stackAlignmentBytes()), CCallHelpers::stackPointerRegister);
-
- jit.storeValue(calleeRegs, CCallHelpers::Address(CCallHelpers::stackPointerRegister, sizeof(JSValue)));
- jit.setupArguments(CCallHelpers::TrustedImmPtr(this));
- jit.move(CCallHelpers::TrustedImmPtr(bitwise_cast<void*>(operationProcessCallEdgeLog)), GPRInfo::nonArgGPR0);
- jit.call(GPRInfo::nonArgGPR0);
- jit.loadValue(CCallHelpers::Address(CCallHelpers::stackPointerRegister, sizeof(JSValue)), calleeRegs);
-
- jit.addPtr(CCallHelpers::TrustedImm32(stackAlignmentBytes()), CCallHelpers::stackPointerRegister);
-
- jit.move(CCallHelpers::TrustedImm32(logSize * sizeof(Entry)), scratchGPR);
- ok.link(&jit);
-
- jit.sub32(CCallHelpers::TrustedImm32(sizeof(Entry)), scratchGPR);
- jit.store32(scratchGPR, &m_scaledLogIndex);
- jit.addPtr(CCallHelpers::TrustedImmPtr(m_log), scratchGPR);
- jit.storeValue(calleeRegs, CCallHelpers::Address(scratchGPR, OBJECT_OFFSETOF(Entry, m_value)));
- jit.storePtr(CCallHelpers::TrustedImmPtr(&profile), CCallHelpers::Address(scratchGPR, OBJECT_OFFSETOF(Entry, m_profile)));
-}
-
-void CallEdgeLog::emitLogCode(
- CCallHelpers& jit, OwnPtr<CallEdgeProfile>& profilePointer, JSValueRegs calleeRegs)
-{
- if (!isEnabled())
- return;
-
- profilePointer.createTransactionally();
- emitLogCode(jit, *profilePointer, calleeRegs);
-}
-
-#endif // ENABLE(JIT)
-
-void CallEdgeLog::processLog()
-{
- ASSERT(!(m_scaledLogIndex % sizeof(Entry)));
-
- if (Options::callEdgeProfileReallyProcessesLog()) {
- CallEdgeProfileVector mergeBackLog;
-
- for (unsigned i = m_scaledLogIndex / sizeof(Entry); i < logSize; ++i)
- m_log[i].m_profile->add(m_log[i].m_value, mergeBackLog);
-
- for (unsigned i = mergeBackLog.size(); i--;)
- mergeBackLog[i]->mergeBack();
- }
-
- m_scaledLogIndex = logSize * sizeof(Entry);
-}
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallEdgeProfileh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallEdgeProfile.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,130 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CallEdgeProfile_h
-#define CallEdgeProfile_h
-
-#include "CallEdge.h"
-#include "CallVariant.h"
-#include "ConcurrentJITLock.h"
-#include "JSCell.h"
-#include <wtf/OwnPtr.h>
-
-namespace JSC {
-
-class CCallHelpers;
-class LLIntOffsetsExtractor;
-
-class CallEdgeLog;
-class CallEdgeProfile;
-typedef Vector<CallEdgeProfile*, 10> CallEdgeProfileVector;
-
-class CallEdgeProfile {
-public:
- CallEdgeProfile();
-
- CallEdgeCountType numCallsToNotCell() const { return m_numCallsToNotCell; }
- CallEdgeCountType numCallsToUnknownCell() const { return m_numCallsToUnknownCell; }
- CallEdgeCountType numCallsToKnownCells() const;
-
- CallEdgeCountType totalCalls() const { return m_totalCount; }
-
- // Call while holding the owning CodeBlock's lock.
- CallEdgeList callEdges() const;
-
- void visitWeak();
-
-private:
- friend class CallEdgeLog;
-
- static const unsigned maxKnownCallees = 5;
-
- void add(JSValue, CallEdgeProfileVector& mergeBackLog);
-
- bool worthDespecifying();
- void addSlow(CallVariant, CallEdgeProfileVector& mergeBackLog);
- void mergeBack();
- void fadeByHalf();
-
- // It's cheaper to let this have its own lock. It needs to be able to find which lock to
- // lock. Normally it would lock the owning CodeBlock's lock, but that would require a
- // pointer-width word to point at the CodeBlock. Having the byte-sized lock here is
- // cheaper. However, this means that the relationship with the CodeBlock lock is:
- // acquire the CodeBlock lock before this one.
- mutable ConcurrentJITLock m_lock;
-
- bool m_closuresAreDespecified;
-
- CallEdgeCountType m_numCallsToPrimary;
- CallEdgeCountType m_numCallsToNotCell;
- CallEdgeCountType m_numCallsToUnknownCell;
- CallEdgeCountType m_totalCount;
- CallVariant m_primaryCallee;
-
- typedef Spectrum<CallVariant, CallEdgeCountType> CallSpectrum;
-
- struct Secondary {
- Vector<CallEdge> m_processed; // Processed but not necessarily sorted.
- std::unique_ptr<CallSpectrum> m_temporarySpectrum;
- };
-
- std::unique_ptr<Secondary> m_otherCallees;
-};
-
-class CallEdgeLog {
-public:
- CallEdgeLog();
- ~CallEdgeLog();
-
- static bool isEnabled();
-
-#if ENABLE(JIT)
- void emitLogCode(CCallHelpers&, CallEdgeProfile&, JSValueRegs calleeRegs); // Assumes that stack is aligned, all volatile registers - other than calleeGPR - are clobberable, and the parameter space is in use.
-
- // Same as above but creates a CallEdgeProfile instance if one did not already exist. Does
- // this in a thread-safe manner by calling OwnPtr::createTransactionally.
- void emitLogCode(CCallHelpers&, OwnPtr<CallEdgeProfile>&, JSValueRegs calleeRegs);
-#endif // ENABLE(JIT)
-
- void processLog();
-
-private:
- friend class LLIntOffsetsExtractor;
-
- static const unsigned logSize = 10000;
-
- struct Entry {
- JSValue m_value;
- CallEdgeProfile* m_profile;
- };
-
- unsigned m_scaledLogIndex;
- Entry m_log[logSize];
-};
-
-} // namespace JSC
-
-#endif // CallEdgeProfile_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallEdgeProfileInlinesh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/CallEdgeProfileInlines.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallEdgeProfileInlines.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallEdgeProfileInlines.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,91 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CallEdgeProfileInlines_h
-#define CallEdgeProfileInlines_h
-
-#include "CallEdgeProfile.h"
-
-namespace JSC {
-
-inline CallEdgeProfile::CallEdgeProfile()
- : m_closuresAreDespecified(false)
- , m_numCallsToPrimary(0)
- , m_numCallsToNotCell(0)
- , m_numCallsToUnknownCell(0)
- , m_totalCount(0)
- , m_primaryCallee(nullptr)
-{
-}
-
-ALWAYS_INLINE void CallEdgeProfile::add(JSValue value, CallEdgeProfileVector& mergeBackLog)
-{
- unsigned newTotalCount = m_totalCount + 1;
- if (UNLIKELY(!newTotalCount)) {
- fadeByHalf(); // Tackle overflows by dividing all counts by two.
- newTotalCount = m_totalCount + 1;
- }
- ASSERT(newTotalCount);
- m_totalCount = newTotalCount;
-
- if (UNLIKELY(!value.isCell())) {
- m_numCallsToNotCell++;
- return;
- }
-
- CallVariant callee = CallVariant(value.asCell());
-
- if (m_closuresAreDespecified)
- callee = callee.despecifiedClosure();
-
- if (UNLIKELY(!m_primaryCallee)) {
- m_primaryCallee = callee;
- m_numCallsToPrimary = 1;
- return;
- }
-
- if (LIKELY(m_primaryCallee == callee)) {
- m_numCallsToPrimary++;
- return;
- }
-
- if (UNLIKELY(!m_otherCallees)) {
- addSlow(callee, mergeBackLog);
- return;
- }
-
- CallSpectrum* secondary = m_otherCallees->m_temporarySpectrum.get();
- if (!secondary) {
- addSlow(callee, mergeBackLog);
- return;
- }
-
- secondary->add(callee);
-}
-
-} // namespace JSC
-
-#endif // CallEdgeProfileInlines_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -83,11 +83,6 @@
</span><span class="cx"> }
</span><span class="cx"> if (!!lastSeenCallee && !Heap::isMarked(lastSeenCallee.get()))
</span><span class="cx"> lastSeenCallee.clear();
</span><del>-
- if (callEdgeProfile) {
- WTF::loadLoadFence();
- callEdgeProfile->visitWeak();
- }
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> CallLinkInfo& CallLinkInfo::dummy()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -26,7 +26,6 @@
</span><span class="cx"> #ifndef CallLinkInfo_h
</span><span class="cx"> #define CallLinkInfo_h
</span><span class="cx">
</span><del>-#include "CallEdgeProfile.h"
</del><span class="cx"> #include "ClosureCallStubRoutine.h"
</span><span class="cx"> #include "CodeLocation.h"
</span><span class="cx"> #include "CodeSpecializationKind.h"
</span><span class="lines">@@ -34,7 +33,6 @@
</span><span class="cx"> #include "JSFunction.h"
</span><span class="cx"> #include "Opcode.h"
</span><span class="cx"> #include "WriteBarrier.h"
</span><del>-#include <wtf/OwnPtr.h>
</del><span class="cx"> #include <wtf/SentinelLinkedList.h>
</span><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -90,7 +88,6 @@
</span><span class="cx"> unsigned calleeGPR : 8;
</span><span class="cx"> unsigned slowPathCount;
</span><span class="cx"> CodeOrigin codeOrigin;
</span><del>- OwnPtr<CallEdgeProfile> callEdgeProfile;
</del><span class="cx">
</span><span class="cx"> bool isLinked() { return stub || callee; }
</span><span class="cx"> void unlink(RepatchBuffer&);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -32,30 +32,62 @@
</span><span class="cx"> #include "LLIntCallLinkInfo.h"
</span><span class="cx"> #include "JSCInlines.h"
</span><span class="cx"> #include <wtf/CommaPrinter.h>
</span><del>-#include <wtf/ListDump.h>
</del><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><span class="cx"> static const bool verbose = false;
</span><span class="cx">
</span><span class="cx"> CallLinkStatus::CallLinkStatus(JSValue value)
</span><del>- : m_couldTakeSlowPath(false)
</del><ins>+ : m_callTarget(value)
+ , m_executable(0)
+ , m_couldTakeSlowPath(false)
</ins><span class="cx"> , m_isProved(false)
</span><span class="cx"> {
</span><del>- if (!value || !value.isCell()) {
- m_couldTakeSlowPath = true;
</del><ins>+ if (!value || !value.isCell())
</ins><span class="cx"> return;
</span><del>- }
</del><span class="cx">
</span><del>- m_edges.append(CallEdge(CallVariant(value.asCell()), 1));
</del><ins>+ if (!value.asCell()->inherits(JSFunction::info()))
+ return;
+
+ m_executable = jsCast<JSFunction*>(value.asCell())->executable();
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+JSFunction* CallLinkStatus::function() const
+{
+ if (!m_callTarget || !m_callTarget.isCell())
+ return 0;
+
+ if (!m_callTarget.asCell()->inherits(JSFunction::info()))
+ return 0;
+
+ return jsCast<JSFunction*>(m_callTarget.asCell());
+}
+
+InternalFunction* CallLinkStatus::internalFunction() const
+{
+ if (!m_callTarget || !m_callTarget.isCell())
+ return 0;
+
+ if (!m_callTarget.asCell()->inherits(InternalFunction::info()))
+ return 0;
+
+ return jsCast<InternalFunction*>(m_callTarget.asCell());
+}
+
+Intrinsic CallLinkStatus::intrinsicFor(CodeSpecializationKind kind) const
+{
+ if (!m_executable)
+ return NoIntrinsic;
+
+ return m_executable->intrinsicFor(kind);
+}
+
</ins><span class="cx"> CallLinkStatus CallLinkStatus::computeFromLLInt(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex)
</span><span class="cx"> {
</span><span class="cx"> UNUSED_PARAM(profiledBlock);
</span><span class="cx"> UNUSED_PARAM(bytecodeIndex);
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><del>- if (profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCell))) {
</del><ins>+ if (profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction))) {
</ins><span class="cx"> // We could force this to be a closure call, but instead we'll just assume that it
</span><span class="cx"> // takes slow path.
</span><span class="cx"> return takesSlowPath();
</span><span class="lines">@@ -93,7 +125,7 @@
</span><span class="cx"> if (!callLinkInfo)
</span><span class="cx"> return computeFromLLInt(locker, profiledBlock, bytecodeIndex);
</span><span class="cx">
</span><del>- return computeFor(locker, profiledBlock, *callLinkInfo, exitSiteData);
</del><ins>+ return computeFor(locker, *callLinkInfo, exitSiteData);
</ins><span class="cx"> #else
</span><span class="cx"> return CallLinkStatus();
</span><span class="cx"> #endif
</span><span class="lines">@@ -107,10 +139,10 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> exitSiteData.m_takesSlowPath =
</span><del>- profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadType, exitingJITType))
</del><ins>+ profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, exitingJITType))
</ins><span class="cx"> || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable, exitingJITType));
</span><span class="cx"> exitSiteData.m_badFunction =
</span><del>- profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCell, exitingJITType));
</del><ins>+ profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction, exitingJITType));
</ins><span class="cx"> #else
</span><span class="cx"> UNUSED_PARAM(locker);
</span><span class="cx"> UNUSED_PARAM(profiledBlock);
</span><span class="lines">@@ -122,35 +154,8 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-CallLinkStatus CallLinkStatus::computeFor(
- const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, CallLinkInfo& callLinkInfo)
</del><ins>+CallLinkStatus CallLinkStatus::computeFor(const ConcurrentJITLocker&, CallLinkInfo& callLinkInfo)
</ins><span class="cx"> {
</span><del>- // We don't really need this, but anytime we have to debug this code, it becomes indispensable.
- UNUSED_PARAM(profiledBlock);
-
- if (Options::callStatusShouldUseCallEdgeProfile()) {
- // Always trust the call edge profile over anything else since this has precise counts.
- // It can make the best possible decision because it never "forgets" what happened for any
- // call, with the exception of fading out the counts of old calls (for example if the
- // counter type is 16-bit then calls that happened more than 2^16 calls ago are given half
- // weight, and this compounds for every 2^15 [sic] calls after that). The combination of
- // high fidelity for recent calls and fading for older calls makes this the most useful
- // mechamism of choosing how to optimize future calls.
- CallEdgeProfile* edgeProfile = callLinkInfo.callEdgeProfile.get();
- WTF::loadLoadFence();
- if (edgeProfile) {
- CallLinkStatus result = computeFromCallEdgeProfile(edgeProfile);
- if (!!result)
- return result;
- }
- }
-
- return computeFromCallLinkInfo(locker, callLinkInfo);
-}
-
-CallLinkStatus CallLinkStatus::computeFromCallLinkInfo(
- const ConcurrentJITLocker&, CallLinkInfo& callLinkInfo)
-{
</del><span class="cx"> // Note that despite requiring that the locker is held, this code is racy with respect
</span><span class="cx"> // to the CallLinkInfo: it may get cleared while this code runs! This is because
</span><span class="cx"> // CallLinkInfo::unlink() may be called from a different CodeBlock than the one that owns
</span><span class="lines">@@ -172,7 +177,7 @@
</span><span class="cx">
</span><span class="cx"> JSFunction* target = callLinkInfo.lastSeenCallee.get();
</span><span class="cx"> if (!target)
</span><del>- return takesSlowPath();
</del><ins>+ return CallLinkStatus();
</ins><span class="cx">
</span><span class="cx"> if (callLinkInfo.hasSeenClosure)
</span><span class="cx"> return CallLinkStatus(target->executable());
</span><span class="lines">@@ -180,43 +185,15 @@
</span><span class="cx"> return CallLinkStatus(target);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-CallLinkStatus CallLinkStatus::computeFromCallEdgeProfile(CallEdgeProfile* edgeProfile)
</del><ins>+CallLinkStatus CallLinkStatus::computeFor(
+ const ConcurrentJITLocker& locker, CallLinkInfo& callLinkInfo, ExitSiteData exitSiteData)
</ins><span class="cx"> {
</span><del>- // In cases where the call edge profile saw nothing, use the CallLinkInfo instead.
- if (!edgeProfile->totalCalls())
- return CallLinkStatus();
-
- // To do anything meaningful, we require that the majority of calls are to something we
- // know how to handle.
- unsigned numCallsToKnown = edgeProfile->numCallsToKnownCells();
- unsigned numCallsToUnknown = edgeProfile->numCallsToNotCell() + edgeProfile->numCallsToUnknownCell();
-
- // We require that the majority of calls were to something that we could possibly inline.
- if (numCallsToKnown <= numCallsToUnknown)
</del><ins>+ if (exitSiteData.m_takesSlowPath)
</ins><span class="cx"> return takesSlowPath();
</span><span class="cx">
</span><del>- // We require that the number of such calls is greater than some minimal threshold, so that we
- // avoid inlining completely cold calls.
- if (numCallsToKnown < Options::frequentCallThreshold())
- return takesSlowPath();
-
- CallLinkStatus result;
- result.m_edges = edgeProfile->callEdges();
- result.m_couldTakeSlowPath = !!numCallsToUnknown;
- result.m_canTrustCounts = true;
-
- return result;
-}
-
-CallLinkStatus CallLinkStatus::computeFor(
- const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, CallLinkInfo& callLinkInfo,
- ExitSiteData exitSiteData)
-{
- CallLinkStatus result = computeFor(locker, profiledBlock, callLinkInfo);
</del><ins>+ CallLinkStatus result = computeFor(locker, callLinkInfo);
</ins><span class="cx"> if (exitSiteData.m_badFunction)
</span><span class="cx"> result.makeClosureCall();
</span><del>- if (exitSiteData.m_takesSlowPath)
- result.m_couldTakeSlowPath = true;
</del><span class="cx">
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="lines">@@ -250,7 +227,7 @@
</span><span class="cx">
</span><span class="cx"> {
</span><span class="cx"> ConcurrentJITLocker locker(dfgCodeBlock->m_lock);
</span><del>- map.add(info.codeOrigin, computeFor(locker, dfgCodeBlock, info, exitSiteData));
</del><ins>+ map.add(info.codeOrigin, computeFor(locker, info, exitSiteData));
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> #else
</span><span class="lines">@@ -279,31 +256,6 @@
</span><span class="cx"> return computeFor(profiledBlock, codeOrigin.bytecodeIndex, baselineMap);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool CallLinkStatus::isClosureCall() const
-{
- for (unsigned i = m_edges.size(); i--;) {
- if (m_edges[i].callee().isClosureCall())
- return true;
- }
- return false;
-}
-
-void CallLinkStatus::makeClosureCall()
-{
- ASSERT(!m_isProved);
- for (unsigned i = m_edges.size(); i--;)
- m_edges[i] = m_edges[i].despecifiedClosure();
-
- if (!ASSERT_DISABLED) {
- // Doing this should not have created duplicates, because the CallEdgeProfile
- // should despecify closures if doing so would reduce the number of known callees.
- for (unsigned i = 0; i < m_edges.size(); ++i) {
- for (unsigned j = i + 1; j < m_edges.size(); ++j)
- ASSERT(m_edges[i].callee() != m_edges[j].callee());
- }
- }
-}
-
</del><span class="cx"> void CallLinkStatus::dump(PrintStream& out) const
</span><span class="cx"> {
</span><span class="cx"> if (!isSet()) {
</span><span class="lines">@@ -319,7 +271,14 @@
</span><span class="cx"> if (m_couldTakeSlowPath)
</span><span class="cx"> out.print(comma, "Could Take Slow Path");
</span><span class="cx">
</span><del>- out.print(listDump(m_edges));
</del><ins>+ if (m_callTarget)
+ out.print(comma, "Known target: ", m_callTarget);
+
+ if (m_executable) {
+ out.print(comma, "Executable/CallHash: ", RawPointer(m_executable));
+ if (!isCompilationThread())
+ out.print("/", m_executable->hashFor(CodeForCall));
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallLinkStatush"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -46,9 +46,9 @@
</span><span class="cx"> class CallLinkStatus {
</span><span class="cx"> public:
</span><span class="cx"> CallLinkStatus()
</span><del>- : m_couldTakeSlowPath(false)
</del><ins>+ : m_executable(0)
+ , m_couldTakeSlowPath(false)
</ins><span class="cx"> , m_isProved(false)
</span><del>- , m_canTrustCounts(false)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -61,11 +61,10 @@
</span><span class="cx">
</span><span class="cx"> explicit CallLinkStatus(JSValue);
</span><span class="cx">
</span><del>- CallLinkStatus(CallVariant variant)
- : m_edges(1, CallEdge(variant, 1))
</del><ins>+ CallLinkStatus(ExecutableBase* executable)
+ : m_executable(executable)
</ins><span class="cx"> , m_couldTakeSlowPath(false)
</span><span class="cx"> , m_isProved(false)
</span><del>- , m_canTrustCounts(false)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -93,9 +92,8 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> // Computes the status assuming that we never took slow path and never previously
</span><span class="cx"> // exited.
</span><del>- static CallLinkStatus computeFor(const ConcurrentJITLocker&, CodeBlock*, CallLinkInfo&);
- static CallLinkStatus computeFor(
- const ConcurrentJITLocker&, CodeBlock*, CallLinkInfo&, ExitSiteData);
</del><ins>+ static CallLinkStatus computeFor(const ConcurrentJITLocker&, CallLinkInfo&);
+ static CallLinkStatus computeFor(const ConcurrentJITLocker&, CallLinkInfo&, ExitSiteData);
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> typedef HashMap<CodeOrigin, CallLinkStatus, CodeOriginApproximateHash> ContextMap;
</span><span class="lines">@@ -109,38 +107,37 @@
</span><span class="cx"> static CallLinkStatus computeFor(
</span><span class="cx"> CodeBlock*, CodeOrigin, const CallLinkInfoMap&, const ContextMap&);
</span><span class="cx">
</span><del>- bool isSet() const { return !m_edges.isEmpty() || m_couldTakeSlowPath; }
</del><ins>+ bool isSet() const { return m_callTarget || m_executable || m_couldTakeSlowPath; }
</ins><span class="cx">
</span><span class="cx"> bool operator!() const { return !isSet(); }
</span><span class="cx">
</span><span class="cx"> bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
</span><ins>+ bool isClosureCall() const { return m_executable && !m_callTarget; }
</ins><span class="cx">
</span><del>- CallEdgeList edges() const { return m_edges; }
- unsigned size() const { return m_edges.size(); }
- CallEdge at(unsigned i) const { return m_edges[i]; }
- CallEdge operator[](unsigned i) const { return at(i); }
</del><ins>+ JSValue callTarget() const { return m_callTarget; }
+ JSFunction* function() const;
+ InternalFunction* internalFunction() const;
+ Intrinsic intrinsicFor(CodeSpecializationKind) const;
+ ExecutableBase* executable() const { return m_executable; }
</ins><span class="cx"> bool isProved() const { return m_isProved; }
</span><del>- bool canOptimize() const { return !m_edges.isEmpty(); }
- bool canTrustCounts() const { return m_canTrustCounts; }
</del><ins>+ bool canOptimize() const { return (m_callTarget || m_executable) && !m_couldTakeSlowPath; }
</ins><span class="cx">
</span><del>- bool isClosureCall() const; // Returns true if any callee is a closure call.
-
</del><span class="cx"> void dump(PrintStream&) const;
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- void makeClosureCall();
</del><ins>+ void makeClosureCall()
+ {
+ ASSERT(!m_isProved);
+ // Turn this into a closure call.
+ m_callTarget = JSValue();
+ }
</ins><span class="cx">
</span><span class="cx"> static CallLinkStatus computeFromLLInt(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex);
</span><del>-#if ENABLE(JIT)
- static CallLinkStatus computeFromCallEdgeProfile(CallEdgeProfile*);
- static CallLinkStatus computeFromCallLinkInfo(
- const ConcurrentJITLocker&, CallLinkInfo&);
-#endif
</del><span class="cx">
</span><del>- CallEdgeList m_edges;
</del><ins>+ JSValue m_callTarget;
+ ExecutableBase* m_executable;
</ins><span class="cx"> bool m_couldTakeSlowPath;
</span><span class="cx"> bool m_isProved;
</span><del>- bool m_canTrustCounts;
</del><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallVariantcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/CallVariant.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallVariant.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallVariant.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,54 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "CallVariant.h"
-
-#include "JSCInlines.h"
-
-namespace JSC {
-
-void CallVariant::dump(PrintStream& out) const
-{
- if (!*this) {
- out.print("null");
- return;
- }
-
- if (InternalFunction* internalFunction = this->internalFunction()) {
- out.print("InternalFunction: ", JSValue(internalFunction));
- return;
- }
-
- if (JSFunction* function = this->function()) {
- out.print("(Function: ", JSValue(function), "; Executable: ", *executable(), ")");
- return;
- }
-
- out.print("Executable: ", *executable());
-}
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCallVarianth"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/CallVariant.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CallVariant.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CallVariant.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,198 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CallVariant_h
-#define CallVariant_h
-
-#include "Executable.h"
-#include "JSCell.h"
-#include "JSFunction.h"
-
-namespace JSC {
-
-// The CallVariant class is meant to encapsulate a callee in a way that is useful for call linking
-// and inlining. Because JavaScript has closures, and because JSC implements the notion of internal
-// non-function objects that nevertheless provide call traps, the call machinery wants to see a
-// callee in one of the following four forms:
-//
-// JSFunction callee: This means that we expect the callsite to always call a particular function
-// instance, that is associated with a particular activation. This pinpoints not just the code
-// that will be called (i.e. the executable) but also the scope within which the code runs.
-//
-// Executable callee: This corresponds to a call to a closure. In this case, we know that the
-// callsite will call a JSFunction, but we do not know which particular JSFunction. We do know
-// what code will be called - i.e. we know the executable.
-//
-// InternalFunction callee: JSC supports a special kind of native functions that support bizarre
-// semantics. These are always singletons. If we know that the callee is an InternalFunction
-// then we know both the code that will be called and the scope; in fact the "scope" is really
-// just the InternalFunction itself.
-//
-// Something else: It's possible call all manner of rubbish in JavaScript. This implicitly supports
-// bizarre object callees, but it can't really tell you anything interesting about them other
-// than the fact that they don't fall into any of the above categories.
-//
-// This class serves as a kind of union over these four things. It does so by just holding a
-// JSCell*. We determine which of the modes its in by doing type checks on the cell. Note that there
-// is no lifecycle management for the cell because this class is always used in contexts where we
-// either do custom weak reference logic over instances of this class (see CallEdgeProfile), or we
-// are inside the compiler and we assume that the compiler runs in between collections and so can
-// touch the heap without notifying anyone.
-
-class CallVariant {
-public:
- explicit CallVariant(JSCell* callee = nullptr)
- : m_callee(callee)
- {
- }
-
- CallVariant(WTF::HashTableDeletedValueType)
- : m_callee(deletedToken())
- {
- }
-
- bool operator!() const { return !m_callee; }
-
- // If this variant refers to a function, change it to refer to its executable.
- ALWAYS_INLINE CallVariant despecifiedClosure() const
- {
- if (m_callee->type() == JSFunctionType)
- return CallVariant(jsCast<JSFunction*>(m_callee)->executable());
- return *this;
- }
-
- JSCell* rawCalleeCell() const { return m_callee; }
-
- InternalFunction* internalFunction() const
- {
- return jsDynamicCast<InternalFunction*>(m_callee);
- }
-
- JSFunction* function() const
- {
- return jsDynamicCast<JSFunction*>(m_callee);
- }
-
- bool isClosureCall() const { return !!jsDynamicCast<ExecutableBase*>(m_callee); }
-
- ExecutableBase* executable() const
- {
- if (JSFunction* function = this->function())
- return function->executable();
- return jsDynamicCast<ExecutableBase*>(m_callee);
- }
-
- JSCell* nonExecutableCallee() const
- {
- RELEASE_ASSERT(!isClosureCall());
- return m_callee;
- }
-
- Intrinsic intrinsicFor(CodeSpecializationKind kind) const
- {
- if (ExecutableBase* executable = this->executable())
- return executable->intrinsicFor(kind);
- return NoIntrinsic;
- }
-
- FunctionExecutable* functionExecutable() const
- {
- if (ExecutableBase* executable = this->executable())
- return jsDynamicCast<FunctionExecutable*>(executable);
- return nullptr;
- }
-
- void dump(PrintStream& out) const;
-
- bool isHashTableDeletedValue() const
- {
- return m_callee == deletedToken();
- }
-
- bool operator==(const CallVariant& other) const
- {
- return m_callee == other.m_callee;
- }
-
- bool operator!=(const CallVariant& other) const
- {
- return !(*this == other);
- }
-
- bool operator<(const CallVariant& other) const
- {
- return m_callee < other.m_callee;
- }
-
- bool operator>(const CallVariant& other) const
- {
- return other < *this;
- }
-
- bool operator<=(const CallVariant& other) const
- {
- return !(*this < other);
- }
-
- bool operator>=(const CallVariant& other) const
- {
- return other <= *this;
- }
-
- unsigned hash() const
- {
- return WTF::PtrHash<JSCell*>::hash(m_callee);
- }
-
-private:
- static JSCell* deletedToken() { return bitwise_cast<JSCell*>(static_cast<uintptr_t>(1)); }
-
- JSCell* m_callee;
-};
-
-struct CallVariantHash {
- static unsigned hash(const CallVariant& key) { return key.hash(); }
- static bool equal(const CallVariant& a, const CallVariant& b) { return a == b; }
- static const bool safeToCompareToEmptyOrDeleted = true;
-};
-
-typedef Vector<CallVariant, 1> CallVariantList;
-
-} // namespace JSC
-
-namespace WTF {
-
-template<typename T> struct DefaultHash;
-template<> struct DefaultHash<JSC::CallVariant> {
- typedef JSC::CallVariantHash Hash;
-};
-
-template<typename T> struct HashTraits;
-template<> struct HashTraits<JSC::CallVariant> : SimpleClassHashTraits<JSC::CallVariant> { };
-
-} // namespace WTF
-
-#endif // CallVariant_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeOriginh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -154,17 +154,6 @@
</span><span class="cx"> return CodeForCall;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- static bool isNormalCall(Kind kind)
- {
- switch (kind) {
- case Call:
- case Construct:
- return true;
- default:
- return false;
- }
- }
-
</del><span class="cx"> Vector<ValueRecovery> arguments; // Includes 'this'.
</span><span class="cx"> WriteBarrier<ScriptExecutable> executable;
</span><span class="cx"> ValueRecovery calleeRecovery;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeExitKindcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -38,8 +38,8 @@
</span><span class="cx"> return "Unset";
</span><span class="cx"> case BadType:
</span><span class="cx"> return "BadType";
</span><del>- case BadCell:
- return "BadCell";
</del><ins>+ case BadFunction:
+ return "BadFunction";
</ins><span class="cx"> case BadExecutable:
</span><span class="cx"> return "BadExecutable";
</span><span class="cx"> case BadCache:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeExitKindh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ExitKind.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ExitKind.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/ExitKind.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> enum ExitKind : uint8_t {
</span><span class="cx"> ExitKindUnset,
</span><span class="cx"> BadType, // We exited because a type prediction was wrong.
</span><del>- BadCell, // We exited because we made an incorrect assumption about what cell we would see. Usually used for function checks.
</del><ins>+ BadFunction, // We exited because we made an incorrect assumption about what function we would see.
</ins><span class="cx"> BadExecutable, // We exited because we made an incorrect assumption about what executable we would see.
</span><span class="cx"> BadCache, // We exited because an inline cache was wrong.
</span><span class="cx"> BadConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -187,8 +187,7 @@
</span><span class="cx"> AccessorCallJITStubRoutine* stub = static_cast<AccessorCallJITStubRoutine*>(
</span><span class="cx"> list->at(listIndex).stubRoutine());
</span><span class="cx"> callLinkStatus = std::make_unique<CallLinkStatus>(
</span><del>- CallLinkStatus::computeFor(
- locker, profiledBlock, *stub->m_callLinkInfo, callExitSiteData));
</del><ins>+ CallLinkStatus::computeFor(locker, *stub->m_callLinkInfo, callExitSiteData));
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case GetByIdAccess::CustomGetter:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePutByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -247,7 +247,7 @@
</span><span class="cx"> std::unique_ptr<CallLinkStatus> callLinkStatus =
</span><span class="cx"> std::make_unique<CallLinkStatus>(
</span><span class="cx"> CallLinkStatus::computeFor(
</span><del>- locker, profiledBlock, *stub->m_callLinkInfo, callExitSiteData));
</del><ins>+ locker, *stub->m_callLinkInfo, callExitSiteData));
</ins><span class="cx">
</span><span class="cx"> variant = PutByIdVariant::setter(
</span><span class="cx"> structure, complexGetStatus.offset(), complexGetStatus.chain(),
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1459,6 +1459,14 @@
</span><span class="cx"> forNode(node).setType(SpecInt32);
</span><span class="cx"> break;
</span><span class="cx">
</span><ins>+ case CheckExecutable: {
+ // FIXME: We could track executables in AbstractValue, which would allow us to get rid of these checks
+ // more thoroughly. https://bugs.webkit.org/show_bug.cgi?id=106200
+ // FIXME: We could eliminate these entirely if we know the exact value that flows into this.
+ // https://bugs.webkit.org/show_bug.cgi?id=106201
+ break;
+ }
+
</ins><span class="cx"> case CheckStructure: {
</span><span class="cx"> // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
</span><span class="cx"> AbstractValue& value = forNode(node->child1());
</span><span class="lines">@@ -1718,29 +1726,16 @@
</span><span class="cx"> m_state.setIsValid(false);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
- case GetExecutable: {
- JSValue value = forNode(node->child1()).value();
- if (value) {
- JSFunction* function = jsDynamicCast<JSFunction*>(value);
- if (function) {
- setConstant(node, *m_graph.freeze(function->executable()));
- break;
- }
- }
- forNode(node).setType(SpecCellOther);
- break;
- }
</del><span class="cx">
</span><del>- case CheckCell: {
</del><ins>+ case CheckFunction: {
</ins><span class="cx"> JSValue value = forNode(node->child1()).value();
</span><del>- if (value == node->cellOperand()->value()) {
</del><ins>+ if (value == node->function()->value()) {
</ins><span class="cx"> m_state.setFoundConstants(true);
</span><span class="cx"> ASSERT(value);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- filterByValue(node->child1(), *node->cellOperand());
</del><ins>+ filterByValue(node->child1(), *node->function());
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1864,6 +1859,8 @@
</span><span class="cx">
</span><span class="cx"> case VariableWatchpoint:
</span><span class="cx"> case VarInjectionWatchpoint:
</span><ins>+ break;
+
</ins><span class="cx"> case PutGlobalVar:
</span><span class="cx"> case NotifyWrite:
</span><span class="cx"> break;
</span><span class="lines">@@ -1903,16 +1900,7 @@
</span><span class="cx"> forNode(node).makeHeapTop();
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- case ProfiledCall:
- case ProfiledConstruct:
- if (forNode(m_graph.varArgChild(node, 0)).m_value)
- m_state.setFoundConstants(true);
- clobberWorld(node->origin.semantic, clobberLimit);
- forNode(node).makeHeapTop();
- break;
-
</del><span class="cx"> case ForceOSRExit:
</span><del>- case CheckBadCell:
</del><span class="cx"> m_state.setIsValid(false);
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="lines">@@ -1967,8 +1955,7 @@
</span><span class="cx"> case LastNodeType:
</span><span class="cx"> case ArithIMul:
</span><span class="cx"> case FiatInt52:
</span><del>- case BottomValue:
- DFG_CRASH(m_graph, node, "Unexpected node type");
</del><ins>+ RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBackwardsPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -389,11 +389,6 @@
</span><span class="cx"> // then -0 and 0 are treated the same.
</span><span class="cx"> node->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther);
</span><span class="cx"> break;
</span><del>- case SwitchCell:
- // There is currently no point to being clever here since this is used for switching
- // on objects.
- mergeDefaultFlags(node);
- break;
</del><span class="cx"> }
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBasicBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -58,9 +58,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>-BasicBlock::~BasicBlock()
-{
-}
</del><ins>+BasicBlock::~BasicBlock() { }
</ins><span class="cx">
</span><span class="cx"> void BasicBlock::ensureLocals(unsigned newNumLocals)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBasicBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -62,7 +62,6 @@
</span><span class="cx"> Node*& operator[](size_t i) { return at(i); }
</span><span class="cx"> Node* operator[](size_t i) const { return at(i); }
</span><span class="cx"> Node* last() const { return at(size() - 1); }
</span><del>- Node* takeLast() { return m_nodes.takeLast(); }
</del><span class="cx"> void resize(size_t size) { m_nodes.resize(size); }
</span><span class="cx"> void grow(size_t size) { m_nodes.grow(size); }
</span><span class="cx">
</span><span class="lines">@@ -107,13 +106,6 @@
</span><span class="cx">
</span><span class="cx"> void dump(PrintStream& out) const;
</span><span class="cx">
</span><del>- void didLink()
- {
-#if !ASSERT_DISABLED
- isLinked = true;
-#endif
- }
-
</del><span class="cx"> // This value is used internally for block linking and OSR entry. It is mostly meaningless
</span><span class="cx"> // for other purposes due to inlining.
</span><span class="cx"> unsigned bytecodeBegin;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -50,8 +50,6 @@
</span><span class="cx">
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx">
</span><del>-static const bool verbose = false;
-
</del><span class="cx"> class ConstantBufferKey {
</span><span class="cx"> public:
</span><span class="cx"> ConstantBufferKey()
</span><span class="lines">@@ -180,20 +178,14 @@
</span><span class="cx"> Node* callTarget, int argCount, int registerOffset, CallLinkStatus);
</span><span class="cx"> void handleCall(int result, NodeType op, CodeSpecializationKind, unsigned instructionSize, int callee, int argCount, int registerOffset);
</span><span class="cx"> void handleCall(Instruction* pc, NodeType op, CodeSpecializationKind);
</span><del>- void emitFunctionChecks(CallVariant, Node* callTarget, int registerOffset, CodeSpecializationKind);
- void undoFunctionChecks(CallVariant);
</del><ins>+ void emitFunctionChecks(const CallLinkStatus&, Node* callTarget, int registerOffset, CodeSpecializationKind);
</ins><span class="cx"> void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind);
</span><del>- unsigned inliningCost(CallVariant, int argumentCountIncludingThis, CodeSpecializationKind); // Return UINT_MAX if it's not an inlining candidate. By convention, intrinsics have a cost of 1.
</del><span class="cx"> // Handle inlining. Return true if it succeeded, false if we need to plant a call.
</span><del>- bool handleInlining(Node* callTargetNode, int resultOperand, const CallLinkStatus&, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, NodeType callOp, InlineCallFrame::Kind, SpeculatedType prediction);
- enum CallerLinkability { CallerDoesNormalLinking, CallerLinksManually };
- bool attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, CallerLinkability, SpeculatedType prediction, unsigned& inliningBalance);
- void inlineCall(Node* callTargetNode, int resultOperand, CallVariant, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind, CallerLinkability);
- void cancelLinkingForBlock(InlineStackEntry*, BasicBlock*); // Only works when the given block is the last one to have been added for that inline stack entry.
</del><ins>+ bool handleInlining(Node* callTargetNode, int resultOperand, const CallLinkStatus&, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind);
</ins><span class="cx"> // Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
</span><span class="cx"> bool handleIntrinsic(int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction);
</span><span class="cx"> bool handleTypedArrayConstructor(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, TypedArrayType);
</span><del>- bool handleConstantInternalFunction(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind);
</del><ins>+ bool handleConstantInternalFunction(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind);
</ins><span class="cx"> Node* handlePutByOffset(Node* base, unsigned identifier, PropertyOffset, Node* value);
</span><span class="cx"> Node* handleGetByOffset(SpeculatedType, Node* base, const StructureSet&, unsigned identifierNumber, PropertyOffset, NodeType op = GetByOffset);
</span><span class="cx"> void handleGetById(
</span><span class="lines">@@ -208,9 +200,8 @@
</span><span class="cx">
</span><span class="cx"> Node* getScope(unsigned skipCount);
</span><span class="cx">
</span><ins>+ // Prepare to parse a block.
</ins><span class="cx"> void prepareToParseBlock();
</span><del>- void clearCaches();
-
</del><span class="cx"> // Parse a single basic block of bytecode instructions.
</span><span class="cx"> bool parseBlock(unsigned limit);
</span><span class="cx"> // Link block successors.
</span><span class="lines">@@ -305,13 +296,6 @@
</span><span class="cx">
</span><span class="cx"> return delayed.execute(this, setMode);
</span><span class="cx"> }
</span><del>-
- void processSetLocalQueue()
- {
- for (unsigned i = 0; i < m_setLocalQueue.size(); ++i)
- m_setLocalQueue[i].execute(this);
- m_setLocalQueue.resize(0);
- }
</del><span class="cx">
</span><span class="cx"> Node* set(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
</span><span class="cx"> {
</span><span class="lines">@@ -653,13 +637,6 @@
</span><span class="cx">
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><del>-
- void removeLastNodeFromGraph(NodeType expectedNodeType)
- {
- Node* node = m_currentBlock->takeLast();
- RELEASE_ASSERT(node->op() == expectedNodeType);
- m_graph.m_allocator.free(node);
- }
</del><span class="cx">
</span><span class="cx"> void addVarArgChild(Node* child)
</span><span class="cx"> {
</span><span class="lines">@@ -668,7 +645,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Node* addCallWithoutSettingResult(
</span><del>- NodeType op, OpInfo opInfo, Node* callee, int argCount, int registerOffset,
</del><ins>+ NodeType op, Node* callee, int argCount, int registerOffset,
</ins><span class="cx"> SpeculatedType prediction)
</span><span class="cx"> {
</span><span class="cx"> addVarArgChild(callee);
</span><span class="lines">@@ -676,19 +653,19 @@
</span><span class="cx"> if (parameterSlots > m_parameterSlots)
</span><span class="cx"> m_parameterSlots = parameterSlots;
</span><span class="cx">
</span><del>- int dummyThisArgument = op == Call || op == NativeCall || op == ProfiledCall ? 0 : 1;
</del><ins>+ int dummyThisArgument = op == Call || op == NativeCall ? 0 : 1;
</ins><span class="cx"> for (int i = 0 + dummyThisArgument; i < argCount; ++i)
</span><span class="cx"> addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
</span><span class="cx">
</span><del>- return addToGraph(Node::VarArg, op, opInfo, OpInfo(prediction));
</del><ins>+ return addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(prediction));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Node* addCall(
</span><del>- int result, NodeType op, OpInfo opInfo, Node* callee, int argCount, int registerOffset,
</del><ins>+ int result, NodeType op, Node* callee, int argCount, int registerOffset,
</ins><span class="cx"> SpeculatedType prediction)
</span><span class="cx"> {
</span><span class="cx"> Node* call = addCallWithoutSettingResult(
</span><del>- op, opInfo, callee, argCount, registerOffset, prediction);
</del><ins>+ op, callee, argCount, registerOffset, prediction);
</ins><span class="cx"> VirtualRegister resultReg(result);
</span><span class="cx"> if (resultReg.isValid())
</span><span class="cx"> set(VirtualRegister(result), call);
</span><span class="lines">@@ -894,7 +871,8 @@
</span><span class="cx"> Vector<UnlinkedBlock> m_unlinkedBlocks;
</span><span class="cx">
</span><span class="cx"> // Potential block linking targets. Must be sorted by bytecodeBegin, and
</span><del>- // cannot have two blocks that have the same bytecodeBegin.
</del><ins>+ // cannot have two blocks that have the same bytecodeBegin. For this very
+ // reason, this is not equivalent to
</ins><span class="cx"> Vector<BasicBlock*> m_blockLinkingTargets;
</span><span class="cx">
</span><span class="cx"> // If the callsite's basic block was split into two, then this will be
</span><span class="lines">@@ -1041,63 +1019,77 @@
</span><span class="cx"> CallLinkStatus callLinkStatus, SpeculatedType prediction)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(registerOffset <= 0);
</span><ins>+ CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
</ins><span class="cx">
</span><span class="cx"> if (callTarget->hasConstant())
</span><span class="cx"> callLinkStatus = CallLinkStatus(callTarget->asJSValue()).setIsProved(true);
</span><span class="cx">
</span><del>- if ((!callLinkStatus.canOptimize() || callLinkStatus.size() != 1)
- && !isFTL(m_graph.m_plan.mode) && Options::useFTLJIT()
- && InlineCallFrame::isNormalCall(kind)
- && CallEdgeLog::isEnabled()
- && Options::dfgDoesCallEdgeProfiling()) {
- ASSERT(op == Call || op == Construct);
- if (op == Call)
- op = ProfiledCall;
- else
- op = ProfiledConstruct;
- }
-
</del><span class="cx"> if (!callLinkStatus.canOptimize()) {
</span><span class="cx"> // Oddly, this conflates calls that haven't executed with calls that behaved sufficiently polymorphically
</span><span class="cx"> // that we cannot optimize them.
</span><span class="cx">
</span><del>- addCall(result, op, OpInfo(), callTarget, argumentCountIncludingThis, registerOffset, prediction);
</del><ins>+ addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset, prediction);
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> unsigned nextOffset = m_currentIndex + instructionSize;
</span><del>-
- OpInfo callOpInfo;
-
- if (handleInlining(callTarget, result, callLinkStatus, registerOffset, argumentCountIncludingThis, nextOffset, op, kind, prediction)) {
</del><ins>+
+ if (InternalFunction* function = callLinkStatus.internalFunction()) {
+ if (handleConstantInternalFunction(result, function, registerOffset, argumentCountIncludingThis, prediction, specializationKind)) {
+ // This phantoming has to be *after* the code for the intrinsic, to signify that
+ // the inputs must be kept alive whatever exits the intrinsic may do.
+ addToGraph(Phantom, callTarget);
+ emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, specializationKind);
+ return;
+ }
+
+ // Can only handle this using the generic call handler.
+ addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset, prediction);
+ return;
+ }
+
+ Intrinsic intrinsic = callLinkStatus.intrinsicFor(specializationKind);
+
+ JSFunction* knownFunction = nullptr;
+ if (intrinsic != NoIntrinsic) {
+ emitFunctionChecks(callLinkStatus, callTarget, registerOffset, specializationKind);
+
+ if (handleIntrinsic(result, intrinsic, registerOffset, argumentCountIncludingThis, prediction)) {
+ // This phantoming has to be *after* the code for the intrinsic, to signify that
+ // the inputs must be kept alive whatever exits the intrinsic may do.
+ addToGraph(Phantom, callTarget);
+ emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, specializationKind);
+ if (m_graph.compilation())
+ m_graph.compilation()->noticeInlinedCall();
+ return;
+ }
+ } else if (handleInlining(callTarget, result, callLinkStatus, registerOffset, argumentCountIncludingThis, nextOffset, kind)) {
</ins><span class="cx"> if (m_graph.compilation())
</span><span class="cx"> m_graph.compilation()->noticeInlinedCall();
</span><span class="cx"> return;
</span><del>- }
-
</del><span class="cx"> #if ENABLE(FTL_NATIVE_CALL_INLINING)
</span><del>- if (isFTL(m_graph.m_plan.mode) && Options::optimizeNativeCalls() && callLinkStatus.size() == 1 && !callLinkStatus.couldTakeSlowPath()) {
- CallVariant callee = callLinkStatus[0].callee();
- JSFunction* function = callee.function();
- CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
</del><ins>+ } else if (isFTL(m_graph.m_plan.mode) && Options::optimizeNativeCalls()) {
+ JSFunction* function = callLinkStatus.function();
</ins><span class="cx"> if (function && function->isHostFunction()) {
</span><del>- emitFunctionChecks(callee, callTarget, registerOffset, specializationKind);
- callOpInfo = OpInfo(m_graph.freeze(function));
</del><ins>+ emitFunctionChecks(callLinkStatus, callTarget, registerOffset, specializationKind);
+ knownFunction = function;
</ins><span class="cx">
</span><del>- if (op == Call || op == ProfiledCall)
</del><ins>+ if (op == Call)
</ins><span class="cx"> op = NativeCall;
</span><span class="cx"> else {
</span><del>- ASSERT(op == Construct || op == ProfiledConstruct);
</del><ins>+ ASSERT(op == Construct);
</ins><span class="cx"> op = NativeConstruct;
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>- }
</del><span class="cx"> #endif
</span><del>-
- addCall(result, op, callOpInfo, callTarget, argumentCountIncludingThis, registerOffset, prediction);
</del><ins>+ }
+ Node* call = addCall(result, op, callTarget, argumentCountIncludingThis, registerOffset, prediction);
+
+ if (knownFunction)
+ call->giveKnownFunction(knownFunction);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void ByteCodeParser::emitFunctionChecks(CallVariant callee, Node* callTarget, int registerOffset, CodeSpecializationKind kind)
</del><ins>+void ByteCodeParser::emitFunctionChecks(const CallLinkStatus& callLinkStatus, Node* callTarget, int registerOffset, CodeSpecializationKind kind)
</ins><span class="cx"> {
</span><span class="cx"> Node* thisArgument;
</span><span class="cx"> if (kind == CodeForCall)
</span><span class="lines">@@ -1105,52 +1097,58 @@
</span><span class="cx"> else
</span><span class="cx"> thisArgument = 0;
</span><span class="cx">
</span><del>- JSCell* calleeCell;
- Node* callTargetForCheck;
- if (callee.isClosureCall()) {
- calleeCell = callee.executable();
- callTargetForCheck = addToGraph(GetExecutable, callTarget);
- } else {
- calleeCell = callee.nonExecutableCallee();
- callTargetForCheck = callTarget;
</del><ins>+ if (callLinkStatus.isProved()) {
+ addToGraph(Phantom, callTarget, thisArgument);
+ return;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- ASSERT(calleeCell);
- addToGraph(CheckCell, OpInfo(m_graph.freeze(calleeCell)), callTargetForCheck, thisArgument);
</del><ins>+ ASSERT(callLinkStatus.canOptimize());
+
+ if (JSFunction* function = callLinkStatus.function())
+ addToGraph(CheckFunction, OpInfo(m_graph.freeze(function)), callTarget, thisArgument);
+ else {
+ ASSERT(callLinkStatus.executable());
+
+ addToGraph(CheckExecutable, OpInfo(callLinkStatus.executable()), callTarget, thisArgument);
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void ByteCodeParser::undoFunctionChecks(CallVariant callee)
-{
- removeLastNodeFromGraph(CheckCell);
- if (callee.isClosureCall())
- removeLastNodeFromGraph(GetExecutable);
-}
-
</del><span class="cx"> void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind kind)
</span><span class="cx"> {
</span><span class="cx"> for (int i = kind == CodeForCall ? 0 : 1; i < argumentCountIncludingThis; ++i)
</span><span class="cx"> addToGraph(Phantom, get(virtualRegisterForArgument(i, registerOffset)));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-unsigned ByteCodeParser::inliningCost(CallVariant callee, int argumentCountIncludingThis, CodeSpecializationKind kind)
</del><ins>+bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, const CallLinkStatus& callLinkStatus, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind)
</ins><span class="cx"> {
</span><ins>+ static const bool verbose = false;
+
+ CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
+
</ins><span class="cx"> if (verbose)
</span><del>- dataLog("Considering inlining ", callee, " into ", currentCodeOrigin(), "\n");
</del><ins>+ dataLog("Considering inlining ", callLinkStatus, " into ", currentCodeOrigin(), "\n");
</ins><span class="cx">
</span><del>- FunctionExecutable* executable = callee.functionExecutable();
- if (!executable) {
</del><ins>+ // First, the really simple checks: do we have an actual JS function?
+ if (!callLinkStatus.executable()) {
</ins><span class="cx"> if (verbose)
</span><del>- dataLog(" Failing because there is no function executable.");
- return UINT_MAX;
</del><ins>+ dataLog(" Failing because there is no executable.\n");
+ return false;
</ins><span class="cx"> }
</span><ins>+ if (callLinkStatus.executable()->isHostFunction()) {
+ if (verbose)
+ dataLog(" Failing because it's a host function.\n");
+ return false;
+ }
</ins><span class="cx">
</span><ins>+ FunctionExecutable* executable = jsCast<FunctionExecutable*>(callLinkStatus.executable());
+
</ins><span class="cx"> // Does the number of arguments we're passing match the arity of the target? We currently
</span><span class="cx"> // inline only if the number of arguments passed is greater than or equal to the number
</span><span class="cx"> // arguments expected.
</span><span class="cx"> if (static_cast<int>(executable->parameterCount()) + 1 > argumentCountIncludingThis) {
</span><span class="cx"> if (verbose)
</span><span class="cx"> dataLog(" Failing because of arity mismatch.\n");
</span><del>- return UINT_MAX;
</del><ins>+ return false;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Do we have a code block, and does the code block's size match the heuristics/requirements for
</span><span class="lines">@@ -1159,18 +1157,18 @@
</span><span class="cx"> // if we had a static proof of what was being called; this might happen for example if you call a
</span><span class="cx"> // global function, where watchpointing gives us static information. Overall, it's a rare case
</span><span class="cx"> // because we expect that any hot callees would have already been compiled.
</span><del>- CodeBlock* codeBlock = executable->baselineCodeBlockFor(kind);
</del><ins>+ CodeBlock* codeBlock = executable->baselineCodeBlockFor(specializationKind);
</ins><span class="cx"> if (!codeBlock) {
</span><span class="cx"> if (verbose)
</span><span class="cx"> dataLog(" Failing because no code block available.\n");
</span><del>- return UINT_MAX;
</del><ins>+ return false;
</ins><span class="cx"> }
</span><span class="cx"> CapabilityLevel capabilityLevel = inlineFunctionForCapabilityLevel(
</span><del>- codeBlock, kind, callee.isClosureCall());
</del><ins>+ codeBlock, specializationKind, callLinkStatus.isClosureCall());
</ins><span class="cx"> if (!canInline(capabilityLevel)) {
</span><span class="cx"> if (verbose)
</span><span class="cx"> dataLog(" Failing because the function is not inlineable.\n");
</span><del>- return UINT_MAX;
</del><ins>+ return false;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Check if the caller is already too large. We do this check here because that's just
</span><span class="lines">@@ -1180,7 +1178,7 @@
</span><span class="cx"> codeBlock->m_shouldAlwaysBeInlined = false;
</span><span class="cx"> if (verbose)
</span><span class="cx"> dataLog(" Failing because the caller is too large.\n");
</span><del>- return UINT_MAX;
</del><ins>+ return false;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // FIXME: this should be better at predicting how much bloat we will introduce by inlining
</span><span class="lines">@@ -1199,7 +1197,7 @@
</span><span class="cx"> if (depth >= Options::maximumInliningDepth()) {
</span><span class="cx"> if (verbose)
</span><span class="cx"> dataLog(" Failing because depth exceeded.\n");
</span><del>- return UINT_MAX;
</del><ins>+ return false;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (entry->executable() == executable) {
</span><span class="lines">@@ -1207,26 +1205,19 @@
</span><span class="cx"> if (recursion >= Options::maximumInliningRecursion()) {
</span><span class="cx"> if (verbose)
</span><span class="cx"> dataLog(" Failing because recursion detected.\n");
</span><del>- return UINT_MAX;
</del><ins>+ return false;
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (verbose)
</span><del>- dataLog(" Inlining should be possible.\n");
</del><ins>+ dataLog(" Committing to inlining.\n");
</ins><span class="cx">
</span><del>- // It might be possible to inline.
- return codeBlock->instructionCount();
-}
-
-void ByteCodeParser::inlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, CallerLinkability callerLinkability)
-{
- CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
</del><ins>+ // Now we know without a doubt that we are committed to inlining. So begin the process
+ // by checking the callee (if necessary) and making sure that arguments and the callee
+ // are flushed.
+ emitFunctionChecks(callLinkStatus, callTargetNode, registerOffset, specializationKind);
</ins><span class="cx">
</span><del>- ASSERT(inliningCost(callee, argumentCountIncludingThis, specializationKind) != UINT_MAX);
-
- CodeBlock* codeBlock = callee.functionExecutable()->baselineCodeBlockFor(specializationKind);
-
</del><span class="cx"> // FIXME: Don't flush constants!
</span><span class="cx">
</span><span class="cx"> int inlineCallFrameStart = m_inlineStackTop->remapOperand(VirtualRegister(registerOffset)).offset() + JSStack::CallFrameHeaderSize;
</span><span class="lines">@@ -1242,7 +1233,7 @@
</span><span class="cx"> resultReg = m_inlineStackTop->remapOperand(resultReg);
</span><span class="cx">
</span><span class="cx"> InlineStackEntry inlineStackEntry(
</span><del>- this, codeBlock, codeBlock, m_graph.lastBlock(), callee.function(), resultReg,
</del><ins>+ this, codeBlock, codeBlock, m_graph.lastBlock(), callLinkStatus.function(), resultReg,
</ins><span class="cx"> (VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind);
</span><span class="cx">
</span><span class="cx"> // This is where the actual inlining really happens.
</span><span class="lines">@@ -1256,8 +1247,8 @@
</span><span class="cx">
</span><span class="cx"> RELEASE_ASSERT(
</span><span class="cx"> m_inlineStackTop->m_inlineCallFrame->isClosureCall
</span><del>- == callee.isClosureCall());
- if (callee.isClosureCall()) {
</del><ins>+ == callLinkStatus.isClosureCall());
+ if (callLinkStatus.isClosureCall()) {
</ins><span class="cx"> VariableAccessData* calleeVariable =
</span><span class="cx"> set(VirtualRegister(JSStack::Callee), callTargetNode, ImmediateNakedSet)->variableAccessData();
</span><span class="cx"> VariableAccessData* scopeVariable =
</span><span class="lines">@@ -1272,7 +1263,7 @@
</span><span class="cx"> m_graph.m_inlineVariableData.append(inlineVariableData);
</span><span class="cx">
</span><span class="cx"> parseCodeBlock();
</span><del>- clearCaches(); // Reset our state now that we're back to the outer code.
</del><ins>+ prepareToParseBlock(); // Reset our state now that we're back to the outer code.
</ins><span class="cx">
</span><span class="cx"> m_currentIndex = oldIndex;
</span><span class="cx">
</span><span class="lines">@@ -1285,8 +1276,20 @@
</span><span class="cx"> else
</span><span class="cx"> ASSERT(inlineStackEntry.m_callsiteBlockHead->isLinked);
</span><span class="cx">
</span><del>- if (callerLinkability == CallerDoesNormalLinking)
- cancelLinkingForBlock(inlineStackEntry.m_caller, inlineStackEntry.m_callsiteBlockHead);
</del><ins>+ // It's possible that the callsite block head is not owned by the caller.
+ if (!inlineStackEntry.m_caller->m_unlinkedBlocks.isEmpty()) {
+ // It's definitely owned by the caller, because the caller created new blocks.
+ // Assert that this all adds up.
+ ASSERT(inlineStackEntry.m_caller->m_unlinkedBlocks.last().m_block == inlineStackEntry.m_callsiteBlockHead);
+ ASSERT(inlineStackEntry.m_caller->m_unlinkedBlocks.last().m_needsNormalLinking);
+ inlineStackEntry.m_caller->m_unlinkedBlocks.last().m_needsNormalLinking = false;
+ } else {
+ // It's definitely not owned by the caller. Tell the caller that he does not
+ // need to link his callsite block head, because we did it for him.
+ ASSERT(inlineStackEntry.m_caller->m_callsiteBlockHeadNeedsLinking);
+ ASSERT(inlineStackEntry.m_caller->m_callsiteBlockHead == inlineStackEntry.m_callsiteBlockHead);
+ inlineStackEntry.m_caller->m_callsiteBlockHeadNeedsLinking = false;
+ }
</ins><span class="cx">
</span><span class="cx"> linkBlocks(inlineStackEntry.m_unlinkedBlocks, inlineStackEntry.m_blockLinkingTargets);
</span><span class="cx"> } else
</span><span class="lines">@@ -1305,19 +1308,16 @@
</span><span class="cx"> // for release builds because this block will never serve as a potential target
</span><span class="cx"> // in the linker's binary search.
</span><span class="cx"> lastBlock->bytecodeBegin = m_currentIndex;
</span><del>- if (callerLinkability == CallerDoesNormalLinking) {
- if (verbose)
- dataLog("Adding unlinked block ", RawPointer(m_graph.lastBlock()), " (one return)\n");
- m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.lastBlock()));
- }
</del><ins>+ m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.lastBlock()));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> m_currentBlock = m_graph.lastBlock();
</span><del>- return;
</del><ins>+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // If we get to this point then all blocks must end in some sort of terminals.
</span><span class="cx"> ASSERT(lastBlock->last()->isTerminal());
</span><ins>+
</ins><span class="cx">
</span><span class="cx"> // Need to create a new basic block for the continuation at the caller.
</span><span class="cx"> RefPtr<BasicBlock> block = adoptRef(new BasicBlock(nextOffset, m_numArguments, m_numLocals, PNaN));
</span><span class="lines">@@ -1333,296 +1333,23 @@
</span><span class="cx"> ASSERT(!node->targetBlock());
</span><span class="cx"> node->targetBlock() = block.get();
</span><span class="cx"> inlineStackEntry.m_unlinkedBlocks[i].m_needsEarlyReturnLinking = false;
</span><del>- if (verbose)
- dataLog("Marking ", RawPointer(blockToLink), " as linked (jumps to return)\n");
- blockToLink->didLink();
</del><ins>+#if !ASSERT_DISABLED
+ blockToLink->isLinked = true;
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> m_currentBlock = block.get();
</span><span class="cx"> ASSERT(m_inlineStackTop->m_caller->m_blockLinkingTargets.isEmpty() || m_inlineStackTop->m_caller->m_blockLinkingTargets.last()->bytecodeBegin < nextOffset);
</span><del>- if (verbose)
- dataLog("Adding unlinked block ", RawPointer(block.get()), " (many returns)\n");
- if (callerLinkability == CallerDoesNormalLinking) {
- m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(block.get()));
- m_inlineStackTop->m_caller->m_blockLinkingTargets.append(block.get());
- }
</del><ins>+ m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(block.get()));
+ m_inlineStackTop->m_caller->m_blockLinkingTargets.append(block.get());
</ins><span class="cx"> m_graph.appendBlock(block);
</span><span class="cx"> prepareToParseBlock();
</span><del>-}
-
-void ByteCodeParser::cancelLinkingForBlock(InlineStackEntry* inlineStackEntry, BasicBlock* block)
-{
- // It's possible that the callsite block head is not owned by the caller.
- if (!inlineStackEntry->m_unlinkedBlocks.isEmpty()) {
- // It's definitely owned by the caller, because the caller created new blocks.
- // Assert that this all adds up.
- ASSERT_UNUSED(block, inlineStackEntry->m_unlinkedBlocks.last().m_block == block);
- ASSERT(inlineStackEntry->m_unlinkedBlocks.last().m_needsNormalLinking);
- inlineStackEntry->m_unlinkedBlocks.last().m_needsNormalLinking = false;
- } else {
- // It's definitely not owned by the caller. Tell the caller that he does not
- // need to link his callsite block head, because we did it for him.
- ASSERT(inlineStackEntry->m_callsiteBlockHeadNeedsLinking);
- ASSERT_UNUSED(block, inlineStackEntry->m_callsiteBlockHead == block);
- inlineStackEntry->m_callsiteBlockHeadNeedsLinking = false;
- }
-}
-
-bool ByteCodeParser::attemptToInlineCall(Node* callTargetNode, int resultOperand, CallVariant callee, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, InlineCallFrame::Kind kind, CallerLinkability callerLinkability, SpeculatedType prediction, unsigned& inliningBalance)
-{
- CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
</del><span class="cx">
</span><del>- if (!inliningBalance)
- return false;
-
- if (InternalFunction* function = callee.internalFunction()) {
- if (handleConstantInternalFunction(resultOperand, function, registerOffset, argumentCountIncludingThis, specializationKind)) {
- addToGraph(Phantom, callTargetNode);
- emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, specializationKind);
- inliningBalance--;
- return true;
- }
- return false;
- }
-
- Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
- if (intrinsic != NoIntrinsic) {
- if (handleIntrinsic(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction)) {
- addToGraph(Phantom, callTargetNode);
- emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, specializationKind);
- inliningBalance--;
- return true;
- }
- return false;
- }
-
- unsigned myInliningCost = inliningCost(callee, argumentCountIncludingThis, specializationKind);
- if (myInliningCost > inliningBalance)
- return false;
-
- inlineCall(callTargetNode, resultOperand, callee, registerOffset, argumentCountIncludingThis, nextOffset, kind, callerLinkability);
- inliningBalance -= myInliningCost;
</del><ins>+ // At this point we return and continue to generate code for the caller, but
+ // in the new basic block.
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, const CallLinkStatus& callLinkStatus, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, NodeType callOp, InlineCallFrame::Kind kind, SpeculatedType prediction)
-{
- if (verbose) {
- dataLog("Handling inlining...\n");
- dataLog("Stack: ", currentCodeOrigin(), "\n");
- }
- CodeSpecializationKind specializationKind = InlineCallFrame::specializationKindFor(kind);
-
- if (!callLinkStatus.size()) {
- if (verbose)
- dataLog("Bailing inlining.\n");
- return false;
- }
-
- unsigned inliningBalance = Options::maximumFunctionForCallInlineCandidateInstructionCount();
- if (specializationKind == CodeForConstruct)
- inliningBalance = std::min(inliningBalance, Options::maximumFunctionForConstructInlineCandidateInstructionCount());
- if (callLinkStatus.isClosureCall())
- inliningBalance = std::min(inliningBalance, Options::maximumFunctionForClosureCallInlineCandidateInstructionCount());
-
- // First check if we can avoid creating control flow. Our inliner does some CFG
- // simplification on the fly and this helps reduce compile times, but we can only leverage
- // this in cases where we don't need control flow diamonds to check the callee.
- if (!callLinkStatus.couldTakeSlowPath() && callLinkStatus.size() == 1) {
- emitFunctionChecks(
- callLinkStatus[0].callee(), callTargetNode, registerOffset, specializationKind);
- bool result = attemptToInlineCall(
- callTargetNode, resultOperand, callLinkStatus[0].callee(), registerOffset,
- argumentCountIncludingThis, nextOffset, kind, CallerDoesNormalLinking, prediction,
- inliningBalance);
- if (!result && !callLinkStatus.isProved())
- undoFunctionChecks(callLinkStatus[0].callee());
- if (verbose) {
- dataLog("Done inlining (simple).\n");
- dataLog("Stack: ", currentCodeOrigin(), "\n");
- }
- return result;
- }
-
- // We need to create some kind of switch over callee. For now we only do this if we believe that
- // we're in the top tier. We have two reasons for this: first, it provides us an opportunity to
- // do more detailed polyvariant/polymorphic profiling; and second, it reduces compile times in
- // the DFG. And by polyvariant profiling we mean polyvariant profiling of *this* call. Note that
- // we could improve that aspect of this by doing polymorphic inlining but having the profiling
- // also. Currently we opt against this, but it could be interesting. That would require having a
- // separate node for call edge profiling.
- // FIXME: Introduce the notion of a separate call edge profiling node.
- // https://bugs.webkit.org/show_bug.cgi?id=136033
- if (!isFTL(m_graph.m_plan.mode) || !Options::enablePolymorphicCallInlining()) {
- if (verbose) {
- dataLog("Bailing inlining (hard).\n");
- dataLog("Stack: ", currentCodeOrigin(), "\n");
- }
- return false;
- }
-
- unsigned oldOffset = m_currentIndex;
-
- bool allAreClosureCalls = true;
- bool allAreDirectCalls = true;
- for (unsigned i = callLinkStatus.size(); i--;) {
- if (callLinkStatus[i].callee().isClosureCall())
- allAreDirectCalls = false;
- else
- allAreClosureCalls = false;
- }
-
- Node* thingToSwitchOn;
- if (allAreDirectCalls)
- thingToSwitchOn = callTargetNode;
- else if (allAreClosureCalls)
- thingToSwitchOn = addToGraph(GetExecutable, callTargetNode);
- else {
- // FIXME: We should be able to handle this case, but it's tricky and we don't know of cases
- // where it would be beneficial. Also, CallLinkStatus would make all callees appear like
- // closure calls if any calls were closure calls - except for calls to internal functions.
- // So this will only arise if some callees are internal functions and others are closures.
- // https://bugs.webkit.org/show_bug.cgi?id=136020
- if (verbose) {
- dataLog("Bailing inlining (mix).\n");
- dataLog("Stack: ", currentCodeOrigin(), "\n");
- }
- return false;
- }
-
- if (verbose) {
- dataLog("Doing hard inlining...\n");
- dataLog("Stack: ", currentCodeOrigin(), "\n");
- }
-
- // This makes me wish that we were in SSA all the time. We need to pick a variable into which to
- // store the callee so that it will be accessible to all of the blocks we're about to create. We
- // get away with doing an immediate-set here because we wouldn't have performed any side effects
- // yet.
- if (verbose)
- dataLog("Register offset: ", registerOffset);
- VirtualRegister calleeReg(registerOffset + JSStack::Callee);
- calleeReg = m_inlineStackTop->remapOperand(calleeReg);
- if (verbose)
- dataLog("Callee is going to be ", calleeReg, "\n");
- setDirect(calleeReg, callTargetNode, ImmediateSetWithFlush);
-
- SwitchData& data = *m_graph.m_switchData.add();
- data.kind = SwitchCell;
- addToGraph(Switch, OpInfo(&data), thingToSwitchOn);
-
- BasicBlock* originBlock = m_currentBlock;
- if (verbose)
- dataLog("Marking ", RawPointer(originBlock), " as linked (origin of poly inline)\n");
- originBlock->didLink();
- cancelLinkingForBlock(m_inlineStackTop, originBlock);
-
- // Each inlined callee will have a landing block that it returns at. They should all have jumps
- // to the continuation block, which we create last.
- Vector<BasicBlock*> landingBlocks;
-
- // We make force this true if we give up on inlining any of the edges.
- bool couldTakeSlowPath = callLinkStatus.couldTakeSlowPath();
-
- if (verbose)
- dataLog("About to loop over functions at ", currentCodeOrigin(), ".\n");
-
- for (unsigned i = 0; i < callLinkStatus.size(); ++i) {
- m_currentIndex = oldOffset;
- RefPtr<BasicBlock> block = adoptRef(new BasicBlock(UINT_MAX, m_numArguments, m_numLocals, PNaN));
- m_currentBlock = block.get();
- m_graph.appendBlock(block);
- prepareToParseBlock();
-
- Node* myCallTargetNode = getDirect(calleeReg);
-
- bool inliningResult = attemptToInlineCall(
- myCallTargetNode, resultOperand, callLinkStatus[i].callee(), registerOffset,
- argumentCountIncludingThis, nextOffset, kind, CallerLinksManually, prediction,
- inliningBalance);
-
- if (!inliningResult) {
- // That failed so we let the block die. Nothing interesting should have been added to
- // the block. We also give up on inlining any of the (less frequent) callees.
- ASSERT(m_currentBlock == block.get());
- ASSERT(m_graph.m_blocks.last() == block);
- m_graph.killBlockAndItsContents(block.get());
- m_graph.m_blocks.removeLast();
-
- // The fact that inlining failed means we need a slow path.
- couldTakeSlowPath = true;
- break;
- }
-
- JSCell* thingToCaseOn;
- if (allAreDirectCalls)
- thingToCaseOn = callLinkStatus[i].callee().nonExecutableCallee();
- else {
- ASSERT(allAreClosureCalls);
- thingToCaseOn = callLinkStatus[i].callee().executable();
- }
- data.cases.append(SwitchCase(m_graph.freeze(thingToCaseOn), block.get()));
- m_currentIndex = nextOffset;
- processSetLocalQueue(); // This only comes into play for intrinsics, since normal inlined code will leave an empty queue.
- addToGraph(Jump);
- if (verbose)
- dataLog("Marking ", RawPointer(m_currentBlock), " as linked (tail of poly inlinee)\n");
- m_currentBlock->didLink();
- landingBlocks.append(m_currentBlock);
-
- if (verbose)
- dataLog("Finished inlining ", callLinkStatus[i].callee(), " at ", currentCodeOrigin(), ".\n");
- }
-
- RefPtr<BasicBlock> slowPathBlock = adoptRef(
- new BasicBlock(UINT_MAX, m_numArguments, m_numLocals, PNaN));
- m_currentIndex = oldOffset;
- data.fallThrough = BranchTarget(slowPathBlock.get());
- m_graph.appendBlock(slowPathBlock);
- if (verbose)
- dataLog("Marking ", RawPointer(slowPathBlock.get()), " as linked (slow path block)\n");
- slowPathBlock->didLink();
- prepareToParseBlock();
- m_currentBlock = slowPathBlock.get();
- Node* myCallTargetNode = getDirect(calleeReg);
- if (couldTakeSlowPath) {
- addCall(
- resultOperand, callOp, OpInfo(), myCallTargetNode, argumentCountIncludingThis,
- registerOffset, prediction);
- } else {
- addToGraph(CheckBadCell);
- addToGraph(Phantom, myCallTargetNode);
- emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, specializationKind);
-
- set(VirtualRegister(resultOperand), addToGraph(BottomValue));
- }
-
- m_currentIndex = nextOffset;
- processSetLocalQueue();
- addToGraph(Jump);
- landingBlocks.append(m_currentBlock);
-
- RefPtr<BasicBlock> continuationBlock = adoptRef(
- new BasicBlock(UINT_MAX, m_numArguments, m_numLocals, PNaN));
- m_graph.appendBlock(continuationBlock);
- if (verbose)
- dataLog("Adding unlinked block ", RawPointer(continuationBlock.get()), " (continuation)\n");
- m_inlineStackTop->m_unlinkedBlocks.append(UnlinkedBlock(continuationBlock.get()));
- prepareToParseBlock();
- m_currentBlock = continuationBlock.get();
-
- for (unsigned i = landingBlocks.size(); i--;)
- landingBlocks[i]->last()->targetBlock() = continuationBlock.get();
-
- m_currentIndex = oldOffset;
-
- if (verbose) {
- dataLog("Done inlining (hard).\n");
- dataLog("Stack: ", currentCodeOrigin(), "\n");
- }
- return true;
-}
-
</del><span class="cx"> bool ByteCodeParser::handleMinMax(int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis)
</span><span class="cx"> {
</span><span class="cx"> if (argumentCountIncludingThis == 1) { // Math.min()
</span><span class="lines">@@ -1918,7 +1645,7 @@
</span><span class="cx">
</span><span class="cx"> bool ByteCodeParser::handleConstantInternalFunction(
</span><span class="cx"> int resultOperand, InternalFunction* function, int registerOffset,
</span><del>- int argumentCountIncludingThis, CodeSpecializationKind kind)
</del><ins>+ int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind kind)
</ins><span class="cx"> {
</span><span class="cx"> // If we ever find that we have a lot of internal functions that we specialize for,
</span><span class="cx"> // then we should probably have some sort of hashtable dispatch, or maybe even
</span><span class="lines">@@ -1927,6 +1654,8 @@
</span><span class="cx"> // we know about is small enough, that having just a linear cascade of if statements
</span><span class="cx"> // is good enough.
</span><span class="cx">
</span><ins>+ UNUSED_PARAM(prediction); // Remove this once we do more things.
+
</ins><span class="cx"> if (function->classInfo() == ArrayConstructor::info()) {
</span><span class="cx"> if (function->globalObject() != m_inlineStackTop->m_codeBlock->globalObject())
</span><span class="cx"> return false;
</span><span class="lines">@@ -2291,12 +2020,6 @@
</span><span class="cx">
</span><span class="cx"> void ByteCodeParser::prepareToParseBlock()
</span><span class="cx"> {
</span><del>- clearCaches();
- ASSERT(m_setLocalQueue.isEmpty());
-}
-
-void ByteCodeParser::clearCaches()
-{
</del><span class="cx"> m_constants.resize(0);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2336,7 +2059,9 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> while (true) {
</span><del>- processSetLocalQueue();
</del><ins>+ for (unsigned i = 0; i < m_setLocalQueue.size(); ++i)
+ m_setLocalQueue[i].execute(this);
+ m_setLocalQueue.resize(0);
</ins><span class="cx">
</span><span class="cx"> // Don't extend over jump destinations.
</span><span class="cx"> if (m_currentIndex == limit) {
</span><span class="lines">@@ -2480,13 +2205,13 @@
</span><span class="cx"> JSCell* cachedFunction = currentInstruction[2].u.jsCell.get();
</span><span class="cx"> if (!cachedFunction
</span><span class="cx"> || m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
</span><del>- || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell)) {
</del><ins>+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadFunction)) {
</ins><span class="cx"> set(VirtualRegister(currentInstruction[1].u.operand), get(VirtualRegister(JSStack::Callee)));
</span><span class="cx"> } else {
</span><span class="cx"> FrozenValue* frozen = m_graph.freeze(cachedFunction);
</span><span class="cx"> ASSERT(cachedFunction->inherits(JSFunction::info()));
</span><span class="cx"> Node* actualCallee = get(VirtualRegister(JSStack::Callee));
</span><del>- addToGraph(CheckCell, OpInfo(frozen), actualCallee);
</del><ins>+ addToGraph(CheckFunction, OpInfo(frozen), actualCallee);
</ins><span class="cx"> set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(JSConstant, OpInfo(frozen)));
</span><span class="cx"> }
</span><span class="cx"> NEXT_OPCODE(op_get_callee);
</span><span class="lines">@@ -3168,7 +2893,7 @@
</span><span class="cx"> // already gnarly enough as it is.
</span><span class="cx"> ASSERT(pointerIsFunction(currentInstruction[2].u.specialPointer));
</span><span class="cx"> addToGraph(
</span><del>- CheckCell,
</del><ins>+ CheckFunction,
</ins><span class="cx"> OpInfo(m_graph.freeze(static_cast<JSCell*>(actualPointerFor(
</span><span class="cx"> m_inlineStackTop->m_codeBlock, currentInstruction[2].u.specialPointer)))),
</span><span class="cx"> get(VirtualRegister(currentInstruction[1].u.operand)));
</span><span class="lines">@@ -3592,19 +3317,15 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (verbose)
- dataLog("Marking ", RawPointer(block), " as linked (actually did linking)\n");
- block->didLink();
</del><ins>+#if !ASSERT_DISABLED
+ block->isLinked = true;
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void ByteCodeParser::linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BasicBlock*>& possibleTargets)
</span><span class="cx"> {
</span><span class="cx"> for (size_t i = 0; i < unlinkedBlocks.size(); ++i) {
</span><del>- if (verbose)
- dataLog("Attempting to link ", RawPointer(unlinkedBlocks[i].m_block), "\n");
</del><span class="cx"> if (unlinkedBlocks[i].m_needsNormalLinking) {
</span><del>- if (verbose)
- dataLog(" Does need normal linking.\n");
</del><span class="cx"> linkBlock(unlinkedBlocks[i].m_block, possibleTargets);
</span><span class="cx"> unlinkedBlocks[i].m_needsNormalLinking = false;
</span><span class="cx"> }
</span><span class="lines">@@ -3771,7 +3492,7 @@
</span><span class="cx">
</span><span class="cx"> void ByteCodeParser::parseCodeBlock()
</span><span class="cx"> {
</span><del>- clearCaches();
</del><ins>+ prepareToParseBlock();
</ins><span class="cx">
</span><span class="cx"> CodeBlock* codeBlock = m_inlineStackTop->m_codeBlock;
</span><span class="cx">
</span><span class="lines">@@ -3837,12 +3558,7 @@
</span><span class="cx"> // 2) If the bytecodeBegin is equal to the currentIndex, then we failed to do
</span><span class="cx"> // a peephole coalescing of this block in the if statement above. So, we're
</span><span class="cx"> // generating suboptimal code and leaving more work for the CFG simplifier.
</span><del>- if (!m_inlineStackTop->m_unlinkedBlocks.isEmpty()) {
- unsigned lastBegin =
- m_inlineStackTop->m_unlinkedBlocks.last().m_block->bytecodeBegin;
- ASSERT_UNUSED(
- lastBegin, lastBegin == UINT_MAX || lastBegin < m_currentIndex);
- }
</del><ins>+ ASSERT(m_inlineStackTop->m_unlinkedBlocks.isEmpty() || m_inlineStackTop->m_unlinkedBlocks.last().m_block->bytecodeBegin < m_currentIndex);
</ins><span class="cx"> m_inlineStackTop->m_unlinkedBlocks.append(UnlinkedBlock(block.get()));
</span><span class="cx"> m_inlineStackTop->m_blockLinkingTargets.append(block.get());
</span><span class="cx"> // The first block is definitely an OSR target.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCPSRethreadingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -90,10 +90,8 @@
</span><span class="cx"> node->children.setChild1(Edge());
</span><span class="cx"> break;
</span><span class="cx"> case Phantom:
</span><del>- if (!node->child1()) {
- m_graph.m_allocator.free(node);
</del><ins>+ if (!node->child1())
</ins><span class="cx"> continue;
</span><del>- }
</del><span class="cx"> switch (node->child1()->op()) {
</span><span class="cx"> case Phi:
</span><span class="cx"> case SetArgument:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -144,8 +144,6 @@
</span><span class="cx"> case FiatInt52:
</span><span class="cx"> case MakeRope:
</span><span class="cx"> case ValueToInt32:
</span><del>- case GetExecutable:
- case BottomValue:
</del><span class="cx"> def(PureValue(node));
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="lines">@@ -241,10 +239,14 @@
</span><span class="cx"> def(PureValue(node, node->arithMode()));
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- case CheckCell:
- def(PureValue(CheckCell, AdjacencyList(AdjacencyList::Fixed, node->child1()), node->cellOperand()));
</del><ins>+ case CheckFunction:
+ def(PureValue(CheckFunction, AdjacencyList(AdjacencyList::Fixed, node->child1()), node->function()));
</ins><span class="cx"> return;
</span><span class="cx">
</span><ins>+ case CheckExecutable:
+ def(PureValue(node, node->executable()));
+ return;
+
</ins><span class="cx"> case ConstantStoragePointer:
</span><span class="cx"> def(PureValue(node, node->storagePointer()));
</span><span class="cx"> return;
</span><span class="lines">@@ -261,7 +263,6 @@
</span><span class="cx"> case Switch:
</span><span class="cx"> case Throw:
</span><span class="cx"> case ForceOSRExit:
</span><del>- case CheckBadCell:
</del><span class="cx"> case Return:
</span><span class="cx"> case Unreachable:
</span><span class="cx"> case CheckTierUpInLoop:
</span><span class="lines">@@ -357,8 +358,6 @@
</span><span class="cx"> case ArrayPop:
</span><span class="cx"> case Call:
</span><span class="cx"> case Construct:
</span><del>- case ProfiledCall:
- case ProfiledConstruct:
</del><span class="cx"> case NativeCall:
</span><span class="cx"> case NativeConstruct:
</span><span class="cx"> case ToPrimitive:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCommonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCommon.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCommon.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGCommon.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -63,13 +63,6 @@
</span><span class="cx"> DontRefNode
</span><span class="cx"> };
</span><span class="cx">
</span><del>-enum SwitchKind {
- SwitchImm,
- SwitchChar,
- SwitchString,
- SwitchCell
-};
-
</del><span class="cx"> inline bool verboseCompilationEnabled(CompilationMode mode = DFGMode)
</span><span class="cx"> {
</span><span class="cx"> return Options::verboseCompilation() || Options::dumpGraphAtEachPhase() || (isFTL(mode) && Options::verboseFTLCompilation());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -142,8 +142,8 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case CheckCell: {
- if (m_state.forNode(node->child1()).value() != node->cellOperand()->value())
</del><ins>+ case CheckFunction: {
+ if (m_state.forNode(node->child1()).value() != node->function()->value())
</ins><span class="cx"> break;
</span><span class="cx"> node->convertToPhantom();
</span><span class="cx"> eliminated = true;
</span><span class="lines">@@ -384,19 +384,6 @@
</span><span class="cx"> }
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
- case ProfiledCall:
- case ProfiledConstruct: {
- if (!m_state.forNode(m_graph.varArgChild(node, 0)).m_value)
- break;
-
- // If we were able to prove that the callee is a constant then the normal call
- // inline cache will record this callee. This means that there is no need to do any
- // additional profiling.
- node->setOp(node->op() == ProfiledCall ? Call : Construct);
- eliminated = true;
- break;
- }
</del><span class="cx">
</span><span class="cx"> default:
</span><span class="cx"> break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx"> case PutByIdFlush:
</span><span class="cx"> case PutByIdDirect:
</span><span class="cx"> case CheckStructure:
</span><del>- case GetExecutable:
</del><ins>+ case CheckExecutable:
</ins><span class="cx"> case GetButterfly:
</span><span class="cx"> case CheckArray:
</span><span class="cx"> case GetScope:
</span><span class="lines">@@ -104,7 +104,7 @@
</span><span class="cx"> case PutGlobalVar:
</span><span class="cx"> case VariableWatchpoint:
</span><span class="cx"> case VarInjectionWatchpoint:
</span><del>- case CheckCell:
</del><ins>+ case CheckFunction:
</ins><span class="cx"> case AllocationProfileWatchpoint:
</span><span class="cx"> case RegExpExec:
</span><span class="cx"> case RegExpTest:
</span><span class="lines">@@ -119,8 +119,6 @@
</span><span class="cx"> case Construct:
</span><span class="cx"> case NativeCall:
</span><span class="cx"> case NativeConstruct:
</span><del>- case ProfiledCall:
- case ProfiledConstruct:
</del><span class="cx"> case Breakpoint:
</span><span class="cx"> case ProfileWillCall:
</span><span class="cx"> case ProfileDidCall:
</span><span class="lines">@@ -197,8 +195,6 @@
</span><span class="cx"> case GetDirectPname:
</span><span class="cx"> case FiatInt52:
</span><span class="cx"> case BooleanToNumber:
</span><del>- case CheckBadCell:
- case BottomValue:
</del><span class="cx"> return false;
</span><span class="cx">
</span><span class="cx"> case CreateActivation:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDrivercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -89,9 +89,6 @@
</span><span class="cx"> vm.getCTIStub(virtualConstructThatPreservesRegsThunkGenerator);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (CallEdgeLog::isEnabled())
- vm.ensureCallEdgeLog().processLog();
-
</del><span class="cx"> RefPtr<Plan> plan = adoptRef(
</span><span class="cx"> new Plan(codeBlock, profiledDFGCodeBlock, mode, osrEntryBytecodeIndex, mustHandleValues));
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -736,12 +736,6 @@
</span><span class="cx"> else if (node->child1()->shouldSpeculateString())
</span><span class="cx"> fixEdge<StringUse>(node->child1());
</span><span class="cx"> break;
</span><del>- case SwitchCell:
- if (node->child1()->shouldSpeculateCell())
- fixEdge<CellUse>(node->child1());
- // else it's fine for this to have UntypedUse; we will handle this by just making
- // non-cells take the default case.
- break;
</del><span class="cx"> }
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="lines">@@ -903,13 +897,13 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case GetExecutable: {
</del><ins>+ case CheckExecutable: {
</ins><span class="cx"> fixEdge<FunctionUse>(node->child1());
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case CheckStructure:
</span><del>- case CheckCell:
</del><ins>+ case CheckFunction:
</ins><span class="cx"> case CheckHasInstance:
</span><span class="cx"> case CreateThis:
</span><span class="cx"> case GetButterfly: {
</span><span class="lines">@@ -1126,8 +1120,6 @@
</span><span class="cx"> case AllocationProfileWatchpoint:
</span><span class="cx"> case Call:
</span><span class="cx"> case Construct:
</span><del>- case ProfiledCall:
- case ProfiledConstruct:
</del><span class="cx"> case NativeCall:
</span><span class="cx"> case NativeConstruct:
</span><span class="cx"> case NewObject:
</span><span class="lines">@@ -1157,7 +1149,6 @@
</span><span class="cx"> case ThrowReferenceError:
</span><span class="cx"> case CountExecution:
</span><span class="cx"> case ForceOSRExit:
</span><del>- case CheckBadCell:
</del><span class="cx"> case CheckWatchdogTimer:
</span><span class="cx"> case Unreachable:
</span><span class="cx"> case ExtractOSREntryLocal:
</span><span class="lines">@@ -1168,7 +1159,6 @@
</span><span class="cx"> case TypedArrayWatchpoint:
</span><span class="cx"> case MovHint:
</span><span class="cx"> case ZombieHint:
</span><del>- case BottomValue:
</del><span class="cx"> break;
</span><span class="cx"> #else
</span><span class="cx"> default:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -222,24 +222,25 @@
</span><span class="cx"> out.print(comma, inContext(*node->structure(), context));
</span><span class="cx"> if (node->hasTransition())
</span><span class="cx"> out.print(comma, pointerDumpInContext(node->transition(), context));
</span><del>- if (node->hasCellOperand()) {
- if (!node->cellOperand()->value() || !node->cellOperand()->value().isCell())
- out.print(comma, "invalid cell operand: ", node->cellOperand()->value());
- else {
- out.print(comma, pointerDump(node->cellOperand()->value().asCell()));
- if (node->cellOperand()->value().isCell()) {
- CallVariant variant(node->cellOperand()->value().asCell());
- if (ExecutableBase* executable = variant.executable()) {
- if (executable->isHostFunction())
- out.print(comma, "<host function>");
- else if (FunctionExecutable* functionExecutable = jsDynamicCast<FunctionExecutable*>(executable))
- out.print(comma, FunctionExecutableDump(functionExecutable));
- else
- out.print(comma, "<non-function executable>");
- }
- }
- }
</del><ins>+ if (node->hasFunction()) {
+ out.print(comma, "function(", pointerDump(node->function()), ", ");
+ if (node->function()->value().isCell()
+ && node->function()->value().asCell()->inherits(JSFunction::info())) {
+ JSFunction* function = jsCast<JSFunction*>(node->function()->value().asCell());
+ if (function->isHostFunction())
+ out.print("<host function>");
+ else
+ out.print(FunctionExecutableDump(function->jsExecutable()));
+ } else
+ out.print("<not JSFunction>");
+ out.print(")");
</ins><span class="cx"> }
</span><ins>+ if (node->hasExecutable()) {
+ if (node->executable()->inherits(FunctionExecutable::info()))
+ out.print(comma, "executable(", FunctionExecutableDump(jsCast<FunctionExecutable*>(node->executable())), ")");
+ else
+ out.print(comma, "executable(not function: ", RawPointer(node->executable()), ")");
+ }
</ins><span class="cx"> if (node->hasFunctionDeclIndex()) {
</span><span class="cx"> FunctionExecutable* executable = m_codeBlock->functionDecl(node->functionDeclIndex());
</span><span class="cx"> out.print(comma, FunctionExecutableDump(executable));
</span><span class="lines">@@ -984,6 +985,10 @@
</span><span class="cx"> Node* node = block->at(nodeIndex);
</span><span class="cx">
</span><span class="cx"> switch (node->op()) {
</span><ins>+ case CheckExecutable:
+ visitor.appendUnbarrieredReadOnlyPointer(node->executable());
+ break;
+
</ins><span class="cx"> case CheckStructure:
</span><span class="cx"> for (unsigned i = node->structureSet().size(); i--;)
</span><span class="cx"> visitor.appendUnbarrieredReadOnlyPointer(node->structureSet()[i]);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -188,7 +188,7 @@
</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><del>- table.ctiOffsets[myCase.value.switchLookupValue(data.kind) - table.min] =
</del><ins>+ table.ctiOffsets[myCase.value.switchLookupValue() - table.min] =
</ins><span class="cx"> linkBuffer.locationOf(m_blockHeads[myCase.target.block->index]);
</span><span class="cx"> }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGLazyJSValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -113,36 +113,6 @@
</span><span class="cx"> return FalseTriState;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-uintptr_t LazyJSValue::switchLookupValue(SwitchKind kind) const
-{
- // NB. Not every kind of JSValue will be able to give you a switch lookup
- // value, and this method will assert, or do bad things, if you use it
- // for a kind of value that can't.
- switch (m_kind) {
- case KnownValue:
- switch (kind) {
- case SwitchImm:
- return value()->value().asInt32();
- case SwitchCell:
- return bitwise_cast<uintptr_t>(value()->value().asCell());
- default:
- RELEASE_ASSERT_NOT_REACHED();
- return 0;
- }
- case SingleCharacterString:
- switch (kind) {
- case SwitchChar:
- return character();
- default:
- RELEASE_ASSERT_NOT_REACHED();
- return 0;
- }
- default:
- RELEASE_ASSERT_NOT_REACHED();
- return 0;
- }
-}
-
</del><span class="cx"> void LazyJSValue::dumpInContext(PrintStream& out, DumpContext* context) const
</span><span class="cx"> {
</span><span class="cx"> switch (m_kind) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGLazyJSValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -28,7 +28,6 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">
</span><del>-#include "DFGCommon.h"
</del><span class="cx"> #include "DFGFrozenValue.h"
</span><span class="cx"> #include <wtf/text/StringImpl.h>
</span><span class="cx">
</span><span class="lines">@@ -96,7 +95,21 @@
</span><span class="cx">
</span><span class="cx"> TriState strictEqual(const LazyJSValue& other) const;
</span><span class="cx">
</span><del>- uintptr_t switchLookupValue(SwitchKind) const;
</del><ins>+ unsigned switchLookupValue() const
+ {
+ // NB. Not every kind of JSValue will be able to give you a switch lookup
+ // value, and this method will assert, or do bad things, if you use it
+ // for a kind of value that can't.
+ switch (m_kind) {
+ case KnownValue:
+ return value()->value().asInt32();
+ case SingleCharacterString:
+ return character();
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return 0;
+ }
+ }
</ins><span class="cx">
</span><span class="cx"> void dump(PrintStream&) const;
</span><span class="cx"> void dumpInContext(PrintStream&, DumpContext*) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -113,9 +113,6 @@
</span><span class="cx"> case SwitchString:
</span><span class="cx"> out.print("SwitchString");
</span><span class="cx"> return;
</span><del>- case SwitchCell:
- out.print("SwitchCell");
- return;
</del><span class="cx"> }
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -157,6 +157,12 @@
</span><span class="cx"> BranchTarget target;
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+enum SwitchKind {
+ SwitchImm,
+ SwitchChar,
+ SwitchString
+};
+
</ins><span class="cx"> struct SwitchData {
</span><span class="cx"> // Initializes most fields to obviously invalid values. Anyone
</span><span class="cx"> // constructing this should make sure to initialize everything they
</span><span class="lines">@@ -179,7 +185,6 @@
</span><span class="cx"> // distinguishes an immediate value (typically an index into a CodeBlock data structure -
</span><span class="cx"> // a constant index, argument, or identifier) from a Node*.
</span><span class="cx"> struct OpInfo {
</span><del>- OpInfo() : m_value(0) { }
</del><span class="cx"> explicit OpInfo(int32_t value) : m_value(static_cast<uintptr_t>(value)) { }
</span><span class="cx"> explicit OpInfo(uint32_t value) : m_value(static_cast<uintptr_t>(value)) { }
</span><span class="cx"> #if OS(DARWIN) || USE(JSVALUE64)
</span><span class="lines">@@ -1004,8 +1009,6 @@
</span><span class="cx"> case GetMyArgumentByValSafe:
</span><span class="cx"> case Call:
</span><span class="cx"> case Construct:
</span><del>- case ProfiledCall:
- case ProfiledConstruct:
</del><span class="cx"> case NativeCall:
</span><span class="cx"> case NativeConstruct:
</span><span class="cx"> case GetByOffset:
</span><span class="lines">@@ -1041,11 +1044,9 @@
</span><span class="cx"> m_opInfo2 = prediction;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- bool hasCellOperand()
</del><ins>+ bool canBeKnownFunction()
</ins><span class="cx"> {
</span><span class="cx"> switch (op()) {
</span><del>- case AllocationProfileWatchpoint:
- case CheckCell:
</del><span class="cx"> case NativeConstruct:
</span><span class="cx"> case NativeCall:
</span><span class="cx"> return true;
</span><span class="lines">@@ -1054,18 +1055,56 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- FrozenValue* cellOperand()
</del><ins>+ bool hasKnownFunction()
</ins><span class="cx"> {
</span><del>- ASSERT(hasCellOperand());
</del><ins>+ switch (op()) {
+ case NativeConstruct:
+ case NativeCall:
+ return (bool)m_opInfo;
+ default:
+ return false;
+ }
+ }
+
+ JSFunction* knownFunction()
+ {
+ ASSERT(canBeKnownFunction());
+ return bitwise_cast<JSFunction*>(m_opInfo);
+ }
+
+ void giveKnownFunction(JSFunction* callData)
+ {
+ ASSERT(canBeKnownFunction());
+ m_opInfo = bitwise_cast<uintptr_t>(callData);
+ }
+
+ bool hasFunction()
+ {
+ switch (op()) {
+ case CheckFunction:
+ case AllocationProfileWatchpoint:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ FrozenValue* function()
+ {
+ ASSERT(hasFunction());
</ins><span class="cx"> return reinterpret_cast<FrozenValue*>(m_opInfo);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void setCellOperand(FrozenValue* value)
</del><ins>+ bool hasExecutable()
</ins><span class="cx"> {
</span><del>- ASSERT(hasCellOperand());
- m_opInfo = bitwise_cast<uintptr_t>(value);
</del><ins>+ return op() == CheckExecutable;
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+ ExecutableBase* executable()
+ {
+ return jsCast<ExecutableBase*>(reinterpret_cast<JSCell*>(m_opInfo));
+ }
+
</ins><span class="cx"> bool hasVariableWatchpointSet()
</span><span class="cx"> {
</span><span class="cx"> return op() == NotifyWrite || op() == VariableWatchpoint;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -153,7 +153,7 @@
</span><span class="cx"> macro(PutByIdFlush, NodeMustGenerate | NodeMustGenerate | NodeClobbersWorld) \
</span><span class="cx"> macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \
</span><span class="cx"> macro(CheckStructure, NodeMustGenerate) \
</span><del>- macro(GetExecutable, NodeResultJS) \
</del><ins>+ macro(CheckExecutable, NodeMustGenerate) \
</ins><span class="cx"> macro(PutStructure, NodeMustGenerate) \
</span><span class="cx"> macro(AllocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
</span><span class="cx"> macro(ReallocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
</span><span class="lines">@@ -185,8 +185,7 @@
</span><span class="cx"> macro(VariableWatchpoint, NodeMustGenerate) \
</span><span class="cx"> macro(VarInjectionWatchpoint, NodeMustGenerate) \
</span><span class="cx"> macro(FunctionReentryWatchpoint, NodeMustGenerate) \
</span><del>- macro(CheckCell, NodeMustGenerate) \
- macro(CheckBadCell, NodeMustGenerate) \
</del><ins>+ macro(CheckFunction, NodeMustGenerate) \
</ins><span class="cx"> macro(AllocationProfileWatchpoint, NodeMustGenerate) \
</span><span class="cx"> macro(CheckInBounds, NodeMustGenerate) \
</span><span class="cx"> \
</span><span class="lines">@@ -215,8 +214,6 @@
</span><span class="cx"> /* Calls. */\
</span><span class="cx"> macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
</span><span class="cx"> macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
</span><del>- macro(ProfiledCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
- macro(ProfiledConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
</del><span class="cx"> macro(NativeCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
</span><span class="cx"> macro(NativeConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
</span><span class="cx"> \
</span><span class="lines">@@ -289,11 +286,6 @@
</span><span class="cx"> /* different compiler. */\
</span><span class="cx"> macro(ForceOSRExit, NodeMustGenerate) \
</span><span class="cx"> \
</span><del>- /* Vends a bottom JS value. It is invalid to ever execute this. Useful for cases */\
- /* where we know that we would have exited but we'd like to still track the control */\
- /* flow. */\
- macro(BottomValue, NodeResultJS) \
- \
</del><span class="cx"> /* Checks the watchdog timer. If the timer has fired, we OSR exit to the */ \
</span><span class="cx"> /* baseline JIT to redo the watchdog timer check, and service the timer. */ \
</span><span class="cx"> macro(CheckWatchdogTimer, NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPhantomCanonicalizationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -92,10 +92,8 @@
</span><span class="cx"> node->children.removeEdge(i--);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (node->children.isEmpty()) {
- m_graph.m_allocator.free(node);
</del><ins>+ if (node->children.isEmpty())
</ins><span class="cx"> continue;
</span><del>- }
</del><span class="cx">
</span><span class="cx"> node->convertToCheck();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPhantomRemovalPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -125,7 +125,6 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (node->children.isEmpty()) {
</span><del>- m_graph.m_allocator.free(node);
</del><span class="cx"> changed = true;
</span><span class="cx"> continue;
</span><span class="cx"> }
</span><span class="lines">@@ -143,7 +142,6 @@
</span><span class="cx"> changed = true;
</span><span class="cx"> }
</span><span class="cx"> if (node->children.isEmpty()) {
</span><del>- m_graph.m_allocator.free(node);
</del><span class="cx"> changed = true;
</span><span class="cx"> continue;
</span><span class="cx"> }
</span><span class="lines">@@ -151,10 +149,8 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case HardPhantom: {
</span><del>- if (node->children.isEmpty()) {
- m_graph.m_allocator.free(node);
</del><ins>+ if (node->children.isEmpty())
</ins><span class="cx"> continue;
</span><del>- }
</del><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -188,8 +188,6 @@
</span><span class="cx"> case GetDirectPname:
</span><span class="cx"> case Call:
</span><span class="cx"> case Construct:
</span><del>- case ProfiledCall:
- case ProfiledConstruct:
</del><span class="cx"> case NativeCall:
</span><span class="cx"> case NativeConstruct:
</span><span class="cx"> case GetGlobalVar:
</span><span class="lines">@@ -198,8 +196,7 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case GetGetterSetterByOffset:
- case GetExecutable: {
</del><ins>+ case GetGetterSetterByOffset: {
</ins><span class="cx"> changed |= setPrediction(SpecCellOther);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="lines">@@ -645,8 +642,8 @@
</span><span class="cx"> case ForceOSRExit:
</span><span class="cx"> case SetArgument:
</span><span class="cx"> case CheckStructure:
</span><del>- case CheckCell:
- case CheckBadCell:
</del><ins>+ case CheckExecutable:
+ case CheckFunction:
</ins><span class="cx"> case PutStructure:
</span><span class="cx"> case TearOffActivation:
</span><span class="cx"> case TearOffArguments:
</span><span class="lines">@@ -668,10 +665,6 @@
</span><span class="cx"> case ZombieHint:
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- // This gets ignored because it only pretends to produce a value.
- case BottomValue:
- break;
-
</del><span class="cx"> // This gets ignored because it already has a prediction.
</span><span class="cx"> case ExtractOSREntryLocal:
</span><span class="cx"> break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -159,7 +159,7 @@
</span><span class="cx"> case PutByIdFlush:
</span><span class="cx"> case PutByIdDirect:
</span><span class="cx"> case CheckStructure:
</span><del>- case GetExecutable:
</del><ins>+ case CheckExecutable:
</ins><span class="cx"> case GetButterfly:
</span><span class="cx"> case CheckArray:
</span><span class="cx"> case Arrayify:
</span><span class="lines">@@ -174,8 +174,7 @@
</span><span class="cx"> case PutGlobalVar:
</span><span class="cx"> case VariableWatchpoint:
</span><span class="cx"> case VarInjectionWatchpoint:
</span><del>- case CheckCell:
- case CheckBadCell:
</del><ins>+ case CheckFunction:
</ins><span class="cx"> case AllocationProfileWatchpoint:
</span><span class="cx"> case RegExpExec:
</span><span class="cx"> case RegExpTest:
</span><span class="lines">@@ -188,8 +187,6 @@
</span><span class="cx"> case CompareStrictEq:
</span><span class="cx"> case Call:
</span><span class="cx"> case Construct:
</span><del>- case ProfiledCall:
- case ProfiledConstruct:
</del><span class="cx"> case NewObject:
</span><span class="cx"> case NewArray:
</span><span class="cx"> case NewArrayWithSize:
</span><span class="lines">@@ -276,11 +273,6 @@
</span><span class="cx"> case NativeConstruct:
</span><span class="cx"> return false; // TODO: add a check for already checked. https://bugs.webkit.org/show_bug.cgi?id=133769
</span><span class="cx">
</span><del>- case BottomValue:
- // If in doubt, assume that this isn't safe to execute, just because we have no way of
- // compiling this node.
- return false;
-
</del><span class="cx"> case GetByVal:
</span><span class="cx"> case GetIndexedPropertyStorage:
</span><span class="cx"> case GetArrayLength:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -5354,10 +5354,6 @@
</span><span class="cx"> case SwitchString: {
</span><span class="cx"> emitSwitchString(node, data);
</span><span class="cx"> return;
</span><del>- }
- case SwitchCell: {
- DFG_CRASH(m_jit.graph(), node, "Bad switch kind");
- return;
</del><span class="cx"> } }
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -640,9 +640,9 @@
</span><span class="cx">
</span><span class="cx"> void SpeculativeJIT::emitCall(Node* node)
</span><span class="cx"> {
</span><del>- bool isCall = node->op() == Call || node->op() == ProfiledCall;
</del><ins>+ bool isCall = node->op() == Call;
</ins><span class="cx"> if (!isCall)
</span><del>- ASSERT(node->op() == Construct || node->op() == ProfiledConstruct);
</del><ins>+ ASSERT(node->op() == Construct);
</ins><span class="cx">
</span><span class="cx"> // For constructors, the this argument is not passed but we have to make space
</span><span class="cx"> // for it.
</span><span class="lines">@@ -689,13 +689,6 @@
</span><span class="cx">
</span><span class="cx"> m_jit.emitStoreCodeOrigin(node->origin.semantic);
</span><span class="cx">
</span><del>- CallLinkInfo* info = m_jit.codeBlock()->addCallLinkInfo();
-
- if (node->op() == ProfiledCall || node->op() == ProfiledConstruct) {
- m_jit.vm()->callEdgeLog->emitLogCode(
- m_jit, info->callEdgeProfile, callee.jsValueRegs());
- }
-
</del><span class="cx"> slowPath.append(branchNotCell(callee.jsValueRegs()));
</span><span class="cx"> slowPath.append(m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleePayloadGPR, targetToCheck));
</span><span class="cx"> m_jit.loadPtr(MacroAssembler::Address(calleePayloadGPR, OBJECT_OFFSETOF(JSFunction, m_scope)), resultPayloadGPR);
</span><span class="lines">@@ -720,6 +713,7 @@
</span><span class="cx"> m_jit.move(calleePayloadGPR, GPRInfo::regT0);
</span><span class="cx"> m_jit.move(calleeTagGPR, GPRInfo::regT1);
</span><span class="cx"> }
</span><ins>+ CallLinkInfo* info = m_jit.codeBlock()->addCallLinkInfo();
</ins><span class="cx"> m_jit.move(MacroAssembler::TrustedImmPtr(info), GPRInfo::regT2);
</span><span class="cx"> JITCompiler::Call slowCall = m_jit.nearCall();
</span><span class="cx">
</span><span class="lines">@@ -3681,21 +3675,18 @@
</span><span class="cx"> compileGetArrayLength(node);
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- case CheckCell: {
- SpeculateCellOperand cell(this, node->child1());
- speculationCheck(BadCell, JSValueSource::unboxedCell(cell.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, cell.gpr(), node->cellOperand()->value().asCell()));
</del><ins>+ case CheckFunction: {
+ SpeculateCellOperand function(this, node->child1());
+ speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node->function()->value().asCell()));
</ins><span class="cx"> noResult(node);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case GetExecutable: {
</del><ins>+ case CheckExecutable: {
</ins><span class="cx"> SpeculateCellOperand function(this, node->child1());
</span><del>- GPRTemporary result(this, Reuse, function);
- GPRReg functionGPR = function.gpr();
- GPRReg resultGPR = result.gpr();
- speculateCellType(node->child1(), functionGPR, SpecFunction, JSFunctionType);
- m_jit.loadPtr(JITCompiler::Address(functionGPR, JSFunction::offsetOfExecutable()), resultGPR);
- cellResult(resultGPR, node);
</del><ins>+ speculateCellType(node->child1(), function.gpr(), SpecFunction, JSFunctionType);
+ speculationCheck(BadExecutable, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(function.gpr(), JSFunction::offsetOfExecutable()), node->executable()));
+ noResult(node);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -4165,8 +4156,6 @@
</span><span class="cx">
</span><span class="cx"> case Call:
</span><span class="cx"> case Construct:
</span><del>- case ProfiledCall:
- case ProfiledConstruct:
</del><span class="cx"> emitCall(node);
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="lines">@@ -4913,8 +4902,6 @@
</span><span class="cx"> case MultiPutByOffset:
</span><span class="cx"> case NativeCall:
</span><span class="cx"> case NativeConstruct:
</span><del>- case CheckBadCell:
- case BottomValue:
</del><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</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 (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -626,9 +626,10 @@
</span><span class="cx">
</span><span class="cx"> void SpeculativeJIT::emitCall(Node* node)
</span><span class="cx"> {
</span><del>- bool isCall = node->op() == Call || node->op() == ProfiledCall;
</del><ins>+
+ bool isCall = node->op() == Call;
</ins><span class="cx"> if (!isCall)
</span><del>- DFG_ASSERT(m_jit.graph(), node, node->op() == Construct || node->op() == ProfiledConstruct);
</del><ins>+ DFG_ASSERT(m_jit.graph(), node, node->op() == Construct);
</ins><span class="cx">
</span><span class="cx"> // For constructors, the this argument is not passed but we have to make space
</span><span class="cx"> // for it.
</span><span class="lines">@@ -669,13 +670,6 @@
</span><span class="cx">
</span><span class="cx"> m_jit.emitStoreCodeOrigin(node->origin.semantic);
</span><span class="cx">
</span><del>- CallLinkInfo* callLinkInfo = m_jit.codeBlock()->addCallLinkInfo();
-
- if (node->op() == ProfiledCall || node->op() == ProfiledConstruct) {
- m_jit.vm()->callEdgeLog->emitLogCode(
- m_jit, callLinkInfo->callEdgeProfile, JSValueRegs(calleeGPR));
- }
-
</del><span class="cx"> slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(0));
</span><span class="cx">
</span><span class="cx"> m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scope)), resultGPR);
</span><span class="lines">@@ -688,6 +682,7 @@
</span><span class="cx"> slowPath.link(&m_jit);
</span><span class="cx">
</span><span class="cx"> m_jit.move(calleeGPR, GPRInfo::regT0); // Callee needs to be in regT0
</span><ins>+ CallLinkInfo* callLinkInfo = m_jit.codeBlock()->addCallLinkInfo();
</ins><span class="cx"> m_jit.move(MacroAssembler::TrustedImmPtr(callLinkInfo), GPRInfo::regT2); // Link info needs to be in regT2
</span><span class="cx"> JITCompiler::Call slowCall = m_jit.nearCall();
</span><span class="cx">
</span><span class="lines">@@ -3773,21 +3768,18 @@
</span><span class="cx"> compileGetArrayLength(node);
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- case CheckCell: {
- SpeculateCellOperand cell(this, node->child1());
- speculationCheck(BadCell, JSValueSource::unboxedCell(cell.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, cell.gpr(), node->cellOperand()->value().asCell()));
</del><ins>+ case CheckFunction: {
+ SpeculateCellOperand function(this, node->child1());
+ speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node->function()->value().asCell()));
</ins><span class="cx"> noResult(node);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case GetExecutable: {
</del><ins>+ case CheckExecutable: {
</ins><span class="cx"> SpeculateCellOperand function(this, node->child1());
</span><del>- GPRTemporary result(this, Reuse, function);
- GPRReg functionGPR = function.gpr();
- GPRReg resultGPR = result.gpr();
- speculateCellType(node->child1(), functionGPR, SpecFunction, JSFunctionType);
- m_jit.loadPtr(JITCompiler::Address(functionGPR, JSFunction::offsetOfExecutable()), resultGPR);
- cellResult(resultGPR, node);
</del><ins>+ speculateCellType(node->child1(), function.gpr(), SpecFunction, JSFunctionType);
+ speculationCheck(BadExecutable, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(function.gpr(), JSFunction::offsetOfExecutable()), node->executable()));
+ noResult(node);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -4227,11 +4219,9 @@
</span><span class="cx">
</span><span class="cx"> case Call:
</span><span class="cx"> case Construct:
</span><del>- case ProfiledCall:
- case ProfiledConstruct:
</del><span class="cx"> emitCall(node);
</span><span class="cx"> break;
</span><del>-
</del><ins>+
</ins><span class="cx"> case CreateActivation: {
</span><span class="cx"> DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
</span><span class="cx">
</span><span class="lines">@@ -4980,9 +4970,7 @@
</span><span class="cx"> case MultiGetByOffset:
</span><span class="cx"> case MultiPutByOffset:
</span><span class="cx"> case FiatInt52:
</span><del>- case CheckBadCell:
- case BottomValue:
- DFG_CRASH(m_jit.graph(), node, "Unexpected node");
</del><ins>+ DFG_CRASH(m_jit.graph(), node, "Unexpected FTL node");
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -62,6 +62,10 @@
</span><span class="cx"> Node* node = block->at(nodeIndex);
</span><span class="cx">
</span><span class="cx"> switch (node->op()) {
</span><ins>+ case CheckExecutable:
+ registerStructure(node->executable()->structure());
+ break;
+
</ins><span class="cx"> case CheckStructure:
</span><span class="cx"> registerStructures(node->structureSet());
</span><span class="cx"> break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGTierUpCheckInjectionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGTierUpCheckInjectionPhase.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGTierUpCheckInjectionPhase.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGTierUpCheckInjectionPhase.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -50,17 +50,13 @@
</span><span class="cx"> if (!Options::useFTLJIT())
</span><span class="cx"> return false;
</span><span class="cx">
</span><del>- if (m_graph.m_profiledBlock->m_didFailFTLCompilation) {
- removeFTLProfiling();
</del><ins>+ if (m_graph.m_profiledBlock->m_didFailFTLCompilation)
</ins><span class="cx"> return false;
</span><del>- }
</del><span class="cx">
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> FTL::CapabilityLevel level = FTL::canCompile(m_graph);
</span><del>- if (level == FTL::CannotCompile) {
- removeFTLProfiling();
</del><ins>+ if (level == FTL::CannotCompile)
</ins><span class="cx"> return false;
</span><del>- }
</del><span class="cx">
</span><span class="cx"> if (!Options::enableOSREntryToFTL())
</span><span class="cx"> level = FTL::CanCompile;
</span><span class="lines">@@ -122,32 +118,6 @@
</span><span class="cx"> return false;
</span><span class="cx"> #endif // ENABLE(FTL_JIT)
</span><span class="cx"> }
</span><del>-
-private:
- void removeFTLProfiling()
- {
- for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
- BasicBlock* block = m_graph.block(blockIndex);
- if (!block)
- continue;
-
- for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
- Node* node = block->at(nodeIndex);
- switch (node->op()) {
- case ProfiledCall:
- node->setOp(Call);
- break;
-
- case ProfiledConstruct:
- node->setOp(Construct);
- break;
-
- default:
- break;
- }
- }
- }
- }
</del><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> bool performTierUpCheckInjection(Graph& graph)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGValidatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -200,8 +200,7 @@
</span><span class="cx">
</span><span class="cx"> VALIDATE((node), !mayExit(m_graph, node) || node->origin.forExit.isSet());
</span><span class="cx"> VALIDATE((node), !node->hasStructure() || !!node->structure());
</span><del>- VALIDATE((node), !node->hasCellOperand() || node->cellOperand()->value().isCell());
- VALIDATE((node), !node->hasCellOperand() || !!node->cellOperand()->value());
</del><ins>+ VALIDATE((node), !node->hasFunction() || node->function()->value().isFunction());
</ins><span class="cx">
</span><span class="cx"> if (!(node->flags() & NodeHasVarArgs)) {
</span><span class="cx"> if (!node->child2())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013 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">@@ -114,7 +114,7 @@
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case AllocationProfileWatchpoint:
</span><del>- addLazily(jsCast<JSFunction*>(m_node->cellOperand()->value())->allocationProfileWatchpointSet());
</del><ins>+ addLazily(jsCast<JSFunction*>(m_node->function()->value())->allocationProfileWatchpointSet());
</ins><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case VariableWatchpoint:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -104,8 +104,7 @@
</span><span class="cx"> case PutClosureVar:
</span><span class="cx"> case InvalidationPoint:
</span><span class="cx"> case StringCharAt:
</span><del>- case CheckCell:
- case CheckBadCell:
</del><ins>+ case CheckFunction:
</ins><span class="cx"> case StringCharCodeAt:
</span><span class="cx"> case AllocatePropertyStorage:
</span><span class="cx"> case ReallocatePropertyStorage:
</span><span class="lines">@@ -127,7 +126,7 @@
</span><span class="cx"> case ConstantStoragePointer:
</span><span class="cx"> case Check:
</span><span class="cx"> case CountExecution:
</span><del>- case GetExecutable:
</del><ins>+ case CheckExecutable:
</ins><span class="cx"> case GetScope:
</span><span class="cx"> case AllocationProfileWatchpoint:
</span><span class="cx"> case CheckArgumentsNotCreated:
</span><span class="lines">@@ -167,14 +166,8 @@
</span><span class="cx"> case GetGenericPropertyEnumerator:
</span><span class="cx"> case GetEnumeratorPname:
</span><span class="cx"> case ToIndexString:
</span><del>- case BottomValue:
</del><span class="cx"> // These are OK.
</span><span class="cx"> break;
</span><del>- case ProfiledCall:
- case ProfiledConstruct:
- // These are OK not because the FTL can support them, but because if the DFG sees one of
- // these then the FTL will see a normal Call/Construct.
- break;
</del><span class="cx"> case Identity:
</span><span class="cx"> // No backend handles this because it will be optimized out. But we may check
</span><span class="cx"> // for capabilities before optimization. It would be a deep error to remove this
</span><span class="lines">@@ -333,7 +326,6 @@
</span><span class="cx"> switch (node->switchData()->kind) {
</span><span class="cx"> case SwitchImm:
</span><span class="cx"> case SwitchChar:
</span><del>- case SwitchCell:
</del><span class="cx"> break;
</span><span class="cx"> default:
</span><span class="cx"> return CannotCompile;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -67,6 +67,7 @@
</span><span class="cx"> NO_RETURN_DUE_TO_CRASH static void ftlUnreachable(
</span><span class="cx"> CodeBlock* codeBlock, BlockIndex blockIndex, unsigned nodeIndex)
</span><span class="cx"> {
</span><ins>+
</ins><span class="cx"> dataLog("Crashing in thought-to-be-unreachable FTL-generated code for ", pointerDump(codeBlock), " at basic block #", blockIndex);
</span><span class="cx"> if (nodeIndex != UINT_MAX)
</span><span class="cx"> dataLog(", node @", nodeIndex);
</span><span class="lines">@@ -152,18 +153,12 @@
</span><span class="cx"> for (unsigned blockIndex = depthFirst.size(); blockIndex--; ) {
</span><span class="cx"> BasicBlock* block = depthFirst[blockIndex];
</span><span class="cx"> for (unsigned nodeIndex = block->size(); nodeIndex--; ) {
</span><del>- Node* node = block->at(nodeIndex);
- switch (node->op()) {
- case NativeCall:
- case NativeConstruct: {
</del><ins>+ Node* m_node = block->at(nodeIndex);
+ if (m_node->hasKnownFunction()) {
</ins><span class="cx"> int numArgs = m_node->numChildren();
</span><span class="cx"> if (numArgs > maxNumberOfArguments)
</span><span class="cx"> maxNumberOfArguments = numArgs;
</span><del>- break;
</del><span class="cx"> }
</span><del>- default:
- break;
- }
</del><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -473,15 +468,12 @@
</span><span class="cx"> case CheckStructure:
</span><span class="cx"> compileCheckStructure();
</span><span class="cx"> break;
</span><del>- case CheckCell:
- compileCheckCell();
</del><ins>+ case CheckFunction:
+ compileCheckFunction();
</ins><span class="cx"> break;
</span><del>- case CheckBadCell:
- compileCheckBadCell();
</del><ins>+ case CheckExecutable:
+ compileCheckExecutable();
</ins><span class="cx"> break;
</span><del>- case GetExecutable:
- compileGetExecutable();
- break;
</del><span class="cx"> case ArrayifyToStructure:
</span><span class="cx"> compileArrayifyToStructure();
</span><span class="cx"> break;
</span><span class="lines">@@ -1751,25 +1743,26 @@
</span><span class="cx"> m_out.appendTo(continuation, lastNext);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void compileCheckCell()
</del><ins>+ void compileCheckFunction()
</ins><span class="cx"> {
</span><span class="cx"> LValue cell = lowCell(m_node->child1());
</span><span class="cx">
</span><span class="cx"> speculate(
</span><del>- BadCell, jsValueValue(cell), m_node->child1().node(),
- m_out.notEqual(cell, weakPointer(m_node->cellOperand()->value().asCell())));
</del><ins>+ BadFunction, jsValueValue(cell), m_node->child1().node(),
+ m_out.notEqual(cell, weakPointer(m_node->function()->value().asCell())));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- void compileCheckBadCell()
</del><ins>+ void compileCheckExecutable()
</ins><span class="cx"> {
</span><del>- terminate(BadCell);
- }
-
- void compileGetExecutable()
- {
</del><span class="cx"> LValue cell = lowCell(m_node->child1());
</span><ins>+
</ins><span class="cx"> speculateFunction(m_node->child1(), cell);
</span><del>- setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
</del><ins>+
+ speculate(
+ BadExecutable, jsValueValue(cell), m_node->child1().node(),
+ m_out.notEqual(
+ m_out.loadPtr(cell, m_heaps.JSFunction_executable),
+ weakPointer(m_node->executable())));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void compileArrayifyToStructure()
</span><span class="lines">@@ -3680,7 +3673,9 @@
</span><span class="cx"> int numPassedArgs = m_node->numChildren() - 1;
</span><span class="cx"> int numArgs = numPassedArgs + dummyThisArgument;
</span><span class="cx">
</span><del>- JSFunction* knownFunction = jsCast<JSFunction*>(m_node->cellOperand()->value().asCell());
</del><ins>+ ASSERT(m_node->hasKnownFunction());
+
+ JSFunction* knownFunction = m_node->knownFunction();
</ins><span class="cx"> NativeFunction function = knownFunction->nativeFunction();
</span><span class="cx">
</span><span class="cx"> Dl_info info;
</span><span class="lines">@@ -3923,37 +3918,10 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case SwitchString: {
</del><ins>+ case SwitchString:
</ins><span class="cx"> DFG_CRASH(m_graph, m_node, "Unimplemented");
</span><del>- return;
</del><ins>+ break;
</ins><span class="cx"> }
</span><del>-
- case SwitchCell: {
- LValue cell;
- switch (m_node->child1().useKind()) {
- case CellUse: {
- cell = lowCell(m_node->child1());
- break;
- }
-
- case UntypedUse: {
- LValue value = lowJSValue(m_node->child1());
- LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("Switch/SwitchCell cell case"));
- m_out.branch(
- isCell(value), unsure(cellCase), unsure(lowBlock(data->fallThrough.block)));
- m_out.appendTo(cellCase);
- cell = value;
- break;
- }
-
- default:
- DFG_CRASH(m_graph, m_node, "Bad use kind");
- return;
- }
-
- buildSwitch(m_node->switchData(), m_out.intPtr, cell);
- return;
- } }
</del><span class="cx">
</span><span class="cx"> DFG_CRASH(m_graph, m_node, "Bad switch kind");
</span><span class="cx"> }
</span><span class="lines">@@ -5218,7 +5186,7 @@
</span><span class="cx"> Vector<SwitchCase> cases;
</span><span class="cx"> for (unsigned i = 0; i < data->cases.size(); ++i) {
</span><span class="cx"> cases.append(SwitchCase(
</span><del>- constInt(type, data->cases[i].value.switchLookupValue(data->kind)),
</del><ins>+ constInt(type, data->cases[i].value.switchLookupValue()),
</ins><span class="cx"> lowBlock(data->cases[i].target.block), Weight(data->cases[i].target.count)));
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -984,11 +984,6 @@
</span><span class="cx"> vm()->typeProfilerLog()->processLogEntries(ASCIILiteral("GC"));
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (vm()->callEdgeLog) {
- DeferGCForAWhile awhile(*this);
- vm()->callEdgeLog->processLog();
- }
-
</del><span class="cx"> RELEASE_ASSERT(!m_deferralDepth);
</span><span class="cx"> ASSERT(vm()->currentThreadIsHoldingAPILock());
</span><span class="cx"> RELEASE_ASSERT(vm()->atomicStringTable() == wtfThreadData().atomicStringTable());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -88,31 +88,6 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void storeValue(JSValueRegs regs, void* address)
- {
-#if USE(JSVALUE64)
- store64(regs.gpr(), address);
-#else
- store32(regs.payloadGPR(), bitwise_cast<void*>(bitwise_cast<uintptr_t>(address) + PayloadOffset));
- store32(regs.tagGPR(), bitwise_cast<void*>(bitwise_cast<uintptr_t>(address) + TagOffset));
-#endif
- }
-
- void loadValue(Address address, JSValueRegs regs)
- {
-#if USE(JSVALUE64)
- load64(address, regs.gpr());
-#else
- if (address.base == regs.payloadGPR()) {
- load32(address.withOffset(TagOffset), regs.tagGPR());
- load32(address.withOffset(PayloadOffset), regs.payloadGPR());
- } else {
- load32(address.withOffset(PayloadOffset), regs.payloadGPR());
- load32(address.withOffset(TagOffset), regs.tagGPR());
- }
-#endif
- }
-
</del><span class="cx"> void moveTrustedValue(JSValue value, JSValueRegs regs)
</span><span class="cx"> {
</span><span class="cx"> #if USE(JSVALUE64)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitCCallHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/CCallHelpers.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/CCallHelpers.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/jit/CCallHelpers.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1666,15 +1666,6 @@
</span><span class="cx"> move(arg4, GPRInfo::argumentGPR3);
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><del>-
- void setupArguments(JSValueRegs arg1)
- {
-#if USE(JSVALUE64)
- setupArguments(arg1.gpr());
-#else
- setupArguments(arg1.payloadGPR(), arg1.tagGPR());
-#endif
- }
</del><span class="cx">
</span><span class="cx"> void setupResults(GPRReg destA, GPRReg destB)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitGPRInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/GPRInfo.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/GPRInfo.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/jit/GPRInfo.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -60,8 +60,6 @@
</span><span class="cx"> GPRReg tagGPR() const { return InvalidGPRReg; }
</span><span class="cx"> GPRReg payloadGPR() const { return m_gpr; }
</span><span class="cx">
</span><del>- bool uses(GPRReg gpr) const { return m_gpr == gpr; }
-
</del><span class="cx"> private:
</span><span class="cx"> GPRReg m_gpr;
</span><span class="cx"> };
</span><span class="lines">@@ -171,8 +169,6 @@
</span><span class="cx"> return tagGPR();
</span><span class="cx"> }
</span><span class="cx">
</span><del>- bool uses(GPRReg gpr) const { return m_tagGPR == gpr || m_payloadGPR == gpr; }
-
</del><span class="cx"> private:
</span><span class="cx"> int8_t m_tagGPR;
</span><span class="cx"> int8_t m_payloadGPR;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITCallcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITCall.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITCall.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/jit/JITCall.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -212,13 +212,7 @@
</span><span class="cx"> emitGetVirtualRegister(callee, regT0); // regT0 holds callee.
</span><span class="cx">
</span><span class="cx"> store64(regT0, Address(stackPointerRegister, JSStack::Callee * static_cast<int>(sizeof(Register)) - sizeof(CallerFrameAndPC)));
</span><del>-
- CallLinkInfo* info = m_codeBlock->addCallLinkInfo();
</del><span class="cx">
</span><del>- if (CallEdgeLog::isEnabled() && shouldEmitProfiling()
- && Options::baselineDoesCallEdgeProfiling())
- m_vm->ensureCallEdgeLog().emitLogCode(*this, info->callEdgeProfile, JSValueRegs(regT0));
-
</del><span class="cx"> if (opcodeID == op_call_eval) {
</span><span class="cx"> compileCallEval(instruction);
</span><span class="cx"> return;
</span><span class="lines">@@ -229,6 +223,7 @@
</span><span class="cx"> addSlowCase(slowCase);
</span><span class="cx">
</span><span class="cx"> ASSERT(m_callCompilationInfo.size() == callLinkInfoIndex);
</span><ins>+ CallLinkInfo* info = m_codeBlock->addCallLinkInfo();
</ins><span class="cx"> info->callType = CallLinkInfo::callTypeFor(opcodeID);
</span><span class="cx"> info->codeOrigin = CodeOrigin(m_bytecodeOffset);
</span><span class="cx"> info->calleeGPR = regT0;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITCall32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -300,14 +300,6 @@
</span><span class="cx"> store32(regT0, Address(stackPointerRegister, JSStack::Callee * static_cast<int>(sizeof(Register)) + PayloadOffset - sizeof(CallerFrameAndPC)));
</span><span class="cx"> store32(regT1, Address(stackPointerRegister, JSStack::Callee * static_cast<int>(sizeof(Register)) + TagOffset - sizeof(CallerFrameAndPC)));
</span><span class="cx">
</span><del>- CallLinkInfo* info = m_codeBlock->addCallLinkInfo();
-
- if (CallEdgeLog::isEnabled() && shouldEmitProfiling()
- && Options::baselineDoesCallEdgeProfiling()) {
- m_vm->ensureCallEdgeLog().emitLogCode(
- *this, info->callEdgeProfile, JSValueRegs(regT1, regT0));
- }
-
</del><span class="cx"> if (opcodeID == op_call_eval) {
</span><span class="cx"> compileCallEval(instruction);
</span><span class="cx"> return;
</span><span class="lines">@@ -321,6 +313,7 @@
</span><span class="cx"> addSlowCase(slowCase);
</span><span class="cx">
</span><span class="cx"> ASSERT(m_callCompilationInfo.size() == callLinkInfoIndex);
</span><ins>+ CallLinkInfo* info = m_codeBlock->addCallLinkInfo();
</ins><span class="cx"> info->callType = CallLinkInfo::callTypeFor(opcodeID);
</span><span class="cx"> info->codeOrigin = CodeOrigin(m_bytecodeOffset);
</span><span class="cx"> info->calleeGPR = regT0;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -167,13 +167,6 @@
</span><span class="cx"> v(bool, enableAccessInlining, true) \
</span><span class="cx"> v(bool, enablePolyvariantDevirtualization, true) \
</span><span class="cx"> v(bool, enablePolymorphicAccessInlining, true) \
</span><del>- v(bool, enablePolymorphicCallInlining, true) \
- v(bool, callStatusShouldUseCallEdgeProfile, true) \
- v(bool, callEdgeProfileReallyProcessesLog, true) \
- v(bool, baselineDoesCallEdgeProfiling, false) \
- v(bool, dfgDoesCallEdgeProfiling, true) \
- v(bool, enableCallEdgeProfiling, true) \
- v(unsigned, frequentCallThreshold, 2) \
</del><span class="cx"> v(bool, optimizeNativeCalls, false) \
</span><span class="cx"> \
</span><span class="cx"> v(bool, enableConcurrentJIT, true) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -373,13 +373,6 @@
</span><span class="cx"> return sharedInstance;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-CallEdgeLog& VM::ensureCallEdgeLog()
-{
- if (!callEdgeLog)
- callEdgeLog = std::make_unique<CallEdgeLog>();
- return *callEdgeLog;
-}
-
</del><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> static ThunkGenerator thunkGeneratorForIntrinsic(Intrinsic intrinsic)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -72,7 +72,6 @@
</span><span class="cx">
</span><span class="cx"> class ArityCheckFailReturnThunks;
</span><span class="cx"> class BuiltinExecutables;
</span><del>- class CallEdgeLog;
</del><span class="cx"> class CodeBlock;
</span><span class="cx"> class CodeCache;
</span><span class="cx"> class CommonIdentifiers;
</span><span class="lines">@@ -234,9 +233,6 @@
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> OwnPtr<DFG::LongLivedState> dfgState;
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span><del>-
- std::unique_ptr<CallEdgeLog> callEdgeLog;
- CallEdgeLog& ensureCallEdgeLog();
</del><span class="cx">
</span><span class="cx"> VMType vmType;
</span><span class="cx"> ClientData* clientData;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressnewarraythenexitjs"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/tests/stress/new-array-then-exit.js (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/new-array-then-exit.js        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/tests/stress/new-array-then-exit.js        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,14 +0,0 @@
</span><del>-function foo(f) {
- return new f();
-}
-
-noInline(foo);
-
-for (var i = 0; i < 10000; ++i)
- foo(Array);
-
-var didCall = false;
-foo(function() { didCall = true; });
-
-if (!didCall)
- throw "Error: didn't call my function.";
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresspolycallexitthisjs"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/tests/stress/poly-call-exit-this.js (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/poly-call-exit-this.js        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/tests/stress/poly-call-exit-this.js        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,29 +0,0 @@
</span><del>-(function() {
- function foo(x) { return 1 + this.f; }
- function bar(x) { return x + this.f; }
- function baz(x) { return x + 1 + this.f; }
-
- var n = 1000000;
-
- var result = (function(o) {
- var f = {fun:foo, f:1};
- var g = {fun:bar, f:2};
- var h = {fun:baz, f:3};
-
- var result = 0;
- for (var i = 0; i < n; ++i) {
- if (i == n - 1)
- f = h;
- result += f.fun(o.f);
-
- var tmp = f;
- f = g;
- g = tmp;
- }
-
- return result;
- })({f:42});
-
- if (result != ((n / 2 - 1) * (42 + 2)) + (n / 2 * (1 + 1) + (42 + 1 + 3)))
- throw "Error: bad result: " + result;
-})();
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresspolycallexitjs"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/tests/stress/poly-call-exit.js (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/poly-call-exit.js        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/JavaScriptCore/tests/stress/poly-call-exit.js        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,29 +0,0 @@
</span><del>-(function() {
- function foo(x) { return 1; }
- function bar(x) { return x; }
- function baz(x) { return x + 1; }
-
- var n = 1000000;
-
- var result = (function(o) {
- var f = foo;
- var g = bar;
- var h = baz;
-
- var result = 0;
- for (var i = 0; i < n; ++i) {
- if (i == n - 1)
- f = h;
- result += f(o.f);
-
- var tmp = f;
- f = g;
- g = tmp;
- }
-
- return result;
- })({f:42});
-
- if (result != ((n / 2 - 1) * 42) + (n / 2 * 1) + (42 + 1))
- throw "Error: bad result: " + result;
-})();
</del></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/WTF/ChangeLog        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2014-08-26 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r172940.
+ https://bugs.webkit.org/show_bug.cgi?id=136256
+
+ Caused assertions on fast/storage/serialized-script-
+ value.html, and possibly flakiness on more tests (Requested by
+ ap on #webkit).
+
+ Reverted changeset:
+
+ "FTL should be able to do polymorphic call inlining"
+ https://bugs.webkit.org/show_bug.cgi?id=135145
+ http://trac.webkit.org/changeset/172940
+
</ins><span class="cx"> 2014-08-23 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> FTL should be able to do polymorphic call inlining
</span></span></pre></div>
<a id="trunkSourceWTFwtfOwnPtrh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/OwnPtr.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/OwnPtr.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/WTF/wtf/OwnPtr.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * This library is free software; you can redistribute it and/or
</span><span class="cx"> * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -22,7 +22,6 @@
</span><span class="cx"> #define WTF_OwnPtr_h
</span><span class="cx">
</span><span class="cx"> #include <wtf/Assertions.h>
</span><del>-#include <wtf/Atomics.h>
</del><span class="cx"> #include <wtf/Noncopyable.h>
</span><span class="cx"> #include <wtf/OwnPtrCommon.h>
</span><span class="cx"> #include <algorithm>
</span><span class="lines">@@ -73,17 +72,6 @@
</span><span class="cx"> template<typename U> OwnPtr& operator=(OwnPtr<U>&&);
</span><span class="cx">
</span><span class="cx"> void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
</span><del>-
- // Construct an object to store into this OwnPtr, but only so long as this OwnPtr
- // doesn't already point to an object. This will ensure that after you call this,
- // the OwnPtr will point to an instance of T, even if called concurrently. This
- // instance may or may not have been created by this call. Moreover, this call uses
- // an opportunistic transaction, in that we may create an instance of T and then
- // immediately throw it away, if in the process of creating that instance some
- // other thread was doing the same thing and stored its instance into this pointer
- // before we had a chance to do so.
- template<typename... Args>
- void createTransactionally(Args...);
</del><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> explicit OwnPtr(PtrType ptr) : m_ptr(ptr) { }
</span><span class="lines">@@ -198,28 +186,6 @@
</span><span class="cx"> return p.get();
</span><span class="cx"> }
</span><span class="cx">
</span><del>- template<typename T> template<typename... Args> inline void OwnPtr<T>::createTransactionally(Args... args)
- {
- if (m_ptr) {
- WTF::loadLoadFence();
- return;
- }
-
- T* newObject = new T(args...);
- WTF::storeStoreFence();
-#if ENABLE(COMPARE_AND_SWAP)
- do {
- if (m_ptr) {
- delete newObject;
- WTF::loadLoadFence();
- return;
- }
- } while (!WTF::weakCompareAndSwap(bitwise_cast<void*volatile*>(&m_ptr), nullptr, newObject));
-#else
- m_ptr = newObject;
-#endif
- }
-
</del><span class="cx"> } // namespace WTF
</span><span class="cx">
</span><span class="cx"> using WTF::OwnPtr;
</span></span></pre></div>
<a id="trunkSourceWTFwtfSpectrumh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Spectrum.h (172960 => 172961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Spectrum.h        2014-08-26 16:30:23 UTC (rev 172960)
+++ trunk/Source/WTF/wtf/Spectrum.h        2014-08-26 16:46:10 UTC (rev 172961)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011 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">@@ -32,40 +32,29 @@
</span><span class="cx">
</span><span class="cx"> namespace WTF {
</span><span class="cx">
</span><del>-template<typename T, typename CounterType = unsigned>
</del><ins>+template<typename T>
</ins><span class="cx"> class Spectrum {
</span><span class="cx"> public:
</span><del>- typedef typename HashMap<T, CounterType>::iterator iterator;
- typedef typename HashMap<T, CounterType>::const_iterator const_iterator;
</del><ins>+ typedef typename HashMap<T, unsigned long>::iterator iterator;
+ typedef typename HashMap<T, unsigned long>::const_iterator const_iterator;
</ins><span class="cx">
</span><span class="cx"> Spectrum() { }
</span><span class="cx">
</span><del>- void add(const T& key, CounterType count = 1)
</del><ins>+ void add(const T& key, unsigned long count = 1)
</ins><span class="cx"> {
</span><del>- if (!count)
- return;
- typename HashMap<T, CounterType>::AddResult result = m_map.add(key, count);
</del><ins>+ typename HashMap<T, unsigned long>::AddResult result = m_map.add(key, count);
</ins><span class="cx"> if (!result.isNewEntry)
</span><span class="cx"> result.iterator->value += count;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- template<typename U>
- void addAll(const Spectrum<T, U>& otherSpectrum)
</del><ins>+ unsigned long get(const T& key) const
</ins><span class="cx"> {
</span><del>- for (auto& entry : otherSpectrum)
- add(entry.key, entry.count);
- }
-
- CounterType get(const T& key) const
- {
</del><span class="cx"> const_iterator iter = m_map.find(key);
</span><span class="cx"> if (iter == m_map.end())
</span><span class="cx"> return 0;
</span><span class="cx"> return iter->value;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- size_t size() const { return m_map.size(); }
-
</del><span class="cx"> iterator begin() { return m_map.begin(); }
</span><span class="cx"> iterator end() { return m_map.end(); }
</span><span class="cx"> const_iterator begin() const { return m_map.begin(); }
</span><span class="lines">@@ -74,7 +63,7 @@
</span><span class="cx"> struct KeyAndCount {
</span><span class="cx"> KeyAndCount() { }
</span><span class="cx">
</span><del>- KeyAndCount(const T& key, CounterType count)
</del><ins>+ KeyAndCount(const T& key, unsigned long count)
</ins><span class="cx"> : key(key)
</span><span class="cx"> , count(count)
</span><span class="cx"> {
</span><span class="lines">@@ -91,7 +80,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> T key;
</span><del>- CounterType count;
</del><ins>+ unsigned long count;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> // Returns a list ordered from lowest-count to highest-count.
</span><span class="lines">@@ -105,18 +94,8 @@
</span><span class="cx"> return list;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void clear() { m_map.clear(); }
-
- template<typename Functor>
- void removeIf(const Functor& functor)
- {
- m_map.removeIf([functor] (typename HashMap<T, CounterType>::KeyValuePairType& pair) {
- return functor(KeyAndCount(pair.key, pair.value));
- });
- }
-
</del><span class="cx"> private:
</span><del>- HashMap<T, CounterType> m_map;
</del><ins>+ HashMap<T, unsigned long> m_map;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WTF
</span></span></pre>
</div>
</div>
</body>
</html>