ruby-changes:43686
From: nobu <ko1@a...>
Date: Tue, 26 Jul 2016 22:43:43 +0900 (JST)
Subject: [ruby-changes:43686] nobu:r55759 (trunk): gc.c: running finalizer state
nobu 2016-07-26 22:43:38 +0900 (Tue, 26 Jul 2016) New Revision: 55759 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55759 Log: gc.c: running finalizer state * gc.c (run_finalizer): make saved running finalizer state volatile to ensure not to be clobbered by longjmp. Modified files: trunk/ChangeLog trunk/gc.c Index: ChangeLog =================================================================== --- ChangeLog (revision 55758) +++ ChangeLog (revision 55759) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Jul 26 22:43:36 2016 Nobuyoshi Nakada <nobu@r...> + + * gc.c (run_finalizer): make saved running finalizer state + volatile to ensure not to be clobbered by longjmp. + Tue Jul 26 19:26:00 2016 Koichi Sasada <ko1@a...> * vm_insnhelper.c: introduce rb_vm_pop_frame() and use it Index: gc.c =================================================================== --- gc.c (revision 55758) +++ gc.c (revision 55759) @@ -2706,26 +2706,34 @@ run_finalizer(rb_objspace_t *objspace, V https://github.com/ruby/ruby/blob/trunk/gc.c#L2706 { long i; int status; - const int safe = rb_safe_level(); - const VALUE errinfo = rb_errinfo(); - const VALUE objid = nonspecial_obj_id(obj); + volatile struct { + VALUE errinfo; + VALUE objid; + long finished; + int safe; + } saved; rb_thread_t *const th = GET_THREAD(); - volatile long finished = 0; +#define RESTORE_FINALIZER() (\ + rb_set_safe_level_force(saved.safe), \ + rb_set_errinfo(saved.errinfo)) + + saved.safe = rb_safe_level(); + saved.errinfo = rb_errinfo(); + saved.objid = nonspecial_obj_id(obj); + saved.finished = 0; TH_PUSH_TAG(th); status = TH_EXEC_TAG(); if (status) { - ++finished; /* skip failed finalizer */ - rb_set_safe_level_force(safe); - rb_set_errinfo(errinfo); + ++saved.finished; /* skip failed finalizer */ } - for (i = finished; i<RARRAY_LEN(table); i++) { - finished = i; - run_single_final(RARRAY_AREF(table, i), objid); - rb_set_safe_level_force(safe); - rb_set_errinfo(errinfo); + for (i = saved.finished; + RESTORE_FINALIZER(), i<RARRAY_LEN(table); + saved.finished = ++i) { + run_single_final(RARRAY_AREF(table, i), saved.objid); } TH_POP_TAG(); +#undef RESTORE_FINALIZER } static void -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/