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);
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;
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;
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. */
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);
#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! */