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
Wasm async compilation #4867
Wasm async compilation #4867
Conversation
(first commit is from the dependency PR, second is the new stuff) |
Why keep the synchronous compilation in O0 and allow turning it off at all? |
Synchronous compilation is useful in some use cases, e.g. a library like ammo or box2d, especially if it's small, might not want users to need an async step before it is ready. Also, an option to turn it off can help debugging in some cases. Regarding -O0, we do need async on in all release modes because of what the browser people said in that design issue. So that forces us on -O1+. Perhaps we could also enable it in -O0, but it is an optimization, so makes sense not to. Another reason is it ties into existing precedent, where for asm.js -O0 is synchronous now, while optimized modes are not due to the mem init file (which we load with an xhr) - so this keeps us close to how things currently work, less surprises for people. |
Added a commit that enables async only in wasm-only mode. I realized while talking to @juj about debugging wasm/asm.js differences that a build that can run as asm.js as well (i.e. not wasm-only) shouldn't be compiled asynchronously (for one thing it's a difference that is confusing, for another, the asm.js xhr for the mem init file, if used, can race with this async step - fixable, but maybe not worth it). |
#4859 LGTM, if you can rebase this I'll take a look today. |
Rebased after the required PR landed. |
OK, so again just to make sure I understand: So I guess a question then: Why have the indirection shims? Why not make all the |
Yes, in
So it looks up the asm property on each call, which allows it to be replaced over time. In async mode, we set
specifically what does "that" refer to? I might be missing what you're asking here. The reason for the indirection is that the exports can be captured synchronously:
So we need to provide a capture-able thing immediately. It's not valid to call it until the runtime is set up, which may be asynchronous for various reasons - filesystem loading, mem init file, or wasm async compilation. Wasm async compilation is trickier than the others because we don't have the exports themselves yet, so we need the indirection for it. In the future if the indirection adds overhead we can investigate adding a new compilation mode, in which it is not ok to capture the exports immediately. But that would be a breaking change, so we'd need to do it carefully. |
Testing this in chrome (latest dev on linux), the async promise returns an instance, instead of an object containing an instance property as firefox does. I think that might have been what an older spec said. Maybe fixed on canary already? |
By "that" I meant that Also ok, I hadn't thought about capturing synchronously and then calling later. Do you have a sense of whether that's the common practice, or if it's more common to just call directly like Wrt what the promise returns: I don't know, I haven't tested that. I'll see if I can find out. |
The function gets called right in between the preamble and postamble, which is right after all the JS imports are ready. We then instantiate the asm.js/wasm module by calling that function (with the imports as a param). Might be confusing that we use Module.asm both for that function and for the output from it later, now that I think of it. Perhaps worth refactoring later, but I'm not sure offhand what that would entail.
Not sure. For things like a game engine, usually nothing is captured anyhow (main is called automatically and that's it). For something like a library though, like ammo.js or box2d, then definitely there is plenty of capturing. But how common libraries are, I'm not sure.
Hmm, possible in theory, but it means we create a difference between the two cases. That seems like a risk for bugs/confusion. |
Also it seems V8's implementation of |
How would the difference even be observable? Would people be comparing their capture |
Should we wait to land this on chromium fixing instantiate? Otherwise stuff won't work in it. The difference might be observable if someone swaps The advantage is avoiding the wrapper overhead, but that is achievable otherwise (e.g. the user can grab |
... except that V8 should be fixed with https://codereview.chromium.org/2644993002/. I think it needs to get merged onto some branch but it should end up on Canary in a day or 2. |
Yeah, it's true Thanks for the v8 update. Ok, seems like there is no rush here anyhow, let's wait a while before landing this. Also it seems there is still spec discussion on it, maybe things will change? |
(That issue is now closed.) If there were to be a change, at most it would be a renaming, but that also seems unlikely given that both V8/SM have landed |
@dschuff, do you know if now is ok to land this? (no chrome canary on linux, so i can't test if those fixes landed) |
This should be good to go; verified locally with d8 on trunk and 5.7.492 branch (https://omahaproxy.appspot.com/ tells me those are rolled in) |
Ok, thanks. Then the last blocker here is confirmation from @juj about the bots having wasm turned on, as the new tests here require that. |
if shared.Settings.BINARYEN_ASYNC_COMPILATION == 1: | ||
if shared.Building.is_wasm_only(): | ||
# async compilation requires a swappable module - we swap it in when it's ready | ||
shared.Settings.SWAPPABLE_ASM_MODULE = 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not clear from this limited slice of context, but is there something somewhere explaining in more detail what SWAPPABLE_ASM_MODULE means?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a little detail in src/settings.js
where the setting is defined. I improved it now.
Ok, after discussion with @juj, let's land this. We don't cover it properly on the bots yet, we'll fix that next week probably, til then we can just ignore these tests on the bots (but they pass when running the suite locally, which is already helpful). |
This builds on #4859 (and must wait for it to land) to implement async compilation using
WebAssembly.instantiate
. As discussed in the design repo, this is enabled by default in all recommended compilation modes (everything but-O0
, and it can be manually flipped off but no one should do that).As also discussed in the design repo, this works around the problems with doing async compilation (see details there) by wrapping the exports in an indirection layer. We already had one lying around,
SWAPPABLE_ASM_MODULE
, so this PR reuses that. Basically, all calls to exports callModule.asm.*
, so that theasm
part can be replaced. Here we start with nothing, and replace it with the compiled module when it arrives. This adds overhead when calling exports, but the hope is that it isn't too bad.@juj, the tests here require that bots have wasm enabled in the browser test suite, let me know if that's ok.