From 5d25645a210f32dddecde9c50afb14f9ee63e180 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Mon, 14 Oct 2013 19:31:24 +0200 Subject: [PATCH] FFI: Rehash finalizer table after GC cycle, if needed. --- src/lj_gc.c | 7 +++++++ src/lj_obj.h | 2 +- src/lj_tab.c | 7 +++++++ src/lj_tab.h | 3 +++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/lj_gc.c b/src/lj_gc.c index 79f8b720..5c665786 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c @@ -501,6 +501,7 @@ static void gc_finalize(lua_State *L) setcdataV(L, &tmp, gco2cd(o)); tv = lj_tab_set(L, ctype_ctsG(g)->finalizer, &tmp); if (!tvisnil(tv)) { + g->gc.nocdatafin = 0; copyTV(L, &tmp, tv); setnilV(tv); /* Clear entry in finalizer table. */ gc_call_finalizer(g, L, &tmp, o); @@ -634,6 +635,9 @@ static size_t gc_onestep(lua_State *L) gc_shrink(g, L); if (gcref(g->gc.mmudata)) { /* Need any finalizations? */ g->gc.state = GCSfinalize; +#if LJ_HASFFI + g->gc.nocdatafin = 1; +#endif } else { /* Otherwise skip this phase to help the JIT. */ g->gc.state = GCSpause; /* End of GC cycle. */ g->gc.debt = 0; @@ -652,6 +656,9 @@ static size_t gc_onestep(lua_State *L) g->gc.estimate -= GCFINALIZECOST; return GCFINALIZECOST; } +#if LJ_HASFFI + if (!g->gc.nocdatafin) lj_tab_rehash(L, ctype_ctsG(g)->finalizer); +#endif g->gc.state = GCSpause; /* End of GC cycle. */ g->gc.debt = 0; return 0; diff --git a/src/lj_obj.h b/src/lj_obj.h index b967819d..f8aed318 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h @@ -493,7 +493,7 @@ typedef struct GCState { MSize threshold; /* Memory threshold. */ uint8_t currentwhite; /* Current white color. */ uint8_t state; /* GC state. */ - uint8_t unused1; + uint8_t nocdatafin; /* No cdata finalizer called. */ uint8_t unused2; MSize sweepstr; /* Sweep position in string table. */ GCRef root; /* List of all collectable objects. */ diff --git a/src/lj_tab.c b/src/lj_tab.c index ccad1f68..0a4bf107 100644 --- a/src/lj_tab.c +++ b/src/lj_tab.c @@ -351,6 +351,13 @@ static void rehashtab(lua_State *L, GCtab *t, cTValue *ek) resizetab(L, t, asize, hsize2hbits(total)); } +#if LJ_HASFFI +void lj_tab_rehash(lua_State *L, GCtab *t) +{ + rehashtab(L, t, niltv(L)); +} +#endif + void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize) { resizetab(L, t, nasize+1, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0); diff --git a/src/lj_tab.h b/src/lj_tab.h index 2787caa0..98ded17e 100644 --- a/src/lj_tab.h +++ b/src/lj_tab.h @@ -39,6 +39,9 @@ LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize); #endif LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt); LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t); +#if LJ_HASFFI +LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t); +#endif LJ_FUNCA void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize); /* Caveat: all getters except lj_tab_get() can return NULL! */