aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-02-26 10:35:03 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-02-26 10:35:03 -0300
commit2952bc5fc9cdc05ed061539cb7be26899513f004 (patch)
treeac3b1438843797e816ed04fac102c0820ea174ea
parent38d3bc89093010fa9c460b61a1965d9077b5378f (diff)
downloadlua-2952bc5fc9cdc05ed061539cb7be26899513f004.tar.gz
lua-2952bc5fc9cdc05ed061539cb7be26899513f004.tar.bz2
lua-2952bc5fc9cdc05ed061539cb7be26899513f004.zip
special compact representation for userdata with no user values
(a common case)
-rw-r--r--lgc.c19
-rw-r--r--lobject.h37
2 files changed, 44 insertions, 12 deletions
diff --git a/lgc.c b/lgc.c
index 13f372d3..9da0f498 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.250 2018/02/23 13:16:18 roberto Exp roberto $ 2** $Id: lgc.c,v 2.251 2018/02/23 13:21:27 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -118,11 +118,15 @@ static lu_mem atomic (lua_State *L);
118static GCObject **getgclist (GCObject *o) { 118static GCObject **getgclist (GCObject *o) {
119 switch (o->tt) { 119 switch (o->tt) {
120 case LUA_TTABLE: return &gco2t(o)->gclist; 120 case LUA_TTABLE: return &gco2t(o)->gclist;
121 case LUA_TUSERDATA: return &gco2u(o)->gclist;
122 case LUA_TLCL: return &gco2lcl(o)->gclist; 121 case LUA_TLCL: return &gco2lcl(o)->gclist;
123 case LUA_TCCL: return &gco2ccl(o)->gclist; 122 case LUA_TCCL: return &gco2ccl(o)->gclist;
124 case LUA_TTHREAD: return &gco2th(o)->gclist; 123 case LUA_TTHREAD: return &gco2th(o)->gclist;
125 case LUA_TPROTO: return &gco2p(o)->gclist; 124 case LUA_TPROTO: return &gco2p(o)->gclist;
125 case LUA_TUSERDATA: {
126 Udata *u = gco2u(o);
127 lua_assert(u->nuvalue > 0);
128 return &u->gclist;
129 }
126 default: lua_assert(0); return 0; 130 default: lua_assert(0); return 0;
127 } 131 }
128} 132}
@@ -290,8 +294,17 @@ static void reallymarkobject (global_State *g, GCObject *o) {
290 markvalue(g, uv->v); /* mark its content */ 294 markvalue(g, uv->v); /* mark its content */
291 break; 295 break;
292 } 296 }
297 case LUA_TUSERDATA: {
298 Udata *u = gco2u(o);
299 if (u->nuvalue == 0) { /* no user values? */
300 markobjectN(g, u->metatable); /* mark its metatable */
301 gray2black(o); /* nothing else to mark */
302 break;
303 }
304 /* else *//* FALLTHROUGH */
305 }
293 case LUA_TLCL: case LUA_TCCL: case LUA_TTABLE: 306 case LUA_TLCL: case LUA_TCCL: case LUA_TTABLE:
294 case LUA_TUSERDATA: case LUA_TTHREAD: case LUA_TPROTO: { 307 case LUA_TTHREAD: case LUA_TPROTO: {
295 linkobjgclist(o, g->gray); 308 linkobjgclist(o, g->gray);
296 break; 309 break;
297 } 310 }
diff --git a/lobject.h b/lobject.h
index 8e7f4101..6d34759f 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.138 2018/02/25 12:48:16 roberto Exp roberto $ 2** $Id: lobject.h,v 2.139 2018/02/25 12:52:32 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -70,7 +70,7 @@ typedef struct TValue {
70#define rttype(o) ((o)->tt_) 70#define rttype(o) ((o)->tt_)
71 71
72/* tag with no variants (bits 0-3) */ 72/* tag with no variants (bits 0-3) */
73#define novariant(x) ((x) & 0x0F) 73#define novariant(t) ((t) & 0x0F)
74 74
75/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ 75/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
76#define ttyperaw(t) ((t) & 0x3F) 76#define ttyperaw(t) ((t) & 0x3F)
@@ -379,7 +379,7 @@ typedef union UTString {
379*/ 379*/
380 380
381#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) 381#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
382#define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA)) 382#define ttisfulluserdata(o) checktype((o), LUA_TUSERDATA)
383 383
384#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) 384#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
385#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) 385#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
@@ -403,7 +403,8 @@ typedef union UValue {
403 403
404 404
405/* 405/*
406** Header for userdata; memory area follows the end of this structure. 406** Header for userdata with user values;
407** memory area follows the end of this structure.
407*/ 408*/
408typedef struct Udata { 409typedef struct Udata {
409 CommonHeader; 410 CommonHeader;
@@ -415,15 +416,33 @@ typedef struct Udata {
415} Udata; 416} Udata;
416 417
417 418
418/* computes the offset of the memory area of a userdata */
419#define udatamemoffset(nuv) (sizeof(Udata) + (sizeof(UValue) * ((nuv) - 1)))
420
421/* 419/*
422** Get the address of the memory block inside 'Udata'. 420** Header for userdata with no user values. These userdata do not need
421** to be gray during GC, and therefore do not need a 'gclist' field.
422** To simplify, the code always use 'Udata' for both kinds of userdata,
423** making sure it never accesses 'gclist' on userdata with no user values.
424** This structure here is used only to compute the correct size for
425** this representation. (The 'bindata' field in its end ensures correct
426** alignment for binary data following this header.)
423*/ 427*/
428typedef struct Udata0 {
429 CommonHeader;
430 unsigned short nuvalue; /* number of user values */
431 size_t len; /* number of bytes */
432 struct Table *metatable;
433 union {LUAI_MAXALIGN;} bindata;
434} Udata0;
435
436
437/* compute the offset of the memory area of a userdata */
438#define udatamemoffset(nuv) \
439 ((nuv) == 0 ? offsetof(Udata0, bindata) \
440 : offsetof(Udata, uv) + (sizeof(UValue) * (nuv)))
441
442/* get the address of the memory block inside 'Udata' */
424#define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue)) 443#define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue))
425 444
426/* computes the size of a userdata */ 445/* compute the size of a userdata */
427#define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb)) 446#define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb))
428 447
429/* }================================================================== */ 448/* }================================================================== */