special compact representation for userdata with no user values
(a common case)
This commit is contained in:
19
lgc.c
19
lgc.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 2.250 2018/02/23 13:16:18 roberto Exp roberto $
|
** $Id: lgc.c,v 2.251 2018/02/23 13:21:27 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -118,11 +118,15 @@ static lu_mem atomic (lua_State *L);
|
|||||||
static GCObject **getgclist (GCObject *o) {
|
static GCObject **getgclist (GCObject *o) {
|
||||||
switch (o->tt) {
|
switch (o->tt) {
|
||||||
case LUA_TTABLE: return &gco2t(o)->gclist;
|
case LUA_TTABLE: return &gco2t(o)->gclist;
|
||||||
case LUA_TUSERDATA: return &gco2u(o)->gclist;
|
|
||||||
case LUA_TLCL: return &gco2lcl(o)->gclist;
|
case LUA_TLCL: return &gco2lcl(o)->gclist;
|
||||||
case LUA_TCCL: return &gco2ccl(o)->gclist;
|
case LUA_TCCL: return &gco2ccl(o)->gclist;
|
||||||
case LUA_TTHREAD: return &gco2th(o)->gclist;
|
case LUA_TTHREAD: return &gco2th(o)->gclist;
|
||||||
case LUA_TPROTO: return &gco2p(o)->gclist;
|
case LUA_TPROTO: return &gco2p(o)->gclist;
|
||||||
|
case LUA_TUSERDATA: {
|
||||||
|
Udata *u = gco2u(o);
|
||||||
|
lua_assert(u->nuvalue > 0);
|
||||||
|
return &u->gclist;
|
||||||
|
}
|
||||||
default: lua_assert(0); return 0;
|
default: lua_assert(0); return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,8 +294,17 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
|||||||
markvalue(g, uv->v); /* mark its content */
|
markvalue(g, uv->v); /* mark its content */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case LUA_TUSERDATA: {
|
||||||
|
Udata *u = gco2u(o);
|
||||||
|
if (u->nuvalue == 0) { /* no user values? */
|
||||||
|
markobjectN(g, u->metatable); /* mark its metatable */
|
||||||
|
gray2black(o); /* nothing else to mark */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* else *//* FALLTHROUGH */
|
||||||
|
}
|
||||||
case LUA_TLCL: case LUA_TCCL: case LUA_TTABLE:
|
case LUA_TLCL: case LUA_TCCL: case LUA_TTABLE:
|
||||||
case LUA_TUSERDATA: case LUA_TTHREAD: case LUA_TPROTO: {
|
case LUA_TTHREAD: case LUA_TPROTO: {
|
||||||
linkobjgclist(o, g->gray);
|
linkobjgclist(o, g->gray);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
37
lobject.h
37
lobject.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 2.138 2018/02/25 12:48:16 roberto Exp roberto $
|
** $Id: lobject.h,v 2.139 2018/02/25 12:52:32 roberto Exp roberto $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -70,7 +70,7 @@ typedef struct TValue {
|
|||||||
#define rttype(o) ((o)->tt_)
|
#define rttype(o) ((o)->tt_)
|
||||||
|
|
||||||
/* tag with no variants (bits 0-3) */
|
/* tag with no variants (bits 0-3) */
|
||||||
#define novariant(x) ((x) & 0x0F)
|
#define novariant(t) ((t) & 0x0F)
|
||||||
|
|
||||||
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
|
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
|
||||||
#define ttyperaw(t) ((t) & 0x3F)
|
#define ttyperaw(t) ((t) & 0x3F)
|
||||||
@@ -379,7 +379,7 @@ typedef union UTString {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
|
#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
|
||||||
#define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))
|
#define ttisfulluserdata(o) checktype((o), LUA_TUSERDATA)
|
||||||
|
|
||||||
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
|
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
|
||||||
#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
|
#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
|
||||||
@@ -403,7 +403,8 @@ typedef union UValue {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Header for userdata; memory area follows the end of this structure.
|
** Header for userdata with user values;
|
||||||
|
** memory area follows the end of this structure.
|
||||||
*/
|
*/
|
||||||
typedef struct Udata {
|
typedef struct Udata {
|
||||||
CommonHeader;
|
CommonHeader;
|
||||||
@@ -415,15 +416,33 @@ typedef struct Udata {
|
|||||||
} Udata;
|
} Udata;
|
||||||
|
|
||||||
|
|
||||||
/* computes the offset of the memory area of a userdata */
|
|
||||||
#define udatamemoffset(nuv) (sizeof(Udata) + (sizeof(UValue) * ((nuv) - 1)))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Get the address of the memory block inside 'Udata'.
|
** Header for userdata with no user values. These userdata do not need
|
||||||
|
** to be gray during GC, and therefore do not need a 'gclist' field.
|
||||||
|
** To simplify, the code always use 'Udata' for both kinds of userdata,
|
||||||
|
** making sure it never accesses 'gclist' on userdata with no user values.
|
||||||
|
** This structure here is used only to compute the correct size for
|
||||||
|
** this representation. (The 'bindata' field in its end ensures correct
|
||||||
|
** alignment for binary data following this header.)
|
||||||
*/
|
*/
|
||||||
|
typedef struct Udata0 {
|
||||||
|
CommonHeader;
|
||||||
|
unsigned short nuvalue; /* number of user values */
|
||||||
|
size_t len; /* number of bytes */
|
||||||
|
struct Table *metatable;
|
||||||
|
union {LUAI_MAXALIGN;} bindata;
|
||||||
|
} Udata0;
|
||||||
|
|
||||||
|
|
||||||
|
/* compute the offset of the memory area of a userdata */
|
||||||
|
#define udatamemoffset(nuv) \
|
||||||
|
((nuv) == 0 ? offsetof(Udata0, bindata) \
|
||||||
|
: offsetof(Udata, uv) + (sizeof(UValue) * (nuv)))
|
||||||
|
|
||||||
|
/* get the address of the memory block inside 'Udata' */
|
||||||
#define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue))
|
#define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue))
|
||||||
|
|
||||||
/* computes the size of a userdata */
|
/* compute the size of a userdata */
|
||||||
#define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb))
|
#define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb))
|
||||||
|
|
||||||
/* }================================================================== */
|
/* }================================================================== */
|
||||||
|
|||||||
Reference in New Issue
Block a user