<!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>[248824] 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/248824">248824</a></dd>
<dt>Author</dt> <dd>ysuzuki@apple.com</dd>
<dt>Date</dt> <dd>2019-08-17 18:47:58 -0700 (Sat, 17 Aug 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>[JSC] WebAssembly BBQ should switch compile mode for size of modules
https://bugs.webkit.org/show_bug.cgi?id=200807

Reviewed by Mark Lam.

Some webpages use very large Wasm module, and it exhausts all executable memory in ARM64 devices since the size of executable memory region is 128MB.
The long term solution should be introducing Wasm interpreter. But as a short term solution, we introduce heuristics switching back to BBQ B3 at
the sacrifice of start-up time, since BBQ Air bloats such lengthy code, and thereby consumes a large amount of executable memory.

Currently, I picked 10MB since the reported website is using 11MB wasm module.

* runtime/Options.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::parseAndCompileAir):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::parseAndCompile):
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::compileFunctions):
* wasm/WasmModuleInformation.h:
* wasm/WasmSectionParser.cpp:
(JSC::Wasm::SectionParser::parseCode):
* wasm/WasmStreamingParser.cpp:
(JSC::Wasm::StreamingParser::parseCodeSectionSize):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmAirIRGeneratorcpp">trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmB3IRGeneratorcpp">trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmBBQPlancpp">trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmModuleInformationh">trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmSectionParsercpp">trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmStreamingParsercpp">trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (248823 => 248824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2019-08-17 19:13:59 UTC (rev 248823)
+++ trunk/Source/JavaScriptCore/ChangeLog       2019-08-18 01:47:58 UTC (rev 248824)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2019-08-17  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] WebAssembly BBQ should switch compile mode for size of modules
+        https://bugs.webkit.org/show_bug.cgi?id=200807
+
+        Reviewed by Mark Lam.
+
+        Some webpages use very large Wasm module, and it exhausts all executable memory in ARM64 devices since the size of executable memory region is 128MB.
+        The long term solution should be introducing Wasm interpreter. But as a short term solution, we introduce heuristics switching back to BBQ B3 at
+        the sacrifice of start-up time, since BBQ Air bloats such lengthy code, and thereby consumes a large amount of executable memory.
+
+        Currently, I picked 10MB since the reported website is using 11MB wasm module.
+
+        * runtime/Options.h:
+        * wasm/WasmAirIRGenerator.cpp:
+        (JSC::Wasm::parseAndCompileAir):
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::parseAndCompile):
+        * wasm/WasmBBQPlan.cpp:
+        (JSC::Wasm::BBQPlan::compileFunctions):
+        * wasm/WasmModuleInformation.h:
+        * wasm/WasmSectionParser.cpp:
+        (JSC::Wasm::SectionParser::parseCode):
+        * wasm/WasmStreamingParser.cpp:
+        (JSC::Wasm::StreamingParser::parseCodeSectionSize):
+
</ins><span class="cx"> 2019-08-16  Mark Lam  <mark.lam@apple.com>
</span><span class="cx"> 
</span><span class="cx">         More missing exception checks in string comparison operators.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (248823 => 248824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h    2019-08-17 19:13:59 UTC (rev 248823)
+++ trunk/Source/JavaScriptCore/runtime/Options.h       2019-08-18 01:47:58 UTC (rev 248824)
</span><span class="lines">@@ -476,7 +476,8 @@
</span><span class="cx">     \
</span><span class="cx">     v(bool, failToCompileWebAssemblyCode, false, Normal, "If true, no Wasm::Plan will sucessfully compile a function.") \
</span><span class="cx">     v(size, webAssemblyPartialCompileLimit, 5000, Normal, "Limit on the number of bytes a Wasm::Plan::compile should attempt before checking for other work.") \
</span><del>-    v(unsigned, webAssemblyBBQOptimizationLevel, 0, Normal, "B3 Optimization level for BBQ Web Assembly module compilations.") \
</del><ins>+    v(unsigned, webAssemblyBBQAirOptimizationLevel, 0, Normal, "Air Optimization level for BBQ Web Assembly module compilations.") \
+    v(unsigned, webAssemblyBBQB3OptimizationLevel, 1, Normal, "B3 Optimization level for BBQ Web Assembly module compilations.") \
</ins><span class="cx">     v(unsigned, webAssemblyOMGOptimizationLevel, Options::defaultB3OptLevel(), Normal, "B3 Optimization level for OMG Web Assembly module compilations.") \
</span><span class="cx">     \
</span><span class="cx">     v(bool, useBBQTierUpChecks, true, Normal, "Enables tier up checks for our BBQ code.") \
</span><span class="lines">@@ -491,6 +492,7 @@
</span><span class="cx">     v(unsigned, maxNumWebAssemblyFastMemories, 4, Normal, nullptr) \
</span><span class="cx">     v(bool, useFastTLSForWasmContext, true, Normal, "If true, we will store context in fast TLS. If false, we will pin it to a register.") \
</span><span class="cx">     v(bool, wasmBBQUsesAir, true, Normal, nullptr) \
</span><ins>+    v(size, webAssemblyBBQAirModeThreshold, isIOS() ? (10 * MB) : 0, Normal, "If 0, we always use BBQ Air. If Wasm module code size hits this threshold, we compile Wasm module with B3 BBQ mode.") \
</ins><span class="cx">     v(bool, useWebAssemblyStreamingApi, enableWebAssemblyStreamingApi, Normal, "Allow to run WebAssembly's Streaming API") \
</span><span class="cx">     v(bool, useCallICsForWebAssemblyToJSCalls, true, Normal, "If true, we will use CallLinkInfo to inline cache Wasm to JS calls.") \
</span><span class="cx">     v(bool, useEagerWebAssemblyModuleHashing, false, Normal, "Unnamed WebAssembly modules are identified in backtraces through their hash, if available.") \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmAirIRGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp (248823 => 248824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp  2019-08-17 19:13:59 UTC (rev 248823)
+++ trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp     2019-08-18 01:47:58 UTC (rev 248824)
</span><span class="lines">@@ -2158,7 +2158,7 @@
</span><span class="cx">     // optLevel=1.
</span><span class="cx">     procedure.setNeedsUsedRegisters(false);
</span><span class="cx">     
</span><del>-    procedure.setOptLevel(Options::webAssemblyBBQOptimizationLevel());
</del><ins>+    procedure.setOptLevel(Options::webAssemblyBBQAirOptimizationLevel());
</ins><span class="cx"> 
</span><span class="cx">     AirIRGenerator irGenerator(info, procedure, result.get(), unlinkedWasmToWasmCalls, mode, functionIndex, tierUp, throwWasmException, signature);
</span><span class="cx">     FunctionParser<AirIRGenerator> parser(irGenerator, functionStart, functionLength, signature, info);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmB3IRGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp (248823 => 248824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp   2019-08-17 19:13:59 UTC (rev 248823)
+++ trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp      2019-08-18 01:47:58 UTC (rev 248824)
</span><span class="lines">@@ -1570,7 +1570,7 @@
</span><span class="cx">     procedure.setNeedsUsedRegisters(false);
</span><span class="cx">     
</span><span class="cx">     procedure.setOptLevel(compilationMode == CompilationMode::BBQMode
</span><del>-        ? Options::webAssemblyBBQOptimizationLevel()
</del><ins>+        ? Options::webAssemblyBBQB3OptimizationLevel()
</ins><span class="cx">         : Options::webAssemblyOMGOptimizationLevel());
</span><span class="cx"> 
</span><span class="cx">     B3IRGenerator irGenerator(info, procedure, result.get(), unlinkedWasmToWasmCalls, mode, compilationMode, functionIndex, tierUp, throwWasmException);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmBBQPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp (248823 => 248824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp 2019-08-17 19:13:59 UTC (rev 248823)
+++ trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp    2019-08-18 01:47:58 UTC (rev 248824)
</span><span class="lines">@@ -269,7 +269,15 @@
</span><span class="cx">         m_unlinkedWasmToWasmCalls[functionIndex] = Vector<UnlinkedWasmToWasmCall>();
</span><span class="cx">         TierUpCount* tierUp = Options::useBBQTierUpChecks() ? &m_tierUpCounts[functionIndex] : nullptr;
</span><span class="cx">         Expected<std::unique_ptr<InternalFunction>, String> parseAndCompileResult;
</span><del>-        if (Options::wasmBBQUsesAir())
</del><ins>+
+        // FIXME: Some webpages use very large Wasm module, and it exhausts all executable memory in ARM64 devices since the size of executable memory region is only limited to 128MB.
+        // The long term solution should be to introduce a Wasm interpreter. But as a short term solution, we introduce heuristics to switch back to BBQ B3 at the sacrifice of start-up time,
+        // as BBQ Air bloats such lengthy Wasm code and will consume a large amount of executable memory.
+        bool forceUsingB3 = false;
+        if (Options::webAssemblyBBQAirModeThreshold() && m_moduleInformation->codeSectionSize >= Options::webAssemblyBBQAirModeThreshold())
+            forceUsingB3 = true;
+
+        if (!forceUsingB3 && Options::wasmBBQUsesAir())
</ins><span class="cx">             parseAndCompileResult = parseAndCompileAir(m_compilationContexts[functionIndex], function.data.data(), function.data.size(), signature, m_unlinkedWasmToWasmCalls[functionIndex], m_moduleInformation.get(), m_mode, functionIndex, tierUp, m_throwWasmException);
</span><span class="cx">         else
</span><span class="cx">             parseAndCompileResult = parseAndCompile(m_compilationContexts[functionIndex], function.data.data(), function.data.size(), signature, m_unlinkedWasmToWasmCalls[functionIndex], m_moduleInformation.get(), m_mode, CompilationMode::BBQMode, functionIndex, tierUp, m_throwWasmException);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmModuleInformationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.h (248823 => 248824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.h 2019-08-17 19:13:59 UTC (rev 248823)
+++ trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.h    2019-08-18 01:47:58 UTC (rev 248824)
</span><span class="lines">@@ -86,6 +86,7 @@
</span><span class="cx">     Vector<TableInformation> tables;
</span><span class="cx">     Vector<Global> globals;
</span><span class="cx">     unsigned firstInternalGlobal { 0 };
</span><ins>+    uint32_t codeSectionSize { 0 };
</ins><span class="cx">     Vector<CustomSection> customSections;
</span><span class="cx">     Ref<NameSection> nameSection;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmSectionParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp (248823 => 248824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp   2019-08-17 19:13:59 UTC (rev 248823)
+++ trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp      2019-08-18 01:47:58 UTC (rev 248824)
</span><span class="lines">@@ -414,6 +414,7 @@
</span><span class="cx"> // This function will be changed to be RELEASE_ASSERT_NOT_REACHED once we switch our parsing infrastructure to the streaming parser.
</span><span class="cx"> auto SectionParser::parseCode() -> PartialResult
</span><span class="cx"> {
</span><ins>+    m_info->codeSectionSize = length();
</ins><span class="cx">     uint32_t count;
</span><span class="cx">     WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Code section's count");
</span><span class="cx">     WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Code section's count is too big ", count);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmStreamingParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp (248823 => 248824)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp 2019-08-17 19:13:59 UTC (rev 248823)
+++ trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp    2019-08-18 01:47:58 UTC (rev 248824)
</span><span class="lines">@@ -110,6 +110,7 @@
</span><span class="cx"> 
</span><span class="cx"> auto StreamingParser::parseCodeSectionSize(uint32_t functionCount) -> State
</span><span class="cx"> {
</span><ins>+    m_info->codeSectionSize = m_sectionLength;
</ins><span class="cx">     m_functionCount = functionCount;
</span><span class="cx">     m_functionIndex = 0;
</span><span class="cx">     m_codeOffset = m_offset;
</span></span></pre>
</div>
</div>

</body>
</html>