-
Notifications
You must be signed in to change notification settings - Fork 114
Pass correct live value in BIFs #1610
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
base: release-0.6
Are you sure you want to change the base?
Conversation
If BIF did GC and tried to preserve input registers and args with memory_ensure_free_with_roots(ctx, TERMS_N, live, ctx->x, MEMORY_CAN_SHRINK) it would invalidate registers anyways because live=0. Now, GC BIFs can keep them at cost of temporary memory increase until next GC is done. Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
I'm not sure this is a required change. GC in binary_part was wrongly invoked without arg1 in roots. |
Actually it is not a required change (right now), but it might be a good idea for avoiding any future headache. When we do GC inside a BIF function called with gc_bif instruction, we must do So this change doesn't hurt at all and it allow us to avoid this situation in the future. Let me know if there is anything wrong with my reasoning. |
I wanted to add that currently this code is called from two code-paths – CALL_LAST (which AFAIK comes from tail calls and is fine in that case) and If the original code stays, this warrants at least a comment and maybe even some debug-only asserts to ensure we're not calling it from the wrong context. |
NIF functions don't have live, as the compiler allows them to scratch all x registers. NIF implementations calling GC BIF functions do have live, as the compiler requires them to preserve the first live x registers. If we use the trick as suggested to pass argc as live to GC BIF functions when calling them as NIFs, we assume that when the GC BIF functions are called as BIFs, the compiler sets lives in such a way that the parameters are either within the first live x registers or on the stack. I thought it would not always hold but it seems to be the case with OTP27. Please also note that it seems that GC BIFs no longer GC on OTP, instead they allocate fragments. |
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.
Regardless the outcome of this discussion, we still have a number of occurrences (where we call gcbif1_ptr) where we didn't update live parameter accordingly as we did here. (just search for gcbif1_ptr
).
Lets's think about the whole discussion this way:
|
Right. To clarify further:
|
Can you give locations? I don't see any after searching for |
In opcodesswitch.h: |
Ah, my bad, wrongly interpreted global search in my editor. Thanks! |
@bettio did changes to opcodesswitch from main ever got to release-0.6?
|
If BIF did GC and tried to preserve input registers and args with memory_ensure_free_with_roots(ctx, TERMS_N, live, ctx->x, MEMORY_CAN_SHRINK) it would invalidate registers anyways because live=0.
Now, GC BIFs can keep them at cost of temporary memory increase until next GC is done.
These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).
SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later