From 3ae73f0671c70a35627fc9e0de6f77594412c0e1 Mon Sep 17 00:00:00 2001 From: alok-108 Date: Sun, 17 May 2026 03:11:00 +0530 Subject: [PATCH 01/11] Fix WASM memory allocation failure (#4989) This commit addresses the unbounded memory allocation issue on WASM targets that caused minimal programs (like  = 1) to fail with ~79MB allocation errors in constrained runtimes like wasmi. The fixes include: 1. Capping the max memory limit at 64MB and restricting stack size to 1MB via linker flags in .cargo/config.toml. 2. Reducing the minimum chunk size of the DataStack from 16KB to 4KB on WASM targets to shrink the initial memory footprint. 3. Adding a wasm-release profile in the root Cargo.toml optimized for size with opt-level = s, LTO enabled, and symbols stripped. --- .cargo/config.toml | 12 ++++++++++++ Cargo.toml | 8 ++++++++ crates/vm/src/datastack.rs | 4 ++++ 3 files changed, 24 insertions(+) diff --git a/.cargo/config.toml b/.cargo/config.toml index 635229119f8..b307d35eee9 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -6,3 +6,15 @@ rustflags = "-C link-args=-Wl,--stack,8000000" [target.wasm32-unknown-unknown] rustflags = ["--cfg=getrandom_backend=\"wasm_js\""] + +[target.wasm32-wasip1] +rustflags = [ + "-C", "link-arg=--max-memory=67108864", + "-C", "link-arg=-zstack-size=1048576", +] + +[target.wasm32-wasip2] +rustflags = [ + "-C", "link-arg=--max-memory=67108864", + "-C", "link-arg=-zstack-size=1048576", +] diff --git a/Cargo.toml b/Cargo.toml index a63656ebea7..c0ec19e0fa1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,6 +117,14 @@ opt-level = 3 [profile.release] lto = "thin" +[profile.wasm-release] +inherits = "release" +opt-level = "s" +lto = true +codegen-units = 1 +strip = true +panic = "abort" + [patch.crates-io] parking_lot_core = { git = "https://github.com/youknowone/parking_lot", branch = "rustpython" } # REDOX START, Uncomment when you want to compile/check with redoxer diff --git a/crates/vm/src/datastack.rs b/crates/vm/src/datastack.rs index f2ffb74894a..cacb9f7c9ed 100644 --- a/crates/vm/src/datastack.rs +++ b/crates/vm/src/datastack.rs @@ -9,6 +9,10 @@ use core::alloc::Layout; use core::ptr; /// Minimum chunk size in bytes (`_PY_DATA_STACK_CHUNK_SIZE`). +/// Smaller on WASM to reduce initial memory footprint. +#[cfg(target_arch = "wasm32")] +const MIN_CHUNK_SIZE: usize = 4 * 1024; +#[cfg(not(target_arch = "wasm32"))] const MIN_CHUNK_SIZE: usize = 16 * 1024; /// Extra headroom (in bytes) to avoid allocating a new chunk for the next From 09aba039be676d771d87802f7170289d1e45a29b Mon Sep 17 00:00:00 2001 From: alok-108 Date: Sun, 24 May 2026 03:29:01 +0530 Subject: [PATCH 02/11] Trigger CI rerun From 2808d1f03ca4fc808a90a5ea1c30d5b24f28a606 Mon Sep 17 00:00:00 2001 From: alok-108 Date: Sun, 24 May 2026 20:00:02 +0530 Subject: [PATCH 03/11] Address review feedback: add comments, use cfg! for MIN_CHUNK_SIZE --- .cargo/config.toml | 4 ++++ crates/vm/src/datastack.rs | 7 ++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index b307d35eee9..ceb8134791c 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -7,6 +7,10 @@ rustflags = "-C link-args=-Wl,--stack,8000000" [target.wasm32-unknown-unknown] rustflags = ["--cfg=getrandom_backend=\"wasm_js\""] +# Enforce a 64 MB memory cap and 1 MB stack limit for WASI targets. +# Without these, the WASM heap can grow unboundedly (e.g., a simple +# `a = 1` allocated ~79 MB) and crash on constrained runtimes like wasmi. +# See issue #4989. [target.wasm32-wasip1] rustflags = [ "-C", "link-arg=--max-memory=67108864", diff --git a/crates/vm/src/datastack.rs b/crates/vm/src/datastack.rs index cacb9f7c9ed..ed611557591 100644 --- a/crates/vm/src/datastack.rs +++ b/crates/vm/src/datastack.rs @@ -9,11 +9,8 @@ use core::alloc::Layout; use core::ptr; /// Minimum chunk size in bytes (`_PY_DATA_STACK_CHUNK_SIZE`). -/// Smaller on WASM to reduce initial memory footprint. -#[cfg(target_arch = "wasm32")] -const MIN_CHUNK_SIZE: usize = 4 * 1024; -#[cfg(not(target_arch = "wasm32"))] -const MIN_CHUNK_SIZE: usize = 16 * 1024; +/// Smaller on WASM (4 KB) to reduce initial memory footprint; 16 KB otherwise. +const MIN_CHUNK_SIZE: usize = if cfg!(target_arch = "wasm32") { 4 * 1024 } else { 16 * 1024 }; /// Extra headroom (in bytes) to avoid allocating a new chunk for the next /// frame right after growing. From f084abaae4969d8fe33c4290adf263a8534520a3 Mon Sep 17 00:00:00 2001 From: alok-108 Date: Sun, 24 May 2026 20:04:00 +0530 Subject: [PATCH 04/11] Remove duplicate MIN_CHUNK_SIZE definition From 2be338209e91ed4ed5c23cd8d27905739f25cbf2 Mon Sep 17 00:00:00 2001 From: alok-108 Date: Mon, 25 May 2026 21:26:15 +0530 Subject: [PATCH 05/11] Fix duplicate MIN_CHUNK_SIZE and format for prek lint --- crates/vm/src/datastack.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/vm/src/datastack.rs b/crates/vm/src/datastack.rs index ed611557591..7529263ac7e 100644 --- a/crates/vm/src/datastack.rs +++ b/crates/vm/src/datastack.rs @@ -10,7 +10,11 @@ use core::ptr; /// Minimum chunk size in bytes (`_PY_DATA_STACK_CHUNK_SIZE`). /// Smaller on WASM (4 KB) to reduce initial memory footprint; 16 KB otherwise. -const MIN_CHUNK_SIZE: usize = if cfg!(target_arch = "wasm32") { 4 * 1024 } else { 16 * 1024 }; +const MIN_CHUNK_SIZE: usize = if cfg!(target_arch = "wasm32") { + 4 * 1024 +} else { + 16 * 1024 +}; /// Extra headroom (in bytes) to avoid allocating a new chunk for the next /// frame right after growing. From 4c4f4eed7911eeed5ad7c3704d56258225dd7c05 Mon Sep 17 00:00:00 2001 From: alok-108 Date: Thu, 28 May 2026 00:36:53 +0530 Subject: [PATCH 06/11] Update CI to use wasm-release profile for WASM tests --- .github/workflows/ci.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 2a6a5264c21..5910ff18f0b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -790,11 +790,11 @@ jobs: clang: true - name: build rustpython - run: cargo build --release --target wasm32-wasip1 --no-default-features --features freeze-stdlib,stdlib,stdio,importlib,host_env --verbose + run: cargo build --profile wasm-release --target wasm32-wasip1 --no-default-features --features freeze-stdlib,stdlib,stdio,importlib,host_env --verbose - name: run snippets - run: wasmer run --dir "$(pwd)" target/wasm32-wasip1/release/rustpython.wasm -- "$(pwd)/extra_tests/snippets/stdlib_random.py" + run: wasmer run --dir "$(pwd)" target/wasm32-wasip1/wasm-release/rustpython.wasm -- "$(pwd)/extra_tests/snippets/stdlib_random.py" - name: run cpython unittest - run: wasmer run --dir "$(pwd)" target/wasm32-wasip1/release/rustpython.wasm -- "$(pwd)/Lib/test/test_int.py" + run: wasmer run --dir "$(pwd)" target/wasm32-wasip1/wasm-release/rustpython.wasm -- "$(pwd)/Lib/test/test_int.py" cargo_doc: needs: From 620f31ddb8c4849c28b7e265c918c40f95433b23 Mon Sep 17 00:00:00 2001 From: alok-108 Date: Thu, 28 May 2026 11:32:21 +0530 Subject: [PATCH 07/11] Remove leftover conflict markers From eeb0dadb87fce659655a5857c28db6272c08ceb5 Mon Sep 17 00:00:00 2001 From: alok-108 Date: Thu, 28 May 2026 11:36:52 +0530 Subject: [PATCH 08/11] Clean remaining conflict markers in CI workflow From 74b95a9030671acdce3acd5576b9b3eeb26cc55d Mon Sep 17 00:00:00 2001 From: alok-108 Date: Thu, 28 May 2026 11:40:09 +0530 Subject: [PATCH 09/11] Clean remaining conflict markers in CI workflow --- .github/workflows/ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5910ff18f0b..1da4cb1ba64 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -831,3 +831,4 @@ jobs: - name: cargo doc run: cargo doc --locked + From 407890cc3c5368df6d5d198f528bb8f819ec7368 Mon Sep 17 00:00:00 2001 From: alok-108 Date: Tue, 2 Jun 2026 18:47:41 +0530 Subject: [PATCH 10/11] Trigger CI to pick up new required check From d9245f72ac5b29af3f8c74015f5b3bdccf482dd6 Mon Sep 17 00:00:00 2001 From: alok-108 Date: Wed, 3 Jun 2026 00:47:13 +0530 Subject: [PATCH 11/11] Remove --max-memory flag, keep stack limit only --- .cargo/config.toml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index ceb8134791c..4e54d1d3b18 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -7,18 +7,15 @@ rustflags = "-C link-args=-Wl,--stack,8000000" [target.wasm32-unknown-unknown] rustflags = ["--cfg=getrandom_backend=\"wasm_js\""] -# Enforce a 64 MB memory cap and 1 MB stack limit for WASI targets. -# Without these, the WASM heap can grow unboundedly (e.g., a simple -# `a = 1` allocated ~79 MB) and crash on constrained runtimes like wasmi. -# See issue #4989. +# Enforce a 1 MB stack limit for WASI targets. +# (Runaway heap growth is fixed by the smaller DataStack chunk +# and the size‑optimized wasm‑release profile.) [target.wasm32-wasip1] rustflags = [ - "-C", "link-arg=--max-memory=67108864", "-C", "link-arg=-zstack-size=1048576", ] [target.wasm32-wasip2] rustflags = [ - "-C", "link-arg=--max-memory=67108864", "-C", "link-arg=-zstack-size=1048576", ]