aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-02-19 17:06:56 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-02-19 17:06:56 -0300
commit1afd5a152dc8b3a304236dc4e07bca38ea5eb53a (patch)
tree7c4f880b09a023a3fe527d7d2cbcec9f11c09302
parent422318f6777d8d3bac13ade797d9c8eaa38686b6 (diff)
downloadlua-1afd5a152dc8b3a304236dc4e07bca38ea5eb53a.tar.gz
lua-1afd5a152dc8b3a304236dc4e07bca38ea5eb53a.tar.bz2
lua-1afd5a152dc8b3a304236dc4e07bca38ea5eb53a.zip
more generic way to handle 'gclist'
-rw-r--r--lapi.c8
-rw-r--r--lgc.c112
-rw-r--r--lgc.h4
-rw-r--r--ltable.c4
-rw-r--r--lvm.c6
-rw-r--r--lvm.h4
6 files changed, 63 insertions, 75 deletions
diff --git a/lapi.c b/lapi.c
index d4bf7e17..1ec649b0 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.282 2018/01/29 16:21:35 roberto Exp roberto $ 2** $Id: lapi.c,v 2.283 2018/02/05 17:10:52 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -828,7 +828,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
828 slot = luaH_set(L, hvalue(o), s2v(L->top - 2)); 828 slot = luaH_set(L, hvalue(o), s2v(L->top - 2));
829 setobj2t(L, slot, s2v(L->top - 1)); 829 setobj2t(L, slot, s2v(L->top - 1));
830 invalidateTMcache(hvalue(o)); 830 invalidateTMcache(hvalue(o));
831 luaC_barrierback(L, hvalue(o), s2v(L->top - 1)); 831 luaC_barrierback(L, gcvalue(o), s2v(L->top - 1));
832 L->top -= 2; 832 L->top -= 2;
833 lua_unlock(L); 833 lua_unlock(L);
834} 834}
@@ -841,7 +841,7 @@ LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
841 o = index2value(L, idx); 841 o = index2value(L, idx);
842 api_check(L, ttistable(o), "table expected"); 842 api_check(L, ttistable(o), "table expected");
843 luaH_setint(L, hvalue(o), n, s2v(L->top - 1)); 843 luaH_setint(L, hvalue(o), n, s2v(L->top - 1));
844 luaC_barrierback(L, hvalue(o), s2v(L->top - 1)); 844 luaC_barrierback(L, gcvalue(o), s2v(L->top - 1));
845 L->top--; 845 L->top--;
846 lua_unlock(L); 846 lua_unlock(L);
847} 847}
@@ -857,7 +857,7 @@ LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
857 setpvalue(&k, cast_voidp(p)); 857 setpvalue(&k, cast_voidp(p));
858 slot = luaH_set(L, hvalue(o), &k); 858 slot = luaH_set(L, hvalue(o), &k);
859 setobj2t(L, slot, s2v(L->top - 1)); 859 setobj2t(L, slot, s2v(L->top - 1));
860 luaC_barrierback(L, hvalue(o), s2v(L->top - 1)); 860 luaC_barrierback(L, gcvalue(o), s2v(L->top - 1));
861 L->top--; 861 L->top--;
862 lua_unlock(L); 862 lua_unlock(L);
863} 863}
diff --git a/lgc.c b/lgc.c
index 20397e48..77ccae0a 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.245 2018/01/28 15:13:26 roberto Exp roberto $ 2** $Id: lgc.c,v 2.248 2018/02/19 16:02:25 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*/
@@ -110,13 +110,32 @@ static lu_mem atomic (lua_State *L);
110#define gnodelast(h) gnode(h, cast_sizet(sizenode(h))) 110#define gnodelast(h) gnode(h, cast_sizet(sizenode(h)))
111 111
112 112
113static GCObject **getgclist (GCObject *o) {
114 switch (o->tt) {
115 case LUA_TTABLE: return &gco2t(o)->gclist;
116 case LUA_TLCL: return &gco2lcl(o)->gclist;
117 case LUA_TCCL: return &gco2ccl(o)->gclist;
118 case LUA_TTHREAD: return &gco2th(o)->gclist;
119 case LUA_TPROTO: return &gco2p(o)->gclist;
120 default: lua_assert(0); return 0;
121 }
122}
123
124
113/* 125/*
114** link collectable object 'o' into list pointed by 'p' 126** Link a collectable object 'o' with a known type into list pointed by 'p'.
115*/ 127*/
116#define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o)) 128#define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o))
117 129
118 130
119/* 131/*
132** Link a generic collectable object 'o' into list pointed by 'p'.
133*/
134#define linkobjgclist(o,p) (*getgclist(o) = (p), (p) = obj2gco(o))
135
136
137
138/*
120** Clear keys for empty entries in tables. If entry is empty 139** Clear keys for empty entries in tables. If entry is empty
121** and its key is not marked, mark its entry as dead. This allows the 140** and its key is not marked, mark its entry as dead. This allows the
122** collection of the key, but keeps its entry in the table (its removal 141** collection of the key, but keeps its entry in the table (its removal
@@ -175,14 +194,14 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
175** barrier that moves collector backward, that is, mark the black object 194** barrier that moves collector backward, that is, mark the black object
176** pointing to a white object as gray again. 195** pointing to a white object as gray again.
177*/ 196*/
178void luaC_barrierback_ (lua_State *L, Table *t) { 197void luaC_barrierback_ (lua_State *L, GCObject *o) {
179 global_State *g = G(L); 198 global_State *g = G(L);
180 lua_assert(isblack(t) && !isdead(g, t)); 199 lua_assert(isblack(o) && !isdead(g, o));
181 lua_assert(g->gckind != KGC_GEN || (isold(t) && getage(t) != G_TOUCHED1)); 200 lua_assert(g->gckind != KGC_GEN || (isold(o) && getage(o) != G_TOUCHED1));
182 if (getage(t) != G_TOUCHED2) /* not already in gray list? */ 201 if (getage(o) != G_TOUCHED2) /* not already in gray list? */
183 linkgclist(t, g->grayagain); /* link it in 'grayagain' */ 202 linkobjgclist(o, g->grayagain); /* link it in 'grayagain' */
184 black2gray(t); /* make table gray (again) */ 203 black2gray(o); /* make table gray (again) */
185 setage(t, G_TOUCHED1); /* touched in current cycle */ 204 setage(o, G_TOUCHED1); /* touched in current cycle */
186} 205}
187 206
188 207
@@ -276,24 +295,9 @@ static void reallymarkobject (global_State *g, GCObject *o) {
276 markvalue(g, uv->v); /* mark its content */ 295 markvalue(g, uv->v); /* mark its content */
277 break; 296 break;
278 } 297 }
279 case LUA_TLCL: { 298 case LUA_TLCL: case LUA_TCCL: case LUA_TTABLE:
280 linkgclist(gco2lcl(o), g->gray); 299 case LUA_TTHREAD: case LUA_TPROTO: {
281 break; 300 linkobjgclist(o, g->gray);
282 }
283 case LUA_TCCL: {
284 linkgclist(gco2ccl(o), g->gray);
285 break;
286 }
287 case LUA_TTABLE: {
288 linkgclist(gco2t(o), g->gray);
289 break;
290 }
291 case LUA_TTHREAD: {
292 linkgclist(gco2th(o), g->gray);
293 break;
294 }
295 case LUA_TPROTO: {
296 linkgclist(gco2p(o), g->gray);
297 break; 301 break;
298 } 302 }
299 default: lua_assert(0); break; 303 default: lua_assert(0); break;
@@ -605,34 +609,18 @@ static int traversethread (global_State *g, lua_State *th) {
605static lu_mem propagatemark (global_State *g) { 609static lu_mem propagatemark (global_State *g) {
606 GCObject *o = g->gray; 610 GCObject *o = g->gray;
607 gray2black(o); 611 gray2black(o);
612 g->gray = *getgclist(o); /* remove from 'gray' list */
608 switch (o->tt) { 613 switch (o->tt) {
609 case LUA_TTABLE: { 614 case LUA_TTABLE: return traversetable(g, gco2t(o));
610 Table *h = gco2t(o); 615 case LUA_TLCL: return traverseLclosure(g, gco2lcl(o));
611 g->gray = h->gclist; /* remove from 'gray' list */ 616 case LUA_TCCL: return traverseCclosure(g, gco2ccl(o));
612 return traversetable(g, h); 617 case LUA_TPROTO: return traverseproto(g, gco2p(o));
613 }
614 case LUA_TLCL: {
615 LClosure *cl = gco2lcl(o);
616 g->gray = cl->gclist; /* remove from 'gray' list */
617 return traverseLclosure(g, cl);
618 }
619 case LUA_TCCL: {
620 CClosure *cl = gco2ccl(o);
621 g->gray = cl->gclist; /* remove from 'gray' list */
622 return traverseCclosure(g, cl);
623 }
624 case LUA_TTHREAD: { 618 case LUA_TTHREAD: {
625 lua_State *th = gco2th(o); 619 lua_State *th = gco2th(o);
626 g->gray = th->gclist; /* remove from 'gray' list */
627 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ 620 linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
628 black2gray(o); 621 black2gray(o);
629 return traversethread(g, th); 622 return traversethread(g, th);
630 } 623 }
631 case LUA_TPROTO: {
632 Proto *p = gco2p(o);
633 g->gray = p->gclist; /* remove from 'gray' list */
634 return traverseproto(g, p);
635 }
636 default: lua_assert(0); return 0; 624 default: lua_assert(0); return 0;
637 } 625 }
638} 626}
@@ -1069,8 +1057,8 @@ static void whitelist (global_State *g, GCObject *p) {
1069** Correct a list of gray objects. Because this correction is 1057** Correct a list of gray objects. Because this correction is
1070** done after sweeping, young objects can be white and still 1058** done after sweeping, young objects can be white and still
1071** be in the list. They are only removed. 1059** be in the list. They are only removed.
1072** For tables, advance 'touched1' to 'touched2'; 'touched2' objects 1060** For tables and userdata, advance 'touched1' to 'touched2'; 'touched2'
1073** become regular old and are removed from the list. 1061** objects become regular old and are removed from the list.
1074** For threads, just remove white ones from the list. 1062** For threads, just remove white ones from the list.
1075*/ 1063*/
1076static GCObject **correctgraylist (GCObject **p) { 1064static GCObject **correctgraylist (GCObject **p) {
@@ -1078,21 +1066,21 @@ static GCObject **correctgraylist (GCObject **p) {
1078 while ((curr = *p) != NULL) { 1066 while ((curr = *p) != NULL) {
1079 switch (curr->tt) { 1067 switch (curr->tt) {
1080 case LUA_TTABLE: { 1068 case LUA_TTABLE: {
1081 Table *h = gco2t(curr); 1069 GCObject **next = getgclist(curr);
1082 if (getage(h) == G_TOUCHED1) { /* touched in this cycle? */ 1070 if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */
1083 lua_assert(isgray(h)); 1071 lua_assert(isgray(curr));
1084 gray2black(h); /* make it black, for next barrier */ 1072 gray2black(curr); /* make it black, for next barrier */
1085 changeage(h, G_TOUCHED1, G_TOUCHED2); 1073 changeage(curr, G_TOUCHED1, G_TOUCHED2);
1086 p = &h->gclist; /* go to next element */ 1074 p = next; /* go to next element */
1087 } 1075 }
1088 else { 1076 else {
1089 if (!iswhite(h)) { 1077 if (!iswhite(curr)) {
1090 lua_assert(isold(h)); 1078 lua_assert(isold(curr));
1091 if (getage(h) == G_TOUCHED2) 1079 if (getage(curr) == G_TOUCHED2)
1092 changeage(h, G_TOUCHED2, G_OLD); 1080 changeage(curr, G_TOUCHED2, G_OLD);
1093 gray2black(h); /* make it black */ 1081 gray2black(curr); /* make it black */
1094 } 1082 }
1095 *p = h->gclist; /* remove 'curr' from gray list */ 1083 *p = *next; /* remove 'curr' from gray list */
1096 } 1084 }
1097 break; 1085 break;
1098 } 1086 }
diff --git a/lgc.h b/lgc.h
index fec0e5a7..fc62cfd8 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 2.100 2018/01/28 15:13:26 roberto Exp roberto $ 2** $Id: lgc.h,v 2.102 2018/02/19 13:55:34 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*/
@@ -173,7 +173,7 @@ LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
173LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 173LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
174LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); 174LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
175LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 175LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
176LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o); 176LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
177LUAI_FUNC void luaC_protobarrier_ (lua_State *L, Proto *p); 177LUAI_FUNC void luaC_protobarrier_ (lua_State *L, Proto *p);
178LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 178LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
179LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); 179LUAI_FUNC void luaC_changemode (lua_State *L, int newmode);
diff --git a/ltable.c b/ltable.c
index a8929961..dbe5e2ed 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.130 2017/12/29 15:58:23 roberto Exp roberto $ 2** $Id: ltable.c,v 2.131 2018/01/28 15:13:26 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -600,7 +600,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
600 } 600 }
601 } 601 }
602 setnodekey(L, mp, key); 602 setnodekey(L, mp, key);
603 luaC_barrierback(L, t, key); 603 luaC_barrierback(L, obj2gco(t), key);
604 lua_assert(ttisnil(gval(mp))); 604 lua_assert(ttisnil(gval(mp)));
605 return gval(mp); 605 return gval(mp);
606} 606}
diff --git a/lvm.c b/lvm.c
index 0ba6b4bc..0389352f 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.340 2018/02/15 15:34:29 roberto Exp roberto $ 2** $Id: lvm.c,v 2.341 2018/02/17 19:20:00 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -223,7 +223,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
223 /* no metamethod and (now) there is an entry with given key */ 223 /* no metamethod and (now) there is an entry with given key */
224 setobj2t(L, cast(TValue *, slot), val); /* set its new value */ 224 setobj2t(L, cast(TValue *, slot), val); /* set its new value */
225 invalidateTMcache(h); 225 invalidateTMcache(h);
226 luaC_barrierback(L, h, val); 226 luaC_barrierback(L, obj2gco(h), val);
227 return; 227 return;
228 } 228 }
229 /* else will try the metamethod */ 229 /* else will try the metamethod */
@@ -1691,7 +1691,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1691 TValue *val = s2v(ra + n); 1691 TValue *val = s2v(ra + n);
1692 setobj2t(L, &h->array[last - 1], val); 1692 setobj2t(L, &h->array[last - 1], val);
1693 last--; 1693 last--;
1694 luaC_barrierback(L, h, val); 1694 luaC_barrierback(L, obj2gco(h), val);
1695 } 1695 }
1696 vmbreak; 1696 vmbreak;
1697 } 1697 }
diff --git a/lvm.h b/lvm.h
index 0d2eed14..2cc4130a 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 2.47 2017/11/08 14:50:23 roberto Exp roberto $ 2** $Id: lvm.h,v 2.48 2017/11/29 13:02:17 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -96,7 +96,7 @@
96*/ 96*/
97#define luaV_finishfastset(L,t,slot,v) \ 97#define luaV_finishfastset(L,t,slot,v) \
98 { setobj2t(L, cast(TValue *,slot), v); \ 98 { setobj2t(L, cast(TValue *,slot), v); \
99 luaC_barrierback(L, hvalue(t), v); } 99 luaC_barrierback(L, gcvalue(t), v); }
100 100
101 101
102 102