aboutsummaryrefslogtreecommitdiff
path: root/src/lua/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua/lgc.c')
-rw-r--r--src/lua/lgc.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/src/lua/lgc.c b/src/lua/lgc.c
index 4a7bcae..5dba56f 100644
--- a/src/lua/lgc.c
+++ b/src/lua/lgc.c
@@ -161,18 +161,17 @@ static void linkgclist_ (GCObject *o, GCObject **pnext, GCObject **list) {
161 161
162 162
163/* 163/*
164** Clear keys for empty entries in tables. If entry is empty 164** Clear keys for empty entries in tables. If entry is empty, mark its
165** and its key is not marked, mark its entry as dead. This allows the 165** entry as dead. This allows the collection of the key, but keeps its
166** collection of the key, but keeps its entry in the table (its removal 166** entry in the table: its removal could break a chain and could break
167** could break a chain). The main feature of a dead key is that it must 167** a table traversal. Other places never manipulate dead keys, because
168** be different from any other value, to do not disturb searches. 168** its associated empty value is enough to signal that the entry is
169** Other places never manipulate dead keys, because its associated empty 169** logically empty.
170** value is enough to signal that the entry is logically empty.
171*/ 170*/
172static void clearkey (Node *n) { 171static void clearkey (Node *n) {
173 lua_assert(isempty(gval(n))); 172 lua_assert(isempty(gval(n)));
174 if (keyiswhite(n)) 173 if (keyiscollectable(n))
175 setdeadkey(n); /* unused and unmarked key; remove it */ 174 setdeadkey(n); /* unused key; remove it */
176} 175}
177 176
178 177
@@ -301,7 +300,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
301 if (upisopen(uv)) 300 if (upisopen(uv))
302 set2gray(uv); /* open upvalues are kept gray */ 301 set2gray(uv); /* open upvalues are kept gray */
303 else 302 else
304 set2black(o); /* closed upvalues are visited here */ 303 set2black(uv); /* closed upvalues are visited here */
305 markvalue(g, uv->v); /* mark its content */ 304 markvalue(g, uv->v); /* mark its content */
306 break; 305 break;
307 } 306 }
@@ -309,7 +308,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
309 Udata *u = gco2u(o); 308 Udata *u = gco2u(o);
310 if (u->nuvalue == 0) { /* no user values? */ 309 if (u->nuvalue == 0) { /* no user values? */
311 markobjectN(g, u->metatable); /* mark its metatable */ 310 markobjectN(g, u->metatable); /* mark its metatable */
312 set2black(o); /* nothing else to mark */ 311 set2black(u); /* nothing else to mark */
313 break; 312 break;
314 } 313 }
315 /* else... */ 314 /* else... */
@@ -633,8 +632,7 @@ static int traversethread (global_State *g, lua_State *th) {
633 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) 632 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
634 markobject(g, uv); /* open upvalues cannot be collected */ 633 markobject(g, uv); /* open upvalues cannot be collected */
635 if (g->gcstate == GCSatomic) { /* final traversal? */ 634 if (g->gcstate == GCSatomic) { /* final traversal? */
636 StkId lim = th->stack + th->stacksize; /* real end of stack */ 635 for (; o < th->stack_last; o++) /* clear not-marked stack slice */
637 for (; o < lim; o++) /* clear not-marked stack slice */
638 setnilvalue(s2v(o)); 636 setnilvalue(s2v(o));
639 /* 'remarkupvals' may have removed thread from 'twups' list */ 637 /* 'remarkupvals' may have removed thread from 'twups' list */
640 if (!isintwups(th) && th->openupval != NULL) { 638 if (!isintwups(th) && th->openupval != NULL) {
@@ -644,7 +642,7 @@ static int traversethread (global_State *g, lua_State *th) {
644 } 642 }
645 else if (!g->gcemergency) 643 else if (!g->gcemergency)
646 luaD_shrinkstack(th); /* do not change stack in emergency cycle */ 644 luaD_shrinkstack(th); /* do not change stack in emergency cycle */
647 return 1 + th->stacksize; 645 return 1 + stacksize(th);
648} 646}
649 647
650 648
@@ -771,12 +769,16 @@ static void freeobj (lua_State *L, GCObject *o) {
771 case LUA_VUPVAL: 769 case LUA_VUPVAL:
772 freeupval(L, gco2upv(o)); 770 freeupval(L, gco2upv(o));
773 break; 771 break;
774 case LUA_VLCL: 772 case LUA_VLCL: {
775 luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); 773 LClosure *cl = gco2lcl(o);
774 luaM_freemem(L, cl, sizeLclosure(cl->nupvalues));
776 break; 775 break;
777 case LUA_VCCL: 776 }
778 luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); 777 case LUA_VCCL: {
778 CClosure *cl = gco2ccl(o);
779 luaM_freemem(L, cl, sizeCclosure(cl->nupvalues));
779 break; 780 break;
781 }
780 case LUA_VTABLE: 782 case LUA_VTABLE:
781 luaH_free(L, gco2t(o)); 783 luaH_free(L, gco2t(o));
782 break; 784 break;
@@ -788,13 +790,17 @@ static void freeobj (lua_State *L, GCObject *o) {
788 luaM_freemem(L, o, sizeudata(u->nuvalue, u->len)); 790 luaM_freemem(L, o, sizeudata(u->nuvalue, u->len));
789 break; 791 break;
790 } 792 }
791 case LUA_VSHRSTR: 793 case LUA_VSHRSTR: {
792 luaS_remove(L, gco2ts(o)); /* remove it from hash table */ 794 TString *ts = gco2ts(o);
793 luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen)); 795 luaS_remove(L, ts); /* remove it from hash table */
796 luaM_freemem(L, ts, sizelstring(ts->shrlen));
794 break; 797 break;
795 case LUA_VLNGSTR: 798 }
796 luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen)); 799 case LUA_VLNGSTR: {
800 TString *ts = gco2ts(o);
801 luaM_freemem(L, ts, sizelstring(ts->u.lnglen));
797 break; 802 break;
803 }
798 default: lua_assert(0); 804 default: lua_assert(0);
799 } 805 }
800} 806}