summaryrefslogtreecommitdiff
path: root/lfunc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-01-19 13:54:26 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-01-19 13:54:26 -0200
commit621ef9f7675829234e75b0b3e73afc7a1a74aa16 (patch)
tree5ced360a5af2f8dd0b57fc6849148b6dffa5c12a /lfunc.c
parentd89a56f86921dc3c62edf0345748ba5c41b2632c (diff)
downloadlua-621ef9f7675829234e75b0b3e73afc7a1a74aa16.tar.gz
lua-621ef9f7675829234e75b0b3e73afc7a1a74aa16.tar.bz2
lua-621ef9f7675829234e75b0b3e73afc7a1a74aa16.zip
better control over GC collors of upvalues
Diffstat (limited to 'lfunc.c')
-rw-r--r--lfunc.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/lfunc.c b/lfunc.c
index 3171c5ec..65d70cfb 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -56,7 +56,11 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
56 UpVal *uv; 56 UpVal *uv;
57 while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { 57 while ((p = ngcotouv(*pp)) != NULL && p->v >= level) {
58 lua_assert(p->v != &p->u.value); 58 lua_assert(p->v != &p->u.value);
59 if (p->v == level) return p; 59 if (p->v == level) { /* found a corresponding upvalue? */
60 if (isdead(G(L), obj2gco(p))) /* is it dead? */
61 changewhite(obj2gco(p)); /* ressurect it */
62 return p;
63 }
60 pp = &p->next; 64 pp = &p->next;
61 } 65 }
62 uv = luaM_new(L, UpVal); /* not found: create a new one */ 66 uv = luaM_new(L, UpVal); /* not found: create a new one */
@@ -65,8 +69,6 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
65 uv->v = level; /* current value lives in the stack */ 69 uv->v = level; /* current value lives in the stack */
66 uv->next = *pp; /* chain it in the proper position */ 70 uv->next = *pp; /* chain it in the proper position */
67 *pp = obj2gco(uv); 71 *pp = obj2gco(uv);
68 lua_assert(g->uvhead.u.l.next->u.l.prev == &g->uvhead &&
69 g->uvhead.u.l.prev->u.l.next == &g->uvhead);
70 uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ 72 uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
71 uv->u.l.next = g->uvhead.u.l.next; 73 uv->u.l.next = g->uvhead.u.l.next;
72 uv->u.l.next->u.l.prev = uv; 74 uv->u.l.next->u.l.prev = uv;
@@ -102,6 +104,10 @@ void luaF_close (lua_State *L, StkId level) {
102 else { 104 else {
103 unlinkupval(uv); 105 unlinkupval(uv);
104 setobj(L, &uv->u.value, uv->v); 106 setobj(L, &uv->u.value, uv->v);
107 if (isgray(o)) {
108 gray2black(o); /* closed upvalues are never gray */
109 luaC_barrier(L, uv, uv->v);
110 }
105 uv->v = &uv->u.value; /* now current value lives here */ 111 uv->v = &uv->u.value; /* now current value lives here */
106 luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ 112 luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
107 } 113 }