lua-users home
lua-l archive

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


Gé:

On Sun, Jun 2, 2019 at 12:34 AM Gé Weijers <ge@weijers.org> wrote:
> The Microsoft C# compiler does precisely this when running in release mode, and I suspect most other compiled languages that use finalizers and a garbage collector do the same thing.

Disregarding other languages, how does the C# language define object
liveness / collectability / finalizability ?

> An object (a window object) that was accessed via a weak reference literally disappeared because the reference from the main program was optimized away, but when running in debug mode this never happened.

This may be totally kosher given the right definition. An object is
dead whenever nobody uses it again, and can be collected at any time
after that.

But this definition opens a can of worms for the optimizer. If I do
a=collectable;.......lot of things....;a=a; the optimizer cannot
optimize away the a=a stuff, because that object liveness definition
changes the semantics of a=a, and of all reads of vars in general.
Optimization is a tricky stuff, made much easier in new languages by
the lack of precise definitions of lots of things ( which makes
everything "undefined behaviour" without having to write it this way,
pleasing people who like to critique undefined behaviour, but it is a
big lie, like the "you do not have pointers in Java" statement ).

> This was easily fixed, but is surprised quite a few people. Compilers need to perform this optimization to limit the number of registers and stack locations used and speed up the code.

mmmm, I think they DO NOT need to perform that optimization. In fact I
think you proved they do not when you said "never happened" in "debug
mode", which I assume is compiled too. Also, you sais "to...and speed
up the code". Compilers are not allowed to skip the language
definition to speed the code, if they where I would make an optimizer
which spat a 0-byte exe for every speed optimized program. Not very
useful, but it sure runs ( and compiles! ) fast.

>I would expect a Lua implementation that has a JIT compiler to perform this too (the new ‘toclose’ local variables would be live until the end of the scope because of the call to the __close metamethod)

Now you are inventing a new language. Ok for me as long as you
document it properly. In this spirit you could also optimize every
sin/cos call to return 0. It does not the same as the manual, but it
is faster.

> I have not seen anything in the Lua spec that guarantees the lifetime of an object referenced by a local variable to extend to the point where the execution exits a scope, even if the program no longer accesses the object via that variable. It may be that the current Lua implementation actually does that (except for tail calls) but is it required?

I think I quoted it before but what I use as a reference (
https://www.lua.org/manual/5.3/manual.html#2.5 ) says, in the very 1st
paragraph:

"2.5 – Garbage Collection

Lua performs automatic memory management. This means that you do not
have to worry about allocating memory for new objects or freeing it
when the objects are no longer needed. Lua manages memory
automatically by running a garbage collector to collect all dead
objects (that is, objects that are no longer accessible from Lua). All
memory used by Lua is subject to automatic management: strings,
tables, userdata, functions, threads, internal structures, etc. "

To me this defines dead objects as no longer accessible from Lua. Note
ACCESSIBLE not ACCESSED. So I would consider the optimization an
optimizer bug.

Francisco Olarte.