<!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>[161409] branches/jsCStack</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/161409">161409</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-01-06 23:19:46 -0800 (Mon, 06 Jan 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Source/JavaScriptCore: Merge trunk <a href="http://trac.webkit.org/projects/webkit/changeset/161072">r161072</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/161126">r161126</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/161218">r161218</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/161353">r161353</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/161356">r161356</a>, <a href="http://trac.webkit.org/projects/webkit/changeset/161364">r161364</a>, 161399.
Source/WTF: Merge trunk <a href="http://trac.webkit.org/projects/webkit/changeset/161364">r161364</a>.
LayoutTests: Merge trunk <a href="http://trac.webkit.org/projects/webkit/changeset/161072">r161072</a>.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsCStackLayoutTestsChangeLog">branches/jsCStack/LayoutTests/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreCMakeListstxt">branches/jsCStack/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreChangeLog">branches/jsCStack/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreGNUmakefilelistam">branches/jsCStack/Source/JavaScriptCore/GNUmakefile.list.am</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorebytecodeCallLinkStatuscpp">branches/jsCStack/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorebytecodeCodeBlockcpp">branches/jsCStack/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorebytecodeCodeBlockh">branches/jsCStack/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorebytecodeGetByIdStatuscpp">branches/jsCStack/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorebytecodeLazyOperandValueProfilecpp">branches/jsCStack/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorebytecodeLazyOperandValueProfileh">branches/jsCStack/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorebytecodePutByIdStatuscpp">branches/jsCStack/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorebytecodeValueProfileh">branches/jsCStack/Source/JavaScriptCore/bytecode/ValueProfile.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">branches/jsCStack/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredebuggerDebuggerh">branches/jsCStack/Source/JavaScriptCore/debugger/Debugger.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGArgumentsSimplificationPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGArrayifySlowPathGeneratorh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGBackwardsPropagationPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGByteCodeParsercpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGCSEPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGClobberizeh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGCommonh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGCommon.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGDCEPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGFixupPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGFlushFormatcpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGFlushFormath">branches/jsCStack/Source/JavaScriptCore/dfg/DFGFlushFormat.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGGraphcpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGGraphh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGLICMPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGMinifiedNodecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGMinifiedNodeh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGMinifiedNode.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGNodecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGNode.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGNodeh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGNodeFlagscpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGNodeFlagsh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeFlags.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGNodeTypeh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGOSREntrypointCreationPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGOSRExitcpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExit.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGOSRExith">branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExit.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGOSRExitBasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExitBase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGOSRExitBaseh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExitBase.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGSSAConversionPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGSafeToExecuteh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGSpeculativeJITcpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGSpeculativeJITh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGTypeCheckHoistingPhasecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGValidatecpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGValidate.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGValueSourceh">branches/jsCStack/Source/JavaScriptCore/dfg/DFGValueSource.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGVariableAccessDatah">branches/jsCStack/Source/JavaScriptCore/dfg/DFGVariableAccessData.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredfgDFGVariableEventStreamcpp">branches/jsCStack/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLCapabilitiescpp">branches/jsCStack/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">branches/jsCStack/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLOSRExitcpp">branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExit.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLOSRExith">branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExit.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitGPRInfoh">branches/jsCStack/Source/JavaScriptCore/jit/GPRInfo.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITcpp">branches/jsCStack/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITh">branches/jsCStack/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITArithmeticcpp">branches/jsCStack/Source/JavaScriptCore/jit/JITArithmetic.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITArithmetic32_64cpp">branches/jsCStack/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITCallcpp">branches/jsCStack/Source/JavaScriptCore/jit/JITCall.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITCall32_64cpp">branches/jsCStack/Source/JavaScriptCore/jit/JITCall32_64.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITInlinesh">branches/jsCStack/Source/JavaScriptCore/jit/JITInlines.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITOpcodescpp">branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITOpcodes32_64cpp">branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITPropertyAccesscpp">branches/jsCStack/Source/JavaScriptCore/jit/JITPropertyAccess.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITPropertyAccess32_64cpp">branches/jsCStack/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntCommonh">branches/jsCStack/Source/JavaScriptCore/llint/LLIntCommon.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntOfflineAsmConfigh">branches/jsCStack/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp">branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreterasm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter32_64asm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter64asm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreprofilerProfilerBytecodeSequencecpp">branches/jsCStack/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreruntimeCommonSlowPathscpp">branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#branchesjsCStackSourceWTFChangeLog">branches/jsCStack/Source/WTF/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceWTFwtfPlatformh">branches/jsCStack/Source/WTF/wtf/Platform.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#branchesjsCStackLayoutTestsjsregressinlineargumentsaliasedaccessexpectedtxt">branches/jsCStack/LayoutTests/js/regress/inline-arguments-aliased-access-expected.txt</a></li>
<li><a href="#branchesjsCStackLayoutTestsjsregressinlineargumentsaliasedaccesshtml">branches/jsCStack/LayoutTests/js/regress/inline-arguments-aliased-access.html</a></li>
<li><a href="#branchesjsCStackLayoutTestsjsregressscripttestsinlineargumentsaliasedaccessjs">branches/jsCStack/LayoutTests/js/regress/script-tests/inline-arguments-aliased-access.js</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoretestsstressdeadint32todoublejs">branches/jsCStack/Source/JavaScriptCore/tests/stress/dead-int32-to-double.js</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoretestsstressdeaduint32tonumberjs">branches/jsCStack/Source/JavaScriptCore/tests/stress/dead-uint32-to-number.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsCStackLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/LayoutTests/ChangeLog (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/LayoutTests/ChangeLog        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/LayoutTests/ChangeLog        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -1,5 +1,9 @@
</span><span class="cx"> 2014-01-06 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><ins>+ Merge trunk r161072.
+
+2014-01-06 Filip Pizlo <fpizlo@apple.com>
+
</ins><span class="cx"> Merge trunk r160242, r160246, r160252, r160257.
</span><span class="cx">
</span><span class="cx"> 2013-12-06 Michał Pakuła vel Rutka <m.pakula@samsung.com>
</span></span></pre></div>
<a id="branchesjsCStackLayoutTestsjsregressinlineargumentsaliasedaccessexpectedtxt"></a>
<div class="addfile"><h4>Added: branches/jsCStack/LayoutTests/js/regress/inline-arguments-aliased-access-expected.txt (0 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/LayoutTests/js/regress/inline-arguments-aliased-access-expected.txt         (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/inline-arguments-aliased-access-expected.txt        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/inline-arguments-aliased-access
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="branchesjsCStackLayoutTestsjsregressinlineargumentsaliasedaccesshtml"></a>
<div class="addfile"><h4>Added: branches/jsCStack/LayoutTests/js/regress/inline-arguments-aliased-access.html (0 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/LayoutTests/js/regress/inline-arguments-aliased-access.html         (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/inline-arguments-aliased-access.html        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+<!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/inline-arguments-aliased-access.js"></script>
+<script src="resources/regress-post.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="branchesjsCStackLayoutTestsjsregressscripttestsinlineargumentsaliasedaccessjs"></a>
<div class="addfile"><h4>Added: branches/jsCStack/LayoutTests/js/regress/script-tests/inline-arguments-aliased-access.js (0 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/LayoutTests/js/regress/script-tests/inline-arguments-aliased-access.js         (rev 0)
+++ branches/jsCStack/LayoutTests/js/regress/script-tests/inline-arguments-aliased-access.js        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+function foo() {
+ var a = arguments;
+ return a[0] + a[1] + a[2];
+}
+
+function bar(a, b, c) {
+ return foo(b, c, 42);
+}
+
+for (var i = 0; i < 200000; ++i) {
+ var result = bar(1, 2, 3);
+ if (result != 47)
+ throw "Bad result: " + result;
+}
</ins></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/CMakeLists.txt (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/CMakeLists.txt        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/CMakeLists.txt        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -90,6 +90,7 @@
</span><span class="cx"> dfg/DFGAbstractHeap.cpp
</span><span class="cx"> dfg/DFGAbstractValue.cpp
</span><span class="cx"> dfg/DFGArgumentsSimplificationPhase.cpp
</span><ins>+ dfg/DFGArithMode.cpp
</ins><span class="cx"> dfg/DFGArrayMode.cpp
</span><span class="cx"> dfg/DFGAtTailAbstractState.cpp
</span><span class="cx"> dfg/DFGAvailability.cpp
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ChangeLog (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -1,3 +1,7 @@
</span><ins>+2014-01-06 Filip Pizlo <fpizlo@apple.com>
+
+ Merge trunk r161072, r161126, r161218, r161353, r161356, r161364, 161399.
+
</ins><span class="cx"> 2014-01-06 Michael Saboff <msaboff@apple.com>
</span><span class="cx">
</span><span class="cx"> CStack Branch: ARM64 Crash in llint_function_for_call_arity_check running 3d-raytrace.js
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/GNUmakefile.list.am (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/GNUmakefile.list.am        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/GNUmakefile.list.am        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -207,6 +207,8 @@
</span><span class="cx">         Source/JavaScriptCore/dfg/DFGArgumentPosition.h \
</span><span class="cx">         Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp \
</span><span class="cx">         Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h \
</span><ins>+        Source/JavaScriptCore/dfg/DFGArithMode.cpp \
+        Source/JavaScriptCore/dfg/DFGArithMode.h \
</ins><span class="cx">         Source/JavaScriptCore/dfg/DFGArrayMode.cpp \
</span><span class="cx">         Source/JavaScriptCore/dfg/DFGArrayMode.h \
</span><span class="cx">         Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h \
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -336,6 +336,7 @@
</span><span class="cx"> <ClCompile Include="..\dfg\DFGAbstractHeap.cpp" />
</span><span class="cx"> <ClCompile Include="..\dfg\DFGAbstractValue.cpp" />
</span><span class="cx"> <ClCompile Include="..\dfg\DFGArgumentsSimplificationPhase.cpp" />
</span><ins>+ <ClCompile Include="..\dfg\DFGArithMode.cpp" />
</ins><span class="cx"> <ClCompile Include="..\dfg\DFGArrayMode.cpp" />
</span><span class="cx"> <ClCompile Include="..\dfg\DFGAtTailAbstractState.cpp" />
</span><span class="cx"> <ClCompile Include="..\dfg\DFGAvailability.cpp" />
</span><span class="lines">@@ -823,6 +824,7 @@
</span><span class="cx"> <ClInclude Include="..\dfg\DFGArgumentPosition.h" />
</span><span class="cx"> <ClInclude Include="..\dfg\DFGArgumentsSimplificationPhase.h" />
</span><span class="cx"> <ClInclude Include="..\dfg\DFGArrayifySlowPathGenerator.h" />
</span><ins>+ <ClInclude Include="..\dfg\DFGArithMode.h" />
</ins><span class="cx"> <ClInclude Include="..\dfg\DFGArrayMode.h" />
</span><span class="cx"> <ClInclude Include="..\dfg\DFGAtTailAbstractState.h" />
</span><span class="cx"> <ClInclude Include="..\dfg\DFGAvailability.h" />
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -234,6 +234,8 @@
</span><span class="cx">                 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680CF14BBB3D100BFE272 /* LLIntData.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */; };
</span><span class="cx">                 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F485321187750560083B687 /* DFGArithMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F48531F187750560083B687 /* DFGArithMode.cpp */; };
+                0F485322187750560083B687 /* DFGArithMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485320187750560083B687 /* DFGArithMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F493AF816D0CAD10084508B /* SourceProvider.cpp */; };
</span><span class="cx">                 0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */; };
</span><span class="lines">@@ -1562,6 +1564,8 @@
</span><span class="cx">                 0F4680CF14BBB3D100BFE272 /* LLIntData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntData.h; path = llint/LLIntData.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HostCallReturnValue.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HostCallReturnValue.h; sourceTree = "<group>"; };
</span><ins>+                0F48531F187750560083B687 /* DFGArithMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArithMode.cpp; path = dfg/DFGArithMode.cpp; sourceTree = "<group>"; };
+                0F485320187750560083B687 /* DFGArithMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArithMode.h; path = dfg/DFGArithMode.h; sourceTree = "<group>"; };
</ins><span class="cx">                 0F493AF816D0CAD10084508B /* SourceProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProvider.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayInlines.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialPointer.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -3835,6 +3839,8 @@
</span><span class="cx">                                 0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */,
</span><span class="cx">                                 0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */,
</span><span class="cx">                                 0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */,
</span><ins>+                                0F48531F187750560083B687 /* DFGArithMode.cpp */,
+                                0F485320187750560083B687 /* DFGArithMode.h */,
</ins><span class="cx">                                 0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */,
</span><span class="cx">                                 0F63948115E48114006A597C /* DFGArrayMode.cpp */,
</span><span class="cx">                                 0F63948215E48114006A597C /* DFGArrayMode.h */,
</span><span class="lines">@@ -4732,6 +4738,7 @@
</span><span class="cx">                                 A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */,
</span><span class="cx">                                 0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
</span><span class="cx">                                 A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */,
</span><ins>+                                0F485322187750560083B687 /* DFGArithMode.h in Headers */,
</ins><span class="cx">                                 BC18C45E0E16F5CD00B34460 /* JSStack.h in Headers */,
</span><span class="cx">                                 A7C1EAF017987AB600299DB2 /* JSStackInlines.h in Headers */,
</span><span class="cx">                                 BC18C4270E16F5CD00B34460 /* JSString.h in Headers */,
</span><span class="lines">@@ -5426,6 +5433,7 @@
</span><span class="cx">                                 0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */,
</span><span class="cx">                                 A7A8AF3417ADB5F3005AB174 /* ArrayBuffer.cpp in Sources */,
</span><span class="cx">                                 A7A8AF3617ADB5F3005AB174 /* ArrayBufferView.cpp in Sources */,
</span><ins>+                                0F485321187750560083B687 /* DFGArithMode.cpp in Sources */,
</ins><span class="cx">                                 147F39BF107EC37600427A48 /* ArrayConstructor.cpp in Sources */,
</span><span class="cx">                                 A7BDAEC617F4EA1400F6140C /* ArrayIteratorConstructor.cpp in Sources */,
</span><span class="cx">                                 A7BDAEC817F4EA1400F6140C /* ArrayIteratorPrototype.cpp in Sources */,
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorebytecodeCallLinkStatuscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -101,7 +101,7 @@
</span><span class="cx">
</span><span class="cx"> UNUSED_PARAM(profiledBlock);
</span><span class="cx"> UNUSED_PARAM(bytecodeIndex);
</span><del>-#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
</del><ins>+#if ENABLE(JIT)
</ins><span class="cx"> if (!profiledBlock->hasBaselineJITProfiling())
</span><span class="cx"> return computeFromLLInt(profiledBlock, bytecodeIndex);
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/bytecode/CodeBlock.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -135,6 +135,7 @@
</span><span class="cx">
</span><span class="cx"> if (codeType() == FunctionCode)
</span><span class="cx"> out.print(specializationKind());
</span><ins>+ out.print(", ", instructionCount());
</ins><span class="cx"> if (this->jitType() == JITCode::BaselineJIT && m_shouldAlwaysBeInlined)
</span><span class="cx"> out.print(" (SABI)");
</span><span class="cx"> if (ownerExecutable()->neverInline())
</span><span class="lines">@@ -621,16 +622,11 @@
</span><span class="cx"> ConcurrentJITLocker locker(m_lock);
</span><span class="cx">
</span><span class="cx"> ++it;
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> CString description = it->u.profile->briefDescription(locker);
</span><span class="cx"> if (!description.length())
</span><span class="cx"> return;
</span><span class="cx"> beginDumpProfiling(out, hasPrintedProfiling);
</span><span class="cx"> out.print(description);
</span><del>-#else
- UNUSED_PARAM(out);
- UNUSED_PARAM(hasPrintedProfiling);
-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void CodeBlock::dumpArrayProfiling(PrintStream& out, const Instruction*& it, bool& hasPrintedProfiling)
</span><span class="lines">@@ -638,7 +634,6 @@
</span><span class="cx"> ConcurrentJITLocker locker(m_lock);
</span><span class="cx">
</span><span class="cx"> ++it;
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> if (!it->u.arrayProfile)
</span><span class="cx"> return;
</span><span class="cx"> CString description = it->u.arrayProfile->briefDescription(locker, this);
</span><span class="lines">@@ -646,13 +641,8 @@
</span><span class="cx"> return;
</span><span class="cx"> beginDumpProfiling(out, hasPrintedProfiling);
</span><span class="cx"> out.print(description);
</span><del>-#else
- UNUSED_PARAM(out);
- UNUSED_PARAM(hasPrintedProfiling);
-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> void CodeBlock::dumpRareCaseProfile(PrintStream& out, const char* name, RareCaseProfile* profile, bool& hasPrintedProfiling)
</span><span class="cx"> {
</span><span class="cx"> if (!profile || !profile->m_counter)
</span><span class="lines">@@ -661,7 +651,6 @@
</span><span class="cx"> beginDumpProfiling(out, hasPrintedProfiling);
</span><span class="cx"> out.print(name, profile->m_counter);
</span><span class="cx"> }
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> void CodeBlock::dumpBytecode(PrintStream& out, ExecState* exec, const Instruction* begin, const Instruction*& it, const StubInfoMap& map)
</span><span class="cx"> {
</span><span class="lines">@@ -1421,10 +1410,8 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> dumpRareCaseProfile(out, "rare case: ", rareCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
</span><span class="cx"> dumpRareCaseProfile(out, "special fast case: ", specialFastCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> Vector<DFG::FrequentExitSite> exitSites = exitProfile().exitSitesFor(location);
</span><span class="lines">@@ -1798,12 +1785,10 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case op_get_from_scope: {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> ValueProfile* profile = &m_valueProfiles[pc[i + opLength - 1].u.operand];
</span><span class="cx"> ASSERT(profile->m_bytecodeOffset == -1);
</span><span class="cx"> profile->m_bytecodeOffset = i;
</span><span class="cx"> instructions[i + opLength - 1] = profile;
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
</span><span class="cx"> const Identifier& ident = identifier(pc[i + 3].u.operand);
</span><span class="lines">@@ -1923,9 +1908,7 @@
</span><span class="cx"> {
</span><span class="cx"> m_numParameters = newValue;
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> m_argumentValueProfiles.resizeToFit(newValue);
</span><del>-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void EvalCodeCache::visitAggregate(SlotVisitor& visitor)
</span><span class="lines">@@ -2595,10 +2578,8 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> m_callLinkInfos.shrinkToFit();
</span><span class="cx"> #endif
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> m_rareCaseProfiles.shrinkToFit();
</span><span class="cx"> m_specialFastCaseProfiles.shrinkToFit();
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> if (shrinkMode == EarlyShrink) {
</span><span class="cx"> m_additionalIdentifiers.shrinkToFit();
</span><span class="lines">@@ -3180,7 +3161,6 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> ArrayProfile* CodeBlock::getArrayProfile(unsigned bytecodeOffset)
</span><span class="cx"> {
</span><span class="cx"> for (unsigned i = 0; i < m_arrayProfiles.size(); ++i) {
</span><span class="lines">@@ -3253,10 +3233,6 @@
</span><span class="cx"> if (Options::verboseOSR())
</span><span class="cx"> dataLog("Considering optimizing ", *this, "...\n");
</span><span class="cx">
</span><del>-#if ENABLE(VERBOSE_VALUE_PROFILE)
- dumpValueProfiles();
-#endif
-
</del><span class="cx"> if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay())
</span><span class="cx"> return true;
</span><span class="cx">
</span><span class="lines">@@ -3285,7 +3261,6 @@
</span><span class="cx"> optimizeAfterWarmUp();
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> void CodeBlock::tallyFrequentExitSites()
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/bytecode/CodeBlock.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -244,7 +244,7 @@
</span><span class="cx">
</span><span class="cx"> bool usesOpcode(OpcodeID);
</span><span class="cx">
</span><del>- unsigned instructionCount() { return m_instructions.size(); }
</del><ins>+ unsigned instructionCount() const { return m_instructions.size(); }
</ins><span class="cx">
</span><span class="cx"> int argumentIndexAfterCapture(size_t argument);
</span><span class="cx">
</span><span class="lines">@@ -275,12 +275,12 @@
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-#if ENABLE(JIT)
</del><span class="cx"> bool hasBaselineJITProfiling() const
</span><span class="cx"> {
</span><span class="cx"> return jitType() == JITCode::BaselineJIT;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if ENABLE(JIT)
</ins><span class="cx"> virtual CodeBlock* replacement() = 0;
</span><span class="cx">
</span><span class="cx"> virtual DFG::CapabilityLevel capabilityLevelInternal() = 0;
</span><span class="lines">@@ -408,7 +408,6 @@
</span><span class="cx"> CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> unsigned numberOfArgumentValueProfiles()
</span><span class="cx"> {
</span><span class="cx"> ASSERT(m_numParameters >= 0);
</span><span class="lines">@@ -427,13 +426,12 @@
</span><span class="cx"> ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset)
</span><span class="cx"> {
</span><span class="cx"> ValueProfile* result = binarySearch<ValueProfile, int>(
</span><del>- m_valueProfiles, m_valueProfiles.size(), bytecodeOffset,
- getValueProfileBytecodeOffset<ValueProfile>);
</del><ins>+ m_valueProfiles, m_valueProfiles.size(), bytecodeOffset,
+ getValueProfileBytecodeOffset<ValueProfile>);
</ins><span class="cx"> ASSERT(result->m_bytecodeOffset != -1);
</span><span class="cx"> ASSERT(instructions()[bytecodeOffset + opcodeLength(
</span><del>- m_vm->interpreter->getOpcodeID(
- instructions()[
- bytecodeOffset].u.opcode)) - 1].u.profile == result);
</del><ins>+ m_vm->interpreter->getOpcodeID(
+ instructions()[bytecodeOffset].u.opcode)) - 1].u.profile == result);
</ins><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx"> SpeculatedType valueProfilePredictionForBytecodeOffset(const ConcurrentJITLocker& locker, int bytecodeOffset)
</span><span class="lines">@@ -541,7 +539,6 @@
</span><span class="cx"> }
</span><span class="cx"> ArrayProfile* getArrayProfile(unsigned bytecodeOffset);
</span><span class="cx"> ArrayProfile* getOrAddArrayProfile(unsigned bytecodeOffset);
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> // Exception handling support
</span><span class="cx">
</span><span class="lines">@@ -882,22 +879,11 @@
</span><span class="cx"> unsigned numberOfDFGCompiles() { return 0; }
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> bool shouldOptimizeNow();
</span><span class="cx"> void updateAllValueProfilePredictions();
</span><span class="cx"> void updateAllArrayPredictions();
</span><span class="cx"> void updateAllPredictions();
</span><del>-#else
- bool updateAllPredictionsAndCheckIfShouldOptimizeNow() { return false; }
- void updateAllValueProfilePredictions() { }
- void updateAllArrayPredictions() { }
- void updateAllPredictions() { }
-#endif
</del><span class="cx">
</span><del>-#if ENABLE(VERBOSE_VALUE_PROFILE)
- void dumpValueProfiles();
-#endif
-
</del><span class="cx"> unsigned frameRegisterCount();
</span><span class="cx"> int stackPointerOffset();
</span><span class="cx">
</span><span class="lines">@@ -958,9 +944,7 @@
</span><span class="cx"> ClosureCallStubRoutine* findClosureCallForReturnPC(ReturnAddressPtr);
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> void updateAllPredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants)
</span><span class="cx"> {
</span><span class="lines">@@ -995,9 +979,7 @@
</span><span class="cx"> void beginDumpProfiling(PrintStream&, bool& hasPrintedProfiling);
</span><span class="cx"> void dumpValueProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling);
</span><span class="cx"> void dumpArrayProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling);
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> void dumpRareCaseProfile(PrintStream&, const char* name, RareCaseProfile*, bool& hasPrintedProfiling);
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> bool shouldImmediatelyAssumeLivenessDuringScan()
</span><span class="lines">@@ -1078,14 +1060,12 @@
</span><span class="cx"> DFG::ExitProfile m_exitProfile;
</span><span class="cx"> CompressedLazyOperandValueProfileHolder m_lazyOperandValueProfiles;
</span><span class="cx"> #endif
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> Vector<ValueProfile> m_argumentValueProfiles;
</span><span class="cx"> Vector<ValueProfile> m_valueProfiles;
</span><span class="cx"> SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles;
</span><span class="cx"> SegmentedVector<RareCaseProfile, 8> m_specialFastCaseProfiles;
</span><span class="cx"> Vector<ArrayAllocationProfile> m_arrayAllocationProfiles;
</span><span class="cx"> ArrayProfileVector m_arrayProfiles;
</span><del>-#endif
</del><span class="cx"> Vector<ObjectAllocationProfile> m_objectAllocationProfiles;
</span><span class="cx">
</span><span class="cx"> // Constant Pool
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorebytecodeGetByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx">
</span><span class="cx"> void GetByIdStatus::computeForChain(GetByIdStatus& result, CodeBlock* profiledBlock, StringImpl* uid)
</span><span class="cx"> {
</span><del>-#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
</del><ins>+#if ENABLE(JIT)
</ins><span class="cx"> // Validate the chain. If the chain is invalid, then currently the best thing
</span><span class="cx"> // we can do is to assume that TakesSlow is true. In the future, it might be
</span><span class="cx"> // worth exploring reifying the structure chain from the structure we've got
</span><span class="lines">@@ -112,7 +112,7 @@
</span><span class="cx"> UNUSED_PARAM(profiledBlock);
</span><span class="cx"> UNUSED_PARAM(bytecodeIndex);
</span><span class="cx"> UNUSED_PARAM(uid);
</span><del>-#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
</del><ins>+#if ENABLE(JIT)
</ins><span class="cx"> StructureStubInfo* stubInfo = map.get(CodeOrigin(bytecodeIndex));
</span><span class="cx"> if (!stubInfo || !stubInfo->seen)
</span><span class="cx"> return computeFromLLInt(profiledBlock, bytecodeIndex, uid);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorebytecodeLazyOperandValueProfilecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -26,8 +26,6 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "LazyOperandValueProfile.h"
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
-
</del><span class="cx"> #include "Operations.h"
</span><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -100,5 +98,3 @@
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span><span class="cx">
</span><del>-#endif // ENABLE(VALUE_PROFILER)
-
</del></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorebytecodeLazyOperandValueProfileh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -26,10 +26,6 @@
</span><span class="cx"> #ifndef LazyOperandValueProfile_h
</span><span class="cx"> #define LazyOperandValueProfile_h
</span><span class="cx">
</span><del>-#include <wtf/Platform.h>
-
-#if ENABLE(VALUE_PROFILER)
-
</del><span class="cx"> #include "ConcurrentJITLock.h"
</span><span class="cx"> #include "ValueProfile.h"
</span><span class="cx"> #include "VirtualRegister.h"
</span><span class="lines">@@ -188,8 +184,6 @@
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span><span class="cx">
</span><del>-#endif // ENABLE(VALUE_PROFILER)
-
</del><span class="cx"> #endif // LazyOperandValueProfile_h
</span><span class="cx">
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorebytecodePutByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -88,7 +88,7 @@
</span><span class="cx"> UNUSED_PARAM(profiledBlock);
</span><span class="cx"> UNUSED_PARAM(bytecodeIndex);
</span><span class="cx"> UNUSED_PARAM(uid);
</span><del>-#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
</del><ins>+#if ENABLE(JIT)
</ins><span class="cx"> if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
</span><span class="cx"> return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorebytecodeValueProfileh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/bytecode/ValueProfile.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/bytecode/ValueProfile.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/bytecode/ValueProfile.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -29,10 +29,6 @@
</span><span class="cx"> #ifndef ValueProfile_h
</span><span class="cx"> #define ValueProfile_h
</span><span class="cx">
</span><del>-#include <wtf/Platform.h>
-
-#if ENABLE(VALUE_PROFILER)
-
</del><span class="cx"> #include "ConcurrentJITLock.h"
</span><span class="cx"> #include "Heap.h"
</span><span class="cx"> #include "JSArray.h"
</span><span class="lines">@@ -212,7 +208,5 @@
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span><span class="cx">
</span><del>-#endif // ENABLE(VALUE_PROFILER)
-
</del><span class="cx"> #endif // ValueProfile_h
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -636,20 +636,12 @@
</span><span class="cx">
</span><span class="cx"> UnlinkedArrayProfile BytecodeGenerator::newArrayProfile()
</span><span class="cx"> {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> return m_codeBlock->addArrayProfile();
</span><del>-#else
- return 0;
-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> UnlinkedArrayAllocationProfile BytecodeGenerator::newArrayAllocationProfile()
</span><span class="cx"> {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> return m_codeBlock->addArrayAllocationProfile();
</span><del>-#else
- return 0;
-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> UnlinkedObjectAllocationProfile BytecodeGenerator::newObjectAllocationProfile()
</span><span class="lines">@@ -659,11 +651,7 @@
</span><span class="cx">
</span><span class="cx"> UnlinkedValueProfile BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID)
</span><span class="cx"> {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> UnlinkedValueProfile result = m_codeBlock->addValueProfile();
</span><del>-#else
- UnlinkedValueProfile result = 0;
-#endif
</del><span class="cx"> emitOpcode(opcodeID);
</span><span class="cx"> return result;
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredebuggerDebuggerh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/debugger/Debugger.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/debugger/Debugger.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/debugger/Debugger.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -195,7 +195,7 @@
</span><span class="cx">
</span><span class="cx"> class Debugger {
</span><span class="cx"> public:
</span><del>- Debugger(bool = false) { }
</del><ins>+ Debugger(bool = false) : m_needsOpDebugCallbacks(false) { }
</ins><span class="cx"> bool needsOpDebugCallbacks() const { return false; }
</span><span class="cx"> bool needsExceptionCallbacks() const { return false; }
</span><span class="cx"> void detach(JSGlobalObject*) { }
</span><span class="lines">@@ -207,6 +207,8 @@
</span><span class="cx"> void willExecuteProgram(CallFrame*) { }
</span><span class="cx"> void didExecuteProgram(CallFrame*) { }
</span><span class="cx"> void didReachBreakpoint(CallFrame*) { }
</span><ins>+
+ bool m_needsOpDebugCallbacks;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(JAVASCRIPT_DEBUGGER)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -195,18 +195,13 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case MovHint:
- case MovHintAndCheck: {
- // Don't need to do anything. A MovHint is effectively a promise that the SetLocal
- // was dead.
</del><ins>+ case MovHint: {
+ // Don't need to do anything. A MovHint only informs us about what would have happened
+ // in bytecode, but this code is just concerned with what is actually happening during
+ // DFG execution.
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case ZombieHint: {
- RELEASE_ASSERT_NOT_REACHED();
- break;
- }
-
</del><span class="cx"> case SetArgument:
</span><span class="cx"> // Assert that the state of arguments has been set.
</span><span class="cx"> ASSERT(!m_state.block()->valuesAtHead.operand(node->local()).isClear());
</span><span class="lines">@@ -254,18 +249,24 @@
</span><span class="cx">
</span><span class="cx"> case UInt32ToNumber: {
</span><span class="cx"> JSValue child = forNode(node->child1()).value();
</span><del>- if (child && child.isNumber()) {
- ASSERT(child.isInt32());
- uint32_t value = child.asInt32();
- setConstant(node, jsNumber(value));
</del><ins>+ if (doesOverflow(node->arithMode())) {
+ if (child && child.isInt32()) {
+ uint32_t value = child.asInt32();
+ setConstant(node, jsNumber(value));
+ break;
+ }
+ forNode(node).setType(SpecDouble);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><del>- if (!node->canSpeculateInt32())
- forNode(node).setType(SpecDouble);
- else {
- forNode(node).setType(SpecInt32);
- node->setCanExit(true);
</del><ins>+ if (child && child.isInt32()) {
+ int32_t value = child.asInt32();
+ if (value >= 0) {
+ setConstant(node, jsNumber(value));
+ break;
+ }
</ins><span class="cx"> }
</span><ins>+ forNode(node).setType(SpecInt32);
+ node->setCanExit(true);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -340,27 +341,51 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case ValueAdd:
</del><ins>+ case ValueAdd: {
+ ASSERT(node->binaryUseKind() == UntypedUse);
+ clobberWorld(node->codeOrigin, clobberLimit);
+ forNode(node).setType(SpecString | SpecBytecodeNumber);
+ break;
+ }
+
</ins><span class="cx"> case ArithAdd: {
</span><span class="cx"> JSValue left = forNode(node->child1()).value();
</span><span class="cx"> JSValue right = forNode(node->child2()).value();
</span><del>- if (left && right && left.isNumber() && right.isNumber()) {
- setConstant(node, JSValue(left.asNumber() + right.asNumber()));
- break;
- }
</del><span class="cx"> switch (node->binaryUseKind()) {
</span><span class="cx"> case Int32Use:
</span><ins>+ if (left && right && left.isInt32() && right.isInt32()) {
+ if (!shouldCheckOverflow(node->arithMode())) {
+ setConstant(node, jsNumber(left.asInt32() + right.asInt32()));
+ break;
+ }
+ JSValue result = jsNumber(left.asNumber() + right.asNumber());
+ if (result.isInt32()) {
+ setConstant(node, result);
+ break;
+ }
+ }
</ins><span class="cx"> forNode(node).setType(SpecInt32);
</span><del>- if (!bytecodeCanTruncateInteger(node->arithNodeFlags()))
</del><ins>+ if (shouldCheckOverflow(node->arithMode()))
</ins><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx"> case MachineIntUse:
</span><ins>+ if (left && right && left.isMachineInt() && right.isMachineInt()) {
+ JSValue result = jsNumber(left.asMachineInt() + right.asMachineInt());
+ if (result.isMachineInt()) {
+ setConstant(node, result);
+ break;
+ }
+ }
</ins><span class="cx"> forNode(node).setType(SpecInt52);
</span><span class="cx"> if (!forNode(node->child1()).isType(SpecInt32)
</span><span class="cx"> || !forNode(node->child2()).isType(SpecInt32))
</span><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx"> case NumberUse:
</span><ins>+ if (left && right && left.isNumber() && right.isNumber()) {
+ setConstant(node, jsNumber(left.asNumber() + right.asNumber()));
+ break;
+ }
</ins><span class="cx"> if (isFullRealNumberSpeculation(forNode(node->child1()).m_type)
</span><span class="cx"> && isFullRealNumberSpeculation(forNode(node->child2()).m_type))
</span><span class="cx"> forNode(node).setType(SpecDoubleReal);
</span><span class="lines">@@ -368,9 +393,7 @@
</span><span class="cx"> forNode(node).setType(SpecDouble);
</span><span class="cx"> break;
</span><span class="cx"> default:
</span><del>- RELEASE_ASSERT(node->op() == ValueAdd);
- clobberWorld(node->codeOrigin, clobberLimit);
- forNode(node).setType(SpecString | SpecBytecodeNumber);
</del><ins>+ RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> break;
</span><span class="lines">@@ -384,23 +407,41 @@
</span><span class="cx"> case ArithSub: {
</span><span class="cx"> JSValue left = forNode(node->child1()).value();
</span><span class="cx"> JSValue right = forNode(node->child2()).value();
</span><del>- if (left && right && left.isNumber() && right.isNumber()) {
- setConstant(node, JSValue(left.asNumber() - right.asNumber()));
- break;
- }
</del><span class="cx"> switch (node->binaryUseKind()) {
</span><span class="cx"> case Int32Use:
</span><ins>+ if (left && right && left.isInt32() && right.isInt32()) {
+ if (!shouldCheckOverflow(node->arithMode())) {
+ setConstant(node, jsNumber(left.asInt32() - right.asInt32()));
+ break;
+ }
+ JSValue result = jsNumber(left.asNumber() - right.asNumber());
+ if (result.isInt32()) {
+ setConstant(node, result);
+ break;
+ }
+ }
</ins><span class="cx"> forNode(node).setType(SpecInt32);
</span><del>- if (!bytecodeCanTruncateInteger(node->arithNodeFlags()))
</del><ins>+ if (shouldCheckOverflow(node->arithMode()))
</ins><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx"> case MachineIntUse:
</span><ins>+ if (left && right && left.isMachineInt() && right.isMachineInt()) {
+ JSValue result = jsNumber(left.asMachineInt() - right.asMachineInt());
+ if (result.isMachineInt() || !shouldCheckOverflow(node->arithMode())) {
+ setConstant(node, result);
+ break;
+ }
+ }
</ins><span class="cx"> forNode(node).setType(SpecInt52);
</span><span class="cx"> if (!forNode(node->child1()).isType(SpecInt32)
</span><span class="cx"> || !forNode(node->child2()).isType(SpecInt32))
</span><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx"> case NumberUse:
</span><ins>+ if (left && right && left.isNumber() && right.isNumber()) {
+ setConstant(node, jsNumber(left.asNumber() - right.asNumber()));
+ break;
+ }
</ins><span class="cx"> forNode(node).setType(SpecDouble);
</span><span class="cx"> break;
</span><span class="cx"> default:
</span><span class="lines">@@ -412,24 +453,52 @@
</span><span class="cx">
</span><span class="cx"> case ArithNegate: {
</span><span class="cx"> JSValue child = forNode(node->child1()).value();
</span><del>- if (child && child.isNumber()) {
- setConstant(node, JSValue(-child.asNumber()));
- break;
- }
</del><span class="cx"> switch (node->child1().useKind()) {
</span><span class="cx"> case Int32Use:
</span><ins>+ if (child && child.isInt32()) {
+ if (!shouldCheckOverflow(node->arithMode())) {
+ setConstant(node, jsNumber(-child.asInt32()));
+ break;
+ }
+ double doubleResult;
+ if (shouldCheckNegativeZero(node->arithMode()))
+ doubleResult = -child.asNumber();
+ else
+ doubleResult = 0 - child.asNumber();
+ JSValue valueResult = jsNumber(doubleResult);
+ if (valueResult.isInt32()) {
+ setConstant(node, valueResult);
+ break;
+ }
+ }
</ins><span class="cx"> forNode(node).setType(SpecInt32);
</span><del>- if (!bytecodeCanTruncateInteger(node->arithNodeFlags()))
</del><ins>+ if (shouldCheckOverflow(node->arithMode()))
</ins><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx"> case MachineIntUse:
</span><ins>+ if (child && child.isMachineInt()) {
+ double doubleResult;
+ if (shouldCheckNegativeZero(node->arithMode()))
+ doubleResult = -child.asNumber();
+ else
+ doubleResult = 0 - child.asNumber();
+ JSValue valueResult = jsNumber(doubleResult);
+ if (valueResult.isMachineInt()) {
+ setConstant(node, valueResult);
+ break;
+ }
+ }
</ins><span class="cx"> forNode(node).setType(SpecInt52);
</span><span class="cx"> if (m_state.forNode(node->child1()).couldBeType(SpecInt52))
</span><span class="cx"> node->setCanExit(true);
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode()))
</ins><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx"> case NumberUse:
</span><ins>+ if (child && child.isNumber()) {
+ setConstant(node, jsNumber(-child.asNumber()));
+ break;
+ }
</ins><span class="cx"> forNode(node).setType(SpecDouble);
</span><span class="cx"> break;
</span><span class="cx"> default:
</span><span class="lines">@@ -442,22 +511,45 @@
</span><span class="cx"> case ArithMul: {
</span><span class="cx"> JSValue left = forNode(node->child1()).value();
</span><span class="cx"> JSValue right = forNode(node->child2()).value();
</span><del>- if (left && right && left.isNumber() && right.isNumber()) {
- setConstant(node, JSValue(left.asNumber() * right.asNumber()));
- break;
- }
</del><span class="cx"> switch (node->binaryUseKind()) {
</span><span class="cx"> case Int32Use:
</span><ins>+ if (left && right && left.isInt32() && right.isInt32()) {
+ if (!shouldCheckOverflow(node->arithMode())) {
+ setConstant(node, jsNumber(left.asInt32() * right.asInt32()));
+ break;
+ }
+ double doubleResult = left.asNumber() * right.asNumber();
+ if (!shouldCheckNegativeZero(node->arithMode()))
+ doubleResult += 0; // Sanitizes zero.
+ JSValue valueResult = jsNumber(doubleResult);
+ if (valueResult.isInt32()) {
+ setConstant(node, valueResult);
+ break;
+ }
+ }
</ins><span class="cx"> forNode(node).setType(SpecInt32);
</span><del>- if (!bytecodeCanTruncateInteger(node->arithNodeFlags())
- || !bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
</del><ins>+ if (shouldCheckOverflow(node->arithMode()))
</ins><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx"> case MachineIntUse:
</span><ins>+ if (left && right && left.isMachineInt() && right.isMachineInt()) {
+ double doubleResult = left.asNumber() * right.asNumber();
+ if (!shouldCheckNegativeZero(node->arithMode()))
+ doubleResult += 0;
+ JSValue valueResult = jsNumber(doubleResult);
+ if (valueResult.isMachineInt()) {
+ setConstant(node, valueResult);
+ break;
+ }
+ }
</ins><span class="cx"> forNode(node).setType(SpecInt52);
</span><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx"> case NumberUse:
</span><ins>+ if (left && right && left.isNumber() && right.isNumber()) {
+ setConstant(node, jsNumber(left.asNumber() * right.asNumber()));
+ break;
+ }
</ins><span class="cx"> if (isFullRealNumberSpeculation(forNode(node->child1()).m_type)
</span><span class="cx"> || isFullRealNumberSpeculation(forNode(node->child2()).m_type))
</span><span class="cx"> forNode(node).setType(SpecDoubleReal);
</span><span class="lines">@@ -470,46 +562,122 @@
</span><span class="cx"> }
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
- case ArithIMul: {
- forNode(node).setType(SpecInt32);
</del><ins>+
+ case ArithDiv: {
+ JSValue left = forNode(node->child1()).value();
+ JSValue right = forNode(node->child2()).value();
+ switch (node->binaryUseKind()) {
+ case Int32Use:
+ if (left && right && left.isInt32() && right.isInt32()) {
+ double doubleResult = left.asNumber() / right.asNumber();
+ if (!shouldCheckOverflow(node->arithMode()))
+ doubleResult = toInt32(doubleResult);
+ else if (!shouldCheckNegativeZero(node->arithMode()))
+ doubleResult += 0; // Sanitizes zero.
+ JSValue valueResult = jsNumber(doubleResult);
+ if (valueResult.isInt32()) {
+ setConstant(node, valueResult);
+ break;
+ }
+ }
+ forNode(node).setType(SpecInt32);
+ node->setCanExit(true);
+ break;
+ case NumberUse:
+ if (left && right && left.isNumber() && right.isNumber()) {
+ setConstant(node, jsNumber(left.asNumber() / right.asNumber()));
+ break;
+ }
+ forNode(node).setType(SpecDouble);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
- case ArithDiv:
- case ArithMin:
- case ArithMax:
</del><ins>+
</ins><span class="cx"> case ArithMod: {
</span><span class="cx"> JSValue left = forNode(node->child1()).value();
</span><span class="cx"> JSValue right = forNode(node->child2()).value();
</span><del>- if (left && right && left.isNumber() && right.isNumber()) {
- double a = left.asNumber();
- double b = right.asNumber();
- switch (node->op()) {
- case ArithDiv:
- setConstant(node, JSValue(a / b));
</del><ins>+ switch (node->binaryUseKind()) {
+ case Int32Use:
+ if (left && right && left.isInt32() && right.isInt32()) {
+ double doubleResult = fmod(left.asNumber(), right.asNumber());
+ if (!shouldCheckOverflow(node->arithMode()))
+ doubleResult = toInt32(doubleResult);
+ else if (!shouldCheckNegativeZero(node->arithMode()))
+ doubleResult += 0; // Sanitizes zero.
+ JSValue valueResult = jsNumber(doubleResult);
+ if (valueResult.isInt32()) {
+ setConstant(node, valueResult);
+ break;
+ }
+ }
+ forNode(node).setType(SpecInt32);
+ node->setCanExit(true);
+ break;
+ case NumberUse:
+ if (left && right && left.isNumber() && right.isNumber()) {
+ setConstant(node, jsNumber(fmod(left.asNumber(), right.asNumber())));
</ins><span class="cx"> break;
</span><del>- case ArithMin:
- setConstant(node, JSValue(a < b ? a : (b <= a ? b : a + b)));
</del><ins>+ }
+ forNode(node).setType(SpecDouble);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ break;
+ }
+
+ case ArithMin: {
+ JSValue left = forNode(node->child1()).value();
+ JSValue right = forNode(node->child2()).value();
+ switch (node->binaryUseKind()) {
+ case Int32Use:
+ if (left && right && left.isInt32() && right.isInt32()) {
+ setConstant(node, jsNumber(std::min(left.asInt32(), right.asInt32())));
</ins><span class="cx"> break;
</span><del>- case ArithMax:
- setConstant(node, JSValue(a > b ? a : (b >= a ? b : a + b)));
</del><ins>+ }
+ forNode(node).setType(SpecInt32);
+ node->setCanExit(true);
+ break;
+ case NumberUse:
+ if (left && right && left.isNumber() && right.isNumber()) {
+ double a = left.asNumber();
+ double b = right.asNumber();
+ setConstant(node, jsNumber(a < b ? a : (b <= a ? b : a + b)));
</ins><span class="cx"> break;
</span><del>- case ArithMod:
- setConstant(node, JSValue(fmod(a, b)));
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- break;
</del><span class="cx"> }
</span><ins>+ forNode(node).setType(SpecDouble);
</ins><span class="cx"> break;
</span><ins>+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
</ins><span class="cx"> }
</span><ins>+ break;
+ }
+
+ case ArithMax: {
+ JSValue left = forNode(node->child1()).value();
+ JSValue right = forNode(node->child2()).value();
</ins><span class="cx"> switch (node->binaryUseKind()) {
</span><span class="cx"> case Int32Use:
</span><ins>+ if (left && right && left.isInt32() && right.isInt32()) {
+ setConstant(node, jsNumber(std::max(left.asInt32(), right.asInt32())));
+ break;
+ }
</ins><span class="cx"> forNode(node).setType(SpecInt32);
</span><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx"> case NumberUse:
</span><ins>+ if (left && right && left.isNumber() && right.isNumber()) {
+ double a = left.asNumber();
+ double b = right.asNumber();
+ setConstant(node, jsNumber(a > b ? a : (b >= a ? b : a + b)));
+ break;
+ }
</ins><span class="cx"> forNode(node).setType(SpecDouble);
</span><span class="cx"> break;
</span><span class="cx"> default:
</span><span class="lines">@@ -521,16 +689,23 @@
</span><span class="cx">
</span><span class="cx"> case ArithAbs: {
</span><span class="cx"> JSValue child = forNode(node->child1()).value();
</span><del>- if (child && child.isNumber()) {
- setConstant(node, JSValue(fabs(child.asNumber())));
- break;
- }
</del><span class="cx"> switch (node->child1().useKind()) {
</span><span class="cx"> case Int32Use:
</span><ins>+ if (child && child.isInt32()) {
+ JSValue result = jsNumber(fabs(child.asNumber()));
+ if (result.isInt32()) {
+ setConstant(node, result);
+ break;
+ }
+ }
</ins><span class="cx"> forNode(node).setType(SpecInt32);
</span><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx"> case NumberUse:
</span><ins>+ if (child && child.isNumber()) {
+ setConstant(node, jsNumber(child.asNumber()));
+ break;
+ }
</ins><span class="cx"> forNode(node).setType(SpecDouble);
</span><span class="cx"> break;
</span><span class="cx"> default:
</span><span class="lines">@@ -1583,6 +1758,7 @@
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case Phantom:
</span><ins>+ case Check:
</ins><span class="cx"> case CountExecution:
</span><span class="cx"> case CheckTierUpInLoop:
</span><span class="cx"> case CheckTierUpAtReturn:
</span><span class="lines">@@ -1594,11 +1770,10 @@
</span><span class="cx"> node->setCanExit(true);
</span><span class="cx"> break;
</span><span class="cx">
</span><ins>+ case ZombieHint:
</ins><span class="cx"> case Unreachable:
</span><del>- RELEASE_ASSERT_NOT_REACHED();
- break;
-
</del><span class="cx"> case LastNodeType:
</span><ins>+ case ArithIMul:
</ins><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGArgumentsSimplificationPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -333,6 +333,11 @@
</span><span class="cx"> // structures of another variable.
</span><span class="cx"> break;
</span><span class="cx">
</span><ins>+ case MovHint:
+ // We don't care about MovHints at all, since they represent what happens
+ // in bytecode. We rematerialize arguments objects on OSR exit anyway.
+ break;
+
</ins><span class="cx"> default:
</span><span class="cx"> observeBadArgumentsUses(node);
</span><span class="cx"> break;
</span><span class="lines">@@ -395,16 +400,6 @@
</span><span class="cx"> || unmodifiedArgumentsRegister(m_graph.argumentsRegisterFor(node->codeOrigin)) == variableAccessData->local())
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- ASSERT(!variableAccessData->isCaptured());
-
- // If this is a store into a VariableAccessData* that is marked as
- // arguments aliasing for an InlineCallFrame* that does not create
- // arguments, then flag the VariableAccessData as being an
- // arguments-aliased. This'll let the OSR exit machinery do the right
- // things. Note also that the SetLocal should become dead as soon as
- // we replace all uses of this variable with GetMyArgumentsLength and
- // GetMyArgumentByVal.
- ASSERT(m_argumentsAliasing.find(variableAccessData)->value.isValid());
</del><span class="cx"> if (variableAccessData->mergeIsArgumentsAlias(true)) {
</span><span class="cx"> changed = true;
</span><span class="cx">
</span><span class="lines">@@ -420,22 +415,6 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case PhantomLocal: {
- VariableAccessData* variableAccessData = node->variableAccessData();
-
- if (variableAccessData->isCaptured()
- || !m_argumentsAliasing.find(variableAccessData)->value.isValid()
- || m_createsArguments.contains(node->codeOrigin.inlineCallFrame))
- break;
-
- // Turn PhantomLocals into just GetLocals. This will preserve the threading
- // of the local through to this point, but will allow it to die, causing
- // only OSR to know about it.
-
- node->setOpAndDefaultFlags(GetLocal);
- break;
- }
-
</del><span class="cx"> case Flush: {
</span><span class="cx"> VariableAccessData* variableAccessData = node->variableAccessData();
</span><span class="cx">
</span><span class="lines">@@ -459,7 +438,7 @@
</span><span class="cx"> // 2) The Phantom may keep the CreateArguments node alive, which is
</span><span class="cx"> // precisely what we don't want.
</span><span class="cx"> for (unsigned i = 0; i < AdjacencyList::Size; ++i)
</span><del>- removeArgumentsReferencingPhantomChild(node, i);
</del><ins>+ detypeArgumentsReferencingPhantomChild(node, i);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -470,7 +449,6 @@
</span><span class="cx"> if (!isOKToOptimize(node->child1().node()))
</span><span class="cx"> break;
</span><span class="cx"> node->convertToPhantom();
</span><del>- node->children.setChild1(Edge());
</del><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -488,8 +466,11 @@
</span><span class="cx"> if (!isOKToOptimize(node->child1().node()))
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- node->children.child1() = node->children.child2();
- node->children.child2() = Edge();
</del><ins>+ insertionSet.insertNode(
+ indexInBlock, SpecNone, Phantom, node->codeOrigin, node->child1());
+
+ node->child1() = node->child2();
+ node->child2() = Edge();
</ins><span class="cx"> node->setOpAndDefaultFlags(GetMyArgumentByVal);
</span><span class="cx"> changed = true;
</span><span class="cx"> --indexInBlock; // Force reconsideration of this op now that it's a GetMyArgumentByVal.
</span><span class="lines">@@ -503,7 +484,10 @@
</span><span class="cx"> if (!isOKToOptimize(node->child1().node()))
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- node->children.child1() = Edge();
</del><ins>+ insertionSet.insertNode(
+ indexInBlock, SpecNone, Phantom, node->codeOrigin, node->child1());
+
+ node->child1() = Edge();
</ins><span class="cx"> node->setOpAndDefaultFlags(GetMyArgumentsLength);
</span><span class="cx"> changed = true;
</span><span class="cx"> --indexInBlock; // Force reconsideration of this op noew that it's a GetMyArgumentsLength.
</span><span class="lines">@@ -580,8 +564,7 @@
</span><span class="cx"> indexInBlock, SpecNone, CheckArgumentsNotCreated,
</span><span class="cx"> codeOrigin);
</span><span class="cx"> insertionSet.insertNode(
</span><del>- indexInBlock, SpecNone, Phantom, codeOrigin,
- children);
</del><ins>+ indexInBlock, SpecNone, Phantom, codeOrigin, children);
</ins><span class="cx">
</span><span class="cx"> changed = true;
</span><span class="cx"> break;
</span><span class="lines">@@ -591,8 +574,7 @@
</span><span class="cx"> if (m_createsArguments.contains(node->codeOrigin.inlineCallFrame))
</span><span class="cx"> continue;
</span><span class="cx">
</span><del>- node->setOpAndDefaultFlags(Phantom);
- node->children.reset();
</del><ins>+ node->convertToPhantom();
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -627,6 +609,19 @@
</span><span class="cx"> insertionSet.execute(block);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+ BasicBlock* block = m_graph.block(blockIndex);
+ if (!block)
+ continue;
+ for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
+ Node* node = block->at(indexInBlock);
+ if (node->op() != Phantom)
+ continue;
+ for (unsigned i = 0; i < AdjacencyList::Size; ++i)
+ detypeArgumentsReferencingPhantomChild(node, i);
+ }
+ }
+
</ins><span class="cx"> if (changed) {
</span><span class="cx"> m_graph.dethread();
</span><span class="cx"> m_graph.m_form = LoadStore;
</span><span class="lines">@@ -764,35 +759,23 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void removeArgumentsReferencingPhantomChild(Node* node, unsigned edgeIndex)
</del><ins>+ void detypeArgumentsReferencingPhantomChild(Node* node, unsigned edgeIndex)
</ins><span class="cx"> {
</span><span class="cx"> Edge edge = node->children.child(edgeIndex);
</span><span class="cx"> if (!edge)
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> switch (edge->op()) {
</span><del>- case Phi: // Arises if we had CSE on a GetLocal of the arguments register.
- case GetLocal: // Arises if we had CSE on an arguments access to a variable aliased to the arguments.
- case SetLocal: { // Arises if we had CSE on a GetLocal of the arguments register.
</del><ins>+ case GetLocal: {
</ins><span class="cx"> VariableAccessData* variableAccessData = edge->variableAccessData();
</span><del>- bool isDeadArgumentsRegister =
- variableAccessData->local() ==
- m_graph.uncheckedArgumentsRegisterFor(edge->codeOrigin)
- && !m_createsArguments.contains(edge->codeOrigin.inlineCallFrame);
- bool isAliasedArgumentsRegister =
- !variableAccessData->isCaptured()
- && m_argumentsAliasing.find(variableAccessData)->value.isValid()
- && !m_createsArguments.contains(edge->codeOrigin.inlineCallFrame);
- if (!isDeadArgumentsRegister && !isAliasedArgumentsRegister)
</del><ins>+ if (!variableAccessData->isArgumentsAlias())
</ins><span class="cx"> break;
</span><del>- node->children.removeEdge(edgeIndex);
</del><ins>+ node->children.child(edgeIndex).setUseKind(UntypedUse);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case CreateArguments: { // Arises if we CSE two GetLocals to the arguments register and then CSE the second use of the GetLocal to the first.
- if (m_createsArguments.contains(edge->codeOrigin.inlineCallFrame))
- break;
- node->children.removeEdge(edgeIndex);
</del><ins>+ case PhantomArguments: {
+ node->children.child(edgeIndex).setUseKind(UntypedUse);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGArrayifySlowPathGeneratorh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -63,13 +63,13 @@
</span><span class="cx"> case Array::Int32:
</span><span class="cx"> case Array::Double:
</span><span class="cx"> case Array::Contiguous:
</span><del>- m_badPropertyJump = jit->backwardSpeculationCheck(Uncountable, JSValueRegs(), 0);
</del><ins>+ m_badPropertyJump = jit->speculationCheck(Uncountable, JSValueRegs(), 0);
</ins><span class="cx"> break;
</span><span class="cx"> default:
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>- m_badIndexingTypeJump = jit->backwardSpeculationCheck(BadIndexingType, JSValueSource::unboxedCell(m_baseGPR), 0);
</del><ins>+ m_badIndexingTypeJump = jit->speculationCheck(BadIndexingType, JSValueSource::unboxedCell(m_baseGPR), 0);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> protected:
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGBackwardsPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -187,6 +187,10 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case MovHint:
+ case Check:
+ break;
+
</ins><span class="cx"> case BitAnd:
</span><span class="cx"> case BitOr:
</span><span class="cx"> case BitXor:
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -232,15 +232,19 @@
</span><span class="cx"> return getDirect(m_inlineStackTop->remapOperand(operand));
</span><span class="cx"> }
</span><span class="cx">
</span><del>- enum SetMode { NormalSet, SetOnEntry };
</del><ins>+ enum SetMode { NormalSet, ImmediateSet };
</ins><span class="cx"> Node* setDirect(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
</span><span class="cx"> {
</span><del>- // Is this an argument?
- if (operand.isArgument())
- return setArgument(operand, value, setMode);
-
- // Must be a local.
- return setLocal(operand, value, setMode);
</del><ins>+ addToGraph(MovHint, OpInfo(operand.offset()), value);
+
+ DelayedSetLocal delayed = DelayedSetLocal(operand, value);
+
+ if (setMode == NormalSet) {
+ m_setLocalQueue.append(delayed);
+ return 0;
+ }
+
+ return delayed.execute(this, setMode);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Node* set(VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
</span><span class="lines">@@ -1123,6 +1127,27 @@
</span><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> InlineStackEntry* m_inlineStackTop;
</span><ins>+
+ struct DelayedSetLocal {
+ VirtualRegister m_operand;
+ Node* m_value;
+
+ DelayedSetLocal() { }
+ DelayedSetLocal(VirtualRegister operand, Node* value)
+ : m_operand(operand)
+ , m_value(value)
+ {
+ }
+
+ Node* execute(ByteCodeParser* parser, SetMode setMode = NormalSet)
+ {
+ if (m_operand.isArgument())
+ return parser->setArgument(m_operand, m_value, setMode);
+ return parser->setLocal(m_operand, m_value, setMode);
+ }
+ };
+
+ Vector<DelayedSetLocal, 2> m_setLocalQueue;
</ins><span class="cx">
</span><span class="cx"> // Have we built operand maps? We initialize them lazily, and only when doing
</span><span class="cx"> // inlining.
</span><span class="lines">@@ -1327,9 +1352,9 @@
</span><span class="cx"> == callLinkStatus.isClosureCall());
</span><span class="cx"> if (callLinkStatus.isClosureCall()) {
</span><span class="cx"> VariableAccessData* calleeVariable =
</span><del>- set(VirtualRegister(JSStack::Callee), callTargetNode)->variableAccessData();
</del><ins>+ set(VirtualRegister(JSStack::Callee), callTargetNode, ImmediateSet)->variableAccessData();
</ins><span class="cx"> VariableAccessData* scopeVariable =
</span><del>- set(VirtualRegister(JSStack::ScopeChain), addToGraph(GetScope, callTargetNode))->variableAccessData();
</del><ins>+ set(VirtualRegister(JSStack::ScopeChain), addToGraph(GetScope, callTargetNode), ImmediateSet)->variableAccessData();
</ins><span class="cx">
</span><span class="cx"> calleeVariable->mergeShouldNeverUnbox(true);
</span><span class="cx"> scopeVariable->mergeShouldNeverUnbox(true);
</span><span class="lines">@@ -1874,6 +1899,10 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> while (true) {
</span><ins>+ for (unsigned i = 0; i < m_setLocalQueue.size(); ++i)
+ m_setLocalQueue[i].execute(this);
+ m_setLocalQueue.resize(0);
+
</ins><span class="cx"> // Don't extend over jump destinations.
</span><span class="cx"> if (m_currentIndex == limit) {
</span><span class="cx"> // Ordinarily we want to plant a jump. But refuse to do this if the block is
</span><span class="lines">@@ -1905,7 +1934,7 @@
</span><span class="cx"> case op_enter:
</span><span class="cx"> // Initialize all locals to undefined.
</span><span class="cx"> for (int i = 0; i < m_inlineStackTop->m_codeBlock->m_numVars; ++i)
</span><del>- set(virtualRegisterForLocal(i), constantUndefined(), SetOnEntry);
</del><ins>+ set(virtualRegisterForLocal(i), constantUndefined(), ImmediateSet);
</ins><span class="cx"> NEXT_OPCODE(op_enter);
</span><span class="cx">
</span><span class="cx"> case op_touch_entry:
</span><span class="lines">@@ -2910,7 +2939,7 @@
</span><span class="cx"> flushArgumentsAndCapturedVariables();
</span><span class="cx"> if (inlineCallFrame()) {
</span><span class="cx"> ASSERT(m_inlineStackTop->m_returnValue.isValid());
</span><del>- setDirect(m_inlineStackTop->m_returnValue, get(VirtualRegister(currentInstruction[1].u.operand)));
</del><ins>+ setDirect(m_inlineStackTop->m_returnValue, get(VirtualRegister(currentInstruction[1].u.operand)), ImmediateSet);
</ins><span class="cx"> m_inlineStackTop->m_didReturn = true;
</span><span class="cx"> if (m_inlineStackTop->m_unlinkedBlocks.isEmpty()) {
</span><span class="cx"> // If we're returning from the first block, then we're done parsing.
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGCSEPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -135,8 +135,10 @@
</span><span class="cx"> if (node->op() != otherNode->op())
</span><span class="cx"> continue;
</span><span class="cx">
</span><del>- if (node->arithNodeFlags() != otherNode->arithNodeFlags())
- continue;
</del><ins>+ if (node->hasArithMode()) {
+ if (node->arithMode() != otherNode->arithMode())
+ continue;
+ }
</ins><span class="cx">
</span><span class="cx"> Edge otherChild = otherNode->child1();
</span><span class="cx"> if (!otherChild)
</span><span class="lines">@@ -1050,7 +1052,7 @@
</span><span class="cx"> if (!node)
</span><span class="cx"> return;
</span><span class="cx"> ASSERT(node->mustGenerate());
</span><del>- node->setOpAndDefaultNonExitFlags(phantomType);
</del><ins>+ node->setOpAndDefaultFlags(phantomType);
</ins><span class="cx"> if (phantomType == Phantom)
</span><span class="cx"> eliminateIrrelevantPhantomChildren(node);
</span><span class="cx">
</span><span class="lines">@@ -1081,7 +1083,6 @@
</span><span class="cx"> case ArithSub:
</span><span class="cx"> case ArithNegate:
</span><span class="cx"> case ArithMul:
</span><del>- case ArithIMul:
</del><span class="cx"> case ArithMod:
</span><span class="cx"> case ArithDiv:
</span><span class="cx"> case ArithAbs:
</span><span class="lines">@@ -1238,7 +1239,6 @@
</span><span class="cx">
</span><span class="cx"> // Handle nodes that are conditionally pure: these are pure, and can
</span><span class="cx"> // be CSE'd, so long as the prediction is the one we want.
</span><del>- case ValueAdd:
</del><span class="cx"> case CompareLess:
</span><span class="cx"> case CompareLessEq:
</span><span class="cx"> case CompareGreater:
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGClobberize.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -120,9 +120,9 @@
</span><span class="cx"> case ConstantStoragePointer:
</span><span class="cx"> case UInt32ToNumber:
</span><span class="cx"> case DoubleAsInt32:
</span><ins>+ case Check:
</ins><span class="cx"> return;
</span><span class="cx">
</span><del>- case MovHintAndCheck:
</del><span class="cx"> case MovHint:
</span><span class="cx"> case ZombieHint:
</span><span class="cx"> case Upsilon:
</span><span class="lines">@@ -197,25 +197,11 @@
</span><span class="cx"> case In:
</span><span class="cx"> case GetMyArgumentsLengthSafe:
</span><span class="cx"> case GetMyArgumentByValSafe:
</span><ins>+ case ValueAdd:
</ins><span class="cx"> read(World);
</span><span class="cx"> write(World);
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- case ValueAdd:
- switch (node->binaryUseKind()) {
- case Int32Use:
- case NumberUse:
- case MachineIntUse:
- return;
- case UntypedUse:
- read(World);
- write(World);
- return;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- return;
- }
-
</del><span class="cx"> case GetCallee:
</span><span class="cx"> read(AbstractHeap(Variables, JSStack::Callee));
</span><span class="cx"> return;
</span><span class="lines">@@ -577,30 +563,17 @@
</span><span class="cx"> }
</span><span class="cx"> return;
</span><span class="cx">
</span><ins>+ case CompareEq:
</ins><span class="cx"> case CompareLess:
</span><span class="cx"> case CompareLessEq:
</span><span class="cx"> case CompareGreater:
</span><span class="cx"> case CompareGreaterEq:
</span><del>- if (graph.isPredictedNumerical(node))
</del><ins>+ if (!node->isBinaryUseKind(UntypedUse))
</ins><span class="cx"> return;
</span><span class="cx"> read(World);
</span><span class="cx"> write(World);
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- case CompareEq:
- if (graph.isPredictedNumerical(node)
- || node->isBinaryUseKind(StringUse)
- || node->isBinaryUseKind(StringIdentUse))
- return;
-
- if ((node->child1().useKind() == ObjectUse || node->child1().useKind() == ObjectOrOtherUse)
- && (node->child2().useKind() == ObjectUse || node->child2().useKind() == ObjectOrOtherUse))
- return;
-
- read(World);
- write(World);
- return;
-
</del><span class="cx"> case ToString:
</span><span class="cx"> switch (node->child1().useKind()) {
</span><span class="cx"> case StringObjectUse:
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGCommonh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGCommon.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGCommon.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGCommon.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -182,8 +182,6 @@
</span><span class="cx">
</span><span class="cx"> enum OperandSpeculationMode { AutomaticOperandSpeculation, ManualOperandSpeculation };
</span><span class="cx">
</span><del>-enum SpeculationDirection { ForwardSpeculation, BackwardSpeculation };
-
</del><span class="cx"> enum ProofStatus { NeedsCheck, IsProved };
</span><span class="cx">
</span><span class="cx"> inline bool isProved(ProofStatus proofStatus)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -110,12 +110,8 @@
</span><span class="cx"> m_interpreter.execute(indexInBlock); // Catch the fact that we may filter on cell.
</span><span class="cx"> AdjacencyList children = node->children;
</span><span class="cx"> children.removeEdge(0);
</span><del>- if (!!children.child1()) {
- Node phantom(Phantom, node->codeOrigin, children);
- if (node->flags() & NodeExitsForward)
- phantom.mergeFlags(NodeExitsForward);
- m_insertionSet.insertNode(indexInBlock, SpecNone, phantom);
- }
</del><ins>+ if (!!children.child1())
+ m_insertionSet.insertNode(indexInBlock, SpecNone, Phantom, node->codeOrigin, children);
</ins><span class="cx"> node->children.setChild2(Edge());
</span><span class="cx"> node->children.setChild3(Edge());
</span><span class="cx"> node->convertToStructureTransitionWatchpoint(structure);
</span><span class="lines">@@ -340,6 +336,21 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> m_interpreter.execute(indexInBlock);
</span><ins>+ if (!m_state.isValid()) {
+ // If we invalidated then we shouldn't attempt to constant-fold. Here's an
+ // example:
+ //
+ // c: JSConstant(4.2)
+ // x: ValueToInt32(Check:Int32:@const)
+ //
+ // It would be correct for an analysis to assume that execution cannot
+ // proceed past @x. Therefore, constant-folding @x could be rather bad. But,
+ // the CFA may report that it found a constant even though it also reported
+ // that everything has been invalidated. This will only happen in a couple of
+ // the constant folding cases; most of them are also separately defensive
+ // about such things.
+ break;
+ }
</ins><span class="cx"> if (!node->shouldGenerate() || m_state.didClobber() || node->hasConstant())
</span><span class="cx"> continue;
</span><span class="cx"> JSValue value = m_state.forNode(node).value();
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGDCEPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -113,8 +113,12 @@
</span><span class="cx"> for (unsigned i = depthFirst.size(); i--;)
</span><span class="cx"> fixupBlock(depthFirst[i]);
</span><span class="cx"> } else {
</span><ins>+ RELEASE_ASSERT(m_graph.m_form == ThreadedCPS);
+
</ins><span class="cx"> for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
</span><span class="cx"> fixupBlock(m_graph.block(blockIndex));
</span><ins>+
+ cleanVariables(m_graph.m_arguments);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> m_graph.m_refCountState = ExactRefCount;
</span><span class="lines">@@ -152,6 +156,36 @@
</span><span class="cx"> {
</span><span class="cx"> if (!block)
</span><span class="cx"> return;
</span><ins>+
+ switch (m_graph.m_form) {
+ case SSA:
+ break;
+
+ case ThreadedCPS: {
+ // Clean up variable links for the block. We need to do this before the actual DCE
+ // because we need to see GetLocals, so we can bypass them in situations where the
+ // vars-at-tail point to a GetLocal, the GetLocal is dead, but the Phi it points
+ // to is alive.
+
+ for (unsigned phiIndex = 0; phiIndex < block->phis.size(); ++phiIndex) {
+ if (!block->phis[phiIndex]->shouldGenerate()) {
+ // FIXME: We could actually free nodes here. Except that it probably
+ // doesn't matter, since we don't add any nodes after this phase.
+ // https://bugs.webkit.org/show_bug.cgi?id=126239
+ block->phis[phiIndex--] = block->phis.last();
+ block->phis.removeLast();
+ }
+ }
+
+ cleanVariables(block->variablesAtHead);
+ cleanVariables(block->variablesAtTail);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return;
+ }
</ins><span class="cx">
</span><span class="cx"> for (unsigned indexInBlock = block->size(); indexInBlock--;) {
</span><span class="cx"> Node* node = block->at(indexInBlock);
</span><span class="lines">@@ -159,37 +193,23 @@
</span><span class="cx"> continue;
</span><span class="cx">
</span><span class="cx"> switch (node->op()) {
</span><del>- case SetLocal:
</del><span class="cx"> case MovHint: {
</span><del>- ASSERT((node->op() == SetLocal) == (m_graph.m_form == ThreadedCPS));
- if (node->child1().willNotHaveCheck()) {
- // Consider the possibility that UInt32ToNumber is dead but its
- // child isn't; if so then we should MovHint the child.
- if (!node->child1()->shouldGenerate()
- && permitsOSRBackwardRewiring(node->child1()->op()))
- node->child1() = node->child1()->child1();
-
- if (!node->child1()->shouldGenerate()) {
- node->setOpAndDefaultFlags(ZombieHint);
- node->child1() = Edge();
- break;
- }
- node->setOpAndDefaultFlags(MovHint);
</del><ins>+ ASSERT(node->child1().useKind() == UntypedUse);
+ if (!node->child1()->shouldGenerate()) {
+ node->setOpAndDefaultFlags(ZombieHint);
+ node->child1() = Edge();
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><del>- node->setOpAndDefaultFlags(MovHintAndCheck);
- node->setRefCount(1);
</del><ins>+ node->setOpAndDefaultFlags(MovHint);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
- case GetLocal:
- case SetArgument: {
- if (m_graph.m_form == ThreadedCPS) {
- // Leave them as not shouldGenerate.
- break;
- }
</del><ins>+
+ case ZombieHint: {
+ // Currently we assume that DCE runs only once.
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
</ins><span class="cx"> }
</span><del>-
</del><ins>+
</ins><span class="cx"> default: {
</span><span class="cx"> if (node->flags() & NodeHasVarArgs) {
</span><span class="cx"> for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++) {
</span><span class="lines">@@ -228,6 +248,27 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ template<typename VariablesVectorType>
+ void cleanVariables(VariablesVectorType& variables)
+ {
+ for (unsigned i = variables.size(); i--;) {
+ Node* node = variables[i];
+ if (!node)
+ continue;
+ if (node->op() != Phantom && node->shouldGenerate())
+ continue;
+ if (node->op() == GetLocal) {
+ node = node->child1().node();
+ ASSERT(node->op() == Phi || node->op() == SetArgument);
+ if (node->shouldGenerate()) {
+ variables[i] = node;
+ continue;
+ }
+ }
+ variables[i] = 0;
+ }
+ }
+
</ins><span class="cx"> Vector<Node*, 128> m_worklist;
</span><span class="cx"> InsertionSet m_insertionSet;
</span><span class="cx"> };
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -103,10 +103,19 @@
</span><span class="cx"> case BitXor:
</span><span class="cx"> case BitRShift:
</span><span class="cx"> case BitLShift:
</span><del>- case BitURShift:
</del><ins>+ case BitURShift: {
+ fixIntEdge(node->child1());
+ fixIntEdge(node->child2());
+ break;
+ }
+
</ins><span class="cx"> case ArithIMul: {
</span><span class="cx"> fixIntEdge(node->child1());
</span><span class="cx"> fixIntEdge(node->child2());
</span><ins>+ node->setOp(ArithMul);
+ node->setArithMode(Arith::Unchecked);
+ node->child1().setUseKind(Int32Use);
+ node->child2().setUseKind(Int32Use);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -114,6 +123,10 @@
</span><span class="cx"> fixEdge<KnownInt32Use>(node->child1());
</span><span class="cx"> if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
</span><span class="cx"> node->convertToIdentity();
</span><ins>+ else if (nodeCanSpeculateInt32(node->arithNodeFlags()))
+ node->setArithMode(Arith::CheckOverflow);
+ else
+ node->setArithMode(Arith::DoOverflow);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -154,11 +167,16 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case ValueAdd: {
</span><del>- if (attemptToMakeIntegerAdd(node))
</del><ins>+ if (attemptToMakeIntegerAdd(node)) {
+ node->setOp(ArithAdd);
+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><ins>+ }
</ins><span class="cx"> if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
</span><span class="cx"> fixEdge<NumberUse>(node->child1());
</span><span class="cx"> fixEdge<NumberUse>(node->child2());
</span><ins>+ node->setOp(ArithAdd);
+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -205,10 +223,20 @@
</span><span class="cx"> case ArithNegate: {
</span><span class="cx"> if (m_graph.negateShouldSpeculateInt32(node)) {
</span><span class="cx"> fixEdge<Int32Use>(node->child1());
</span><ins>+ if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
+ node->setArithMode(Arith::Unchecked);
+ else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+ node->setArithMode(Arith::CheckOverflow);
+ else
+ node->setArithMode(Arith::CheckOverflowAndNegativeZero);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (m_graph.negateShouldSpeculateMachineInt(node)) {
</span><span class="cx"> fixEdge<MachineIntUse>(node->child1());
</span><ins>+ if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+ node->setArithMode(Arith::CheckOverflow);
+ else
+ node->setArithMode(Arith::CheckOverflowAndNegativeZero);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> fixEdge<NumberUse>(node->child1());
</span><span class="lines">@@ -219,11 +247,21 @@
</span><span class="cx"> if (m_graph.mulShouldSpeculateInt32(node)) {
</span><span class="cx"> fixEdge<Int32Use>(node->child1());
</span><span class="cx"> fixEdge<Int32Use>(node->child2());
</span><ins>+ if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
+ node->setArithMode(Arith::Unchecked);
+ else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+ node->setArithMode(Arith::CheckOverflow);
+ else
+ node->setArithMode(Arith::CheckOverflowAndNegativeZero);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (m_graph.mulShouldSpeculateMachineInt(node)) {
</span><span class="cx"> fixEdge<MachineIntUse>(node->child1());
</span><span class="cx"> fixEdge<MachineIntUse>(node->child2());
</span><ins>+ if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+ node->setArithMode(Arith::CheckOverflow);
+ else
+ node->setArithMode(Arith::CheckOverflowAndNegativeZero);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> fixEdge<NumberUse>(node->child1());
</span><span class="lines">@@ -238,6 +276,12 @@
</span><span class="cx"> if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7s()) {
</span><span class="cx"> fixEdge<Int32Use>(node->child1());
</span><span class="cx"> fixEdge<Int32Use>(node->child2());
</span><ins>+ if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
+ node->setArithMode(Arith::Unchecked);
+ else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+ node->setArithMode(Arith::CheckOverflow);
+ else
+ node->setArithMode(Arith::CheckOverflowAndNegativeZero);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> Edge child1 = node->child1();
</span><span class="lines">@@ -253,6 +297,10 @@
</span><span class="cx">
</span><span class="cx"> node->setOp(DoubleAsInt32);
</span><span class="cx"> node->children.initialize(Edge(newDivision, KnownNumberUse), Edge(), Edge());
</span><ins>+ if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+ node->setArithMode(Arith::CheckOverflow);
+ else
+ node->setArithMode(Arith::CheckOverflowAndNegativeZero);
</ins><span class="cx">
</span><span class="cx"> m_insertionSet.insertNode(m_indexInBlock + 1, SpecNone, Phantom, node->codeOrigin, child1, child2);
</span><span class="cx"> break;
</span><span class="lines">@@ -326,17 +374,20 @@
</span><span class="cx"> if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
</span><span class="cx"> fixEdge<Int32Use>(node->child1());
</span><span class="cx"> fixEdge<Int32Use>(node->child2());
</span><ins>+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (enableInt52()
</span><span class="cx"> && Node::shouldSpeculateMachineInt(node->child1().node(), node->child2().node())) {
</span><span class="cx"> fixEdge<MachineIntUse>(node->child1());
</span><span class="cx"> fixEdge<MachineIntUse>(node->child2());
</span><ins>+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
</span><span class="cx"> fixEdge<NumberUse>(node->child1());
</span><span class="cx"> fixEdge<NumberUse>(node->child2());
</span><ins>+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (node->op() != CompareEq)
</span><span class="lines">@@ -344,31 +395,37 @@
</span><span class="cx"> if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
</span><span class="cx"> fixEdge<BooleanUse>(node->child1());
</span><span class="cx"> fixEdge<BooleanUse>(node->child2());
</span><ins>+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
</span><span class="cx"> fixEdge<StringIdentUse>(node->child1());
</span><span class="cx"> fixEdge<StringIdentUse>(node->child2());
</span><ins>+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
</span><span class="cx"> fixEdge<StringUse>(node->child1());
</span><span class="cx"> fixEdge<StringUse>(node->child2());
</span><ins>+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
</span><span class="cx"> fixEdge<ObjectUse>(node->child1());
</span><span class="cx"> fixEdge<ObjectUse>(node->child2());
</span><ins>+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
</span><span class="cx"> fixEdge<ObjectUse>(node->child1());
</span><span class="cx"> fixEdge<ObjectOrOtherUse>(node->child2());
</span><ins>+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
</span><span class="cx"> fixEdge<ObjectOrOtherUse>(node->child1());
</span><span class="cx"> fixEdge<ObjectUse>(node->child2());
</span><ins>+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> break;
</span><span class="lines">@@ -853,7 +910,8 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case Phantom:
</span><del>- case Identity: {
</del><ins>+ case Identity:
+ case Check: {
</ins><span class="cx"> switch (node->child1().useKind()) {
</span><span class="cx"> case NumberUse:
</span><span class="cx"> if (node->child1()->shouldSpeculateInt32ForArithmetic())
</span><span class="lines">@@ -874,9 +932,6 @@
</span><span class="cx"> case GetIndexedPropertyStorage:
</span><span class="cx"> case GetTypedArrayByteOffset:
</span><span class="cx"> case LastNodeType:
</span><del>- case MovHint:
- case MovHintAndCheck:
- case ZombieHint:
</del><span class="cx"> case CheckTierUpInLoop:
</span><span class="cx"> case CheckTierUpAtReturn:
</span><span class="cx"> case CheckTierUpAndOSREnter:
</span><span class="lines">@@ -900,7 +955,7 @@
</span><span class="cx"> observeUseKindOnNode<StringUse>(node);
</span><span class="cx"> }
</span><span class="cx"> break;
</span><del>-
</del><ins>+
</ins><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx"> // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
</span><span class="cx"> case SetArgument:
</span><span class="lines">@@ -953,6 +1008,8 @@
</span><span class="cx"> case LoopHint:
</span><span class="cx"> case FunctionReentryWatchpoint:
</span><span class="cx"> case TypedArrayWatchpoint:
</span><ins>+ case MovHint:
+ case ZombieHint:
</ins><span class="cx"> break;
</span><span class="cx"> #else
</span><span class="cx"> default:
</span><span class="lines">@@ -960,7 +1017,8 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><del>- DFG_NODE_DO_TO_CHILDREN(m_graph, node, observeUntypedEdge);
</del><ins>+ if (!node->containsMovHint())
+ DFG_NODE_DO_TO_CHILDREN(m_graph, node, observeUntypedEdge);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void observeUntypedEdge(Node*, Edge& edge)
</span><span class="lines">@@ -1426,7 +1484,7 @@
</span><span class="cx"> {
</span><span class="cx"> if (isDouble(useKind)) {
</span><span class="cx"> if (edge->shouldSpeculateInt32ForArithmetic()) {
</span><del>- injectInt32ToDoubleNode(edge, useKind, m_currentNode->speculationDirection());
</del><ins>+ injectInt32ToDoubleNode(edge, useKind);
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1439,7 +1497,6 @@
</span><span class="cx"> Node* result = m_insertionSet.insertNode(
</span><span class="cx"> m_indexInBlock, SpecInt52AsDouble, Int52ToDouble,
</span><span class="cx"> m_currentNode->codeOrigin, Edge(edge.node(), NumberUse));
</span><del>- result->setSpeculationDirection(m_currentNode->speculationDirection());
</del><span class="cx"> edge = Edge(result, useKind);
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="lines">@@ -1493,7 +1550,6 @@
</span><span class="cx"> Node* result = m_insertionSet.insertNode(
</span><span class="cx"> m_indexInBlock, SpecInt52, Int52ToValue,
</span><span class="cx"> m_currentNode->codeOrigin, Edge(edge.node(), UntypedUse));
</span><del>- result->setSpeculationDirection(m_currentNode->speculationDirection());
</del><span class="cx"> edge = Edge(result, useKind);
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="lines">@@ -1522,13 +1578,11 @@
</span><span class="cx"> edge = newEdge;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void injectInt32ToDoubleNode(Edge& edge, UseKind useKind = NumberUse, SpeculationDirection direction = BackwardSpeculation)
</del><ins>+ void injectInt32ToDoubleNode(Edge& edge, UseKind useKind = NumberUse)
</ins><span class="cx"> {
</span><span class="cx"> Node* result = m_insertionSet.insertNode(
</span><span class="cx"> m_indexInBlock, SpecInt52AsDouble, Int32ToDouble,
</span><span class="cx"> m_currentNode->codeOrigin, Edge(edge.node(), NumberUse));
</span><del>- if (direction == ForwardSpeculation)
- result->mergeFlags(NodeExitsForward);
</del><span class="cx">
</span><span class="cx"> edge = Edge(result, useKind);
</span><span class="cx"> }
</span><span class="lines">@@ -1579,12 +1633,17 @@
</span><span class="cx"> truncateConstantsIfNecessary(node, mode);
</span><span class="cx"> fixEdge<Int32Use>(node->child1());
</span><span class="cx"> fixEdge<Int32Use>(node->child2());
</span><ins>+ if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
+ node->setArithMode(Arith::Unchecked);
+ else
+ node->setArithMode(Arith::CheckOverflow);
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (m_graph.addShouldSpeculateMachineInt(node)) {
</span><span class="cx"> fixEdge<MachineIntUse>(node->child1());
</span><span class="cx"> fixEdge<MachineIntUse>(node->child2());
</span><ins>+ node->setArithMode(Arith::CheckOverflow);
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGFlushFormatcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -56,6 +56,9 @@
</span><span class="cx"> case FlushedJSValue:
</span><span class="cx"> out.print("FlushedJSValue");
</span><span class="cx"> return;
</span><ins>+ case FlushedArguments:
+ out.print("FlushedArguments");
+ return;
</ins><span class="cx"> case ConflictingFlush:
</span><span class="cx"> out.print("ConflictingFlush");
</span><span class="cx"> return;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGFlushFormath"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGFlushFormat.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGFlushFormat.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGFlushFormat.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> FlushedCell,
</span><span class="cx"> FlushedBoolean,
</span><span class="cx"> FlushedJSValue,
</span><ins>+ FlushedArguments,
</ins><span class="cx"> ConflictingFlush
</span><span class="cx"> };
</span><span class="cx">
</span><span class="lines">@@ -56,6 +57,7 @@
</span><span class="cx"> case FlushedJSValue:
</span><span class="cx"> case FlushedCell:
</span><span class="cx"> case ConflictingFlush:
</span><ins>+ case FlushedArguments:
</ins><span class="cx"> return NodeResultJS;
</span><span class="cx"> case FlushedInt32:
</span><span class="cx"> return NodeResultInt32;
</span><span class="lines">@@ -76,6 +78,7 @@
</span><span class="cx"> case DeadFlush:
</span><span class="cx"> case FlushedJSValue:
</span><span class="cx"> case ConflictingFlush:
</span><ins>+ case FlushedArguments:
</ins><span class="cx"> return UntypedUse;
</span><span class="cx"> case FlushedCell:
</span><span class="cx"> return CellUse;
</span><span class="lines">@@ -110,6 +113,8 @@
</span><span class="cx"> return DataFormatCell;
</span><span class="cx"> case FlushedBoolean:
</span><span class="cx"> return DataFormatBoolean;
</span><ins>+ case FlushedArguments:
+ return DataFormatArguments;
</ins><span class="cx"> }
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> return DataFormatDead;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGGraph.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -200,6 +200,8 @@
</span><span class="cx"> out.print(comma, SpeculationDump(node->prediction()));
</span><span class="cx"> if (node->hasArrayMode())
</span><span class="cx"> out.print(comma, node->arrayMode());
</span><ins>+ if (node->hasArithMode())
+ out.print(comma, node->arithMode());
</ins><span class="cx"> if (node->hasVarNumber())
</span><span class="cx"> out.print(comma, node->varNumber());
</span><span class="cx"> if (node->hasRegisterPointer())
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGGraph.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGGraph.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGGraph.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -648,13 +648,6 @@
</span><span class="cx"> if (!(node->flags() & NodeMightClobber))
</span><span class="cx"> return false;
</span><span class="cx"> switch (node->op()) {
</span><del>- case ValueAdd:
- case CompareLess:
- case CompareLessEq:
- case CompareGreater:
- case CompareGreaterEq:
- case CompareEq:
- return !isPredictedNumerical(node);
</del><span class="cx"> case GetByVal:
</span><span class="cx"> case PutByValDirect:
</span><span class="cx"> case PutByVal:
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGLICMPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -128,7 +128,6 @@
</span><span class="cx"> // time and preserve some kind of sanity, if we hoist something that must exit.
</span><span class="cx"> //
</span><span class="cx"> // Also, we need to remember to:
</span><del>- // - Clear NodeExitsForward for any nodes we hoisted.
</del><span class="cx"> // - Update the state-at-tail with the node we hoisted, so future hoist candidates
</span><span class="cx"> // know about any type checks we hoisted.
</span><span class="cx"> //
</span><span class="lines">@@ -230,8 +229,6 @@
</span><span class="cx">
</span><span class="cx"> data.preHeader->insertBeforeLast(node);
</span><span class="cx"> node->misc.owner = data.preHeader;
</span><del>- NodeFlags didExitForward = node->flags() & NodeExitsForward;
- node->clearFlags(NodeExitsForward);
</del><span class="cx"> node->codeOriginForExitTarget = data.preHeader->last()->codeOriginForExitTarget;
</span><span class="cx">
</span><span class="cx"> // Modify the states at the end of the preHeader of the loop we hoisted to,
</span><span class="lines">@@ -256,7 +253,6 @@
</span><span class="cx"> RELEASE_ASSERT(!(node->flags() & NodeHasVarArgs));
</span><span class="cx">
</span><span class="cx"> nodeRef = m_graph.addNode(SpecNone, Phantom, node->codeOrigin, node->children);
</span><del>- nodeRef->mergeFlags(didExitForward);
</del><span class="cx">
</span><span class="cx"> return true;
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGMinifiedNodecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -38,15 +38,13 @@
</span><span class="cx"> MinifiedNode result;
</span><span class="cx"> result.m_id = MinifiedID(node);
</span><span class="cx"> result.m_op = node->op();
</span><del>- if (hasChild(node->op()))
- result.m_childOrInfo = MinifiedID(node->child1().node()).m_id;
- else if (hasConstantNumber(node->op()))
- result.m_childOrInfo = node->constantNumber();
</del><ins>+ if (hasConstantNumber(node->op()))
+ result.m_info = node->constantNumber();
</ins><span class="cx"> else if (hasWeakConstant(node->op()))
</span><del>- result.m_childOrInfo = bitwise_cast<uintptr_t>(node->weakConstant());
</del><ins>+ result.m_info = bitwise_cast<uintptr_t>(node->weakConstant());
</ins><span class="cx"> else {
</span><span class="cx"> ASSERT(node->op() == PhantomArguments);
</span><del>- result.m_childOrInfo = 0;
</del><ins>+ result.m_info = 0;
</ins><span class="cx"> }
</span><span class="cx"> return result;
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGMinifiedNodeh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGMinifiedNode.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGMinifiedNode.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGMinifiedNode.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -43,16 +43,9 @@
</span><span class="cx"> switch (type) {
</span><span class="cx"> case JSConstant:
</span><span class="cx"> case WeakJSConstant:
</span><del>- case ValueToInt32:
- case Int32ToDouble:
- case UInt32ToNumber:
- case DoubleAsInt32:
</del><span class="cx"> case PhantomArguments:
</span><del>- case Int52ToValue:
- case Int52ToDouble:
</del><span class="cx"> return true;
</span><span class="cx"> default:
</span><del>- ASSERT(!permitsOSRBackwardRewiring(type) && !permitsOSRForwardRewiring(type));
</del><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -66,14 +59,6 @@
</span><span class="cx"> MinifiedID id() const { return m_id; }
</span><span class="cx"> NodeType op() const { return m_op; }
</span><span class="cx">
</span><del>- bool hasChild1() const { return hasChild(m_op); }
-
- MinifiedID child1() const
- {
- ASSERT(hasChild(m_op));
- return MinifiedID::fromBits(m_childOrInfo);
- }
-
</del><span class="cx"> bool hasConstant() const { return hasConstantNumber() || hasWeakConstant(); }
</span><span class="cx">
</span><span class="cx"> bool hasConstantNumber() const { return hasConstantNumber(m_op); }
</span><span class="lines">@@ -81,7 +66,7 @@
</span><span class="cx"> unsigned constantNumber() const
</span><span class="cx"> {
</span><span class="cx"> ASSERT(hasConstantNumber(m_op));
</span><del>- return m_childOrInfo;
</del><ins>+ return m_info;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool hasWeakConstant() const { return hasWeakConstant(m_op); }
</span><span class="lines">@@ -89,7 +74,7 @@
</span><span class="cx"> JSCell* weakConstant() const
</span><span class="cx"> {
</span><span class="cx"> ASSERT(hasWeakConstant(m_op));
</span><del>- return bitwise_cast<JSCell*>(m_childOrInfo);
</del><ins>+ return bitwise_cast<JSCell*>(m_info);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> static MinifiedID getID(MinifiedNode* node) { return node->id(); }
</span><span class="lines">@@ -99,20 +84,6 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- static bool hasChild(NodeType type)
- {
- switch (type) {
- case ValueToInt32:
- case Int32ToDouble:
- case UInt32ToNumber:
- case DoubleAsInt32:
- case Int52ToDouble:
- case Int52ToValue:
- return true;
- default:
- return false;
- }
- }
</del><span class="cx"> static bool hasConstantNumber(NodeType type)
</span><span class="cx"> {
</span><span class="cx"> return type == JSConstant;
</span><span class="lines">@@ -123,7 +94,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> MinifiedID m_id;
</span><del>- uintptr_t m_childOrInfo; // Nodes in the minified graph have only one child each.
</del><ins>+ uintptr_t m_info;
</ins><span class="cx"> NodeType m_op;
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGNodecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGNode.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGNode.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGNode.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -46,9 +46,6 @@
</span><span class="cx"> case GetLocal:
</span><span class="cx"> case GetArgument:
</span><span class="cx"> case SetLocal:
</span><del>- case MovHint:
- case MovHintAndCheck:
- case ZombieHint:
</del><span class="cx"> case SetArgument:
</span><span class="cx"> case Flush:
</span><span class="cx"> case PhantomLocal:
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGNode.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGNode.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGNode.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include "CodeOrigin.h"
</span><span class="cx"> #include "DFGAbstractValue.h"
</span><span class="cx"> #include "DFGAdjacencyList.h"
</span><ins>+#include "DFGArithMode.h"
</ins><span class="cx"> #include "DFGArrayMode.h"
</span><span class="cx"> #include "DFGCommon.h"
</span><span class="cx"> #include "DFGLazyJSValue.h"
</span><span class="lines">@@ -180,6 +181,8 @@
</span><span class="cx"> , m_virtualRegister(VirtualRegister())
</span><span class="cx"> , m_refCount(1)
</span><span class="cx"> , m_prediction(SpecNone)
</span><ins>+ , m_opInfo(0)
+ , m_opInfo2(0)
</ins><span class="cx"> {
</span><span class="cx"> misc.replacement = 0;
</span><span class="cx"> setOpAndDefaultFlags(op);
</span><span class="lines">@@ -195,6 +198,7 @@
</span><span class="cx"> , m_refCount(1)
</span><span class="cx"> , m_prediction(SpecNone)
</span><span class="cx"> , m_opInfo(imm.m_value)
</span><ins>+ , m_opInfo2(0)
</ins><span class="cx"> {
</span><span class="cx"> misc.replacement = 0;
</span><span class="cx"> setOpAndDefaultFlags(op);
</span><span class="lines">@@ -274,59 +278,27 @@
</span><span class="cx"> return filterFlags(~flags);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- SpeculationDirection speculationDirection()
- {
- if (flags() & NodeExitsForward)
- return ForwardSpeculation;
- return BackwardSpeculation;
- }
-
- void setSpeculationDirection(SpeculationDirection direction)
- {
- switch (direction) {
- case ForwardSpeculation:
- mergeFlags(NodeExitsForward);
- return;
- case BackwardSpeculation:
- clearFlags(NodeExitsForward);
- return;
- }
- RELEASE_ASSERT_NOT_REACHED();
- }
-
</del><span class="cx"> void setOpAndDefaultFlags(NodeType op)
</span><span class="cx"> {
</span><span class="cx"> m_op = op;
</span><span class="cx"> m_flags = defaultFlags(op);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void setOpAndDefaultNonExitFlags(NodeType op)
- {
- ASSERT(!(m_flags & NodeHasVarArgs));
- setOpAndDefaultNonExitFlagsUnchecked(op);
- }
-
- void setOpAndDefaultNonExitFlagsUnchecked(NodeType op)
- {
- m_op = op;
- m_flags = (defaultFlags(op) & ~NodeExitsForward) | (m_flags & NodeExitsForward);
- }
-
</del><span class="cx"> void convertToPhantom()
</span><span class="cx"> {
</span><del>- setOpAndDefaultNonExitFlags(Phantom);
</del><ins>+ setOpAndDefaultFlags(Phantom);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void convertToPhantomUnchecked()
</span><span class="cx"> {
</span><del>- setOpAndDefaultNonExitFlagsUnchecked(Phantom);
</del><ins>+ setOpAndDefaultFlags(Phantom);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void convertToIdentity()
</span><span class="cx"> {
</span><span class="cx"> RELEASE_ASSERT(child1());
</span><span class="cx"> RELEASE_ASSERT(!child2());
</span><del>- setOpAndDefaultNonExitFlags(Identity);
</del><ins>+ setOpAndDefaultFlags(Identity);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool mustGenerate()
</span><span class="lines">@@ -531,9 +503,7 @@
</span><span class="cx"> bool containsMovHint()
</span><span class="cx"> {
</span><span class="cx"> switch (op()) {
</span><del>- case SetLocal:
</del><span class="cx"> case MovHint:
</span><del>- case MovHintAndCheck:
</del><span class="cx"> case ZombieHint:
</span><span class="cx"> return true;
</span><span class="cx"> default:
</span><span class="lines">@@ -567,6 +537,8 @@
</span><span class="cx"> switch (op()) {
</span><span class="cx"> case GetLocalUnlinked:
</span><span class="cx"> case ExtractOSREntryLocal:
</span><ins>+ case MovHint:
+ case ZombieHint:
</ins><span class="cx"> return true;
</span><span class="cx"> default:
</span><span class="cx"> return false;
</span><span class="lines">@@ -1138,6 +1110,34 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ bool hasArithMode()
+ {
+ switch (op()) {
+ case ArithAdd:
+ case ArithSub:
+ case ArithNegate:
+ case ArithMul:
+ case ArithDiv:
+ case ArithMod:
+ case UInt32ToNumber:
+ case DoubleAsInt32:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ Arith::Mode arithMode()
+ {
+ ASSERT(hasArithMode());
+ return static_cast<Arith::Mode>(m_opInfo);
+ }
+
+ void setArithMode(Arith::Mode mode)
+ {
+ m_opInfo = mode;
+ }
+
</ins><span class="cx"> bool hasVirtualRegister()
</span><span class="cx"> {
</span><span class="cx"> return m_virtualRegister.isValid();
</span><span class="lines">@@ -1178,11 +1178,6 @@
</span><span class="cx"> case SetLocal:
</span><span class="cx"> case MovHint:
</span><span class="cx"> case ZombieHint:
</span><del>- case MovHintAndCheck:
- case Int32ToDouble:
- case ValueToInt32:
- case UInt32ToNumber:
- case DoubleAsInt32:
</del><span class="cx"> case PhantomArguments:
</span><span class="cx"> return true;
</span><span class="cx"> case Phantom:
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGNodeFlagscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -96,9 +96,6 @@
</span><span class="cx"> if (!(flags & NodeDoesNotExit))
</span><span class="cx"> out.print(comma, "CanExit");
</span><span class="cx">
</span><del>- if (flags & NodeExitsForward)
- out.print(comma, "NodeExitsForward");
-
</del><span class="cx"> CString string = out.toCString();
</span><span class="cx"> if (!string.length())
</span><span class="cx"> actualOut.print("<empty>");
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGNodeFlagsh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeFlags.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeFlags.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeFlags.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -68,10 +68,8 @@
</span><span class="cx">
</span><span class="cx"> #define NodeRelevantToOSR 0x4000
</span><span class="cx">
</span><del>-#define NodeExitsForward 0x8000
</del><ins>+#define NodeIsStaticConstant 0x8000 // Used only by the parser, to determine if a constant arose statically and hence could be folded at parse-time.
</ins><span class="cx">
</span><del>-#define NodeIsStaticConstant 0x10000 // Used only by the parser, to determine if a constant arose statically and hence could be folded at parse-time.
-
</del><span class="cx"> typedef uint32_t NodeFlags;
</span><span class="cx">
</span><span class="cx"> static inline bool bytecodeUsesAsNumber(NodeFlags flags)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeType.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -57,12 +57,12 @@
</span><span class="cx"> /* Any two nodes that are part of the same Phi graph will share the same */\
</span><span class="cx"> /* VariableAccessData, and thus will share predictions. */\
</span><span class="cx"> macro(GetLocal, NodeResultJS) \
</span><del>- macro(SetLocal, NodeExitsForward) \
- macro(MovHintAndCheck, NodeMustGenerate | NodeExitsForward) \
</del><ins>+ macro(SetLocal, 0) \
</ins><span class="cx"> macro(MovHint, NodeDoesNotExit) \
</span><span class="cx"> macro(ZombieHint, NodeDoesNotExit) \
</span><span class="cx"> macro(GetArgument, NodeResultJS | NodeMustGenerate) \
</span><span class="cx"> macro(Phantom, NodeMustGenerate) \
</span><ins>+ macro(Check, 0) /* Used if we want just a type check but not liveness. DCE eithers kills this or converts it to Phantom. */\
</ins><span class="cx"> macro(Upsilon, NodeDoesNotExit | NodeRelevantToOSR) \
</span><span class="cx"> macro(Phi, NodeDoesNotExit | NodeRelevantToOSR) \
</span><span class="cx"> macro(Flush, NodeMustGenerate | NodeDoesNotExit) \
</span><span class="lines">@@ -96,12 +96,12 @@
</span><span class="cx"> macro(InvalidationPoint, NodeMustGenerate) \
</span><span class="cx"> \
</span><span class="cx"> /* Nodes for bitwise operations. */\
</span><del>- macro(BitAnd, NodeResultInt32 | NodeMustGenerate) \
- macro(BitOr, NodeResultInt32 | NodeMustGenerate) \
- macro(BitXor, NodeResultInt32 | NodeMustGenerate) \
- macro(BitLShift, NodeResultInt32 | NodeMustGenerate) \
- macro(BitRShift, NodeResultInt32 | NodeMustGenerate) \
- macro(BitURShift, NodeResultInt32 | NodeMustGenerate) \
</del><ins>+ macro(BitAnd, NodeResultInt32) \
+ macro(BitOr, NodeResultInt32) \
+ macro(BitXor, NodeResultInt32) \
+ macro(BitLShift, NodeResultInt32) \
+ macro(BitRShift, NodeResultInt32) \
+ macro(BitURShift, NodeResultInt32) \
</ins><span class="cx"> /* Bitwise operators call ToInt32 on their operands. */\
</span><span class="cx"> macro(ValueToInt32, NodeResultInt32) \
</span><span class="cx"> /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
</span><span class="lines">@@ -118,22 +118,22 @@
</span><span class="cx"> macro(Int52ToDouble, NodeResultNumber) \
</span><span class="cx"> \
</span><span class="cx"> /* Nodes for arithmetic operations. */\
</span><del>- macro(ArithAdd, NodeResultNumber | NodeMustGenerate) \
- macro(ArithSub, NodeResultNumber | NodeMustGenerate) \
- macro(ArithNegate, NodeResultNumber | NodeMustGenerate) \
- macro(ArithMul, NodeResultNumber | NodeMustGenerate) \
- macro(ArithIMul, NodeResultInt32 | NodeMustGenerate) \
- macro(ArithDiv, NodeResultNumber | NodeMustGenerate) \
- macro(ArithMod, NodeResultNumber | NodeMustGenerate) \
- macro(ArithAbs, NodeResultNumber | NodeMustGenerate) \
- macro(ArithMin, NodeResultNumber | NodeMustGenerate) \
- macro(ArithMax, NodeResultNumber | NodeMustGenerate) \
- macro(ArithSqrt, NodeResultNumber | NodeMustGenerate) \
- macro(ArithSin, NodeResultNumber | NodeMustGenerate) \
- macro(ArithCos, NodeResultNumber | NodeMustGenerate) \
</del><ins>+ macro(ArithAdd, NodeResultNumber) \
+ macro(ArithSub, NodeResultNumber) \
+ macro(ArithNegate, NodeResultNumber) \
+ macro(ArithMul, NodeResultNumber) \
+ macro(ArithIMul, NodeResultInt32) \
+ macro(ArithDiv, NodeResultNumber) \
+ macro(ArithMod, NodeResultNumber) \
+ macro(ArithAbs, NodeResultNumber) \
+ macro(ArithMin, NodeResultNumber) \
+ macro(ArithMax, NodeResultNumber) \
+ macro(ArithSqrt, NodeResultNumber) \
+ macro(ArithSin, NodeResultNumber) \
+ macro(ArithCos, NodeResultNumber) \
</ins><span class="cx"> \
</span><span class="cx"> /* Add of values may either be arithmetic, or result in string concatenation. */\
</span><del>- macro(ValueAdd, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
</del><ins>+ macro(ValueAdd, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
</ins><span class="cx"> \
</span><span class="cx"> /* Property access. */\
</span><span class="cx"> /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\
</span><span class="lines">@@ -208,12 +208,12 @@
</span><span class="cx"> macro(StringFromCharCode, NodeResultJS) \
</span><span class="cx"> \
</span><span class="cx"> /* Nodes for comparison operations. */\
</span><del>- macro(CompareLess, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
- macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
- macro(CompareGreater, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
- macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
- macro(CompareEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
- macro(CompareEqConstant, NodeResultBoolean | NodeMustGenerate) \
</del><ins>+ macro(CompareLess, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
+ macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
+ macro(CompareGreater, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
+ macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
+ macro(CompareEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
+ macro(CompareEqConstant, NodeResultBoolean) \
</ins><span class="cx"> macro(CompareStrictEq, NodeResultBoolean) \
</span><span class="cx"> macro(CompareStrictEqConstant, NodeResultBoolean) \
</span><span class="cx"> \
</span><span class="lines">@@ -314,80 +314,6 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline bool permitsOSRBackwardRewiring(NodeType op)
-{
- switch (op) {
- case Identity:
- RELEASE_ASSERT_NOT_REACHED();
- return true;
- case UInt32ToNumber:
- case Int52ToValue:
- case Int52ToDouble:
- // These are the only node where we do:
- //
- // b: UInt32ToNumber(@a)
- // c: SetLocal(@b)
- //
- // and then also have some uses of @a without Phantom'ing @b.
- return true;
- default:
- return false;
- }
-}
-
-// Returns the priority with which we should select the given node for forward
-// rewiring. Higher is better. Zero means that the node is not useful for rewiring.
-// By convention, we use 100 to mean that the node is totally equivalent to its
-// input with no information loss.
-inline unsigned forwardRewiringSelectionScore(NodeType op)
-{
- switch (op) {
- case Identity:
- // We shouldn't see these by the time we get to OSR even though it clearly
- // is a perfect identity function.
- RELEASE_ASSERT_NOT_REACHED();
- return 100;
-
- case DoubleAsInt32:
- // This speculates that the incoming double is convertible to an int32. So
- // its result is totally equivalent.
- return 100;
-
- case Int32ToDouble:
- // This converts an int32 to a double, but that loses a bit of information.
- // OTOH it's still an equivalent number.
- return 75;
-
- case UInt32ToNumber:
- // It's completely fine to use this for OSR exit, since the uint32 isn't
- // actually representable in bytecode.
- return 100;
-
- case ValueToInt32:
- // This loses information. Only use it if there are no better alternatives.
- return 25;
-
- case Int52ToValue:
- // Loses no information. It just boxes the value, which is what OSR wants
- // to do anyway.
- return 100;
-
- case Int52ToDouble:
- // This is like Int32ToDouble; we can use it because it gives a semantically
- // equivalent value but that value may be an int32 in a double, so we'd
- // rather not if we can avoid it.
- return 75;
-
- default:
- return 0;
- }
-}
-
-inline bool permitsOSRForwardRewiring(NodeType op)
-{
- return forwardRewiringSelectionScore(op) > 0;
-}
-
</del><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGOSRAvailabilityAnalysisPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -103,17 +103,15 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case MovHint:
- case MovHintAndCheck: {
- VariableAccessData* variable = node->variableAccessData();
- availability.operand(variable->local()) =
</del><ins>+ case MovHint: {
+ availability.operand(node->unlinkedLocal()) =
</ins><span class="cx"> Availability(node->child1().node());
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case ZombieHint: {
</span><del>- VariableAccessData* variable = node->variableAccessData();
- availability.operand(variable->local()) = Availability::unavailable();
</del><ins>+ availability.operand(node->unlinkedLocal()) =
+ Availability::unavailable();
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGOSREntrypointCreationPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -104,17 +104,9 @@
</span><span class="cx"> m_graph, variable->prediction(), ExtractOSREntryLocal, codeOrigin,
</span><span class="cx"> OpInfo(variable->local().offset()));
</span><span class="cx">
</span><del>- // Create a MovHint. We can't use MovHint's directly at this stage of
- // compilation, so we cook one up by creating a new VariableAccessData
- // that isn't unified with any of the others. This ensures that this
- // SetLocal will turn into a MovHint and will not have any type checks.
- m_graph.m_variableAccessData.append(
- VariableAccessData(variable->local(), variable->isCaptured()));
- VariableAccessData* newVariable = &m_graph.m_variableAccessData.last();
- Node* setLocal = newRoot->appendNode(
- m_graph, SpecNone, SetLocal, codeOrigin, OpInfo(newVariable),
</del><ins>+ newRoot->appendNode(
+ m_graph, SpecNone, MovHint, codeOrigin, OpInfo(variable->local().offset()),
</ins><span class="cx"> Edge(locals[local]));
</span><del>- setLocal->setSpeculationDirection(BackwardSpeculation);
</del><span class="cx"> }
</span><span class="cx"> for (int local = 0; local < baseline->m_numCalleeRegisters; ++local) {
</span><span class="cx"> Node* previousHead = target->variablesAtHead.local(local);
</span><span class="lines">@@ -122,9 +114,8 @@
</span><span class="cx"> continue;
</span><span class="cx"> VariableAccessData* variable = previousHead->variableAccessData();
</span><span class="cx"> Node* node = locals[local];
</span><del>- Node* setLocal = newRoot->appendNode(
</del><ins>+ newRoot->appendNode(
</ins><span class="cx"> m_graph, SpecNone, SetLocal, codeOrigin, OpInfo(variable), Edge(node));
</span><del>- setLocal->setSpeculationDirection(BackwardSpeculation);
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> newRoot->appendNode(
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGOSRExitcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExit.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExit.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExit.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -68,26 +68,6 @@
</span><span class="cx"> m_patchableCodeOffset = linkBuffer.offsetOf(label);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void OSRExit::convertToForward(BasicBlock* block, Node* currentNode, unsigned nodeIndex, const ValueRecovery& valueRecovery)
-{
- Node* node;
- Node* lastMovHint;
- if (!doSearchForForwardConversion(block, currentNode, nodeIndex, !!valueRecovery, node, lastMovHint))
- return;
-
- ASSERT(node->codeOrigin != currentNode->codeOrigin);
-
- m_codeOrigin = node->codeOrigin;
-
- if (!valueRecovery)
- return;
-
- ASSERT(lastMovHint);
- ASSERT(lastMovHint->child1() == currentNode);
- m_valueRecoveryOverride = adoptRef(
- new ValueRecoveryOverride(lastMovHint->local(), valueRecovery));
-}
-
</del><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGOSRExith"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExit.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExit.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExit.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -101,8 +101,6 @@
</span><span class="cx"> MacroAssembler::Jump getPatchableCodeOffsetAsJump() const;
</span><span class="cx"> CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
</span><span class="cx"> void correctJump(LinkBuffer&);
</span><del>-
- void convertToForward(BasicBlock*, Node*, unsigned nodeIndex, const ValueRecovery&);
</del><span class="cx">
</span><span class="cx"> unsigned m_streamIndex;
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGOSRExitBasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExitBase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExitBase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExitBase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -46,45 +46,6 @@
</span><span class="cx"> FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool OSRExitBase::doSearchForForwardConversion(
- BasicBlock* block, Node* currentNode, unsigned nodeIndex, bool hasValueRecovery,
- Node*& node, Node*& lastMovHint)
-{
- // Check that either the current node is a SetLocal, or the preceding node was a
- // SetLocal with the same code origin, or that we've provided a valueRecovery.
- if (!ASSERT_DISABLED
- && !hasValueRecovery
- && !currentNode->containsMovHint()) {
- Node* setLocal = block->at(nodeIndex - 1);
- ASSERT_UNUSED(setLocal, setLocal->containsMovHint());
- ASSERT_UNUSED(setLocal, setLocal->codeOriginForExitTarget == currentNode->codeOriginForExitTarget);
- }
-
- // Find the first node for the next bytecode instruction. Also track the last mov hint
- // on this node.
- unsigned indexInBlock = nodeIndex + 1;
- node = 0;
- lastMovHint = 0;
- for (;;) {
- if (indexInBlock == block->size()) {
- // This is an inline return. Give up and do a backwards speculation. This is safe
- // because an inline return has its own bytecode index and it's always safe to
- // reexecute that bytecode.
- ASSERT(node->op() == Jump);
- return false;
- }
- node = block->at(indexInBlock);
- if (node->containsMovHint() && node->child1() == currentNode)
- lastMovHint = node;
- if (node->codeOriginForExitTarget != currentNode->codeOriginForExitTarget)
- break;
- indexInBlock++;
- }
-
- ASSERT(node->codeOriginForExitTarget != currentNode->codeOriginForExitTarget);
- return true;
-}
-
</del><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGOSRExitBaseh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExitBase.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExitBase.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGOSRExitBase.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -64,11 +64,6 @@
</span><span class="cx"> return false;
</span><span class="cx"> return considerAddingAsFrequentExitSiteSlow(profiledCodeBlock);
</span><span class="cx"> }
</span><del>-
- // Returns true if the forward conversion is really needed.
- bool doSearchForForwardConversion(
- BasicBlock*, Node* currentNode, unsigned nodeIndex, bool hasValueRecovery,
- Node*& nextBCNode, Node*& lastMovHint);
</del><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> bool considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -504,9 +504,6 @@
</span><span class="cx"> case CheckArray:
</span><span class="cx"> case Arrayify:
</span><span class="cx"> case ArrayifyToStructure:
</span><del>- case MovHint:
- case MovHintAndCheck:
- case ZombieHint:
</del><span class="cx"> case CheckTierUpInLoop:
</span><span class="cx"> case CheckTierUpAtReturn:
</span><span class="cx"> case CheckTierUpAndOSREnter:
</span><span class="lines">@@ -574,6 +571,7 @@
</span><span class="cx"> case VarInjectionWatchpoint:
</span><span class="cx"> case AllocationProfileWatchpoint:
</span><span class="cx"> case Phantom:
</span><ins>+ case Check:
</ins><span class="cx"> case PutGlobalVar:
</span><span class="cx"> case CheckWatchdogTimer:
</span><span class="cx"> case Unreachable:
</span><span class="lines">@@ -582,6 +580,8 @@
</span><span class="cx"> case FunctionReentryWatchpoint:
</span><span class="cx"> case TypedArrayWatchpoint:
</span><span class="cx"> case ConstantStoragePointer:
</span><ins>+ case MovHint:
+ case ZombieHint:
</ins><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> // This gets ignored because it already has a prediction.
</span><span class="lines">@@ -741,6 +741,10 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case MovHint:
+ // Ignore these since they have no effect on in-DFG execution.
+ break;
+
</ins><span class="cx"> default:
</span><span class="cx"> m_graph.voteChildren(node, VoteValue);
</span><span class="cx"> break;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGSSAConversionPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -186,8 +186,8 @@
</span><span class="cx"> // the value was already on the stack.
</span><span class="cx"> } else {
</span><span class="cx"> m_insertionSet.insertNode(
</span><del>- 0, SpecNone, MovHint, CodeOrigin(), OpInfo(variable),
- Edge(node));
</del><ins>+ 0, SpecNone, MovHint, CodeOrigin(),
+ OpInfo(variable->local().offset()), Edge(node));
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -269,7 +269,7 @@
</span><span class="cx"> // - GetLocal over uncaptured variables die and get replaced with references
</span><span class="cx"> // to the node specified by variablesAtHead.
</span><span class="cx"> // - SetLocal gets NodeMustGenerate if it's flushed, or turns into a
</span><del>- // MovHint otherwise.
</del><ins>+ // Check otherwise.
</ins><span class="cx"> // - Flush loses its children but remains, because we want to know when a
</span><span class="cx"> // flushed SetLocal's value is no longer needed. This also makes it simpler
</span><span class="cx"> // to reason about the format of a local, since we can just do a backwards
</span><span class="lines">@@ -308,7 +308,7 @@
</span><span class="cx"> if (variable->isCaptured() || m_flushedLocalOps.contains(node))
</span><span class="cx"> node->mergeFlags(NodeMustGenerate);
</span><span class="cx"> else
</span><del>- node->setOpAndDefaultFlags(MovHint);
</del><ins>+ node->setOpAndDefaultFlags(Check);
</ins><span class="cx"> node->misc.replacement = node->child1().node(); // Only for Upsilons.
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -118,7 +118,6 @@
</span><span class="cx"> case GetCallee:
</span><span class="cx"> case GetLocal:
</span><span class="cx"> case SetLocal:
</span><del>- case MovHintAndCheck:
</del><span class="cx"> case MovHint:
</span><span class="cx"> case ZombieHint:
</span><span class="cx"> case GetArgument:
</span><span class="lines">@@ -247,6 +246,7 @@
</span><span class="cx"> case TypedArrayWatchpoint:
</span><span class="cx"> case CheckInBounds:
</span><span class="cx"> case ConstantStoragePointer:
</span><ins>+ case Check:
</ins><span class="cx"> return true;
</span><span class="cx">
</span><span class="cx"> case GetByVal:
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -104,7 +104,7 @@
</span><span class="cx"> structure, numElements)));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail)
</del><ins>+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail)
</ins><span class="cx"> {
</span><span class="cx"> if (!m_compileOkay)
</span><span class="cx"> return;
</span><span class="lines">@@ -113,7 +113,7 @@
</span><span class="cx"> m_jit.jitCode()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size()));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, const MacroAssembler::JumpList& jumpsToFail)
</del><ins>+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, const MacroAssembler::JumpList& jumpsToFail)
</ins><span class="cx"> {
</span><span class="cx"> if (!m_compileOkay)
</span><span class="cx"> return;
</span><span class="lines">@@ -122,24 +122,9 @@
</span><span class="cx"> m_jit.jitCode()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size()));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail)
</del><ins>+OSRExitJumpPlaceholder SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node)
</ins><span class="cx"> {
</span><span class="cx"> if (!m_compileOkay)
</span><del>- return;
- backwardSpeculationCheck(kind, jsValueSource, node, jumpToFail);
- if (m_speculationDirection == ForwardSpeculation)
- convertLastOSRExitToForward();
-}
-
-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail)
-{
- ASSERT(m_isCheckingArgumentTypes || m_canExit);
- speculationCheck(kind, jsValueSource, nodeUse.node(), jumpToFail);
-}
-
-OSRExitJumpPlaceholder SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node)
-{
- if (!m_compileOkay)
</del><span class="cx"> return OSRExitJumpPlaceholder();
</span><span class="cx"> ASSERT(m_isCheckingArgumentTypes || m_canExit);
</span><span class="cx"> unsigned index = m_jit.jitCode()->osrExit.size();
</span><span class="lines">@@ -148,19 +133,16 @@
</span><span class="cx"> return OSRExitJumpPlaceholder(index);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-OSRExitJumpPlaceholder SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse)
</del><ins>+OSRExitJumpPlaceholder SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(m_isCheckingArgumentTypes || m_canExit);
</span><del>- return backwardSpeculationCheck(kind, jsValueSource, nodeUse.node());
</del><ins>+ return speculationCheck(kind, jsValueSource, nodeUse.node());
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, const MacroAssembler::JumpList& jumpsToFail)
</del><ins>+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail)
</ins><span class="cx"> {
</span><del>- if (!m_compileOkay)
- return;
- backwardSpeculationCheck(kind, jsValueSource, node, jumpsToFail);
- if (m_speculationDirection == ForwardSpeculation)
- convertLastOSRExitToForward();
</del><ins>+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ speculationCheck(kind, jsValueSource, nodeUse.node(), jumpToFail);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, const MacroAssembler::JumpList& jumpsToFail)
</span><span class="lines">@@ -169,7 +151,7 @@
</span><span class="cx"> speculationCheck(kind, jsValueSource, nodeUse.node(), jumpsToFail);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
</del><ins>+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
</ins><span class="cx"> {
</span><span class="cx"> if (!m_compileOkay)
</span><span class="cx"> return;
</span><span class="lines">@@ -179,32 +161,17 @@
</span><span class="cx"> m_jit.jitCode()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size(), recoveryIndex));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
</del><ins>+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(m_isCheckingArgumentTypes || m_canExit);
</span><del>- backwardSpeculationCheck(kind, jsValueSource, nodeUse.node(), jumpToFail, recovery);
</del><ins>+ speculationCheck(kind, jsValueSource, nodeUse.node(), jumpToFail, recovery);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
-{
- if (!m_compileOkay)
- return;
- backwardSpeculationCheck(kind, jsValueSource, node, jumpToFail, recovery);
- if (m_speculationDirection == ForwardSpeculation)
- convertLastOSRExitToForward();
-}
-
-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
-{
- speculationCheck(kind, jsValueSource, edge.node(), jumpToFail, recovery);
-}
-
</del><span class="cx"> void SpeculativeJIT::emitInvalidationPoint(Node* node)
</span><span class="cx"> {
</span><span class="cx"> if (!m_compileOkay)
</span><span class="cx"> return;
</span><span class="cx"> ASSERT(m_canExit);
</span><del>- ASSERT(m_speculationDirection == BackwardSpeculation);
</del><span class="cx"> OSRExitCompilationInfo& info = m_jit.appendExitInfo(JITCompiler::JumpList());
</span><span class="cx"> m_jit.jitCode()->appendOSRExit(OSRExit(
</span><span class="cx"> UncountableInvalidation, JSValueSource(),
</span><span class="lines">@@ -215,26 +182,6 @@
</span><span class="cx"> noResult(node);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::convertLastOSRExitToForward(const ValueRecovery& valueRecovery)
-{
- m_jit.jitCode()->lastOSRExit().convertToForward(
- m_block, m_currentNode, m_indexInBlock, valueRecovery);
-}
-
-void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
-{
- ASSERT(m_isCheckingArgumentTypes || m_canExit);
- backwardSpeculationCheck(kind, jsValueSource, node, jumpToFail);
- convertLastOSRExitToForward(valueRecovery);
-}
-
-void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& valueRecovery)
-{
- ASSERT(m_isCheckingArgumentTypes || m_canExit);
- backwardSpeculationCheck(kind, jsValueSource, node, jumpsToFail);
- convertLastOSRExitToForward(valueRecovery);
-}
-
</del><span class="cx"> void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, Node* node)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(m_isCheckingArgumentTypes || m_canExit);
</span><span class="lines">@@ -250,26 +197,13 @@
</span><span class="cx"> terminateSpeculativeExecution(kind, jsValueRegs, nodeUse.node());
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::backwardTypeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail)
</del><ins>+void SpeculativeJIT::typeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(needsTypeCheck(edge, typesPassedThrough));
</span><span class="cx"> m_interpreter.filter(edge, typesPassedThrough);
</span><del>- backwardSpeculationCheck(BadType, source, edge.node(), jumpToFail);
</del><ins>+ speculationCheck(BadType, source, edge.node(), jumpToFail);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::typeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail)
-{
- backwardTypeCheck(source, edge, typesPassedThrough, jumpToFail);
- if (m_speculationDirection == ForwardSpeculation)
- convertLastOSRExitToForward();
-}
-
-void SpeculativeJIT::forwardTypeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
-{
- backwardTypeCheck(source, edge, typesPassedThrough, jumpToFail);
- convertLastOSRExitToForward(valueRecovery);
-}
-
</del><span class="cx"> RegisterSet SpeculativeJIT::usedRegisters()
</span><span class="cx"> {
</span><span class="cx"> RegisterSet result;
</span><span class="lines">@@ -1425,16 +1359,9 @@
</span><span class="cx"> Node* child = node->child1().node();
</span><span class="cx"> noticeOSRBirth(child);
</span><span class="cx">
</span><del>- m_stream->appendAndLog(VariableEvent::movHint(MinifiedID(child), node->local()));
</del><ins>+ m_stream->appendAndLog(VariableEvent::movHint(MinifiedID(child), node->unlinkedLocal()));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::compileMovHintAndCheck(Node* node)
-{
- compileMovHint(node);
- speculate(node, node->child1());
- noResult(node);
-}
-
</del><span class="cx"> void SpeculativeJIT::bail()
</span><span class="cx"> {
</span><span class="cx"> m_compileOkay = true;
</span><span class="lines">@@ -1483,9 +1410,7 @@
</span><span class="cx">
</span><span class="cx"> VariableAccessData* variable = node->variableAccessData();
</span><span class="cx"> DataFormat format;
</span><del>- if (variable->isArgumentsAlias())
- format = DataFormatArguments;
- else if (!node->refCount())
</del><ins>+ if (!node->refCount())
</ins><span class="cx"> continue; // No need to record dead SetLocal's.
</span><span class="cx"> else
</span><span class="cx"> format = dataFormatFor(variable->flushFormat());
</span><span class="lines">@@ -1531,7 +1456,7 @@
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case ZombieHint: {
</span><del>- recordSetLocal(DataFormatDead);
</del><ins>+ recordSetLocal(m_currentNode->unlinkedLocal(), VirtualRegister(), DataFormatDead);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1550,8 +1475,6 @@
</span><span class="cx"> dataLog("\n");
</span><span class="cx"> }
</span><span class="cx">
</span><del>- m_speculationDirection = (m_currentNode->flags() & NodeExitsForward) ? ForwardSpeculation : BackwardSpeculation;
-
</del><span class="cx"> compile(m_currentNode);
</span><span class="cx">
</span><span class="cx"> #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
</span><span class="lines">@@ -1589,18 +1512,19 @@
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!m_currentNode);
</span><span class="cx"> m_isCheckingArgumentTypes = true;
</span><del>- m_speculationDirection = BackwardSpeculation;
</del><span class="cx"> m_codeOriginForExitTarget = CodeOrigin(0);
</span><span class="cx"> m_codeOriginForExitProfile = CodeOrigin(0);
</span><span class="cx">
</span><span class="cx"> for (int i = 0; i < m_jit.codeBlock()->numParameters(); ++i) {
</span><span class="cx"> Node* node = m_jit.graph().m_arguments[i];
</span><del>- ASSERT(node->op() == SetArgument);
- if (!node->shouldGenerate()) {
</del><ins>+ if (!node) {
</ins><span class="cx"> // The argument is dead. We don't do any checks for such arguments.
</span><span class="cx"> continue;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ ASSERT(node->op() == SetArgument);
+ ASSERT(node->shouldGenerate());
+
</ins><span class="cx"> VariableAccessData* variableAccessData = node->variableAccessData();
</span><span class="cx"> FlushFormat format = variableAccessData->flushFormat();
</span><span class="cx">
</span><span class="lines">@@ -2140,7 +2064,7 @@
</span><span class="cx">
</span><span class="cx"> void SpeculativeJIT::compileUInt32ToNumber(Node* node)
</span><span class="cx"> {
</span><del>- if (!nodeCanSpeculateInt32(node->arithNodeFlags())) {
</del><ins>+ if (doesOverflow(node->arithMode())) {
</ins><span class="cx"> // We know that this sometimes produces doubles. So produce a double every
</span><span class="cx"> // time. This at least allows subsequent code to not have weird conditionals.
</span><span class="cx">
</span><span class="lines">@@ -2160,7 +2084,7 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- RELEASE_ASSERT(!bytecodeCanTruncateInteger(node->arithNodeFlags()));
</del><ins>+ RELEASE_ASSERT(node->arithMode() == Arith::CheckOverflow);
</ins><span class="cx">
</span><span class="cx"> SpeculateInt32Operand op1(this, node->child1());
</span><span class="cx"> GPRTemporary result(this);
</span><span class="lines">@@ -2183,8 +2107,10 @@
</span><span class="cx"> GPRReg resultGPR = result.gpr();
</span><span class="cx">
</span><span class="cx"> JITCompiler::JumpList failureCases;
</span><del>- bool negZeroCheck = !bytecodeCanIgnoreNegativeZero(node->arithNodeFlags());
- m_jit.branchConvertDoubleToInt32(valueFPR, resultGPR, failureCases, scratchFPR, negZeroCheck);
</del><ins>+ RELEASE_ASSERT(shouldCheckOverflow(node->arithMode()));
+ m_jit.branchConvertDoubleToInt32(
+ valueFPR, resultGPR, failureCases, scratchFPR,
+ shouldCheckNegativeZero(node->arithMode()));
</ins><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, failureCases);
</span><span class="cx">
</span><span class="cx"> int32Result(resultGPR, node);
</span><span class="lines">@@ -2216,16 +2142,9 @@
</span><span class="cx"> MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
</span><span class="cx">
</span><span class="cx"> if (needsTypeCheck(node->child1(), SpecFullNumber)) {
</span><del>- if (node->flags() & NodeExitsForward) {
- forwardTypeCheck(
- JSValueRegs(op1GPR), node->child1(), SpecFullNumber,
- m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister),
- ValueRecovery::inGPR(op1GPR, DataFormatJS));
- } else {
- backwardTypeCheck(
- JSValueRegs(op1GPR), node->child1(), SpecFullNumber,
- m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
- }
</del><ins>+ typeCheck(
+ JSValueRegs(op1GPR), node->child1(), SpecFullNumber,
+ m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> m_jit.move(op1GPR, tempGPR);
</span><span class="lines">@@ -2247,16 +2166,9 @@
</span><span class="cx"> MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
</span><span class="cx">
</span><span class="cx"> if (needsTypeCheck(node->child1(), SpecFullNumber)) {
</span><del>- if (node->flags() & NodeExitsForward) {
- forwardTypeCheck(
- JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecFullNumber,
- m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)),
- ValueRecovery::inPair(op1TagGPR, op1PayloadGPR));
- } else {
- backwardTypeCheck(
- JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecFullNumber,
- m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
- }
</del><ins>+ typeCheck(
+ JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecFullNumber,
+ m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> unboxDouble(op1TagGPR, op1PayloadGPR, resultFPR, tempFPR);
</span><span class="lines">@@ -2722,12 +2634,14 @@
</span><span class="cx"> {
</span><span class="cx"> switch (node->binaryUseKind()) {
</span><span class="cx"> case Int32Use: {
</span><ins>+ ASSERT(!shouldCheckNegativeZero(node->arithMode()));
+
</ins><span class="cx"> if (isNumberConstant(node->child1().node())) {
</span><span class="cx"> int32_t imm1 = valueOfInt32Constant(node->child1().node());
</span><span class="cx"> SpeculateInt32Operand op2(this, node->child2());
</span><span class="cx"> GPRTemporary result(this);
</span><span class="cx">
</span><del>- if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
</del><ins>+ if (!shouldCheckOverflow(node->arithMode())) {
</ins><span class="cx"> m_jit.move(op2.gpr(), result.gpr());
</span><span class="cx"> m_jit.add32(Imm32(imm1), result.gpr());
</span><span class="cx"> } else
</span><span class="lines">@@ -2742,7 +2656,7 @@
</span><span class="cx"> int32_t imm2 = valueOfInt32Constant(node->child2().node());
</span><span class="cx"> GPRTemporary result(this);
</span><span class="cx">
</span><del>- if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
</del><ins>+ if (!shouldCheckOverflow(node->arithMode())) {
</ins><span class="cx"> m_jit.move(op1.gpr(), result.gpr());
</span><span class="cx"> m_jit.add32(Imm32(imm2), result.gpr());
</span><span class="cx"> } else
</span><span class="lines">@@ -2760,7 +2674,7 @@
</span><span class="cx"> GPRReg gpr2 = op2.gpr();
</span><span class="cx"> GPRReg gprResult = result.gpr();
</span><span class="cx">
</span><del>- if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
</del><ins>+ if (!shouldCheckOverflow(node->arithMode())) {
</ins><span class="cx"> if (gpr1 == gprResult)
</span><span class="cx"> m_jit.add32(gpr2, gprResult);
</span><span class="cx"> else {
</span><span class="lines">@@ -2784,6 +2698,9 @@
</span><span class="cx">
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx"> case MachineIntUse: {
</span><ins>+ ASSERT(shouldCheckOverflow(node->arithMode()));
+ ASSERT(!shouldCheckNegativeZero(node->arithMode()));
+
</ins><span class="cx"> // Will we need an overflow check? If we can prove that neither input can be
</span><span class="cx"> // Int52 then the overflow check will not be necessary.
</span><span class="cx"> if (!m_state.forNode(node->child1()).couldBeType(SpecInt52)
</span><span class="lines">@@ -2822,12 +2739,6 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case UntypedUse: {
- RELEASE_ASSERT(node->op() == ValueAdd);
- compileValueAdd(node);
- return;
- }
-
</del><span class="cx"> default:
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span><span class="lines">@@ -2903,12 +2814,14 @@
</span><span class="cx"> {
</span><span class="cx"> switch (node->binaryUseKind()) {
</span><span class="cx"> case Int32Use: {
</span><ins>+ ASSERT(!shouldCheckNegativeZero(node->arithMode()));
+
</ins><span class="cx"> if (isNumberConstant(node->child2().node())) {
</span><span class="cx"> SpeculateInt32Operand op1(this, node->child1());
</span><span class="cx"> int32_t imm2 = valueOfInt32Constant(node->child2().node());
</span><span class="cx"> GPRTemporary result(this);
</span><span class="cx">
</span><del>- if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
</del><ins>+ if (!shouldCheckOverflow(node->arithMode())) {
</ins><span class="cx"> m_jit.move(op1.gpr(), result.gpr());
</span><span class="cx"> m_jit.sub32(Imm32(imm2), result.gpr());
</span><span class="cx"> } else {
</span><span class="lines">@@ -2926,7 +2839,7 @@
</span><span class="cx"> GPRTemporary result(this);
</span><span class="cx">
</span><span class="cx"> m_jit.move(Imm32(imm1), result.gpr());
</span><del>- if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
</del><ins>+ if (!shouldCheckOverflow(node->arithMode()))
</ins><span class="cx"> m_jit.sub32(op2.gpr(), result.gpr());
</span><span class="cx"> else
</span><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchSub32(MacroAssembler::Overflow, op2.gpr(), result.gpr()));
</span><span class="lines">@@ -2939,7 +2852,7 @@
</span><span class="cx"> SpeculateInt32Operand op2(this, node->child2());
</span><span class="cx"> GPRTemporary result(this);
</span><span class="cx">
</span><del>- if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
</del><ins>+ if (!shouldCheckOverflow(node->arithMode())) {
</ins><span class="cx"> m_jit.move(op1.gpr(), result.gpr());
</span><span class="cx"> m_jit.sub32(op2.gpr(), result.gpr());
</span><span class="cx"> } else
</span><span class="lines">@@ -2951,6 +2864,9 @@
</span><span class="cx">
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx"> case MachineIntUse: {
</span><ins>+ ASSERT(shouldCheckOverflow(node->arithMode()));
+ ASSERT(!shouldCheckNegativeZero(node->arithMode()));
+
</ins><span class="cx"> // Will we need an overflow check? If we can prove that neither input can be
</span><span class="cx"> // Int52 then the overflow check will not be necessary.
</span><span class="cx"> if (!m_state.forNode(node->child1()).couldBeType(SpecInt52)
</span><span class="lines">@@ -3007,9 +2923,9 @@
</span><span class="cx"> // Note: there is no notion of being not used as a number, but someone
</span><span class="cx"> // caring about negative zero.
</span><span class="cx">
</span><del>- if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
</del><ins>+ if (!shouldCheckOverflow(node->arithMode()))
</ins><span class="cx"> m_jit.neg32(result.gpr());
</span><del>- else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
</del><ins>+ else if (!shouldCheckNegativeZero(node->arithMode()))
</ins><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchNeg32(MacroAssembler::Overflow, result.gpr()));
</span><span class="cx"> else {
</span><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(MacroAssembler::Zero, result.gpr(), TrustedImm32(0x7fffffff)));
</span><span class="lines">@@ -3022,6 +2938,8 @@
</span><span class="cx">
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx"> case MachineIntUse: {
</span><ins>+ ASSERT(shouldCheckOverflow(node->arithMode()));
+
</ins><span class="cx"> if (!m_state.forNode(node->child1()).couldBeType(SpecInt52)) {
</span><span class="cx"> SpeculateWhicheverInt52Operand op1(this, node->child1());
</span><span class="cx"> GPRTemporary result(this);
</span><span class="lines">@@ -3029,7 +2947,7 @@
</span><span class="cx"> GPRReg resultGPR = result.gpr();
</span><span class="cx"> m_jit.move(op1GPR, resultGPR);
</span><span class="cx"> m_jit.neg64(resultGPR);
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (!shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> speculationCheck(
</span><span class="cx"> NegativeZero, JSValueRegs(), 0,
</span><span class="cx"> m_jit.branchTest64(MacroAssembler::Zero, resultGPR));
</span><span class="lines">@@ -3046,7 +2964,7 @@
</span><span class="cx"> speculationCheck(
</span><span class="cx"> Int52Overflow, JSValueRegs(), 0,
</span><span class="cx"> m_jit.branchNeg64(MacroAssembler::Overflow, resultGPR));
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (!shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> speculationCheck(
</span><span class="cx"> NegativeZero, JSValueRegs(), 0,
</span><span class="cx"> m_jit.branchTest64(MacroAssembler::Zero, resultGPR));
</span><span class="lines">@@ -3071,21 +2989,6 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>-void SpeculativeJIT::compileArithIMul(Node* node)
-{
- SpeculateInt32Operand op1(this, node->child1());
- SpeculateInt32Operand op2(this, node->child2());
- GPRTemporary result(this);
-
- GPRReg reg1 = op1.gpr();
- GPRReg reg2 = op2.gpr();
-
- m_jit.move(reg1, result.gpr());
- m_jit.mul32(reg2, result.gpr());
- int32Result(result.gpr(), node);
- return;
-}
-
</del><span class="cx"> void SpeculativeJIT::compileArithMul(Node* node)
</span><span class="cx"> {
</span><span class="cx"> switch (node->binaryUseKind()) {
</span><span class="lines">@@ -3100,7 +3003,7 @@
</span><span class="cx"> // We can perform truncated multiplications if we get to this point, because if the
</span><span class="cx"> // fixup phase could not prove that it would be safe, it would have turned us into
</span><span class="cx"> // a double multiplication.
</span><del>- if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
</del><ins>+ if (!shouldCheckOverflow(node->arithMode())) {
</ins><span class="cx"> m_jit.move(reg1, result.gpr());
</span><span class="cx"> m_jit.mul32(reg2, result.gpr());
</span><span class="cx"> } else {
</span><span class="lines">@@ -3110,7 +3013,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Check for negative zero, if the users of this node care about such things.
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr());
</span><span class="cx"> speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));
</span><span class="cx"> speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));
</span><span class="lines">@@ -3123,6 +3026,8 @@
</span><span class="cx">
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx"> case MachineIntUse: {
</span><ins>+ ASSERT(shouldCheckOverflow(node->arithMode()));
+
</ins><span class="cx"> // This is super clever. We want to do an int52 multiplication and check the
</span><span class="cx"> // int52 overflow bit. There is no direct hardware support for this, but we do
</span><span class="cx"> // have the ability to do an int64 multiplication and check the int64 overflow
</span><span class="lines">@@ -3160,7 +3065,7 @@
</span><span class="cx"> Int52Overflow, JSValueRegs(), 0,
</span><span class="cx"> m_jit.branchMul64(MacroAssembler::Overflow, op2GPR, resultGPR));
</span><span class="cx">
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> MacroAssembler::Jump resultNonZero = m_jit.branchTest64(
</span><span class="cx"> MacroAssembler::NonZero, resultGPR);
</span><span class="cx"> speculationCheck(
</span><span class="lines">@@ -3230,7 +3135,7 @@
</span><span class="cx"> JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1));
</span><span class="cx">
</span><span class="cx"> JITCompiler::JumpList done;
</span><del>- if (bytecodeUsesAsNumber(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckOverflow(node->arithMode())) {
</ins><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
</span><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
</span><span class="cx"> } else {
</span><span class="lines">@@ -3258,7 +3163,7 @@
</span><span class="cx">
</span><span class="cx"> // If the user cares about negative zero, then speculate that we're not about
</span><span class="cx"> // to produce negative zero.
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
</span><span class="cx"> speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
</span><span class="cx"> numeratorNonZero.link(&m_jit);
</span><span class="lines">@@ -3278,7 +3183,7 @@
</span><span class="cx">
</span><span class="cx"> // Check that there was no remainder. If there had been, then we'd be obligated to
</span><span class="cx"> // produce a double result instead.
</span><del>- if (bytecodeUsesAsNumber(node->arithNodeFlags()))
</del><ins>+ if (shouldCheckOverflow(node->arithMode()))
</ins><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));
</span><span class="cx">
</span><span class="cx"> done.link(&m_jit);
</span><span class="lines">@@ -3293,7 +3198,7 @@
</span><span class="cx">
</span><span class="cx"> // If the user cares about negative zero, then speculate that we're not about
</span><span class="cx"> // to produce negative zero.
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
</span><span class="cx"> speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
</span><span class="cx"> numeratorNonZero.link(&m_jit);
</span><span class="lines">@@ -3303,7 +3208,7 @@
</span><span class="cx">
</span><span class="cx"> // Check that there was no remainder. If there had been, then we'd be obligated to
</span><span class="cx"> // produce a double result instead.
</span><del>- if (bytecodeUsesAsNumber(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckOverflow(node->arithMode())) {
</ins><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotient.gpr(), op2GPR, multiplyAnswer.gpr()));
</span><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::NotEqual, multiplyAnswer.gpr(), op1GPR));
</span><span class="cx"> }
</span><span class="lines">@@ -3319,7 +3224,7 @@
</span><span class="cx">
</span><span class="cx"> // If the user cares about negative zero, then speculate that we're not about
</span><span class="cx"> // to produce negative zero.
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
</span><span class="cx"> speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
</span><span class="cx"> numeratorNonZero.link(&m_jit);
</span><span class="lines">@@ -3329,7 +3234,7 @@
</span><span class="cx">
</span><span class="cx"> // Check that there was no remainder. If there had been, then we'd be obligated to
</span><span class="cx"> // produce a double result instead.
</span><del>- if (bytecodeUsesAsNumber(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckOverflow(node->arithMode())) {
</ins><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotient.gpr(), op2GPR, multiplyAnswer.gpr()));
</span><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::NotEqual, multiplyAnswer.gpr(), op1GPR));
</span><span class="cx"> }
</span><span class="lines">@@ -3417,7 +3322,7 @@
</span><span class="cx"> m_jit.neg32(resultGPR);
</span><span class="cx"> m_jit.add32(dividendGPR, resultGPR);
</span><span class="cx">
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> // Check that we're not about to create negative zero.
</span><span class="cx"> JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
</span><span class="cx"> speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, resultGPR));
</span><span class="lines">@@ -3454,7 +3359,7 @@
</span><span class="cx"> m_jit.move(TrustedImm32(divisor), scratchGPR);
</span><span class="cx"> m_jit.assembler().cdq();
</span><span class="cx"> m_jit.assembler().idivl_r(scratchGPR);
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
</span><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
</span><span class="cx"> numeratorPositive.link(&m_jit);
</span><span class="lines">@@ -3511,7 +3416,7 @@
</span><span class="cx">
</span><span class="cx"> // FIXME: -2^31 / -1 will actually yield negative zero, so we could have a
</span><span class="cx"> // separate case for that. But it probably doesn't matter so much.
</span><del>- if (bytecodeUsesAsNumber(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckOverflow(node->arithMode())) {
</ins><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
</span><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
</span><span class="cx"> } else {
</span><span class="lines">@@ -3550,7 +3455,7 @@
</span><span class="cx"> unlock(op2TempGPR);
</span><span class="cx">
</span><span class="cx"> // Check that we're not about to create negative zero.
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
</span><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
</span><span class="cx"> numeratorPositive.link(&m_jit);
</span><span class="lines">@@ -3572,12 +3477,15 @@
</span><span class="cx"> GPRReg multiplyAnswerGPR = multiplyAnswer.gpr();
</span><span class="cx">
</span><span class="cx"> m_jit.assembler().sdiv(quotientThenRemainderGPR, dividendGPR, divisorGPR);
</span><ins>+ // FIXME: It seems like there are cases where we don't need this? What if we have
+ // arithMode() == Arith::Unchecked?
+ // https://bugs.webkit.org/show_bug.cgi?id=126444
</ins><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotientThenRemainderGPR, divisorGPR, multiplyAnswerGPR));
</span><span class="cx"> m_jit.assembler().sub(quotientThenRemainderGPR, dividendGPR, multiplyAnswerGPR);
</span><span class="cx">
</span><span class="cx"> // If the user cares about negative zero, then speculate that we're not about
</span><span class="cx"> // to produce negative zero.
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> // Check that we're not about to create negative zero.
</span><span class="cx"> JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
</span><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, quotientThenRemainderGPR));
</span><span class="lines">@@ -3595,12 +3503,15 @@
</span><span class="cx"> GPRReg multiplyAnswerGPR = multiplyAnswer.gpr();
</span><span class="cx">
</span><span class="cx"> m_jit.assembler().sdiv<32>(quotientThenRemainderGPR, dividendGPR, divisorGPR);
</span><ins>+ // FIXME: It seems like there are cases where we don't need this? What if we have
+ // arithMode() == Arith::Unchecked?
+ // https://bugs.webkit.org/show_bug.cgi?id=126444
</ins><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotientThenRemainderGPR, divisorGPR, multiplyAnswerGPR));
</span><span class="cx"> m_jit.assembler().sub<32>(quotientThenRemainderGPR, dividendGPR, multiplyAnswerGPR);
</span><span class="cx">
</span><span class="cx"> // If the user cares about negative zero, then speculate that we're not about
</span><span class="cx"> // to produce negative zero.
</span><del>- if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(node->arithMode())) {
</ins><span class="cx"> // Check that we're not about to create negative zero.
</span><span class="cx"> JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
</span><span class="cx"> speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, quotientThenRemainderGPR));
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -686,8 +686,12 @@
</span><span class="cx"> // Check that no intervening nodes will be generated.
</span><span class="cx"> for (unsigned index = m_indexInBlock + 1; index < m_block->size() - 1; ++index) {
</span><span class="cx"> Node* node = m_block->at(index);
</span><del>- if (node->shouldGenerate())
- return UINT_MAX;
</del><ins>+ if (!node->shouldGenerate())
+ continue;
+ // Check if it's a Phantom that can be safely ignored.
+ if (node->op() == Phantom && !node->child1())
+ continue;
+ return UINT_MAX;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Check if the lastNode is a branch on this node.
</span><span class="lines">@@ -1936,7 +1940,6 @@
</span><span class="cx"> void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode);
</span><span class="cx"> void compileObjectEquality(Node*);
</span><span class="cx"> void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
</span><del>- void compileValueAdd(Node*);
</del><span class="cx"> void compileObjectOrOtherLogicalNot(Edge value);
</span><span class="cx"> void compileLogicalNot(Node*);
</span><span class="cx"> void compileStringEquality(Node*);
</span><span class="lines">@@ -2023,7 +2026,6 @@
</span><span class="cx"> void compileArithSub(Node*);
</span><span class="cx"> void compileArithNegate(Node*);
</span><span class="cx"> void compileArithMul(Node*);
</span><del>- void compileArithIMul(Node*);
</del><span class="cx"> void compileArithDiv(Node*);
</span><span class="cx"> void compileArithMod(Node*);
</span><span class="cx"> void compileConstantStoragePointer(Node*);
</span><span class="lines">@@ -2117,43 +2119,28 @@
</span><span class="cx"> JITCompiler::Jump convertToDouble(JSValueOperand&, FPRReg result);
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>- // Add a backward speculation check.
- void backwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
- void backwardSpeculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
-
- // Add a speculation check without additional recovery.
</del><ins>+ // Add a speculation check.
</ins><span class="cx"> void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
</span><del>- void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail);
- // Add a speculation check without additional recovery, and with a promise to supply a jump later.
- OSRExitJumpPlaceholder backwardSpeculationCheck(ExitKind, JSValueSource, Node*);
- OSRExitJumpPlaceholder backwardSpeculationCheck(ExitKind, JSValueSource, Edge);
- // Add a set of speculation checks without additional recovery.
</del><span class="cx"> void speculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
</span><ins>+
+ // Add a speculation check without additional recovery, and with a promise to supply a jump later.
+ OSRExitJumpPlaceholder speculationCheck(ExitKind, JSValueSource, Node*);
+ OSRExitJumpPlaceholder speculationCheck(ExitKind, JSValueSource, Edge);
+ void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail);
</ins><span class="cx"> void speculationCheck(ExitKind, JSValueSource, Edge, const MacroAssembler::JumpList& jumpsToFail);
</span><span class="cx"> // Add a speculation check with additional recovery.
</span><del>- void backwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
- void backwardSpeculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
</del><ins>+ void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
+ void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
</ins><span class="cx">
</span><span class="cx"> void emitInvalidationPoint(Node*);
</span><span class="cx">
</span><del>- // It is generally a good idea to not use this directly.
- void convertLastOSRExitToForward(const ValueRecovery& = ValueRecovery());
-
- // Note: not specifying the valueRecovery argument (leaving it as ValueRecovery()) implies
- // that you've ensured that there exists a MovHint prior to your use of forwardSpeculationCheck().
- void forwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const ValueRecovery& = ValueRecovery());
- void forwardSpeculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& = ValueRecovery());
- void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
- void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
</del><span class="cx"> // Called when we statically determine that a speculation will fail.
</span><span class="cx"> void terminateSpeculativeExecution(ExitKind, JSValueRegs, Node*);
</span><span class="cx"> void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);
</span><span class="cx">
</span><span class="cx"> // Helpers for performing type checks on an edge stored in the given registers.
</span><span class="cx"> bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_interpreter.needsTypeCheck(edge, typesPassedThrough); }
</span><del>- void backwardTypeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
</del><span class="cx"> void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
</span><del>- void forwardTypeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, const ValueRecovery&);
</del><span class="cx">
</span><span class="cx"> void speculateInt32(Edge);
</span><span class="cx"> void speculateMachineInt(Edge);
</span><span class="lines">@@ -2226,7 +2213,6 @@
</span><span class="cx"> // The current node being generated.
</span><span class="cx"> BasicBlock* m_block;
</span><span class="cx"> Node* m_currentNode;
</span><del>- SpeculationDirection m_speculationDirection;
</del><span class="cx"> bool m_canExit;
</span><span class="cx"> unsigned m_indexInBlock;
</span><span class="cx"> // Virtual and physical register maps.
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -1403,28 +1403,6 @@
</span><span class="cx"> booleanResult(resultPayload.gpr(), node);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::compileValueAdd(Node* node)
-{
- JSValueOperand op1(this, node->child1());
- JSValueOperand op2(this, node->child2());
-
- GPRReg op1TagGPR = op1.tagGPR();
- GPRReg op1PayloadGPR = op1.payloadGPR();
- GPRReg op2TagGPR = op2.tagGPR();
- GPRReg op2PayloadGPR = op2.payloadGPR();
-
- flushRegisters();
-
- GPRResult2 resultTag(this);
- GPRResult resultPayload(this);
- if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
- callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
- else
- callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
-
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
-}
-
</del><span class="cx"> void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
</span><span class="cx"> {
</span><span class="cx"> JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
</span><span class="lines">@@ -1874,7 +1852,8 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case FlushedJSValue: {
</del><ins>+ case FlushedJSValue:
+ case FlushedArguments: {
</ins><span class="cx"> GPRTemporary result(this);
</span><span class="cx"> GPRTemporary tag(this);
</span><span class="cx"> m_jit.load32(JITCompiler::payloadFor(node->machineLocal()), result.gpr());
</span><span class="lines">@@ -1905,24 +1884,14 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case MovHintAndCheck: {
- compileMovHintAndCheck(node);
- break;
- }
-
</del><span class="cx"> case MovHint:
</span><del>- case ZombieHint: {
</del><ins>+ case ZombieHint:
+ case Check: {
</ins><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case SetLocal: {
</span><del>- // SetLocal doubles as a hint as to where a node will be stored and
- // as a speculation point. So before we speculate make sure that we
- // know where the child of this node needs to go in the virtual
- // stack.
- compileMovHint(node);
-
</del><span class="cx"> switch (node->variableAccessData()->flushFormat()) {
</span><span class="cx"> case FlushedDouble: {
</span><span class="cx"> SpeculateDoubleOperand value(this, node->child1());
</span><span class="lines">@@ -1960,7 +1929,8 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case FlushedJSValue: {
</del><ins>+ case FlushedJSValue:
+ case FlushedArguments: {
</ins><span class="cx"> if (generationInfoFromVirtualRegister(node->child1()->virtualRegister()).registerFormat() == DataFormatDouble) {
</span><span class="cx"> SpeculateDoubleOperand value(this, node->child1(), ManualOperandSpeculation);
</span><span class="cx"> m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node->machineLocal()));
</span><span class="lines">@@ -1974,14 +1944,6 @@
</span><span class="cx"> m_jit.store32(value.tagGPR(), JITCompiler::tagFor(node->machineLocal()));
</span><span class="cx"> noResult(node);
</span><span class="cx"> recordSetLocal(DataFormatJS);
</span><del>-
- // If we're storing an arguments object that has been optimized away,
- // our variable event stream for OSR exit now reflects the optimized
- // value (JSValue()). On the slow path, we want an arguments object
- // instead. We add an additional move hint to show OSR exit that it
- // needs to reconstruct the arguments object.
- if (node->child1()->op() == PhantomArguments)
- compileMovHint(node);
</del><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2073,7 +2035,28 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case ValueAdd:
</del><ins>+ case ValueAdd: {
+ JSValueOperand op1(this, node->child1());
+ JSValueOperand op2(this, node->child2());
+
+ GPRReg op1TagGPR = op1.tagGPR();
+ GPRReg op1PayloadGPR = op1.payloadGPR();
+ GPRReg op2TagGPR = op2.tagGPR();
+ GPRReg op2PayloadGPR = op2.payloadGPR();
+
+ flushRegisters();
+
+ GPRResult2 resultTag(this);
+ GPRResult resultPayload(this);
+ if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
+ callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
+ else
+ callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
+
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
+ break;
+ }
+
</ins><span class="cx"> case ArithAdd:
</span><span class="cx"> compileAdd(node);
</span><span class="cx"> break;
</span><span class="lines">@@ -2094,10 +2077,6 @@
</span><span class="cx"> compileArithMul(node);
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- case ArithIMul:
- compileArithIMul(node);
- break;
-
</del><span class="cx"> case ArithDiv: {
</span><span class="cx"> compileArithDiv(node);
</span><span class="cx"> break;
</span><span class="lines">@@ -4741,6 +4720,7 @@
</span><span class="cx"> case Int52ToDouble:
</span><span class="cx"> case Int52ToValue:
</span><span class="cx"> case CheckInBounds:
</span><ins>+ case ArithIMul:
</ins><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -1787,25 +1787,6 @@
</span><span class="cx"> jsValueResult(result.gpr(), node, DataFormatJSBoolean);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SpeculativeJIT::compileValueAdd(Node* node)
-{
- JSValueOperand op1(this, node->child1());
- JSValueOperand op2(this, node->child2());
-
- GPRReg op1GPR = op1.gpr();
- GPRReg op2GPR = op2.gpr();
-
- flushRegisters();
-
- GPRResult result(this);
- if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
- callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
- else
- callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
-
- jsValueResult(result.gpr(), node);
-}
-
</del><span class="cx"> void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
</span><span class="cx"> {
</span><span class="cx"> JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
</span><span class="lines">@@ -2217,24 +2198,14 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case MovHintAndCheck: {
- compileMovHintAndCheck(node);
- break;
- }
-
</del><span class="cx"> case MovHint:
</span><del>- case ZombieHint: {
</del><ins>+ case ZombieHint:
+ case Check: {
</ins><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case SetLocal: {
</span><del>- // SetLocal doubles as a hint as to where a node will be stored and
- // as a speculation point. So before we speculate make sure that we
- // know where the child of this node needs to go in the virtual
- // stack.
- compileMovHint(node);
-
</del><span class="cx"> switch (node->variableAccessData()->flushFormat()) {
</span><span class="cx"> case FlushedDouble: {
</span><span class="cx"> SpeculateDoubleOperand value(this, node->child1());
</span><span class="lines">@@ -2280,20 +2251,12 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case FlushedJSValue: {
</del><ins>+ case FlushedJSValue:
+ case FlushedArguments: {
</ins><span class="cx"> JSValueOperand value(this, node->child1());
</span><span class="cx"> m_jit.store64(value.gpr(), JITCompiler::addressFor(node->machineLocal()));
</span><span class="cx"> noResult(node);
</span><del>-
</del><span class="cx"> recordSetLocal(DataFormatJS);
</span><del>-
- // If we're storing an arguments object that has been optimized away,
- // our variable event stream for OSR exit now reflects the optimized
- // value (JSValue()). On the slow path, we want an arguments object
- // instead. We add an additional move hint to show OSR exit that it
- // needs to reconstruct the arguments object.
- if (node->child1()->op() == PhantomArguments)
- compileMovHint(node);
</del><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2402,7 +2365,25 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case ValueAdd:
</del><ins>+ case ValueAdd: {
+ JSValueOperand op1(this, node->child1());
+ JSValueOperand op2(this, node->child2());
+
+ GPRReg op1GPR = op1.gpr();
+ GPRReg op2GPR = op2.gpr();
+
+ flushRegisters();
+
+ GPRResult result(this);
+ if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
+ callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
+ else
+ callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
+
+ jsValueResult(result.gpr(), node);
+ break;
+ }
+
</ins><span class="cx"> case ArithAdd:
</span><span class="cx"> compileAdd(node);
</span><span class="cx"> break;
</span><span class="lines">@@ -2423,10 +2404,6 @@
</span><span class="cx"> compileArithMul(node);
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- case ArithIMul:
- compileArithIMul(node);
- break;
-
</del><span class="cx"> case ArithDiv: {
</span><span class="cx"> compileArithDiv(node);
</span><span class="cx"> break;
</span><span class="lines">@@ -5033,6 +5010,7 @@
</span><span class="cx"> case GetArgument:
</span><span class="cx"> case ExtractOSREntryLocal:
</span><span class="cx"> case CheckInBounds:
</span><ins>+ case ArithIMul:
</ins><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGTypeCheckHoistingPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -163,33 +163,22 @@
</span><span class="cx"> if (!iter->value.m_structure && !iter->value.m_arrayModeIsValid)
</span><span class="cx"> break;
</span><span class="cx">
</span><del>- // First insert a dead SetLocal to tell OSR that the child's value should
- // be dropped into this bytecode variable if the CheckStructure decides
- // to exit.
-
</del><span class="cx"> CodeOrigin codeOrigin = node->codeOrigin;
</span><span class="cx"> Edge child1 = node->child1();
</span><span class="cx">
</span><del>- insertionSet.insertNode(
- indexInBlock, SpecNone, SetLocal, codeOrigin, OpInfo(variable), child1);
-
- // Use NodeExitsForward to indicate that we should exit to the next
- // bytecode instruction rather than reexecuting the current one.
- Node* newNode = 0;
</del><span class="cx"> if (iter->value.m_structure) {
</span><del>- newNode = insertionSet.insertNode(
</del><ins>+ insertionSet.insertNode(
</ins><span class="cx"> indexInBlock, SpecNone, CheckStructure, codeOrigin,
</span><span class="cx"> OpInfo(m_graph.addStructureSet(iter->value.m_structure)),
</span><span class="cx"> Edge(child1.node(), CellUse));
</span><span class="cx"> } else if (iter->value.m_arrayModeIsValid) {
</span><span class="cx"> ASSERT(iter->value.m_arrayModeHoistingOkay);
</span><del>- newNode = insertionSet.insertNode(
</del><ins>+ insertionSet.insertNode(
</ins><span class="cx"> indexInBlock, SpecNone, CheckArray, codeOrigin,
</span><span class="cx"> OpInfo(iter->value.m_arrayMode.asWord()),
</span><span class="cx"> Edge(child1.node(), CellUse));
</span><span class="cx"> } else
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><del>- newNode->mergeFlags(NodeExitsForward);
</del><span class="cx"> changed = true;
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="lines">@@ -228,9 +217,6 @@
</span><span class="cx"> switch (node->op()) {
</span><span class="cx"> case CheckStructure:
</span><span class="cx"> case StructureTransitionWatchpoint: {
</span><del>- // We currently rely on the fact that we're the only ones who would
- // insert these nodes with NodeExitsForward.
- RELEASE_ASSERT(!(node->flags() & NodeExitsForward));
</del><span class="cx"> Node* child = node->child1().node();
</span><span class="cx"> if (child->op() != GetLocal)
</span><span class="cx"> break;
</span><span class="lines">@@ -257,6 +243,7 @@
</span><span class="cx"> case GetIndexedPropertyStorage:
</span><span class="cx"> case GetTypedArrayByteOffset:
</span><span class="cx"> case Phantom:
</span><ins>+ case MovHint:
</ins><span class="cx"> // Don't count these uses.
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="lines">@@ -329,9 +316,6 @@
</span><span class="cx"> Node* node = block->at(indexInBlock);
</span><span class="cx"> switch (node->op()) {
</span><span class="cx"> case CheckArray: {
</span><del>- // We currently rely on the fact that we're the only ones who would
- // insert these nodes with NodeExitsForward.
- RELEASE_ASSERT(!(node->flags() & NodeExitsForward));
</del><span class="cx"> Node* child = node->child1().node();
</span><span class="cx"> if (child->op() != GetLocal)
</span><span class="cx"> break;
</span><span class="lines">@@ -357,6 +341,7 @@
</span><span class="cx"> case GetArrayLength:
</span><span class="cx"> case GetIndexedPropertyStorage:
</span><span class="cx"> case Phantom:
</span><ins>+ case MovHint:
</ins><span class="cx"> // Don't count these uses.
</span><span class="cx"> break;
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGValidatecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGValidate.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGValidate.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGValidate.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -245,10 +245,7 @@
</span><span class="cx"> edge->op() == SetLocal
</span><span class="cx"> || edge->op() == SetArgument
</span><span class="cx"> || edge->op() == Flush
</span><del>- || edge->op() == Phi
- || edge->op() == ZombieHint
- || edge->op() == MovHint
- || edge->op() == MovHintAndCheck);
</del><ins>+ || edge->op() == Phi);
</ins><span class="cx">
</span><span class="cx"> if (phisInThisBlock.contains(edge.node()))
</span><span class="cx"> continue;
</span><span class="lines">@@ -257,9 +254,6 @@
</span><span class="cx"> VALIDATE(
</span><span class="cx"> (node, edge),
</span><span class="cx"> edge->op() == SetLocal
</span><del>- || edge->op() == ZombieHint
- || edge->op() == MovHint
- || edge->op() == MovHintAndCheck
</del><span class="cx"> || edge->op() == SetArgument
</span><span class="cx"> || edge->op() == Flush);
</span><span class="cx">
</span><span class="lines">@@ -292,9 +286,6 @@
</span><span class="cx"> VALIDATE(
</span><span class="cx"> (local, block->predecessors[k], prevNode),
</span><span class="cx"> prevNode->op() == SetLocal
</span><del>- || prevNode->op() == MovHint
- || prevNode->op() == MovHintAndCheck
- || prevNode->op() == ZombieHint
</del><span class="cx"> || prevNode->op() == SetArgument
</span><span class="cx"> || prevNode->op() == Phi);
</span><span class="cx"> if (prevNode == edge.node()) {
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGValueSourceh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGValueSource.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGValueSource.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGValueSource.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -122,7 +122,7 @@
</span><span class="cx"> explicit ValueSource(ValueSourceKind valueSourceKind)
</span><span class="cx"> : m_kind(valueSourceKind)
</span><span class="cx"> {
</span><del>- ASSERT(kind() == ArgumentsSource || kind() == SourceIsDead);
</del><ins>+ ASSERT(kind() == ArgumentsSource || kind() == SourceIsDead || kind() == ArgumentsSource);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> explicit ValueSource(MinifiedID id)
</span><span class="lines">@@ -159,6 +159,8 @@
</span><span class="cx"> return ValueSource(CellInJSStack, where);
</span><span class="cx"> case FlushedBoolean:
</span><span class="cx"> return ValueSource(BooleanInJSStack, where);
</span><ins>+ case FlushedArguments:
+ return ValueSource(ArgumentsSource);
</ins><span class="cx"> }
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> return ValueSource();
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGVariableAccessDatah"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGVariableAccessData.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGVariableAccessData.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGVariableAccessData.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -74,6 +74,7 @@
</span><span class="cx"> , m_structureCheckHoistingFailed(false)
</span><span class="cx"> , m_checkArrayHoistingFailed(false)
</span><span class="cx"> , m_isProfitableToUnbox(false)
</span><ins>+ , m_isLoadedFrom(false)
</ins><span class="cx"> , m_doubleFormatState(EmptyDoubleFormatState)
</span><span class="cx"> {
</span><span class="cx"> clearVotes();
</span><span class="lines">@@ -328,6 +329,9 @@
</span><span class="cx"> {
</span><span class="cx"> ASSERT(find() == this);
</span><span class="cx">
</span><ins>+ if (isArgumentsAlias())
+ return FlushedArguments;
+
</ins><span class="cx"> if (!shouldUnboxIfPossible())
</span><span class="cx"> return FlushedJSValue;
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredfgDFGVariableEventStreamcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -192,70 +192,8 @@
</span><span class="cx">
</span><span class="cx"> MinifiedGenerationInfo info = generationInfos.get(source.id());
</span><span class="cx"> if (info.format == DataFormatNone) {
</span><del>- // Try to see if there is an alternate node that would contain the value we want.
- //
- // Backward rewiring refers to:
- //
- // a: Something(...)
- // b: Id(@a) // some identity function
- // c: SetLocal(@b)
- //
- // Where we find @b being dead, but @a is still alive.
- //
- // Forward rewiring refers to:
- //
- // a: Something(...)
- // b: SetLocal(@a)
- // c: Id(@a) // some identity function
- //
- // Where we find @a being dead, but @b is still alive.
-
- bool found = false;
-
- if (node && permitsOSRBackwardRewiring(node->op())) {
- MinifiedID id = node->child1();
- if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, graph.at(id)))
- continue;
- info = generationInfos.get(id);
- if (info.format != DataFormatNone)
- found = true;
- }
-
- if (!found) {
- MinifiedID bestID;
- unsigned bestScore = 0;
-
- HashMap<MinifiedID, MinifiedGenerationInfo>::iterator iter = generationInfos.begin();
- HashMap<MinifiedID, MinifiedGenerationInfo>::iterator end = generationInfos.end();
- for (; iter != end; ++iter) {
- MinifiedID id = iter->key;
- node = graph.at(id);
- if (!node)
- continue;
- if (!node->hasChild1())
- continue;
- if (node->child1() != source.id())
- continue;
- if (iter->value.format == DataFormatNone)
- continue;
- unsigned myScore = forwardRewiringSelectionScore(node->op());
- if (myScore <= bestScore)
- continue;
- bestID = id;
- bestScore = myScore;
- }
-
- if (!!bestID) {
- info = generationInfos.get(bestID);
- ASSERT(info.format != DataFormatNone);
- found = true;
- }
- }
-
- if (!found) {
- valueRecoveries[i] = ValueRecovery::constant(jsUndefined());
- continue;
- }
</del><ins>+ valueRecoveries[i] = ValueRecovery::constant(jsUndefined());
+ continue;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> ASSERT(info.format != DataFormatNone);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -42,7 +42,6 @@
</span><span class="cx"> case WeakJSConstant:
</span><span class="cx"> case GetLocal:
</span><span class="cx"> case SetLocal:
</span><del>- case MovHintAndCheck:
</del><span class="cx"> case MovHint:
</span><span class="cx"> case ZombieHint:
</span><span class="cx"> case Phantom:
</span><span class="lines">@@ -111,6 +110,7 @@
</span><span class="cx"> case LogicalNot:
</span><span class="cx"> case CheckInBounds:
</span><span class="cx"> case ConstantStoragePointer:
</span><ins>+ case Check:
</ins><span class="cx"> // These are OK.
</span><span class="cx"> break;
</span><span class="cx"> case GetById:
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -253,8 +253,6 @@
</span><span class="cx">
</span><span class="cx"> bool shouldExecuteEffects = m_interpreter.startExecuting(m_node);
</span><span class="cx">
</span><del>- m_direction = (m_node->flags() & NodeExitsForward) ? ForwardSpeculation : BackwardSpeculation;
-
</del><span class="cx"> switch (m_node->op()) {
</span><span class="cx"> case Upsilon:
</span><span class="cx"> compileUpsilon();
</span><span class="lines">@@ -285,14 +283,13 @@
</span><span class="cx"> case ZombieHint:
</span><span class="cx"> compileZombieHint();
</span><span class="cx"> break;
</span><del>- case MovHintAndCheck:
- compileMovHintAndCheck();
- break;
</del><span class="cx"> case Phantom:
</span><span class="cx"> compilePhantom();
</span><span class="cx"> break;
</span><del>- case ArithAdd:
</del><span class="cx"> case ValueAdd:
</span><ins>+ compileValueAdd();
+ break;
+ case ArithAdd:
</ins><span class="cx"> compileAddSub();
</span><span class="cx"> break;
</span><span class="cx"> case ArithSub:
</span><span class="lines">@@ -682,15 +679,15 @@
</span><span class="cx">
</span><span class="cx"> switch (useKindFor(variable->flushFormat())) {
</span><span class="cx"> case Int32Use:
</span><del>- speculateBackward(BadType, jsValueValue(jsValue), m_node, isNotInt32(jsValue));
</del><ins>+ speculate(BadType, jsValueValue(jsValue), m_node, isNotInt32(jsValue));
</ins><span class="cx"> setInt32(unboxInt32(jsValue));
</span><span class="cx"> break;
</span><span class="cx"> case CellUse:
</span><del>- speculateBackward(BadType, jsValueValue(jsValue), m_node, isNotCell(jsValue));
</del><ins>+ speculate(BadType, jsValueValue(jsValue), m_node, isNotCell(jsValue));
</ins><span class="cx"> setJSValue(jsValue);
</span><span class="cx"> break;
</span><span class="cx"> case BooleanUse:
</span><del>- speculateBackward(BadType, jsValueValue(jsValue), m_node, isNotBoolean(jsValue));
</del><ins>+ speculate(BadType, jsValueValue(jsValue), m_node, isNotBoolean(jsValue));
</ins><span class="cx"> setBoolean(unboxBoolean(jsValue));
</span><span class="cx"> break;
</span><span class="cx"> case UntypedUse:
</span><span class="lines">@@ -726,8 +723,6 @@
</span><span class="cx">
</span><span class="cx"> void compileSetLocal()
</span><span class="cx"> {
</span><del>- observeMovHint(m_node);
-
</del><span class="cx"> VariableAccessData* variable = m_node->variableAccessData();
</span><span class="cx"> switch (variable->flushFormat()) {
</span><span class="cx"> case FlushedJSValue: {
</span><span class="lines">@@ -778,24 +773,34 @@
</span><span class="cx">
</span><span class="cx"> void compileMovHint()
</span><span class="cx"> {
</span><del>- observeMovHint(m_node);
</del><ins>+ ASSERT(m_node->containsMovHint());
+ ASSERT(m_node->op() != ZombieHint);
+
+ VirtualRegister operand = m_node->unlinkedLocal();
+ m_availability.operand(operand) = Availability(m_node->child1().node());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void compileZombieHint()
</span><span class="cx"> {
</span><del>- VariableAccessData* data = m_node->variableAccessData();
- m_availability.operand(data->local()) = Availability::unavailable();
</del><ins>+ m_availability.operand(m_node->unlinkedLocal()) = Availability::unavailable();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- void compileMovHintAndCheck()
</del><ins>+ void compilePhantom()
</ins><span class="cx"> {
</span><del>- observeMovHint(m_node);
- speculate(m_node->child1());
</del><ins>+ DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- void compilePhantom()
</del><ins>+ void compileValueAdd()
</ins><span class="cx"> {
</span><del>- DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
</del><ins>+ J_JITOperation_EJJ operation;
+ if (!(m_state.forNode(m_node->child1()).m_type & SpecFullNumber)
+ && !(m_state.forNode(m_node->child2()).m_type & SpecFullNumber))
+ operation = operationValueAddNotNumber;
+ else
+ operation = operationValueAdd;
+ setJSValue(vmCall(
+ m_out.operation(operation), m_callFrame,
+ lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void compileAddSub()
</span><span class="lines">@@ -806,7 +811,7 @@
</span><span class="cx"> LValue left = lowInt32(m_node->child1());
</span><span class="cx"> LValue right = lowInt32(m_node->child2());
</span><span class="cx">
</span><del>- if (bytecodeCanTruncateInteger(m_node->arithNodeFlags())) {
</del><ins>+ if (!shouldCheckOverflow(m_node->arithMode())) {
</ins><span class="cx"> setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="lines">@@ -860,7 +865,7 @@
</span><span class="cx">
</span><span class="cx"> LValue result;
</span><span class="cx">
</span><del>- if (bytecodeCanTruncateInteger(m_node->arithNodeFlags()))
</del><ins>+ if (!shouldCheckOverflow(m_node->arithMode()))
</ins><span class="cx"> result = m_out.mul(left, right);
</span><span class="cx"> else {
</span><span class="cx"> LValue overflowResult = m_out.mulWithOverflow32(left, right);
</span><span class="lines">@@ -868,7 +873,7 @@
</span><span class="cx"> result = m_out.extractValue(overflowResult, 0);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(m_node->arithMode())) {
</ins><span class="cx"> LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
</span><span class="cx"> LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
</span><span class="cx">
</span><span class="lines">@@ -894,7 +899,7 @@
</span><span class="cx"> speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
</span><span class="cx"> LValue result = m_out.extractValue(overflowResult, 0);
</span><span class="cx">
</span><del>- if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(m_node->arithMode())) {
</ins><span class="cx"> LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
</span><span class="cx"> LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
</span><span class="cx">
</span><span class="lines">@@ -944,7 +949,7 @@
</span><span class="cx">
</span><span class="cx"> LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
</span><span class="cx">
</span><del>- if (bytecodeUsesAsNumber(m_node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckOverflow(m_node->arithMode())) {
</ins><span class="cx"> LValue cond = m_out.bitOr(m_out.isZero32(denominator), m_out.equal(numerator, neg2ToThe31));
</span><span class="cx"> speculate(Overflow, noValue(), 0, cond);
</span><span class="cx"> m_out.jump(continuation);
</span><span class="lines">@@ -974,7 +979,7 @@
</span><span class="cx">
</span><span class="cx"> m_out.appendTo(continuation, done);
</span><span class="cx">
</span><del>- if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckNegativeZero(m_node->arithMode())) {
</ins><span class="cx"> LBasicBlock zeroNumerator = FTL_NEW_BLOCK(m_out, ("ArithDivMod zero numerator"));
</span><span class="cx"> LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithDivMod numerator continuation"));
</span><span class="cx">
</span><span class="lines">@@ -994,7 +999,7 @@
</span><span class="cx"> ? m_out.div(numerator, denominator)
</span><span class="cx"> : m_out.rem(numerator, denominator);
</span><span class="cx">
</span><del>- if (bytecodeUsesAsNumber(m_node->arithNodeFlags())) {
</del><ins>+ if (shouldCheckOverflow(m_node->arithMode())) {
</ins><span class="cx"> speculate(
</span><span class="cx"> Overflow, noValue(), 0,
</span><span class="cx"> m_out.notEqual(m_out.mul(divModResult, denominator), numerator));
</span><span class="lines">@@ -1106,9 +1111,9 @@
</span><span class="cx"> LValue value = lowInt32(m_node->child1());
</span><span class="cx">
</span><span class="cx"> LValue result;
</span><del>- if (bytecodeCanTruncateInteger(m_node->arithNodeFlags()))
</del><ins>+ if (!shouldCheckOverflow(m_node->arithMode()))
</ins><span class="cx"> result = m_out.neg(value);
</span><del>- else if (bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) {
</del><ins>+ else if (!shouldCheckNegativeZero(m_node->arithMode())) {
</ins><span class="cx"> // We don't have a negate-with-overflow intrinsic. Hopefully this
</span><span class="cx"> // does the trick, though.
</span><span class="cx"> LValue overflowResult = m_out.subWithOverflow32(m_out.int32Zero, value);
</span><span class="lines">@@ -1128,7 +1133,7 @@
</span><span class="cx"> Int52Kind kind;
</span><span class="cx"> LValue value = lowWhicheverInt52(m_node->child1(), kind);
</span><span class="cx"> LValue result = m_out.neg(value);
</span><del>- if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags()))
</del><ins>+ if (shouldCheckNegativeZero(m_node->arithMode()))
</ins><span class="cx"> speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
</span><span class="cx"> setInt52(result, kind);
</span><span class="cx"> break;
</span><span class="lines">@@ -1194,7 +1199,7 @@
</span><span class="cx"> {
</span><span class="cx"> LValue value = lowInt32(m_node->child1());
</span><span class="cx">
</span><del>- if (!nodeCanSpeculateInt32(m_node->arithNodeFlags())) {
</del><ins>+ if (doesOverflow(m_node->arithMode())) {
</ins><span class="cx"> setDouble(m_out.unsignedToDouble(value));
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="lines">@@ -1205,40 +1210,7 @@
</span><span class="cx">
</span><span class="cx"> void compileInt32ToDouble()
</span><span class="cx"> {
</span><del>- if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecFullNumber)
- || m_node->speculationDirection() == BackwardSpeculation) {
- setDouble(lowDouble(m_node->child1()));
- return;
- }
-
- LValue boxedValue = lowJSValue(m_node->child1(), ManualOperandSpeculation);
-
- LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("Double unboxing int case"));
- LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("Double unboxing double case"));
- LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Double unboxing continuation"));
-
- m_out.branch(isNotInt32(boxedValue), doubleCase, intCase);
-
- LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
-
- ValueFromBlock intToDouble = m_out.anchor(
- m_out.intToDouble(unboxInt32(boxedValue)));
- m_out.jump(continuation);
-
- m_out.appendTo(doubleCase, continuation);
-
- forwardTypeCheck(
- jsValueValue(boxedValue), m_node->child1(), SpecFullNumber,
- isCellOrMisc(boxedValue), jsValueValue(boxedValue));
-
- ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedValue));
- m_out.jump(continuation);
-
- m_out.appendTo(continuation, lastNext);
-
- LValue result = m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
-
- setDouble(result);
</del><ins>+ setDouble(lowDouble(m_node->child1()));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void compileCheckStructure()
</span><span class="lines">@@ -3226,26 +3198,10 @@
</span><span class="cx"> return m_out.phi(m_out.int32, fastResult, slowResult);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void speculateBackward(
- ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
- {
- appendOSRExit(
- kind, lowValue, highValue, failCondition, BackwardSpeculation, FormattedValue());
- }
-
- void speculateForward(
- ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition,
- const FormattedValue& recovery)
- {
- appendOSRExit(
- kind, lowValue, highValue, failCondition, ForwardSpeculation, recovery);
- }
-
</del><span class="cx"> void speculate(
</span><span class="cx"> ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
</span><span class="cx"> {
</span><del>- appendOSRExit(
- kind, lowValue, highValue, failCondition, m_direction, FormattedValue());
</del><ins>+ appendOSRExit(kind, lowValue, highValue, failCondition);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void terminate(ExitKind kind)
</span><span class="lines">@@ -3253,41 +3209,21 @@
</span><span class="cx"> speculate(kind, noValue(), 0, m_out.booleanTrue);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void backwardTypeCheck(
- FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
- LValue failCondition)
- {
- appendTypeCheck(
- lowValue, highValue, typesPassedThrough, failCondition, BackwardSpeculation,
- FormattedValue());
- }
-
- void forwardTypeCheck(
- FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
- LValue failCondition, const FormattedValue& recovery)
- {
- appendTypeCheck(
- lowValue, highValue, typesPassedThrough, failCondition, ForwardSpeculation,
- recovery);
- }
-
</del><span class="cx"> void typeCheck(
</span><span class="cx"> FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
</span><span class="cx"> LValue failCondition)
</span><span class="cx"> {
</span><del>- appendTypeCheck(
- lowValue, highValue, typesPassedThrough, failCondition, m_direction,
- FormattedValue());
</del><ins>+ appendTypeCheck(lowValue, highValue, typesPassedThrough, failCondition);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void appendTypeCheck(
</span><span class="cx"> FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
</span><del>- LValue failCondition, SpeculationDirection direction, FormattedValue recovery)
</del><ins>+ LValue failCondition)
</ins><span class="cx"> {
</span><span class="cx"> if (!m_interpreter.needsTypeCheck(highValue, typesPassedThrough))
</span><span class="cx"> return;
</span><span class="cx"> ASSERT(mayHaveTypeCheck(highValue.useKind()));
</span><del>- appendOSRExit(BadType, lowValue, highValue.node(), failCondition, direction, recovery);
</del><ins>+ appendOSRExit(BadType, lowValue, highValue.node(), failCondition);
</ins><span class="cx"> m_interpreter.filter(highValue, typesPassedThrough);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -4122,8 +4058,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void appendOSRExit(
</span><del>- ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition,
- SpeculationDirection direction, FormattedValue recovery)
</del><ins>+ ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
</ins><span class="cx"> {
</span><span class="cx"> if (verboseCompilationEnabled())
</span><span class="cx"> dataLog(" OSR exit #", m_ftlState.jitCode->osrExit.size(), " with availability: ", m_availability, "\n");
</span><span class="lines">@@ -4148,38 +4083,20 @@
</span><span class="cx">
</span><span class="cx"> lastNext = m_out.appendTo(failCase, continuation);
</span><span class="cx">
</span><del>- emitOSRExitCall(exit, lowValue, direction, recovery);
</del><ins>+ emitOSRExitCall(exit, lowValue);
</ins><span class="cx">
</span><span class="cx"> m_out.unreachable();
</span><span class="cx">
</span><span class="cx"> m_out.appendTo(continuation, lastNext);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void emitOSRExitCall(
- OSRExit& exit, FormattedValue lowValue, SpeculationDirection direction,
- FormattedValue recovery)
</del><ins>+ void emitOSRExitCall(OSRExit& exit, FormattedValue lowValue)
</ins><span class="cx"> {
</span><span class="cx"> ExitArgumentList arguments;
</span><span class="cx">
</span><span class="cx"> CodeOrigin codeOrigin = exit.m_codeOrigin;
</span><span class="cx">
</span><del>- if (direction == BackwardSpeculation)
- buildExitArguments(exit, arguments, lowValue, codeOrigin);
- else {
- ASSERT(direction == ForwardSpeculation);
- if (!recovery) {
- for (unsigned nodeIndex = m_nodeIndex; nodeIndex < m_highBlock->size(); ++nodeIndex) {
- Node* node = m_highBlock->at(nodeIndex);
- if (node->codeOriginForExitTarget == codeOrigin)
- continue;
- codeOrigin = node->codeOriginForExitTarget;
- break;
- }
- }
-
- buildExitArguments(exit, arguments, lowValue, codeOrigin);
- exit.convertToForward(m_highBlock, m_node, m_nodeIndex, recovery, arguments);
- }
</del><ins>+ buildExitArguments(exit, arguments, lowValue, codeOrigin);
</ins><span class="cx">
</span><span class="cx"> callStackmap(exit, arguments);
</span><span class="cx"> }
</span><span class="lines">@@ -4238,6 +4155,12 @@
</span><span class="cx"> case FlushedDouble:
</span><span class="cx"> exit.m_values[i] = ExitValue::inJSStackAsDouble(flush.virtualRegister());
</span><span class="cx"> break;
</span><ins>+
+ case FlushedArguments:
+ // FIXME: implement PhantomArguments.
+ // https://bugs.webkit.org/show_bug.cgi?id=113986
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -4332,16 +4255,6 @@
</span><span class="cx"> arguments.append(value);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void observeMovHint(Node* node)
- {
- ASSERT(node->containsMovHint());
- ASSERT(node->op() != ZombieHint);
-
- VirtualRegister operand = node->local();
-
- m_availability.operand(operand) = Availability(node->child1().node());
- }
-
</del><span class="cx"> void setInt32(Node* node, LValue value)
</span><span class="cx"> {
</span><span class="cx"> m_int32Values.set(node, LoweredNodeValue(value, m_highBlock));
</span><span class="lines">@@ -4515,7 +4428,6 @@
</span><span class="cx"> CodeOrigin m_codeOriginForExitProfile;
</span><span class="cx"> unsigned m_nodeIndex;
</span><span class="cx"> Node* m_node;
</span><del>- SpeculationDirection m_direction;
</del><span class="cx">
</span><span class="cx"> uint32_t m_stackmapIDs;
</span><span class="cx"> };
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLOSRExitcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExit.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExit.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExit.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -61,41 +61,6 @@
</span><span class="cx"> m_patchableCodeOffset);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void OSRExit::convertToForward(
- BasicBlock* block, Node* currentNode, unsigned nodeIndex,
- const FormattedValue &value, ExitArgumentList& arguments)
-{
- Node* node;
- Node* lastMovHint;
- if (!doSearchForForwardConversion(block, currentNode, nodeIndex, !!value, node, lastMovHint))
- return;
-
- ASSERT(node->codeOrigin != currentNode->codeOrigin);
-
- m_codeOrigin = node->codeOrigin;
-
- if (!value)
- return;
-
- VirtualRegister overriddenOperand = lastMovHint->local();
-
- // Is the value for this operand being passed as an argument to the exit, or is
- // it something else? If it's an argument already, then replace that argument;
- // otherwise add another argument.
- if (m_values.operand(overriddenOperand).isArgument()) {
- ExitArgument exitArgument = m_values.operand(overriddenOperand).exitArgument();
- arguments[exitArgument.argument()] = value.value();
- m_values.operand(overriddenOperand) = ExitValue::exitArgument(
- exitArgument.withFormat(value.format()));
- return;
- }
-
- unsigned argument = arguments.size();
- arguments.append(value.value());
- m_values.operand(overriddenOperand) = ExitValue::exitArgument(
- ExitArgument(value.format(), argument));
-}
-
</del><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(FTL_JIT)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLOSRExith"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExit.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExit.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExit.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -166,10 +166,6 @@
</span><span class="cx"> uint32_t m_stackmapID;
</span><span class="cx">
</span><span class="cx"> CodeLocationJump codeLocationForRepatch(CodeBlock* ftlCodeBlock) const;
</span><del>-
- void convertToForward(
- DFG::BasicBlock*, DFG::Node* currentNode, unsigned nodeIndex,
- const FormattedValue&, ExitArgumentList& arguments);
</del><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } } // namespace JSC::FTL
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitGPRInfoh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/GPRInfo.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/GPRInfo.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/GPRInfo.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -574,10 +574,6 @@
</span><span class="cx"> static const GPRReg returnValueGPR2 = ARM64Registers::x1; // regT1
</span><span class="cx"> static const GPRReg nonPreservedNonReturnGPR = ARM64Registers::x2;
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
- static const GPRReg bucketCounterRegister = ARM64Registers::x7;
-#endif
-
</del><span class="cx"> // GPRReg mapping is direct, the machine regsiter numbers can
</span><span class="cx"> // be used directly as indices into the GPR RegisterBank.
</span><span class="cx"> COMPILE_ASSERT(ARM64Registers::q0 == 0, q0_is_0);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JIT.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JIT.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JIT.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -84,10 +84,8 @@
</span><span class="cx"> , m_byValInstructionIndex(UINT_MAX)
</span><span class="cx"> , m_callLinkInfoIndex(UINT_MAX)
</span><span class="cx"> , m_randomGenerator(cryptographicallyRandomNumber())
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> , m_canBeOptimized(false)
</span><span class="cx"> , m_shouldEmitProfiling(false)
</span><del>-#endif
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -336,7 +334,6 @@
</span><span class="cx"> m_byValInstructionIndex = 0;
</span><span class="cx"> m_callLinkInfoIndex = 0;
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> // Use this to assert that slow-path code associates new profiling sites with existing
</span><span class="cx"> // ValueProfiles rather than creating new ones. This ensures that for a given instruction
</span><span class="cx"> // (say, get_by_id) we get combined statistics for both the fast-path executions of that
</span><span class="lines">@@ -344,7 +341,6 @@
</span><span class="cx"> // new ValueProfiles then the ValueProfiles would no longer be sorted by bytecode offset,
</span><span class="cx"> // which would break the invariant necessary to use CodeBlock::valueProfileForBytecodeOffset().
</span><span class="cx"> unsigned numberOfValueProfiles = m_codeBlock->numberOfValueProfiles();
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end();) {
</span><span class="cx"> m_bytecodeOffset = iter->to;
</span><span class="lines">@@ -353,11 +349,9 @@
</span><span class="cx">
</span><span class="cx"> Instruction* currentInstruction = instructionsBegin + m_bytecodeOffset;
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> RareCaseProfile* rareCaseProfile = 0;
</span><span class="cx"> if (shouldEmitProfiling())
</span><span class="cx"> rareCaseProfile = m_codeBlock->addRareCaseProfile(m_bytecodeOffset);
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> #if ENABLE(JIT_VERBOSE)
</span><span class="cx"> dataLogF("Old JIT emitting slow code for bc#%u at offset 0x%lx.\n", m_bytecodeOffset, (long)debugOffset());
</span><span class="lines">@@ -438,10 +432,8 @@
</span><span class="cx"> RELEASE_ASSERT_WITH_MESSAGE(iter == m_slowCases.end() || firstTo != iter->to, "Not enough jumps linked in slow case codegen.");
</span><span class="cx"> RELEASE_ASSERT_WITH_MESSAGE(firstTo == (iter - 1)->to, "Too many jumps linked in slow case codegen.");
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> if (shouldEmitProfiling())
</span><span class="cx"> add32(TrustedImm32(1), AbsoluteAddress(&rareCaseProfile->m_counter));
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> emitJumpSlowToHot(jump(), 0);
</span><span class="cx"> }
</span><span class="lines">@@ -449,9 +441,7 @@
</span><span class="cx"> RELEASE_ASSERT(m_getByIdIndex == m_getByIds.size());
</span><span class="cx"> RELEASE_ASSERT(m_putByIdIndex == m_putByIds.size());
</span><span class="cx"> RELEASE_ASSERT(m_callLinkInfoIndex == m_callStructureStubCompilationInfo.size());
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> RELEASE_ASSERT(numberOfValueProfiles == m_codeBlock->numberOfValueProfiles());
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> #ifndef NDEBUG
</span><span class="cx"> // Reset this, in order to guard its use with ASSERTs.
</span><span class="lines">@@ -461,7 +451,6 @@
</span><span class="cx">
</span><span class="cx"> CompilationResult JIT::privateCompile(JITCompilationEffort effort)
</span><span class="cx"> {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> DFG::CapabilityLevel level = m_codeBlock->capabilityLevel();
</span><span class="cx"> switch (level) {
</span><span class="cx"> case DFG::CannotCompile:
</span><span class="lines">@@ -496,7 +485,6 @@
</span><span class="cx"> m_codeBlock->m_shouldAlwaysBeInlined &= canInline(level) && DFG::mightInlineFunction(m_codeBlock);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> if (Options::showDisassembly() || m_vm->m_perBytecodeProfiler)
</span><span class="cx"> m_disassembler = adoptPtr(new JITDisassembler(m_codeBlock));
</span><span class="lines">@@ -527,7 +515,6 @@
</span><span class="cx">
</span><span class="cx"> Jump stackOverflow;
</span><span class="cx"> if (m_codeBlock->codeType() == FunctionCode) {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> ASSERT(m_bytecodeOffset == (unsigned)-1);
</span><span class="cx"> if (shouldEmitProfiling()) {
</span><span class="cx"> for (int argument = 0; argument < m_codeBlock->numParameters(); ++argument) {
</span><span class="lines">@@ -542,10 +529,9 @@
</span><span class="cx"> load32(Address(callFrameRegister, offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
</span><span class="cx"> load32(Address(callFrameRegister, offset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
</span><span class="cx"> #endif
</span><del>- emitValueProfilingSite(m_codeBlock->valueProfileForArgument(argument), regT4);
</del><ins>+ emitValueProfilingSite(m_codeBlock->valueProfileForArgument(argument));
</ins><span class="cx"> }
</span><span class="cx"> }
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, regT1);
</span><span class="cx"> stackOverflow = branchPtr(Above, AbsoluteAddress(m_vm->addressOfJSStackLimit()), regT1);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JIT.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JIT.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JIT.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -320,16 +320,11 @@
</span><span class="cx"> template<typename StructureType> // StructureType can be RegisterID or ImmPtr.
</span><span class="cx"> void emitAllocateJSObject(RegisterID allocator, StructureType, RegisterID result, RegisterID scratch);
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> // This assumes that the value to profile is in regT0 and that regT3 is available for
</span><span class="cx"> // scratch.
</span><del>- void emitValueProfilingSite(ValueProfile*, RegisterID);
- void emitValueProfilingSite(unsigned bytecodeOffset, RegisterID);
- void emitValueProfilingSite(RegisterID);
-#else
- void emitValueProfilingSite(unsigned, RegisterID) { }
- void emitValueProfilingSite(RegisterID) { }
-#endif
</del><ins>+ void emitValueProfilingSite(ValueProfile*);
+ void emitValueProfilingSite(unsigned bytecodeOffset);
+ void emitValueProfilingSite();
</ins><span class="cx"> void emitArrayProfilingSite(RegisterID structureAndIndexingType, RegisterID scratch, ArrayProfile*);
</span><span class="cx"> void emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndIndexingType, RegisterID scratch, unsigned bytecodeIndex);
</span><span class="cx"> void emitArrayProfileStoreToHoleSpecialCase(ArrayProfile*);
</span><span class="lines">@@ -816,11 +811,9 @@
</span><span class="cx"> WeakRandom m_randomGenerator;
</span><span class="cx"> static CodeRef stringGetByValStubGenerator(VM*);
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> bool m_canBeOptimized;
</span><span class="cx"> bool m_canBeOptimizedOrInlined;
</span><span class="cx"> bool m_shouldEmitProfiling;
</span><del>-#endif
</del><span class="cx"> } JIT_CLASS_ALIGNMENT;
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITArithmeticcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITArithmetic.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITArithmetic.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITArithmetic.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -668,16 +668,13 @@
</span><span class="cx"> emitGetVirtualRegisters(op1, regT0, op2, regT1);
</span><span class="cx"> emitJumpSlowCaseIfNotImmediateInteger(regT0);
</span><span class="cx"> emitJumpSlowCaseIfNotImmediateInteger(regT1);
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> RareCaseProfile* profile = m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset);
</span><del>-#endif
</del><span class="cx"> if (opcodeID == op_add)
</span><span class="cx"> addSlowCase(branchAdd32(Overflow, regT1, regT0));
</span><span class="cx"> else if (opcodeID == op_sub)
</span><span class="cx"> addSlowCase(branchSub32(Overflow, regT1, regT0));
</span><span class="cx"> else {
</span><span class="cx"> ASSERT(opcodeID == op_mul);
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> if (shouldEmitProfiling()) {
</span><span class="cx"> // We want to be able to measure if this is taking the slow case just
</span><span class="cx"> // because of negative zero. If this produces positive zero, then we
</span><span class="lines">@@ -701,10 +698,6 @@
</span><span class="cx"> addSlowCase(branchMul32(Overflow, regT1, regT0));
</span><span class="cx"> addSlowCase(branchTest32(Zero, regT0));
</span><span class="cx"> }
</span><del>-#else
- addSlowCase(branchMul32(Overflow, regT1, regT0));
- addSlowCase(branchTest32(Zero, regT0));
-#endif
</del><span class="cx"> }
</span><span class="cx"> emitFastArithIntToImmNoCheck(regT0, regT0);
</span><span class="cx"> }
</span><span class="lines">@@ -849,19 +842,15 @@
</span><span class="cx"> // For now, only plant a fast int case if the constant operand is greater than zero.
</span><span class="cx"> int32_t value;
</span><span class="cx"> if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> // Add a special fast case profile because the DFG JIT will expect one.
</span><span class="cx"> m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset);
</span><del>-#endif
</del><span class="cx"> emitGetVirtualRegister(op2, regT0);
</span><span class="cx"> emitJumpSlowCaseIfNotImmediateInteger(regT0);
</span><span class="cx"> addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT1));
</span><span class="cx"> emitFastArithReTagImmediate(regT1, regT0);
</span><span class="cx"> } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> // Add a special fast case profile because the DFG JIT will expect one.
</span><span class="cx"> m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset);
</span><del>-#endif
</del><span class="cx"> emitGetVirtualRegister(op1, regT0);
</span><span class="cx"> emitJumpSlowCaseIfNotImmediateInteger(regT0);
</span><span class="cx"> addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT1));
</span><span class="lines">@@ -930,7 +919,6 @@
</span><span class="cx"> }
</span><span class="cx"> divDouble(fpRegT1, fpRegT0);
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> // Is the result actually an integer? The DFG JIT would really like to know. If it's
</span><span class="cx"> // not an integer, we increment a count. If this together with the slow case counter
</span><span class="cx"> // are below threshold then the DFG JIT will compile this division with a specualtion
</span><span class="lines">@@ -957,11 +945,6 @@
</span><span class="cx"> move(tagTypeNumberRegister, regT0);
</span><span class="cx"> trueDouble.link(this);
</span><span class="cx"> isInteger.link(this);
</span><del>-#else
- // Double result.
- moveDoubleTo64(fpRegT0, regT0);
- sub64(tagTypeNumberRegister, regT0);
-#endif
</del><span class="cx">
</span><span class="cx"> emitPutVirtualRegister(dst, regT0);
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITArithmetic32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -742,7 +742,6 @@
</span><span class="cx"> emitLoadDouble(op1, fpRegT1);
</span><span class="cx"> divDouble(fpRegT0, fpRegT1);
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> // Is the result actually an integer? The DFG JIT would really like to know. If it's
</span><span class="cx"> // not an integer, we increment a count. If this together with the slow case counter
</span><span class="cx"> // are below threshold then the DFG JIT will compile this division with a specualtion
</span><span class="lines">@@ -766,9 +765,6 @@
</span><span class="cx"> add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
</span><span class="cx"> emitStoreDouble(dst, fpRegT1);
</span><span class="cx"> isInteger.link(this);
</span><del>-#else
- emitStoreDouble(dst, fpRegT1);
-#endif
</del><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case op_jless:
</span><span class="lines">@@ -846,7 +842,6 @@
</span><span class="cx"> case op_div: {
</span><span class="cx"> emitLoadDouble(op2, fpRegT2);
</span><span class="cx"> divDouble(fpRegT2, fpRegT0);
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> // Is the result actually an integer? The DFG JIT would really like to know. If it's
</span><span class="cx"> // not an integer, we increment a count. If this together with the slow case counter
</span><span class="cx"> // are below threshold then the DFG JIT will compile this division with a specualtion
</span><span class="lines">@@ -870,9 +865,6 @@
</span><span class="cx"> add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
</span><span class="cx"> emitStoreDouble(dst, fpRegT0);
</span><span class="cx"> isInteger.link(this);
</span><del>-#else
- emitStoreDouble(dst, fpRegT0);
-#endif
</del><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case op_jless:
</span><span class="lines">@@ -924,9 +916,7 @@
</span><span class="cx"> int op2 = currentInstruction[3].u.operand;
</span><span class="cx"> OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset);
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> JumpList notInt32Op1;
</span><span class="cx"> JumpList notInt32Op2;
</span><span class="lines">@@ -969,12 +959,10 @@
</span><span class="cx"> emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_mul));
</span><span class="cx">
</span><span class="cx"> negZero.link(this);
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> // We only get here if we have a genuine negative zero. Record this,
</span><span class="cx"> // so that the speculative JIT knows that we failed speculation
</span><span class="cx"> // because of a negative zero.
</span><span class="cx"> add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
</span><del>-#endif
</del><span class="cx"> overflow.link(this);
</span><span class="cx">
</span><span class="cx"> if (!supportsFloatingPoint()) {
</span><span class="lines">@@ -1005,9 +993,7 @@
</span><span class="cx"> int op2 = currentInstruction[3].u.operand;
</span><span class="cx"> OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset);
</span><del>-#endif
</del><span class="cx">
</span><span class="cx"> if (!supportsFloatingPoint()) {
</span><span class="cx"> addSlowCase(jump());
</span><span class="lines">@@ -1028,7 +1014,6 @@
</span><span class="cx"> convertInt32ToDouble(regT0, fpRegT0);
</span><span class="cx"> convertInt32ToDouble(regT2, fpRegT1);
</span><span class="cx"> divDouble(fpRegT1, fpRegT0);
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> // Is the result actually an integer? The DFG JIT would really like to know. If it's
</span><span class="cx"> // not an integer, we increment a count. If this together with the slow case counter
</span><span class="cx"> // are below threshold then the DFG JIT will compile this division with a specualtion
</span><span class="lines">@@ -1051,9 +1036,6 @@
</span><span class="cx"> notInteger.link(this);
</span><span class="cx"> add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
</span><span class="cx"> emitStoreDouble(dst, fpRegT0);
</span><del>-#else
- emitStoreDouble(dst, fpRegT0);
-#endif
</del><span class="cx"> end.append(jump());
</span><span class="cx">
</span><span class="cx"> // Double divide.
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITCallcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITCall.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITCall.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITCall.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx"> void JIT::emitPutCallResult(Instruction* instruction)
</span><span class="cx"> {
</span><span class="cx"> int dst = instruction[1].u.operand;
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> emitPutVirtualRegister(dst);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITCall32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITCall32_64.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITCall32_64.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITCall32_64.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx"> void JIT::emitPutCallResult(Instruction* instruction)
</span><span class="cx"> {
</span><span class="cx"> int dst = instruction[1].u.operand;
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> emitStore(dst, regT1, regT0);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITInlinesh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITInlines.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITInlines.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITInlines.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -142,7 +142,7 @@
</span><span class="cx"> ALWAYS_INLINE MacroAssembler::Call JIT::appendCallWithExceptionCheckSetJSValueResultWithProfile(const FunctionPtr& function, int dst)
</span><span class="cx"> {
</span><span class="cx"> MacroAssembler::Call call = appendCallWithExceptionCheck(function);
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx"> emitPutVirtualRegister(dst, returnValueGPR);
</span><span class="cx"> #else
</span><span class="lines">@@ -681,8 +681,7 @@
</span><span class="cx"> storePtr(TrustedImmPtr(0), Address(result, JSObject::butterflyOffset()));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
-inline void JIT::emitValueProfilingSite(ValueProfile* valueProfile, RegisterID bucketCounterRegister)
</del><ins>+inline void JIT::emitValueProfilingSite(ValueProfile* valueProfile)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(shouldEmitProfiling());
</span><span class="cx"> ASSERT(valueProfile);
</span><span class="lines">@@ -691,47 +690,29 @@
</span><span class="cx"> #if USE(JSVALUE32_64)
</span><span class="cx"> const RegisterID valueTag = regT1;
</span><span class="cx"> #endif
</span><del>- const RegisterID scratch = regT3;
</del><span class="cx">
</span><del>- if (ValueProfile::numberOfBuckets == 1) {
- // We're in a simple configuration: only one bucket, so we can just do a direct
- // store.
</del><ins>+ // We're in a simple configuration: only one bucket, so we can just do a direct
+ // store.
</ins><span class="cx"> #if USE(JSVALUE64)
</span><del>- store64(value, valueProfile->m_buckets);
</del><ins>+ store64(value, valueProfile->m_buckets);
</ins><span class="cx"> #else
</span><del>- EncodedValueDescriptor* descriptor = bitwise_cast<EncodedValueDescriptor*>(valueProfile->m_buckets);
- store32(value, &descriptor->asBits.payload);
- store32(valueTag, &descriptor->asBits.tag);
</del><ins>+ EncodedValueDescriptor* descriptor = bitwise_cast<EncodedValueDescriptor*>(valueProfile->m_buckets);
+ store32(value, &descriptor->asBits.payload);
+ store32(valueTag, &descriptor->asBits.tag);
</ins><span class="cx"> #endif
</span><del>- return;
- }
-
- if (m_randomGenerator.getUint32() & 1)
- add32(TrustedImm32(1), bucketCounterRegister);
- else
- add32(TrustedImm32(3), bucketCounterRegister);
- and32(TrustedImm32(ValueProfile::bucketIndexMask), bucketCounterRegister);
- move(TrustedImmPtr(valueProfile->m_buckets), scratch);
-#if USE(JSVALUE64)
- store64(value, BaseIndex(scratch, bucketCounterRegister, TimesEight));
-#elif USE(JSVALUE32_64)
- store32(value, BaseIndex(scratch, bucketCounterRegister, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
- store32(valueTag, BaseIndex(scratch, bucketCounterRegister, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><del>-inline void JIT::emitValueProfilingSite(unsigned bytecodeOffset, RegisterID bucketCounterRegister)
</del><ins>+inline void JIT::emitValueProfilingSite(unsigned bytecodeOffset)
</ins><span class="cx"> {
</span><span class="cx"> if (!shouldEmitProfiling())
</span><span class="cx"> return;
</span><del>- emitValueProfilingSite(m_codeBlock->valueProfileForBytecodeOffset(bytecodeOffset), bucketCounterRegister);
</del><ins>+ emitValueProfilingSite(m_codeBlock->valueProfileForBytecodeOffset(bytecodeOffset));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-inline void JIT::emitValueProfilingSite(RegisterID bucketCounterRegister)
</del><ins>+inline void JIT::emitValueProfilingSite()
</ins><span class="cx"> {
</span><del>- emitValueProfilingSite(m_bytecodeOffset, bucketCounterRegister);
</del><ins>+ emitValueProfilingSite(m_bytecodeOffset);
</ins><span class="cx"> }
</span><del>-#endif // ENABLE(VALUE_PROFILER)
</del><span class="cx">
</span><span class="cx"> inline void JIT::emitArrayProfilingSite(RegisterID structureAndIndexingType, RegisterID scratch, ArrayProfile* arrayProfile)
</span><span class="cx"> {
</span><span class="lines">@@ -748,46 +729,26 @@
</span><span class="cx">
</span><span class="cx"> inline void JIT::emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndIndexingType, RegisterID scratch, unsigned bytecodeIndex)
</span><span class="cx"> {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> emitArrayProfilingSite(structureAndIndexingType, scratch, m_codeBlock->getOrAddArrayProfile(bytecodeIndex));
</span><del>-#else
- UNUSED_PARAM(bytecodeIndex);
- emitArrayProfilingSite(structureAndIndexingType, scratch, 0);
-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline void JIT::emitArrayProfileStoreToHoleSpecialCase(ArrayProfile* arrayProfile)
</span><span class="cx"> {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> store8(TrustedImm32(1), arrayProfile->addressOfMayStoreToHole());
</span><del>-#else
- UNUSED_PARAM(arrayProfile);
-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline void JIT::emitArrayProfileOutOfBoundsSpecialCase(ArrayProfile* arrayProfile)
</span><span class="cx"> {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> store8(TrustedImm32(1), arrayProfile->addressOfOutOfBounds());
</span><del>-#else
- UNUSED_PARAM(arrayProfile);
-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> static inline bool arrayProfileSaw(ArrayModes arrayModes, IndexingType capability)
</span><span class="cx"> {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> return arrayModesInclude(arrayModes, capability);
</span><del>-#else
- UNUSED_PARAM(arrayModes);
- UNUSED_PARAM(capability);
- return false;
-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline JITArrayMode JIT::chooseArrayMode(ArrayProfile* profile)
</span><span class="cx"> {
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> ConcurrentJITLocker locker(m_codeBlock->m_lock);
</span><span class="cx"> profile->computeUpdatedPrediction(locker, m_codeBlock);
</span><span class="cx"> ArrayModes arrayModes = profile->observedArrayModes(locker);
</span><span class="lines">@@ -798,10 +759,6 @@
</span><span class="cx"> if (arrayProfileSaw(arrayModes, ArrayStorageShape))
</span><span class="cx"> return JITArrayStorage;
</span><span class="cx"> return JITContiguous;
</span><del>-#else
- UNUSED_PARAM(profile);
- return JITContiguous;
-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if USE(JSVALUE32_64)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -1057,7 +1057,7 @@
</span><span class="cx">
</span><span class="cx"> signExtend32ToPtr(regT1, regT1);
</span><span class="cx"> load64(BaseIndex(callFrameRegister, regT1, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT0);
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> emitPutVirtualRegister(dst, regT0);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -1166,7 +1166,7 @@
</span><span class="cx">
</span><span class="cx"> loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT0);
</span><span class="cx"> loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT1);
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> emitStore(dst, regT1, regT0);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITPropertyAccesscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITPropertyAccess.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -143,7 +143,7 @@
</span><span class="cx"> resultOK.link(this);
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> emitPutVirtualRegister(dst);
</span><span class="cx">
</span><span class="cx"> m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done));
</span><span class="lines">@@ -232,7 +232,7 @@
</span><span class="cx"> m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call;
</span><span class="cx"> m_byValInstructionIndex++;
</span><span class="cx">
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch, FinalObjectMode finalObjectMode)
</span><span class="lines">@@ -524,7 +524,7 @@
</span><span class="cx"> addSlowCase(gen.slowPathJump());
</span><span class="cx"> m_getByIds.append(gen);
</span><span class="cx">
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> emitPutVirtualRegister(resultVReg);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -742,7 +742,7 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> emitPutVirtualRegister(dst);
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void JIT::emitSlow_op_get_from_scope(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITPropertyAccess32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -168,7 +168,7 @@
</span><span class="cx"> resultOK.link(this);
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> emitStore(dst, regT1, regT0);
</span><span class="cx">
</span><span class="cx"> m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done));
</span><span class="lines">@@ -263,7 +263,7 @@
</span><span class="cx"> m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call;
</span><span class="cx"> m_byValInstructionIndex++;
</span><span class="cx">
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void JIT::emit_op_put_by_val(Instruction* currentInstruction)
</span><span class="lines">@@ -483,7 +483,7 @@
</span><span class="cx"> addSlowCase(gen.slowPathJump());
</span><span class="cx"> m_getByIds.append(gen);
</span><span class="cx">
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> emitStore(dst, regT1, regT0);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -776,7 +776,7 @@
</span><span class="cx"> addSlowCase(jump());
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>- emitValueProfilingSite(regT4);
</del><ins>+ emitValueProfilingSite();
</ins><span class="cx"> emitStore(dst, regT1, regT0);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntCommonh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntCommon.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntCommon.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntCommon.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -43,14 +43,5 @@
</span><span class="cx"> // Disable inline caching of get_by_id and put_by_id.
</span><span class="cx"> #define LLINT_ALWAYS_ACCESS_SLOW 0
</span><span class="cx">
</span><del>-// Enable OSR into the JIT. Disabling this while the LLInt is enabled effectively
-// turns off all JIT'ing, since in LLInt's parlance, OSR subsumes any form of JIT
-// invocation.
-#if ENABLE(JIT) && !ENABLE(ALLOCATION_LOGGING)
-#define LLINT_OSR_TO_JIT 1
-#else
-#define LLINT_OSR_TO_JIT 0
-#endif
-
</del><span class="cx"> #endif // LLIntCommon_h
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntOfflineAsmConfigh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -136,12 +136,6 @@
</span><span class="cx"> #define OFFLINE_ASM_BIG_ENDIAN 0
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>-#if LLINT_OSR_TO_JIT
-#define OFFLINE_ASM_JIT_ENABLED 1
-#else
-#define OFFLINE_ASM_JIT_ENABLED 0
-#endif
-
</del><span class="cx"> #if LLINT_EXECUTION_TRACING
</span><span class="cx"> #define OFFLINE_ASM_EXECUTION_TRACING 1
</span><span class="cx"> #else
</span><span class="lines">@@ -154,16 +148,4 @@
</span><span class="cx"> #define OFFLINE_ASM_ALWAYS_ALLOCATE_SLOW 0
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>-#if ENABLE(JAVASCRIPT_DEBUGGER)
-#define OFFLINE_ASM_JAVASCRIPT_DEBUGGER 1
-#else
-#define OFFLINE_ASM_JAVASCRIPT_DEBUGGER 0
-#endif
-
-#if ENABLE(VALUE_PROFILER)
-#define OFFLINE_ASM_VALUE_PROFILER 1
-#else
-#define OFFLINE_ASM_VALUE_PROFILER 0
-#endif
-
</del><span class="cx"> #endif // LLIntOfflineAsmConfig_h
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -120,7 +120,6 @@
</span><span class="cx"> LLINT_END_IMPL(); \
</span><span class="cx"> } while (false)
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> #define LLINT_RETURN_PROFILED(opcode, value) do { \
</span><span class="cx"> JSValue __rp_returnValue = (value); \
</span><span class="cx"> LLINT_CHECK_EXCEPTION(); \
</span><span class="lines">@@ -134,13 +133,6 @@
</span><span class="cx"> JSValue::encode(value); \
</span><span class="cx"> } while (false)
</span><span class="cx">
</span><del>-#else // ENABLE(VALUE_PROFILER)
-#define LLINT_RETURN_PROFILED(opcode, value) LLINT_RETURN(value)
-
-#define LLINT_PROFILE_VALUE(opcode, value) do { } while (false)
-
-#endif // ENABLE(VALUE_PROFILER)
-
</del><span class="cx"> #define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
</span><span class="cx">
</span><span class="cx"> #define LLINT_CALL_THROW(exec, exceptionToThrow) do { \
</span><span class="lines">@@ -279,6 +271,8 @@
</span><span class="cx"> LLINT_END_IMPL();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+enum EntryKind { Prologue, ArityCheck };
+
</ins><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> inline bool shouldJIT(ExecState* exec)
</span><span class="cx"> {
</span><span class="lines">@@ -332,7 +326,6 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-enum EntryKind { Prologue, ArityCheck };
</del><span class="cx"> static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
</span><span class="cx"> {
</span><span class="cx"> if (Options::verboseOSR()) {
</span><span class="lines">@@ -355,6 +348,13 @@
</span><span class="cx"> *codeBlock->vm(), codeBlock->ownerExecutable(), MustCheckArity,
</span><span class="cx"> RegisterPreservationNotRequired).executableAddress(), 0);
</span><span class="cx"> }
</span><ins>+#else // ENABLE(JIT)
+static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char*, EntryKind)
+{
+ codeBlock->dontJITAnytimeSoon();
+ LLINT_RETURN_TWO(0, exec);
+}
+#endif // ENABLE(JIT)
</ins><span class="cx">
</span><span class="cx"> LLINT_SLOW_PATH_DECL(entry_osr)
</span><span class="cx"> {
</span><span class="lines">@@ -385,6 +385,7 @@
</span><span class="cx"> {
</span><span class="cx"> CodeBlock* codeBlock = exec->codeBlock();
</span><span class="cx">
</span><ins>+#if ENABLE(JIT)
</ins><span class="cx"> if (Options::verboseOSR()) {
</span><span class="cx"> dataLog(
</span><span class="cx"> *codeBlock, ": Entered loop_osr with executeCounter = ",
</span><span class="lines">@@ -411,12 +412,17 @@
</span><span class="cx"> ASSERT(jumpTarget);
</span><span class="cx">
</span><span class="cx"> LLINT_RETURN_TWO(jumpTarget, exec->topOfFrame());
</span><ins>+#else // ENABLE(JIT)
+ codeBlock->dontJITAnytimeSoon();
+ LLINT_RETURN_TWO(0, 0);
+#endif // ENABLE(JIT)
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> LLINT_SLOW_PATH_DECL(replace)
</span><span class="cx"> {
</span><span class="cx"> CodeBlock* codeBlock = exec->codeBlock();
</span><span class="cx">
</span><ins>+#if ENABLE(JIT)
</ins><span class="cx"> if (Options::verboseOSR()) {
</span><span class="cx"> dataLog(
</span><span class="cx"> *codeBlock, ": Entered replace with executeCounter = ",
</span><span class="lines">@@ -428,8 +434,11 @@
</span><span class="cx"> else
</span><span class="cx"> codeBlock->dontJITAnytimeSoon();
</span><span class="cx"> LLINT_END_IMPL();
</span><ins>+#else // ENABLE(JIT)
+ codeBlock->dontJITAnytimeSoon();
+ LLINT_END_IMPL();
+#endif // ENABLE(JIT)
</ins><span class="cx"> }
</span><del>-#endif // ENABLE(JIT)
</del><span class="cx">
</span><span class="cx"> LLINT_SLOW_PATH_DECL(stack_check)
</span><span class="cx"> {
</span><span class="lines">@@ -582,16 +591,12 @@
</span><span class="cx"> && isJSArray(baseValue)
</span><span class="cx"> && ident == exec->propertyNames().length) {
</span><span class="cx"> pc[0].u.opcode = LLInt::getOpcode(llint_op_get_array_length);
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
</span><span class="cx"> arrayProfile->observeStructure(baseValue.asCell()->structure());
</span><span class="cx"> pc[4].u.arrayProfile = arrayProfile;
</span><del>-#endif
</del><span class="cx"> }
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
</span><del>-#endif
</del><span class="cx"> LLINT_END();
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -377,19 +377,15 @@
</span><span class="cx"> macro arrayProfile(structureAndIndexingType, profile, scratch)
</span><span class="cx"> const structure = structureAndIndexingType
</span><span class="cx"> const indexingType = structureAndIndexingType
</span><del>- if VALUE_PROFILER
- storep structure, ArrayProfile::m_lastSeenStructure[profile]
- end
</del><ins>+ storep structure, ArrayProfile::m_lastSeenStructure[profile]
</ins><span class="cx"> loadb Structure::m_indexingType[structure], indexingType
</span><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> macro checkSwitchToJIT(increment, action)
</span><del>- if JIT_ENABLED
- loadp CodeBlock[cfr], t0
- baddis increment, CodeBlock::m_llintExecuteCounter + ExecutionCounter::m_counter[t0], .continue
- action()
</del><ins>+ loadp CodeBlock[cfr], t0
+ baddis increment, CodeBlock::m_llintExecuteCounter + ExecutionCounter::m_counter[t0], .continue
+ action()
</ins><span class="cx"> .continue:
</span><del>- end
</del><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> macro checkSwitchToJITForEpilogue()
</span><span class="lines">@@ -438,22 +434,20 @@
</span><span class="cx"> callSlowPath(traceSlowPath)
</span><span class="cx"> end
</span><span class="cx"> codeBlockGetter(t1)
</span><del>- if JIT_ENABLED
- baddis 5, CodeBlock::m_llintExecuteCounter + ExecutionCounter::m_counter[t1], .continue
- cCall2(osrSlowPath, cfr, PC)
- btpz t0, .recover
- move cfr, sp # restore the previous sp
- # pop the callerFrame since we will jump to a function that wants to save it
- if ARM64
- popLRAndFP
- else
- pop cfr
- end
- jmp t0
- .recover:
- codeBlockGetter(t1)
- .continue:
</del><ins>+ baddis 5, CodeBlock::m_llintExecuteCounter + ExecutionCounter::m_counter[t1], .continue
+ cCall2(osrSlowPath, cfr, PC)
+ btpz t0, .recover
+ move cfr, sp # restore the previous sp
+ # pop the callerFrame since we will jump to a function that wants to save it
+ if ARM64
+ popLRAndFP
+ else
+ pop cfr
</ins><span class="cx"> end
</span><ins>+ jmp t0
+.recover:
+ codeBlockGetter(t1)
+.continue:
</ins><span class="cx"> codeBlockSetter(t1)
</span><span class="cx">
</span><span class="cx"> moveStackPointerForCodeBlock(t1, t2)
</span><span class="lines">@@ -470,37 +464,35 @@
</span><span class="cx"> # Expects that CodeBlock is in t1, which is what prologue() leaves behind.
</span><span class="cx"> # Must call dispatch(0) after calling this.
</span><span class="cx"> macro functionInitialization(profileArgSkip)
</span><del>- if VALUE_PROFILER
- # Profile the arguments. Unfortunately, we have no choice but to do this. This
- # code is pretty horrendous because of the difference in ordering between
- # arguments and value profiles, the desire to have a simple loop-down-to-zero
- # loop, and the desire to use only three registers so as to preserve the PC and
- # the code block. It is likely that this code should be rewritten in a more
- # optimal way for architectures that have more than five registers available
- # for arbitrary use in the interpreter.
- loadi CodeBlock::m_numParameters[t1], t0
- addp -profileArgSkip, t0 # Use addi because that's what has the peephole
- assert(macro (ok) bpgteq t0, 0, ok end)
- btpz t0, .argumentProfileDone
- loadp CodeBlock::m_argumentValueProfiles + VectorBufferOffset[t1], t3
- mulp sizeof ValueProfile, t0, t2 # Aaaaahhhh! Need strength reduction!
- lshiftp 3, t0
- addp t2, t3
- .argumentProfileLoop:
- if JSVALUE64
- loadq ThisArgumentOffset - 8 + profileArgSkip * 8[cfr, t0], t2
- subp sizeof ValueProfile, t3
- storeq t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets[t3]
- else
- loadi ThisArgumentOffset + TagOffset - 8 + profileArgSkip * 8[cfr, t0], t2
- subp sizeof ValueProfile, t3
- storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + TagOffset[t3]
- loadi ThisArgumentOffset + PayloadOffset - 8 + profileArgSkip * 8[cfr, t0], t2
- storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + PayloadOffset[t3]
- end
- baddpnz -8, t0, .argumentProfileLoop
- .argumentProfileDone:
</del><ins>+ # Profile the arguments. Unfortunately, we have no choice but to do this. This
+ # code is pretty horrendous because of the difference in ordering between
+ # arguments and value profiles, the desire to have a simple loop-down-to-zero
+ # loop, and the desire to use only three registers so as to preserve the PC and
+ # the code block. It is likely that this code should be rewritten in a more
+ # optimal way for architectures that have more than five registers available
+ # for arbitrary use in the interpreter.
+ loadi CodeBlock::m_numParameters[t1], t0
+ addp -profileArgSkip, t0 # Use addi because that's what has the peephole
+ assert(macro (ok) bpgteq t0, 0, ok end)
+ btpz t0, .argumentProfileDone
+ loadp CodeBlock::m_argumentValueProfiles + VectorBufferOffset[t1], t3
+ mulp sizeof ValueProfile, t0, t2 # Aaaaahhhh! Need strength reduction!
+ lshiftp 3, t0
+ addp t2, t3
+.argumentProfileLoop:
+ if JSVALUE64
+ loadq ThisArgumentOffset - 8 + profileArgSkip * 8[cfr, t0], t2
+ subp sizeof ValueProfile, t3
+ storeq t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets[t3]
+ else
+ loadi ThisArgumentOffset + TagOffset - 8 + profileArgSkip * 8[cfr, t0], t2
+ subp sizeof ValueProfile, t3
+ storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + TagOffset[t3]
+ loadi ThisArgumentOffset + PayloadOffset - 8 + profileArgSkip * 8[cfr, t0], t2
+ storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + PayloadOffset[t3]
</ins><span class="cx"> end
</span><ins>+ baddpnz -8, t0, .argumentProfileLoop
+.argumentProfileDone:
</ins><span class="cx">
</span><span class="cx"> # Check stack height.
</span><span class="cx"> loadi CodeBlock::m_numCalleeRegisters[t1], t0
</span><span class="lines">@@ -990,7 +982,6 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> _llint_op_debug:
</span><del>-if JAVASCRIPT_DEBUGGER
</del><span class="cx"> traceExecution()
</span><span class="cx"> loadp CodeBlock[cfr], t0
</span><span class="cx"> loadp CodeBlock::m_globalObject[t0], t0
</span><span class="lines">@@ -1001,7 +992,6 @@
</span><span class="cx">
</span><span class="cx"> callSlowPath(_llint_slow_path_debug)
</span><span class="cx"> .opDebugDone:
</span><del>-end
</del><span class="cx"> dispatch(2)
</span><span class="cx">
</span><span class="cx">
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -506,11 +506,9 @@
</span><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> macro valueProfile(tag, payload, operand, scratch)
</span><del>- if VALUE_PROFILER
- loadp operand[PC], scratch
- storei tag, ValueProfile::m_buckets + TagOffset[scratch]
- storei payload, ValueProfile::m_buckets + PayloadOffset[scratch]
- end
</del><ins>+ loadp operand[PC], scratch
+ storei tag, ValueProfile::m_buckets + TagOffset[scratch]
+ storei payload, ValueProfile::m_buckets + PayloadOffset[scratch]
</ins><span class="cx"> end
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -1508,10 +1506,8 @@
</span><span class="cx"> dispatch(6)
</span><span class="cx">
</span><span class="cx"> .opGetByValOutOfBounds:
</span><del>- if VALUE_PROFILER
- loadpFromInstruction(4, t0)
- storeb 1, ArrayProfile::m_outOfBounds[t0]
- end
</del><ins>+ loadpFromInstruction(4, t0)
+ storeb 1, ArrayProfile::m_outOfBounds[t0]
</ins><span class="cx"> .opGetByValSlow:
</span><span class="cx"> callSlowPath(_llint_slow_path_get_by_val)
</span><span class="cx"> dispatch(6)
</span><span class="lines">@@ -1581,10 +1577,8 @@
</span><span class="cx">
</span><span class="cx"> .outOfBounds:
</span><span class="cx"> biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
</span><del>- if VALUE_PROFILER
- loadp 16[PC], t2
- storeb 1, ArrayProfile::m_mayStoreToHole[t2]
- end
</del><ins>+ loadp 16[PC], t2
+ storeb 1, ArrayProfile::m_mayStoreToHole[t2]
</ins><span class="cx"> addi 1, t3, t2
</span><span class="cx"> storei t2, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
</span><span class="cx"> jmp .storeResult
</span><span class="lines">@@ -1651,10 +1645,8 @@
</span><span class="cx"> dispatch(5)
</span><span class="cx">
</span><span class="cx"> .opPutByValArrayStorageEmpty:
</span><del>- if VALUE_PROFILER
- loadp 16[PC], t1
- storeb 1, ArrayProfile::m_mayStoreToHole[t1]
- end
</del><ins>+ loadp 16[PC], t1
+ storeb 1, ArrayProfile::m_mayStoreToHole[t1]
</ins><span class="cx"> addi 1, ArrayStorage::m_numValuesInVector[t0]
</span><span class="cx"> bib t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .opPutByValArrayStorageStoreResult
</span><span class="cx"> addi 1, t3, t1
</span><span class="lines">@@ -1662,10 +1654,8 @@
</span><span class="cx"> jmp .opPutByValArrayStorageStoreResult
</span><span class="cx">
</span><span class="cx"> .opPutByValOutOfBounds:
</span><del>- if VALUE_PROFILER
- loadpFromInstruction(4, t0)
- storeb 1, ArrayProfile::m_outOfBounds[t0]
- end
</del><ins>+ loadpFromInstruction(4, t0)
+ storeb 1, ArrayProfile::m_outOfBounds[t0]
</ins><span class="cx"> .opPutByValSlow:
</span><span class="cx"> callSlowPath(slowPath)
</span><span class="cx"> dispatch(5)
</span><span class="lines">@@ -1882,16 +1872,14 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> macro arrayProfileForCall()
</span><del>- if VALUE_PROFILER
- loadi 16[PC], t3
- negi t3
- bineq ThisArgumentOffset + TagOffset[cfr, t3, 8], CellTag, .done
- loadi ThisArgumentOffset + PayloadOffset[cfr, t3, 8], t0
- loadp JSCell::m_structure[t0], t0
- loadp 24[PC], t1
- storep t0, ArrayProfile::m_lastSeenStructure[t1]
- .done:
- end
</del><ins>+ loadi 16[PC], t3
+ negi t3
+ bineq ThisArgumentOffset + TagOffset[cfr, t3, 8], CellTag, .done
+ loadi ThisArgumentOffset + PayloadOffset[cfr, t3, 8], t0
+ loadp JSCell::m_structure[t0], t0
+ loadp 24[PC], t1
+ storep t0, ArrayProfile::m_lastSeenStructure[t1]
+.done:
</ins><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> macro doCall(slowPath)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -369,10 +369,8 @@
</span><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> macro valueProfile(value, operand, scratch)
</span><del>- if VALUE_PROFILER
- loadpFromInstruction(operand, scratch)
- storeq value, ValueProfile::m_buckets[scratch]
- end
</del><ins>+ loadpFromInstruction(operand, scratch)
+ storeq value, ValueProfile::m_buckets[scratch]
</ins><span class="cx"> end
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -1334,10 +1332,8 @@
</span><span class="cx"> dispatch(6)
</span><span class="cx">
</span><span class="cx"> .opGetByValOutOfBounds:
</span><del>- if VALUE_PROFILER
- loadpFromInstruction(4, t0)
- storeb 1, ArrayProfile::m_outOfBounds[t0]
- end
</del><ins>+ loadpFromInstruction(4, t0)
+ storeb 1, ArrayProfile::m_outOfBounds[t0]
</ins><span class="cx"> .opGetByValSlow:
</span><span class="cx"> callSlowPath(_llint_slow_path_get_by_val)
</span><span class="cx"> dispatch(6)
</span><span class="lines">@@ -1407,10 +1403,8 @@
</span><span class="cx">
</span><span class="cx"> .outOfBounds:
</span><span class="cx"> biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
</span><del>- if VALUE_PROFILER
- loadp 32[PB, PC, 8], t2
- storeb 1, ArrayProfile::m_mayStoreToHole[t2]
- end
</del><ins>+ loadp 32[PB, PC, 8], t2
+ storeb 1, ArrayProfile::m_mayStoreToHole[t2]
</ins><span class="cx"> addi 1, t3, t2
</span><span class="cx"> storei t2, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
</span><span class="cx"> jmp .storeResult
</span><span class="lines">@@ -1473,10 +1467,8 @@
</span><span class="cx"> dispatch(5)
</span><span class="cx">
</span><span class="cx"> .opPutByValArrayStorageEmpty:
</span><del>- if VALUE_PROFILER
- loadpFromInstruction(4, t1)
- storeb 1, ArrayProfile::m_mayStoreToHole[t1]
- end
</del><ins>+ loadpFromInstruction(4, t1)
+ storeb 1, ArrayProfile::m_mayStoreToHole[t1]
</ins><span class="cx"> addi 1, ArrayStorage::m_numValuesInVector[t0]
</span><span class="cx"> bib t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .opPutByValArrayStorageStoreResult
</span><span class="cx"> addi 1, t3, t1
</span><span class="lines">@@ -1484,10 +1476,8 @@
</span><span class="cx"> jmp .opPutByValArrayStorageStoreResult
</span><span class="cx">
</span><span class="cx"> .opPutByValOutOfBounds:
</span><del>- if VALUE_PROFILER
- loadpFromInstruction(4, t0)
- storeb 1, ArrayProfile::m_outOfBounds[t0]
- end
</del><ins>+ loadpFromInstruction(4, t0)
+ storeb 1, ArrayProfile::m_outOfBounds[t0]
</ins><span class="cx"> .opPutByValSlow:
</span><span class="cx"> callSlowPath(slowPath)
</span><span class="cx"> dispatch(5)
</span><span class="lines">@@ -1709,16 +1699,14 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> macro arrayProfileForCall()
</span><del>- if VALUE_PROFILER
- loadisFromInstruction(4, t3)
- negp t3
- loadq ThisArgumentOffset[cfr, t3, 8], t0
- btqnz t0, tagMask, .done
- loadp JSCell::m_structure[t0], t0
- loadpFromInstruction(6, t1)
- storep t0, ArrayProfile::m_lastSeenStructure[t1]
- .done:
- end
</del><ins>+ loadisFromInstruction(4, t3)
+ negp t3
+ loadq ThisArgumentOffset[cfr, t3, 8], t0
+ btqnz t0, tagMask, .done
+ loadp JSCell::m_structure[t0], t0
+ loadpFromInstruction(6, t1)
+ storep t0, ArrayProfile::m_lastSeenStructure[t1]
+.done:
</ins><span class="cx"> end
</span><span class="cx">
</span><span class="cx"> macro doCall(slowPath)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreprofilerProfilerBytecodeSequencecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -38,7 +38,6 @@
</span><span class="cx"> {
</span><span class="cx"> StringPrintStream out;
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> for (unsigned i = 0; i < codeBlock->numberOfArgumentValueProfiles(); ++i) {
</span><span class="cx"> ConcurrentJITLocker locker(codeBlock->m_lock);
</span><span class="cx"> CString description = codeBlock->valueProfileForArgument(i)->briefDescription(locker);
</span><span class="lines">@@ -48,7 +47,6 @@
</span><span class="cx"> out.print("arg", i, " (r", virtualRegisterForArgument(i).offset(), "): ", description);
</span><span class="cx"> m_header.append(out.toCString());
</span><span class="cx"> }
</span><del>-#endif // ENABLE(VALUE_PROFILER)
</del><span class="cx">
</span><span class="cx"> for (unsigned bytecodeIndex = 0; bytecodeIndex < codeBlock->instructions().size();) {
</span><span class="cx"> out.reset();
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -125,7 +125,6 @@
</span><span class="cx"> END_IMPL(); \
</span><span class="cx"> } while (false)
</span><span class="cx">
</span><del>-#if ENABLE(VALUE_PROFILER)
</del><span class="cx"> #define RETURN_PROFILED(opcode, value) do { \
</span><span class="cx"> JSValue rpPeturnValue = (value); \
</span><span class="cx"> CHECK_EXCEPTION(); \
</span><span class="lines">@@ -139,13 +138,6 @@
</span><span class="cx"> JSValue::encode(value); \
</span><span class="cx"> } while (false)
</span><span class="cx">
</span><del>-#else // ENABLE(VALUE_PROFILER)
-#define RETURN_PROFILED(opcode, value) RETURN(value)
-
-#define PROFILE_VALUE(opcode, value) do { } while (false)
-
-#endif // ENABLE(VALUE_PROFILER)
-
</del><span class="cx"> #define CALL_END_IMPL(exec, callTarget) RETURN_TWO((callTarget), (exec))
</span><span class="cx">
</span><span class="cx"> #define CALL_THROW(exec, pc, exceptionToThrow) do { \
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoretestsstressdeadint32todoublejs"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/tests/stress/dead-int32-to-double.js (0 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/tests/stress/dead-int32-to-double.js         (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/tests/stress/dead-int32-to-double.js        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo(int, o) {
+ var x = int;
+ o.f = x;
+ for (var i = 0; i < 100; ++i)
+ x += 0.5;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100; ++i)
+ foo(42, {});
+
+var o = {g: 43};
+foo(47, o);
+if (o.f != 47)
+ throw "Error: o.f is " + o.f;
</ins></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoretestsstressdeaduint32tonumberjs"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/tests/stress/dead-uint32-to-number.js (0 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/tests/stress/dead-uint32-to-number.js         (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/tests/stress/dead-uint32-to-number.js        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo(a, o) {
+ var x = a >>> 0;
+ o.f = x | 0;
+ for (var i = 0; i < 100; ++i)
+ x++;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100; ++i)
+ foo(42, {});
+
+var o = {g: 43};
+foo(47, o);
+if (o.f != 47)
+ throw "Error: o.f is " + o.f;
</ins></span></pre></div>
<a id="branchesjsCStackSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/WTF/ChangeLog (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/WTF/ChangeLog        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/WTF/ChangeLog        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -1,3 +1,7 @@
</span><ins>+2014-01-06 Filip Pizlo <fpizlo@apple.com>
+
+ Merge trunk r161364.
+
</ins><span class="cx"> 2013-12-13 Michael Saboff <msaboff@apple.com>
</span><span class="cx">
</span><span class="cx"> CStack Branch: Remove WTF_USE_SEPARATE_C_AND_JS_STACK
</span></span></pre></div>
<a id="branchesjsCStackSourceWTFwtfPlatformh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/WTF/wtf/Platform.h (161408 => 161409)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/WTF/wtf/Platform.h        2014-01-07 07:11:53 UTC (rev 161408)
+++ branches/jsCStack/Source/WTF/wtf/Platform.h        2014-01-07 07:19:46 UTC (rev 161409)
</span><span class="lines">@@ -772,18 +772,6 @@
</span><span class="cx"> #error You have to have at least one execution model enabled to build JSC
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>-/* Profiling of types and values used by JIT code. DFG_JIT depends on it, but you
- can enable it manually with DFG turned off if you want to use it as a standalone
- profiler. In that case, you probably want to also enable VERBOSE_VALUE_PROFILE
- below. */
-#if !defined(ENABLE_VALUE_PROFILER) && ENABLE(DFG_JIT)
-#define ENABLE_VALUE_PROFILER 1
-#endif
-
-#if !defined(ENABLE_VERBOSE_VALUE_PROFILE) && ENABLE(VALUE_PROFILER)
-#define ENABLE_VERBOSE_VALUE_PROFILE 0
-#endif
-
</del><span class="cx"> /* Counts uses of write barriers using sampling counters. Be sure to also
</span><span class="cx"> set ENABLE_SAMPLING_COUNTERS to 1. */
</span><span class="cx"> #if !defined(ENABLE_WRITE_BARRIER_PROFILING)
</span></span></pre>
</div>
</div>
</body>
</html>