Re: How come simple "closures" aren't compiled?

  • From: Las <lasssafin@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Tue, 6 Dec 2016 08:15:15 +0000

Thanks for the thorough explanation.

Las

On 6 December 2016 at 00:23, Peter Cawley <corsix@xxxxxxxxxx> wrote:

On Sun, Dec 4, 2016 at 5:18 PM, Las <lasssafin@xxxxxxxxx> wrote:
Yeah, that's what I meant.
I know it can compile calls, but it can't compile FNEW and UCLO of
simple functions.

To address the original point, I think the rough answer is "because
they are fiddly to compile and nobody has been motivated enough to
make them compile". In particular:
  * There is probably little point getting FNEW to compile without
also getting UCLO to compile (this may or may not be true, and toy
examples can easily present situations where you get FNEW without
UCLO, but this is nevertheless my current stance).
  * FNEW probably warrants a new optimisation pass to hoist FNEW
instructions out of loops (where possible; we're stuck with the
pre-5.2 semantics of closures having unique identity). Full allocation
sinking probably isn't going to happen, but getting one new closure
per trace entry as opposed to one per loop iteration is a reasonable
middle-ground.
  * Compiled FNEW might have to create upvalues which point to beyond
the top of the Lua stack (as stack growth can be deferred until trace
exit). Maybe this is fine, maybe it isn't (in which case FNEW has to
have the possibility of causing a trace exit).
  * The semantics of UCLO are heavily tied to the Lua stack, which
doesn't exist during trace execution. The trace recorder probably
wants to turn "close all slots >= A" into "assert that {slots >= A
which are aliased by upvalues} == {S_1, ..., S_n}, close S_1, ...,
close S_n". Perhaps the "==" in the assertion can be changed to "is
equal to or a subset of" (one awkward case is that at recording-time,
a particular slot might be aliased by an upvalue which is due for GC,
and then at trace execution time after a subsequent GC, said slot
might not be aliased by any upvalues). This might require the trace to
load some slots which it wouldn't otherwise need to load, which is
slightly sad (or would require extra implementation complexity).
There's an alternative implementation idea based around pretending to
take a trace exit, using the exit snapshot to reconstitute any slots
which need closing, and then reversing the exit, but I don't think
that this idea has legs.
  * It isn't immediately clear how UCLO interacts with UREFO or with
upvalue alias analysis, as both kind of assume that the open-ness of
upvalues doesn't change during trace execution.

Perhaps there are other considerations, but the above is what comes to
mind right now.


Other related posts: