Skip to content
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

Investigate connection with top-level await #20

Closed
littledan opened this issue Oct 18, 2018 · 9 comments
Closed

Investigate connection with top-level await #20

littledan opened this issue Oct 18, 2018 · 9 comments

Comments

@littledan
Copy link
Collaborator

The proposal in #13 for WebAssembly/ESM integration is more or less to do a top-level await of WebAssembly.instantiateStreaming of the module, and this raises many of the same issues of asynchronous-ness during module evaluation that top-level await faces.

@MylesBorins has indicated that the current status of top-level await is to go with "variant B", which allows module siblings to proceed in parallel. Such ordering should be good for WebAssembly, in that it allows less waiting on compilation.

Two issues remain:

  • What changes need to be made in the ECMAScript specification to accommodate this asynchronous-ness? I don't think we need to block entirely on top-level await, but we'll need most of the underlying machinery.
  • If we go with parallel sibling execution, the execution of the WebAssembly "start function" could get out of order with respect to siblings (depending how long the prior steps of instantiation take for different siblings). Is this an issue? Should we provide additional synchronization here?
@xtuc
Copy link
Contributor

xtuc commented Oct 18, 2018

Wasm compilation will be done in parallel and the instantiation on the main thread (actually blocking it).

We need to make sure that the ordering is respected, given that compilation times are variables it will require a bit of bookeping, but the module graph will indicate the order.

Note that wasm modules with no dependencies can be instantiated (including the start func evaluation) in any order (we do this already in Webpack).

@littledan
Copy link
Collaborator Author

Note that wasm modules with no dependencies can be instantiated (including the start func evaluation) in any order (we do this already in Webpack).

This is a design question: Do we want to allow implementations to execute the start function in any order, or should this be deterministic based on the ordering of the imports that led to its use? ESM+HTML makes this deterministic for JS, I believe.

@xtuc
Copy link
Contributor

xtuc commented Oct 18, 2018

They SHOULD be deterministic and ordered, because they can cause side-effects. You can run any JS function during the start.

@littledan
Copy link
Collaborator Author

OK, if we do want to keep them well-ordered, then the actual requirement is a little more subtle: We should start instantiation as soon as the dependencies (which might export types) are available, and then execute the start function exactly in order, based on the same sibling ordering that JS modules have. This means we need a sort of synchronization barrier in the middle of the WebAssembly instantiation algorithm.

@sokra
Copy link

sokra commented Oct 21, 2018

We should start instantiation as soon as the dependencies (which might export types) are available

As the order of the dependencies is also defined the same way, this leads to no optimization:

- a.js
  - x.wasm
    - b.js
    - c.js
  - y.wasm
    - d.js
    - e.js

The execution order is:

b, c, x, d, e, y, a

The dependencies are exactly at the time available when execution should happen. You can't start instantiation earlier. You can't order the dependencies of wasm modules because they could have side-effects and their execution order is well defined.

There actually is an edgecase where you could start instantiation earlier, but that is very rare: All dependencies of the wasm module are referenced by some modules earlier in the graph, like this:

- a.js
  - d.js
  - e.js
  - x.wasm
    - b.js
    - c.js
  - y.wasm
    - d.js
    - e.js

d, e, (y instantiation), b, c, x, y start function, a

But this is too rare to make any difference.

=> When running instantiation while evaluation phase it will cause sequential instantiation of wasm modules. => Bad for performance

@littledan
Copy link
Collaborator Author

@sokra If we schedule the heavy parts of instantiation (chiefly, compilation) ahead of time, are you still worried about the startup time impact? Can you think of any benchmarks/simulations we could do to assess the impact now while we are in the design phase?

@xtuc
Copy link
Contributor

xtuc commented Oct 21, 2018

Downloading and compiling can be done at any time in any order because that isn't causing any side-effects.

Instantiation must respect the order, as said before.

@littledan
Copy link
Collaborator Author

Sounds like we are on the same page. In particular, the compilation work can be done ahead of time even in platforms that do that compilation as part of their instantiation API.

I think we all agree that startup should be fast, and just have different theories about how long this pause would be. What should be our next steps to getting data on this question?

@littledan
Copy link
Collaborator Author

The current specification is in terms of the top-level await proposal, so this issue can be closed.

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

No branches or pull requests

3 participants