Skip to content

Wasm-friendly implementation of varargs. #5215

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

sjrd
Copy link
Member

@sjrd sjrd commented Jul 26, 2025

For JavaScript, using Scala arrays wrapped in WrappedArray (2.12) or ArraySeq (2.13) is not ideal for performance. Instead, since about forever, we have re-emitted them as JS arrays wrapped in our own js.WrappedArray/WrappedVarArgs. This, however, has poor performance on Wasm.

We now call generic methods to choose the best implementation of a varargs Seq, depending on the platform. They take Scala arrays, and "convert" them to JS arrays if necessary. The conversions are intrinsified so that they are zero-cost.

For this to work, we add an InlineArrayReplacement in the optimizer, similar to the existing InlineJSArrayReplacement.

@sjrd
Copy link
Member Author

sjrd commented Jul 26, 2025

@tanishiking Could you check that this PR achieves the same performance improvements on Wasm that you have measured before?

For JS, the resulting code is basically not affected. (there are more intermediate variables in non-minify, but they are removed in minify mode)

@tanishiking
Copy link
Contributor

Sure! It looks this makes Wasm varargs faster without de-optimizing JS 👍

fastopt 1.19.0 JS 1.20.0-SNAPSHOT JS 1.19.0 Wasm 1.20.0-SNAPSHOT Wasm
Varargs.Call_0_Args 540.86 558.65 1444.62 1495.60
Varargs.Call_1_Arg 2081.17 2085.40 6805.43 3861.56
Varargs.Call_5_Args 3189.43 3115.38 13857.60 6174.55

For JavaScript, using Scala arrays wrapped in `WrappedArray` (2.12)
or `ArraySeq` (2.13) is not ideal for performance. Instead, since
about forever, we have re-emitted them as JS arrays wrapped in our
own `js.WrappedArray`/`WrappedVarArgs`. This, however, has poor
performance on Wasm.

We now call generic methods to choose the best implementation of
a varargs Seq, depending on the platform. They take Scala arrays,
and "convert" them to JS arrays if necessary. The conversions are
intrinsified so that they are zero-cost.

For this to work, we add an `InlineArrayReplacement` in the
optimizer, similar to the existing `InlineJSArrayReplacement`.

These changes revert the `toString()` of varargs seqs to what it
is on the JVM, but only on Wasm. This breaks three partests, for
which we had checkfiles with the Scala.js-specific strings. We
extend our `partest` fork to recognize platform-specific
checkfiles in order to fix this issue.
@sjrd sjrd force-pushed the wasm-friendly-varargs branch from 8c8cb84 to e7fb94b Compare July 28, 2025 12:45
@sjrd sjrd requested a review from gzm0 July 28, 2025 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants