<!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>[153175] 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/153175">153175</a></dd>
<dt>Author</dt> <dd>oliver@apple.com</dd>
<dt>Date</dt> <dd>2013-07-24 21:00:50 -0700 (Wed, 24 Jul 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>fourthTier: It should be possible to use more than one compiler thread
https://bugs.webkit.org/show_bug.cgi?id=116630

Reviewed by Mark Hahnenberg.

This gives us the ability to use more compiler threads, but doesn't actually
enable the functionality because it isn't a speed-up on any benchmark. It can
even be a slow-down. This also adds the ability to disable concurrent
compilation if we're on a uniprocessor machine, and adds more logging to the
worklist code to allow us to investigate how many threads are active. It
appears that even on the most compiler-heavy benchmarks, we never have enough
work for more than 4 threads, and even then the 4 threads are all active for
a short time.

Something that having more threads does accomplish is that it shakes out bugs.
This patch fixes a bug with Watchpoint not being thread-safe ref-counted,
which enabling 7 compilation threads did catch.

As it stands, this patch is performance-neutral and just fixes bugs and adds
some options.

* bytecode/Watchpoint.h:
* dfg/DFGCommon.h:
(JSC::DFG::enableConcurrentJIT):
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::Worklist):
(JSC::DFG::Worklist::~Worklist):
(JSC::DFG::Worklist::finishCreation):
(JSC::DFG::Worklist::create):
(JSC::DFG::Worklist::enqueue):
(JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady):
(JSC::DFG::Worklist::dump):
(JSC::DFG::Worklist::runThread):
(JSC::DFG::initializeGlobalWorklistOnce):
* dfg/DFGWorklist.h:
* runtime/Options.cpp:
(JSC::computeNumberOfWorkerThreads):
(JSC):
(JSC::computeNumberOfGCMarkers):
* runtime/Options.h:
(JSC):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeWatchpointh">trunk/Source/JavaScriptCore/bytecode/Watchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCommonh">trunk/Source/JavaScriptCore/dfg/DFGCommon.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWorklistcpp">trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWorklisth">trunk/Source/JavaScriptCore/dfg/DFGWorklist.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionscpp">trunk/Source/JavaScriptCore/runtime/Options.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 (153174 => 153175)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2013-07-25 04:00:48 UTC (rev 153174)
+++ trunk/Source/JavaScriptCore/ChangeLog        2013-07-25 04:00:50 UTC (rev 153175)
</span><span class="lines">@@ -1,5 +1,49 @@
</span><span class="cx"> 2013-05-22  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        fourthTier: It should be possible to use more than one compiler thread
+        https://bugs.webkit.org/show_bug.cgi?id=116630
+
+        Reviewed by Mark Hahnenberg.
+        
+        This gives us the ability to use more compiler threads, but doesn't actually
+        enable the functionality because it isn't a speed-up on any benchmark. It can
+        even be a slow-down. This also adds the ability to disable concurrent
+        compilation if we're on a uniprocessor machine, and adds more logging to the
+        worklist code to allow us to investigate how many threads are active. It
+        appears that even on the most compiler-heavy benchmarks, we never have enough
+        work for more than 4 threads, and even then the 4 threads are all active for
+        a short time.
+        
+        Something that having more threads does accomplish is that it shakes out bugs.
+        This patch fixes a bug with Watchpoint not being thread-safe ref-counted,
+        which enabling 7 compilation threads did catch.
+        
+        As it stands, this patch is performance-neutral and just fixes bugs and adds
+        some options.
+
+        * bytecode/Watchpoint.h:
+        * dfg/DFGCommon.h:
+        (JSC::DFG::enableConcurrentJIT):
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::Worklist):
+        (JSC::DFG::Worklist::~Worklist):
+        (JSC::DFG::Worklist::finishCreation):
+        (JSC::DFG::Worklist::create):
+        (JSC::DFG::Worklist::enqueue):
+        (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady):
+        (JSC::DFG::Worklist::dump):
+        (JSC::DFG::Worklist::runThread):
+        (JSC::DFG::initializeGlobalWorklistOnce):
+        * dfg/DFGWorklist.h:
+        * runtime/Options.cpp:
+        (JSC::computeNumberOfWorkerThreads):
+        (JSC):
+        (JSC::computeNumberOfGCMarkers):
+        * runtime/Options.h:
+        (JSC):
+
+2013-05-22  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
</ins><span class="cx">         fourthTier: FTL shouldn't use the LLVM global context, and should instead create its own context for each compilation
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=116631
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Watchpoint.h (153174 => 153175)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Watchpoint.h        2013-07-25 04:00:48 UTC (rev 153174)
+++ trunk/Source/JavaScriptCore/bytecode/Watchpoint.h        2013-07-25 04:00:50 UTC (rev 153175)
</span><span class="lines">@@ -26,8 +26,8 @@
</span><span class="cx"> #ifndef Watchpoint_h
</span><span class="cx"> #define Watchpoint_h
</span><span class="cx"> 
</span><del>-#include &lt;wtf/RefCounted.h&gt;
</del><span class="cx"> #include &lt;wtf/SentinelLinkedList.h&gt;
</span><ins>+#include &lt;wtf/ThreadSafeRefCounted.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx"> 
</span><span class="cx"> class InlineWatchpointSet;
</span><span class="cx"> 
</span><del>-class WatchpointSet : public RefCounted&lt;WatchpointSet&gt; {
</del><ins>+class WatchpointSet : public ThreadSafeRefCounted&lt;WatchpointSet&gt; {
</ins><span class="cx"> public:
</span><span class="cx">     WatchpointSet(InitialWatchpointSetMode);
</span><span class="cx">     ~WatchpointSet();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCommonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCommon.h (153174 => 153175)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCommon.h        2013-07-25 04:00:48 UTC (rev 153174)
+++ trunk/Source/JavaScriptCore/dfg/DFGCommon.h        2013-07-25 04:00:50 UTC (rev 153175)
</span><span class="lines">@@ -139,7 +139,7 @@
</span><span class="cx"> inline bool enableConcurrentJIT()
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(CONCURRENT_JIT)
</span><del>-    return Options::enableConcurrentJIT();
</del><ins>+    return Options::enableConcurrentJIT() &amp;&amp; Options::numberOfCompilerThreads();
</ins><span class="cx"> #else
</span><span class="cx">     return false;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWorklistcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp (153174 => 153175)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2013-07-25 04:00:48 UTC (rev 153174)
+++ trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2013-07-25 04:00:50 UTC (rev 153175)
</span><span class="lines">@@ -35,24 +35,34 @@
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><span class="cx"> Worklist::Worklist()
</span><ins>+    : m_numberOfActiveThreads(0)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Worklist::~Worklist()
</span><span class="cx"> {
</span><del>-    m_queue.append(nullptr); // Use null plan to indicate that we want the thread to terminate.
-    waitForThreadCompletion(m_thread);
</del><ins>+    {
+        MutexLocker locker(m_lock);
+        for (unsigned i = m_threads.size(); i--;)
+            m_queue.append(nullptr); // Use null plan to indicate that we want the thread to terminate.
+        m_planEnqueued.broadcast();
+    }
+    for (unsigned i = m_threads.size(); i--;)
+        waitForThreadCompletion(m_threads[i]);
+    ASSERT(!m_numberOfActiveThreads);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Worklist::finishCreation()
</del><ins>+void Worklist::finishCreation(unsigned numberOfThreads)
</ins><span class="cx"> {
</span><del>-    m_thread = createThread(threadFunction, this, &quot;JSC Compilation Thread&quot;);
</del><ins>+    RELEASE_ASSERT(numberOfThreads);
+    for (unsigned i = numberOfThreads; i--;)
+        m_threads.append(createThread(threadFunction, this, &quot;JSC Compilation Thread&quot;));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;Worklist&gt; Worklist::create()
</del><ins>+PassRefPtr&lt;Worklist&gt; Worklist::create(unsigned numberOfThreads)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;Worklist&gt; result = adoptRef(new Worklist());
</span><del>-    result-&gt;finishCreation();
</del><ins>+    result-&gt;finishCreation(numberOfThreads);
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -67,7 +77,7 @@
</span><span class="cx">     ASSERT(m_plans.find(plan-&gt;key()) == m_plans.end());
</span><span class="cx">     m_plans.add(plan-&gt;key(), plan);
</span><span class="cx">     m_queue.append(plan);
</span><del>-    m_condition.broadcast();
</del><ins>+    m_planEnqueued.signal();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Worklist::State Worklist::compilationState(CodeBlock* profiledBlock)
</span><span class="lines">@@ -110,7 +120,7 @@
</span><span class="cx">         if (allAreCompiled)
</span><span class="cx">             break;
</span><span class="cx">         
</span><del>-        m_condition.wait(m_lock);
</del><ins>+        m_planCompiled.wait(m_lock);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -195,11 +205,15 @@
</span><span class="cx"> {
</span><span class="cx">     out.print(
</span><span class="cx">         &quot;Worklist(&quot;, RawPointer(this), &quot;)[Queue Length = &quot;, m_queue.size(),
</span><del>-        &quot;, Map Size = &quot;, m_plans.size(), &quot;]&quot;);
</del><ins>+        &quot;, Map Size = &quot;, m_plans.size(), &quot;, Num Ready = &quot;, m_readyPlans.size(),
+        &quot;, Num Active Threads = &quot;, m_numberOfActiveThreads, &quot;/&quot;, m_threads.size(), &quot;]&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Worklist::runThread()
</span><span class="cx"> {
</span><ins>+    if (Options::verboseCompilationQueue())
+        dataLog(*this, &quot;: Thread started\n&quot;);
+    
</ins><span class="cx">     LongLivedState longLivedState;
</span><span class="cx">     
</span><span class="cx">     for (;;) {
</span><span class="lines">@@ -207,13 +221,21 @@
</span><span class="cx">         {
</span><span class="cx">             MutexLocker locker(m_lock);
</span><span class="cx">             while (m_queue.isEmpty())
</span><del>-                m_condition.wait(m_lock);
</del><ins>+                m_planEnqueued.wait(m_lock);
</ins><span class="cx">             plan = m_queue.takeFirst();
</span><ins>+            if (plan)
+                m_numberOfActiveThreads++;
</ins><span class="cx">         }
</span><span class="cx">         
</span><del>-        if (!plan)
</del><ins>+        if (!plan) {
+            if (Options::verboseCompilationQueue())
+                dataLog(*this, &quot;: Thread shutting down\n&quot;);
</ins><span class="cx">             return;
</span><ins>+        }
</ins><span class="cx">         
</span><ins>+        if (Options::verboseCompilationQueue())
+            dataLog(*this, &quot;: Compiling &quot;, *plan-&gt;key(), &quot; asynchronously\n&quot;);
+        
</ins><span class="cx">         plan-&gt;compileInThread(longLivedState);
</span><span class="cx">         
</span><span class="cx">         {
</span><span class="lines">@@ -228,7 +250,8 @@
</span><span class="cx">             
</span><span class="cx">             m_readyPlans.append(plan);
</span><span class="cx">             
</span><del>-            m_condition.broadcast();
</del><ins>+            m_planCompiled.broadcast();
+            m_numberOfActiveThreads--;
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -243,7 +266,14 @@
</span><span class="cx"> 
</span><span class="cx"> static void initializeGlobalWorklistOnce()
</span><span class="cx"> {
</span><del>-    theGlobalWorklist = Worklist::create().leakRef();
</del><ins>+    unsigned numberOfThreads;
+    
+    if (Options::useExperimentalFTL())
+        numberOfThreads = 1; // We don't yet use LLVM in a thread-safe way.
+    else
+        numberOfThreads = Options::numberOfCompilerThreads();
+    
+    theGlobalWorklist = Worklist::create(numberOfThreads).leakRef();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Worklist* globalWorklist()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWorklisth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWorklist.h (153174 => 153175)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWorklist.h        2013-07-25 04:00:48 UTC (rev 153174)
+++ trunk/Source/JavaScriptCore/dfg/DFGWorklist.h        2013-07-25 04:00:50 UTC (rev 153175)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx"> 
</span><span class="cx">     ~Worklist();
</span><span class="cx">     
</span><del>-    static PassRefPtr&lt;Worklist&gt; create();
</del><ins>+    static PassRefPtr&lt;Worklist&gt; create(unsigned numberOfThreads);
</ins><span class="cx">     
</span><span class="cx">     void enqueue(PassRefPtr&lt;Plan&gt;);
</span><span class="cx">     
</span><span class="lines">@@ -65,7 +65,7 @@
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     Worklist();
</span><del>-    void finishCreation();
</del><ins>+    void finishCreation(unsigned numberOfThreads);
</ins><span class="cx">     
</span><span class="cx">     void runThread();
</span><span class="cx">     static void threadFunction(void* argument);
</span><span class="lines">@@ -89,11 +89,10 @@
</span><span class="cx">     Vector&lt;RefPtr&lt;Plan&gt;, 16&gt; m_readyPlans;
</span><span class="cx">     
</span><span class="cx">     mutable Mutex m_lock;
</span><del>-    // We broadcast on this condition whenever:
-    // - Something is enqueued.
-    // - Something is completed.
-    ThreadCondition m_condition;
-    ThreadIdentifier m_thread;
</del><ins>+    ThreadCondition m_planEnqueued;
+    ThreadCondition m_planCompiled;
+    Vector&lt;ThreadIdentifier&gt; m_threads;
+    unsigned m_numberOfActiveThreads;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> // For now we use a single global worklist. It's not clear that this
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.cpp (153174 => 153175)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.cpp        2013-07-25 04:00:48 UTC (rev 153174)
+++ trunk/Source/JavaScriptCore/runtime/Options.cpp        2013-07-25 04:00:50 UTC (rev 153175)
</span><span class="lines">@@ -91,22 +91,26 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static unsigned computeNumberOfGCMarkers(int maxNumberOfGCMarkers)
</del><ins>+static unsigned computeNumberOfWorkerThreads(int maxNumberOfWorkerThreads)
</ins><span class="cx"> {
</span><del>-    int cpusToUse = 1;
</del><ins>+    int cpusToUse = std::min(WTF::numberOfProcessorCores(), maxNumberOfWorkerThreads);
</ins><span class="cx"> 
</span><del>-#if ENABLE(PARALLEL_GC)
-    cpusToUse = std::min(WTF::numberOfProcessorCores(), maxNumberOfGCMarkers);
-
</del><span class="cx">     // Be paranoid, it is the OS we're dealing with, after all.
</span><span class="cx">     ASSERT(cpusToUse &gt;= 1);
</span><span class="cx">     if (cpusToUse &lt; 1)
</span><span class="cx">         cpusToUse = 1;
</span><ins>+    
+    return cpusToUse;
+}
+
+static unsigned computeNumberOfGCMarkers(unsigned maxNumberOfGCMarkers)
+{
+#if ENABLE(PARALLEL_GC)
+    return computeNumberOfWorkerThreads(maxNumberOfGCMarkers);
</ins><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(maxNumberOfGCMarkers);
</span><ins>+    return 1;
</ins><span class="cx"> #endif
</span><del>-
-    return cpusToUse;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool OptionRange::init(const char* rangeString)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (153174 => 153175)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2013-07-25 04:00:48 UTC (rev 153174)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2013-07-25 04:00:50 UTC (rev 153175)
</span><span class="lines">@@ -121,6 +121,7 @@
</span><span class="cx">     v(unsigned, llvmOptimizationLevel, 2) \
</span><span class="cx">     \
</span><span class="cx">     v(bool, enableConcurrentJIT, true) \
</span><ins>+    v(unsigned, numberOfCompilerThreads, computeNumberOfWorkerThreads(2) - 1) \
</ins><span class="cx">     \
</span><span class="cx">     v(bool, enableProfiler, false) \
</span><span class="cx">     \
</span></span></pre>
</div>
</div>

</body>
</html>