-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Convert extended string handling functions into JS library code #17403
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
Conversation
446cfa5
to
f2db29f
Compare
ff588bc
to
ad0f669
Compare
OK I added a new |
d41861d
to
75ed148
Compare
This is now a more conservative changes since |
c0ca093
to
614506c
Compare
// Ignore null values. | ||
if (item) { | ||
functionsInTableMap.set(item, i); | ||
} |
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.
Is this a separate fix?
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.
This is actually needed work around a JSDCE optmizer + closure issue.
Here is how I remember it going (roughly):
- addFunction (which depends on updateTableMap + functionsInTableMap) get added due to
LEGACY_RUNTIME
being set by default. - JSDCE run which is able to remove addFunction.. but it only run a single round so leaved the now used
updateTableMap
function in place. - Closure compiler then run as sees that there is no place where
functionsInTableMap
is ever set to anything byundefined
which means it can then prove thatfunctionsInTableMap.set
is invalid here.
This seems like a bug that can occur when JSDCE (the single pass version) is used with closure compiler.. but its probably fairly rare.
In any case this seems like a good fix. If functionsInTableMap
has not yet been initilzed when updateTableMap
is called it would crash (without this fix).
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.
What would closure actually do in step 3? It seems like any change it makes is ok since it's to a function that is never called.
Regardless I think you are right, reading the code it looks like this has been a possible bug. To hit it we'd need to load a side module that somehow avoids calling addFunction
at all, and then the dylink call to updateTableMap
will throw. I guess that's rare enough to never happen in practice.
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.
closure reports an error saying functionsInTableMap.set
is not a function since it knows that functionsInTableMap
is undefined. By adding the check here make closure happy since it can tell that the undefined
is being checked for.
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.
I see, thanks. Yes, I guess partially optimized code can end up hitting closure errors in that way.
@@ -1 +1 @@ | |||
26698 | |||
26717 |
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.
Just unoptimized size, but still, why does it increase? Shouldn't we be emitting the same code? (maybe we add more assertions instrumentation if we only add it to library functions and not runtime functions?)
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.
This is only a 19 byte difference. Its likely just minor difference in the way library function get emitted.. I'm not sure its work investigating, especially since the diff will be tricky to read.
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.
Fair enough. The diff to tests/other/test_unoptimized_code_size.js.size is almost 4K though.
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.
Oh ok .. I'll take a look at that one.
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.
Oh, I figured it out, its because this change also means that we get all of allocate
/addFunction
/removeFunction
etc as part of LEGACY_RUNTIME
which is now the default.
Would you rather I split the LEGACY_RUNTIME
change from the moving the string functions to make this more clear?
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.
I see, thanks for checking.
I think it's fine in this PR to do both.
…ripten-core#17403) This was already the case with MINIMAL_RUNTIME. Add a new setting, which is currently enabled by default called `LEGACY_RUNTIME` which enables all of these library functions by default. As a followup we can consider disabling `LEGACY_RUNTIME` by default which will give code size benefits by default.
Hi, is this documented anywhere? I can't find it: https://emscripten.org/search.html?q=LEGACY_RUNTIME&check_keywords=yes&area=default Do we need to change our linker flags if we use these functions? I was using allocateUTF8OnStack, which, admittedly, was never documented either, and now I need Ideally I would pick and choose which of the functions to include, but I am not really sure how to do that (is this documented? |
Its mostly documented in the changelog: Lines 70 to 97 in 6416c35
If you use the functions externally you should can use |
Hmm,
I get:
Looking in the
Do I need the leading dollar-sign on |
Yes, Also, where are you using this function? If its from EM_ASM or EM_JS then you can now express that dependency in the source code itself. See #17854. |
Thanks for the quick reply! Yes, it appears that somewhere in the guts of CMake, |
Ah. It is recognized as a bug in CMake, and there is a workaround: |
In my case the (very much Not Correct Modern Cmake (tm)) solution is this:
|
Is there by any chance a way to specify -s options from a file instead of just on the command-line? That would solve the problem (and make things generally cleaner when there is a long list of functions to include/export/etc)... |
Yes, you can specify any option that takes a list as a filelname using e.g.g Then in that file you just put one symbol on each line. You can also put the entire command line into a file and just run |
Thank you!!! That will solve all my problems :) |
This was already the case with MINIMAL_RUNTIME.
Add a new setting, which is currently enabled by default called
LEGACY_RUNTIME
which enables all of these library functions by default.
As a followup we can consider disabling
LEGACY_RUNTIME
by default which willgive code size benefits by default.