[Tarantool-patches] [PATCH] lua: refactor port_lua_do_dump and encode_lua_call
imun at tarantool.org
Sat Aug 14 13:16:41 MSK 2021
I've checked the patch into 1.10, 2.7, 2.8 and master.
On 18.06.21, Sergey Kaplun wrote:
> The old code flow was the following:
> 1) `struct port_lua` given to `port_lua_do_dump()` has Lua stack with
> arguments to encode to MessagePack
> 2) The main coroutine `tarantool_L` is used with `lua_cpcall()` to call
> `encode_lua_call_16()` or `encode_lua_call()`
> 3) Objects on minor coroutine are encoded via `luamp_encode_call16()` or
> `luamp_encode()`. This encoding may raise an error on unprotected
> `port->L` coroutine. This coroutine has no protected frame on it
> and this call should fail in pure Lua. It is forbidden to call
> anything on unprotected coroutine  (Lua 5.1 sets protection only
> for specific lua_State  and calls a panic function if we raise an
> error on unprotected lua_State ). Netherless, there is no panic
> at now due to two facts. The first one is LuaJIT's support of C++
> exception handling  that allows to raise an error in Lua and
> catch it in C++ or vice versa. But documentation still doesn't
> permit errors on unprotected coroutines (at least we must set
> try-catch block). The second one is double monkey-patching of LuaJIT
> to restore currently executed coroutine, when C function or fast
> function raises an error  (see related issue here ).
> For these reasons, when an error occurs, the unwinder searches and
> finds the C-protected stack frame from the `lua_cpcall()` for the
> `tarantool_L` coroutine and unwinds until that point (without
> aforementioned patches LuaJIT just calls a panic function and exit).
> 4) If an error is raised, and `lua_cpcall()` returns not `LUA_OK`, then
> the error from `port->L` coroutine is converted into a Tarantool error
> and a diagnostic is set.
> The auxiliary usage of `tarantool_L` coroutine is redundant and doesn't
> respect Lua idiomatic of usage. So this patch drops it and uses only
> minor coroutine instead with `lua_pcall()`.
> Functions to encode are saved as entrance in the `LUA_REGISTRY` table
> to reduce GC pressure, like it is done for other handlers .
> : https://www.lua.org/manual/5.2/manual.html#4.6
> > If an error happens outside any protected environment, Lua calls a
> > panic function
> : https://www.lua.org/source/5.1/lstate.h.html#lua_State
> : https://www.lua.org/source/5.1/ldo.c.html#luaD_throw
> : https://luajit.org/extensions.html#exceptions
> : https://github.com/tarantool/luajit/commit/ed412cd9f55fe87fd32a69c86e1732690fc5c1b0
> : https://github.com/tarantool/luajit/commit/97699d9ee2467389b6aea21a098e38aff3469b5f
> : https://github.com/tarantool/tarantool/issues/1516
> : https://www.freelists.org/post/luajit/Issue-with-PCALL-in-21
> : https://github.com/tarantool/tarantool/commit/e88c0d21ab765d4c53bed2437c49d77b3ffe4216
> Branch: https://github.com/tarantool/tarantool/tree/skaplun/gh-noticket-refactor-lua-call
> See the benchmarks sources here .
> Before patch:
> | Encode map: 189851357 mcs, 15.8 K ps
> | Encode seq: 187926351 mcs, 16.0 K ps
> | Encode str: 185451675 mcs, 16.2 K ps
> | Encode dig: 184833396 mcs, 16.2 K ps
> After patch:
> | Encode map: 187814261 mcs, 16.0 K ps
> | Encode seq: 183755028 mcs, 16.3 K ps
> | Encode str: 181571626 mcs, 16.5 K ps
> | Encode dig: 181572998 mcs, 16.5 K ps
> Looks like the perf doesn't degrade at least.
> : https://gist.github.com/Buristan/3e6d6bf2c722874bec55a8c5a44b98f3
> src/box/lua/call.c | 71 ++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 56 insertions(+), 15 deletions(-)
More information about the Tarantool-patches