[JSC] WebAssembly BBQ should switch compile mode for size of modules
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 18 Aug 2019 01:47:58 +0000 (01:47 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 18 Aug 2019 01:47:58 +0000 (01:47 +0000)
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):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248824 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/Options.h
Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
Source/JavaScriptCore/wasm/WasmBBQPlan.cpp
Source/JavaScriptCore/wasm/WasmModuleInformation.h
Source/JavaScriptCore/wasm/WasmSectionParser.cpp
Source/JavaScriptCore/wasm/WasmStreamingParser.cpp

index 3e342b6..1c11e37 100644 (file)
@@ -1,3 +1,29 @@
+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):
+
 2019-08-16  Mark Lam  <mark.lam@apple.com>
 
         More missing exception checks in string comparison operators.
index b476737..e30d2d2 100644 (file)
@@ -476,7 +476,8 @@ constexpr bool enableWebAssemblyStreamingApi = false;
     \
     v(bool, failToCompileWebAssemblyCode, false, Normal, "If true, no Wasm::Plan will sucessfully compile a function.") \
     v(size, webAssemblyPartialCompileLimit, 5000, Normal, "Limit on the number of bytes a Wasm::Plan::compile should attempt before checking for other work.") \
-    v(unsigned, webAssemblyBBQOptimizationLevel, 0, Normal, "B3 Optimization level for BBQ Web Assembly module compilations.") \
+    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.") \
     v(unsigned, webAssemblyOMGOptimizationLevel, Options::defaultB3OptLevel(), Normal, "B3 Optimization level for OMG Web Assembly module compilations.") \
     \
     v(bool, useBBQTierUpChecks, true, Normal, "Enables tier up checks for our BBQ code.") \
@@ -491,6 +492,7 @@ constexpr bool enableWebAssemblyStreamingApi = false;
     v(unsigned, maxNumWebAssemblyFastMemories, 4, Normal, nullptr) \
     v(bool, useFastTLSForWasmContext, true, Normal, "If true, we will store context in fast TLS. If false, we will pin it to a register.") \
     v(bool, wasmBBQUsesAir, true, Normal, nullptr) \
+    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.") \
     v(bool, useWebAssemblyStreamingApi, enableWebAssemblyStreamingApi, Normal, "Allow to run WebAssembly's Streaming API") \
     v(bool, useCallICsForWebAssemblyToJSCalls, true, Normal, "If true, we will use CallLinkInfo to inline cache Wasm to JS calls.") \
     v(bool, useEagerWebAssemblyModuleHashing, false, Normal, "Unnamed WebAssembly modules are identified in backtraces through their hash, if available.") \
index 24f18ad..e7cdf86 100644 (file)
@@ -2158,7 +2158,7 @@ Expected<std::unique_ptr<InternalFunction>, String> parseAndCompileAir(Compilati
     // optLevel=1.
     procedure.setNeedsUsedRegisters(false);
     
-    procedure.setOptLevel(Options::webAssemblyBBQOptimizationLevel());
+    procedure.setOptLevel(Options::webAssemblyBBQAirOptimizationLevel());
 
     AirIRGenerator irGenerator(info, procedure, result.get(), unlinkedWasmToWasmCalls, mode, functionIndex, tierUp, throwWasmException, signature);
     FunctionParser<AirIRGenerator> parser(irGenerator, functionStart, functionLength, signature, info);
index 2094177..92d9f48 100644 (file)
@@ -1570,7 +1570,7 @@ Expected<std::unique_ptr<InternalFunction>, String> parseAndCompile(CompilationC
     procedure.setNeedsUsedRegisters(false);
     
     procedure.setOptLevel(compilationMode == CompilationMode::BBQMode
-        ? Options::webAssemblyBBQOptimizationLevel()
+        ? Options::webAssemblyBBQB3OptimizationLevel()
         : Options::webAssemblyOMGOptimizationLevel());
 
     B3IRGenerator irGenerator(info, procedure, result.get(), unlinkedWasmToWasmCalls, mode, compilationMode, functionIndex, tierUp, throwWasmException);
index f985d52..540d2d9 100644 (file)
@@ -269,7 +269,15 @@ void BBQPlan::compileFunctions(CompilationEffort effort)
         m_unlinkedWasmToWasmCalls[functionIndex] = Vector<UnlinkedWasmToWasmCall>();
         TierUpCount* tierUp = Options::useBBQTierUpChecks() ? &m_tierUpCounts[functionIndex] : nullptr;
         Expected<std::unique_ptr<InternalFunction>, String> parseAndCompileResult;
-        if (Options::wasmBBQUsesAir())
+
+        // 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())
             parseAndCompileResult = parseAndCompileAir(m_compilationContexts[functionIndex], function.data.data(), function.data.size(), signature, m_unlinkedWasmToWasmCalls[functionIndex], m_moduleInformation.get(), m_mode, functionIndex, tierUp, m_throwWasmException);
         else
             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);
index 268f88b..ca72e48 100644 (file)
@@ -86,6 +86,7 @@ struct ModuleInformation : public ThreadSafeRefCounted<ModuleInformation> {
     Vector<TableInformation> tables;
     Vector<Global> globals;
     unsigned firstInternalGlobal { 0 };
+    uint32_t codeSectionSize { 0 };
     Vector<CustomSection> customSections;
     Ref<NameSection> nameSection;
     
index ba960b6..841c0ea 100644 (file)
@@ -414,6 +414,7 @@ auto SectionParser::parseElement() -> PartialResult
 // This function will be changed to be RELEASE_ASSERT_NOT_REACHED once we switch our parsing infrastructure to the streaming parser.
 auto SectionParser::parseCode() -> PartialResult
 {
+    m_info->codeSectionSize = length();
     uint32_t count;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Code section's count");
     WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Code section's count is too big ", count);
index f716e58..c546923 100644 (file)
@@ -110,6 +110,7 @@ auto StreamingParser::parseSectionSize(uint32_t sectionLength) -> State
 
 auto StreamingParser::parseCodeSectionSize(uint32_t functionCount) -> State
 {
+    m_info->codeSectionSize = m_sectionLength;
     m_functionCount = functionCount;
     m_functionIndex = 0;
     m_codeOffset = m_offset;