diff options
author | Mike Pall <mike> | 2024-04-19 01:33:19 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2024-04-19 01:33:19 +0200 |
commit | f5affaa6c4e7524e661484f22f24255f9a83eb47 (patch) | |
tree | f31ad8fb54b3cf6e592b0ea099cb0532b3044edc /src/lj_gc.c | |
parent | 7110b935672489afd6ba3eef3e5139d2f3bd05b6 (diff) | |
download | luajit-f5affaa6c4e7524e661484f22f24255f9a83eb47.tar.gz luajit-f5affaa6c4e7524e661484f22f24255f9a83eb47.tar.bz2 luajit-f5affaa6c4e7524e661484f22f24255f9a83eb47.zip |
FFI: Turn FFI finalizer table into a proper GC root.
Reported by Sergey Bronnikov. #1168
Diffstat (limited to 'src/lj_gc.c')
-rw-r--r-- | src/lj_gc.c | 41 |
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) | |||
588 | void lj_gc_finalize_cdata(lua_State *L) | 584 | void 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; |