diff options
author | Mike Pall <mike> | 2012-06-09 20:30:27 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-06-09 20:30:27 +0200 |
commit | 9d7bd04faed5feed273d9b9a11962f01e3cc7edf (patch) | |
tree | f783c54f1ae790953b01d01e772d46819ca06b99 | |
parent | 1c8ed534b3e7bfec65d0724b53cd6f5f6c19c832 (diff) | |
download | luajit-9d7bd04faed5feed273d9b9a11962f01e3cc7edf.tar.gz luajit-9d7bd04faed5feed273d9b9a11962f01e3cc7edf.tar.bz2 luajit-9d7bd04faed5feed273d9b9a11962f01e3cc7edf.zip |
Avoid potential store-forwarding stalls in GC marking.
-rw-r--r-- | src/lj_gc.c | 20 |
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. */ |
55 | static void gc_mark(global_State *g, GCobj *o) | 55 | static 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) | |||
298 | static size_t propagatemark(global_State *g) | 299 | static 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); |