Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions src/docs/internal/PERFORMANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,16 +156,14 @@ EH+PIC sysroot, including SIMD, relaxed SIMD, and extended const. Adding an
extra `-msimd128` did not change the generated AOT artifact sizes in the local
release experiment, so it is not carried as a project-specific flag.

Wasmer LLVM AOT is generated with the selected mainline codegen profile:
nonvolatile memory operations and a readonly funcref table. Local exact Oliphaunt
speed-suite measurements showed nonvolatile memory operations improving the
server SQLx suite by about 9% geomean. Adding the readonly funcref table on top
was about 1.4% faster geomean than nonvolatile-only and improved the indexed
update cases (`557.152ms -> 534.737ms` and `695.663ms -> 681.778ms`), while
regressing CREATE INDEX and DROP TABLE cases. Wasmer documents nonvolatile
memory operations as faster but not fully WebAssembly-spec compliant; this is a
conscious mainline runtime-profile decision for the packaged single-process
Postgres runtime and must stay covered by the correctness matrix.
Wasmer LLVM AOT uses the fixed `llvm-opta-ro_ftable` profile: spec-compliant
memory operations and the existing readonly funcref optimization. Disabling
the previous nonvolatile-memory optimization preserves Wasm memory semantics
but can increase query latency. Compiler policy is not a consumer runtime knob;
conflicting build-time overrides are rejected.

The profile is part of the artifact identity. Rebuild AOT artifacts when it
changes; legacy nonvolatile artifacts cannot be relabelled as strict.

WebAssembly exceptions are mandatory for production artifacts. The Postgres
runtime depends on exception/longjmp recovery across the main module and side
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ fn write_generated_aot(out: &Path, target: &str, artifact_dir: &Path) {

let text = format!(
"pub const TARGET_TRIPLE: &str = {:?};\n\
pub const ENGINE: &str = \"llvm-opta\";\n\
pub const ENGINE: &str = \"llvm-opta-ro_ftable\";\n\
pub const HAS_EMBEDDED_AOT: bool = true;\n\
pub const MANIFEST_JSON: &str = include_str!({});\n\
#[rustfmt::skip]\n\
Expand All @@ -188,11 +188,11 @@ fn write_generated_aot(out: &Path, target: &str, artifact_dir: &Path) {

fn write_source_only_aot(out: &Path, target: &str) {
let manifest = format!(
"{{\"format-version\":1,\"target-triple\":{target:?},\"engine\":\"llvm-opta\",\"wasmer-version\":\"7.2.1\",\"wasmer-wasix-version\":\"0.702.1\",\"artifacts\":[]}}"
"{{\"format-version\":1,\"target-triple\":{target:?},\"engine\":\"llvm-opta-ro_ftable\",\"wasmer-version\":\"7.2.1\",\"wasmer-wasix-version\":\"0.702.1\",\"artifacts\":[]}}"
);
let text = format!(
"pub const TARGET_TRIPLE: &str = {target:?};\n\
pub const ENGINE: &str = \"llvm-opta\";\n\
pub const ENGINE: &str = \"llvm-opta-ro_ftable\";\n\
pub const HAS_EMBEDDED_AOT: bool = false;\n\
pub const MANIFEST_JSON: &str = r#\"{manifest}\"#;\n\
pub fn artifact_bytes(_name: &str) -> Option<&'static [u8]> {{ None }}\n"
Expand Down Expand Up @@ -233,7 +233,7 @@ fn write_core_aot_manifest(source: &Path, destination: &Path) -> Vec<String> {
serde_json::from_str(&text).expect("parse generated WASIX AOT manifest");
assert_eq!(
manifest.get("engine").and_then(serde_json::Value::as_str),
Some("llvm-opta"),
Some("llvm-opta-ro_ftable"),
"stale WASIX AOT profile; rebuild artifacts before compiling the carrier"
);
let artifacts = manifest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ fn write_generated_aot(out: &Path, target: &str, artifact_dir: &Path) {

let text = format!(
"pub const TARGET_TRIPLE: &str = {:?};\n\
pub const ENGINE: &str = \"llvm-opta\";\n\
pub const ENGINE: &str = \"llvm-opta-ro_ftable\";\n\
pub const HAS_EMBEDDED_AOT: bool = true;\n\
pub const MANIFEST_JSON: &str = include_str!({});\n\
#[rustfmt::skip]\n\
Expand All @@ -188,11 +188,11 @@ fn write_generated_aot(out: &Path, target: &str, artifact_dir: &Path) {

fn write_source_only_aot(out: &Path, target: &str) {
let manifest = format!(
"{{\"format-version\":1,\"target-triple\":{target:?},\"engine\":\"llvm-opta\",\"wasmer-version\":\"7.2.1\",\"wasmer-wasix-version\":\"0.702.1\",\"artifacts\":[]}}"
"{{\"format-version\":1,\"target-triple\":{target:?},\"engine\":\"llvm-opta-ro_ftable\",\"wasmer-version\":\"7.2.1\",\"wasmer-wasix-version\":\"0.702.1\",\"artifacts\":[]}}"
);
let text = format!(
"pub const TARGET_TRIPLE: &str = {target:?};\n\
pub const ENGINE: &str = \"llvm-opta\";\n\
pub const ENGINE: &str = \"llvm-opta-ro_ftable\";\n\
pub const HAS_EMBEDDED_AOT: bool = false;\n\
pub const MANIFEST_JSON: &str = r#\"{manifest}\"#;\n\
pub fn artifact_bytes(_name: &str) -> Option<&'static [u8]> {{ None }}\n"
Expand Down Expand Up @@ -233,7 +233,7 @@ fn write_core_aot_manifest(source: &Path, destination: &Path) -> Vec<String> {
serde_json::from_str(&text).expect("parse generated WASIX AOT manifest");
assert_eq!(
manifest.get("engine").and_then(serde_json::Value::as_str),
Some("llvm-opta"),
Some("llvm-opta-ro_ftable"),
"stale WASIX AOT profile; rebuild artifacts before compiling the carrier"
);
let artifacts = manifest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ fn write_generated_aot(out: &Path, target: &str, artifact_dir: &Path) {

let text = format!(
"pub const TARGET_TRIPLE: &str = {:?};\n\
pub const ENGINE: &str = \"llvm-opta\";\n\
pub const ENGINE: &str = \"llvm-opta-ro_ftable\";\n\
pub const HAS_EMBEDDED_AOT: bool = true;\n\
pub const MANIFEST_JSON: &str = include_str!({});\n\
#[rustfmt::skip]\n\
Expand All @@ -188,11 +188,11 @@ fn write_generated_aot(out: &Path, target: &str, artifact_dir: &Path) {

fn write_source_only_aot(out: &Path, target: &str) {
let manifest = format!(
"{{\"format-version\":1,\"target-triple\":{target:?},\"engine\":\"llvm-opta\",\"wasmer-version\":\"7.2.1\",\"wasmer-wasix-version\":\"0.702.1\",\"artifacts\":[]}}"
"{{\"format-version\":1,\"target-triple\":{target:?},\"engine\":\"llvm-opta-ro_ftable\",\"wasmer-version\":\"7.2.1\",\"wasmer-wasix-version\":\"0.702.1\",\"artifacts\":[]}}"
);
let text = format!(
"pub const TARGET_TRIPLE: &str = {target:?};\n\
pub const ENGINE: &str = \"llvm-opta\";\n\
pub const ENGINE: &str = \"llvm-opta-ro_ftable\";\n\
pub const HAS_EMBEDDED_AOT: bool = false;\n\
pub const MANIFEST_JSON: &str = r#\"{manifest}\"#;\n\
pub fn artifact_bytes(_name: &str) -> Option<&'static [u8]> {{ None }}\n"
Expand Down Expand Up @@ -233,7 +233,7 @@ fn write_core_aot_manifest(source: &Path, destination: &Path) -> Vec<String> {
serde_json::from_str(&text).expect("parse generated WASIX AOT manifest");
assert_eq!(
manifest.get("engine").and_then(serde_json::Value::as_str),
Some("llvm-opta"),
Some("llvm-opta-ro_ftable"),
"stale WASIX AOT profile; rebuild artifacts before compiling the carrier"
);
let artifacts = manifest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ fn write_generated_aot(out: &Path, target: &str, artifact_dir: &Path) {

let text = format!(
"pub const TARGET_TRIPLE: &str = {:?};\n\
pub const ENGINE: &str = \"llvm-opta\";\n\
pub const ENGINE: &str = \"llvm-opta-ro_ftable\";\n\
pub const HAS_EMBEDDED_AOT: bool = true;\n\
pub const MANIFEST_JSON: &str = include_str!({});\n\
#[rustfmt::skip]\n\
Expand All @@ -188,11 +188,11 @@ fn write_generated_aot(out: &Path, target: &str, artifact_dir: &Path) {

fn write_source_only_aot(out: &Path, target: &str) {
let manifest = format!(
"{{\"format-version\":1,\"target-triple\":{target:?},\"engine\":\"llvm-opta\",\"wasmer-version\":\"7.2.1\",\"wasmer-wasix-version\":\"0.702.1\",\"artifacts\":[]}}"
"{{\"format-version\":1,\"target-triple\":{target:?},\"engine\":\"llvm-opta-ro_ftable\",\"wasmer-version\":\"7.2.1\",\"wasmer-wasix-version\":\"0.702.1\",\"artifacts\":[]}}"
);
let text = format!(
"pub const TARGET_TRIPLE: &str = {target:?};\n\
pub const ENGINE: &str = \"llvm-opta\";\n\
pub const ENGINE: &str = \"llvm-opta-ro_ftable\";\n\
pub const HAS_EMBEDDED_AOT: bool = false;\n\
pub const MANIFEST_JSON: &str = r#\"{manifest}\"#;\n\
pub fn artifact_bytes(_name: &str) -> Option<&'static [u8]> {{ None }}\n"
Expand Down Expand Up @@ -233,7 +233,7 @@ fn write_core_aot_manifest(source: &Path, destination: &Path) -> Vec<String> {
serde_json::from_str(&text).expect("parse generated WASIX AOT manifest");
assert_eq!(
manifest.get("engine").and_then(serde_json::Value::as_str),
Some("llvm-opta"),
Some("llvm-opta-ro_ftable"),
"stale WASIX AOT profile; rebuild artifacts before compiling the carrier"
);
let artifacts = manifest
Expand Down
14 changes: 7 additions & 7 deletions src/wasix/postmaster/executor/src/bin/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ fn parse() -> Result<Option<Options>> {

fn product_compiler() -> LLVM {
let mut compiler = LLVM::new();
// Retain main's policy; strict shared-memory compilation is a separate change.
// Postmaster shares guest memory across concurrently running threads.
compiler
.opt_level(LLVMOptLevel::Aggressive)
.non_volatile_memops(true)
.non_volatile_memops(false)
.readonly_funcref_table(true);
compiler
}
Expand Down Expand Up @@ -213,11 +213,11 @@ fn verify_aot(module_path: PathBuf, artifact_path: PathBuf) -> Result<()> {
}

#[test]
fn product_compiler_uses_main_memory_identity() {
let relaxed_id = Box::new(product_compiler()).compiler().deterministic_id();
let mut strict = product_compiler();
strict.non_volatile_memops(false);
let strict_id = Box::new(strict).compiler().deterministic_id();
fn product_compiler_uses_strict_memory_identity() {
let strict_id = Box::new(product_compiler()).compiler().deterministic_id();
let mut relaxed = product_compiler();
relaxed.non_volatile_memops(true);
let relaxed_id = Box::new(relaxed).compiler().deterministic_id();
assert!(strict_id.contains("-nv0-"));
assert!(relaxed_id.contains("-nv1-"));
assert_ne!(strict_id, relaxed_id);
Expand Down
6 changes: 3 additions & 3 deletions src/wasix/postmaster/executor/src/sealed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1813,8 +1813,8 @@ fn validate_manifest_identity(manifest: &SealedManifest, engine: &Engine) -> Res
Target::default().triple()
);
ensure!(
manifest.engine == "llvm-opta",
"sealed manifest producer engine must be 'llvm-opta'"
manifest.engine == "llvm-opta-ro_ftable",
"sealed manifest producer engine must be 'llvm-opta-ro_ftable'"
);
ensure_nonempty("compiler-config", &manifest.compiler_config)?;
ensure!(
Expand Down Expand Up @@ -2545,7 +2545,7 @@ mod tests {
postgres_version: "18.4".to_string(),
target_triple: "test-target".to_string(),
host_abi: "test-abi".to_string(),
engine: "llvm-opta".to_string(),
engine: "llvm-opta-ro_ftable".to_string(),
compiler_config: "test-compiler".to_string(),
cpu_policy: "generic-baseline".to_string(),
cpu_features: Vec::new(),
Expand Down
2 changes: 1 addition & 1 deletion src/wasix/postmaster/lib/build-sealed-carrier.mts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ function manifest(args: string[]) {
'postgres-version': pg,
'target-triple': target,
'host-abi': abi,
engine: 'llvm-opta',
engine: 'llvm-opta-ro_ftable',
'compiler-config': config,
'cpu-policy': 'generic-baseline',
'cpu-features': [],
Expand Down
2 changes: 1 addition & 1 deletion src/wasix/postmaster/lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1603,7 +1603,7 @@ fresh_wasmer_compiler_cache_bucket() {

case "$(fresh_normalize_wasmer_compiler "$compiler")" in
llvm)
printf 'llvm-%s-v%s\n' "$(fresh_wasmer_llvm_opt_suffix "$llvm_opt_level")" "$artifact_version"
printf 'llvm-%s-ro_ftable-v%s\n' "$(fresh_wasmer_llvm_opt_suffix "$llvm_opt_level")" "$artifact_version"
;;
esac
}
Expand Down
2 changes: 1 addition & 1 deletion src/wasix/postmaster/lib/common.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ write_postmaster_executor_receipt
default_cache_dir="$(fresh_wasmer_cache_dir "$FRESH_UPSTREAM_WASMER_BIN")"
default_cache_bucket="$(fresh_wasmer_compiler_cache_bucket llvm aggressive 21)"
[ -n "$default_cache_dir" ]
[ "$default_cache_bucket" = llvm-opta-v21 ]
[ "$default_cache_bucket" = llvm-opta-ro_ftable-v21 ]

mv "$WASMER_BUILD_RECEIPT" "$test_root/receipt.saved"
expect_failure fresh_require_patched_wasmer "$FRESH_UPSTREAM_WASMER_BIN"
Expand Down
2 changes: 1 addition & 1 deletion src/wasix/postmaster/lib/sealed-carrier.sh
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ fresh_aot_producer_recipe_sha256() {
for guest_input in "${verifier_inputs[@]}"; do
printf '%s\0%s\0' verifier-input-sha256 "$(fresh_wasmer_bin_hash "$guest_input")"
done
printf '%s\0%s\0' producer-engine llvm-opta
printf '%s\0%s\0' producer-engine llvm-opta-ro_ftable
printf '%s\0%s\0' compiler-config "$compiler_config"
printf '%s\0%s\0' target-triple "$target_triple"
printf '%s\0%s\0' cpu-policy generic-baseline
Expand Down
2 changes: 1 addition & 1 deletion src/wasix/postmaster/lib/verify-sealed-carrier.mts
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ export function verify(
'postgres-version': pgVersion,
'target-triple': wasmer.rustc_host,
'host-abi': wasmer.host_abi,
engine: 'llvm-opta',
engine: 'llvm-opta-ro_ftable',
'cpu-policy': 'generic-baseline',
'cpu-features': [],
'wasmer-version': wasmerVersion,
Expand Down
5 changes: 3 additions & 2 deletions src/wasix/postmaster/wasmer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ hashes. Runtime selection never falls back to a stock or `PATH` Wasmer.
The ordered `series` files, not directory globs, select patches. Their digest
includes the manifest, member names and contents; editing or reordering a patch
invalidates receipts. The product executor lives in `../executor`.
The compiler and verifier use the nonvolatile-memory profile. Compiler policy
changes require rebuilt carriers with matching identities.
Patch 0009 separately disables LLVM nonvolatile memory operations for shared
guest memory; the product compiler and artifact verifier use the same strict
policy. Carriers and AOT artifacts must be rebuilt, never relabelled.

The libc series separates mapping, file, socket, process, exception and resource
contracts. Its `sigsetjmp` fix evaluates the buffer expression once in the live
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
From: Sid Jain <sid_26@outlook.com>
Date: Mon, 7 Sep 2026 00:00:00 +0000
Subject: [PATCH 9/9] Keep concurrent Postmaster LLVM memory operations strict

Postmaster shares guest linear memory across threads and processes. Enabling
non-volatile memory operations promises an isolation guarantee that this
runtime does not have. Use the conservative LLVM setting in the product AOT
producer/verifier and both generic CLI compilation routes. This patch changes
the CLI routes; the first-party executor applies the same policy directly. Keep the existing
disable option accepted but hidden for caller compatibility; add no new knob.

This is an explicit correctness change AFTER the source-equivalent bundle
split in patches 0001-0008, not part of that equivalence claim. Producer and
verifier share one fixed configuration. Tests require nv0 deterministic
compiler identities and distinguish the previously relaxed nv1 identity.
The ordered patch digest changes runtime ABI/receipts; the changed compiler
binary changes the AOT cache root. Old compiled carriers must be rebuilt.

The strict LLVM policy is generally applicable to shared guest memory;
product compiler plumbing and receipt requirements are Oliphaunt-specific.
No performance win or fresh concurrent-runtime qualification is claimed here.

diff --git a/lib/cli/src/backend.rs b/lib/cli/src/backend.rs
index 17fe4c9..63c2144 100644
--- a/lib/cli/src/backend.rs
+++ b/lib/cli/src/backend.rs
@@ -170,11 +170,9 @@ pub struct RuntimeOptions {
#[clap(long = "enable-nan-canonicalization")]
enable_nan_canonicalization: bool,

- /// Disable LLVM non-volatile memory operations.
- ///
- /// Available for LLVM.
+ /// Deprecated compatibility option: this runtime always uses strict LLVM memory operations.
#[cfg(feature = "llvm")]
- #[clap(long = "disable-non-volatile-memops")]
+ #[clap(long = "disable-non-volatile-memops", hide = true)]
disable_non_volatile_memops: bool,

#[clap(flatten)]
@@ -480,9 +478,7 @@ impl RuntimeOptions {
use wasmer_compiler_llvm::LLVMCallbacks;
use wasmer_types::entity::EntityRef;
let mut config = LLVM::new();
- if !self.disable_non_volatile_memops {
- config.enable_non_volatile_memops();
- }
+ config.non_volatile_memops(false);
config.enable_readonly_funcref_table();

if let Some(num_threads) = self.compiler_threads {
@@ -631,9 +627,7 @@ impl BackendType {
use wasmer_types::entity::EntityRef;

let mut config = wasmer_compiler_llvm::LLVM::new();
- if !runtime_opts.disable_non_volatile_memops {
- config.enable_non_volatile_memops();
- }
+ config.non_volatile_memops(false);
config.enable_readonly_funcref_table();

let supported_features = config.supported_features_for_target(target);
@@ -751,3 +745,21 @@ impl std::fmt::Display for BackendType {
)
}
}
+
+#[cfg(all(test, feature = "llvm"))]
+mod tests {
+ use super::*;
+ use clap::Parser;
+
+ #[test]
+ fn llvm_cli_routes_use_strict_memory_identity() {
+ let target = Target::default();
+ for arguments in [vec!["wasmer"], vec!["wasmer", "--disable-non-volatile-memops"]] {
+ let options = RuntimeOptions::try_parse_from(arguments).unwrap();
+ let compiler = options.get_sys_compiler_config(&BackendType::LLVM).unwrap();
+ assert!(compiler.compiler().deterministic_id().contains("-nv0-"));
+ let engine = BackendType::LLVM.get_engine(&target, &options).unwrap();
+ assert!(engine.deterministic_id().contains("-nv0-"));
+ }
+ }
+}
1 change: 1 addition & 0 deletions src/wasix/postmaster/wasmer/patches/wasmer/series
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
0006-wasix-epoll-and-socket-readiness.patch
0007-wasix-instance-linker-and-sealed-runtime.patch
0008-postmaster-executor-and-build-closure.patch
0009-strict-shared-memory-compilation.patch
9 changes: 7 additions & 2 deletions src/wasix/postmaster/wasmer/tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,15 @@ run_tests \
-- \
memory_profile::wasm_tool::tests

# The product compiler must preserve main's policy and distinguish strict AOT.
# run_tests rejects an empty selection; both producer and generic CLI routes
# must bind artifacts to the strict compiler identity.
run_tests --locked --target-dir "$POSTMASTER_COMPILER_TARGET_DIR" \
--manifest-path "$FRESH_ROOT/executor/Cargo.toml" \
--package "$FRESH_POSTMASTER_EXECUTOR_PACKAGE" \
--bin "$FRESH_POSTMASTER_COMPILER_BINARY" \
--no-default-features --features "$FRESH_POSTMASTER_COMPILER_FEATURES" \
-- --exact product_compiler_uses_main_memory_identity
-- --exact product_compiler_uses_strict_memory_identity
run_tests --locked --target-dir "$WASMER_TARGET_DIR" \
--manifest-path "$WASMER_ROOT/lib/cli/Cargo.toml" --lib \
--no-default-features --features "$FRESH_WASMER_COMPILER_FEATURES" \
-- --exact backend::tests::llvm_cli_routes_use_strict_memory_identity
Loading
Loading