Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save authorNari/5227985 to your computer and use it in GitHub Desktop.
Save authorNari/5227985 to your computer and use it in GitHub Desktop.
diff --git a/gc.c b/gc.c
index 0f84e22..8efd053 100644
--- a/gc.c
+++ b/gc.c
@@ -393,6 +393,7 @@ typedef struct rb_objspace {
struct gc_list *global_list;
size_t count;
int gc_stress;
+ int gc_disable_lazy_sweep;
} rb_objspace_t;
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
@@ -419,6 +420,7 @@ int *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress;
#define deferred_final_list objspace->final.deferred
#define global_List objspace->global_list
#define ruby_gc_stress objspace->gc_stress
+#define ruby_gc_disable_lazy_sweep objspace->gc_disable_lazy_sweep
#define initial_malloc_limit initial_params.initial_malloc_limit
#define initial_heap_min_slots initial_params.initial_heap_min_slots
#define initial_free_min initial_params.initial_free_min
@@ -445,6 +447,7 @@ void
rb_gc_set_params(void)
{
char *malloc_limit_ptr, *heap_min_slots_ptr, *free_min_ptr;
+ char *disable_lazy_sweep_ptr;
if (rb_safe_level() > 0) return;
@@ -480,6 +483,15 @@ rb_gc_set_params(void)
initial_free_min = free_min_i;
}
}
+
+ disable_lazy_sweep_ptr = getenv("RUBY_GC_DISABLE_LAZY_SWEEP");
+ if (disable_lazy_sweep_ptr != NULL) {
+ int disable_lazy_sweep_i = atoi(disable_lazy_sweep_ptr);
+ if (RTEST(ruby_verbose))
+ fprintf(stderr, "disable_lazy_sweep=%d (%d)\n",
+ disable_lazy_sweep_i, rb_objspace.gc_disable_lazy_sweep);
+ rb_objspace.gc_disable_lazy_sweep = disable_lazy_sweep_i;
+ }
}
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
@@ -963,6 +975,51 @@ rb_gc_disable(void)
return old ? Qtrue : Qfalse;
}
+/*
+ * call-seq:
+ * GC.enable_lazy_sweep -> true or false
+ *
+ * Enables lazy sweep algorithm, returning <code>true</code> if lazy
+ * sweep was previously disabled.
+ *
+ * GC.disable_lazy_sweep #=> false
+ * GC.enable_lazy_sweep #=> true
+ * GC.enable_lazy_sweep #=> false
+ *
+ */
+
+VALUE
+rb_gc_enable_lazy_sweep(void)
+{
+ rb_objspace_t *objspace = &rb_objspace;
+ int old = ruby_gc_disable_lazy_sweep;
+
+ ruby_gc_disable_lazy_sweep = FALSE;
+ return old ? Qtrue : Qfalse;
+}
+
+/*
+ * call-seq:
+ * GC.disable_lazy_sweep -> true or false
+ *
+ * Disables lazy sweep algorithm, returning <code>true</code> if lazy
+ * sweep was already disabled.
+ *
+ * GC.disable_lazy_sweep #=> false
+ * GC.disable_lazy_sweep #=> true
+ *
+ */
+
+VALUE
+rb_gc_disable_lazy_sweep(void)
+{
+ rb_objspace_t *objspace = &rb_objspace;
+ int old = ruby_gc_disable_lazy_sweep;
+
+ ruby_gc_disable_lazy_sweep = TRUE;
+ return old ? Qtrue : Qfalse;
+}
+
VALUE rb_mGC;
void
@@ -2273,9 +2330,11 @@ gc_lazy_sweep(rb_objspace_t *objspace)
int res;
INIT_GC_PROF_PARAMS;
- if (objspace->flags.dont_lazy_sweep)
- return garbage_collect(objspace);
-
+ if (ruby_gc_disable_lazy_sweep || objspace->flags.dont_lazy_sweep) {
+ if (!heaps_increment(objspace)) {
+ return garbage_collect(objspace);
+ }
+ }
if (!ready_to_gc(objspace)) return TRUE;
@@ -3674,6 +3733,8 @@ Init_GC(void)
rb_define_singleton_method(rb_mGC, "start", rb_gc_start, 0);
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, "enable_lazy_sweep", rb_gc_enable_lazy_sweep, 0);
+ rb_define_singleton_method(rb_mGC, "disable_lazy_sweep", rb_gc_disable_lazy_sweep, 0);
rb_define_singleton_method(rb_mGC, "stress", gc_stress_get, 0);
rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1);
rb_define_singleton_method(rb_mGC, "count", gc_count, 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment