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

ruby-changes:61050

From: Aaron <ko1@a...>
Date: Fri, 8 May 2020 03:43:11 +0900 (JST)
Subject: [ruby-changes:61050] ff4f9cf95d (master): Allow global variables to move

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

From ff4f9cf95d73cc2730949df583bf0e41702d7aae Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Thu, 7 May 2020 10:07:57 -0700
Subject: Allow global variables to move

This patch allows global variables that have been assigned in Ruby to
move.  I added a new function for the GC to call that will update
global references and introduced a new callback in the global variable
struct for updating references.

Only pure Ruby global variables are supported right now, other
references will be pinned.

diff --git a/gc.c b/gc.c
index 67ec968..ab75d67 100644
--- a/gc.c
+++ b/gc.c
@@ -8491,6 +8491,7 @@ gc_update_references(rb_objspace_t * objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L8491
     objspace_each_objects_without_setup(objspace, gc_ref_update, objspace);
     rb_vm_update_references(vm);
     rb_transient_heap_update_references();
+    rb_gc_update_global_tbl();
     global_symbols.ids = rb_gc_location(global_symbols.ids);
     global_symbols.dsymbol_fstr_hash = rb_gc_location(global_symbols.dsymbol_fstr_hash);
     gc_update_tbl_refs(objspace, objspace->obj_to_id_tbl);
diff --git a/internal/variable.h b/internal/variable.h
index a3b8f79..8defc15 100644
--- a/internal/variable.h
+++ b/internal/variable.h
@@ -28,6 +28,7 @@ struct rb_global_entry { https://github.com/ruby/ruby/blob/trunk/internal/variable.h#L28
 
 /* variable.c */
 void rb_gc_mark_global_tbl(void);
+void rb_gc_update_global_tbl(void);
 size_t rb_generic_ivar_memsize(VALUE);
 VALUE rb_search_class_path(VALUE);
 VALUE rb_attr_delete(VALUE, ID);
diff --git a/variable.c b/variable.c
index 3bcee43..dad20f2 100644
--- a/variable.c
+++ b/variable.c
@@ -36,6 +36,8 @@ https://github.com/ruby/ruby/blob/trunk/variable.c#L36
 #include "variable.h"
 #include "vm_core.h"
 
+typedef void rb_gvar_compact_t(void *var);
+
 static struct rb_id_table *rb_global_tbl;
 static ID autoload, classpath, tmp_classpath;
 static VALUE autoload_featuremap; /* feature => autoload_i */
@@ -316,6 +318,7 @@ struct rb_global_variable { https://github.com/ruby/ruby/blob/trunk/variable.c#L318
     rb_gvar_getter_t *getter;
     rb_gvar_setter_t *setter;
     rb_gvar_marker_t *marker;
+    rb_gvar_compact_t *compactor;
     struct trace_var *trace;
 };
 
@@ -333,6 +336,11 @@ rb_find_global_entry(ID id) https://github.com/ruby/ruby/blob/trunk/variable.c#L336
     return entry;
 }
 
+static void
+rb_gvar_undef_compactor(void *var)
+{
+}
+
 MJIT_FUNC_EXPORTED struct rb_global_entry*
 rb_global_entry(ID id)
 {
@@ -348,6 +356,7 @@ rb_global_entry(ID id) https://github.com/ruby/ruby/blob/trunk/variable.c#L356
 	var->getter = rb_gvar_undef_getter;
 	var->setter = rb_gvar_undef_setter;
 	var->marker = rb_gvar_undef_marker;
+	var->compactor = rb_gvar_undef_compactor;
 
 	var->block_trace = 0;
 	var->trace = 0;
@@ -364,6 +373,21 @@ rb_gvar_undef_getter(ID id, VALUE *_) https://github.com/ruby/ruby/blob/trunk/variable.c#L373
     return Qnil;
 }
 
+static void
+rb_gvar_val_compactor(void *_var)
+{
+    struct rb_global_variable *var = (struct rb_global_variable *)_var;
+
+    VALUE obj = (VALUE)var->data;
+
+    if (obj) {
+        VALUE new = rb_gc_location(obj);
+        if (new != obj) {
+            var->data = (void*)new;
+        }
+    }
+}
+
 void
 rb_gvar_undef_setter(VALUE val, ID id, VALUE *_)
 {
@@ -371,6 +395,7 @@ rb_gvar_undef_setter(VALUE val, ID id, VALUE *_) https://github.com/ruby/ruby/blob/trunk/variable.c#L395
     var->getter = rb_gvar_val_getter;
     var->setter = rb_gvar_val_setter;
     var->marker = rb_gvar_val_marker;
+    var->compactor = rb_gvar_val_compactor;
 
     var->data = (void*)val;
 }
@@ -397,7 +422,7 @@ void https://github.com/ruby/ruby/blob/trunk/variable.c#L422
 rb_gvar_val_marker(VALUE *var)
 {
     VALUE data = (VALUE)var;
-    if (data) rb_gc_mark(data);
+    if (data) rb_gc_mark_movable(data);
 }
 
 VALUE
@@ -448,6 +473,23 @@ rb_gc_mark_global_tbl(void) https://github.com/ruby/ruby/blob/trunk/variable.c#L473
         rb_id_table_foreach_values(rb_global_tbl, mark_global_entry, 0);
 }
 
+static enum rb_id_table_iterator_result
+update_global_entry(VALUE v, void *ignored)
+{
+    struct rb_global_entry *entry = (struct rb_global_entry *)v;
+    struct rb_global_variable *var = entry->var;
+
+    (*var->compactor)(var);
+    return ID_TABLE_CONTINUE;
+}
+
+void
+rb_gc_update_global_tbl(void)
+{
+    if (rb_global_tbl)
+        rb_id_table_foreach_values(rb_global_tbl, update_global_entry, 0);
+}
+
 static ID
 global_id(const char *name)
 {
-- 
cgit v0.10.2


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

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