diff options
author | tmm1 <tmm1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-12-06 05:11:51 +0000 |
---|---|---|
committer | tmm1 <tmm1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-12-06 05:11:51 +0000 |
commit | 470c9d844b11f003d0118def80a08fb2437fd0d0 (patch) | |
tree | 5e18b9864130df2d6af5c4aaedc2f2513423c33c /gc.c | |
parent | c52eadeb77908afb629ae74e20d734015d63c82a (diff) | |
download | ruby-470c9d844b11f003d0118def80a08fb2437fd0d0.tar.gz |
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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44027 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 49 |
1 files changed, 46 insertions, 3 deletions
@@ -4992,11 +4992,54 @@ Init_stack(volatile VALUE *addr) * 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) 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) 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) 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); |