<!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>[191840] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/191840">191840</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2015-10-31 02:15:35 -0700 (Sat, 31 Oct 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>JSC should have a forceGCSlowPaths option
https://bugs.webkit.org/show_bug.cgi?id=150744

Reviewed by Filip Pizlo.

This patch implements the forceGCSlowPaths option.
It defaults to false, but when it is set to true,
the JITs will always allocate objects along the slow
path. This will be helpful for writing a certain class
of tests. This may also come in handy for debugging
later.

This patch also adds the &quot;forceGCSlowPaths&quot; function
in jsc.cpp which sets the option to true. If you
use this function in a jsc stress test, it's best
to call it as the first thing in the program before
we JIT anything.

* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::emitAllocateJSCell):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::allocateCell):
* jit/JITInlines.h:
(JSC::JIT::emitAllocateJSObject):
* jsc.cpp:
(GlobalObject::finishCreation):
(functionEdenGC):
(functionForceGCSlowPaths):
(functionHeapSize):
* runtime/Options.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITInlinesh">trunk/Source/JavaScriptCore/jit/JITInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (191839 => 191840)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-10-31 04:58:28 UTC (rev 191839)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-10-31 09:15:35 UTC (rev 191840)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2015-10-31  Saam barati  &lt;sbarati@apple.com&gt;
+
+        JSC should have a forceGCSlowPaths option
+        https://bugs.webkit.org/show_bug.cgi?id=150744
+
+        Reviewed by Filip Pizlo.
+
+        This patch implements the forceGCSlowPaths option.
+        It defaults to false, but when it is set to true,
+        the JITs will always allocate objects along the slow
+        path. This will be helpful for writing a certain class
+        of tests. This may also come in handy for debugging
+        later.
+
+        This patch also adds the &quot;forceGCSlowPaths&quot; function
+        in jsc.cpp which sets the option to true. If you
+        use this function in a jsc stress test, it's best
+        to call it as the first thing in the program before
+        we JIT anything.
+
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSCell):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::allocateCell):
+        * jit/JITInlines.h:
+        (JSC::JIT::emitAllocateJSObject):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionEdenGC):
+        (functionForceGCSlowPaths):
+        (functionHeapSize):
+        * runtime/Options.h:
+
</ins><span class="cx"> 2015-10-30  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Test Debugger.scriptParsed events received after opening inspector frontend
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (191839 => 191840)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-10-31 04:58:28 UTC (rev 191839)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-10-31 09:15:35 UTC (rev 191840)
</span><span class="lines">@@ -2282,8 +2282,12 @@
</span><span class="cx">     void emitAllocateJSCell(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
</span><span class="cx">         GPRReg scratchGPR, MacroAssembler::JumpList&amp; slowPath)
</span><span class="cx">     {
</span><del>-        m_jit.loadPtr(MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()), resultGPR);
-        slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
</del><ins>+        if (Options::forceGCSlowPaths())
+            slowPath.append(m_jit.jump());
+        else {
+            m_jit.loadPtr(MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()), resultGPR);
+            slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
+        }
</ins><span class="cx">         
</span><span class="cx">         // The object is half-allocated: we have what we know is a fresh object, but
</span><span class="cx">         // it's still on the GC's free list.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (191839 => 191840)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-10-31 04:58:28 UTC (rev 191839)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-10-31 09:15:35 UTC (rev 191840)
</span><span class="lines">@@ -6411,18 +6411,25 @@
</span><span class="cx">     LValue allocateCell(LValue allocator, LBasicBlock slowPath)
</span><span class="cx">     {
</span><span class="cx">         LBasicBlock success = FTL_NEW_BLOCK(m_out, (&quot;object allocation success&quot;));
</span><ins>+    
+        LValue result;
+        LValue condition;
+        if (Options::forceGCSlowPaths()) {
+            result = getUndef(m_out.int64);
+            condition = m_out.booleanFalse;
+        } else {
+            result = m_out.loadPtr(
+                allocator, m_heaps.MarkedAllocator_freeListHead);
+            condition = m_out.notNull(result);
+        }
+        m_out.branch(condition, usually(success), rarely(slowPath));
</ins><span class="cx">         
</span><del>-        LValue result = m_out.loadPtr(
-            allocator, m_heaps.MarkedAllocator_freeListHead);
-        
-        m_out.branch(m_out.notNull(result), usually(success), rarely(slowPath));
-        
</del><span class="cx">         m_out.appendTo(success);
</span><span class="cx">         
</span><span class="cx">         m_out.storePtr(
</span><span class="cx">             m_out.loadPtr(result, m_heaps.JSCell_freeListNext),
</span><span class="cx">             allocator, m_heaps.MarkedAllocator_freeListHead);
</span><del>-        
</del><ins>+
</ins><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITInlines.h (191839 => 191840)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITInlines.h        2015-10-31 04:58:28 UTC (rev 191839)
+++ trunk/Source/JavaScriptCore/jit/JITInlines.h        2015-10-31 09:15:35 UTC (rev 191840)
</span><span class="lines">@@ -880,8 +880,12 @@
</span><span class="cx"> template&lt;typename StructureType&gt;
</span><span class="cx"> inline void JIT::emitAllocateJSObject(RegisterID allocator, StructureType structure, RegisterID result, RegisterID scratch)
</span><span class="cx"> {
</span><del>-    loadPtr(Address(allocator, MarkedAllocator::offsetOfFreeListHead()), result);
-    addSlowCase(branchTestPtr(Zero, result));
</del><ins>+    if (Options::forceGCSlowPaths())
+        addSlowCase(jump());
+    else {
+        loadPtr(Address(allocator, MarkedAllocator::offsetOfFreeListHead()), result);
+        addSlowCase(branchTestPtr(Zero, result));
+    }
</ins><span class="cx"> 
</span><span class="cx">     // remove the object from the free list
</span><span class="cx">     loadPtr(Address(result), scratch);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (191839 => 191840)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2015-10-31 04:58:28 UTC (rev 191839)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2015-10-31 09:15:35 UTC (rev 191840)
</span><span class="lines">@@ -508,6 +508,7 @@
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionGCAndSweep(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionFullGC(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState*);
</span><ins>+static EncodedJSValue JSC_HOST_CALL functionForceGCSlowPaths(ExecState*);
</ins><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState*);
</span><span class="cx"> #ifndef NDEBUG
</span><span class="lines">@@ -668,6 +669,7 @@
</span><span class="cx">         addFunction(vm, &quot;gc&quot;, functionGCAndSweep, 0);
</span><span class="cx">         addFunction(vm, &quot;fullGC&quot;, functionFullGC, 0);
</span><span class="cx">         addFunction(vm, &quot;edenGC&quot;, functionEdenGC, 0);
</span><ins>+        addFunction(vm, &quot;forceGCSlowPaths&quot;, functionForceGCSlowPaths, 0);
</ins><span class="cx">         addFunction(vm, &quot;gcHeapSize&quot;, functionHeapSize, 0);
</span><span class="cx">         addFunction(vm, &quot;addressOf&quot;, functionAddressOf, 1);
</span><span class="cx"> #ifndef NDEBUG
</span><span class="lines">@@ -1186,6 +1188,14 @@
</span><span class="cx">     return JSValue::encode(jsNumber(exec-&gt;heap()-&gt;sizeAfterLastEdenCollection()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+EncodedJSValue JSC_HOST_CALL functionForceGCSlowPaths(ExecState*)
+{
+    // It's best for this to be the first thing called in the 
+    // JS program so the option is set to true before we JIT.
+    Options::forceGCSlowPaths() = true;
+    return JSValue::encode(jsUndefined());
+}
+
</ins><span class="cx"> EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     JSLockHolder lock(exec);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (191839 => 191840)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2015-10-31 04:58:28 UTC (rev 191839)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2015-10-31 09:15:35 UTC (rev 191840)
</span><span class="lines">@@ -313,6 +313,7 @@
</span><span class="cx">     \
</span><span class="cx">     v(gcLogLevel, logGC, GCLogging::None, &quot;debugging option to log GC activity (0 = None, 1 = Basic, 2 = Verbose)&quot;) \
</span><span class="cx">     v(bool, useGC, true, nullptr) \
</span><ins>+    v(bool, forceGCSlowPaths, false, &quot;If true, we will force all JIT fast allocations down their slow paths.&quot;)\
</ins><span class="cx">     v(unsigned, gcMaxHeapSize, 0, nullptr) \
</span><span class="cx">     v(unsigned, forceRAMSize, 0, nullptr) \
</span><span class="cx">     v(bool, recordGCPauseTimes, false, nullptr) \
</span></span></pre>
</div>
</div>

</body>
</html>