소스 검색

FFI: Rehash finalizer table after GC cycle, if needed.

Mike Pall 12 년 전
부모
커밋
5d25645a21
4개의 변경된 파일18개의 추가작업 그리고 1개의 파일을 삭제
  1. 7 0
      src/lj_gc.c
  2. 1 1
      src/lj_obj.h
  3. 7 0
      src/lj_tab.c
  4. 3 0
      src/lj_tab.h

+ 7 - 0
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;

+ 1 - 1
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. */

+ 7 - 0
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);

+ 3 - 0
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! */