lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi Gé:

On Sat, Jun 1, 2019 at 6:50 PM Gé Weijers <ge@weijers.org> wrote:
> A general observation:
> An optimizing implementation of Lua could do variable liveness analysis and reuse stack slots, resulting in the following:
> function f(x)
>   print(x)
>   local y = g() -- this overwrites x, making it collectable
>   print(y)
> end
> I have seen this behavior in compiled languages that use a garbage collector, the compiler translates the code into static single assignment form, and 'x' is considered dead once its value is passed to 'print', so the GC no longer traces it and 'x' disappears.

I think this would be a faulty optimizer. To be exact, I think doing
this and allowing the value to be collected would be an optimizer
error. I have not tried to understand the spec in detail, but, in a
language with finalizers which can be observed, this changes the
semantics of the program.

If you do not have finalizers, and the only thing you can do with a
value is read it, that's ok to me, or if the language specifies these
kind of behaviour, but I may have coded a function which this shape,
even without the print of x, with the only purpose of insuring the
finalizer of x's value does not run until function return, and the
optimizer is changing it ( again, if the optimizer is sure that's not
the case, optimize it, but that would be real impressive optimizer ).

Again, not sure of the intention but "Lua manages memory automatically
by running a garbage collector to collect all dead objects (that is,
objects that are no longer accessible from Lua)." indicates to me I
can count of the value of x not being collected before return from the
function, otherwise the guys at Rio could have written "no longer
ACCESED", their english is quite good and given their work I am quite
sure they understand the difference.

And, the only thing I should be able to observe from an optimization
of code ( with defined behaviour, not entering into the undefined
behaviour tarpit here ) should be it running at a different speed (
not necessarily faster ). Other effects, buggy optimizer.

> PUC's Lua interpreter does not do this but a different implementation (JIT-based?) may well. Assuming the object is reachable until the function returns is hazardous to your health

I think PUC's follow their own definition in 2.5 of the manual, and
I've always assumed they would do it or modify it ( the interpreter OR
the manual ) if reported not doing it on any case.

A different implementation, as long as it documents it, is fine for me
as long as they document their behaviour ( although it may be really
difficult to justify that optimization. Fine on a language without
finalizers, but on a different one saying "when you call
f(create_observable_finalizer_object()) the object may be garbage
collected and the finalizer called at any time" is a though thing to
defend. And would prohibit a series of more "legit" optimizations (
and, IMO, useful) optimizations, like folding
"var=create_observable_finalizer_object();f(var);var=nil into the
above call.):

Francisco Olarte.