Add a kind of finalisation function called without argument#562
Add a kind of finalisation function called without argument#562damiendoligez merged 12 commits intoocaml:trunkfrom
Conversation
ab504e5 to
4f423bb
Compare
byterun/finalise.c
Outdated
| Assert (Is_in_heap (final_table[i].val)); | ||
| if (Is_white_val (final_table[i].val)) ++ todo_count; | ||
| if (final_table[i].flags == flags && | ||
| Is_white_val (final_table[i].val)) ++ todo_count; |
There was a problem hiding this comment.
Please add braces and put the statement on a separate line.
|
I don't like the function name. You should change it, probably to As for the documentation, I find it confusing because it speaks about "unreachable for the first time" and "unreachable for the last time", notions that are non-obvious and not used anywhere else. Moreover, you absolutely need to mention ephemerons here, because that's the whole point. |
|
I see that these finalisers still cause their associated values to be marked during minor collections. Instead couldn't we only mark the values associated with "traditional" finalisers, and move the finalisers whose values are not promoted directly into the finalising set? |
I don't have a specific good idea, but it might be good to just call these by some other name than "finaliser" ("destructor", "cleaner", ...).
I agree. The documentation should include a guarantee that these new finalisers run after any weak pointers to the object have been cleared. |
|
@lpw25 Indeed it is a good idea. I can modify
Just to be clear, when the finalisers run, the weak pointers could have not yet been cleared, but the accessors behave as if it is already done (during the clean phase accessors verify if the weak pointer is going to be cleared in this phase).
In the current documentation of In any case I'm going to add something about weak pointers and ephemerons. |
|
@damiendoligez Could you please check the comments I added in cfa8a1d before I try to implement @lpw25 idea? When the branch will be stable, I will stash the commits, but for now I think it can help the review. |
|
@damiendoligez I don't understand why there is a finalisable set and a recent set, they both appear at the same time in 0a2021e. Why can't we just check if the value is young or not? Thank you for your help. |
|
The comment in cfa8a1d looks OK. The recent set is used when scanning roots for minor collection. We don't want to go through all the finalized values at each minor GC, so we isolate a subset that is guaranteed to contain all young finalized values. |
byterun/finalise.c
Outdated
| This is called by the minor GC through [caml_oldify_local_roots]. | ||
| */ | ||
| void caml_final_do_young_roots (scanning_action f) | ||
| void caml_final_do_young_roots () |
There was a problem hiding this comment.
We decided this function (and any others without the "f") should be renamed.
There was a problem hiding this comment.
We decided this function (and any others without the "f") should be renamed.
Done. That was the only function like that.
|
@lpw25 idea have been implemented: don't mark value with finalisation_last` during minor collection. It was trickier than what I though. The implementation have been simplified, by keeping the two datastructures separate. The added tests doesn't contain any oracle but with the debug runtime it found an error. It is hard to have deterministic (ocamlc/ocamlopt) oracle for this problems. @damiendoligez Something strange: for executing all the finaliser, sometime two |
and rename it to caml_final_invert_finalizable_values
into caml_final_do_roots because there is no other place where
roots are called strong roots, and the weak roots function have
already been renamed.
into caml_final_oldify_young_root
Values with finalize_last could be garbage collected immediately during minor collection, they don't have to pass by the major heap. No change for finalize(_first) values since the value is needed for running the finalization function.
But there is no unit test or oracles.
When no finalisation function need to be run, the young values where not
updated with their new location in major heap.
Also add a check for some invariants
It was just because I attached a Edit: substitute |
|
Maybe it should say "this will collect and finalize all currently unreachable blocks". |
|
@bobot What is the status of this? I'm rather hoping to use these in 4.04. |
|
On my side it is finished (the modification of the documentation of |
|
Reviewed, rebased, merged. |
|
@damiendoligez Thank you! |
Import fixes to the minor heap allocation code from DLABs.
When resolving a symbol projection to some simple `s`, we then
recursively try and resolve `s` as a symbol projection. If `s` carries a
coercion, we need to apply that coercion to the final result.
Unfortunately, I don't have a test case for this, because I'm not sure
it's currently possible to trip it: one would need a symbol that gets
set to a recursive occurrence, and yet that recursive occurrence needs
to be an alias to some other symbol projection. You'd want to do
something like
let foo = Sys.opaque_identity 42
let rec waste b = if b then waste false else bar [@@inline]
and bar = foo
but the `and bar = foo` part is not valid OCaml.
At any rate, I ran tests with the shortcut in
`create_coerced_singleton_let` removed, so the basic functionality of
wrapping a `Named.t` in a coercion is working.
fe8a98b flambda-backend: Save Mach as Cfg after Selection (ocaml#624) 2b205d8 flambda-backend: Clean up algorithms (ocaml#611) 524f0b4 flambda-backend: Initial refactoring of To_cmm (ocaml#619) 0bf75de flambda-backend: Refactor and correct the "is pure" and "can raise" (port upstream PR#10354 and PR#10387) (ocaml#555) d234bfd flambda-backend: Cpp mangling is now a configuration option (ocaml#614) 20fc614 flambda-backend: Check that stack frames are not too large (ocaml#10085) (ocaml#561) 5fc2e95 flambda-backend: Allow CSE of immutable loads across stores (port upstream PR#9562) (ocaml#562) 2a650de flambda-backend: Backport commit fc95347 from trunk (ocaml#584) 31651b8 flambda-backend: Improved ARM64 code generation (port upstream PR#9937) (ocaml#556) f0b6d68 flambda-backend: Simplify processing and remove dead code (error paths) in asmlink (port upstream PR#9943) (ocaml#557) 90c6746 flambda-backend: Improve code-generation for inlined comparisons (port upstream PR#10228) (ocaml#563) git-subtree-dir: ocaml git-subtree-split: fe8a98b
The advantage is that this kind of finalization functions are called after the value being unreachable for the last time instead of the first time (GC.finalise). MPR#7210
Tests are not provided because there are no tests for
GC.finaliseand I must understand which kind of tests should be done.