lua-users home
lua-l archive

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

>From lobject.h, the definition of LClosure (the structure for Lua closures):
typedef struct LClosure {
  GCObject *next;
  lu_byte tt;
  lu_byte marked;
  lu_byte isC;
  lu_byte nupvalues;
  GCObject *gclist;
  struct Table *env
  struct Proto *p;
  UpVal *upvals[1];
} LClosure;

>From the above, you can see that a Lua closure, in memory, takes 4
pointers, plus 4 bytes, plus maybe some padding bytes between
nupvalues and gclist (i.e. 4 padding bytes on x64 to align gclist on
an 8 byte boundary), and then one extra pointer (UpVal*) for each
upvalue which it references. If two or more closures share an upvalue,
then just one UpVal structure will be allocated for that upvalue.
Otherwise, an UpVal structure is allocated for each upvalue.

An UpVal structure looks something like:
typedef struct UpVal {
  GCObject *next;
  lu_byte tt;
  lu_byte marked;
  TValue *v;  /* points to stack or to its own value */
  union {
    struct /* TValue */ { /* the value (when closed) */
      union {
        GCObject *gc;
        void *p;
        lua_Number /* double */ n;
        int b;
      } Value;
      int tt;
    } value;
    struct {  /* double linked list (when open) */
      struct UpVal *prev;
      struct UpVal *next;
    } l;
  } u;
} UpVal;

Thus each upvalue structure has a pointer, two bytes, maybe some
padding, another pointer, and then about 16 bytes for the value /
linked list union (might only be 12 bytes on 32 bit architectures if
there is no padding after int tt;).

If upvalues are not shared, then for a closure with N upvalues, the
required memory will probably be:
sizeof(void*) * (5 + N) + N * (sizeof(void*) * 3 + 16)
where sizeof(void*) == 4 on x86 and sizeof(void*) == 8 on x64.

On Mon, Sep 7, 2009 at 2:37 PM, Jim Pryor<> wrote:
> I should note I'm using a 64-bit Linux kernel. That may affect some of the sizes. (Perhaps that's why I'm seeing functions as 40 bytes overhead rather than 20 bytes.)
> Also I notice this comment in the discussion on that WoW wiki page, in case it helps:
>> Description of upvalues is a bit flawed
>> Just a note, the way upvalue memory use is described is somewhat flawed, as
>> it's not separating the memory for the upvalue reference (4 bytes per closure)
>> from the memory for the value (28 bytes, IIRC). Lua doesn't care if the upvalue
>> changes or not (contrary to the wording here), the difference is that in the
>> 'constant' case there's only one VALUE and a reference in each closure, but in
>> the 'variable' example, there's a value for each instance, plus the 4 bytes on
>> each closure.
> But I still need someone to talk me through what's going on here...?
> --
> Jim Pryor