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

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

<h3>Log Message</h3>
<pre>Fixed VM pool allocation should have a reserve for allocations that cannot fail
https://bugs.webkit.org/show_bug.cgi?id=147154
rdar://problem/21847618

Reviewed by Geoffrey Garen.
        
Source/JavaScriptCore:

This adds the notion of a JIT pool reserve fraction. Some fraction, currently 1/4, of
the JIT pool is reserved for allocations that cannot fail. It makes sense to make this
a fraction rather than a constant because each allocation that can fail may cause some
number of allocations that cannot fail (for example, the OSR exit thunks that we
compile when we exit from some CodeBlock cannot fail).
        
I've tested this by adding a test mode where we artificially limit the JIT pool size.
Prior to the fix, we had &gt;20 failures. Now we have none.

* heap/GCLogging.cpp:
(WTF::printInternal): I needed a dump method on Options members when debugging this.
* heap/GCLogging.h:
* jit/ExecutableAllocator.h: Raise the ARM64 limit to 32MB because 16MB is cutting it too close.
* jit/ExecutableAllocatorFixedVMPool.cpp:
(JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator): Add the ability to artificially limit JIT pool size for testing.
(JSC::ExecutableAllocator::memoryPressureMultiplier): Implement the reserve when computing memory pressure for JIT tier-up heuristics.
(JSC::ExecutableAllocator::allocate): Implement the reserve when allocating can-fail things.
* jsc.cpp: Rewire some options parsing so that CommandLine happens before we create the JIT pool.
(main):
(CommandLine::parseArguments):
(jscmain):
* runtime/Options.cpp: 
(JSC::OptionRange::dump): I needed a dump method on Options members when debugging this.
(JSC::Options::initialize): This can now be called more than once.
* runtime/Options.h:

Tools:

Add a new test mode where we artificially limit JIT memory to 50KB. If our JIT OOM
mitigations work, these should all pass. Prior to this patch there were &gt;20 failures.

* Scripts/run-jsc-stress-tests:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapGCLoggingcpp">trunk/Source/JavaScriptCore/heap/GCLogging.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapGCLoggingh">trunk/Source/JavaScriptCore/heap/GCLogging.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitExecutableAllocatorh">trunk/Source/JavaScriptCore/jit/ExecutableAllocator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitExecutableAllocatorFixedVMPoolcpp">trunk/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</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>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptsrunjscstresstests">trunk/Tools/Scripts/run-jsc-stress-tests</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (187124 => 187125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-07-21 21:39:58 UTC (rev 187124)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-07-21 21:41:30 UTC (rev 187125)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2015-07-21  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Fixed VM pool allocation should have a reserve for allocations that cannot fail
+        https://bugs.webkit.org/show_bug.cgi?id=147154
+        rdar://problem/21847618
+
+        Reviewed by Geoffrey Garen.
+        
+        This adds the notion of a JIT pool reserve fraction. Some fraction, currently 1/4, of
+        the JIT pool is reserved for allocations that cannot fail. It makes sense to make this
+        a fraction rather than a constant because each allocation that can fail may cause some
+        number of allocations that cannot fail (for example, the OSR exit thunks that we
+        compile when we exit from some CodeBlock cannot fail).
+        
+        I've tested this by adding a test mode where we artificially limit the JIT pool size.
+        Prior to the fix, we had &gt;20 failures. Now we have none.
+
+        * heap/GCLogging.cpp:
+        (WTF::printInternal): I needed a dump method on Options members when debugging this.
+        * heap/GCLogging.h:
+        * jit/ExecutableAllocator.h: Raise the ARM64 limit to 32MB because 16MB is cutting it too close.
+        * jit/ExecutableAllocatorFixedVMPool.cpp:
+        (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator): Add the ability to artificially limit JIT pool size for testing.
+        (JSC::ExecutableAllocator::memoryPressureMultiplier): Implement the reserve when computing memory pressure for JIT tier-up heuristics.
+        (JSC::ExecutableAllocator::allocate): Implement the reserve when allocating can-fail things.
+        * jsc.cpp: Rewire some options parsing so that CommandLine happens before we create the JIT pool.
+        (main):
+        (CommandLine::parseArguments):
+        (jscmain):
+        * runtime/Options.cpp: 
+        (JSC::OptionRange::dump): I needed a dump method on Options members when debugging this.
+        (JSC::Options::initialize): This can now be called more than once.
+        * runtime/Options.h:
+
</ins><span class="cx"> 2015-07-21  Saam barati  &lt;saambarati1@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         ObjectPatternNode's entry should use &quot;const Identifier&amp;&quot; instead of &quot;Identifier&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapGCLoggingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/GCLogging.cpp (187124 => 187125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/GCLogging.cpp        2015-07-21 21:39:58 UTC (rev 187124)
+++ trunk/Source/JavaScriptCore/heap/GCLogging.cpp        2015-07-21 21:41:30 UTC (rev 187125)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;HeapIterationScope.h&quot;
</span><span class="cx"> #include &quot;JSCell.h&quot;
</span><span class="cx"> #include &quot;JSCellInlines.h&quot;
</span><ins>+#include &lt;wtf/PrintStream.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -113,3 +114,26 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span><ins>+
+namespace WTF {
+
+void printInternal(PrintStream&amp; out, JSC::GCLogging::Level level)
+{
+    switch (level) {
+    case JSC::GCLogging::Level::None:
+        out.print(&quot;None&quot;);
+        return;
+    case JSC::GCLogging::Level::Basic:
+        out.print(&quot;Basic&quot;);
+        return;
+    case JSC::GCLogging::Level::Verbose:
+        out.print(&quot;Verbose&quot;);
+        return;
+    default:
+        out.print(&quot;Level=&quot;, level - JSC::GCLogging::Level::None);
+        return;
+    }
+}
+
+} // namespace WTF
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapGCLoggingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/GCLogging.h (187124 => 187125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/GCLogging.h        2015-07-21 21:39:58 UTC (rev 187124)
+++ trunk/Source/JavaScriptCore/heap/GCLogging.h        2015-07-21 21:41:30 UTC (rev 187125)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -48,4 +48,12 @@
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><ins>+namespace WTF {
+
+class PrintStream;
+
+void printInternal(PrintStream&amp;, JSC::GCLogging::Level);
+
+} // namespace WTF
+
</ins><span class="cx"> #endif // GCLogging_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitExecutableAllocatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ExecutableAllocator.h (187124 => 187125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ExecutableAllocator.h        2015-07-21 21:39:58 UTC (rev 187124)
+++ trunk/Source/JavaScriptCore/jit/ExecutableAllocator.h        2015-07-21 21:41:30 UTC (rev 187125)
</span><span class="lines">@@ -80,13 +80,16 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
</span><del>-#if CPU(ARM) || CPU(ARM64)
</del><ins>+#if CPU(ARM)
</ins><span class="cx"> static const size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024;
</span><ins>+#elif CPU(ARM64)
+static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024;
</ins><span class="cx"> #elif CPU(X86_64)
</span><span class="cx"> static const size_t fixedExecutableMemoryPoolSize = 1024 * 1024 * 1024;
</span><span class="cx"> #else
</span><span class="cx"> static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024;
</span><span class="cx"> #endif
</span><ins>+static const double executablePoolReservationFraction = 0.25;
</ins><span class="cx"> 
</span><span class="cx"> extern uintptr_t startOfFixedExecutableMemoryPool;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitExecutableAllocatorFixedVMPoolcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp (187124 => 187125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp        2015-07-21 21:39:58 UTC (rev 187124)
+++ trunk/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp        2015-07-21 21:41:30 UTC (rev 187125)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -60,9 +60,14 @@
</span><span class="cx">     FixedVMPoolExecutableAllocator()
</span><span class="cx">         : MetaAllocator(jitAllocationGranule) // round up all allocations to 32 bytes
</span><span class="cx">     {
</span><del>-        m_reservation = PageReservation::reserveWithGuardPages(fixedExecutableMemoryPoolSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
</del><ins>+        size_t reservationSize;
+        if (Options::jitMemoryReservationSize())
+            reservationSize = Options::jitMemoryReservationSize();
+        else
+            reservationSize = fixedExecutableMemoryPoolSize;
+        m_reservation = PageReservation::reserveWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
</ins><span class="cx">         if (m_reservation) {
</span><del>-            ASSERT(m_reservation.size() == fixedExecutableMemoryPoolSize);
</del><ins>+            ASSERT(m_reservation.size() == reservationSize);
</ins><span class="cx">             addFreshFreeSpace(m_reservation.base(), m_reservation.size());
</span><span class="cx">             
</span><span class="cx">             startOfFixedExecutableMemoryPool = reinterpret_cast&lt;uintptr_t&gt;(m_reservation.base());
</span><span class="lines">@@ -148,12 +153,14 @@
</span><span class="cx">     MetaAllocator::Statistics statistics = allocator-&gt;currentStatistics();
</span><span class="cx">     ASSERT(statistics.bytesAllocated &lt;= statistics.bytesReserved);
</span><span class="cx">     size_t bytesAllocated = statistics.bytesAllocated + addedMemoryUsage;
</span><del>-    if (bytesAllocated &gt;= statistics.bytesReserved)
-        bytesAllocated = statistics.bytesReserved;
</del><ins>+    size_t bytesAvailable = static_cast&lt;size_t&gt;(
+        statistics.bytesReserved * (1 - executablePoolReservationFraction));
+    if (bytesAllocated &gt;= bytesAvailable)
+        bytesAllocated = bytesAvailable;
</ins><span class="cx">     double result = 1.0;
</span><del>-    size_t divisor = statistics.bytesReserved - bytesAllocated;
</del><ins>+    size_t divisor = bytesAvailable - bytesAllocated;
</ins><span class="cx">     if (divisor)
</span><del>-        result = static_cast&lt;double&gt;(statistics.bytesReserved) / divisor;
</del><ins>+        result = static_cast&lt;double&gt;(bytesAvailable) / divisor;
</ins><span class="cx">     if (result &lt; 1.0)
</span><span class="cx">         result = 1.0;
</span><span class="cx">     return result;
</span><span class="lines">@@ -170,6 +177,16 @@
</span><span class="cx">         &amp;&amp; doExecutableAllocationFuzzingIfEnabled() == PretendToFailExecutableAllocation)
</span><span class="cx">         return nullptr;
</span><span class="cx">     
</span><ins>+    if (effort == JITCompilationCanFail) {
+        // Don't allow allocations if we are down to reserve.
+        MetaAllocator::Statistics statistics = allocator-&gt;currentStatistics();
+        size_t bytesAllocated = statistics.bytesAllocated + sizeInBytes;
+        size_t bytesAvailable = static_cast&lt;size_t&gt;(
+            statistics.bytesReserved * (1 - executablePoolReservationFraction));
+        if (bytesAllocated &gt; bytesAvailable)
+            return nullptr;
+    }
+    
</ins><span class="cx">     RefPtr&lt;ExecutableMemoryHandle&gt; result = allocator-&gt;allocate(sizeInBytes, ownerUID);
</span><span class="cx">     if (!result) {
</span><span class="cx">         if (effort != JITCompilationCanFail) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (187124 => 187125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2015-07-21 21:39:58 UTC (rev 187124)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2015-07-21 21:41:30 UTC (rev 187125)
</span><span class="lines">@@ -1248,12 +1248,6 @@
</span><span class="cx">     ecore_init();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    // Initialize JSC before getting VM.
-#if ENABLE(SAMPLING_REGIONS)
-    WTF::initializeMainThread();
-#endif
-    JSC::initializeThreading();
-
</del><span class="cx">     if (char* timeoutString = getenv(&quot;JSC_timeout&quot;)) {
</span><span class="cx">         if (sscanf(timeoutString, &quot;%lf&quot;, &amp;s_desiredTimeout) != 1) {
</span><span class="cx">             dataLog(
</span><span class="lines">@@ -1430,6 +1424,8 @@
</span><span class="cx"> 
</span><span class="cx"> void CommandLine::parseArguments(int argc, char** argv)
</span><span class="cx"> {
</span><ins>+    Options::initialize();
+    
</ins><span class="cx">     int i = 1;
</span><span class="cx">     bool needToDumpOptions = false;
</span><span class="cx">     bool needToExit = false;
</span><span class="lines">@@ -1494,8 +1490,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // See if the -- option is a JSC VM option.
</span><del>-        // NOTE: At this point, we know that the arg starts with &quot;--&quot;. Skip it.
-        if (JSC::Options::setOption(&amp;arg[2])) {
</del><ins>+        if (strstr(arg, &quot;--&quot;) == arg &amp;&amp; JSC::Options::setOption(&amp;arg[2])) {
</ins><span class="cx">             // The arg was recognized as a VM option and has been parsed.
</span><span class="cx">             continue; // Just continue with the next arg. 
</span><span class="cx">         }
</span><span class="lines">@@ -1523,6 +1518,13 @@
</span><span class="cx">     // Note that the options parsing can affect VM creation, and thus
</span><span class="cx">     // comes first.
</span><span class="cx">     CommandLine options(argc, argv);
</span><ins>+
+    // Initialize JSC before getting VM.
+#if ENABLE(SAMPLING_REGIONS)
+    WTF::initializeMainThread();
+#endif
+    JSC::initializeThreading();
+
</ins><span class="cx">     VM* vm = &amp;VM::create(LargeHeap).leakRef();
</span><span class="cx">     int result;
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.cpp (187124 => 187125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.cpp        2015-07-21 21:39:58 UTC (rev 187124)
+++ trunk/Source/JavaScriptCore/runtime/Options.cpp        2015-07-21 21:41:30 UTC (rev 187125)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &lt;algorithm&gt;
</span><span class="cx"> #include &lt;limits&gt;
</span><span class="cx"> #include &lt;math.h&gt;
</span><ins>+#include &lt;mutex&gt;
</ins><span class="cx"> #include &lt;stdlib.h&gt;
</span><span class="cx"> #include &lt;string.h&gt;
</span><span class="cx"> #include &lt;wtf/DataLog.h&gt;
</span><span class="lines">@@ -201,6 +202,11 @@
</span><span class="cx">     return m_state == Normal ? false : true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void OptionRange::dump(PrintStream&amp; out) const
+{
+    out.print(m_rangeString);
+}
+
</ins><span class="cx"> Options::Entry Options::s_options[Options::numberOfOptions];
</span><span class="cx"> Options::Entry Options::s_defaultOptions[Options::numberOfOptions];
</span><span class="cx"> 
</span><span class="lines">@@ -318,60 +324,66 @@
</span><span class="cx"> 
</span><span class="cx"> void Options::initialize()
</span><span class="cx"> {
</span><del>-    // Initialize each of the options with their default values:
-#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
-    name_() = defaultValue_; \
-    name_##Default() = defaultValue_;
-    JSC_OPTIONS(FOR_EACH_OPTION)
</del><ins>+    static std::once_flag initializeOptionsOnceFlag;
+    
+    std::call_once(
+        initializeOptionsOnceFlag,
+        [] {
+            // Initialize each of the options with their default values:
+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_)      \
+            name_() = defaultValue_;                                    \
+            name_##Default() = defaultValue_;
+            JSC_OPTIONS(FOR_EACH_OPTION)
</ins><span class="cx"> #undef FOR_EACH_OPTION
</span><span class="cx">     
</span><del>-    // It *probably* makes sense for other platforms to enable this.
</del><ins>+                // It *probably* makes sense for other platforms to enable this.
</ins><span class="cx"> #if PLATFORM(IOS) &amp;&amp; CPU(ARM64)
</span><del>-    enableLLVMFastISel() = true;
</del><ins>+                enableLLVMFastISel() = true;
</ins><span class="cx"> #endif
</span><span class="cx">         
</span><del>-    // Allow environment vars to override options if applicable.
-    // The evn var should be the name of the option prefixed with
-    // &quot;JSC_&quot;.
-#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_) \
-    overrideOptionWithHeuristic(name_(), &quot;JSC_&quot; #name_);
-    JSC_OPTIONS(FOR_EACH_OPTION)
</del><ins>+            // Allow environment vars to override options if applicable.
+            // The evn var should be the name of the option prefixed with
+            // &quot;JSC_&quot;.
+#define FOR_EACH_OPTION(type_, name_, defaultValue_, description_)      \
+            overrideOptionWithHeuristic(name_(), &quot;JSC_&quot; #name_);
+            JSC_OPTIONS(FOR_EACH_OPTION)
</ins><span class="cx"> #undef FOR_EACH_OPTION
</span><span class="cx"> 
</span><span class="cx"> #if 0
</span><del>-    ; // Deconfuse editors that do auto indentation
</del><ins>+                ; // Deconfuse editors that do auto indentation
</ins><span class="cx"> #endif
</span><span class="cx">     
</span><del>-    recomputeDependentOptions();
</del><ins>+            recomputeDependentOptions();
</ins><span class="cx"> 
</span><del>-    // Do range checks where needed and make corrections to the options:
-    ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() &gt;= Options::thresholdForOptimizeAfterWarmUp());
-    ASSERT(Options::thresholdForOptimizeAfterWarmUp() &gt;= Options::thresholdForOptimizeSoon());
-    ASSERT(Options::thresholdForOptimizeAfterWarmUp() &gt;= 0);
</del><ins>+            // Do range checks where needed and make corrections to the options:
+            ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() &gt;= Options::thresholdForOptimizeAfterWarmUp());
+            ASSERT(Options::thresholdForOptimizeAfterWarmUp() &gt;= Options::thresholdForOptimizeSoon());
+            ASSERT(Options::thresholdForOptimizeAfterWarmUp() &gt;= 0);
</ins><span class="cx"> 
</span><del>-    if (Options::showOptions()) {
-        DumpLevel level = static_cast&lt;DumpLevel&gt;(Options::showOptions());
-        if (level &gt; DumpLevel::Verbose)
-            level = DumpLevel::Verbose;
</del><ins>+            if (Options::showOptions()) {
+                DumpLevel level = static_cast&lt;DumpLevel&gt;(Options::showOptions());
+                if (level &gt; DumpLevel::Verbose)
+                    level = DumpLevel::Verbose;
</ins><span class="cx"> 
</span><del>-        const char* title = nullptr;
-        switch (level) {
-        case DumpLevel::None:
-            break;
-        case DumpLevel::Overridden:
-            title = &quot;Overridden JSC options:&quot;;
-            break;
-        case DumpLevel::All:
-            title = &quot;All JSC options:&quot;;
-            break;
-        case DumpLevel::Verbose:
-            title = &quot;All JSC options with descriptions:&quot;;
-            break;
-        }
-        dumpAllOptions(level, title);
-    }
</del><ins>+                const char* title = nullptr;
+                switch (level) {
+                case DumpLevel::None:
+                    break;
+                case DumpLevel::Overridden:
+                    title = &quot;Overridden JSC options:&quot;;
+                    break;
+                case DumpLevel::All:
+                    title = &quot;All JSC options:&quot;;
+                    break;
+                case DumpLevel::Verbose:
+                    title = &quot;All JSC options with descriptions:&quot;;
+                    break;
+                }
+                dumpAllOptions(level, title);
+            }
</ins><span class="cx"> 
</span><del>-    ensureOptionsAreCoherent();
</del><ins>+            ensureOptionsAreCoherent();
+        });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Parses a single command line option in the format &quot;&lt;optionName&gt;=&lt;value&gt;&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (187124 => 187125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2015-07-21 21:39:58 UTC (rev 187124)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2015-07-21 21:41:30 UTC (rev 187125)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;JSExportMacros.h&quot;
</span><span class="cx"> #include &lt;stdint.h&gt;
</span><span class="cx"> #include &lt;stdio.h&gt;
</span><ins>+#include &lt;wtf/PrintStream.h&gt;
</ins><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -80,6 +81,8 @@
</span><span class="cx">     bool init(const char*);
</span><span class="cx">     bool isInRange(unsigned);
</span><span class="cx">     const char* rangeString() const { return (m_state &gt; InitError) ? m_rangeString : &quot;&lt;null&gt;&quot;; }
</span><ins>+    
+    void dump(PrintStream&amp; out) const;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     RangeState m_state;
</span><span class="lines">@@ -106,6 +109,7 @@
</span><span class="cx">     v(unsigned, errorModeReservedZoneSize, 64 * KB, nullptr) \
</span><span class="cx">     \
</span><span class="cx">     v(bool, crashIfCantAllocateJITMemory, false, nullptr) \
</span><ins>+    v(unsigned, jitMemoryReservationSize, 0, nullptr) \
</ins><span class="cx">     \
</span><span class="cx">     v(bool, forceDFGCodeBlockLiveness, false, nullptr) \
</span><span class="cx">     v(bool, forceICFailure, false, nullptr) \
</span><span class="lines">@@ -350,7 +354,7 @@
</span><span class="cx">         gcLogLevelType,
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    static void initialize();
</del><ins>+    JS_EXPORT_PRIVATE static void initialize();
</ins><span class="cx"> 
</span><span class="cx">     // Parses a single command line option in the format &quot;&lt;optionName&gt;=&lt;value&gt;&quot;
</span><span class="cx">     // (no spaces allowed) and set the specified option if appropriate.
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (187124 => 187125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-07-21 21:39:58 UTC (rev 187124)
+++ trunk/Tools/ChangeLog        2015-07-21 21:41:30 UTC (rev 187125)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2015-07-21  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Fixed VM pool allocation should have a reserve for allocations that cannot fail
+        https://bugs.webkit.org/show_bug.cgi?id=147154
+        rdar://problem/21847618
+
+        Reviewed by Geoffrey Garen.
+        
+        Add a new test mode where we artificially limit JIT memory to 50KB. If our JIT OOM
+        mitigations work, these should all pass. Prior to this patch there were &gt;20 failures.
+
+        * Scripts/run-jsc-stress-tests:
+
</ins><span class="cx"> 2015-07-20  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Add API to be notified about editor state changes
</span></span></pre></div>
<a id="trunkToolsScriptsrunjscstresstests"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/run-jsc-stress-tests (187124 => 187125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-jsc-stress-tests        2015-07-21 21:39:58 UTC (rev 187124)
+++ trunk/Tools/Scripts/run-jsc-stress-tests        2015-07-21 21:41:30 UTC (rev 187125)
</span><span class="lines">@@ -758,6 +758,10 @@
</span><span class="cx">     run(&quot;ftl-no-cjit-no-access-inlining&quot;, &quot;--enableAccessInlining=false&quot;, *(FTL_OPTIONS + NO_CJIT_OPTIONS)) if $enableFTL
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+def runFTLNoCJITSmallPool
+    run(&quot;ftl-no-cjit-small-pool&quot;, &quot;--jitMemoryReservationSize=50000&quot;, *(FTL_OPTIONS + NO_CJIT_OPTIONS)) if $enableFTL
+end
+
</ins><span class="cx"> def defaultRun
</span><span class="cx">     runDefault
</span><span class="cx">     runAlwaysTriggerCopyPhase
</span><span class="lines">@@ -771,6 +775,7 @@
</span><span class="cx">         runFTLNoCJITNoInlineValidate
</span><span class="cx">         runFTLEager
</span><span class="cx">         runFTLEagerNoCJITValidate
</span><ins>+        runFTLNoCJITSmallPool
</ins><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>