ruby-changes:6873
From: nobu <ko1@a...>
Date: Wed, 6 Aug 2008 20:51:21 +0900 (JST)
Subject: [ruby-changes:6873] Ruby:r18391 (trunk): * gc.c (rb_gc_call_finalizer_at_exit): self-referencing finalizers
nobu 2008-08-06 20:48:30 +0900 (Wed, 06 Aug 2008) New Revision: 18391 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=18391 Log: * gc.c (rb_gc_call_finalizer_at_exit): self-referencing finalizers cannot be invoked. [ruby-dev:35681] Added files: trunk/bootstraptest/test_finalizer.rb Modified files: trunk/ChangeLog trunk/gc.c Index: ChangeLog =================================================================== --- ChangeLog (revision 18390) +++ ChangeLog (revision 18391) @@ -1,3 +1,8 @@ +Wed Aug 6 20:48:27 2008 Nobuyoshi Nakada <nobu@r...> + + * gc.c (rb_gc_call_finalizer_at_exit): self-referencing finalizers + cannot be invoked. [ruby-dev:35681] + Wed Aug 6 20:44:41 2008 Tanaka Akira <akr@f...> * tool/transcode-tblgen.rb: distinguish UNDEF and INVALID. Index: bootstraptest/test_finalizer.rb =================================================================== --- bootstraptest/test_finalizer.rb (revision 0) +++ bootstraptest/test_finalizer.rb (revision 18391) @@ -0,0 +1,8 @@ +assert_normal_exit %q{ +a1,a2,b1,b2=Array.new(4){""} +ObjectSpace.define_finalizer(b2,proc{}) +ObjectSpace.define_finalizer(b1,proc{b1.inspect}) + +ObjectSpace.define_finalizer(a2,proc{a1.inspect}) +ObjectSpace.define_finalizer(a1,proc{}) +}, '[ruby-dev:35778]' Property changes on: bootstraptest/test_finalizer.rb ___________________________________________________________________ Name: svn:eol-style + LF Index: gc.c =================================================================== --- gc.c (revision 18390) +++ gc.c (revision 18391) @@ -1489,6 +1489,12 @@ add_freelist(objspace, (RVALUE *)p); } +static inline void +make_deferred(RVALUE *p) +{ + p->as.basic.flags = (p->as.basic.flags & ~T_MASK) | T_DEFERRED; +} + static int obj_free(rb_objspace_t *objspace, VALUE obj) { @@ -1546,14 +1552,8 @@ xfree(DATA_PTR(obj)); } else if (RANY(obj)->as.data.dfree) { - if (1) { - RANY(obj)->as.basic.flags &= ~T_MASK; - RANY(obj)->as.basic.flags |= T_DEFERRED; - return 1; - } - else { - (*RANY(obj)->as.data.dfree)(DATA_PTR(obj)); - } + make_deferred(RANY(obj)); + return 1; } } break; @@ -1562,23 +1562,17 @@ struct rmatch *rm = RANY(obj)->as.match.rmatch; onig_region_free(&rm->regs, 0); if (rm->char_offset) - xfree(rm->char_offset); + xfree(rm->char_offset); xfree(rm); } break; case T_FILE: if (RANY(obj)->as.file.fptr) { rb_io_t *fptr = RANY(obj)->as.file.fptr; - if (1) { - RANY(obj)->as.basic.flags &= ~T_MASK; - RANY(obj)->as.basic.flags |= T_DEFERRED; - RDATA(obj)->dfree = (void (*)(void*))rb_io_fptr_finalize; - RDATA(obj)->data = fptr; - return 1; - } - else { - rb_io_fptr_finalize(fptr); - } + make_deferred(RANY(obj)); + RDATA(obj)->dfree = (void (*)(void*))rb_io_fptr_finalize; + RDATA(obj)->data = fptr; + return 1; } break; case T_RATIONAL: @@ -2091,7 +2085,7 @@ 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_DEFERRED) { p->as.free.flags = FL_MARK | T_DEFERRED; /* remain marked */ RDATA(p)->dfree = 0; @@ -2115,6 +2109,7 @@ p = deferred_final_list; deferred_final_list = 0; finalize_list(objspace, p); + mark_tbl(objspace, finalizer_table, 0); st_foreach(finalizer_table, chain_finalized_object, (st_data_t)&deferred_final_list); } while (deferred_final_list); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/