10BC0 Add WASM opcode counter · WebKit/WebKit@70ccbd9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 70ccbd9

Browse files
committed
Add WASM opcode counter
https://bugs.webkit.org/show_bug.cgi?id=250213 rdar://103956646 Reviewed by Justin Michaud. This patch includes three things: a) Added `atob` and `btoa` to jsc shell as helpers for loading tfjs pre-trained models. b) Skipped JetStream3 tests UniPoker and bigint-paillier, since UniPoker fails on browser with error messages and bigint-paillier hangs with `deterministicRandom` is true. c) Added a WASM opcode counter. Use `dumpWasmOpcodeStatistics=1` to enable opcode collection. And use `notifyutil -v -p com.apple.WebKit.wasm.op.stat` to dump statistics sorted by counts in descending order for all WASM opcodes. An example of dumped statistics: <WASM.OP.STAT><92428> Registering callback for wasm opcode statistics. <WASM.OP.STAT><92428> Use `notifyutil -v -p com.apple.WebKit.wasm.op.stat` to dump statistics. <WASM.EXT.SIMD.OP.STAT><92428> wasm extended SIMD opcode use coverage 32.63%. <WASM.EXT.SIMD.OP.STAT><92428> V128Load: 4588 <WASM.EXT.SIMD.OP.STAT><92428> F32x4Add: 2522 ... <WASM.EXT.ATOMIC.OP.STAT><92428> wasm extended atomic opcode use coverage 0.00%. <WASM.EXT.ATOMIC.OP.STAT><92428> MemoryAtomicNotify: 0 <WASM.EXT.ATOMIC.OP.STAT><92428> MemoryAtomicWait32: 0 ... <WASM.GC.OP.STAT><92428> wasm GC opcode use coverage 0.00%. <WASM.GC.OP.STAT><92428> StructNewCanon: 0 <WASM.GC.OP.STAT><92428> StructGet: 0 ... <WASM.BASE.OP.STAT><92428> wasm base opcode use coverage 74.49%. <WASM.BASE.OP.STAT><92428> GetLocal: 80967 <WASM.BASE.OP.STAT><92428> I32Const: 28805 ... * JSTests/stress/atob-btoa.js: Added. (assert): (shouldThrow): * Source/JavaScriptCore/Sources.txt: * Source/JavaScriptCore/jsc.cpp: (JSC_DEFINE_HOST_FUNCTION): * Source/JavaScriptCore/runtime/OptionsList.h: * Source/JavaScriptCore/wasm/WasmFunctionParser.h: (JSC::Wasm::FunctionParser<Context>::parseBody): (JSC::Wasm::FunctionParser<Context>::parseExpression): (JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression): * Source/JavaScriptCore/wasm/WasmOpcodeCounter.cpp: Added. (JSC::Wasm::WasmOpcodeCounter::singleton): (JSC::Wasm::WasmOpcodeCounter::dump): (JSC::Wasm::WasmOpcodeCounter::registerDispatch): (JSC::Wasm::WasmOpcodeCounter::increment): * Source/JavaScriptCore/wasm/WasmOpcodeCounter.h: Added. * Source/JavaScriptCore/wasm/WasmTypeDefinition.h: (JSC::Wasm::countNumberOfWasmExtendedSIMDOpcodes): (JSC::Wasm::isRegisteredWasmExtendedSIMDOpcode): (JSC::Wasm::dumpExtSIMDOpType): (JSC::Wasm::countNumberOfWasmExtendedAtomicOpcodes): (JSC::Wasm::isRegisteredExtenedAtomicOpcode): (JSC::Wasm::dumpExtAtomicOpType): (JSC::Wasm::countNumberOfWasmGCOpcodes): (JSC::Wasm::isRegisteredGCOpcode): (JSC::Wasm::dumpGCOpType): (JSC::Wasm::countNumberOfWasmBaseOpcodes): (JSC::Wasm::isRegisteredBaseOpcode): (JSC::Wasm::dumpOpType): Canonical link: https://commits.webkit.org/258678@main
1 parent ae00dca commit 70ccbd9

File tree

8 files changed

+469
-2
lines changed

8 files changed

+469
-2
lines changed

JSTests/stress/atob-btoa.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
function assert(b) {
2+
if (!b)
3+
throw new Error("Bad assertion");
4+
}
5+
6+
function shouldThrow(func, errorMessage) {
7+
var errorThrown = false;
8+
var error = null;
9+
try {
10+
func();
11+
} catch (e) {
12+
errorThrown = true;
13+
error = e;
14+
}
15+
if (!errorThrown)
16+
throw new Error('not thrown');
17+
if (String(error) !== errorMessage)
18+
throw new Error(`bad error: ${String(error)}`);
19+
}
20+
21+
let strs = [
22+
"",
23+
"3OBQwMDuz29xSLpfDZ3BZpoSmOp5uqpC1AvdUeO4Mj",
24+
"U5qFQTeWHPtyLAfFpf0DzgNiCXr17LsZxEHRlRoE3S",
25+
"97tJorct1Pc1IhFuMNCb2XWQ01cVbZF6dQCzcH3QRn",
26+
"zIom9GE2x1xr6VS6kM8iRoco34an8FVfZ6EvT2kd5EHZ2YxkL91hLhjsmRRsmT6GiOdkSFhOdGJF4GEC42gUosLLNxBmspVl",
27+
"G8YxPonzURIHs5SOURZnYeASifuSbifqyFoWPexDuxTN3x84Uti00fCUS9DgbqKMIySK4wt9TCeecyr2rD55QDzIlOgmiPUC",
28+
"rcivMmo7ECcfITpH3uB2FXHfOJH5ILdXoXHbZ4FuzFiPBcTUUfcpSFZlaopWtGSa7YP4Gb9embV2cBsS5vFV6mo7HqCyGAyG",
29+
];
30+
31+
for (let str in strs)
32+
assert(atob(btoa(str)) === str);
33+
34+
assert(atob(btoa(null)) === "null");
35+
assert(atob(btoa(undefined)) === "undefined");
36+
37+
shouldThrow(() => { btoa("嗨"); }, "Error: Invalid argument for btoa.");
38+
shouldThrow(() => { atob(undefined); }, "Error: Invalid argument for atob.");

Source/JavaScriptCore/Sources.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,7 @@ wasm/WasmOperations.cpp
11361136
wasm/WasmPlan.cpp
11371137
wasm/WasmSectionParser.cpp
11381138
wasm/WasmTypeDefinition.cpp
1139+
wasm/WasmOpcodeCounter.cpp
11391140
wasm/WasmSlowPaths.cpp
11401141
wasm/WasmStreamingCompiler.cpp
11411142
wasm/WasmStreamingParser.cpp

Source/JavaScriptCore/jsc.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
#include <wtf/StringPrintStream.h>
9898
#include <wtf/URL.h>
9999
#include <wtf/WallTime.h>
100+
#include <wtf/text/Base64.h>
100101
#include <wtf/text/StringBuilder.h>
101102
#include <wtf/threads/BinarySemaphore.h>
102103
#include <wtf/threads/Signals.h>
@@ -275,6 +276,9 @@ class Workers {
275276
};
276277

277278

279+
static JSC_DECLARE_HOST_FUNCTION(functionAtob);
280+
static JSC_DECLARE_HOST_FUNCTION(functionBtoa);
281+
278282
static JSC_DECLARE_HOST_FUNCTION(functionCreateGlobalObject);
279283
static JSC_DECLARE_HOST_FUNCTION(functionCreateHeapBigInt);
280284
#if USE(BIGINT32)
@@ -536,6 +540,8 @@ class GlobalObject final : public JSGlobalObject {
536540
Base::finishCreation(vm);
537541
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
538542

543+
addFunction(vm, "atob"_s, functionAtob, 1);
544+
addFunction(vm, "btoa"_s, functionBtoa, 1);
539545
addFunction(vm, "debug"_s, functionDebug, 1);
540546
addFunction(vm, "describe"_s, functionDescribe, 1);
541547
addFunction(vm, "describeArray"_s, functionDescribeArray, 1);
@@ -1379,6 +1385,39 @@ JSC_DEFINE_HOST_FUNCTION(functionPrettyPrint, (JSGlobalObject* globalObject, Cal
13791385
return printInternal(globalObject, callFrame, stdout, true);
13801386
}
13811387

1388+
JSC_DEFINE_HOST_FUNCTION(functionAtob, (JSGlobalObject* globalObject, CallFrame* callFrame))
1389+
{
1390+
VM& vm = globalObject->vm();
1391+
auto scope = DECLARE_THROW_SCOPE(vm);
1392+
auto* string = callFrame->argument(0).toString(globalObject);
1393+
RETURN_IF_EXCEPTION(scope, { });
1394+
1395+
auto decodedData = base64Decode(string->value(globalObject), { Base64DecodeOptions::ValidatePadding, Base64DecodeOptions::IgnoreSpacesAndNewLines, Base64DecodeOptions::DiscardVerticalTab });
1396+
if (!decodedData)
1397+
throwException(globalObject, scope, createError(globalObject, "Invalid argument for atob."_s));
1398+
1399+
return JSValue::encode(jsString(vm, String(decodedData->data(), decodedData->size())));
1400+
}
1401+
1402+
JSC_DEFINE_HOST_FUNCTION(functionBtoa, (JSGlobalObject* globalObject, CallFrame* callFrame))
1403+
{
1404+
VM& vm = globalObject->vm();
1405+
auto scope = DECLARE_THROW_SCOPE(vm);
1406+
auto* string = callFrame->argument(0).toString(globalObject);
1407+
RETURN_IF_EXCEPTION(scope, { });
1408+
1409+
String stringToEncode = string->value(globalObject);
1410+
1411+
if (stringToEncode.isNull())
1412+
return JSValue::encode(jsEmptyString(vm));
1413+
1414+
if (!stringToEncode.isAllLatin1())
1415+
throwException(globalObject, scope, createError(globalObject, "Invalid argument for btoa."_s));
1416+
1417+
String encodedString = base64EncodeToString(stringToEncode.latin1());
1418+
return JSValue::encode(jsString(vm, encodedString));
1419+
}
1420+
13821421
JSC_DEFINE_HOST_FUNCTION(functionDebug, (JSGlobalObject* globalObject, CallFrame* callFrame))
13831422
{
13841423
VM& vm = globalObject->vm();

Source/JavaScriptCore/runtime/OptionsList.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ bool canUseWebAssemblyFastMemory();
540540
v(Bool, libpasScavengeContinuously, false, Normal, nullptr) \
541541
v(Bool, useWasmFaultSignalHandler, true, Normal, nullptr) \
542542
v(Bool, dumpUnlinkedDFGValidation, false, Normal, nullptr) \
543+
v(Bool, dumpWasmOpcodeStatistics, false, Normal, nullptr) \
543544
\
544545
/* Feature Flags */\
545546
\

Source/JavaScriptCore/wasm/WasmFunctionParser.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
#if ENABLE(WEBASSEMBLY)
2929

3030
#include "AirArg.h"
31+
#include "WasmOpcodeCounter.h"
3132
#include "WasmParser.h"
32-
#include "WasmSIMDOpcodes.h"
3333
#include "WasmTypeDefinitionInlines.h"
3434
#include <wtf/DataLog.h>
3535
#include <wtf/ListDump.h>
@@ -342,6 +342,9 @@ auto FunctionParser<Context>::parseBody() -> PartialResult
342342

343343
m_currentOpcode = static_cast<OpType>(op);
344344

345+
if (UNLIKELY(Options::dumpWasmOpcodeStatistics()))
346+
WasmOpcodeCounter::singleton().increment(m_currentOpcode);
347+
345348
if (verbose) {
346349
dataLogLn("processing op (", m_unreachableBlocks, "): ", RawHex(op), ", ", makeString(static_cast<OpType>(op)), " at offset: ", RawHex(m_offset));
347350
m_context.dump(m_controlStack, &m_expressionStack);
@@ -1951,6 +1954,10 @@ FOR_EACH_WASM_MEMORY_STORE_OP(CREATE_CASE)
19511954
WASM_PARSER_FAIL_IF(!parseUInt8(extOp), "can't parse atomic extended opcode");
19521955

19531956
ExtAtomicOpType op = static_cast<ExtAtomicOpType>(extOp);
1957+
1958+
if (UNLIKELY(Options::dumpWasmOpcodeStatistics()))
1959+
WasmOpcodeCounter::singleton().increment(op);
1960+
19541961
switch (op) {
19551962
#define CREATE_CASE(name, id, b3op, inc, memoryType) case ExtAtomicOpType::name: return atomicLoad(op, Types::memoryType);
19561963
FOR_EACH_WASM_EXT_ATOMIC_LOAD_OP(CREATE_CASE)
@@ -2597,6 +2604,10 @@ FOR_EACH_WASM_MEMORY_STORE_OP(CREATE_CASE)
25972604
constexpr bool isReachable = true;
25982605

25992606
ExtSIMDOpType op = static_cast<ExtSIMDOpType>(simdOp);
2607+
2608+
if (UNLIKELY(Options::dumpWasmOpcodeStatistics()))
2609+
WasmOpcodeCounter::singleton().increment(op);
2610+
26002611
switch (op) {
26012612
#define CREATE_SIMD_CASE(name, _, laneOp, lane, signMode) case ExtSIMDOpType::name: return simd<isReachable>(SIMDLaneOperation::laneOp, lane, signMode);
26022613
FOR_EACH_WASM_EXT_SIMD_GENERAL_OP(CREATE_SIMD_CASE)
@@ -2923,7 +2934,12 @@ auto FunctionParser<Context>::parseUnreachableExpression() -> PartialResult
29232934
uint8_t extOp;
29242935
WASM_PARSER_FAIL_IF(!parseUInt8(extOp), "can't parse extended GC opcode");
29252936

2926-
switch (static_cast<GCOpType>(extOp)) {
2937+
GCOpType op = static_cast<GCOpType>(extOp);
2938+
2939+
if (UNLIKELY(Options::dumpWasmOpcodeStatistics()))
2940+
WasmOpcodeCounter::singleton().increment(op);
2941+
2942+
switch (op) {
29272943
case GCOpType::I31New:
29282944
case GCOpType::I31GetS:
29292945
case GCOpType::I31GetU:
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/*
2+
* Copyright (C) 2023 Apple Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
#include "config.h"
26+
#include "WasmOpcodeCounter.h"
27+
28+
#if ENABLE(WEBASSEMBLY) && ENABLE(B3_JIT)
29+
#include "WasmTypeDefinition.h"
30+
#include <wtf/Atomics.h>
31+
#include <wtf/DataLog.h>
32+
#include <wtf/NeverDestroyed.h>
33+
#include <wtf/Vector.h>
34+
35+
#if PLATFORM(COCOA)
36+
#include <notify.h>
37+
#include <unistd.h>
38+
#endif
39+
40+
namespace JSC {
41+
namespace Wasm {
42+
43+
WasmOpcodeCounter& WasmOpcodeCounter::singleton()
44+
{
45+
static LazyNeverDestroyed<WasmOpcodeCounter> counter;
46+
static std::once_flag onceKey;
47+
std::call_once(onceKey, [&] {
48+
counter.construct();
49+
});
50+
return counter;
51+
}
52+
53+
54+
template<typename OpcodeType, typename OpcodeTypeDump, typename IsRegisteredOpcodeFunctor>
55+
void WasmOpcodeCounter::dump(Atomic<uint64_t>* counter, NumberOfRegisteredOpcodes numberOfRegisteredOpcode, CounterSize counterSize, const IsRegisteredOpcodeFunctor& isRegisteredOpcodeFunctor, const char* prefix, const char* suffix)
56+
{
57+
struct Pair {
58+
OpcodeType opcode;
59+
uint64_t count;
60+
};
61+
62+
Vector<Pair> vector;
63+
uint64_t usedOpcode = 0;
64+
for (size_t i = 0; i < counterSize; i++) {
65+
if (!isRegisteredOpcodeFunctor((OpcodeType)i))
66+
continue;
67+
68+
uint64_t count = counter[i].loadFullyFenced();
69+
if (count)
70+
usedOpcode++;
71+
vector.append({ (OpcodeType)i, count });
72+
}
73+
74+
std::sort(vector.begin(), vector.end(), [](Pair& a, Pair& b) {
75+
return b.count < a.count;
76+
});
77+
78+
int pid = 0;
79+
#if PLATFORM(COCOA)
80+
pid = getpid();
81+
#endif
82+
float coverage = usedOpcode * 1.0 / numberOfRegisteredOpcode * 100;
83+
dataLogF("%s<%d> %s use coverage %.2f%%.\n", prefix, pid, suffix, coverage);
84+
for (Pair& pair : vector)
85+
dataLogLn(prefix, "<", pid, "> ", OpcodeTypeDump(pair.opcode), ": ", pair.count);
86+
}
87+
88+
void WasmOpcodeCounter::dump()
89+
{
90+
dump<ExtSIMDOpType, ExtSIMDOpTypeDump>(m_extendedSIMDOpcodeCounter, m_extendedSIMDOpcodeInfo.first, m_extendedSIMDOpcodeInfo.second, isRegisteredWasmExtendedSIMDOpcode, "<WASM.EXT.SIMD.OP.STAT>", "wasm extended SIMD opcode");
91+
92+
dump<ExtAtomicOpType, ExtAtomicOpTypeDump>(m_extendedAtomicOpcodeCounter, m_extendedAtomicOpcodeInfo.first, m_extendedAtomicOpcodeInfo.second, isRegisteredExtenedAtomicOpcode, "<WASM.EXT.ATOMIC.OP.STAT>", "wasm extended atomic opcode");
93+
94+
dump<GCOpType, GCOpTypeDump>(m_GCOpcodeCounter, m_GCOpcodeInfo.first, m_GCOpcodeInfo.second, isRegisteredGCOpcode, "<WASM.GC.OP.STAT>", "wasm GC opcode");
95+
96+
dump<OpType, OpTypeDump>(m_baseOpcodeCounter, m_baseOpcodeInfo.first, m_baseOpcodeInfo.second, isRegisteredBaseOpcode, "<WASM.BASE.OP.STAT>", "wasm base opcode");
97+
}
98+
99+
void WasmOpcodeCounter::registerDispatch()
100+
{
101+
#if PLATFORM(COCOA)
102+
static std::once_flag registerFlag;
103+
std::call_once(registerFlag, [&]() {
104+
int pid = getpid();
105+
const char* key = "com.apple.WebKit.wasm.op.stat";
106+
dataLogF("<WASM.OP.STAT><%d> Registering callback for wasm opcode statistics.\n", pid);
107+
dataLogF("<WASM.OP.STAT><%d> Use `notifyutil -v -p %s` to dump statistics.\n", pid, key);
108+
109+
int token;
110+
notify_register_dispatch(key, &token, dispatch_get_main_queue(), ^(int) {
111+
WasmOpcodeCounter::singleton().dump();
112+
});
113+
});
114+
#endif
115+
}
116+
117+
void WasmOpcodeCounter::increment(ExtSIMDOpType op)
118+
{
119+
registerDispatch();
120+
m_extendedSIMDOpcodeCounter[(uint8_t)op].exchangeAdd(1);
121+
}
122+
123+
void WasmOpcodeCounter::increment(ExtAtomicOpType op)
124+
{
125+
registerDispatch();
126+
m_extendedAtomicOpcodeCounter[(uint8_t)op].exchangeAdd(1);
127+
}
128+
129+
void WasmOpcodeCounter::increment(GCOpType op)
130+
{
131+
registerDispatch();
132+
m_GCOpcodeCounter[(uint8_t)op].exchangeAdd(1);
133+
}
134+
135+
void WasmOpcodeCounter::increment(OpType op 109A2 )
136+
{
137+
registerDispatch();
138+
m_baseOpcodeCounter[(uint8_t)op].exchangeAdd(1);
139+
}
140+
141+
} // namespace JSC
142+
} // namespace JSC::Wasm
143+
144+
#endif // ENABLE(WEBASSEMBLY) && && ENABLE(B3_JIT)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (C) 2023 Apple Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
#pragma once
26+
27+
#if ENABLE(WEBASSEMBLY) && ENABLE(B3_JIT)
28+
29+
#include "WasmTypeDefinition.h"
30+
#include <wtf/Atomics.h>
31+
32+
namespace JSC {
33+
namespace Wasm {
34+
35+
class WasmOpcodeCounter {
36+
WTF_MAKE_FAST_ALLOCATED;
37+
using NumberOfRegisteredOpcodes = size_t;
38+
using CounterSize = size_t;
39+
40+
public:
41+
static WasmOpcodeCounter& singleton();
42+
43+
void registerDispatch();
44+
45+
void increment(ExtSIMDOpType);
46+
void increment(ExtAtomicOpType);
47+
void increment(GCOpType);
48+
void increment(OpType);
49+
50+
void dump();
51+
template<typename OpcodeType, typename OpcodeTypeDump, typename IsRegisteredOpcodeFunctor>
52+
void dump(Atomic<uint64_t>* counter, NumberOfRegisteredOpcodes, CounterSize, const IsRegisteredOpcodeFunctor&, const char* prefix, const char* suffix);
53+
54+
private:
55+
constexpr static std::pair<NumberOfRegisteredOpcodes, CounterSize> m_extendedSIMDOpcodeInfo = countNumberOfWasmExtendedSIMDOpcodes();
56+
Atomic<uint64_t> m_extendedSIMDOpcodeCounter[m_extendedSIMDOpcodeInfo.second];
57+
58+
constexpr static std::pair<NumberOfRegisteredOpcodes, CounterSize> m_extendedAtomicOpcodeInfo = countNumberOfWasmExtendedAtomicOpcodes();
59+
Atomic<uint64_t> m_extendedAtomicOpcodeCounter[m_extendedAtomicOpcodeInfo.second];
60+
61+
constexpr static std::pair<NumberOfRegisteredOpcodes, CounterSize> m_GCOpcodeInfo = countNumberOfWasmGCOpcodes();
62+
Atomic<uint64_t> m_GCOpcodeCounter[m_GCOpcodeInfo.second];
63+
64+
constexpr static std::pair<NumberOfRegisteredOpcodes, CounterSize> m_baseOpcodeInfo = countNumberOfWasmBaseOpcodes();
65+
Atomic<uint64_t> m_baseOpcodeCounter[m_baseOpcodeInfo.second];
66+
};
67+
68+
} // namespace JSC
69+
} // namespace JSC::Wasm
70+
71+
#endif // ENABLE(WEBASSEMBLY) && && ENABLE(B3_JIT)

0 commit comments

Comments
 (0)
0