lua-users home
lua-l archive

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


Roberto:

On Sun, Jun 2, 2019 at 3:42 PM Roberto Ierusalimschy
<roberto@inf.puc-rio.br> wrote:
> > 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.
> I see the problem the other way around. It is not optimization that
> should be restricted; what should be restricted are the assumptions
> around finalizers. Of course any optimizer should be able to erase
> 'a=a' (as long as the assignment itself has no side effects, as it
> can have in C++), as it should be able to erase any code that does
> not produce side effects.

I'm ok with this, totally. But that is not the case for my example, at
least in Lua.

> A finalizer is part of garbage collection, and it should behave as
> such. If all a finalizer does is "collect garbage" (free unused memory),
> all optimizations are Ok, as long as the code does not access the memory
> that might be released. And that is what the optimizer should verify
> when doing an optimization. If the optimized code does not need that
> piece of memory, it can be relased. That is it.  The "trickiness" comes
> from the extended uses of finalizers for all softs of things, not from
> the optimizations.

Well, IMO the only thing a finalizer does not need to do is "collect
garbage", that's already done nicely by the garbage collector. And, in
my usage, all finalizers I've written have side efects. They have the
effect of garbage collection, when I no longer use a file I want the
now garbage OS handle to be freed ( even if I did stop using it
because some callback I used errored out of me and was caught three
levels up the call stack. <toclose> can do this for simple cases, but
when the handle is shared by half a dozen things and may or may be not
stored in some longer living stuff, it is hard, I normally use
ref-count for that, where it shines.

If the language allows us to do side-effecty things in the finalizers,
the ( to be done ) optimizer, cannot do this sort of things. But you
can change that, just make Lua 5.4 or 5.5 defined as "anything with
side effects is forbiden in finalizers" ( which is the same, IMO, as
getting rid of them, if you only can free ram, the GC does it, and
even if you simply increment a global "finalizer count" that's a side
effect ). But I suspect there is a reason your group put them there to
begin with.

I think the current definitions is nice and useful, the accesible
stuff is clear for me, and it seems to be what it is doing. Anyone
knows how to make the object inaccessible, just clear the ref, my code
is full of "x=nil -- free the reference for GC", specially its cousin
"some_objecty_thingie.whatever_handle=nil",  deep inside libs, like
the Java library is full of =null. Most of the usefulness of zapping
this vars or reusing variable slots in a potential optimizer is
normally realized by tracing local var initialized in the function,
destroying the reference normally does not gain a thing ( not used,
not hooking a registry ), and the marking as dead cannormally be done
at exit, faster and easier.


> I agree that, in Lua, things are more complex because of its interface
> with C. That is why the API has some clear rules around that
> subject: Objects in the stack cannot be collected, objects in the
> registry cannot be collected, etc.

Is not only the C interface. It's a problem I constantly find with
garbage collected language. GC is great for managing memory, but not
so great for managing many other resources, like open files. That's
why Java NEEDS try/finally ( and somebody markets it as and advantage
over C++ which does not HAVE it ( because it is not needed and can be
done in a few lines ) ). You can GC files, making the file objects
native to the GC so it knows what to when collecting, but they are
much scarcer than memory. But then you have sockets and all other
sorts of fancy resources. So, you do RAII or something similar stuff,
tie your external resource to a memory chunk and tell the GC to aid
you. In lua we have a problem with control jumping around a bunch of
frames, due to a pcall-error pair, which rules out the doable, but
tedious, way of carefully writting every code path to close files. It
can be done, a pcall after every acquisition. But finalizers make that
easier. The new <toclose> for 5.4 seems to make it easier.

( I repeat again my previous problem with the C api is dead and
buried, it was my fault to assume some "magic" copy of the args I
pushed lived in my C function stack till just before lua_pcall
returned to me )

Francisco Olarte.