Conversation
|
I tested this on a device and the premise was wrong. Rewritten. Android does not qualify for polkavm's compiler at all, and not because of SELinux — because of the platform gate itself. Measured on an API 35 x86_64 emulator, with a probe binary built against this branch and run on-device: 7.0 fps for a real SNES guest, which reproduces the field report of 7-10 fps on Android exactly. I then tried to make the compiler work by adding
That work belongs upstream in polkavm, and it needs validating on a real arm64 device under app-domain SELinux, not just an emulator shell. So this PR now contains only the part that survived: For Android speed the realistic path is the one iOS just took: hand the guest to the WASM translator and let the WebView's engine compile it. GeckoView is already in the Android app, and |
preferred_backend()hands the interpreter to wasm32, iOS and Android. Android does not belong in that list: polkavm's own gate (polkavm/src/lib.rs:9-17) enables the compiler forany(target_arch = "x86_64", target_arch = "aarch64")ontarget_os = "linux", and Android is aarch64 Linux. The only recorded justification is a line in epoca'sdocs/android-development-plan.mdstating JIT is unavailable — no ticket, no code comment, and no security rationale.What that costs, measured on this machine with the same guest (Supafaust) and the same ROM, changing nothing but the backend:
24.8x. The interpreter saturates a full desktop core to deliver 7.7 fps; a phone core is several times slower again. (Method: the pinned runtime rev was copied out of the cargo git cache with
preferred_backend()forced toInterpreter, patched into a native host build, measured, reverted.)Two changes:
preferred_backend()returnsInterpreterforwasm32andiosonly. iOS stays because polkavm's gate excludes it outright, quite apart from Apple's JIT policy.with_backend_fallback()wraps the four convenience constructors (Runtime::new,ApplicationRuntime::new,ComputerRuntime::new,ComputerSupervisor::new). Passing a compile-time platform gate is not the same as a device permitting writable-then-executable mappings — SELinux is the case this exists for — so a failed construction retries once on the interpreter and attaches the original failure as context. A slow guest beats a guest that will not start. The explicitnew_with_backendentry points are untouched, so callers that pin a backend still do.Verified:
cargo check -p polkavm-host-runtimeandcargo test -p polkavm-host-runtimepass, andcargo check -p polkavm-host-runtime --target aarch64-linux-androidcompiles clean with the compiler backend enabled.This needs a device to accept. The host already reports the active backend (
android.rsnativeBackend, surfaced byPvmProductView), so the check is: install, confirm the reported backend iscompiler, then run a framebuffer guest and confirm the frame rate moves. If a device's policy refuses executable mappings, the fallback should reportinterpreterand the guest should still run — that path deserves a look on a real device too, since I can only exercise it by construction failure here.No test asserts
preferred_backend() == Compiler; that would restate thecfgrather than defend behaviour.