From 054bb525d65a1ff2b942fb6e906517ad90cce5af Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 3 Sep 2024 15:56:46 -0700 Subject: [PATCH 1/6] Implement MONO_MEMORY_BARRIER in jiterpreter --- src/mono/browser/runtime/jiterpreter-trace-generator.ts | 5 +++++ src/mono/browser/runtime/jiterpreter.ts | 6 ++++++ src/mono/mono/mini/interp/jiterpreter-opcode-values.h | 1 + src/mono/mono/mini/interp/jiterpreter.c | 6 ++++++ 4 files changed, 18 insertions(+) diff --git a/src/mono/browser/runtime/jiterpreter-trace-generator.ts b/src/mono/browser/runtime/jiterpreter-trace-generator.ts index 9ca8453e58a8cc..a657d7f098d622 100644 --- a/src/mono/browser/runtime/jiterpreter-trace-generator.ts +++ b/src/mono/browser/runtime/jiterpreter-trace-generator.ts @@ -3975,6 +3975,11 @@ function emit_simd_4 (builder: WasmBuilder, ip: MintOpcodePtr, index: SimdIntrin function emit_atomics ( builder: WasmBuilder, ip: MintOpcodePtr, opcode: number ) { + if (opcode === MintOpcode.MINT_MONO_MEMORY_BARRIER) { + builder.callImport("membar"); + return true; + } + if (!builder.options.enableAtomics) return false; diff --git a/src/mono/browser/runtime/jiterpreter.ts b/src/mono/browser/runtime/jiterpreter.ts index 68130b681358ae..75ea46326a20af 100644 --- a/src/mono/browser/runtime/jiterpreter.ts +++ b/src/mono/browser/runtime/jiterpreter.ts @@ -286,6 +286,7 @@ function getTraceImports () { ["stelemr_tc", "stelemr", getRawCwrap("mono_jiterp_stelem_ref")], importDef("fma", getRawCwrap("fma")), importDef("fmaf", getRawCwrap("fmaf")), + importDef("membar", getRawCwrap("mono_jiterp_memory_barrier")), ]; if (instrumentedMethodNames.length > 0) { @@ -663,6 +664,11 @@ function initialize_builder (builder: WasmBuilder) { }, WasmValtype.void, true ); + builder.defineType( + "membar", + {}, + WasmValtype.void, true + ); const traceImports = getTraceImports(); diff --git a/src/mono/mono/mini/interp/jiterpreter-opcode-values.h b/src/mono/mono/mini/interp/jiterpreter-opcode-values.h index 7d903e2aeefe19..a509b8471cfa95 100644 --- a/src/mono/mono/mini/interp/jiterpreter-opcode-values.h +++ b/src/mono/mono/mini/interp/jiterpreter-opcode-values.h @@ -187,6 +187,7 @@ OP(MINT_THROW, ABORT_OUTSIDE_BRANCH_BLOCK_NONE) OP(MINT_MOV_SRC_OFF, NORMAL) OP(MINT_MOV_DST_OFF, NORMAL) +OP(MINT_MONO_MEMORY_BARRIER, NORMAL) OPRANGE(MINT_MONO_EXCHANGE_U1, MINT_MONO_EXCHANGE_I8, HIGH) OPRANGE(MINT_MONO_CMPXCHG_U1, MINT_MONO_CMPXCHG_I8, HIGH) diff --git a/src/mono/mono/mini/interp/jiterpreter.c b/src/mono/mono/mini/interp/jiterpreter.c index 13d337b10c9fe0..2bb2204accbf76 100644 --- a/src/mono/mono/mini/interp/jiterpreter.c +++ b/src/mono/mono/mini/interp/jiterpreter.c @@ -1165,6 +1165,12 @@ mono_jiterp_stelem_ref ( return 1; } +EMSCRIPTEN_KEEPALIVE void +mono_jiterp_memory_barrier () { + mono_memory_barrier (); +} + + // keep in sync with jiterpreter-enums.ts JiterpMember enum { JITERP_MEMBER_VT_INITIALIZED = 0, From 08ac69183f7d94e655948c8ec91b26cb6b08d2e5 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 3 Sep 2024 19:02:27 -0700 Subject: [PATCH 2/6] Don't emit memory barrier in ST builds --- src/mono/browser/runtime/jiterpreter-trace-generator.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mono/browser/runtime/jiterpreter-trace-generator.ts b/src/mono/browser/runtime/jiterpreter-trace-generator.ts index a657d7f098d622..c62b3be0e9aa51 100644 --- a/src/mono/browser/runtime/jiterpreter-trace-generator.ts +++ b/src/mono/browser/runtime/jiterpreter-trace-generator.ts @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +import WasmEnableThreads from "consts:wasmEnableThreads"; import { MonoMethod } from "./types/internal"; import { NativePointer } from "./types/emscripten"; import { @@ -3976,7 +3977,8 @@ function emit_atomics ( builder: WasmBuilder, ip: MintOpcodePtr, opcode: number ) { if (opcode === MintOpcode.MINT_MONO_MEMORY_BARRIER) { - builder.callImport("membar"); + if (WasmEnableThreads) + builder.callImport("membar"); return true; } From 7b171b2fa876ddd42dd8e8faa6763ffdfcd0b432 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 4 Sep 2024 00:36:22 -0700 Subject: [PATCH 3/6] Enable jiterp traces for MT wasm --- src/mono/mono/utils/options-def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/utils/options-def.h b/src/mono/mono/utils/options-def.h index fc7e403a2bbd0d..4d3bdddaf7073c 100644 --- a/src/mono/mono/utils/options-def.h +++ b/src/mono/mono/utils/options-def.h @@ -89,7 +89,7 @@ DEFINE_BOOL(jiterpreter_jit_call_enabled, "jiterpreter-jit-call-enabled", TRUE, DEFINE_BOOL(wasm_gc_safepoints, "wasm-gc-safepoints", FALSE, "Use GC safepoints on WASM") #else // traces_enabled controls whether the jiterpreter will JIT individual interpreter opcode traces -DEFINE_BOOL_READONLY(jiterpreter_traces_enabled, "jiterpreter-traces-enabled", FALSE, "JIT interpreter opcode traces into WASM") +DEFINE_BOOL(jiterpreter_traces_enabled, "jiterpreter-traces-enabled", TRUE, "JIT interpreter opcode traces into WASM") // interp_entry_enabled controls whether specialized interp_entry wrappers will be jitted DEFINE_BOOL_READONLY(jiterpreter_interp_entry_enabled, "jiterpreter-interp-entry-enabled", FALSE, "JIT specialized WASM interp_entry wrappers") // jit_call_enabled controls whether do_jit_call will use specialized trampolines for hot call sites From 5a9b7b738852a2f8cb95d77db087f4a5397e9289 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 5 Sep 2024 08:06:43 -0700 Subject: [PATCH 4/6] Use native wasm atomic fence instead of calling C for memory barriers --- src/mono/browser/runtime/jiterpreter-trace-generator.ts | 4 ++-- src/mono/browser/runtime/jiterpreter.ts | 6 ------ src/mono/mono/mini/interp/jiterpreter.c | 5 ----- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/mono/browser/runtime/jiterpreter-trace-generator.ts b/src/mono/browser/runtime/jiterpreter-trace-generator.ts index c62b3be0e9aa51..092d721daa2bd2 100644 --- a/src/mono/browser/runtime/jiterpreter-trace-generator.ts +++ b/src/mono/browser/runtime/jiterpreter-trace-generator.ts @@ -10,7 +10,7 @@ import { } from "./memory"; import { WasmOpcode, WasmSimdOpcode, WasmValtype, - getOpcodeName, MintOpArgType + getOpcodeName, MintOpArgType, WasmAtomicOpcode } from "./jiterpreter-opcodes"; import { MintOpcode, SimdInfo, @@ -3978,7 +3978,7 @@ function emit_atomics ( ) { if (opcode === MintOpcode.MINT_MONO_MEMORY_BARRIER) { if (WasmEnableThreads) - builder.callImport("membar"); + builder.appendAtomic(WasmAtomicOpcode.atomic_fence); return true; } diff --git a/src/mono/browser/runtime/jiterpreter.ts b/src/mono/browser/runtime/jiterpreter.ts index 75ea46326a20af..68130b681358ae 100644 --- a/src/mono/browser/runtime/jiterpreter.ts +++ b/src/mono/browser/runtime/jiterpreter.ts @@ -286,7 +286,6 @@ function getTraceImports () { ["stelemr_tc", "stelemr", getRawCwrap("mono_jiterp_stelem_ref")], importDef("fma", getRawCwrap("fma")), importDef("fmaf", getRawCwrap("fmaf")), - importDef("membar", getRawCwrap("mono_jiterp_memory_barrier")), ]; if (instrumentedMethodNames.length > 0) { @@ -664,11 +663,6 @@ function initialize_builder (builder: WasmBuilder) { }, WasmValtype.void, true ); - builder.defineType( - "membar", - {}, - WasmValtype.void, true - ); const traceImports = getTraceImports(); diff --git a/src/mono/mono/mini/interp/jiterpreter.c b/src/mono/mono/mini/interp/jiterpreter.c index 2bb2204accbf76..fa75f766cec02b 100644 --- a/src/mono/mono/mini/interp/jiterpreter.c +++ b/src/mono/mono/mini/interp/jiterpreter.c @@ -1165,11 +1165,6 @@ mono_jiterp_stelem_ref ( return 1; } -EMSCRIPTEN_KEEPALIVE void -mono_jiterp_memory_barrier () { - mono_memory_barrier (); -} - // keep in sync with jiterpreter-enums.ts JiterpMember enum { From 8de6f6058e6236ad13ccac933158def70237e946 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 5 Sep 2024 19:21:52 -0700 Subject: [PATCH 5/6] Fix atomic fence encoding --- src/mono/browser/runtime/jiterpreter-trace-generator.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mono/browser/runtime/jiterpreter-trace-generator.ts b/src/mono/browser/runtime/jiterpreter-trace-generator.ts index 092d721daa2bd2..956538ffe5f3cc 100644 --- a/src/mono/browser/runtime/jiterpreter-trace-generator.ts +++ b/src/mono/browser/runtime/jiterpreter-trace-generator.ts @@ -3977,8 +3977,12 @@ function emit_atomics ( builder: WasmBuilder, ip: MintOpcodePtr, opcode: number ) { if (opcode === MintOpcode.MINT_MONO_MEMORY_BARRIER) { - if (WasmEnableThreads) + if (WasmEnableThreads) { builder.appendAtomic(WasmAtomicOpcode.atomic_fence); + // The text format and other parts of the spec say atomic.fence has no operands, + // but the binary encoding requires a dummy zero byte for some reason + builder.appendU8(0); + } return true; } From 204563c704eb644528c8ea69f8f96488bd4f76a9 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 6 Sep 2024 11:28:53 -0700 Subject: [PATCH 6/6] Update comment --- src/mono/browser/runtime/jiterpreter-trace-generator.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mono/browser/runtime/jiterpreter-trace-generator.ts b/src/mono/browser/runtime/jiterpreter-trace-generator.ts index 956538ffe5f3cc..da85d7ab02163b 100644 --- a/src/mono/browser/runtime/jiterpreter-trace-generator.ts +++ b/src/mono/browser/runtime/jiterpreter-trace-generator.ts @@ -3978,9 +3978,13 @@ function emit_atomics ( ) { if (opcode === MintOpcode.MINT_MONO_MEMORY_BARRIER) { if (WasmEnableThreads) { + // Mono memory barriers use sync_synchronize which generates atomic.fence on clang, + // provided you pass -pthread at compile time builder.appendAtomic(WasmAtomicOpcode.atomic_fence); // The text format and other parts of the spec say atomic.fence has no operands, - // but the binary encoding requires a dummy zero byte for some reason + // but the binary encoding contains a byte specifying whether the barrier is + // sequentially consistent (0) or acquire-release (1) + // Mono memory barriers are sync_synchronize which is sequentially consistent. builder.appendU8(0); } return true;