ruby-changes:31948
From: tmm1 <ko1@a...>
Date: Fri, 6 Dec 2013 14:12:01 +0900 (JST)
Subject: [ruby-changes:31948] tmm1:r44027 (trunk): gc.c: add minor marking and lazy sweeping options to GC.start
tmm1 2013-12-06 14:11:51 +0900 (Fri, 06 Dec 2013) New Revision: 44027 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44027 Log: gc.c: add minor marking and lazy sweeping options to GC.start * gc.c (gc_start_internal): GC.start() now accepts two optional keyword arguments. These can be used to disable full_mark (minor mark only) or disable immediate_sweep (use lazy sweep). These new options are useful for benchmarking GC behavior, or performing minor GC out-of-band. * test/ruby/test_gc.rb (class TestGc): tests for new options. Modified files: trunk/ChangeLog trunk/gc.c trunk/test/ruby/test_gc.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 44026) +++ ChangeLog (revision 44027) @@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Dec 6 14:05:19 2013 Aman Gupta <ruby@t...> + + * gc.c (gc_start_internal): GC.start() now accepts two optional + keyword arguments. These can be used to disable full_mark (minor + mark only) or disable immediate_sweep (use lazy sweep). These new + options are useful for benchmarking GC behavior, or performing minor + GC out-of-band. + * test/ruby/test_gc.rb (class TestGc): tests for new options. + Fri Dec 6 11:51:28 2013 SHIBATA Hiroshi <shibata.hiroshi@g...> * lib/erb.rb: [DOC] fix broken link, Use rubygems.org and www.ruby-toolbox.com instead of RAA. Index: gc.c =================================================================== --- gc.c (revision 44026) +++ gc.c (revision 44027) @@ -4992,11 +4992,54 @@ Init_stack(volatile VALUE *addr) https://github.com/ruby/ruby/blob/trunk/gc.c#L4992 * GC.start -> nil * GC.garbage_collect -> nil * ObjectSpace.garbage_collect -> nil + * GC.start(full_mark: false) -> nil * * Initiates garbage collection, unless manually disabled. * + * This method is defined with keyword arguments that default to true: + * + * def GC.start(full_mark: true, immediate_sweep: true) end + * + * Use full_mark: false to perform a minor GC. + * Use immediate_sweep: false to defer sweeping (use lazy sweep). */ +static VALUE +gc_start_internal(int argc, VALUE *argv, VALUE self) +{ + rb_objspace_t *objspace = &rb_objspace; + int full_mark = TRUE, immediate_sweep = TRUE; + VALUE opt = Qnil; + VALUE kwval; + static ID keyword_ids[2]; + static VALUE keyword_syms[2]; + + rb_scan_args(argc, argv, "0:", &opt); + if (NIL_P(opt)) { + return rb_gc_start(); + } + + if (!keyword_ids[0]) { + keyword_ids[0] = rb_intern("full_mark"); + keyword_ids[1] = rb_intern("immediate_sweep"); + keyword_syms[0] = ID2SYM(keyword_ids[0]); + keyword_syms[1] = ID2SYM(keyword_ids[1]); + } + + rb_check_keyword_opthash(opt, keyword_ids, 0, 2); + + if ((kwval = rb_hash_lookup2(opt, keyword_syms[0], Qundef)) != Qundef) + full_mark = RTEST(kwval); + if ((kwval = rb_hash_lookup2(opt, keyword_syms[1], Qundef)) != Qundef) + immediate_sweep = RTEST(kwval); + + garbage_collect(objspace, full_mark, immediate_sweep, GPR_FLAG_METHOD); + if (!finalizing) finalize_deferred(objspace); + heap_pages_free_unused_pages(objspace); + + return Qnil; +} + VALUE rb_gc_start(void) { @@ -7206,7 +7249,7 @@ Init_GC(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L7249 VALUE gc_constants; rb_mGC = rb_define_module("GC"); - rb_define_singleton_method(rb_mGC, "start", rb_gc_start, 0); + rb_define_singleton_method(rb_mGC, "start", gc_start_internal, -1); rb_define_singleton_method(rb_mGC, "enable", rb_gc_enable, 0); rb_define_singleton_method(rb_mGC, "disable", rb_gc_disable, 0); rb_define_singleton_method(rb_mGC, "stress", gc_stress_get, 0); @@ -7214,7 +7257,7 @@ Init_GC(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L7257 rb_define_singleton_method(rb_mGC, "count", gc_count, 0); rb_define_singleton_method(rb_mGC, "stat", gc_stat, -1); rb_define_singleton_method(rb_mGC, "latest_gc_info", gc_latest_gc_info, -1); - rb_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0); + rb_define_method(rb_mGC, "garbage_collect", gc_start_internal, -1); gc_constants = rb_hash_new(); rb_hash_aset(gc_constants, ID2SYM(rb_intern("RVALUE_SIZE")), SIZET2NUM(sizeof(RVALUE))); @@ -7236,7 +7279,7 @@ Init_GC(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L7279 rb_mObjSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObjSpace, "each_object", os_each_obj, -1); - rb_define_module_function(rb_mObjSpace, "garbage_collect", rb_gc_start, 0); + rb_define_module_function(rb_mObjSpace, "garbage_collect", gc_start_internal, -1); rb_define_module_function(rb_mObjSpace, "define_finalizer", define_final, -1); rb_define_module_function(rb_mObjSpace, "undefine_finalizer", undefine_final, 1); Index: test/ruby/test_gc.rb =================================================================== --- test/ruby/test_gc.rb (revision 44026) +++ test/ruby/test_gc.rb (revision 44027) @@ -48,6 +48,22 @@ class TestGc < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_gc.rb#L48 GC.enable end + def test_start_full_mark + GC.start(full_mark: false) + assert_nil GC.latest_gc_info(:major_by) + + GC.start(full_mark: true) + assert_not_nil GC.latest_gc_info(:major_by) + end + + def test_start_immediate_sweep + GC.start(immediate_sweep: false) + assert_equal false, GC.latest_gc_info(:immediate_sweep) + + GC.start(immediate_sweep: true) + assert_equal true, GC.latest_gc_info(:immediate_sweep) + end + def test_count c = GC.count GC.start -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/