-
Notifications
You must be signed in to change notification settings - Fork 86
Improves the modes of mixed recursive definitions #3039
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
This looks dangerous to me. What about the following piece of code (where let rec f () = f ()
and g () = g ()
and h = ()
in
force_global f;
force_local g;
() This shouldn't be allowed to compile, as |
Sorry, for the locality it should error out correctly as this PR still forces the locality to be global. I'm still worried about the other modes, as |
It used to be the case, but since 5.2 upstream and #2394 here the pre-allocate-and-backpatch scheme is only used for regular blocks, with functions always compiled to regular closures (as a single block if there are several of them). |
@lthls Could you elaborate it to the degree that I can fix this PR? For example, do we still specially treat entire-functions defintions? How are they allocated in each cases? |
In a given set of recursive definitions, we sort them into four categories:
There is a special case for recursive functions that are not syntactic functions: let rec f =
let r = ref 0 in
fun () -> incr r; !r (* actual code would also use [f] *) These definitions are transformed into a pseudo-closure allocation and a syntactic function: let rec f () = incr f_env.r; !(f_env.r)
and f_env =
let r = ref 0 in
{ r } The syntactic function then becomes part of the set of recursive closures, while the pseudo-closure gets pre-allocated and back-patched. For this PR, ideally the classification that is currently done in |
@lthls thank you for the detailed explanation. What is shared closure?
Currently it runs before. I'm not sure if it can be made otherwise. |
I call a shared closure a closure block that defines several functions (i.e. |
I think that all the complication in this discussion is caused by the first point, but that the user reported issue you are trying to fix is caused by the second one. Perhaps it would be worth fixing them separately? |
9e0869e
to
5fab8a4
Compare
Yeah sounds good - this PR now contains only the second fix. We will do the first fix in a future PR, as it sounds complex. |
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.
LGTM
This PR improves the modes of mixed (not entirely functions) recursive definitions.
When a group of recursive definitions are all functions, they are allocated as a single block, and this block can be any mode. All functions will have that mode.
When the group is not entirely functions, they are allocated separately. If they are genuiely mutually recursive, they will contain backward pointers (old pointing to new) that our GC currently cannot handle. To prevent that, they will all be allocated on heap.
This PR does two things:
locality
are set to legacy as well. This PR removes this restriction.