summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authortmm1 <tmm1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-06 05:11:51 +0000
committertmm1 <tmm1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-06 05:11:51 +0000
commit470c9d844b11f003d0118def80a08fb2437fd0d0 (patch)
tree5e18b9864130df2d6af5c4aaedc2f2513423c33c /gc.c
parentc52eadeb77908afb629ae74e20d734015d63c82a (diff)
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.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/gc.c b/gc.c
index 1b1be69d1e..b03da82d76 100644
--- a/gc.c
+++ b/gc.c
@@ -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);