Skip to content

Commit

Permalink
box: reduce box_process_lua Lua GC memory usage
Browse files Browse the repository at this point in the history
<box_process_lua> function created a new GCfunc object for a handler
having no upvalues depending on the request context on each call.

The change introduces the following mapping:
| <handler id> -> <handler GCfunc object>
Initializing this mapping on Tarantool startup is aimed to reduce Lua GC
memory usage.

Reviewed-by: Sergey Ostanevich <sergos@tarantool.org>
Reviewed-by: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Signed-off-by: Igor Munkin <imun@tarantool.org>
(cherry picked from commit e88c0d2)
  • Loading branch information
igormunkin authored and kyukhin committed Jun 26, 2020
1 parent c74d272 commit e13698f
Showing 1 changed file with 36 additions and 5 deletions.
41 changes: 36 additions & 5 deletions src/box/lua/call.c
Expand Up @@ -47,6 +47,24 @@
#include "trivia/util.h"
#include "mpstream.h"

/**
* Handlers identifiers to obtain lua_Cfunction reference from
* Lua registry table. These handlers are initialized on Tarantool
* startup and are used until the Lua universe is destroyed.
* Such approach reduces Lua GC usage since there is no need to
* create short-lived GCfunc objects for the corresponding C
* function on each iproto CALL/EVAL request or stored Lua
* procedure call.
*/
enum handlers {
HANDLER_CALL,
HANDLER_CALL_BY_REF,
HANDLER_EVAL,
HANDLER_MAX,
};

static int execute_lua_refs[HANDLER_MAX];

/**
* A helper to find a Lua function by name and put it
* on top of the stack.
Expand Down Expand Up @@ -524,7 +542,7 @@ static const struct port_vtab port_lua_vtab = {
};

static inline int
box_process_lua(lua_CFunction handler, struct execute_lua_ctx *ctx,
box_process_lua(enum handlers handler, struct execute_lua_ctx *ctx,
struct port *ret)
{
lua_State *L = luaT_newthread(tarantool_L);
Expand All @@ -534,7 +552,8 @@ box_process_lua(lua_CFunction handler, struct execute_lua_ctx *ctx,
port_lua_create(ret, L);
((struct port_lua *) ret)->ref = coro_ref;

lua_pushcfunction(L, handler);
lua_rawgeti(L, LUA_REGISTRYINDEX, execute_lua_refs[handler]);
assert(lua_isfunction(L, -1));
lua_pushlightuserdata(L, ctx);
if (luaT_call(L, 1, LUA_MULTRET) != 0) {
port_lua_destroy(ret);
Expand All @@ -551,7 +570,7 @@ box_lua_call(const char *name, uint32_t name_len,
ctx.name = name;
ctx.name_len = name_len;
ctx.args = args;
return box_process_lua(execute_lua_call, &ctx, ret);
return box_process_lua(HANDLER_CALL, &ctx, ret);
}

int
Expand All @@ -562,7 +581,7 @@ box_lua_eval(const char *expr, uint32_t expr_len,
ctx.name = expr;
ctx.name_len = expr_len;
ctx.args = args;
return box_process_lua(execute_lua_eval, &ctx, ret);
return box_process_lua(HANDLER_EVAL, &ctx, ret);
}

struct func_lua {
Expand Down Expand Up @@ -778,7 +797,7 @@ func_persistent_lua_call(struct func *base, struct port *args, struct port *ret)
struct execute_lua_ctx ctx;
ctx.lua_ref = func->lua_ref;
ctx.args = args;
return box_process_lua(execute_lua_call_by_ref, &ctx, ret);
return box_process_lua(HANDLER_CALL_BY_REF, &ctx, ret);

}

Expand Down Expand Up @@ -995,6 +1014,18 @@ box_lua_call_init(struct lua_State *L)
*/
on_alter_func_in_lua.data = L;
trigger_add(&on_alter_func, &on_alter_func_in_lua);

lua_CFunction handles[] = {
[HANDLER_CALL] = execute_lua_call,
[HANDLER_CALL_BY_REF] = execute_lua_call_by_ref,
[HANDLER_EVAL] = execute_lua_eval,
};

for (int i = 0; i < HANDLER_MAX; i++) {
lua_pushcfunction(L, handles[i]);
execute_lua_refs[i] = luaL_ref(L, LUA_REGISTRYINDEX);
}

#if 0
/* Get CTypeID for `struct port *' */
int rc = luaL_cdef(L, "struct port;");
Expand Down

0 comments on commit e13698f

Please sign in to comment.