|
| 1 | += Locals Clearing |
| 2 | +Fogus |
| 3 | +2024-08-05 |
| 4 | +:type: reference |
| 5 | +:toc: macro |
| 6 | +:icons: font |
| 7 | + |
| 8 | +ifdef::env-github,env-browser[:outfilesuffix: .adoc] |
| 9 | + |
| 10 | +== Local Clearing |
| 11 | + |
| 12 | +Local bindings can be created by function arguments, ~let~, ~loop~, ~letfn~, or ~try/catch~ (caught exception). Locals clearing finds the last use of a local in a body and clears the local at that point. This is supported in the compiler with three stateful dynamic vars: |
| 13 | + |
| 14 | +* ~CLEAR_ROOT~ - PathNode head marking method context |
| 15 | +* ~CLEAR_PATH~ - List of ~Compiler.PathNode~ objects to root |
| 16 | +* ~METHOD~ - The ~Compiler.ObjMethod~ instance representing the implementation boundary of a function body. Holds information about its closed-over bindings |
| 17 | + |
| 18 | +The compiler tracks Local binding usage and clear-ability using: |
| 19 | + |
| 20 | +* ~Compiler.LocalBinding~ - Holds local information (name, init, etc.) and initialized with the value of the ~CLEAR_ROOT~ on construction |
| 21 | +* ~Compiler.LocalBindingExpr~ - Holds information about local usage and root and path information at point of use |
| 22 | +* ~CLEAR_SITES~ - Map of ~LocalBinding~ -> ~LocalBindingExpr~ to clear |
| 23 | + |
| 24 | +Bindings in functions are implemented either as method arguments, method variables, or as instance fields when the binding represents a closed-over. |
| 25 | + |
| 26 | +During OME emit, clearing an LBE means that the binding in the enclosing OM is set to ~null~ on last use. |
| 27 | + |
| 28 | +=== Later use and Last use |
| 29 | + |
| 30 | +Later use is defined in the LBE constructor by first checking if there exist clearing sites for a LB with the same path as in the LBE. If so, then they are set to not clear as there is later use of that LB. |
| 31 | + |
| 32 | +Last use is also defined in the LBE constructor for two cases, locals and closed-overs: |
| 33 | + |
| 34 | +* When the LBE has the same root as the LB (the local was created in the current function), then the LBE should be cleared |
| 35 | +* When a closed-over has the same root as the OM boundary, then the closed-over should be cleared |
| 36 | + |
| 37 | +=== :once functions |
| 38 | + |
| 39 | +Functions marked with a ~:once~ metadata set to ~true~ are a special case. By marking a function this way, the user is indicating that the function will only run once. Therefore, the compiler can more aggressively clear its locals and closed-overs. However, Clojure has long supported ~recur~ to the head of once functions which causes a contradiction in the run-once semantics. Therefore, when a ~Compiler.RecurExpr~ is parsed the compiler checks for this conflict by detecting if the enclosing OM method context is set as ~onceOnly~ and that the recur target is to its head. If both conditions are true then the enclosing OM instance's ~onceOnly~ flag is set to ~false~, thus ensuring that the normal later-use and last-use checks are in play. |
| 40 | + |
| 41 | + |
0 commit comments