diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-19 17:06:56 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-19 17:06:56 -0300 |
| commit | 1afd5a152dc8b3a304236dc4e07bca38ea5eb53a (patch) | |
| tree | 7c4f880b09a023a3fe527d7d2cbcec9f11c09302 | |
| parent | 422318f6777d8d3bac13ade797d9c8eaa38686b6 (diff) | |
| download | lua-1afd5a152dc8b3a304236dc4e07bca38ea5eb53a.tar.gz lua-1afd5a152dc8b3a304236dc4e07bca38ea5eb53a.tar.bz2 lua-1afd5a152dc8b3a304236dc4e07bca38ea5eb53a.zip | |
more generic way to handle 'gclist'
| -rw-r--r-- | lapi.c | 8 | ||||
| -rw-r--r-- | lgc.c | 112 | ||||
| -rw-r--r-- | lgc.h | 4 | ||||
| -rw-r--r-- | ltable.c | 4 | ||||
| -rw-r--r-- | lvm.c | 6 | ||||
| -rw-r--r-- | lvm.h | 4 |
6 files changed, 63 insertions, 75 deletions
| @@ -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 | } |
| @@ -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 | ||
| 113 | static 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 | */ |
| 178 | void luaC_barrierback_ (lua_State *L, Table *t) { | 197 | void 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) { | |||
| 605 | static lu_mem propagatemark (global_State *g) { | 609 | static 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 | */ |
| 1076 | static GCObject **correctgraylist (GCObject **p) { | 1064 | static 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 | } |
| @@ -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); | |||
| 173 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); | 173 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
| 174 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); | 174 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); |
| 175 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); | 175 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); |
| 176 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o); | 176 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); |
| 177 | LUAI_FUNC void luaC_protobarrier_ (lua_State *L, Proto *p); | 177 | LUAI_FUNC void luaC_protobarrier_ (lua_State *L, Proto *p); |
| 178 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); | 178 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); |
| 179 | LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); | 179 | LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); |
| @@ -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 | } |
| @@ -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 | } |
| @@ -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 | ||
