diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-01-19 13:54:26 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-01-19 13:54:26 -0200 |
commit | 621ef9f7675829234e75b0b3e73afc7a1a74aa16 (patch) | |
tree | 5ced360a5af2f8dd0b57fc6849148b6dffa5c12a /lfunc.c | |
parent | d89a56f86921dc3c62edf0345748ba5c41b2632c (diff) | |
download | lua-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.c | 12 |
1 files changed, 9 insertions, 3 deletions
@@ -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 | } |