aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-06-07 13:55:34 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-06-07 13:55:34 -0300
commitfabe4ec487cb034ef983a29c52df2927be463d3c (patch)
tree4b824977d6b99b657c821681ca1a643ad345569a
parent575074fd857b90cd7c14c7b172e8fe147080962a (diff)
downloadlua-fabe4ec487cb034ef983a29c52df2927be463d3c.tar.gz
lua-fabe4ec487cb034ef983a29c52df2927be463d3c.tar.bz2
lua-fabe4ec487cb034ef983a29c52df2927be463d3c.zip
better barrier for prototypes
-rw-r--r--lgc.c48
-rw-r--r--lgc.h8
-rw-r--r--lvm.c10
3 files changed, 30 insertions, 36 deletions
diff --git a/lgc.c b/lgc.c
index bf36d025..dd6af6c5 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.97 2010/06/02 18:36:58 roberto Exp roberto $ 2** $Id: lgc.c,v 2.98 2010/06/04 13:25:10 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*/
@@ -157,14 +157,24 @@ void luaC_barrierback_ (lua_State *L, GCObject *o) {
157 157
158 158
159/* 159/*
160** barrier for prototypes 160** barrier for prototypes. When creating first closure (cache is
161** NULL), use a forward barrier; this may be the only closure of the
162** prototype (if it is a "regular" function, with a single instance)
163** and the prototype may be big, so it is better to avoid traversing
164** it again. Otherwise, use a backward barrier, to avoid marking all
165** possible instances.
161*/ 166*/
162LUAI_FUNC void luaC_barrierproto_ (lua_State *L, GCObject *p) { 167LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) {
163 global_State *g = G(L); 168 global_State *g = G(L);
164 lua_assert(isblack(p)); 169 lua_assert(isblack(obj2gco(p)));
165 black2gray(p); /* make object gray (again) */ 170 if (p->cache == NULL) { /* first time? */
166 gco2p(p)->gclist = g->clearcache; 171 luaC_objbarrier(L, p, c);
167 g->clearcache = p; 172 }
173 else { /* use a backward barrier */
174 black2gray(obj2gco(p)); /* make prototype gray (again) */
175 p->gclist = g->grayagain;
176 g->grayagain = obj2gco(p);
177 }
168} 178}
169 179
170 180
@@ -312,7 +322,7 @@ static void remarkupvals (global_State *g) {
312static void markroot (lua_State *L) { 322static void markroot (lua_State *L) {
313 global_State *g = G(L); 323 global_State *g = G(L);
314 g->gray = g->grayagain = NULL; 324 g->gray = g->grayagain = NULL;
315 g->weak = g->allweak = g->ephemeron = g->clearcache = NULL; 325 g->weak = g->allweak = g->ephemeron = NULL;
316 markobject(g, g->mainthread); 326 markobject(g, g->mainthread);
317 markvalue(g, &g->l_registry); 327 markvalue(g, &g->l_registry);
318 markmt(g); 328 markmt(g);
@@ -422,19 +432,10 @@ static int traversetable (global_State *g, Table *h) {
422} 432}
423 433
424 434
425/*
426** if prototype's cached closure is not marked, erase it so it
427** can be collected
428*/
429static void checkcache (Proto *p) {
430 if (p->cache && iswhite(obj2gco(p->cache)))
431 p->cache = NULL; /* allow cache to be collected */
432}
433
434
435static int traverseproto (global_State *g, Proto *f) { 435static int traverseproto (global_State *g, Proto *f) {
436 int i; 436 int i;
437 checkcache(f); 437 if (f->cache && iswhite(obj2gco(f->cache)))
438 f->cache = NULL; /* allow cache to be collected */
438 stringmark(f->source); 439 stringmark(f->source);
439 for (i = 0; i < f->sizek; i++) /* mark literals */ 440 for (i = 0; i < f->sizek; i++) /* mark literals */
440 markvalue(g, &f->k[i]); 441 markvalue(g, &f->k[i]);
@@ -557,14 +558,6 @@ static void convergeephemerons (global_State *g) {
557** ======================================================= 558** =======================================================
558*/ 559*/
559 560
560/*
561** clear cache field in all prototypes in list 'l'
562*/
563static void clearproto (GCObject *l) {
564 for (; l != NULL; l = gco2p(l)->gclist)
565 checkcache(gco2p(l));
566}
567
568 561
569/* 562/*
570** clear collected entries from all weaktables in list 'l' 563** clear collected entries from all weaktables in list 'l'
@@ -878,7 +871,6 @@ static void atomic (lua_State *L) {
878 cleartable(g->weak); 871 cleartable(g->weak);
879 cleartable(g->ephemeron); 872 cleartable(g->ephemeron);
880 cleartable(g->allweak); 873 cleartable(g->allweak);
881 clearproto(g->clearcache);
882 g->sweepstrgc = 0; /* prepare to sweep strings */ 874 g->sweepstrgc = 0; /* prepare to sweep strings */
883 g->gcstate = GCSsweepstring; 875 g->gcstate = GCSsweepstring;
884 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ 876 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
diff --git a/lgc.h b/lgc.h
index fa007969..191adfeb 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 2.41 2010/05/10 18:23:45 roberto Exp roberto $ 2** $Id: lgc.h,v 2.42 2010/06/04 13:25:10 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*/
@@ -124,8 +124,8 @@
124#define luaC_objbarrierback(L,p,o) \ 124#define luaC_objbarrierback(L,p,o) \
125 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); } 125 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); }
126 126
127#define luaC_barrierproto(L,p) \ 127#define luaC_barrierproto(L,p,c) \
128 { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p); } 128 { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); }
129 129
130LUAI_FUNC void luaC_separateudata (lua_State *L, int all); 130LUAI_FUNC void luaC_separateudata (lua_State *L, int all);
131LUAI_FUNC void luaC_freeallobjects (lua_State *L); 131LUAI_FUNC void luaC_freeallobjects (lua_State *L);
@@ -136,7 +136,7 @@ LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz,
136 GCObject **list, int offset); 136 GCObject **list, int offset);
137LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 137LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
138LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); 138LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
139LUAI_FUNC void luaC_barrierproto_ (lua_State *L, GCObject *p); 139LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c);
140LUAI_FUNC void luaC_checkfinalizer (lua_State *L, Udata *u); 140LUAI_FUNC void luaC_checkfinalizer (lua_State *L, Udata *u);
141LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); 141LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv);
142LUAI_FUNC void luaC_changemode (lua_State *L, int mode); 142LUAI_FUNC void luaC_changemode (lua_State *L, int mode);
diff --git a/lvm.c b/lvm.c
index 3a66e0aa..8361d3dd 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.120 2010/05/13 19:53:05 roberto Exp roberto $ 2** $Id: lvm.c,v 2.121 2010/06/04 13:25:10 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*/
@@ -368,7 +368,9 @@ static Closure *getcached (Proto *p, UpVal **encup, StkId base) {
368 368
369/* 369/*
370** create a new Lua closure, push it in the stack, and initialize 370** create a new Lua closure, push it in the stack, and initialize
371** its upvalues 371** its upvalues. Note that the call to 'luaC_barrierproto' must come
372** before the assignment to 'p->cache', as the function needs the
373** orginal value of that field.
372*/ 374*/
373static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, 375static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
374 StkId ra) { 376 StkId ra) {
@@ -383,8 +385,8 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
383 else /* get upvalue from enclosing function */ 385 else /* get upvalue from enclosing function */
384 ncl->l.upvals[i] = encup[uv[i].idx]; 386 ncl->l.upvals[i] = encup[uv[i].idx];
385 } 387 }
386 p->cache = ncl; /* save it on cache, so it can be reused */ 388 luaC_barrierproto(L, p, ncl);
387 luaC_barrierproto(L, obj2gco(p)); 389 p->cache = ncl; /* save it on cache for reuse */
388} 390}
389 391
390 392