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/