Stream: git-wasmtime

Topic: wasmtime / issue #9868 Investigate shrinking code size by...


view this post on Zulip Wasmtime GitHub notifications bot (Dec 19 2024 at 18:03):

fitzgen added the wasmtime:code-size label to Issue #9868.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 19 2024 at 18:03):

fitzgen opened issue #9868:

We suspect error strings are a major code size offender, and revamping wasmtime::Error to optionally (based on compile-time features) contain just error codes, instead of full strings, could improve code size.

And then for regular Wasmtime CLI builds, we would probably want something like

$ wasmtime --explain 1234
Error 1234: <one-line explanation>

<paragraph with more detail, if applicable>

Apparently the defmt and/or pw_tokenizer crates could be helpful here, although I have no experience with either of them.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 19 2024 at 19:49):

bjorn3 commented on issue #9868:

For me CARGO_PROFILE_RELEASE_OPT_LEVEL=s CARGO_PROFILE_RELEASE_LTO=fat CARGO_PROFILE_RELEASE_STRIP=symbols CARGO_PROFILE_RELEASE_PANIC=abort cargo build -p wasmtime-c-api --release --no-default-features --features disable-logging produces a 955kb dylib on x86_64-unknown-linux-gnu. Of this the total rodata size is just a little over 60kb. This is the upper bound on the size of the error messages.

With panic_immediate_abort (CARGO_PROFILE_RELEASE_OPT_LEVEL=s CARGO_PROFILE_RELEASE_LTO=fat CARGO_PROFILE_RELEASE_STRIP=symbols CARGO_PROFILE_RELEASE_PANIC=abort RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -p wasmtime-c-api --release --no-default-features --features disable-logging -Z build-std=std,panic_abort --target x86_64-unknown-linux-gnu -Z build-std-features=panic_immediate_abort) the dylib is 531kb with only 34kb in rodata.

A quick look through the contents of the .rodata section shows that with panic_immediate_abort maybe half are error messages. A significant part of this however are not coming from wasmtime::Error but rather from various eprintln!() by wasmtime-c-api for unimplemented things, the crash message of the signal handler, various aborts in the internals of wasmtime, error messages produced by postcard, context messages for anyhow and things like that. As for the other half that are not error messages, they are things like cranelift flag names, names of libcalls and a whole lot of non-string data.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 19 2024 at 19:51):

bjorn3 commented on issue #9868:

By the way there is currently more space taken up by relocations (.rela.dyn) than .rodata and the actual code takes up 77% of the binary, there are probably bigger things to worry about than error messages.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 20 2024 at 22:29):

hanna-kruppe commented on issue #9868:

The actual strings don't seem to be significant from those numbers. What might be more relevant use is heavy use of std::fmt and anyhow::Error, both of which create a whole lot of code in .text and (for PIC) relocations. It's difficult to estimate how much of a difference it makes without doing the hard work of switching over, but I've seen its traces often enough while digging through compiler output. Some specific points:

As higher-level anecdata: I have a (non-public) project where I recently replaced all uses of anyhow::Error with a mostly API-compatible error type that only stores a String internally, converts other error types to their Display outcome (never Debug), and doesn't support downcasting. Despite still using std::fmt to some extent, this change alone saved about 80 KiB from an opt-level=s, lto=true, stripped binary on x86_64-unknown-linux-gnu.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 20 2024 at 23:33):

hanna-kruppe edited a comment on issue #9868:

The actual strings don't seem to be significant from those numbers. What might be more relevant use is heavy use of std::fmt and anyhow::Error, both of which create a whole lot of code in .text and (for PIC) relocations. It's difficult to estimate how much of a difference it makes without doing the hard work of switching over, but I've seen its traces often enough while digging through compiler output. Some specific points:

As higher-level anecdata: I have a (non-public) project where I recently replaced all uses of anyhow::Error with a mostly API-compatible error type that only stores a String and a cause (recursively) internally, converts other error types to their Display outcome (never Debug), and doesn't support downcasting or backtracks. Despite still using std::fmt to some extent, this change alone saved about 80 KiB from an opt-level=s, lto=true, stripped binary on x86_64-unknown-linux-gnu.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 20 2024 at 23:33):

hanna-kruppe edited a comment on issue #9868:

The actual strings don't seem to be significant from those numbers. What might be more relevant use is heavy use of std::fmt and anyhow::Error, both of which create a whole lot of code in .text and (for PIC) relocations. It's difficult to estimate how much of a difference it makes without doing the hard work of switching over, but I've seen its traces often enough while digging through compiler output. Some specific points:

As higher-level anecdata: I have a (non-public) project where I recently replaced all uses of anyhow::Error with a mostly API-compatible error type that only stores a String and a cause (recursively) internally, converts other error types to their Display outcome (never Debug), and doesn't support downcasting or backtraces. Despite still using std::fmt to some extent, this change alone saved about 80 KiB from an opt-level=s, lto=true, stripped binary on x86_64-unknown-linux-gnu.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 21 2024 at 12:39):

hanna-kruppe edited a comment on issue #9868:

The actual strings don't seem to be significant from those numbers. What might be more relevant use is heavy use of std::fmt and anyhow::Error, both of which create a whole lot of code in .text and (for PIC) relocations. It's difficult to estimate how much of a difference it makes without doing the hard work of switching over, but I've seen its traces often enough while digging through compiler output. Some specific points:

As higher-level anecdata: I have a (non-public) project where I recently replaced all uses of anyhow::Error with a mostly API-compatible error type that only stores a String and a cause (recursively) internally, converts other error types to their Display outcome (never Debug), and doesn't support downcasting or backtraces. Despite still using std::fmt to some extent, this change alone saved about 80 KiB from an opt-level=s, lto=true, stripped binary on x86_64-unknown-linux-gnu.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 21 2024 at 18:53):

kornelski commented on issue #9868:

-Zfmt-debug=none may help remove code and strings used by fmt::Debug.


Last updated: Dec 23 2024 at 12:05 UTC