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

Allow certain ES6 constructs in internal JS code #15763

Merged
merged 1 commit into from
Dec 18, 2021
Merged

Conversation

sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Dec 13, 2021

With this change we allow these features by default. If a user
explicitly opts into older browser support we trigger the running
of closure compiler with --language_out ES5 --compilation_level WHITESPACE_ONLY.

For most users this will be a code size win, but otherwise a no-op.

For users who need older browser support they will now have their
output run though closure by default. If they want to take a care
of the transpilaion process themselves rather than have emscripten
to it auto-magically they can run with --closure=0.

When we auto-magically run closure to do transpilation we generate
a warning. This warning can be suppressed by add --closure=1 to
explicitly opt in, or --closure=0 to explicitly opt out.

This change in does not actually include any usage of these features
and so don't include the code size benefits. Those will be part of
followup PRs: #15764 #15765 #15758

Fixes: #11984

@sbc100 sbc100 changed the title Allow let, const and => (arrow functions) in internal JS code [WIP] Allow certain ES6 constructs in internal JS code Dec 13, 2021
@sbc100 sbc100 force-pushed the closure_transpile_only branch from d743ca4 to adc04c2 Compare December 13, 2021 19:58
sbc100 added a commit that referenced this pull request Dec 13, 2021
This a followup to #15763 which actually starts to use
some ES6 features in our core library code.

This change is designed to demonstrate that code size
wins that we can get from ES6 usage.

See: #11984
sbc100 added a commit that referenced this pull request Dec 13, 2021
This a followup to #15763 which actually starts to use
some ES6 features in our core library code.

This change is designed to demonstrate that code size
wins that we can get from ES6 usage.

See: #11984
@sbc100 sbc100 changed the title [WIP] Allow certain ES6 constructs in internal JS code Allow certain ES6 constructs in internal JS code Dec 13, 2021
@sbc100 sbc100 requested a review from kripken December 13, 2021 20:15
@sbc100 sbc100 force-pushed the closure_transpile_only branch 3 times, most recently from 99827f4 to 0346d1c Compare December 13, 2021 21:09
@sbc100 sbc100 force-pushed the closure_transpile_only branch 3 times, most recently from 2518eee to 3213444 Compare December 14, 2021 02:05
sbc100 added a commit that referenced this pull request Dec 14, 2021
I ran into this issue when working on #15763.  We have code interally
that converts `=-1` to `=0x7FFFFFFF` for the MIN_XX_VERSION settings.
However, this was then being interpreted interally as a string.  When
read from JS there is no differenence but from python code the value of
this setting would appear as the string "0x7FFFFFFF" and not the number
0x7FFFFFFF.
sbc100 added a commit that referenced this pull request Dec 14, 2021
I ran into this issue when working on #15763.  We have code interally
that converts `=-1` to `=0x7FFFFFFF` for the MIN_XX_VERSION settings.
However, this was then being interpreted interally as a string.  When
read from JS there is no differenence but from python code the value of
this setting would appear as the string "0x7FFFFFFF" and not the number
0x7FFFFFFF.
Base automatically changed from refactor_closure to main December 14, 2021 05:31
sbc100 added a commit that referenced this pull request Dec 14, 2021
I ran into this issue when working on #15763.  We have code interally
that converts `=-1` to `=0x7FFFFFFF` for the MIN_XX_VERSION settings.
However, this was then being interpreted interally as a string.  When
read from JS there is no differenence but from python code the value of
this setting would appear as the string "0x7FFFFFFF" and not the number
0x7FFFFFFF.
@sbc100 sbc100 force-pushed the closure_transpile_only branch from 3213444 to af6ba01 Compare December 14, 2021 06:40
@sbc100 sbc100 changed the base branch from main to hex_settings December 14, 2021 06:41
sbc100 added a commit that referenced this pull request Dec 14, 2021
This a followup to #15763 which actually starts to use
some ES6 features in our core library code.

This change is designed to demonstrate that code size
wins that we can get from ES6 usage.

See: #11984
Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

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

I had some comments about using closure here (speed etc.), but I don't see them here. Was that in another PR? Is this the right one to discuss closure in?

Base automatically changed from hex_settings to main December 14, 2021 20:27
sbc100 added a commit that referenced this pull request Dec 14, 2021
I ran into this issue when working on #15763.  We have code interally
that converts `=-1` to `=0x7FFFFFFF` for the MIN_XX_VERSION settings.
However, this was then being interpreted interally as a string.  When
read from JS there is no differenence but from python code the value of
this setting would appear as the string "0x7FFFFFFF" and not the number
0x7FFFFFFF.
@sbc100 sbc100 force-pushed the closure_transpile_only branch from af6ba01 to 1a9d0b5 Compare December 15, 2021 01:47
@sbc100
Copy link
Collaborator Author

sbc100 commented Dec 15, 2021

I had some comments about using closure here (speed etc.), but I don't see them here. Was that in another PR? Is this the right one to discuss closure in?

Your question about performace was in the followup PR: #15764 (review), but this is the right issue in which to discuss since this is PR which will start enabling it by default for those that target older browsers.

I will do some measurements.

@sbc100
Copy link
Collaborator Author

sbc100 commented Dec 15, 2021

I measured the performance of emcc with -sINCLUDE_FULL_LIBRARY which is think represents the about the worst case. In this mode emcc will generate a raw JS output file which is around 1Mb in size.

Without measured the performance of using emcc as linker in 3 modes. The base case of emcc -s INCLUDE_FULL_LIBRARY hello.o (where hello.o is the pre-compiled object form of the hello world program. The full closure case (with --closure=1) and the transpile-only case (with -sMIN_CHROME_VERSION=10). I ran each version 3 times.

  • base case: 672ms 648ms 668ms.
  • full closure: 4.177s 4.297s 4.270s (~7x slowdown over base)
  • transpile only: 1.828s 1.725s 1.806s (~3x slowdown over base)

So, in general I think is safe to say that transpiling is less have have the cost of full closure. These are also the absolute worse case.. its hard to imagine real project using INCLUDE_FULL_LIBRARY or otherwise including a 1Mb of JS.

@sbc100 sbc100 requested a review from kripken December 15, 2021 02:04
sbc100 added a commit that referenced this pull request Dec 15, 2021
This a followup to #15763 which actually starts to use
some ES6 features in our core library code.

This change is designed to demonstrate that code size
wins that we can get from ES6 usage.

See: #11984
@sbc100 sbc100 requested a review from juj December 15, 2021 02:05
@sbc100
Copy link
Collaborator Author

sbc100 commented Dec 15, 2021

I ran the same test without INCLUDE_FULL_LIBRARY to get results for a more typical JS output size (125k):

  • base case: 559ms 524ms 555ms.
  • full closure: 2.523s 2.485s 2.486s (~5x slowdown over base)
  • transpile only: 1.064s 1.055s 1.057s (~2x slowdown over base)

So I think we have some evidence that supporting older browsers will slow down the links by between 2 and 3 times.

Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

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

Thanks for the measurements! Very useful info.

I think an extra ~1 second during link is acceptable if supporting legacy browsers is a rare case, since we get significant benefits in return thanks to this (smaller code size in general).

I wish we had good data for how rare this is in practice among our users. Hard to get a representative sample, of course, so I don't have any good ideas here. But hopefully not many support legacy browsers in practice, and this is off by default. Also these requirements are higher than the requirements for wasm, in fact, so this would only just affect wasm2js users. Btw, do you know how many of our tests would get slower here? I think almost none, since we hardly test LEGACY_VM_SUPPORT or MIN_*_VERSION.

lgtm aside from tests.

emcc.py Outdated Show resolved Hide resolved
tests/test_other.py Outdated Show resolved Hide resolved
@sbc100 sbc100 requested a review from kripken December 17, 2021 00:11
@sbc100 sbc100 force-pushed the closure_transpile_only branch from 1a9d0b5 to 9aa4ade Compare December 17, 2021 00:18
@sbc100
Copy link
Collaborator Author

sbc100 commented Dec 17, 2021

Added more testing including -O2

@sbc100 sbc100 force-pushed the closure_transpile_only branch 2 times, most recently from 08645c4 to 08dbd6b Compare December 17, 2021 01:03
@sbc100
Copy link
Collaborator Author

sbc100 commented Dec 17, 2021

I investigated the transpiration of let and const and arrow functions and they looks like they to the obvious and minimal thing.

@sbc100 sbc100 force-pushed the closure_transpile_only branch 2 times, most recently from cff7c8d to fe16954 Compare December 18, 2021 00:38
With this change we allow these features by default.  If a user
explicitly opts into older browser support we trigger the running
of closure compiler with `--language_out ES5 --compilation_level
WHITESPACE_ONLY`.

For most users this will be a code size win, but otherwise a no-op.

For users who need older browser support they will now have their
output run though closure by default.  If they want to take a care
of the transpilaion process themselves rather than have emscripten
to it auto-magically they can run with `--closure=0`.

When we auto-magically run closure to do transpilation we generate
a warning.  This warning can be suppressed by add `--closure=1` to
explicitly opt in, or `--closure=0` to explicitly opt out.

This change in does not actually include any usage of these features
and so don't include the code size benefits. Those will be part of
followup PRs.

Fixes: #11984
@sbc100 sbc100 force-pushed the closure_transpile_only branch from fe16954 to bc31c66 Compare December 18, 2021 00:59
@sbc100 sbc100 merged commit 4eefe27 into main Dec 18, 2021
@sbc100 sbc100 deleted the closure_transpile_only branch December 18, 2021 02:02
sbc100 added a commit that referenced this pull request Dec 20, 2021
Now that ES6 features are permitted in emscripten JS library
code (see #15763) we can take advantage of some of them to
reduce size of our output JS.

This is just an initial test of using ES6 features.

See: #11984
sbc100 added a commit that referenced this pull request Dec 20, 2021
Now that ES6 features are permitted in emscripten JS library
code (see #15763) we can take advantage of some of them to
reduce size of our output JS.

This is just an initial test of using ES6 features.

See: #11984
sbc100 added a commit that referenced this pull request Dec 21, 2021
Now that ES6 features are permitted in emscripten JS library
code (see #15763) we can take advantage of some of them to
reduce size of our output JS.

This is just an initial test of using ES6 features.

See: #11984
mmarczell-graphisoft pushed a commit to GRAPHISOFT/emscripten that referenced this pull request Jan 5, 2022
…15771)

I ran into this issue when working on emscripten-core#15763.  We have code interally
that converts `=-1` to `=0x7FFFFFFF` for the MIN_XX_VERSION settings.
However, this was then being interpreted interally as a string.  When
read from JS there is no differenence but from python code the value of
this setting would appear as the string "0x7FFFFFFF" and not the number
0x7FFFFFFF.
mmarczell-graphisoft pushed a commit to GRAPHISOFT/emscripten that referenced this pull request Jan 5, 2022
With this change we allow these features by default.  If a user
explicitly opts into older browser support we trigger the running
of closure compiler with `--language_out ES5 --compilation_level
WHITESPACE_ONLY`.

For most users this will be a code size win, but otherwise a no-op.

For users who need older browser support they will now have their
output run though closure by default.  If they want to take a care
of the transpilation process themselves rather than have emscripten
to it auto-magically they can run with `--closure=0`.

When we auto-magically run closure to do transpilation we generate
a warning.  This warning can be suppressed by add `--closure=1` to
explicitly opt in, or `--closure=0` to explicitly opt out.

This change in does not actually include any usage of these features
and so don't include the code size benefits. Those will be part of
followup PRs.

Fixes: emscripten-core#11984
mmarczell-graphisoft pushed a commit to GRAPHISOFT/emscripten that referenced this pull request Jan 5, 2022
Now that ES6 features are permitted in emscripten JS library
code (see emscripten-core#15763) we can take advantage of some of them to
reduce size of our output JS.

This is just an initial test of using ES6 features.

See: emscripten-core#11984
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.

Allow ES6 in emscripten output
2 participants