e$B1sF#$G$9!#e(B
2010e$BG/e(B2e$B7ne(B11e$BF|e(B19:08 Yusuke ENDOH [email protected]:
e$B0J2<$N$h$&$K$9$k$He(B T_ZOMBIE e$B$,8+$($F$7$^$&$N$O%P%0$G$7$g$&$+!#e(B
snip
GC e$B$K6=L#$N$"$k?M$K9M$($F$[$7$$$G$9!#e(B
e$B4|BT$7$F$$$?e(B wanabe
e$B$5$s$K!V8+$J$$@k8@!W$r$5$l$F$7$^$C$?$N$G!"e(B
e$B<+J,$G$$$$2C8:$K9M$($F$_$^$7$?!#e(B
r18398 e$B$Ge(B runs finalizers with the object terminated. e$B$H$$$&e(B
e$BJQ99$,F~$C$F$$$?$N$G!"$3$l$re(B revert e$B$9$k$h$&$J46$8$G%Q%C%A$re(B
e$B=q$$$F$_$^$7$?!#e(BT_ZOMBIE e$B$O8+$($J$/$J$C$?$h$&$G$9!#e(B
$ ./ruby -e ’
obj = “test”
ObjectSpace.define_finalizer(obj, proc { begin; p obj; ensure; p $!;
end })
’
e$B$^$?!"e(Bmake check e$B$G$be(B objectspace e$B$N%(%i!<$,e(B 1
e$B$DA}$($k$@$1$Ne(B
e$B$h$&$G$9!#e(B
e$B$1$l$I!"0J2<$Ne(B 2 e$B$D$N$h$/$o$+$i$J$$5sF0$KG:$^$5$l$F$$$^$9!#e(B
- e$BBP>]%*%V%8%'%/%H$r%H%C%W%l%Y%k$N%m!<%+%kJQ?t$KBeF~$9$k$He(B
e$B%U%!%$%J%i%$%6$,<B9T$5$l$J$$e(B
e$B2s<}$5$l$J$$e(B
$ ./ruby -e ’
def foo; proc { p :foo }; end
s = “foo”
ObjectSpace.define_finalizer(s, foo)
’
e$B%m!<%+%kJQ?t$KF~$l$J$1$l$P2s<}$5$l$ke(B
$ ./ruby -e ’
def foo; proc { p :foo }; end
ObjectSpace.define_finalizer(“foo”, foo)
’
:foo
e$B%H%C%W%l%Y%k$G$J$1$l$P2s<}$5$l$ke(B
$ ./ruby -e ’
class C
def self.foo; proc { p :foo }; end
s = “foo”
ObjectSpace.define_finalizer(“foo”, foo)
end
’
e$B%U%!%$%J%i%$%6$Ne(B proc e$B$+$i%H%C%W%l%Y%k$N%m!<%+%kJQ?t$,$J$<$+e(B
e$B%^!<%/$5$l$k$s$G$7$g$&$+!#e(B
test/ruby/test_objectspace.rb e$B$,$3$N5sF0$K0MB8$7$F<:GT$9$ke(B
e$B$h$&$G$9!#e(B
- Enumerator#next e$B$r;H$&$H2s<}$5$l$J$$e(B
e$B2s<}$5$l$J$$e(B
$ ./ruby -e ’
module M
def self.callback
proc { p “finalized” }
end
def self.run
@enum = 1.enum_for(:upto, 3)
@enum.next
ObjectSpace.define_finalizer(“foo”, callback)
end
end
M.run
’
next e$B$r;H$o$J$1$l$P2s<}$5$l$ke(B
$ ./ruby -e ’
module M
def self.callback
proc { p “finalized” }
end
def self.run
@enum = 1.enum_for(:upto, 3)
#@enum.next
ObjectSpace.define_finalizer(“foo”, callback)
end
end
M.run
’
“finalized”
Enumerator e$B$r%$%s%9%?%s%9JQ?t$KF~$l$J$1$l$P2s<}$5$l$ke(B
$ ./ruby -e ’
module M
def self.callback
proc { p “finalized” }
end
def self.run
enum = 1.enum_for(:upto, 3)
enum.next
ObjectSpace.define_finalizer(“foo”, callback)
end
end
M.run
’
“finalized”
e$B$*$=$i$/e(B Fiber
e$B$N%^%7%s%9%?%C%/$NCf$K;2>H$,$“$k$N$G$O$J$$$+$He(B
e$B;W$$$^$9$,!”$I$&BP=h$7$?$b$N$+$o$+$j$^$;$s!#e(B
rubyspec e$B$,$3$N5sF0$K0MB8$7$F<:GT$7$^$9e(B (Enumerator e$B$Ne(B spec
e$B$He(B
e$B$"$o$;$F<B9T$7$?$H$-$@$1<:GT$9$ke(B) e$B!#e(B
e$B$b$&>/$79M$($F$$^$9$,!"$=$l$G$be(B T_ZOMBIE
e$B$,8+$($k$h$j$O$$$$$He(B
e$B;W$&$N$G!“H?BP$,$J$1$l$P$H$j$”$($:%3%%C%H$7$h$&$H;W$$$^$9!#e(B
diff --git a/gc.c b/gc.c
index 4cfc23c…32b7436 100644
— a/gc.c
+++ b/gc.c
@@ -2652,7 +2652,7 @@ static int
chain_finalized_object(st_data_t key, st_data_t val, st_data_t arg)
{
RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg;
- if (p->as.basic.flags & FL_FINALIZE) {
- if ((p->as.basic.flags & (FL_FINALIZE|FL_MARK)) == FL_FINALIZE) {
if (BUILTIN_TYPE(p) != T_ZOMBIE) {
p->as.free.flags = FL_MARK | T_ZOMBIE; /* remain marked */
RDATA(p)->dfree = 0;
@@ -2661,9 +2661,7 @@ chain_finalized_object(st_data_t key, st_data_t
val, st_data_t arg)
*final_list = p;
return ST_CONTINUE;
}
- else {
- return ST_DELETE;
- }
void
@@ -2681,15 +2679,16 @@ rb_objspace_call_finalizer(rb_objspace_t
*objspace)
/* run finalizers */
if (finalizer_table) {
- finalize_deferred(objspace);
- while (finalizer_table->num_entries > 0) {
- do {
-
finalize_deferred(objspace);
-
mark_tbl(objspace, finalizer_table, 0);
st_foreach(finalizer_table, chain_finalized_object,
self-reference",