Skip to content

Conversation

@kripken
Copy link
Member

@kripken kripken commented Nov 1, 2018

This new pass minifies import and export names, for example, this may minify

   (import "env" "longname" (func $internal))

to

   (import "env" "a" (func $internal))

By updating the JS that provides those imports/calls those exports, we can use the minified names properly. This can save a useful amount of space in the wasm and JS, see emscripten-core/emscripten#7414

// number of symbols, which is not realistic anyhow.
reserved.insert("do");
reserved.insert("if");
reserved.insert("in");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @kripken. Shouldn't this also reserve null, eval and true keywords?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yeah, the list is incomplete - I just copied it from the emscripten js minifier code. Which is incomplete too I guess ;)

I think in practice, to get to 4 letters is very unlikely. With three letters you can get to 221,184 minified ids. But, would be worth adding the rest of the words too, I agree.

kripken added a commit to emscripten-core/emscripten that referenced this pull request Nov 2, 2018
For background see #7414

This uses a new binaryen pass WebAssembly/binaryen#1719 to minify the import and export names in wasm, and then updates them in JS too. These are things that closure and other minfiers cannot minify themselves since they are on the js/wasm boundary, so it's up to us.

This is kind of related to metadce, which also optimizes stuff on that js/wasm boundary. metadce finds things that can be removed entirely, while this new operation minifies the names of what remains.

Turns out this is pretty useful, if you have lots of imports or exports. On BananaBread there are lots of GL calls, and we save 10% of JS size and 1% of wasm size. On Bullet we wrap classes for JS, which means calls to lots of functions, and we save 16% of JS size and 8% of wasm size. Much more than I expected!

Some other minor fixes in this PR:

* The emterpreter had some hacky way to add the extra globals it needs. Moved those to the proper place. This did require disabling a tiny part of the current test for the emterpreter (asm.js validation of raw emterpreter output, before integration back into the emscripten output), but that's not that important now - it was more useful when bringing it up initially.
* Fix embind usage of dynamic dyncalls - they are on the Module object, we should not access Module.asm directly.
* For CI testing this uses a temp tag in the binaryen port. Before landing we should tag binaryen and update that.
reserved.insert("enum");
reserved.insert("void");
reserved.insert("this");
reserved.insert("void");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

void appears twice (not that it matters)

Beuc pushed a commit to Beuc/emscripten that referenced this pull request Nov 17, 2018
For background see emscripten-core#7414

This uses a new binaryen pass WebAssembly/binaryen#1719 to minify the import and export names in wasm, and then updates them in JS too. These are things that closure and other minfiers cannot minify themselves since they are on the js/wasm boundary, so it's up to us.

This is kind of related to metadce, which also optimizes stuff on that js/wasm boundary. metadce finds things that can be removed entirely, while this new operation minifies the names of what remains.

Turns out this is pretty useful, if you have lots of imports or exports. On BananaBread there are lots of GL calls, and we save 10% of JS size and 1% of wasm size. On Bullet we wrap classes for JS, which means calls to lots of functions, and we save 16% of JS size and 8% of wasm size. Much more than I expected!

Some other minor fixes in this PR:

* The emterpreter had some hacky way to add the extra globals it needs. Moved those to the proper place. This did require disabling a tiny part of the current test for the emterpreter (asm.js validation of raw emterpreter output, before integration back into the emscripten output), but that's not that important now - it was more useful when bringing it up initially.
* Fix embind usage of dynamic dyncalls - they are on the Module object, we should not access Module.asm directly.
* For CI testing this uses a temp tag in the binaryen port. Before landing we should tag binaryen and update that.
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.

4 participants