diff options
Diffstat (limited to 'src/lua/lgc.c')
| -rw-r--r-- | src/lua/lgc.c | 52 |
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 | */ |
| 172 | static void clearkey (Node *n) { | 171 | static 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 | } |
