[前][次][番号順一覧][スレッド一覧]

ruby-changes:56084

From: Aaron <ko1@a...>
Date: Wed, 12 Jun 2019 01:16:45 +0900 (JST)
Subject: [ruby-changes:56084] Aaron Patterson: 6db2d6d852 (trunk): Add compaction support for more types.

https://git.ruby-lang.org/ruby.git/commit/?id=6db2d6d852

From 6db2d6d8520f88e25d97af77495eb6c879f90b21 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Fri, 31 May 2019 13:25:24 -0700
Subject: Add compaction support for more types.

This commit adds compaction support for:

* Fibers
* Continuations
* Autoload Constants

diff --git a/cont.c b/cont.c
index 516a847..0d091b9 100644
--- a/cont.c
+++ b/cont.c
@@ -340,12 +340,21 @@ cont_thread_value(const rb_context_t *cont) https://github.com/ruby/ruby/blob/trunk/cont.c#L340
 }
 
 static void
+cont_compact(void *ptr)
+{
+    rb_context_t *cont = ptr;
+
+    cont->value = rb_gc_location(cont->value);
+    rb_execution_context_update(&cont->saved_ec);
+}
+
+static void
 cont_mark(void *ptr)
 {
     rb_context_t *cont = ptr;
 
     RUBY_MARK_ENTER("cont");
-    rb_gc_mark(cont->value);
+    rb_gc_mark_no_pin(cont->value);
 
     rb_execution_context_mark(&cont->saved_ec);
     rb_gc_mark(cont_thread_value(cont));
@@ -481,10 +490,21 @@ cont_memsize(const void *ptr) https://github.com/ruby/ruby/blob/trunk/cont.c#L490
 }
 
 void
+rb_fiber_update_self(rb_fiber_t *fib)
+{
+    if (fib->cont.self) {
+	fib->cont.self = rb_gc_location(fib->cont.self);
+    }
+    else {
+	rb_execution_context_update(&fib->cont.saved_ec);
+    }
+}
+
+void
 rb_fiber_mark_self(const rb_fiber_t *fib)
 {
     if (fib->cont.self) {
-	rb_gc_mark(fib->cont.self);
+	rb_gc_mark_no_pin(fib->cont.self);
     }
     else {
 	rb_execution_context_mark(&fib->cont.saved_ec);
@@ -492,12 +512,24 @@ rb_fiber_mark_self(const rb_fiber_t *fib) https://github.com/ruby/ruby/blob/trunk/cont.c#L512
 }
 
 static void
+fiber_compact(void *ptr)
+{
+    rb_fiber_t *fib = ptr;
+    fib->first_proc = rb_gc_location(fib->first_proc);
+
+    if (fib->prev) rb_fiber_update_self(fib->prev);
+
+    cont_compact(&fib->cont);
+    fiber_verify(fib);
+}
+
+static void
 fiber_mark(void *ptr)
 {
     rb_fiber_t *fib = ptr;
     RUBY_MARK_ENTER("cont");
     fiber_verify(fib);
-    rb_gc_mark(fib->first_proc);
+    rb_gc_mark_no_pin(fib->first_proc);
     if (fib->prev) rb_fiber_mark_self(fib->prev);
 
 #if !FIBER_USE_NATIVE
@@ -602,7 +634,7 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont) https://github.com/ruby/ruby/blob/trunk/cont.c#L634
 
 static const rb_data_type_t cont_data_type = {
     "continuation",
-    {cont_mark, cont_free, cont_memsize,},
+    {cont_mark, cont_free, cont_memsize, cont_compact},
     0, 0, RUBY_TYPED_FREE_IMMEDIATELY
 };
 
@@ -1424,7 +1456,7 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval) https://github.com/ruby/ruby/blob/trunk/cont.c#L1456
 
 static const rb_data_type_t fiber_data_type = {
     "fiber",
-    {fiber_mark, fiber_free, fiber_memsize,},
+    {fiber_mark, fiber_free, fiber_memsize, fiber_compact,},
     0, 0, RUBY_TYPED_FREE_IMMEDIATELY
 };
 
diff --git a/proc.c b/proc.c
index de60a8c..8372979 100644
--- a/proc.c
+++ b/proc.c
@@ -64,7 +64,7 @@ block_mark(const struct rb_block *block) https://github.com/ruby/ruby/blob/trunk/proc.c#L64
 	    RUBY_MARK_NO_PIN_UNLESS_NULL(captured->self);
 	    RUBY_MARK_NO_PIN_UNLESS_NULL((VALUE)captured->code.val);
 	    if (captured->ep && captured->ep[VM_ENV_DATA_INDEX_ENV] != Qundef /* cfunc_proc_t */) {
-		RUBY_MARK_UNLESS_NULL(VM_ENV_ENVVAL(captured->ep));
+		RUBY_MARK_NO_PIN_UNLESS_NULL(VM_ENV_ENVVAL(captured->ep));
 	    }
 	}
 	break;
@@ -87,6 +87,9 @@ block_compact(struct rb_block *block) https://github.com/ruby/ruby/blob/trunk/proc.c#L87
 	    struct rb_captured_block *captured = &block->as.captured;
             captured->self = rb_gc_location(captured->self);
             captured->code.val = rb_gc_location(captured->code.val);
+	    if (captured->ep && captured->ep[VM_ENV_DATA_INDEX_ENV] != Qundef /* cfunc_proc_t */) {
+                UPDATE_REFERENCE(captured->ep[VM_ENV_DATA_INDEX_ENV]);
+	    }
 	}
 	break;
       case block_type_symbol:
diff --git a/variable.c b/variable.c
index ebfdf0d..be0eee1 100644
--- a/variable.c
+++ b/variable.c
@@ -1913,13 +1913,23 @@ static const rb_data_type_t autoload_data_i_type = { https://github.com/ruby/ruby/blob/trunk/variable.c#L1913
 };
 
 static void
+autoload_c_compact(void *ptr)
+{
+    struct autoload_const *ac = ptr;
+
+    ac->mod = rb_gc_location(ac->mod);
+    ac->ad = rb_gc_location(ac->ad);
+    ac->value = rb_gc_location(ac->value);
+}
+
+static void
 autoload_c_mark(void *ptr)
 {
     struct autoload_const *ac = ptr;
 
-    rb_gc_mark(ac->mod);
-    rb_gc_mark(ac->ad);
-    rb_gc_mark(ac->value);
+    rb_gc_mark_no_pin(ac->mod);
+    rb_gc_mark_no_pin(ac->ad);
+    rb_gc_mark_no_pin(ac->value);
 }
 
 static void
@@ -1938,7 +1948,7 @@ autoload_c_memsize(const void *ptr) https://github.com/ruby/ruby/blob/trunk/variable.c#L1948
 
 static const rb_data_type_t autoload_const_type = {
     "autoload_const",
-    {autoload_c_mark, autoload_c_free, autoload_c_memsize,},
+    {autoload_c_mark, autoload_c_free, autoload_c_memsize, autoload_c_compact,},
     0, 0, RUBY_TYPED_FREE_IMMEDIATELY
 };
 
diff --git a/vm.c b/vm.c
index 70ec231..ce8853b 100644
--- a/vm.c
+++ b/vm.c
@@ -2476,6 +2476,36 @@ rb_thread_recycle_stack_release(VALUE *stack) https://github.com/ruby/ruby/blob/trunk/vm.c#L2476
 }
 
 void
+rb_execution_context_update(const rb_execution_context_t *ec)
+{
+    /* update VM stack */
+    if (ec->vm_stack) {
+	rb_control_frame_t *cfp = ec->cfp;
+	rb_control_frame_t *limit_cfp = (void *)(ec->vm_stack + ec->vm_stack_size);
+
+	while (cfp != limit_cfp) {
+	    const VALUE *ep = cfp->ep;
+            cfp->self = rb_gc_location(cfp->self);
+            cfp->iseq = (rb_iseq_t *)rb_gc_location((VALUE)cfp->iseq);
+            cfp->block_code = (void *)rb_gc_location((VALUE)cfp->block_code);
+
+	    if (!VM_ENV_LOCAL_P(ep)) {
+		VALUE *prev_ep = (VALUE *)VM_ENV_PREV_EP(ep);
+		if (VM_ENV_FLAGS(prev_ep, VM_ENV_FLAG_ESCAPED)) {
+                    prev_ep[VM_ENV_DATA_INDEX_ENV] = rb_gc_location(prev_ep[VM_ENV_DATA_INDEX_ENV]);
+		}
+	    }
+
+	    cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+	}
+    }
+#if VM_CHECK_MODE > 0
+    void rb_ec_verify(const rb_execution_context_t *ec); /* cont.c */
+    rb_ec_verify(ec);
+#endif
+}
+
+void
 rb_execution_context_mark(const rb_execution_context_t *ec)
 {
 #if VM_CHECK_MODE > 0
@@ -2495,14 +2525,14 @@ rb_execution_context_mark(const rb_execution_context_t *ec) https://github.com/ruby/ruby/blob/trunk/vm.c#L2525
 	while (cfp != limit_cfp) {
 	    const VALUE *ep = cfp->ep;
 	    VM_ASSERT(!!VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED) == vm_ep_in_heap_p_(ec, ep));
-	    rb_gc_mark(cfp->self);
-	    rb_gc_mark((VALUE)cfp->iseq);
-	    rb_gc_mark((VALUE)cfp->block_code);
+	    rb_gc_mark_no_pin(cfp->self);
+	    rb_gc_mark_no_pin((VALUE)cfp->iseq);
+	    rb_gc_mark_no_pin((VALUE)cfp->block_code);
 
 	    if (!VM_ENV_LOCAL_P(ep)) {
 		const VALUE *prev_ep = VM_ENV_PREV_EP(ep);
 		if (VM_ENV_FLAGS(prev_ep, VM_ENV_FLAG_ESCAPED)) {
-		    rb_gc_mark(prev_ep[VM_ENV_DATA_INDEX_ENV]);
+		    rb_gc_mark_no_pin(prev_ep[VM_ENV_DATA_INDEX_ENV]);
 		}
 	    }
 
@@ -2529,10 +2559,22 @@ rb_execution_context_mark(const rb_execution_context_t *ec) https://github.com/ruby/ruby/blob/trunk/vm.c#L2559
 }
 
 void rb_fiber_mark_self(rb_fiber_t *fib);
+void rb_fiber_update_self(rb_fiber_t *fib);
 void rb_threadptr_root_fiber_setup(rb_thread_t *th);
 void rb_threadptr_root_fiber_release(rb_thread_t *th);
 
 static void
+thread_compact(void *ptr)
+{
+    rb_thread_t *th = ptr;
+    rb_fiber_update_self(th->ec->fiber_ptr);
+
+    if (th->root_fiber) rb_fiber_update_self(th->root_fiber);
+
+    rb_execution_context_update(th->ec);
+}
+
+static void
 thread_mark(void *ptr)
 {
     rb_thread_t *th = ptr;
@@ -2617,6 +2659,7 @@ const rb_data_type_t ruby_threadptr_data_type = { https://github.com/ruby/ruby/blob/trunk/vm.c#L2659
 	thread_mark,
 	thread_free,
 	thread_memsize,
+	thread_compact,
     },
     0, 0, RUBY_TYPED_FREE_IMMEDIATELY
 };
diff --git a/vm_core.h b/vm_core.h
index 95cd2d8..a0f9388 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -1815,6 +1815,7 @@ void rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th); https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1815
 void rb_threadptr_pending_interrupt_clear(rb_thread_t *th);
 void rb_threadptr_pending_interrupt_enque(rb_thread_t *th, VALUE v);
 void rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo);
+void rb_execution_context_update(const rb_execution_context_t *ec);
 void rb_execution_context_mark(const rb_execution_context_t *ec);
 void rb_fiber_close(rb_fiber_t *fib);
 void Init_native_thread(rb_thread_t *th);
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]