gc.c: reduce EXEC_TAG

* gc.c (run_finalizer): push and exec tag just once, instead of
  protecting for each finalizer.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55722 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2016-07-21 21:28:34 +00:00
parent 3f4acc0e90
commit 2fbb1dca4e
2 changed files with 25 additions and 17 deletions

View file

@ -1,4 +1,7 @@
Fri Jul 22 06:12:51 2016 Nobuyoshi Nakada <nobu@ruby-lang.org> Fri Jul 22 06:28:32 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
* gc.c (run_finalizer): push and exec tag just once, instead of
protecting for each finalizer.
* gc.c (gc_start_internal, rb_gc_start): set finalizing flag * gc.c (gc_start_internal, rb_gc_start): set finalizing flag
whenever calling deferred finalizers not to recurse. whenever calling deferred finalizers not to recurse.

37
gc.c
View file

@ -2691,36 +2691,41 @@ rb_gc_copy_finalizer(VALUE dest, VALUE obj)
} }
static VALUE static VALUE
run_single_final(VALUE arg) run_single_final(VALUE final, VALUE objid)
{ {
VALUE *args = (VALUE *)arg; const VALUE cmd = RARRAY_AREF(final, 1);
const int level = OBJ_TAINTED(cmd) ?
RUBY_SAFE_LEVEL_MAX : FIX2INT(RARRAY_AREF(final, 0));
return rb_check_funcall(args[0], idCall, 1, args+1); rb_set_safe_level_force(level);
return rb_check_funcall(cmd, idCall, 1, &objid);
} }
static void static void
run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table) run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
{ {
long i; long i;
VALUE args[2]; int status;
const int safe = rb_safe_level(); const int safe = rb_safe_level();
const VALUE errinfo = rb_errinfo(); const VALUE errinfo = rb_errinfo();
const VALUE objid = nonspecial_obj_id(obj);
rb_thread_t *const th = GET_THREAD();
volatile long finished = 0;
args[1] = nonspecial_obj_id(obj); TH_PUSH_TAG(th);
status = TH_EXEC_TAG();
for (i=0; i<RARRAY_LEN(table); i++) { if (status) {
const VALUE final = RARRAY_AREF(table, i); ++finished; /* skip failed finalizer */
const VALUE cmd = RARRAY_AREF(final, 1);
const int level = OBJ_TAINTED(cmd) ?
RUBY_SAFE_LEVEL_MAX : FIX2INT(RARRAY_AREF(final, 0));
int status = 0;
args[0] = cmd;
rb_set_safe_level_force(level);
rb_protect(run_single_final, (VALUE)args, &status);
rb_set_safe_level_force(safe); rb_set_safe_level_force(safe);
rb_set_errinfo(errinfo); rb_set_errinfo(errinfo);
} }
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);
}
TH_POP_TAG();
} }
static void static void