dumping ground for random patches and texts
 help / color / mirror / Atom feed
From: Eric Wong <e@80x24.org>
To: spew@80x24.org
Subject: [PATCH] gc.c: enter sleepy GC start
Date: Mon, 14 May 2018 20:15:09 +0000	[thread overview]
Message-ID: <20180514201509.28069-1-e@80x24.org> (raw)

For rare situations when no free pages are available, we may
start GC.  This is a conservative change which may not be worth
the effort.  In the future, we may prematurely start GC before
pages become unavailable.
---
 gc.c | 27 +++++++++++++++++++++++++--
 gc.h |  7 +++++--
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/gc.c b/gc.c
index c705d0d513..c7f19a5f81 100644
--- a/gc.c
+++ b/gc.c
@@ -352,6 +352,7 @@ typedef enum {
     GPR_FLAG_METHOD             = 0x400,
     GPR_FLAG_CAPI               = 0x800,
     GPR_FLAG_STRESS            = 0x1000,
+    GPR_FLAG_SLEEPY             = 0x8000,
 
     /* others */
     GPR_FLAG_IMMEDIATE_SWEEP   = 0x2000,
@@ -6536,7 +6537,23 @@ gc_rest(rb_objspace_t *objspace)
     }
 }
 
-#if RUBY_GC_SLEEPY_SWEEP || RUBY_GC_SLEEPY_MARK
+#if RUBY_GC_SLEEPY_SWEEP || RUBY_GC_SLEEPY_MARK || RUBY_GC_SLEEPY_START
+static inline int
+can_sleepy_start(rb_objspace_t *objspace)
+{
+    rb_heap_t *heap = heap_eden;
+
+    if (!RUBY_GC_SLEEPY_START || dont_gc || during_gc || ruby_disable_gc) {
+        return 0;
+    }
+    if (heap->free_pages == NULL &&
+            (will_be_incremental_marking(objspace) ||
+                heap_increment(objspace, heap) == FALSE)) {
+        return 1;
+    }
+    return 0;
+}
+
 /* this is just a hint, TOCTOU race may happen */
 int
 rb_gc_inprogress(const rb_execution_context_t *ec)
@@ -6544,7 +6561,8 @@ rb_gc_inprogress(const rb_execution_context_t *ec)
     rb_objspace_t *objspace = rb_ec_vm_ptr(ec)->objspace;
 
     return (RUBY_GC_SLEEPY_SWEEP && is_lazy_sweeping(&objspace->eden_heap)) ||
-           (RUBY_GC_SLEEPY_MARK && is_incremental_marking(objspace));
+           (RUBY_GC_SLEEPY_MARK && is_incremental_marking(objspace) ||
+           can_sleepy_start(objspace));
 }
 
 /* returns true if there is more work to do, false if not */
@@ -6563,6 +6581,9 @@ rb_gc_step(const rb_execution_context_t *ec)
 	gc_marks_continue(objspace, &objspace->eden_heap);
 #endif
     }
+    else if (can_sleepy_start(objspace)) {
+        gc_start(objspace, FALSE, FALSE, FALSE, GPR_FLAG_SLEEPY);
+    }
 
     return rb_gc_inprogress(ec);
 }
@@ -6842,6 +6863,7 @@ gc_info_decode(rb_objspace_t *objspace, const VALUE hash_or_key, const int orig_
 {
     static VALUE sym_major_by = Qnil, sym_gc_by, sym_immediate_sweep, sym_have_finalizer, sym_state;
     static VALUE sym_nofree, sym_oldgen, sym_shady, sym_force, sym_stress;
+    static VALUE sym_sleepy;
 #if RGENGC_ESTIMATE_OLDMALLOC
     static VALUE sym_oldmalloc;
 #endif
@@ -6911,6 +6933,7 @@ gc_info_decode(rb_objspace_t *objspace, const VALUE hash_or_key, const int orig_
 	(flags & GPR_FLAG_METHOD) ? sym_method :
 	(flags & GPR_FLAG_CAPI)   ? sym_capi :
 	(flags & GPR_FLAG_STRESS) ? sym_stress :
+	(flags & GPR_FLAG_SLEEPY) ? sym_sleepy :
 	Qnil
     );
 
diff --git a/gc.h b/gc.h
index 1f8a06cdc7..954fa86162 100644
--- a/gc.h
+++ b/gc.h
@@ -99,11 +99,14 @@ struct rb_execution_context_struct;
 #ifndef RUBY_GC_SLEEPY_MARK
 #  define RUBY_GC_SLEEPY_MARK 1
 #endif
+#ifndef RUBY_GC_SLEEPY_START
+#  define RUBY_GC_SLEEPY_START 1
+#endif
 
-#if RUBY_GC_SLEEPY_SWEEP || RUBY_GC_SLEEPY_MARK
+#if RUBY_GC_SLEEPY_SWEEP || RUBY_GC_SLEEPY_MARK || RUBY_GC_SLEEPY_START
 int rb_gc_inprogress(const struct rb_execution_context_struct *);
 int rb_gc_step(const struct rb_execution_context_struct *);
-#else /* (RUBY_GC_SLEEPY_SWEEP|RUBY_GC_SLEEPY_MARK) == 0 */
+#else /* (RUBY_GC_SLEEPY_SWEEP|RUBY_GC_SLEEPY_MARK|RUBY_GC_SLEEPY_START) == 0 */
 static inline int
 rb_gc_inprogress(const struct rb_execution_context_struct *ec)
 {
-- 
EW


                 reply	other threads:[~2018-05-14 20:15 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180514201509.28069-1-e@80x24.org \
    --to=e@80x24.org \
    --cc=spew@80x24.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).