mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-04-20 14:03:26 +00:00
Avoid potential store-forwarding stalls in GC marking.
This commit is contained in:
parent
1c8ed534b3
commit
9d7bd04fae
20
src/lj_gc.c
20
src/lj_gc.c
@ -54,21 +54,22 @@
|
|||||||
/* Mark a white GCobj. */
|
/* Mark a white GCobj. */
|
||||||
static void gc_mark(global_State *g, GCobj *o)
|
static void gc_mark(global_State *g, GCobj *o)
|
||||||
{
|
{
|
||||||
|
int gct = o->gch.gct;
|
||||||
lua_assert(iswhite(o) && !isdead(g, o));
|
lua_assert(iswhite(o) && !isdead(g, o));
|
||||||
white2gray(o);
|
white2gray(o);
|
||||||
if (LJ_UNLIKELY(o->gch.gct == ~LJ_TUDATA)) {
|
if (LJ_UNLIKELY(gct == ~LJ_TUDATA)) {
|
||||||
GCtab *mt = tabref(gco2ud(o)->metatable);
|
GCtab *mt = tabref(gco2ud(o)->metatable);
|
||||||
gray2black(o); /* Userdata are never gray. */
|
gray2black(o); /* Userdata are never gray. */
|
||||||
if (mt) gc_markobj(g, mt);
|
if (mt) gc_markobj(g, mt);
|
||||||
gc_markobj(g, tabref(gco2ud(o)->env));
|
gc_markobj(g, tabref(gco2ud(o)->env));
|
||||||
} else if (LJ_UNLIKELY(o->gch.gct == ~LJ_TUPVAL)) {
|
} else if (LJ_UNLIKELY(gct == ~LJ_TUPVAL)) {
|
||||||
GCupval *uv = gco2uv(o);
|
GCupval *uv = gco2uv(o);
|
||||||
gc_marktv(g, uvval(uv));
|
gc_marktv(g, uvval(uv));
|
||||||
if (uv->closed)
|
if (uv->closed)
|
||||||
gray2black(o); /* Closed upvalues are never gray. */
|
gray2black(o); /* Closed upvalues are never gray. */
|
||||||
} else if (o->gch.gct != ~LJ_TSTR && o->gch.gct != ~LJ_TCDATA) {
|
} else if (gct != ~LJ_TSTR && gct != ~LJ_TCDATA) {
|
||||||
lua_assert(o->gch.gct == ~LJ_TFUNC || o->gch.gct == ~LJ_TTAB ||
|
lua_assert(gct == ~LJ_TFUNC || gct == ~LJ_TTAB ||
|
||||||
o->gch.gct == ~LJ_TTHREAD || o->gch.gct == ~LJ_TPROTO);
|
gct == ~LJ_TTHREAD || gct == ~LJ_TPROTO);
|
||||||
setgcrefr(o->gch.gclist, g->gc.gray);
|
setgcrefr(o->gch.gclist, g->gc.gray);
|
||||||
setgcref(g->gc.gray, o);
|
setgcref(g->gc.gray, o);
|
||||||
}
|
}
|
||||||
@ -298,25 +299,26 @@ static void gc_traverse_thread(global_State *g, lua_State *th)
|
|||||||
static size_t propagatemark(global_State *g)
|
static size_t propagatemark(global_State *g)
|
||||||
{
|
{
|
||||||
GCobj *o = gcref(g->gc.gray);
|
GCobj *o = gcref(g->gc.gray);
|
||||||
|
int gct = o->gch.gct;
|
||||||
lua_assert(isgray(o));
|
lua_assert(isgray(o));
|
||||||
gray2black(o);
|
gray2black(o);
|
||||||
setgcrefr(g->gc.gray, o->gch.gclist); /* Remove from gray list. */
|
setgcrefr(g->gc.gray, o->gch.gclist); /* Remove from gray list. */
|
||||||
if (LJ_LIKELY(o->gch.gct == ~LJ_TTAB)) {
|
if (LJ_LIKELY(gct == ~LJ_TTAB)) {
|
||||||
GCtab *t = gco2tab(o);
|
GCtab *t = gco2tab(o);
|
||||||
if (gc_traverse_tab(g, t) > 0)
|
if (gc_traverse_tab(g, t) > 0)
|
||||||
black2gray(o); /* Keep weak tables gray. */
|
black2gray(o); /* Keep weak tables gray. */
|
||||||
return sizeof(GCtab) + sizeof(TValue) * t->asize +
|
return sizeof(GCtab) + sizeof(TValue) * t->asize +
|
||||||
sizeof(Node) * (t->hmask + 1);
|
sizeof(Node) * (t->hmask + 1);
|
||||||
} else if (LJ_LIKELY(o->gch.gct == ~LJ_TFUNC)) {
|
} else if (LJ_LIKELY(gct == ~LJ_TFUNC)) {
|
||||||
GCfunc *fn = gco2func(o);
|
GCfunc *fn = gco2func(o);
|
||||||
gc_traverse_func(g, fn);
|
gc_traverse_func(g, fn);
|
||||||
return isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) :
|
return isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) :
|
||||||
sizeCfunc((MSize)fn->c.nupvalues);
|
sizeCfunc((MSize)fn->c.nupvalues);
|
||||||
} else if (LJ_LIKELY(o->gch.gct == ~LJ_TPROTO)) {
|
} else if (LJ_LIKELY(gct == ~LJ_TPROTO)) {
|
||||||
GCproto *pt = gco2pt(o);
|
GCproto *pt = gco2pt(o);
|
||||||
gc_traverse_proto(g, pt);
|
gc_traverse_proto(g, pt);
|
||||||
return pt->sizept;
|
return pt->sizept;
|
||||||
} else if (LJ_LIKELY(o->gch.gct == ~LJ_TTHREAD)) {
|
} else if (LJ_LIKELY(gct == ~LJ_TTHREAD)) {
|
||||||
lua_State *th = gco2th(o);
|
lua_State *th = gco2th(o);
|
||||||
setgcrefr(th->gclist, g->gc.grayagain);
|
setgcrefr(th->gclist, g->gc.grayagain);
|
||||||
setgcref(g->gc.grayagain, o);
|
setgcref(g->gc.grayagain, o);
|
||||||
|
Loading…
Reference in New Issue
Block a user