aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2012-06-09 20:30:27 +0200
committerMike Pall <mike>2012-06-09 20:30:27 +0200
commit9d7bd04faed5feed273d9b9a11962f01e3cc7edf (patch)
treef783c54f1ae790953b01d01e772d46819ca06b99
parent1c8ed534b3e7bfec65d0724b53cd6f5f6c19c832 (diff)
downloadluajit-9d7bd04faed5feed273d9b9a11962f01e3cc7edf.tar.gz
luajit-9d7bd04faed5feed273d9b9a11962f01e3cc7edf.tar.bz2
luajit-9d7bd04faed5feed273d9b9a11962f01e3cc7edf.zip
Avoid potential store-forwarding stalls in GC marking.
-rw-r--r--src/lj_gc.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/lj_gc.c b/src/lj_gc.c
index 9d0e7559..e6a9d539 100644
--- a/src/lj_gc.c
+++ b/src/lj_gc.c
@@ -54,21 +54,22 @@
54/* Mark a white GCobj. */ 54/* Mark a white GCobj. */
55static void gc_mark(global_State *g, GCobj *o) 55static void gc_mark(global_State *g, GCobj *o)
56{ 56{
57 int gct = o->gch.gct;
57 lua_assert(iswhite(o) && !isdead(g, o)); 58 lua_assert(iswhite(o) && !isdead(g, o));
58 white2gray(o); 59 white2gray(o);
59 if (LJ_UNLIKELY(o->gch.gct == ~LJ_TUDATA)) { 60 if (LJ_UNLIKELY(gct == ~LJ_TUDATA)) {
60 GCtab *mt = tabref(gco2ud(o)->metatable); 61 GCtab *mt = tabref(gco2ud(o)->metatable);
61 gray2black(o); /* Userdata are never gray. */ 62 gray2black(o); /* Userdata are never gray. */
62 if (mt) gc_markobj(g, mt); 63 if (mt) gc_markobj(g, mt);
63 gc_markobj(g, tabref(gco2ud(o)->env)); 64 gc_markobj(g, tabref(gco2ud(o)->env));
64 } else if (LJ_UNLIKELY(o->gch.gct == ~LJ_TUPVAL)) { 65 } else if (LJ_UNLIKELY(gct == ~LJ_TUPVAL)) {
65 GCupval *uv = gco2uv(o); 66 GCupval *uv = gco2uv(o);
66 gc_marktv(g, uvval(uv)); 67 gc_marktv(g, uvval(uv));
67 if (uv->closed) 68 if (uv->closed)
68 gray2black(o); /* Closed upvalues are never gray. */ 69 gray2black(o); /* Closed upvalues are never gray. */
69 } else if (o->gch.gct != ~LJ_TSTR && o->gch.gct != ~LJ_TCDATA) { 70 } else if (gct != ~LJ_TSTR && gct != ~LJ_TCDATA) {
70 lua_assert(o->gch.gct == ~LJ_TFUNC || o->gch.gct == ~LJ_TTAB || 71 lua_assert(gct == ~LJ_TFUNC || gct == ~LJ_TTAB ||
71 o->gch.gct == ~LJ_TTHREAD || o->gch.gct == ~LJ_TPROTO); 72 gct == ~LJ_TTHREAD || gct == ~LJ_TPROTO);
72 setgcrefr(o->gch.gclist, g->gc.gray); 73 setgcrefr(o->gch.gclist, g->gc.gray);
73 setgcref(g->gc.gray, o); 74 setgcref(g->gc.gray, o);
74 } 75 }
@@ -298,25 +299,26 @@ static void gc_traverse_thread(global_State *g, lua_State *th)
298static size_t propagatemark(global_State *g) 299static size_t propagatemark(global_State *g)
299{ 300{
300 GCobj *o = gcref(g->gc.gray); 301 GCobj *o = gcref(g->gc.gray);
302 int gct = o->gch.gct;
301 lua_assert(isgray(o)); 303 lua_assert(isgray(o));
302 gray2black(o); 304 gray2black(o);
303 setgcrefr(g->gc.gray, o->gch.gclist); /* Remove from gray list. */ 305 setgcrefr(g->gc.gray, o->gch.gclist); /* Remove from gray list. */
304 if (LJ_LIKELY(o->gch.gct == ~LJ_TTAB)) { 306 if (LJ_LIKELY(gct == ~LJ_TTAB)) {
305 GCtab *t = gco2tab(o); 307 GCtab *t = gco2tab(o);
306 if (gc_traverse_tab(g, t) > 0) 308 if (gc_traverse_tab(g, t) > 0)
307 black2gray(o); /* Keep weak tables gray. */ 309 black2gray(o); /* Keep weak tables gray. */
308 return sizeof(GCtab) + sizeof(TValue) * t->asize + 310 return sizeof(GCtab) + sizeof(TValue) * t->asize +
309 sizeof(Node) * (t->hmask + 1); 311 sizeof(Node) * (t->hmask + 1);
310 } else if (LJ_LIKELY(o->gch.gct == ~LJ_TFUNC)) { 312 } else if (LJ_LIKELY(gct == ~LJ_TFUNC)) {
311 GCfunc *fn = gco2func(o); 313 GCfunc *fn = gco2func(o);
312 gc_traverse_func(g, fn); 314 gc_traverse_func(g, fn);
313 return isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) : 315 return isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) :
314 sizeCfunc((MSize)fn->c.nupvalues); 316 sizeCfunc((MSize)fn->c.nupvalues);
315 } else if (LJ_LIKELY(o->gch.gct == ~LJ_TPROTO)) { 317 } else if (LJ_LIKELY(gct == ~LJ_TPROTO)) {
316 GCproto *pt = gco2pt(o); 318 GCproto *pt = gco2pt(o);
317 gc_traverse_proto(g, pt); 319 gc_traverse_proto(g, pt);
318 return pt->sizept; 320 return pt->sizept;
319 } else if (LJ_LIKELY(o->gch.gct == ~LJ_TTHREAD)) { 321 } else if (LJ_LIKELY(gct == ~LJ_TTHREAD)) {
320 lua_State *th = gco2th(o); 322 lua_State *th = gco2th(o);
321 setgcrefr(th->gclist, g->gc.grayagain); 323 setgcrefr(th->gclist, g->gc.grayagain);
322 setgcref(g->gc.grayagain, o); 324 setgcref(g->gc.grayagain, o);