lua-users home
lua-l archive

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

Hi all.

I'm investigating the memory use of lua_State objects, so I modified the l_realloc() macro to pass along the lua_State* given to luaM_realloc(), and attached a new memory allocation function. This is luaM_realloc() with the macro changed:

void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) {
  if (size == 0) {
    if (block != NULL) {
      // LUAMOD: l_realloc has been changed so that a lua_State* is passed as the first parameter
      l_realloc(L, block, oldsize, size);
      block = NULL;
  else if (size >= MAX_SIZET)
    luaG_runerror(L, "memory allocation error: block too big");
  else {
    // LUAMOD: l_realloc has been changed so that a lua_State* is passed as the first parameter
    block = l_realloc(L, block, oldsize, size);
    if (block == NULL) {
      if (L)
        luaD_throw(L, LUA_ERRMEM);
      else return NULL;  /* error before creating state! */
  if (L && G(L)) {
    G(L)->nblocks -= oldsize;
    G(L)->nblocks += size;
  return block;

After using lua_open() to create a state, the accumulated memory totals are as follows:

lua_State* 00000000, mem used 92	(92 bytes for the lua_State object itself)
lua_State* 823BD820, mem used 2553

But after freeing it with lua_close(), some of the blocks are released with NULL as the lua_State* parameter, instead of the pointer they were allocated with:

lua_State* 00000000, mem used -692	(should be zero?)
lua_State* 823BD820, mem used 692	(should be zero?)

Looking closer, the culprits are L->l_G, L->stack, and L->base_ci. 

What I'm wondering is if there's a reason that the deallocation of these structures doesn't want to be associated with a lua_State? The nblocks field inside the global state seems to be tracking per-state allocations like I'm doing, and at the point the lua_State is freed, it's also off (the value is 784 == 692 + 92).

Thanks for your help,

PS- the following changes make the code behave the way I *expect*, for better or worse. 

In leaE_closethread() [lstate.c], replace:
  luaM_freearray(OL, L->base_ci, L->size_ci, CallInfo);
  luaM_freearray(OL, L->stack, L->stacksize, TObject);
  luaM_freearray(L, L->base_ci, L->size_ci, CallInfo);
  luaM_freearray(L, L->stack, L->stacksize, TObject);

In close_state() [lstate.c], replace:
    luaM_freelem(NULL, L->l_G);
    luaM_freelem(L, L->l_G);
    L->l_G = NULL;