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

ruby-changes:66266

From: Aaron <ko1@a...>
Date: Wed, 19 May 2021 06:53:29 +0900 (JST)
Subject: [ruby-changes:66266] e4e416380d (master): Revert any references that are on the machine stack after compacting

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

From e4e416380d4b1b36ca1cc2e1e1ed993c9be694bb Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Mon, 17 May 2021 16:46:49 -0700
Subject: Revert any references that are on the machine stack after compacting

Since compaction can be concurrent, the machine stack is allowed to
change while compaction is happening.  When compaction finishes, there
may be references on the machine stack that need to be reverted so that
we can remove the read barrier.
---
 gc.c | 56 +++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/gc.c b/gc.c
index e36282b..1d34917 100644
--- a/gc.c
+++ b/gc.c
@@ -5112,11 +5112,27 @@ revert_stack_objects(VALUE stack_obj, void *ctx) https://github.com/ruby/ruby/blob/trunk/gc.c#L5112
 }
 
 static void
+revert_machine_stack_references(rb_objspace_t *objspace, VALUE v)
+{
+    if (is_pointer_to_heap(objspace, (void *)v)) {
+        if (BUILTIN_TYPE(v) == T_MOVED) {
+            /* For now we'll revert the whole page if the object made it to the
+             * stack.  I think we can change this to move just the one object
+             * back though */
+            invalidate_moved_page(objspace, GET_HEAP_PAGE(v));
+        }
+    }
+}
+
+static void each_machine_stack_value(const rb_execution_context_t *ec, void (*cb)(rb_objspace_t *, VALUE));
+
+static void
 check_stack_for_moved(rb_objspace_t *objspace)
 {
     rb_execution_context_t *ec = GET_EC();
     rb_vm_t *vm = rb_ec_vm_ptr(ec);
     rb_vm_each_stack_value(vm, revert_stack_objects, (void*)objspace);
+    each_machine_stack_value(ec, revert_machine_stack_references);
 }
 
 static void
@@ -6001,32 +6017,32 @@ ruby_stack_check(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L6017
     return stack_check(GET_EC(), STACKFRAME_FOR_CALL_CFUNC);
 }
 
-ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(static void mark_locations_array(rb_objspace_t *objspace, register const VALUE *x, register long n));
+ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(static void each_location(rb_objspace_t *objspace, register const VALUE *x, register long n, void (*cb)(rb_objspace_t *, VALUE)));
 static void
-mark_locations_array(rb_objspace_t *objspace, register const VALUE *x, register long n)
+each_location(rb_objspace_t *objspace, register const VALUE *x, register long n, void (*cb)(rb_objspace_t *, VALUE))
 {
     VALUE v;
     while (n--) {
         v = *x;
-        gc_mark_maybe(objspace, v);
+        cb(objspace, v);
 	x++;
     }
 }
 
 static void
-gc_mark_locations(rb_objspace_t *objspace, const VALUE *start, const VALUE *end)
+gc_mark_locations(rb_objspace_t *objspace, const VALUE *start, const VALUE *end, void (*cb)(rb_objspace_t *, VALUE))
 {
     long n;
 
     if (end <= start) return;
     n = end - start;
-    mark_locations_array(objspace, start, n);
+    each_location(objspace, start, n, cb);
 }
 
 void
 rb_gc_mark_locations(const VALUE *start, const VALUE *end)
 {
-    gc_mark_locations(&rb_objspace, start, end);
+    gc_mark_locations(&rb_objspace, start, end, gc_mark_maybe);
 }
 
 static void
@@ -6284,8 +6300,8 @@ mark_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl) https://github.com/ruby/ruby/blob/trunk/gc.c#L6300
      ((start) = STACK_END, (end) = STACK_START) : ((start) = STACK_START, (end) = STACK_END+(appendix)))
 #endif
 
-static void mark_stack_locations(rb_objspace_t *objspace, const rb_execution_context_t *ec,
-				 const VALUE *stack_start, const VALUE *stack_end);
+static void each_stack_location(rb_objspace_t *objspace, const rb_execution_context_t *ec,
+                                 const VALUE *stack_start, const VALUE *stack_end, void (*cb)(rb_objspace_t *, VALUE));
 
 #ifndef __EMSCRIPTEN__
 static void
@@ -6308,9 +6324,9 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec https://github.com/ruby/ruby/blob/trunk/gc.c#L6324
     SET_STACK_END;
     GET_STACK_BOUNDS(stack_start, stack_end, 1);
 
-    mark_locations_array(objspace, save_regs_gc_mark.v, numberof(save_regs_gc_mark.v));
+    each_location(objspace, save_regs_gc_mark.v, numberof(save_regs_gc_mark.v), gc_mark_maybe);
 
-    mark_stack_locations(objspace, ec, stack_start, stack_end);
+    each_stack_location(objspace, ec, stack_start, stack_end, gc_mark_maybe);
 }
 #else
 
@@ -6334,27 +6350,33 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec https://github.com/ruby/ruby/blob/trunk/gc.c#L6350
 }
 #endif
 
-void
-rb_gc_mark_machine_stack(const rb_execution_context_t *ec)
+static void
+each_machine_stack_value(const rb_execution_context_t *ec, void (*cb)(rb_objspace_t *, VALUE))
 {
     rb_objspace_t *objspace = &rb_objspace;
     VALUE *stack_start, *stack_end;
 
     GET_STACK_BOUNDS(stack_start, stack_end, 0);
-    mark_stack_locations(objspace, ec, stack_start, stack_end);
+    each_stack_location(objspace, ec, stack_start, stack_end, cb);
+}
+
+void
+rb_gc_mark_machine_stack(const rb_execution_context_t *ec)
+{
+    each_machine_stack_value(ec, gc_mark_maybe);
 }
 
 static void
-mark_stack_locations(rb_objspace_t *objspace, const rb_execution_context_t *ec,
-		     const VALUE *stack_start, const VALUE *stack_end)
+each_stack_location(rb_objspace_t *objspace, const rb_execution_context_t *ec,
+		     const VALUE *stack_start, const VALUE *stack_end, void (*cb)(rb_objspace_t *, VALUE))
 {
 
-    gc_mark_locations(objspace, stack_start, stack_end);
+    gc_mark_locations(objspace, stack_start, stack_end, cb);
 
 #if defined(__mc68000__)
     gc_mark_locations(objspace,
 		      (VALUE*)((char*)stack_start + 2),
-		      (VALUE*)((char*)stack_end - 2));
+		      (VALUE*)((char*)stack_end - 2), cb);
 #endif
 }
 
-- 
cgit v1.1


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

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