Conversation
jgravelle-google
approved these changes
Oct 23, 2019
kripken
added a commit
to emscripten-core/emscripten
that referenced
this pull request
Oct 25, 2019
This adds emscripten_lazy_load_code(), a function that when called will block (using Asyncify) and load the complete program. This lets the initial download not contain code that can be proven to be used only after those calls. How this works is we emit the initial downloaded wasm after modifying it with Binaryen to assume that those calls will not rewind, as we only unwind using that binary (the optimizer can then remove a lot of code). We also emit the later downloaded wasm, optimized the other way, to assume we only rewind but never unwind. These transforms are done using ModAsyncify passes from Binaryen WebAssembly/binaryen#2404 A new option ASYNCIFY_LAZY_LOAD_CODE is necessary to use this (as well as ASYNCIFY itself). The test shows an example where the initial download is less than half the size of the later download. Note that in this model we do download some code twice (the later download contains the code in the initial one), and we do add some code size due to Asyncify support. So this will not be an obvious win for every codebase. But if the later download contains unlikely code that may never be used, and there is a lot of such code, and we can ignore indirect calls for Asyncify's purposes, then the win can be significant.
5 tasks
belraquib
pushed a commit
to belraquib/emscripten
that referenced
this pull request
Dec 23, 2020
This adds emscripten_lazy_load_code(), a function that when called will block (using Asyncify) and load the complete program. This lets the initial download not contain code that can be proven to be used only after those calls. How this works is we emit the initial downloaded wasm after modifying it with Binaryen to assume that those calls will not rewind, as we only unwind using that binary (the optimizer can then remove a lot of code). We also emit the later downloaded wasm, optimized the other way, to assume we only rewind but never unwind. These transforms are done using ModAsyncify passes from Binaryen WebAssembly/binaryen#2404 A new option ASYNCIFY_LAZY_LOAD_CODE is necessary to use this (as well as ASYNCIFY itself). The test shows an example where the initial download is less than half the size of the later download. Note that in this model we do download some code twice (the later download contains the code in the initial one), and we do add some code size due to Asyncify support. So this will not be an obvious win for every codebase. But if the later download contains unlikely code that may never be used, and there is a lot of such code, and we can ignore indirect calls for Asyncify's purposes, then the win can be significant.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
These passes are meant to be run after Asyncify has been run, they modify the output. We can assume that we will always unwind if we reach an import, or that we will never unwind, etc.
This is meant to help with lazy code loading, that is, the ability for an initially-downloaded wasm to not contain all the code, and if code not present there is called, we download all the rest and continue with that. That could work something like this:
(Optionally, there could also be a third wasm, which has not had Asyncify run on it, and which we'd swap to for max speed.)
This requires some runtime code to load the second wasm etc., which for Emscripten I'll implement in a PR there, but in principle this could be used in other runtimes too, just like Asyncify itself.
This replaces #2348 , but renames
PostAsyncifytoModAsyncify.