Diff
Modified: trunk/JSTests/ChangeLog (288757 => 288758)
--- trunk/JSTests/ChangeLog 2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/JSTests/ChangeLog 2022-01-28 20:48:11 UTC (rev 288758)
@@ -1,3 +1,17 @@
+2022-01-28 Tom Tartarin <[email protected]>
+
+ [JSC] Add support for WASM branch hinting proposal
+ https://bugs.webkit.org/show_bug.cgi?id=235581
+
+ Reviewed by Yusuke Suzuki.
+
+ Add test for branch hinting custom section
+
+ * wasm.yaml:
+ * wasm/branch-hints/branchHintsModule.wasm: Added.
+ * wasm/branch-hints/branchHintsSection.js: Added.
+ (const.module):
+
2022-01-24 Yusuke Suzuki <[email protected]>
[JSC] Enable Array#groupBy and Array#groupByToMap
Added: trunk/JSTests/wasm/branch-hints/branchHintsModule.wasm (0 => 288758)
--- trunk/JSTests/wasm/branch-hints/branchHintsModule.wasm (rev 0)
+++ trunk/JSTests/wasm/branch-hints/branchHintsModule.wasm 2022-01-28 20:48:11 UTC (rev 288758)
@@ -0,0 +1,4 @@
+��asm������+`����``����p\x80 A\x80\x80\xC0��memory��_main�� ��A������%code_annotation.branch_hint��%
+1����+A��"!@ AІF@A! Aj"A\xA0\x8DG+��
\ No newline at end of file
Added: trunk/JSTests/wasm/branch-hints/branchHintsSection.js (0 => 288758)
--- trunk/JSTests/wasm/branch-hints/branchHintsSection.js (rev 0)
+++ trunk/JSTests/wasm/branch-hints/branchHintsSection.js 2022-01-28 20:48:11 UTC (rev 288758)
@@ -0,0 +1,62 @@
+import * as assert from '../assert.js'
+
+/*
+This test loads a WebAssembly file compiled with wat2wasm with support for code annotations.
+see: https://github.com/yuri91/wabt/tree/annotations
+
+From the following .wat:
+(module
+ (type (;0;) (func))
+ (type (;1;) (func (param i32) (result i32)))
+ (type (;2;) (func (result i32)))
+ (func $__wasm_nullptr (type 0)
+ unreachable)
+ (func $main (type 2) (result i32)
+ (local i32 i32 i32 i32)
+ i32.const 0
+ local.tee 2
+ local.set 3
+ loop ;; label = @1
+ local.get 2
+ i32.const 50000
+ i32.eq
+ (@code_annotation.branch_hint "\00") if ;; label = @2
+ i32.const 1
+ local.set 3
+ end
+ local.get 2
+ i32.const 1
+ i32.add
+ local.tee 2
+ i32.const 100000
+ i32.ne
+ (@code_annotation.branch_hint "\01") br_if 0 (;@1;)
+ end
+ local.get 3)
+ (table (;0;) 1 1 funcref)
+ (memory (;0;) 17 128)
+ (global (;0;) (mut i32) (i32.const 1048576))
+ (export "memory" (memory 0))
+ (export "_main" (func $main))
+ (elem (;0;) (i32.const 0) func $__wasm_nullptr))
+*/
+
+const verbose = false;
+const wasmFile = 'branchHintsModule.wasm';
+
+const module = (location) => {
+ if (verbose)
+ print(`Processing ${location}`);
+ let buf = typeof readbuffer !== "undefined"? readbuffer(location) : read(location, 'binary');
+ if (verbose)
+ print(` Size: ${buf.byteLength}`);
+ let module = new WebAssembly.Module(buf);
+ return module;
+};
+
+const branchHintsModule = module(wasmFile);
+const parsedBranchHintsSection = WebAssembly.Module.customSections(branchHintsModule, "code_annotation.branch_hint");
+assert.eq(parsedBranchHintsSection.length, 1);
+const instance = new WebAssembly.Instance(branchHintsModule);
+const result = instance.exports._main();
+assert.eq(result, 1);
Modified: trunk/JSTests/wasm.yaml (288757 => 288758)
--- trunk/JSTests/wasm.yaml 2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/JSTests/wasm.yaml 2022-01-28 20:48:11 UTC (rev 288758)
@@ -47,6 +47,8 @@
cmd: runWebAssemblySuite unless parseRunCommands
- path: wasm/v8/
cmd: runWebAssemblySuite(:no_module, "mjsunit.js") unless parseRunCommands
+- path: wasm/branch-hints
+ cmd: runWebAssemblySuite("--useWebAssemblyBranchHints=true")
- path: wasm/references-spec-tests/elem.wast.js
cmd: runWebAssemblyReferenceSpecTest :normal
Modified: trunk/Source/_javascript_Core/ChangeLog (288757 => 288758)
--- trunk/Source/_javascript_Core/ChangeLog 2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/ChangeLog 2022-01-28 20:48:11 UTC (rev 288758)
@@ -1,3 +1,41 @@
+2022-01-28 Tom Tartarin <[email protected]>
+
+ [JSC] Add support for WASM branch hinting proposal
+ https://bugs.webkit.org/show_bug.cgi?id=235581
+
+ Reviewed by Yusuke Suzuki.
+
+ See the proposal for a more detailed description: https://github.com/WebAssembly/branch-hinting.
+
+ This allows parsing a "code_annotation.branch_hint" custom section,
+ as per the code annotation proposal: https://github.com/WebAssembly/annotations.
+ This section provides per function information about how likely a branch at a
+ given offset is to be taken. It is similar to branch weight metadata in LLVM.
+
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * Sources.txt:
+ * runtime/OptionsList.h:
+ * wasm/WasmAirIRGenerator.cpp:
+ (JSC::Wasm::AirIRGenerator::addIf):
+ (JSC::Wasm::AirIRGenerator::addBranch):
+ * wasm/WasmB3IRGenerator.cpp:
+ (JSC::Wasm::B3IRGenerator::addIf):
+ (JSC::Wasm::B3IRGenerator::addBranch):
+ * wasm/WasmBranchHints.h: Added.
+ (JSC::Wasm::BranchHintMap::add):
+ (JSC::Wasm::BranchHintMap::getBranchHint const):
+ (JSC::Wasm::BranchHintMap::isValidKey const):
+ (JSC::Wasm::isValidBranchHint):
+ * wasm/WasmBranchHintsSectionParser.cpp: Added.
+ (JSC::Wasm::BranchHintsSectionParser::parse):
+ * wasm/WasmBranchHintsSectionParser.h: Added.
+ (JSC::Wasm::BranchHintsSectionParser::BranchHintsSectionParser):
+ * wasm/WasmModuleInformation.h:
+ (JSC::Wasm::ModuleInformation::getBranchHint const):
+ * wasm/WasmSectionParser.cpp:
+ (JSC::Wasm::SectionParser::parseCustom):
+
2022-01-28 Yusuke Suzuki <[email protected]>
[JSC] YarrJIT optimization for character BM search
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (288757 => 288758)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2022-01-28 20:48:11 UTC (rev 288758)
@@ -856,6 +856,8 @@
33A920BD23DA2C6D000EBAF0 /* CommonSlowPathsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 33A920BC23DA2C6D000EBAF0 /* CommonSlowPathsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
33B2A54722653481005A0F79 /* B3ValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FB1BDACDAC0080FF74 /* B3ValueInlines.h */; };
33B2A548226543BF005A0F79 /* FTLLowerDFGToB3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A04170513DB00BB722C /* FTLLowerDFGToB3.cpp */; };
+ 37AAC093279F1BFC00D64842 /* WasmBranchHintsSectionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 37AAC092279F124200D64842 /* WasmBranchHintsSectionParser.h */; };
+ 37AAC094279F1C0500D64842 /* WasmBranchHints.h in Headers */ = {isa = PBXBuildFile; fileRef = 37AAC091279F124200D64842 /* WasmBranchHints.h */; };
37C738D21EDB56E4003F2B0B /* ParseInt.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C738D11EDB5672003F2B0B /* ParseInt.h */; settings = {ATTRIBUTES = (Private, ); }; };
412952771D2CF6BC00E78B89 /* builtins_generate_internals_wrapper_header.py in Headers */ = {isa = PBXBuildFile; fileRef = 412952731D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
412952781D2CF6BC00E78B89 /* builtins_generate_internals_wrapper_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = 412952741D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3726,6 +3728,9 @@
33B2A54522651D53005A0F79 /* MarkedSpace.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedSpace.cpp; sourceTree = "<group>"; };
37119A7720CCB5DC002C6DC9 /* WebKitTargetConditionals.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = WebKitTargetConditionals.xcconfig; sourceTree = "<group>"; };
371D842C17C98B6E00ECF994 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
+ 37AAC090279F124100D64842 /* WasmBranchHintsSectionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmBranchHintsSectionParser.cpp; sourceTree = "<group>"; };
+ 37AAC091279F124200D64842 /* WasmBranchHints.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = WasmBranchHints.h; sourceTree = "<group>"; };
+ 37AAC092279F124200D64842 /* WasmBranchHintsSectionParser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = WasmBranchHintsSectionParser.h; sourceTree = "<group>"; };
37C738D11EDB5672003F2B0B /* ParseInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseInt.h; sourceTree = "<group>"; };
412952731D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = builtins_generate_internals_wrapper_header.py; sourceTree = "<group>"; };
412952741D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = builtins_generate_internals_wrapper_implementation.py; sourceTree = "<group>"; };
@@ -7309,6 +7314,9 @@
7B98D1331B60CD1E0023B1A4 /* wasm */ = {
isa = PBXGroup;
children = (
+ 37AAC091279F124200D64842 /* WasmBranchHints.h */,
+ 37AAC090279F124100D64842 /* WasmBranchHintsSectionParser.cpp */,
+ 37AAC092279F124200D64842 /* WasmBranchHintsSectionParser.h */,
AD2FCB8A1DB5840000B3E736 /* js */,
52847AD921FFB8630061A9DB /* WasmAirIRGenerator.cpp */,
52847ADA21FFB8630061A9DB /* WasmAirIRGenerator.h */,
@@ -10956,6 +10964,7 @@
0FE050291AA9095600D33B33 /* ScopedArgumentsTable.h in Headers */,
0FE0502B1AA9095600D33B33 /* ScopeOffset.h in Headers */,
0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */,
+ 37AAC094279F1C0500D64842 /* WasmBranchHints.h in Headers */,
33111B8B2397256500AA34CE /* Scribble.h in Headers */,
A5FD0068189AFE9C00633231 /* ScriptArguments.h in Headers */,
A5FD006E189B00AA00633231 /* ScriptCallFrame.h in Headers */,
@@ -11082,6 +11091,7 @@
FE3422121D6B81C30032BE88 /* ThrowScope.h in Headers */,
0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */,
A7386556118697B400540279 /* ThunkGenerators.h in Headers */,
+ 37AAC093279F1BFC00D64842 /* WasmBranchHintsSectionParser.h in Headers */,
141448CD13A1783700F5BA1A /* TinyBloomFilter.h in Headers */,
0F55989817C86C5800A1E543 /* ToNativeFromValue.h in Headers */,
0F2D4DE919832DAC007D4B19 /* ToThisStatus.h in Headers */,
Modified: trunk/Source/_javascript_Core/Sources.txt (288757 => 288758)
--- trunk/Source/_javascript_Core/Sources.txt 2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/Sources.txt 2022-01-28 20:48:11 UTC (rev 288758)
@@ -1065,6 +1065,7 @@
wasm/WasmB3IRGenerator.cpp
wasm/WasmBBQPlan.cpp
wasm/WasmBinding.cpp
+wasm/WasmBranchHintsSectionParser.cpp
wasm/WasmCallee.cpp
wasm/WasmCalleeGroup.cpp
wasm/WasmCalleeRegistry.cpp
Modified: trunk/Source/_javascript_Core/runtime/OptionsList.h (288757 => 288758)
--- trunk/Source/_javascript_Core/runtime/OptionsList.h 2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/runtime/OptionsList.h 2022-01-28 20:48:11 UTC (rev 288758)
@@ -550,6 +550,7 @@
v(Bool, useWebAssemblyThreading, true, Normal, "Allow instructions from the wasm threading spec.") \
v(Bool, useWebAssemblyTypedFunctionReferences, false, Normal, "Allow function types from the wasm typed function references spec.") \
v(Bool, useWebAssemblyExceptions, true, Normal, "Allow the new section and instructions from the wasm exception handling spec.") \
+ v(Bool, useWebAssemblyBranchHints, false, Normal, "Allow the new section from the wasm branch hinting spec.") \
enum OptionEquivalence {
Modified: trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp (288757 => 288758)
--- trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp 2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp 2022-01-28 20:48:11 UTC (rev 288758)
@@ -44,6 +44,7 @@
#include "JSCJSValueInlines.h"
#include "JSWebAssemblyInstance.h"
#include "ScratchRegisterAllocator.h"
+#include "WasmBranchHints.h"
#include "WasmCallingConvention.h"
#include "WasmContextInlines.h"
#include "WasmExceptionType.h"
@@ -3174,10 +3175,27 @@
BasicBlock* taken = m_code.addBlock();
BasicBlock* notTaken = m_code.addBlock();
BasicBlock* continuation = m_code.addBlock();
-
+ B3::FrequencyClass takenFrequency = B3::FrequencyClass::Normal;
+ B3::FrequencyClass notTakenFrequency= B3::FrequencyClass::Normal;
+
+ if (Options::useWebAssemblyBranchHints()) {
+ BranchHint hint = m_info.getBranchHint(m_functionIndex, m_parser->currentOpcodeStartingOffset());
+
+ switch (hint) {
+ case BranchHint::Unlikely:
+ takenFrequency = B3::FrequencyClass::Rare;
+ break;
+ case BranchHint::Likely:
+ notTakenFrequency = B3::FrequencyClass::Rare;
+ break;
+ case BranchHint::Invalid:
+ break;
+ }
+ }
+
// Wasm bools are i32.
append(BranchTest32, Arg::resCond(MacroAssembler::NonZero), condition, condition);
- m_currentBlock->setSuccessors(taken, notTaken);
+ m_currentBlock->setSuccessors(FrequentedBlock(taken, takenFrequency), FrequentedBlock(notTaken, notTakenFrequency));
m_currentBlock = taken;
splitStack(signature, enclosingStack, newStack);
@@ -3417,14 +3435,32 @@
unifyValuesWithBlock(returnValues, data.results);
BasicBlock* target = data.targetBlockForBranch();
+ B3::FrequencyClass targetFrequency = B3::FrequencyClass::Normal;
+ B3::FrequencyClass continuationFrequency = B3::FrequencyClass::Normal;
+
+ if (Options::useWebAssemblyBranchHints()) {
+ BranchHint hint = m_info.getBranchHint(m_functionIndex, m_parser->currentOpcodeStartingOffset());
+
+ switch (hint) {
+ case BranchHint::Unlikely:
+ targetFrequency = B3::FrequencyClass::Rare;
+ break;
+ case BranchHint::Likely:
+ continuationFrequency = B3::FrequencyClass::Rare;
+ break;
+ case BranchHint::Invalid:
+ break;
+ }
+ }
+
if (condition) {
BasicBlock* continuation = m_code.addBlock();
append(BranchTest32, Arg::resCond(MacroAssembler::NonZero), condition, condition);
- m_currentBlock->setSuccessors(target, continuation);
+ m_currentBlock->setSuccessors(FrequentedBlock(target, targetFrequency), FrequentedBlock(continuation, continuationFrequency));
m_currentBlock = continuation;
} else {
append(Jump);
- m_currentBlock->setSuccessors(target);
+ m_currentBlock->setSuccessors(FrequentedBlock(target, targetFrequency));
}
return { };
Modified: trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (288757 => 288758)
--- trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp 2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp 2022-01-28 20:48:11 UTC (rev 288758)
@@ -52,7 +52,7 @@
#include "JSWebAssemblyInstance.h"
#include "ProbeContext.h"
#include "ScratchRegisterAllocator.h"
-#include "ScratchRegisterAllocator.h"
+#include "WasmBranchHints.h"
#include "WasmCallingConvention.h"
#include "WasmContextInlines.h"
#include "WasmExceptionType.h"
@@ -2475,9 +2475,26 @@
BasicBlock* taken = m_proc.addBlock();
BasicBlock* notTaken = m_proc.addBlock();
BasicBlock* continuation = m_proc.addBlock();
+ FrequencyClass takenFrequency = FrequencyClass::Normal;
+ FrequencyClass notTakenFrequency = FrequencyClass::Normal;
+ if (Options::useWebAssemblyBranchHints()) {
+ BranchHint hint = m_info.getBranchHint(m_functionIndex, m_parser->currentOpcodeStartingOffset());
+
+ switch (hint) {
+ case BranchHint::Unlikely:
+ takenFrequency = FrequencyClass::Rare;
+ break;
+ case BranchHint::Likely:
+ notTakenFrequency = FrequencyClass::Rare;
+ break;
+ case BranchHint::Invalid:
+ break;
+ }
+ }
+
m_currentBlock->appendNew<Value>(m_proc, B3::Branch, origin(), get(condition));
- m_currentBlock->setSuccessors(FrequentedBlock(taken), FrequentedBlock(notTaken));
+ m_currentBlock->setSuccessors(FrequentedBlock(taken, takenFrequency), FrequentedBlock(notTaken, notTakenFrequency));
taken->addPredecessor(m_currentBlock);
notTaken->addPredecessor(m_currentBlock);
@@ -2721,15 +2738,33 @@
unifyValuesWithBlock(returnValues, data);
BasicBlock* target = data.targetBlockForBranch();
+ FrequencyClass targetFrequency = FrequencyClass::Normal;
+ FrequencyClass continuationFrequency = FrequencyClass::Normal;
+
+ if (Options::useWebAssemblyBranchHints()) {
+ BranchHint hint = m_info.getBranchHint(m_functionIndex, m_parser->currentOpcodeStartingOffset());
+
+ switch (hint) {
+ case BranchHint::Unlikely:
+ targetFrequency = FrequencyClass::Rare;
+ break;
+ case BranchHint::Likely:
+ continuationFrequency = FrequencyClass::Rare;
+ break;
+ case BranchHint::Invalid:
+ break;
+ }
+ }
+
if (condition) {
BasicBlock* continuation = m_proc.addBlock();
m_currentBlock->appendNew<Value>(m_proc, B3::Branch, origin(), get(condition));
- m_currentBlock->setSuccessors(FrequentedBlock(target), FrequentedBlock(continuation));
+ m_currentBlock->setSuccessors(FrequentedBlock(target, targetFrequency), FrequentedBlock(continuation, continuationFrequency));
target->addPredecessor(m_currentBlock);
continuation->addPredecessor(m_currentBlock);
m_currentBlock = continuation;
} else {
- m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), FrequentedBlock(target));
+ m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), FrequentedBlock(target, targetFrequency));
target->addPredecessor(m_currentBlock);
}
Added: trunk/Source/_javascript_Core/wasm/WasmBranchHints.h (0 => 288758)
--- trunk/Source/_javascript_Core/wasm/WasmBranchHints.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WasmBranchHints.h 2022-01-28 20:48:11 UTC (rev 288758)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 Leaning Technologies Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/HashMap.h>
+
+namespace JSC {
+namespace Wasm {
+
+enum class BranchHint : uint8_t {
+ Unlikely,
+ Likely,
+ Invalid,
+};
+
+class BranchHintMap {
+
+public:
+
+ void add(uint32_t branchOffset, BranchHint hint)
+ {
+ m_map.add(branchOffset, hint);
+ }
+
+ BranchHint getBranchHint(uint32_t branchOffset) const
+ {
+ auto it = m_map.find(branchOffset);
+ if (it == m_map.end())
+ return BranchHint::Invalid;
+ return it->value;
+ }
+
+ bool isValidKey(uint32_t branchOffset) const
+ {
+ return m_map.isValidKey(branchOffset);
+ }
+
+private:
+
+ HashMap<uint32_t, BranchHint, IntHash<uint32_t>, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>> m_map;
+
+};
+
+inline constexpr bool isValidBranchHint(BranchHint hint)
+{
+ switch (hint) {
+ case BranchHint::Likely:
+ case BranchHint::Unlikely:
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
+}
+} // namespace JSC::Wasm
Added: trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.cpp (0 => 288758)
--- trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.cpp (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.cpp 2022-01-28 20:48:11 UTC (rev 288758)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2022 Leaning Technologies Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "config.h"
+#include "WasmBranchHintsSectionParser.h"
+
+namespace JSC {
+namespace Wasm {
+
+auto BranchHintsSectionParser::parse() -> PartialResult
+{
+ uint32_t functionCount;
+ int64_t previousFunctionIndex = -1;
+ WASM_PARSER_FAIL_IF(!parseVarUInt32(functionCount), "can't get function count");
+
+ for (uint32_t i = 0; i < functionCount; ++i) {
+ uint32_t functionIndex;
+ uint32_t hintCount;
+ WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get function index for function ", i);
+ WASM_PARSER_FAIL_IF(static_cast<int64_t>(functionIndex) < previousFunctionIndex, "invalid function index ", functionIndex, " for function ", i);
+
+ previousFunctionIndex = functionIndex;
+
+ WASM_PARSER_FAIL_IF(!parseVarUInt32(hintCount), "can't get number of hints for function ", i);
+
+ if (!hintCount)
+ continue;
+
+ int64_t previousBranchOffset = -1;
+ BranchHintMap branchHintsForFunction;
+ for (uint32_t j = 0; j < hintCount; ++j) {
+ uint32_t branchOffset;
+ WASM_PARSER_FAIL_IF(!parseVarUInt32(branchOffset), "can't get branch offset for hint ", j);
+ WASM_PARSER_FAIL_IF(static_cast<int64_t>(branchOffset) < previousBranchOffset
+ || !m_info->branchHints.isValidKey(branchOffset), "invalid branch offset ", branchOffset, " for hint ", j);
+
+ previousBranchOffset = branchOffset;
+
+ uint8_t reservedByte;
+ WASM_PARSER_FAIL_IF(!parseVarUInt1(reservedByte), "can't get reserved byte for hint ", j);
+ WASM_PARSER_FAIL_IF(reservedByte != 0x1, "invalid reserved byte for hint ", j);
+
+ uint8_t parsedBranchHint;
+ WASM_PARSER_FAIL_IF(!parseVarUInt1(parsedBranchHint), "can't get or invalid branch hint value for hint ", j);
+
+ BranchHint branchHint = static_cast<BranchHint>(parsedBranchHint);
+ ASSERT(isValidBranchHint(branchHint));
+
+ branchHintsForFunction.add(branchOffset, branchHint);
+ }
+ m_info->branchHints.add(functionIndex, WTFMove(branchHintsForFunction));
+ }
+ return { };
+}
+
+}
+} // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
Added: trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.h (0 => 288758)
--- trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.h 2022-01-28 20:48:11 UTC (rev 288758)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 Leaning Technologies Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmParser.h"
+
+namespace JSC {
+namespace Wasm {
+
+class BranchHintsSectionParser : public Parser<void> {
+public:
+ BranchHintsSectionParser(const uint8_t* sourceBuffer, size_t sourceLength, ModuleInformation& info)
+ : Parser(sourceBuffer, sourceLength)
+ , m_info(info)
+ {
+ }
+ PartialResult parse();
+
+private:
+ Ref<ModuleInformation> m_info;
+};
+
+}
+} // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
Modified: trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h (288757 => 288758)
--- trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h 2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h 2022-01-28 20:48:11 UTC (rev 288758)
@@ -27,13 +27,18 @@
#if ENABLE(WEBASSEMBLY)
+#include "WasmBranchHints.h"
#include "WasmFormat.h"
#include <wtf/BitVector.h>
+#include <wtf/HashMap.h>
namespace JSC { namespace Wasm {
struct ModuleInformation : public ThreadSafeRefCounted<ModuleInformation> {
+
+ using BranchHints = HashMap<uint32_t, BranchHintMap, IntHash<uint32_t>, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>>;
+
ModuleInformation();
ModuleInformation(const ModuleInformation&) = delete;
ModuleInformation(ModuleInformation&&) = delete;
@@ -96,6 +101,14 @@
bool hasMemoryImport() const { return memory.isImport(); }
+ BranchHint getBranchHint(uint32_t functionOffset, uint32_t branchOffset) const
+ {
+ auto it = branchHints.find(functionOffset);
+ return it == branchHints.end()
+ ? BranchHint::Invalid
+ : it->value.getBranchHint(branchOffset);
+ }
+
Vector<Import> imports;
Vector<SignatureIndex> importFunctionSignatureIndices;
Vector<SignatureIndex> internalFunctionSignatureIndices;
@@ -117,6 +130,7 @@
uint32_t codeSectionSize { 0 };
Vector<CustomSection> customSections;
Ref<NameSection> nameSection;
+ BranchHints branchHints;
uint32_t numberOfDataSegments { 0 };
BitVector m_declaredFunctions;
Modified: trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp (288757 => 288758)
--- trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp 2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp 2022-01-28 20:48:11 UTC (rev 288758)
@@ -30,6 +30,7 @@
#if ENABLE(WEBASSEMBLY)
#include "JSCJSValueInlines.h"
+#include "WasmBranchHintsSectionParser.h"
#include "WasmMemoryInformation.h"
#include "WasmNameSectionParser.h"
#include "WasmOps.h"
@@ -896,6 +897,12 @@
NameSectionParser nameSectionParser(section.payload.begin(), section.payload.size(), m_info);
if (auto nameSection = nameSectionParser.parse())
m_info->nameSection = WTFMove(*nameSection);
+ } else if (Options::useWebAssemblyBranchHints()) {
+ Name branchHintsName = { 'c', 'o', 'd', 'e', '_', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '.', 'b', 'r', 'a', 'n', 'c', 'h', '_', 'h', 'i', 'n', 't' };
+ if (section.name == branchHintsName) {
+ BranchHintsSectionParser branchHintsSectionParser(section.payload.begin(), section.payload.size(), m_info);
+ branchHintsSectionParser.parse();
+ }
}
m_info->customSections.uncheckedAppend(WTFMove(section));