aboutsummaryrefslogtreecommitdiff
path: root/src/lj_gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_gc.c')
-rw-r--r--src/lj_gc.c41
1 files changed, 17 insertions, 24 deletions
diff --git a/src/lj_gc.c b/src/lj_gc.c
index eebc751b..9cabdef0 100644
--- a/src/lj_gc.c
+++ b/src/lj_gc.c
@@ -108,9 +108,6 @@ static void gc_mark_start(global_State *g)
108 gc_markobj(g, tabref(mainthread(g)->env)); 108 gc_markobj(g, tabref(mainthread(g)->env));
109 gc_marktv(g, &g->registrytv); 109 gc_marktv(g, &g->registrytv);
110 gc_mark_gcroot(g); 110 gc_mark_gcroot(g);
111#if LJ_HASFFI
112 if (ctype_ctsG(g)) gc_markobj(g, ctype_ctsG(g)->finalizer);
113#endif
114 g->gc.state = GCSpropagate; 111 g->gc.state = GCSpropagate;
115} 112}
116 113
@@ -190,8 +187,7 @@ static int gc_traverse_tab(global_State *g, GCtab *t)
190 } 187 }
191 if (weak) { /* Weak tables are cleared in the atomic phase. */ 188 if (weak) { /* Weak tables are cleared in the atomic phase. */
192#if LJ_HASFFI 189#if LJ_HASFFI
193 CTState *cts = ctype_ctsG(g); 190 if (gcref(g->gcroot[GCROOT_FFI_FIN]) == obj2gco(t)) {
194 if (cts && cts->finalizer == t) {
195 weak = (int)(~0u & ~LJ_GC_WEAKVAL); 191 weak = (int)(~0u & ~LJ_GC_WEAKVAL);
196 } else 192 } else
197#endif 193#endif
@@ -556,7 +552,7 @@ static void gc_finalize(lua_State *L)
556 o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN; 552 o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN;
557 /* Resolve finalizer. */ 553 /* Resolve finalizer. */
558 setcdataV(L, &tmp, gco2cd(o)); 554 setcdataV(L, &tmp, gco2cd(o));
559 tv = lj_tab_set(L, ctype_ctsG(g)->finalizer, &tmp); 555 tv = lj_tab_set(L, tabref(g->gcroot[GCROOT_FFI_FIN]), &tmp);
560 if (!tvisnil(tv)) { 556 if (!tvisnil(tv)) {
561 g->gc.nocdatafin = 0; 557 g->gc.nocdatafin = 0;
562 copyTV(L, &tmp, tv); 558 copyTV(L, &tmp, tv);
@@ -588,23 +584,20 @@ void lj_gc_finalize_udata(lua_State *L)
588void lj_gc_finalize_cdata(lua_State *L) 584void lj_gc_finalize_cdata(lua_State *L)
589{ 585{
590 global_State *g = G(L); 586 global_State *g = G(L);
591 CTState *cts = ctype_ctsG(g); 587 GCtab *t = tabref(g->gcroot[GCROOT_FFI_FIN]);
592 if (cts) { 588 Node *node = noderef(t->node);
593 GCtab *t = cts->finalizer; 589 ptrdiff_t i;
594 Node *node = noderef(t->node); 590 setgcrefnull(t->metatable); /* Mark finalizer table as disabled. */
595 ptrdiff_t i; 591 for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
596 setgcrefnull(t->metatable); /* Mark finalizer table as disabled. */ 592 if (!tvisnil(&node[i].val) && tviscdata(&node[i].key)) {
597 for (i = (ptrdiff_t)t->hmask; i >= 0; i--) 593 GCobj *o = gcV(&node[i].key);
598 if (!tvisnil(&node[i].val) && tviscdata(&node[i].key)) { 594 TValue tmp;
599 GCobj *o = gcV(&node[i].key); 595 makewhite(g, o);
600 TValue tmp; 596 o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN;
601 makewhite(g, o); 597 copyTV(L, &tmp, &node[i].val);
602 o->gch.marked &= (uint8_t)~LJ_GC_CDATA_FIN; 598 setnilV(&node[i].val);
603 copyTV(L, &tmp, &node[i].val); 599 gc_call_finalizer(g, L, &tmp, o);
604 setnilV(&node[i].val); 600 }
605 gc_call_finalizer(g, L, &tmp, o);
606 }
607 }
608} 601}
609#endif 602#endif
610 603
@@ -720,7 +713,7 @@ static size_t gc_onestep(lua_State *L)
720 return GCFINALIZECOST; 713 return GCFINALIZECOST;
721 } 714 }
722#if LJ_HASFFI 715#if LJ_HASFFI
723 if (!g->gc.nocdatafin) lj_tab_rehash(L, ctype_ctsG(g)->finalizer); 716 if (!g->gc.nocdatafin) lj_tab_rehash(L, tabref(g->gcroot[GCROOT_FFI_FIN]));
724#endif 717#endif
725 g->gc.state = GCSpause; /* End of GC cycle. */ 718 g->gc.state = GCSpause; /* End of GC cycle. */
726 g->gc.debt = 0; 719 g->gc.debt = 0;