<!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>[206392] trunk/Source</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/206392">206392</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2016-09-26 14:11:31 -0700 (Mon, 26 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[JSC] Shrink the Math inline caches some more
https://bugs.webkit.org/show_bug.cgi?id=162485

Reviewed by Saam Barati.

Source/JavaScriptCore:

This patch applies some lessons learnt from op_negate
to shrink the generated asm of the previous 3 inline
caches.

In order of importance:
-We do not need to pass the pointer to ArithProfile
 on the slow path. We can just get the profile out
 of the Math IC.
 This saves us from materializing a 64bits value
 in a register before the call on the slow path.
-We can remove a bunch of mov by setting up the registers
 in the way the slow path needs them.
 The slow path makes a function calls with the input
 as second and third arguments, and return the result in
 the &quot;return register&quot;. By using those as target when
 loading/storing from the stack, we remove 3 mov per slow path.
-When performing integer add, we can set the result directly in
 the output register if that does not trashes one of the input
 register. This removes one mov per integer add.

The inline cache average sizes on Sunspider change as follow:
-Adds: 147.573099-&gt;131.555556 (~10%)
-Muls: 186.882353-&gt;170.991597 (~8%)
-Subs: 139.127907-&gt;121.523256 (~12%)

* jit/JIT.h:
* jit/JITAddGenerator.cpp:
(JSC::JITAddGenerator::generateInline):
(JSC::JITAddGenerator::generateFastPath):
* jit/JITArithmetic.cpp:
(JSC::JIT::emitMathICFast):
(JSC::JIT::emitMathICSlow):
* jit/JITInlines.h:
(JSC::JIT::callOperation): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:

Source/WTF:

* wtf/Bag.h:
Don't copy the arguments before initializing the nodes.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeArithProfilecpp">trunk/Source/JavaScriptCore/bytecode/ArithProfile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeArithProfileh">trunk/Source/JavaScriptCore/bytecode/ArithProfile.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITAddGeneratorcpp">trunk/Source/JavaScriptCore/jit/JITAddGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITAddGeneratorh">trunk/Source/JavaScriptCore/jit/JITAddGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITArithmeticcpp">trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITInlinesh">trunk/Source/JavaScriptCore/jit/JITInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITMathICh">trunk/Source/JavaScriptCore/jit/JITMathIC.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITMulGeneratorcpp">trunk/Source/JavaScriptCore/jit/JITMulGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITMulGeneratorh">trunk/Source/JavaScriptCore/jit/JITMulGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITNegGeneratorcpp">trunk/Source/JavaScriptCore/jit/JITNegGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITNegGeneratorh">trunk/Source/JavaScriptCore/jit/JITNegGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITSubGeneratorcpp">trunk/Source/JavaScriptCore/jit/JITSubGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITSubGeneratorh">trunk/Source/JavaScriptCore/jit/JITSubGenerator.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfBagh">trunk/Source/WTF/wtf/Bag.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -1,3 +1,47 @@
</span><ins>+2016-09-26  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        [JSC] Shrink the Math inline caches some more
+        https://bugs.webkit.org/show_bug.cgi?id=162485
+
+        Reviewed by Saam Barati.
+
+        This patch applies some lessons learnt from op_negate
+        to shrink the generated asm of the previous 3 inline
+        caches.
+
+        In order of importance:
+        -We do not need to pass the pointer to ArithProfile
+         on the slow path. We can just get the profile out
+         of the Math IC.
+         This saves us from materializing a 64bits value
+         in a register before the call on the slow path.
+        -We can remove a bunch of mov by setting up the registers
+         in the way the slow path needs them.
+         The slow path makes a function calls with the input
+         as second and third arguments, and return the result in
+         the &quot;return register&quot;. By using those as target when
+         loading/storing from the stack, we remove 3 mov per slow path.
+        -When performing integer add, we can set the result directly in
+         the output register if that does not trashes one of the input
+         register. This removes one mov per integer add.
+
+        The inline cache average sizes on Sunspider change as follow:
+        -Adds: 147.573099-&gt;131.555556 (~10%)
+        -Muls: 186.882353-&gt;170.991597 (~8%)
+        -Subs: 139.127907-&gt;121.523256 (~12%)
+
+        * jit/JIT.h:
+        * jit/JITAddGenerator.cpp:
+        (JSC::JITAddGenerator::generateInline):
+        (JSC::JITAddGenerator::generateFastPath):
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emitMathICFast):
+        (JSC::JIT::emitMathICSlow):
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+
</ins><span class="cx"> 2016-09-26  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Added RETURN_IF_EXCEPTION() macro and use it for exception checks.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeArithProfilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ArithProfile.cpp (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ArithProfile.cpp        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/bytecode/ArithProfile.cpp        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -53,7 +53,7 @@
</span><span class="cx">     return (m_bits &amp; mask) != mask;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ArithProfile::emitSetDouble(CCallHelpers&amp; jit)
</del><ins>+void ArithProfile::emitSetDouble(CCallHelpers&amp; jit) const
</ins><span class="cx"> {
</span><span class="cx">     if (shouldEmitSetDouble())
</span><span class="cx">         jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits()));
</span><span class="lines">@@ -65,7 +65,7 @@
</span><span class="cx">     return (m_bits &amp; mask) != mask;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ArithProfile::emitSetNonNumber(CCallHelpers&amp; jit)
</del><ins>+void ArithProfile::emitSetNonNumber(CCallHelpers&amp; jit) const
</ins><span class="cx"> {
</span><span class="cx">     if (shouldEmitSetNonNumber())
</span><span class="cx">         jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNumber), CCallHelpers::AbsoluteAddress(addressOfBits()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeArithProfileh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ArithProfile.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ArithProfile.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/bytecode/ArithProfile.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -158,7 +158,7 @@
</span><span class="cx">     void setObservedInt32Overflow() { setBit(Int32Overflow); }
</span><span class="cx">     void setObservedInt52Overflow() { setBit(Int52Overflow); }
</span><span class="cx"> 
</span><del>-    void* addressOfBits() { return &amp;m_bits; }
</del><ins>+    const void* addressOfBits() const { return &amp;m_bits; }
</ins><span class="cx"> 
</span><span class="cx">     void observeResult(JSValue value)
</span><span class="cx">     {
</span><span class="lines">@@ -215,10 +215,10 @@
</span><span class="cx">     
</span><span class="cx">     // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble).
</span><span class="cx">     bool shouldEmitSetDouble() const;
</span><del>-    void emitSetDouble(CCallHelpers&amp;);
</del><ins>+    void emitSetDouble(CCallHelpers&amp;) const;
</ins><span class="cx">     
</span><span class="cx">     // Sets NonNumber.
</span><del>-    void emitSetNonNumber(CCallHelpers&amp;);
</del><ins>+    void emitSetNonNumber(CCallHelpers&amp;) const;
</ins><span class="cx">     bool shouldEmitSetNonNumber() const;
</span><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -3000,24 +3000,24 @@
</span><span class="cx">     return m_stubInfos.add(accessType);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JITAddIC* CodeBlock::addJITAddIC()
</del><ins>+JITAddIC* CodeBlock::addJITAddIC(ArithProfile* arithProfile)
</ins><span class="cx"> {
</span><del>-    return m_addICs.add();
</del><ins>+    return m_addICs.add(arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-JITMulIC* CodeBlock::addJITMulIC()
</del><ins>+JITMulIC* CodeBlock::addJITMulIC(ArithProfile* arithProfile)
</ins><span class="cx"> {
</span><del>-    return m_mulICs.add();
</del><ins>+    return m_mulICs.add(arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-JITSubIC* CodeBlock::addJITSubIC()
</del><ins>+JITSubIC* CodeBlock::addJITSubIC(ArithProfile* arithProfile)
</ins><span class="cx"> {
</span><del>-    return m_subICs.add();
</del><ins>+    return m_subICs.add(arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-JITNegIC* CodeBlock::addJITNegIC()
</del><ins>+JITNegIC* CodeBlock::addJITNegIC(ArithProfile* arithProfile)
</ins><span class="cx"> {
</span><del>-    return m_negICs.add();
</del><ins>+    return m_negICs.add(arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> StructureStubInfo* CodeBlock::findStubInfo(CodeOrigin codeOrigin)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -243,10 +243,10 @@
</span><span class="cx">     
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     StructureStubInfo* addStubInfo(AccessType);
</span><del>-    JITAddIC* addJITAddIC();
-    JITMulIC* addJITMulIC();
-    JITNegIC* addJITNegIC();
-    JITSubIC* addJITSubIC();
</del><ins>+    JITAddIC* addJITAddIC(ArithProfile*);
+    JITMulIC* addJITMulIC(ArithProfile*);
+    JITNegIC* addJITNegIC(ArithProfile*);
+    JITSubIC* addJITSubIC(ArithProfile*);
</ins><span class="cx">     Bag&lt;StructureStubInfo&gt;::iterator stubInfoBegin() { return m_stubInfos.begin(); }
</span><span class="cx">     Bag&lt;StructureStubInfo&gt;::iterator stubInfoEnd() { return m_stubInfos.end(); }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -3424,7 +3424,8 @@
</span><span class="cx">     bool needsScratchFPRReg = true;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    JITAddIC* addIC = m_jit.codeBlock()-&gt;addJITAddIC();
</del><ins>+    ArithProfile* arithProfile = m_jit.graph().baselineCodeBlockFor(node-&gt;origin.semantic)-&gt;arithProfileForBytecodeOffset(node-&gt;origin.semantic.bytecodeIndex);
+    JITAddIC* addIC = m_jit.codeBlock()-&gt;addJITAddIC(arithProfile);
</ins><span class="cx">     auto repatchingFunction = operationValueAddOptimize;
</span><span class="cx">     auto nonRepatchingFunction = operationValueAdd;
</span><span class="cx">     
</span><span class="lines">@@ -3500,8 +3501,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     Box&lt;MathICGenerationState&gt; addICGenerationState = Box&lt;MathICGenerationState&gt;::create();
</span><del>-    ArithProfile* arithProfile = m_jit.graph().baselineCodeBlockFor(node-&gt;origin.semantic)-&gt;arithProfileForBytecodeOffset(node-&gt;origin.semantic.bytecodeIndex);
-    mathIC-&gt;m_generator = Generator(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, leftFPR, rightFPR, scratchGPR, scratchFPR, arithProfile);
</del><ins>+    mathIC-&gt;m_generator = Generator(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, leftFPR, rightFPR, scratchGPR, scratchFPR);
</ins><span class="cx"> 
</span><span class="cx">     bool shouldEmitProfiling = false;
</span><span class="cx">     bool generatedInline = mathIC-&gt;generateInline(m_jit, *addICGenerationState, shouldEmitProfiling);
</span><span class="lines">@@ -4093,7 +4093,8 @@
</span><span class="cx">         bool needsScratchFPRReg = true;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-        JITSubIC* subIC = m_jit.codeBlock()-&gt;addJITSubIC();
</del><ins>+        ArithProfile* arithProfile = m_jit.graph().baselineCodeBlockFor(node-&gt;origin.semantic)-&gt;arithProfileForBytecodeOffset(node-&gt;origin.semantic.bytecodeIndex);
+        JITSubIC* subIC = m_jit.codeBlock()-&gt;addJITSubIC(arithProfile);
</ins><span class="cx">         auto repatchingFunction = operationValueSubOptimize;
</span><span class="cx">         auto nonRepatchingFunction = operationValueSub;
</span><span class="cx">         
</span><span class="lines">@@ -4355,7 +4356,9 @@
</span><span class="cx">         bool needsScratchGPRReg = true;
</span><span class="cx">         bool needsScratchFPRReg = true;
</span><span class="cx"> #endif
</span><del>-        JITMulIC* mulIC = m_jit.codeBlock()-&gt;addJITMulIC();
</del><ins>+
+        ArithProfile* arithProfile = m_jit.graph().baselineCodeBlockFor(node-&gt;origin.semantic)-&gt;arithProfileForBytecodeOffset(node-&gt;origin.semantic.bytecodeIndex);
+        JITMulIC* mulIC = m_jit.codeBlock()-&gt;addJITMulIC(arithProfile);
</ins><span class="cx">         auto repatchingFunction = operationValueMulOptimize;
</span><span class="cx">         auto nonRepatchingFunction = operationValueMul;
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -1553,7 +1553,8 @@
</span><span class="cx"> 
</span><span class="cx">     void compileValueAdd()
</span><span class="cx">     {
</span><del>-        JITAddIC* addIC = codeBlock()-&gt;addJITAddIC();
</del><ins>+        ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node-&gt;origin.semantic)-&gt;arithProfileForBytecodeOffset(m_node-&gt;origin.semantic.bytecodeIndex);
+        JITAddIC* addIC = codeBlock()-&gt;addJITAddIC(arithProfile);
</ins><span class="cx">         auto repatchingFunction = operationValueAddOptimize;
</span><span class="cx">         auto nonRepatchingFunction = operationValueAdd;
</span><span class="cx">         compileMathIC(addIC, repatchingFunction, nonRepatchingFunction);
</span><span class="lines">@@ -1593,10 +1594,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">                 Box&lt;MathICGenerationState&gt; mathICGenerationState = Box&lt;MathICGenerationState&gt;::create();
</span><del>-                ArithProfile* arithProfile = state-&gt;graph.baselineCodeBlockFor(node-&gt;origin.semantic)-&gt;arithProfileForBytecodeOffset(node-&gt;origin.semantic.bytecodeIndex);
</del><span class="cx">                 mathIC-&gt;m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
</span><span class="cx">                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
</span><del>-                    params.fpScratch(1), params.gpScratch(0), InvalidFPRReg, arithProfile);
</del><ins>+                    params.fpScratch(1), params.gpScratch(0), InvalidFPRReg);
</ins><span class="cx"> 
</span><span class="cx">                 bool shouldEmitProfiling = false;
</span><span class="cx">                 bool generatedInline = mathIC-&gt;generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
</span><span class="lines">@@ -1724,7 +1724,8 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            JITSubIC* subIC = codeBlock()-&gt;addJITSubIC();
</del><ins>+            ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node-&gt;origin.semantic)-&gt;arithProfileForBytecodeOffset(m_node-&gt;origin.semantic.bytecodeIndex);
+            JITSubIC* subIC = codeBlock()-&gt;addJITSubIC(arithProfile);
</ins><span class="cx">             auto repatchingFunction = operationValueSubOptimize;
</span><span class="cx">             auto nonRepatchingFunction = operationValueSub;
</span><span class="cx">             compileMathIC(subIC, repatchingFunction, nonRepatchingFunction);
</span><span class="lines">@@ -1818,7 +1819,8 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case UntypedUse: {
</span><del>-            JITMulIC* mulIC = codeBlock()-&gt;addJITMulIC();
</del><ins>+            ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node-&gt;origin.semantic)-&gt;arithProfileForBytecodeOffset(m_node-&gt;origin.semantic.bytecodeIndex);
+            JITMulIC* mulIC = codeBlock()-&gt;addJITMulIC(arithProfile);
</ins><span class="cx">             auto repatchingFunction = operationValueMulOptimize;
</span><span class="cx">             auto nonRepatchingFunction = operationValueMul;
</span><span class="cx">             compileMathIC(mulIC, repatchingFunction, nonRepatchingFunction);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -762,7 +762,6 @@
</span><span class="cx">         MacroAssembler::Call callOperation(J_JITOperation_EJArp, JSValueRegs, JSValueRegs, ArithProfile*);
</span><span class="cx">         MacroAssembler::Call callOperation(J_JITOperation_EJJArp, JSValueRegs, JSValueRegs, JSValueRegs, ArithProfile*);
</span><span class="cx">         MacroAssembler::Call callOperation(J_JITOperation_EJJ, JSValueRegs, JSValueRegs, JSValueRegs);
</span><del>-        MacroAssembler::Call callOperation(J_JITOperation_EJJArpMic, JSValueRegs, JSValueRegs, JSValueRegs, ArithProfile*, TrustedImmPtr);
</del><span class="cx">         MacroAssembler::Call callOperation(J_JITOperation_EJMic, JSValueRegs, JSValueRegs, TrustedImmPtr);
</span><span class="cx">         MacroAssembler::Call callOperation(J_JITOperation_EJJMic, JSValueRegs, JSValueRegs, JSValueRegs, TrustedImmPtr);
</span><span class="cx">         MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, ArrayProfile*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITAddGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITAddGenerator.cpp (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITAddGenerator.cpp        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITAddGenerator.cpp        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -34,14 +34,14 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers&amp; jit, MathICGenerationState&amp; state)
</del><ins>+JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers&amp; jit, MathICGenerationState&amp; state, const ArithProfile* arithProfile)
</ins><span class="cx"> {
</span><span class="cx">     // We default to speculating int32.
</span><span class="cx">     ObservedType lhs = ObservedType().withInt32();
</span><span class="cx">     ObservedType rhs = ObservedType().withInt32();
</span><del>-    if (m_arithProfile) {
-        lhs = m_arithProfile-&gt;lhsObservedType();
-        rhs = m_arithProfile-&gt;rhsObservedType();
</del><ins>+    if (arithProfile) {
+        lhs = arithProfile-&gt;lhsObservedType();
+        rhs = arithProfile-&gt;rhsObservedType();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (lhs.isOnlyNonNumber() &amp;&amp; rhs.isOnlyNonNumber())
</span><span class="lines">@@ -54,13 +54,19 @@
</span><span class="cx">         if (!m_rightOperand.isConstInt32())
</span><span class="cx">             state.slowPathJumps.append(jit.branchIfNotInt32(m_right));
</span><span class="cx"> 
</span><ins>+        GPRReg scratch = m_scratchGPR;
</ins><span class="cx">         if (m_leftOperand.isConstInt32() || m_rightOperand.isConstInt32()) {
</span><span class="cx">             JSValueRegs var = m_leftOperand.isConstInt32() ? m_right : m_left;
</span><span class="cx">             int32_t constValue = m_leftOperand.isConstInt32() ? m_leftOperand.asConstInt32() : m_rightOperand.asConstInt32();
</span><del>-            state.slowPathJumps.append(jit.branchAdd32(CCallHelpers::Overflow, var.payloadGPR(), CCallHelpers::Imm32(constValue), m_scratchGPR));
-        } else
-            state.slowPathJumps.append(jit.branchAdd32(CCallHelpers::Overflow, m_right.payloadGPR(), m_left.payloadGPR(), m_scratchGPR));
-        jit.boxInt32(m_scratchGPR, m_result);
</del><ins>+            if (var.payloadGPR() != m_result.payloadGPR())
+                scratch = m_result.payloadGPR();
+            state.slowPathJumps.append(jit.branchAdd32(CCallHelpers::Overflow, var.payloadGPR(), CCallHelpers::Imm32(constValue), scratch));
+        } else {
+            if (m_left.payloadGPR() != m_result.payloadGPR() &amp;&amp; m_right.payloadGPR() != m_result.payloadGPR())
+                scratch = m_result.payloadGPR();
+            state.slowPathJumps.append(jit.branchAdd32(CCallHelpers::Overflow, m_right.payloadGPR(), m_left.payloadGPR(), scratch));
+        }
+        jit.boxInt32(scratch, m_result);
</ins><span class="cx">         return JITMathICInlineResult::GeneratedFastPath;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -67,7 +73,7 @@
</span><span class="cx">     return JITMathICInlineResult::GenerateFullSnippet;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JITAddGenerator::generateFastPath(CCallHelpers&amp; jit, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, bool shouldEmitProfiling)
</del><ins>+bool JITAddGenerator::generateFastPath(CCallHelpers&amp; jit, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_scratchGPR != InvalidGPRReg);
</span><span class="cx">     ASSERT(m_scratchGPR != m_left.payloadGPR());
</span><span class="lines">@@ -91,9 +97,12 @@
</span><span class="cx">         // Try to do intVar + intConstant.
</span><span class="cx">         CCallHelpers::Jump notInt32 = jit.branchIfNotInt32(var);
</span><span class="cx"> 
</span><del>-        slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, var.payloadGPR(), CCallHelpers::Imm32(constOpr.asConstInt32()), m_scratchGPR));
</del><ins>+        GPRReg scratch = m_scratchGPR;
+        if (var.payloadGPR() != m_result.payloadGPR())
+            scratch = m_result.payloadGPR();
+        slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, var.payloadGPR(), CCallHelpers::Imm32(constOpr.asConstInt32()), scratch));
</ins><span class="cx"> 
</span><del>-        jit.boxInt32(m_scratchGPR, m_result);
</del><ins>+        jit.boxInt32(scratch, m_result);
</ins><span class="cx">         endJumpList.append(jit.jump());
</span><span class="cx"> 
</span><span class="cx">         if (!jit.supportsFloatingPoint()) {
</span><span class="lines">@@ -122,9 +131,12 @@
</span><span class="cx">         leftNotInt = jit.branchIfNotInt32(m_left);
</span><span class="cx">         rightNotInt = jit.branchIfNotInt32(m_right);
</span><span class="cx"> 
</span><del>-        slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, m_right.payloadGPR(), m_left.payloadGPR(), m_scratchGPR));
</del><ins>+        GPRReg scratch = m_scratchGPR;
+        if (m_left.payloadGPR() != m_result.payloadGPR() &amp;&amp; m_right.payloadGPR() != m_result.payloadGPR())
+            scratch = m_result.payloadGPR();
+        slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, m_right.payloadGPR(), m_left.payloadGPR(), scratch));
</ins><span class="cx"> 
</span><del>-        jit.boxInt32(m_scratchGPR, m_result);
</del><ins>+        jit.boxInt32(scratch, m_result);
</ins><span class="cx">         endJumpList.append(jit.jump());
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -162,9 +174,9 @@
</span><span class="cx"> 
</span><span class="cx">     // Do doubleVar + doubleVar.
</span><span class="cx">     jit.addDouble(m_rightFPR, m_leftFPR);
</span><del>-    if (m_arithProfile &amp;&amp; shouldEmitProfiling)
-        m_arithProfile-&gt;emitSetDouble(jit);
-        
</del><ins>+    if (arithProfile &amp;&amp; shouldEmitProfiling)
+        arithProfile-&gt;emitSetDouble(jit);
+
</ins><span class="cx">     jit.boxDouble(m_leftFPR, m_result);
</span><span class="cx"> 
</span><span class="cx">     return true;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITAddGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITAddGenerator.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITAddGenerator.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITAddGenerator.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -43,8 +43,7 @@
</span><span class="cx"> 
</span><span class="cx">     JITAddGenerator(SnippetOperand leftOperand, SnippetOperand rightOperand,
</span><span class="cx">         JSValueRegs result, JSValueRegs left, JSValueRegs right,
</span><del>-        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR,
-        ArithProfile* arithProfile = nullptr)
</del><ins>+        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR)
</ins><span class="cx">         : m_leftOperand(leftOperand)
</span><span class="cx">         , m_rightOperand(rightOperand)
</span><span class="cx">         , m_result(result)
</span><span class="lines">@@ -54,18 +53,15 @@
</span><span class="cx">         , m_rightFPR(rightFPR)
</span><span class="cx">         , m_scratchGPR(scratchGPR)
</span><span class="cx">         , m_scratchFPR(scratchFPR)
</span><del>-        , m_arithProfile(arithProfile)
</del><span class="cx">     {
</span><span class="cx">         ASSERT(!m_leftOperand.isConstInt32() || !m_rightOperand.isConstInt32());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JITMathICInlineResult generateInline(CCallHelpers&amp;, MathICGenerationState&amp;);
-    bool generateFastPath(CCallHelpers&amp;, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, bool shouldEmitProfiling);
</del><ins>+    JITMathICInlineResult generateInline(CCallHelpers&amp;, MathICGenerationState&amp;, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&amp;, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);
</ins><span class="cx"> 
</span><span class="cx">     static bool isLeftOperandValidConstant(SnippetOperand leftOperand) { return leftOperand.isPositiveConstInt32(); }
</span><span class="cx">     static bool isRightOperandValidConstant(SnippetOperand rightOperand) { return rightOperand.isPositiveConstInt32(); }
</span><del>-    
-    ArithProfile* arithProfile() const { return m_arithProfile; }
</del><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     SnippetOperand m_leftOperand;
</span><span class="lines">@@ -77,7 +73,6 @@
</span><span class="cx">     FPRReg m_rightFPR;
</span><span class="cx">     GPRReg m_scratchGPR;
</span><span class="cx">     FPRReg m_scratchFPR;
</span><del>-    ArithProfile* m_arithProfile;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITArithmeticcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -469,7 +469,8 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emit_op_negate(Instruction* currentInstruction)
</span><span class="cx"> {
</span><del>-    JITNegIC* negateIC = m_codeBlock-&gt;addJITNegIC();
</del><ins>+    ArithProfile* arithProfile = m_codeBlock-&gt;arithProfileForPC(currentInstruction);
+    JITNegIC* negateIC = m_codeBlock-&gt;addJITNegIC(arithProfile);
</ins><span class="cx">     m_instructionToMathIC.add(currentInstruction, negateIC);
</span><span class="cx">     emitMathICFast(negateIC, currentInstruction, operationArithNegateProfiled, operationArithNegate);
</span><span class="cx"> }
</span><span class="lines">@@ -664,7 +665,8 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emit_op_add(Instruction* currentInstruction)
</span><span class="cx"> {
</span><del>-    JITAddIC* addIC = m_codeBlock-&gt;addJITAddIC();
</del><ins>+    ArithProfile* arithProfile = m_codeBlock-&gt;arithProfileForPC(currentInstruction);
+    JITAddIC* addIC = m_codeBlock-&gt;addJITAddIC(arithProfile);
</ins><span class="cx">     m_instructionToMathIC.add(currentInstruction, addIC);
</span><span class="cx">     emitMathICFast(addIC, currentInstruction, operationValueAddProfiled, operationValueAdd);
</span><span class="cx"> }
</span><span class="lines">@@ -699,8 +701,7 @@
</span><span class="cx">     auto inlineStart = label();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    ArithProfile&amp; arithProfile = *bitwise_cast&lt;ArithProfile*&gt;(&amp;currentInstruction[3].u.operand);
-    mathIC-&gt;m_generator = Generator(resultRegs, srcRegs, scratchGPR, arithProfile);
</del><ins>+    mathIC-&gt;m_generator = Generator(resultRegs, srcRegs, scratchGPR);
</ins><span class="cx"> 
</span><span class="cx">     emitGetVirtualRegister(operand, srcRegs);
</span><span class="cx"> 
</span><span class="lines">@@ -708,8 +709,9 @@
</span><span class="cx"> 
</span><span class="cx">     bool generatedInlineCode = mathIC-&gt;generateInline(*this, mathICGenerationState);
</span><span class="cx">     if (!generatedInlineCode) {
</span><del>-        if (shouldEmitProfiling())
-            callOperation(profiledFunction, resultRegs, srcRegs, &amp;arithProfile);
</del><ins>+        ArithProfile* arithProfile = mathIC-&gt;arithProfile();
+        if (arithProfile &amp;&amp; shouldEmitProfiling())
+            callOperation(profiledFunction, resultRegs, srcRegs, arithProfile);
</ins><span class="cx">         else
</span><span class="cx">             callOperation(nonProfiledFunction, resultRegs, srcRegs);
</span><span class="cx">     } else
</span><span class="lines">@@ -735,9 +737,9 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     OperandTypes types = getOperandTypes(copiedInstruction(currentInstruction));
</span><del>-    JSValueRegs leftRegs = JSValueRegs(regT0);
-    JSValueRegs rightRegs = JSValueRegs(regT1);
-    JSValueRegs resultRegs = JSValueRegs(regT2);
</del><ins>+    JSValueRegs leftRegs = JSValueRegs(regT1);
+    JSValueRegs rightRegs = JSValueRegs(regT2);
+    JSValueRegs resultRegs = JSValueRegs(regT0);
</ins><span class="cx">     GPRReg scratchGPR = regT3;
</span><span class="cx">     FPRReg scratchFPR = fpRegT2;
</span><span class="cx"> #else
</span><span class="lines">@@ -749,10 +751,6 @@
</span><span class="cx">     FPRReg scratchFPR = fpRegT2;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    ArithProfile* arithProfile = nullptr;
-    if (shouldEmitProfiling())
-        arithProfile = m_codeBlock-&gt;arithProfileForPC(currentInstruction);
-
</del><span class="cx">     SnippetOperand leftOperand(types.first());
</span><span class="cx">     SnippetOperand rightOperand(types.second());
</span><span class="cx"> 
</span><span class="lines">@@ -763,7 +761,7 @@
</span><span class="cx"> 
</span><span class="cx">     RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
</span><span class="cx"> 
</span><del>-    mathIC-&gt;m_generator = Generator(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, fpRegT0, fpRegT1, scratchGPR, scratchFPR, arithProfile);
</del><ins>+    mathIC-&gt;m_generator = Generator(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, fpRegT0, fpRegT1, scratchGPR, scratchFPR);
</ins><span class="cx">     
</span><span class="cx">     ASSERT(!(Generator::isLeftOperandValidConstant(leftOperand) &amp;&amp; Generator::isRightOperandValidConstant(rightOperand)));
</span><span class="cx">     
</span><span class="lines">@@ -784,7 +782,8 @@
</span><span class="cx">             emitGetVirtualRegister(op1, leftRegs);
</span><span class="cx">         else if (rightOperand.isConst())
</span><span class="cx">             emitGetVirtualRegister(op2, rightRegs);
</span><del>-        if (arithProfile)
</del><ins>+        ArithProfile* arithProfile = mathIC-&gt;arithProfile();
+        if (arithProfile &amp;&amp; shouldEmitProfiling())
</ins><span class="cx">             callOperation(profiledFunction, resultRegs, leftRegs, rightRegs, arithProfile);
</span><span class="cx">         else
</span><span class="cx">             callOperation(nonProfiledFunction, resultRegs, leftRegs, rightRegs);
</span><span class="lines">@@ -822,8 +821,8 @@
</span><span class="cx">     auto slowPathStart = label();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    if (shouldEmitProfiling()) {
-        ArithProfile* arithProfile = bitwise_cast&lt;ArithProfile*&gt;(&amp;currentInstruction[3].u.operand);
</del><ins>+    ArithProfile* arithProfile = mathIC-&gt;arithProfile();
+    if (arithProfile &amp;&amp; shouldEmitProfiling()) {
</ins><span class="cx">         if (mathICGenerationState.shouldSlowPathRepatch)
</span><span class="cx">             mathICGenerationState.slowPathCall = callOperation(reinterpret_cast&lt;J_JITOperation_EJMic&gt;(profiledRepatchFunction), resultRegs, srcRegs, TrustedImmPtr(mathIC));
</span><span class="cx">         else
</span><span class="lines">@@ -859,9 +858,9 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     OperandTypes types = getOperandTypes(copiedInstruction(currentInstruction));
</span><del>-    JSValueRegs leftRegs = JSValueRegs(regT0);
-    JSValueRegs rightRegs = JSValueRegs(regT1);
-    JSValueRegs resultRegs = JSValueRegs(regT2);
</del><ins>+    JSValueRegs leftRegs = JSValueRegs(regT1);
+    JSValueRegs rightRegs = JSValueRegs(regT2);
+    JSValueRegs resultRegs = JSValueRegs(regT0);
</ins><span class="cx"> #else
</span><span class="cx">     OperandTypes types = getOperandTypes(currentInstruction);
</span><span class="cx">     JSValueRegs leftRegs = JSValueRegs(regT1, regT0);
</span><span class="lines">@@ -888,12 +887,12 @@
</span><span class="cx">     auto slowPathStart = label();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    if (shouldEmitProfiling()) {
-        ArithProfile&amp; arithProfile = *m_codeBlock-&gt;arithProfileForPC(currentInstruction);
</del><ins>+    ArithProfile* arithProfile = mathIC-&gt;arithProfile();
+    if (arithProfile &amp;&amp; shouldEmitProfiling()) {
</ins><span class="cx">         if (mathICGenerationState.shouldSlowPathRepatch)
</span><del>-            mathICGenerationState.slowPathCall = callOperation(bitwise_cast&lt;J_JITOperation_EJJArpMic&gt;(profiledRepatchFunction), resultRegs, leftRegs, rightRegs, &amp;arithProfile, TrustedImmPtr(mathIC));
</del><ins>+            mathICGenerationState.slowPathCall = callOperation(bitwise_cast&lt;J_JITOperation_EJJMic&gt;(profiledRepatchFunction), resultRegs, leftRegs, rightRegs, TrustedImmPtr(mathIC));
</ins><span class="cx">         else
</span><del>-            mathICGenerationState.slowPathCall = callOperation(profiledFunction, resultRegs, leftRegs, rightRegs, &amp;arithProfile);
</del><ins>+            mathICGenerationState.slowPathCall = callOperation(profiledFunction, resultRegs, leftRegs, rightRegs, arithProfile);
</ins><span class="cx">     } else
</span><span class="cx">         mathICGenerationState.slowPathCall = callOperation(bitwise_cast&lt;J_JITOperation_EJJMic&gt;(repatchFunction), resultRegs, leftRegs, rightRegs, TrustedImmPtr(mathIC));
</span><span class="cx"> 
</span><span class="lines">@@ -989,7 +988,8 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emit_op_mul(Instruction* currentInstruction)
</span><span class="cx"> {
</span><del>-    JITMulIC* mulIC = m_codeBlock-&gt;addJITMulIC();
</del><ins>+    ArithProfile* arithProfile = m_codeBlock-&gt;arithProfileForPC(currentInstruction);
+    JITMulIC* mulIC = m_codeBlock-&gt;addJITMulIC(arithProfile);
</ins><span class="cx">     m_instructionToMathIC.add(currentInstruction, mulIC);
</span><span class="cx">     emitMathICFast(mulIC, currentInstruction, operationValueMulProfiled, operationValueMul);
</span><span class="cx"> }
</span><span class="lines">@@ -1004,7 +1004,8 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT::emit_op_sub(Instruction* currentInstruction)
</span><span class="cx"> {
</span><del>-    JITSubIC* subIC = m_codeBlock-&gt;addJITSubIC();
</del><ins>+    ArithProfile* arithProfile = m_codeBlock-&gt;arithProfileForPC(currentInstruction);
+    JITSubIC* subIC = m_codeBlock-&gt;addJITSubIC(arithProfile);
</ins><span class="cx">     m_instructionToMathIC.add(currentInstruction, subIC);
</span><span class="cx">     emitMathICFast(subIC, currentInstruction, operationValueSubProfiled, operationValueSub);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITInlines.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITInlines.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITInlines.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -448,14 +448,6 @@
</span><span class="cx">     return call;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJArpMic operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, ArithProfile* arithProfile, TrustedImmPtr mathIC)
-{
-    setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(arithProfile), mathIC);
-    Call call = appendCallWithExceptionCheck(operation);
-    setupResults(result);
-    return call;
-}
-
</del><span class="cx"> ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJMic operation, JSValueRegs result, JSValueRegs arg, TrustedImmPtr mathIC)
</span><span class="cx"> {
</span><span class="cx">     setupArgumentsWithExecState(arg, mathIC);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITMathICh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITMathIC.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITMathIC.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITMathIC.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -53,9 +53,14 @@
</span><span class="cx"> 
</span><span class="cx"> #define ENABLE_MATH_IC_STATS 0
</span><span class="cx"> 
</span><del>-template &lt;typename GeneratorType, bool(*isProfileEmpty)(ArithProfile*)&gt;
</del><ins>+template &lt;typename GeneratorType, bool(*isProfileEmpty)(ArithProfile&amp;)&gt;
</ins><span class="cx"> class JITMathIC {
</span><span class="cx"> public:
</span><ins>+    JITMathIC(ArithProfile* arithProfile)
+        : m_arithProfile(arithProfile)
+    {
+    }
+
</ins><span class="cx">     CodeLocationLabel doneLocation() { return m_inlineStart.labelAtOffset(m_inlineSize); }
</span><span class="cx">     CodeLocationLabel slowPathStartLocation() { return m_inlineStart.labelAtOffset(m_deltaFromStartToSlowPathStart); }
</span><span class="cx">     CodeLocationCall slowPathCallLocation() { return m_inlineStart.callAtOffset(m_deltaFromStartToSlowPathCallLocation); }
</span><span class="lines">@@ -72,8 +77,8 @@
</span><span class="cx">         state.fastPathStart = jit.label();
</span><span class="cx">         size_t startSize = jit.m_assembler.buffer().codeSize();
</span><span class="cx"> 
</span><del>-        if (ArithProfile* arithProfile = m_generator.arithProfile()) {
-            if (!isProfileEmpty(arithProfile)) {
</del><ins>+        if (m_arithProfile) {
+            if (isProfileEmpty(*m_arithProfile)) {
</ins><span class="cx">                 // It looks like the MathIC has yet to execute. We don't want to emit code in this
</span><span class="cx">                 // case for a couple reasons. First, the operation may never execute, so if we don't emit
</span><span class="cx">                 // code, it's a win. Second, if the operation does execute, we can emit better code
</span><span class="lines">@@ -89,7 +94,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        JITMathICInlineResult result = m_generator.generateInline(jit, state);
</del><ins>+        JITMathICInlineResult result = m_generator.generateInline(jit, state, m_arithProfile);
</ins><span class="cx"> 
</span><span class="cx">         switch (result) {
</span><span class="cx">         case JITMathICInlineResult::GeneratedFastPath: {
</span><span class="lines">@@ -104,7 +109,7 @@
</span><span class="cx">         }
</span><span class="cx">         case JITMathICInlineResult::GenerateFullSnippet: {
</span><span class="cx">             MacroAssembler::JumpList endJumpList;
</span><del>-            bool result = m_generator.generateFastPath(jit, endJumpList, state.slowPathJumps, shouldEmitProfiling);
</del><ins>+            bool result = m_generator.generateFastPath(jit, endJumpList, state.slowPathJumps, m_arithProfile, shouldEmitProfiling);
</ins><span class="cx">             if (result) {
</span><span class="cx">                 state.fastPathEnd = jit.label();
</span><span class="cx">                 state.shouldSlowPathRepatch = false;
</span><span class="lines">@@ -190,7 +195,7 @@
</span><span class="cx">             MacroAssembler::JumpList endJumpList; 
</span><span class="cx">             MacroAssembler::JumpList slowPathJumpList; 
</span><span class="cx"> 
</span><del>-            bool emittedFastPath = m_generator.generateFastPath(jit, endJumpList, slowPathJumpList, shouldEmitProfiling);
</del><ins>+            bool emittedFastPath = m_generator.generateFastPath(jit, endJumpList, slowPathJumpList, m_arithProfile, shouldEmitProfiling);
</ins><span class="cx">             if (!emittedFastPath)
</span><span class="cx">                 return;
</span><span class="cx">             endJumpList.append(jit.jump());
</span><span class="lines">@@ -224,6 +229,8 @@
</span><span class="cx">             start, linkBuffer.locationOf(state.slowPathStart));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ArithProfile* arithProfile() const { return m_arithProfile; }
+
</ins><span class="cx"> #if ENABLE(MATH_IC_STATS)
</span><span class="cx">     size_t m_generatedCodeSize { 0 };
</span><span class="cx">     size_t codeSize() const
</span><span class="lines">@@ -235,6 +242,7 @@
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    ArithProfile* m_arithProfile;
</ins><span class="cx">     MacroAssemblerCodeRef m_code;
</span><span class="cx">     CodeLocationLabel m_inlineStart;
</span><span class="cx">     int32_t m_inlineSize;
</span><span class="lines">@@ -244,12 +252,18 @@
</span><span class="cx">     GeneratorType m_generator;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline bool canGenerateWithBinaryProfile(ArithProfile* arithProfile)
</del><ins>+inline bool isBinaryProfileEmpty(ArithProfile&amp; arithProfile)
</ins><span class="cx"> {
</span><del>-    return !arithProfile-&gt;lhsObservedType().isEmpty() &amp;&amp; !arithProfile-&gt;rhsObservedType().isEmpty();
</del><ins>+    return arithProfile.lhsObservedType().isEmpty() || arithProfile.rhsObservedType().isEmpty();
</ins><span class="cx"> }
</span><span class="cx"> template &lt;typename GeneratorType&gt;
</span><del>-class JITBinaryMathIC : public JITMathIC&lt;GeneratorType, canGenerateWithBinaryProfile&gt; { };
</del><ins>+class JITBinaryMathIC : public JITMathIC&lt;GeneratorType, isBinaryProfileEmpty&gt; {
+public:
+    JITBinaryMathIC(ArithProfile* arithProfile)
+        : JITMathIC&lt;GeneratorType, isBinaryProfileEmpty&gt;(arithProfile)
+    {
+    }
+};
</ins><span class="cx"> 
</span><span class="cx"> typedef JITBinaryMathIC&lt;JITAddGenerator&gt; JITAddIC;
</span><span class="cx"> typedef JITBinaryMathIC&lt;JITMulGenerator&gt; JITMulIC;
</span><span class="lines">@@ -256,12 +270,18 @@
</span><span class="cx"> typedef JITBinaryMathIC&lt;JITSubGenerator&gt; JITSubIC;
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-inline bool canGenerateWithUnaryProfile(ArithProfile* arithProfile)
</del><ins>+inline bool isUnaryProfileEmpty(ArithProfile&amp; arithProfile)
</ins><span class="cx"> {
</span><del>-    return !arithProfile-&gt;lhsObservedType().isEmpty();
</del><ins>+    return arithProfile.lhsObservedType().isEmpty();
</ins><span class="cx"> }
</span><span class="cx"> template &lt;typename GeneratorType&gt;
</span><del>-class JITUnaryMathIC : public JITMathIC&lt;GeneratorType, canGenerateWithUnaryProfile&gt; { };
</del><ins>+class JITUnaryMathIC : public JITMathIC&lt;GeneratorType, isUnaryProfileEmpty&gt; {
+public:
+    JITUnaryMathIC(ArithProfile* arithProfile)
+        : JITMathIC&lt;GeneratorType, isUnaryProfileEmpty&gt;(arithProfile)
+    {
+    }
+};
</ins><span class="cx"> 
</span><span class="cx"> typedef JITUnaryMathIC&lt;JITNegGenerator&gt; JITNegIC;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITMulGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITMulGenerator.cpp (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITMulGenerator.cpp        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITMulGenerator.cpp        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -33,15 +33,14 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers&amp; jit, MathICGenerationState&amp; state)
</del><ins>+JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers&amp; jit, MathICGenerationState&amp; state, const ArithProfile* arithProfile)
</ins><span class="cx"> {
</span><span class="cx">     // We default to speculating int32.
</span><span class="cx">     ObservedType lhs = ObservedType().withInt32();
</span><span class="cx">     ObservedType rhs = ObservedType().withInt32();
</span><del>-
-    if (m_arithProfile) {
-        lhs = m_arithProfile-&gt;lhsObservedType();
-        rhs = m_arithProfile-&gt;rhsObservedType();
</del><ins>+    if (arithProfile) {
+        lhs = arithProfile-&gt;lhsObservedType();
+        rhs = arithProfile-&gt;rhsObservedType();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (lhs.isOnlyNonNumber() &amp;&amp; rhs.isOnlyNonNumber())
</span><span class="lines">@@ -88,7 +87,7 @@
</span><span class="cx">     return JITMathICInlineResult::GenerateFullSnippet;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JITMulGenerator::generateFastPath(CCallHelpers&amp; jit, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, bool shouldEmitProfiling)
</del><ins>+bool JITMulGenerator::generateFastPath(CCallHelpers&amp; jit, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_scratchGPR != InvalidGPRReg);
</span><span class="cx">     ASSERT(m_scratchGPR != m_left.payloadGPR());
</span><span class="lines">@@ -191,7 +190,7 @@
</span><span class="cx">     // Do doubleVar * doubleVar.
</span><span class="cx">     jit.mulDouble(m_rightFPR, m_leftFPR);
</span><span class="cx"> 
</span><del>-    if (!m_arithProfile || !shouldEmitProfiling)
</del><ins>+    if (!arithProfile || !shouldEmitProfiling)
</ins><span class="cx">         jit.boxDouble(m_leftFPR, m_result);
</span><span class="cx">     else {
</span><span class="cx">         // The Int52 overflow check below intentionally omits 1ll &lt;&lt; 51 as a valid negative Int52 value.
</span><span class="lines">@@ -204,11 +203,11 @@
</span><span class="cx"> 
</span><span class="cx">         CCallHelpers::Jump notNegativeZero = jit.branch64(CCallHelpers::NotEqual, m_result.payloadGPR(), CCallHelpers::TrustedImm64(negativeZeroBits));
</span><span class="cx"> 
</span><del>-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(m_arithProfile-&gt;addressOfBits()));
</del><ins>+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile-&gt;addressOfBits()));
</ins><span class="cx">         CCallHelpers::Jump done = jit.jump();
</span><span class="cx"> 
</span><span class="cx">         notNegativeZero.link(&amp;jit);
</span><del>-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(m_arithProfile-&gt;addressOfBits()));
</del><ins>+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile-&gt;addressOfBits()));
</ins><span class="cx"> 
</span><span class="cx">         jit.move(m_result.payloadGPR(), m_scratchGPR);
</span><span class="cx">         jit.urshiftPtr(CCallHelpers::Imm32(52), m_scratchGPR);
</span><span class="lines">@@ -215,7 +214,7 @@
</span><span class="cx">         jit.and32(CCallHelpers::Imm32(0x7ff), m_scratchGPR);
</span><span class="cx">         CCallHelpers::Jump noInt52Overflow = jit.branch32(CCallHelpers::LessThanOrEqual, m_scratchGPR, CCallHelpers::TrustedImm32(0x431));
</span><span class="cx"> 
</span><del>-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(m_arithProfile-&gt;addressOfBits()));
</del><ins>+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile-&gt;addressOfBits()));
</ins><span class="cx">         noInt52Overflow.link(&amp;jit);
</span><span class="cx"> 
</span><span class="cx">         done.link(&amp;jit);
</span><span class="lines">@@ -226,11 +225,11 @@
</span><span class="cx">         notNegativeZero.append(jit.branch32(CCallHelpers::NotEqual, m_result.payloadGPR(), CCallHelpers::TrustedImm32(0)));
</span><span class="cx">         notNegativeZero.append(jit.branch32(CCallHelpers::NotEqual, m_result.tagGPR(), CCallHelpers::TrustedImm32(negativeZeroBits &gt;&gt; 32)));
</span><span class="cx"> 
</span><del>-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(m_arithProfile-&gt;addressOfBits()));
</del><ins>+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile-&gt;addressOfBits()));
</ins><span class="cx">         CCallHelpers::Jump done = jit.jump();
</span><span class="cx"> 
</span><span class="cx">         notNegativeZero.link(&amp;jit);
</span><del>-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(m_arithProfile-&gt;addressOfBits()));
</del><ins>+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile-&gt;addressOfBits()));
</ins><span class="cx"> 
</span><span class="cx">         jit.move(m_result.tagGPR(), m_scratchGPR);
</span><span class="cx">         jit.urshiftPtr(CCallHelpers::Imm32(52 - 32), m_scratchGPR);
</span><span class="lines">@@ -237,7 +236,7 @@
</span><span class="cx">         jit.and32(CCallHelpers::Imm32(0x7ff), m_scratchGPR);
</span><span class="cx">         CCallHelpers::Jump noInt52Overflow = jit.branch32(CCallHelpers::LessThanOrEqual, m_scratchGPR, CCallHelpers::TrustedImm32(0x431));
</span><span class="cx">         
</span><del>-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(m_arithProfile-&gt;addressOfBits()));
</del><ins>+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile-&gt;addressOfBits()));
</ins><span class="cx"> 
</span><span class="cx">         endJumpList.append(noInt52Overflow);
</span><span class="cx">         if (m_scratchGPR == m_result.tagGPR() || m_scratchGPR == m_result.payloadGPR())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITMulGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITMulGenerator.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITMulGenerator.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITMulGenerator.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -43,8 +43,7 @@
</span><span class="cx"> 
</span><span class="cx">     JITMulGenerator(SnippetOperand leftOperand, SnippetOperand rightOperand,
</span><span class="cx">         JSValueRegs result, JSValueRegs left, JSValueRegs right,
</span><del>-        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR,
-        ArithProfile* arithProfile = nullptr)
</del><ins>+        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR)
</ins><span class="cx">         : m_leftOperand(leftOperand)
</span><span class="cx">         , m_rightOperand(rightOperand)
</span><span class="cx">         , m_result(result)
</span><span class="lines">@@ -54,19 +53,16 @@
</span><span class="cx">         , m_rightFPR(rightFPR)
</span><span class="cx">         , m_scratchGPR(scratchGPR)
</span><span class="cx">         , m_scratchFPR(scratchFPR)
</span><del>-        , m_arithProfile(arithProfile)
</del><span class="cx">     {
</span><span class="cx">         ASSERT(!m_leftOperand.isPositiveConstInt32() || !m_rightOperand.isPositiveConstInt32());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JITMathICInlineResult generateInline(CCallHelpers&amp;, MathICGenerationState&amp;);
-    bool generateFastPath(CCallHelpers&amp;, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowJumpList, bool shouldEmitProfiling);
</del><ins>+    JITMathICInlineResult generateInline(CCallHelpers&amp;, MathICGenerationState&amp;, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&amp;, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowJumpList, const ArithProfile*, bool shouldEmitProfiling);
</ins><span class="cx"> 
</span><span class="cx">     static bool isLeftOperandValidConstant(SnippetOperand leftOperand) { return leftOperand.isPositiveConstInt32(); }
</span><span class="cx">     static bool isRightOperandValidConstant(SnippetOperand rightOperand) { return rightOperand.isPositiveConstInt32(); }
</span><span class="cx">     
</span><del>-    ArithProfile* arithProfile() const { return m_arithProfile; }
-
</del><span class="cx"> private:
</span><span class="cx">     SnippetOperand m_leftOperand;
</span><span class="cx">     SnippetOperand m_rightOperand;
</span><span class="lines">@@ -77,7 +73,6 @@
</span><span class="cx">     FPRReg m_rightFPR;
</span><span class="cx">     GPRReg m_scratchGPR;
</span><span class="cx">     FPRReg m_scratchFPR;
</span><del>-    ArithProfile* m_arithProfile;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITNegGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITNegGenerator.cpp (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITNegGenerator.cpp        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITNegGenerator.cpp        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers&amp; jit, MathICGenerationState&amp; state)
</del><ins>+JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers&amp; jit, MathICGenerationState&amp; state, const ArithProfile* arithProfile)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_scratchGPR != InvalidGPRReg);
</span><span class="cx">     ASSERT(m_scratchGPR != m_src.payloadGPR());
</span><span class="lines">@@ -42,7 +42,10 @@
</span><span class="cx">     ASSERT(m_scratchGPR != m_result.tagGPR());
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    ObservedType observedTypes = m_arithProfile-&gt;lhsObservedType();
</del><ins>+    // We default to speculating int32.
+    ObservedType observedTypes = ObservedType().withInt32();
+    if (arithProfile)
+        observedTypes = arithProfile-&gt;lhsObservedType();
</ins><span class="cx">     ASSERT_WITH_MESSAGE(!observedTypes.isEmpty(), &quot;We should not attempt to generate anything if we do not have a profile.&quot;);
</span><span class="cx"> 
</span><span class="cx">     if (observedTypes.isOnlyNonNumber())
</span><span class="lines">@@ -79,7 +82,7 @@
</span><span class="cx">     return JITMathICInlineResult::GenerateFullSnippet;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JITNegGenerator::generateFastPath(CCallHelpers&amp; jit, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, bool)
</del><ins>+bool JITNegGenerator::generateFastPath(CCallHelpers&amp; jit, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, const ArithProfile*, bool)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_scratchGPR != m_src.payloadGPR());
</span><span class="cx">     ASSERT(m_scratchGPR != m_result.payloadGPR());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITNegGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITNegGenerator.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITNegGenerator.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITNegGenerator.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -38,20 +38,16 @@
</span><span class="cx"> public:
</span><span class="cx">     JITNegGenerator() = default;
</span><span class="cx"> 
</span><del>-    JITNegGenerator(JSValueRegs result, JSValueRegs src, GPRReg scratchGPR, ArithProfile&amp; arithProfile)
-        : m_arithProfile(&amp;arithProfile)
-        , m_result(result)
</del><ins>+    JITNegGenerator(JSValueRegs result, JSValueRegs src, GPRReg scratchGPR)
+        : m_result(result)
</ins><span class="cx">         , m_src(src)
</span><span class="cx">         , m_scratchGPR(scratchGPR)
</span><span class="cx">     { }
</span><span class="cx"> 
</span><del>-    JITMathICInlineResult generateInline(CCallHelpers&amp;, MathICGenerationState&amp;);
-    bool generateFastPath(CCallHelpers&amp;, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, bool shouldEmitProfiling);
</del><ins>+    JITMathICInlineResult generateInline(CCallHelpers&amp;, MathICGenerationState&amp;, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&amp;, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);
</ins><span class="cx"> 
</span><del>-    ArithProfile* arithProfile() const { return m_arithProfile; }
-
</del><span class="cx"> private:
</span><del>-    ArithProfile* m_arithProfile { nullptr };
</del><span class="cx">     JSValueRegs m_result;
</span><span class="cx">     JSValueRegs m_src;
</span><span class="cx">     GPRReg m_scratchGPR;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -2270,7 +2270,7 @@
</span><span class="cx">     return JSValue::encode(jsAdd(exec, op1, op2));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE static EncodedJSValue profiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
</del><ins>+ALWAYS_INLINE static EncodedJSValue profiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile&amp; arithProfile)
</ins><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="lines">@@ -2278,11 +2278,9 @@
</span><span class="cx">     JSValue op1 = JSValue::decode(encodedOp1);
</span><span class="cx">     JSValue op2 = JSValue::decode(encodedOp2);
</span><span class="cx"> 
</span><del>-    ASSERT(arithProfile);
-    arithProfile-&gt;observeLHSAndRHS(op1, op2);
-
</del><ins>+    arithProfile.observeLHSAndRHS(op1, op2);
</ins><span class="cx">     JSValue result = jsAdd(exec, op1, op2);
</span><del>-    arithProfile-&gt;observeResult(result);
</del><ins>+    arithProfile.observeResult(result);
</ins><span class="cx"> 
</span><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="lines">@@ -2294,10 +2292,11 @@
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
</span><span class="cx"> {
</span><del>-    return profiledAdd(exec, encodedOp1, encodedOp2, arithProfile);
</del><ins>+    ASSERT(arithProfile);
+    return profiledAdd(exec, encodedOp1, encodedOp2, *arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITAddIC* addIC)
</del><ins>+EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC* addIC)
</ins><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="lines">@@ -2305,6 +2304,7 @@
</span><span class="cx">     JSValue op1 = JSValue::decode(encodedOp1);
</span><span class="cx">     JSValue op2 = JSValue::decode(encodedOp2);
</span><span class="cx"> 
</span><ins>+    ArithProfile* arithProfile = addIC-&gt;arithProfile();
</ins><span class="cx">     ASSERT(arithProfile);
</span><span class="cx">     arithProfile-&gt;observeLHSAndRHS(op1, op2);
</span><span class="cx">     auto nonOptimizeVariant = operationValueAddProfiledNoOptimize;
</span><span class="lines">@@ -2320,9 +2320,14 @@
</span><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITAddIC*)
</del><ins>+EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC* addIC)
</ins><span class="cx"> {
</span><del>-    return profiledAdd(exec, encodedOp1, encodedOp2, arithProfile);
</del><ins>+    VM* vm = &amp;exec-&gt;vm();
+    NativeCallFrameTracer tracer(vm, exec);
+
+    ArithProfile* arithProfile = addIC-&gt;arithProfile();
+    ASSERT(arithProfile);
+    return profiledAdd(exec, encodedOp1, encodedOp2, *arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueAddOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC* addIC)
</span><span class="lines">@@ -2334,7 +2339,7 @@
</span><span class="cx">     JSValue op2 = JSValue::decode(encodedOp2);
</span><span class="cx"> 
</span><span class="cx">     auto nonOptimizeVariant = operationValueAddNoOptimize;
</span><del>-    if (ArithProfile* arithProfile = addIC-&gt;m_generator.arithProfile())
</del><ins>+    if (ArithProfile* arithProfile = addIC-&gt;arithProfile())
</ins><span class="cx">         arithProfile-&gt;observeLHSAndRHS(op1, op2);
</span><span class="cx">     addIC-&gt;generateOutOfLine(*vm, exec-&gt;codeBlock(), nonOptimizeVariant);
</span><span class="cx"> 
</span><span class="lines">@@ -2370,7 +2375,7 @@
</span><span class="cx">     return JSValue::encode(jsNumber(a * b));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE static EncodedJSValue profiledMul(VM&amp; vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, bool shouldObserveLHSAndRHSTypes = true)
</del><ins>+ALWAYS_INLINE static EncodedJSValue profiledMul(VM&amp; vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile&amp; arithProfile, bool shouldObserveLHSAndRHSTypes = true)
</ins><span class="cx"> {
</span><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx">     JSValue op1 = JSValue::decode(encodedOp1);
</span><span class="lines">@@ -2377,7 +2382,7 @@
</span><span class="cx">     JSValue op2 = JSValue::decode(encodedOp2);
</span><span class="cx"> 
</span><span class="cx">     if (shouldObserveLHSAndRHSTypes)
</span><del>-        arithProfile-&gt;observeLHSAndRHS(op1, op2);
</del><ins>+        arithProfile.observeLHSAndRHS(op1, op2);
</ins><span class="cx"> 
</span><span class="cx">     double a = op1.toNumber(exec);
</span><span class="cx">     RETURN_IF_EXCEPTION(scope, encodedJSValue());
</span><span class="lines">@@ -2385,7 +2390,7 @@
</span><span class="cx">     RETURN_IF_EXCEPTION(scope, encodedJSValue());
</span><span class="cx">     
</span><span class="cx">     JSValue result = jsNumber(a * b);
</span><del>-    arithProfile-&gt;observeResult(result);
</del><ins>+    arithProfile.observeResult(result);
</ins><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2411,7 +2416,7 @@
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="cx"> 
</span><span class="cx">     auto nonOptimizeVariant = operationValueMulNoOptimize;
</span><del>-    if (ArithProfile* arithProfile = mulIC-&gt;m_generator.arithProfile())
</del><ins>+    if (ArithProfile* arithProfile = mulIC-&gt;arithProfile())
</ins><span class="cx">         arithProfile-&gt;observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
</span><span class="cx">     mulIC-&gt;generateOutOfLine(*vm, exec-&gt;codeBlock(), nonOptimizeVariant);
</span><span class="cx"> 
</span><span class="lines">@@ -2427,14 +2432,17 @@
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="cx"> 
</span><del>-    return profiledMul(*vm, exec, encodedOp1, encodedOp2, arithProfile);
</del><ins>+    ASSERT(arithProfile);
+    return profiledMul(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITMulIC* mulIC)
</del><ins>+EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC* mulIC)
</ins><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="cx"> 
</span><ins>+    ArithProfile* arithProfile = mulIC-&gt;arithProfile();
+    ASSERT(arithProfile);
</ins><span class="cx">     arithProfile-&gt;observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
</span><span class="cx">     auto nonOptimizeVariant = operationValueMulProfiledNoOptimize;
</span><span class="cx">     mulIC-&gt;generateOutOfLine(*vm, exec-&gt;codeBlock(), nonOptimizeVariant);
</span><span class="lines">@@ -2443,15 +2451,17 @@
</span><span class="cx">     exec-&gt;codeBlock()-&gt;dumpMathICStats();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    return profiledMul(*vm, exec, encodedOp1, encodedOp2, arithProfile, false);
</del><ins>+    return profiledMul(*vm, exec, encodedOp1, encodedOp2, *arithProfile, false);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITMulIC*)
</del><ins>+EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC* mulIC)
</ins><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="cx"> 
</span><del>-    return profiledMul(*vm, exec, encodedOp1, encodedOp2, arithProfile);
</del><ins>+    ArithProfile* arithProfile = mulIC-&gt;arithProfile();
+    ASSERT(arithProfile);
+    return profiledMul(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE static EncodedJSValue unprofiledNegate(ExecState* exec, EncodedJSValue encodedOperand)
</span><span class="lines">@@ -2467,15 +2477,14 @@
</span><span class="cx">     return JSValue::encode(jsNumber(-number));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE static EncodedJSValue profiledNegate(ExecState* exec, EncodedJSValue encodedOperand, ArithProfile* arithProfile)
</del><ins>+ALWAYS_INLINE static EncodedJSValue profiledNegate(ExecState* exec, EncodedJSValue encodedOperand, ArithProfile&amp; arithProfile)
</ins><span class="cx"> {
</span><del>-    ASSERT(arithProfile);
</del><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx">     NativeCallFrameTracer tracer(&amp;vm, exec);
</span><span class="cx"> 
</span><span class="cx">     JSValue operand = JSValue::decode(encodedOperand);
</span><del>-    arithProfile-&gt;observeLHS(operand);
</del><ins>+    arithProfile.observeLHS(operand);
</ins><span class="cx">     double number = operand.toNumber(exec);
</span><span class="cx">     if (UNLIKELY(scope.exception()))
</span><span class="cx">         return JSValue::encode(JSValue());
</span><span class="lines">@@ -2489,7 +2498,8 @@
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState* exec, EncodedJSValue operand, ArithProfile* arithProfile)
</span><span class="cx"> {
</span><del>-    return profiledNegate(exec, operand, arithProfile);
</del><ins>+    ASSERT(arithProfile);
+    return profiledNegate(exec, operand, *arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationArithNegateProfiledOptimize(ExecState* exec, EncodedJSValue encodedOperand, JITNegIC* negIC)
</span><span class="lines">@@ -2500,7 +2510,7 @@
</span><span class="cx">     
</span><span class="cx">     JSValue operand = JSValue::decode(encodedOperand);
</span><span class="cx"> 
</span><del>-    ArithProfile* arithProfile = negIC-&gt;m_generator.arithProfile();
</del><ins>+    ArithProfile* arithProfile = negIC-&gt;arithProfile();
</ins><span class="cx">     ASSERT(arithProfile);
</span><span class="cx">     arithProfile-&gt;observeLHS(operand);
</span><span class="cx">     negIC-&gt;generateOutOfLine(vm, exec-&gt;codeBlock(), operationArithNegateProfiled);
</span><span class="lines">@@ -2523,9 +2533,8 @@
</span><span class="cx"> 
</span><span class="cx">     JSValue operand = JSValue::decode(encodedOperand);
</span><span class="cx"> 
</span><del>-    ArithProfile* arithProfile = negIC-&gt;m_generator.arithProfile();
-    ASSERT(arithProfile);
-    arithProfile-&gt;observeLHS(operand);
</del><ins>+    if (ArithProfile* arithProfile = negIC-&gt;arithProfile())
+        arithProfile-&gt;observeLHS(operand);
</ins><span class="cx">     negIC-&gt;generateOutOfLine(vm, exec-&gt;codeBlock(), operationArithNegate);
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MATH_IC_STATS)
</span><span class="lines">@@ -2550,7 +2559,7 @@
</span><span class="cx">     return JSValue::encode(jsNumber(a - b));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE static EncodedJSValue profiledSub(VM&amp; vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, bool shouldObserveLHSAndRHSTypes = true)
</del><ins>+ALWAYS_INLINE static EncodedJSValue profiledSub(VM&amp; vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile&amp; arithProfile, bool shouldObserveLHSAndRHSTypes = true)
</ins><span class="cx"> {
</span><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx">     JSValue op1 = JSValue::decode(encodedOp1);
</span><span class="lines">@@ -2557,7 +2566,7 @@
</span><span class="cx">     JSValue op2 = JSValue::decode(encodedOp2);
</span><span class="cx"> 
</span><span class="cx">     if (shouldObserveLHSAndRHSTypes)
</span><del>-        arithProfile-&gt;observeLHSAndRHS(op1, op2);
</del><ins>+        arithProfile.observeLHSAndRHS(op1, op2);
</ins><span class="cx"> 
</span><span class="cx">     double a = op1.toNumber(exec);
</span><span class="cx">     RETURN_IF_EXCEPTION(scope, encodedJSValue());
</span><span class="lines">@@ -2565,7 +2574,7 @@
</span><span class="cx">     RETURN_IF_EXCEPTION(scope, encodedJSValue());
</span><span class="cx">     
</span><span class="cx">     JSValue result = jsNumber(a - b);
</span><del>-    arithProfile-&gt;observeResult(result);
</del><ins>+    arithProfile.observeResult(result);
</ins><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2578,10 +2587,12 @@
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
</span><span class="cx"> {
</span><ins>+    ASSERT(arithProfile);
+
</ins><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="cx"> 
</span><del>-    return profiledSub(*vm, exec, encodedOp1, encodedOp2, arithProfile);
</del><ins>+    return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueSubOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC)
</span><span class="lines">@@ -2590,7 +2601,7 @@
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="cx"> 
</span><span class="cx">     auto nonOptimizeVariant = operationValueSubNoOptimize;
</span><del>-    if (ArithProfile* arithProfile = subIC-&gt;m_generator.arithProfile())
</del><ins>+    if (ArithProfile* arithProfile = subIC-&gt;arithProfile())
</ins><span class="cx">         arithProfile-&gt;observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
</span><span class="cx">     subIC-&gt;generateOutOfLine(*vm, exec-&gt;codeBlock(), nonOptimizeVariant);
</span><span class="cx"> 
</span><span class="lines">@@ -2609,11 +2620,13 @@
</span><span class="cx">     return unprofiledSub(*vm, exec, encodedOp1, encodedOp2);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITSubIC* subIC)
</del><ins>+EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC)
</ins><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="cx"> 
</span><ins>+    ArithProfile* arithProfile = subIC-&gt;arithProfile();
+    ASSERT(arithProfile);
</ins><span class="cx">     arithProfile-&gt;observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
</span><span class="cx">     auto nonOptimizeVariant = operationValueSubProfiledNoOptimize;
</span><span class="cx">     subIC-&gt;generateOutOfLine(*vm, exec-&gt;codeBlock(), nonOptimizeVariant);
</span><span class="lines">@@ -2622,15 +2635,17 @@
</span><span class="cx">     exec-&gt;codeBlock()-&gt;dumpMathICStats();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    return profiledSub(*vm, exec, encodedOp1, encodedOp2, arithProfile, false);
</del><ins>+    return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile, false);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITSubIC*)
</del><ins>+EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC)
</ins><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="cx"> 
</span><del>-    return profiledSub(*vm, exec, encodedOp1, encodedOp2, arithProfile);
</del><ins>+    ArithProfile* arithProfile = subIC-&gt;arithProfile();
+    ASSERT(arithProfile);
+    return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JIT_OPERATION operationProcessTypeProfilerLog(ExecState* exec)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -148,7 +148,6 @@
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJBy)(ExecState*, EncodedJSValue, EncodedJSValue, ByValInfo*);
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue);
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJArp)(ExecState*, EncodedJSValue, EncodedJSValue, ArithProfile*);
</span><del>-typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJArpMic)(ExecState*, EncodedJSValue, EncodedJSValue, ArithProfile*, void*);
</del><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJMic)(ExecState*, EncodedJSValue, EncodedJSValue, void*);
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJMic)(ExecState*, EncodedJSValue, void*);
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJssZ)(ExecState*, JSString*, int32_t);
</span><span class="lines">@@ -429,15 +428,15 @@
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
</span><del>-EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITAddIC*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITAddIC*) WTF_INTERNAL;
</del><ins>+EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
</ins><span class="cx"> EncodedJSValue JIT_OPERATION operationValueAddOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueAddNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueMul(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueMulOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueMulNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
</span><del>-EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITMulIC*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITMulIC*) WTF_INTERNAL;
</del><ins>+EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
</ins><span class="cx"> EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationArithNegate(ExecState*, EncodedJSValue operand);
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState*, EncodedJSValue operand, ArithProfile*);
</span><span class="lines">@@ -447,8 +446,8 @@
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueSubOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationValueSubNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
</span><del>-EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITSubIC*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITSubIC*) WTF_INTERNAL;
</del><ins>+EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
</ins><span class="cx"> 
</span><span class="cx"> void JIT_OPERATION operationProcessTypeProfilerLog(ExecState*) WTF_INTERNAL;
</span><span class="cx"> void JIT_OPERATION operationProcessShadowChickenLog(ExecState*) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITSubGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITSubGenerator.cpp (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITSubGenerator.cpp        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITSubGenerator.cpp        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -33,14 +33,14 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers&amp; jit, MathICGenerationState&amp; state)
</del><ins>+JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers&amp; jit, MathICGenerationState&amp; state, const ArithProfile* arithProfile)
</ins><span class="cx"> {
</span><span class="cx">     // We default to speculating int32.
</span><span class="cx">     ObservedType lhs = ObservedType().withInt32();
</span><span class="cx">     ObservedType rhs = ObservedType().withInt32();
</span><del>-    if (m_arithProfile) {
-        lhs = m_arithProfile-&gt;lhsObservedType();
-        rhs = m_arithProfile-&gt;rhsObservedType();
</del><ins>+    if (arithProfile) {
+        lhs = arithProfile-&gt;lhsObservedType();
+        rhs = arithProfile-&gt;rhsObservedType();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (lhs.isOnlyNonNumber() &amp;&amp; rhs.isOnlyNonNumber())
</span><span class="lines">@@ -78,7 +78,7 @@
</span><span class="cx">     return JITMathICInlineResult::GenerateFullSnippet;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JITSubGenerator::generateFastPath(CCallHelpers&amp; jit, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, bool shouldEmitProfiling)
</del><ins>+bool JITSubGenerator::generateFastPath(CCallHelpers&amp; jit, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_scratchGPR != InvalidGPRReg);
</span><span class="cx">     ASSERT(m_scratchGPR != m_left.payloadGPR());
</span><span class="lines">@@ -129,8 +129,8 @@
</span><span class="cx">     rightWasInteger.link(&amp;jit);
</span><span class="cx"> 
</span><span class="cx">     jit.subDouble(m_rightFPR, m_leftFPR);
</span><del>-    if (m_arithProfile &amp;&amp; shouldEmitProfiling)
-        m_arithProfile-&gt;emitSetDouble(jit);
</del><ins>+    if (arithProfile &amp;&amp; shouldEmitProfiling)
+        arithProfile-&gt;emitSetDouble(jit);
</ins><span class="cx"> 
</span><span class="cx">     jit.boxDouble(m_leftFPR, m_result);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITSubGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITSubGenerator.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITSubGenerator.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/JavaScriptCore/jit/JITSubGenerator.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -42,8 +42,7 @@
</span><span class="cx"> 
</span><span class="cx">     JITSubGenerator(SnippetOperand leftOperand, SnippetOperand rightOperand,
</span><span class="cx">         JSValueRegs result, JSValueRegs left, JSValueRegs right,
</span><del>-        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR,
-        ArithProfile* arithProfile = nullptr)
</del><ins>+        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR)
</ins><span class="cx">         : m_leftOperand(leftOperand)
</span><span class="cx">         , m_rightOperand(rightOperand)
</span><span class="cx">         , m_result(result)
</span><span class="lines">@@ -53,17 +52,14 @@
</span><span class="cx">         , m_rightFPR(rightFPR)
</span><span class="cx">         , m_scratchGPR(scratchGPR)
</span><span class="cx">         , m_scratchFPR(scratchFPR)
</span><del>-        , m_arithProfile(arithProfile)
</del><span class="cx">     { }
</span><span class="cx"> 
</span><del>-    JITMathICInlineResult generateInline(CCallHelpers&amp;, MathICGenerationState&amp;);
-    bool generateFastPath(CCallHelpers&amp;, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, bool shouldEmitProfiling);
</del><ins>+    JITMathICInlineResult generateInline(CCallHelpers&amp;, MathICGenerationState&amp;, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&amp;, CCallHelpers::JumpList&amp; endJumpList, CCallHelpers::JumpList&amp; slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);
</ins><span class="cx"> 
</span><span class="cx">     static bool isLeftOperandValidConstant(SnippetOperand) { return false; }
</span><span class="cx">     static bool isRightOperandValidConstant(SnippetOperand) { return false; }
</span><span class="cx"> 
</span><del>-    ArithProfile* arithProfile() const { return m_arithProfile; }
-
</del><span class="cx"> private:
</span><span class="cx">     SnippetOperand m_leftOperand;
</span><span class="cx">     SnippetOperand m_rightOperand;
</span><span class="lines">@@ -74,7 +70,6 @@
</span><span class="cx">     FPRReg m_rightFPR;
</span><span class="cx">     GPRReg m_scratchGPR;
</span><span class="cx">     FPRReg m_scratchFPR;
</span><del>-    ArithProfile* m_arithProfile;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/WTF/ChangeLog        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-09-26  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        [JSC] Shrink the Math inline caches some more
+        https://bugs.webkit.org/show_bug.cgi?id=162485
+
+        Reviewed by Saam Barati.
+
+        * wtf/Bag.h:
+        Don't copy the arguments before initializing the nodes.
+
</ins><span class="cx"> 2016-09-26  Michael Catanzaro  &lt;mcatanzaro@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         std::unique_ptr deleter functions should not check if pointer is null
</span></span></pre></div>
<a id="trunkSourceWTFwtfBagh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Bag.h (206391 => 206392)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Bag.h        2016-09-26 21:02:42 UTC (rev 206391)
+++ trunk/Source/WTF/wtf/Bag.h        2016-09-26 21:11:31 UTC (rev 206392)
</span><span class="lines">@@ -37,8 +37,8 @@
</span><span class="cx">         WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx">     public:
</span><span class="cx">         template&lt;typename... Args&gt;
</span><del>-        Node(Args... args)
-            : m_item(args...)
</del><ins>+        Node(Args&amp;&amp;... args)
+            : m_item(std::forward&lt;Args&gt;(args)...)
</ins><span class="cx">         {
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -81,9 +81,9 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     template&lt;typename... Args&gt;
</span><del>-    T* add(Args... args)
</del><ins>+    T* add(Args&amp;&amp;... args)
</ins><span class="cx">     {
</span><del>-        Node* newNode = new Node(args...);
</del><ins>+        Node* newNode = new Node(std::forward&lt;Args&gt;(args)...);
</ins><span class="cx">         newNode-&gt;m_next = m_head;
</span><span class="cx">         m_head = newNode;
</span><span class="cx">         return &amp;newNode-&gt;m_item;
</span></span></pre>
</div>
</div>

</body>
</html>