3 ms·
I know it says this: "The semantics of LuaJIT do not prescribe when GC can happen and what values will be live, so the GC and the compiler are not constrained t
by epcoa 3y ago
I know it says this: "The semantics of LuaJIT do not prescribe when GC can happen and what values will be live, so the GC and the compiler are not constrained to extend the liveness of blob to, say, the entirety of its lexical scope. "
But it is flat wrong. From the LuaJIT documentation:
"All explicitly (ffi.new(), ffi.cast() etc.) or implicitly (accessors) created cdata objects are garbage collected. You need to ensure to retain valid references to cdata objects somewhere on a Lua stack, an upvalue or in a Lua table while they are still in use. Once the last reference to a cdata object is gone, the garbage collector will automatically free the memory used by it (at the end of the next GC cycle)."
The Lua stack in this case includes all the local variables in that function scope.
It's a non-issue/straw man and is common sense.
If LuaJIT FFI worked the way the author supposed, it would be near impossible to use practically.
“It is perfectly valid to collect blob after its last use”
This is a useless statement. It’s perfectly “valid” for LuaJIT to not even read your source code and exit immediately, but that isn’t what it does because it would be useless. What counts as a reference is both PUC Lua and LuaJIT is defined.
As far as the desirability of finer grained liveness, Lua has block scope (do end), but in practice LuaJIT does well inlining so functions ought to be short anyway.
- reichstein 3y agoGC is usually not specified to happen at particular times, or saying which values are definitely going to be GCed. Instead it relies on the language semantics, so that any value which is used later in the program, is not going to be GCed. How and when the runtime system determines that a value is not going to be used again is an optimization problem, not a correctness problem. So everything you quote Lua a saying here is consistent. The thing is that it only considers "used later" as "used later by the Lua program". Or rather, it only considers Lua values as "values". A value stored in non-managed memory is not a value. It's not GCed. The `ffi.new`-created Lua value is, and it's finalizer happens to free the native memory that the pointer refers to. So non -Lua "values" are not GCed, they are freed as side effects of Lua values being GCed.
- Joker_vD 3y agoOkay, LuaJIT is a bit specific example, what about .NET CLR? Because it absolutely does this optimization, and e.g. an object can get GC'd while one of its instance methods is still running given that this instance method is statically (or maybe even dynamically?) guaranteed to not access `this`.
- epcoa 3y agoYes, and? It has mechanisms with well defined semantics such as GCHandle and KeepAlive. That’s literally what it is there for so it makes this: “or attempt to manually extend the lifetime of a finalizable object, and then pray the compiler and GC don’t learn new tricks to invalidate your trick” a non starter. It’s not a trick, it’s a documented interface.
- amluto 3y agoOn a related note, the OP says: > or attempt to manually extend the lifetime of a finalizable object, and then pray the compiler and GC don’t learn new tricks to invalidate your trick. This is also silly. There is no reason whatsoever that a GC can’t offer an actual API to keep an object alive.
- irq-1 3y agoLuaJIT lets you remove a finalizer: > An existing finalizer can be removed by setting a nil finalizer, e.g. right before explicitly deleting a resource: ffi.C.free(ffi.gc(p, nil)) -- Manually free the memory. https://luajit.org/ext_ffi_api.html#ffi_gc https://luajit.org/ext_ffi_api.html#ffi_gc