-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
"Code for function is too large" error and 1.6GB Memory Spike during JIT compilation of a 781KB Kotlin/Wasm module
Environment:
- Wasmtime version: v40.0.0 (Release Release Wasmtime 40.0.0 #12192)
- Host Machine (Build): Mac M2 (aarch64)
- Target Device (Runtime): Android (aarch64)
- Compiler: Kotlin/Wasm (WASI) via
compileProductionExecutableKotlinWasmWasiOptimize - Project Link: crowforkotlin/wasmline
- Source File: Plugin.kt
Description:
I am reporting a Compilation error: Code for function is too large that occurs during the JIT loading phase on Android.
Despite the generated .wasm binary being only 781.63 KB, the compilation fails when a single Kotlin function contains a large amount of logic/content. During the attempt to compile this module, I observed a massive RSS memory spike on the Android device, jumping from ~235 MB to over 1.6 GB in just 4 seconds, eventually resulting in the "function too large" error.
Wasmtime Configuration:
The engine is configured specifically for Android compatibility to avoid signal conflicts with ART and minimize VSS overhead:
/**
* Creates and configures the Wasm Config object.
*
* Critical Android Settings:
* 1. Signals-based traps DISABLED: To prevent conflicts with Android ART signal handlers (SIGSEGV).
* 2. Memory Guard Size = 0: To prevent VSS (Virtual Set Size) OOM on 32-bit or limited devices.
* 3. GC / Exceptions: Enabled for Kotlin/Wasm support.
*/
wasm_config_t *Engine::createConfig() {
wasm_config_t *conf = wasm_config_new();
// Feature Flags for Kotlin/Wasm support
wasmtime_config_wasm_gc_set(conf, true);
wasmtime_config_wasm_function_references_set(conf, true);
wasmtime_config_wasm_exceptions_set(conf, true);
// Optimization: Disable SIMD if not strictly needed (improves compatibility)
wasmtime_config_wasm_simd_set(conf, false);
wasmtime_config_wasm_relaxed_simd_set(conf, false);
// [CRITICAL] Disable signal handlers to avoid crash conflicts with Android Runtime (ART)
wasmtime_config_signals_based_traps_set(conf, false);
// [CRITICAL] Set guard pages to 0 to minimize Virtual Memory usage (prevents OOM)
wasmtime_config_memory_guard_size_set(conf, 0);
// Set max stack size (512KB is usually sufficient for mobile logic)
wasmtime_config_max_wasm_stack_set(conf, 512 * 1024);
// Compiler Optimization Strategy: Optimize for Speed and Binary Size
wasmtime_config_cranelift_opt_level_set(conf, WASMTIME_OPT_LEVEL_SPEED_AND_SIZE);
wasmtime_config_cranelift_debug_verifier_set(conf, false);
return conf;
}Reproduction Steps:
- Add a large amount of content/logic into the
wasmWasiMainfunction inPlugin.kt. - Build the wasm file:
./gradlew wasmtime-core:plugin:compileProductionExecutableKotlinWasmWasiOptimize. - The resulting
plugin.wasmis ~781 KB. - Load the module on an Android device using the configuration above.
Observed Behavior:
- Total Wasm Size: 781.63 KB (Small)
- Memory Usage: Spikes from 234MB to 1.6GB.
- Result:
Compilation error: Code for function is too large.
Full Android Logs:
00:49:34.204 I [MotionEvent] ViewRootImpl windowName 'crow.wasmtime.wasmline/crow.mordecai.wasmline.MainActivity', { action=ACTION_DOWN, id[0]=0, pointerCount=1, eventTime=51746485, downTime=51746485, phoneEventTime=00:49:34.191 } moveCount:0
00:49:34.206 D getMiuiFreeformStackInfo mTmpFrames.miuiFreeFormStackInfo: null
00:49:34.217 I CreateGraphicsPipeline pipeline cache hit. elpased time: 0.32 ms.
00:49:34.218 E FrameInsert open fail: No such file or directory
00:49:34.230 I This is non sticky GC, maxfree is 33554432 minfree is 8388608
00:49:34.227 W type=1400 audit(0.0:2008818): avc: denied { getopt } for path="/dev/socket/usap_pool_primary" scontext=u:r:untrusted_app:s0:c190,c257,c512,c768 tcontext=u:r:zygote:s0 tclass=unix_stream_socket permissive=0 app=crow.wasmtime.wasmline
00:49:34.322 I [MotionEvent] ViewRootImpl windowName 'crow.wasmtime.wasmline/crow.mordecai.wasmline.MainActivity', { action=ACTION_UP, id[0]=0, pointerCount=1, eventTime=51746611, downTime=51746485, phoneEventTime=00:49:34.316 } moveCount:0
00:49:34.332 I ==============================================
00:49:34.337 I [Android] Wasm file : plugin.wasm || wasm file exits : true || wasm file path : /data/user/0/crow.wasmtime.wasmline/cache/plugin.wasm
00:49:34.338 I [Android] Cwasm cache file : plugin.cwasm || cache file exits : false || cache file path : /data/user/0/crow.wasmtime.wasmline/cache/plugin.cwasm
00:49:34.345 I [Wasmtime] Module --> Jit Compiling for /data/user/0/crow.wasmtime.wasmline/cache/plugin.wasm...
00:49:34.363 W type=1400 audit(0.0:2008819): avc: denied { read } for name="cpu.cfs_quota_us" dev="cgroup" ino=64 scontext=u:r:untrusted_app:s0:c190,c257,c512,c768 tcontext=u:object_r:cgroup:s0 tclass=file permissive=0 app=crow.wasmtime.wasmline
00:49:34.363 W type=1400 audit(0.0:2008820): avc: denied { read } for name="cpu.cfs_period_us" dev="cgroup" ino=65 scontext=u:r:untrusted_app:s0:c190,c257,c512,c768 tcontext=u:object_r:cgroup:s0 tclass=file permissive=0 app=crow.wasmtime.wasmline
00:49:34.363 W type=1400 audit(0.0:2008821): avc: denied { read } for name="cpu.cfs_quota_us" dev="cgroup" ino=10 scontext=u:r:untrusted_app:s0:c190,c257,c512,c768 tcontext=u:object_r:cgroup:s0 tclass=file permissive=0 app=crow.wasmtime.wasmline
00:49:34.363 W type=1400 audit(0.0:2008822): avc: denied { read } for name="cpu.cfs_period_us" dev="cgroup" ino=11 scontext=u:r:untrusted_app:s0:c190,c257,c512,c768 tcontext=u:object_r:cgroup:s0 tclass=file permissive=0 app=crow.wasmtime.wasmline
00:49:34.441 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 234952kb -> 342100kb
00:49:34.494 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 342100kb -> 428844kb
00:49:34.544 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 428844kb -> 541612kb
00:49:34.602 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 541612kb -> 657240kb
00:49:34.928 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 657240kb -> 860432kb
00:49:35.761 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 860432kb -> 959324kb
00:49:36.012 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 959324kb -> 1075892kb
00:49:36.184 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 1075892kb -> 1183820kb
00:49:37.835 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 1183820kb -> 1306888kb
00:49:38.482 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 1306888kb -> 1450064kb
00:49:38.639 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 1450064kb -> 1612484kb
00:49:38.700 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 1612484kb -> 1389664kb
00:49:38.700 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 1389664kb -> 1011816kb
00:49:38.702 E [Wasmtime] Module --> Error loading module /data/user/0/crow.wasmtime.wasmline/cache/plugin.wasm: Compilation error: Code for function is too large
00:49:38.708 I [Wasmline] Load failure, because native load return false, file path is : /data/user/0/crow.wasmtime.wasmline/cache/plugin.wasm
00:49:38.790 E ->pid:19641,processName:"crow.wasmtime.wasmline",Rss Memory Size Change 1011816kb -> 727648kb
Artifacts:
Wasmline-wasmline-core-plugin.wasm.zip
Analysis & Questions:
- Why does a relatively small Wasm file (under 1MB) trigger a "Code too large" error? It seems the Kotlin/Wasm compiler is generating a single function with extremely high complexity.
- The memory usage spike to 1.6GB suggests that Cranelift might be hitting a worst-case scenario in its e-graph optimization or register allocation phase.
- Are there any specific Cranelift settings to mitigate this, or is this a fundamental limit on function complexity regardless of the total
.wasmfile size?


