mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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.
This commit is contained in:
parent
7ded8fd29a
commit
ff4f9cf95d
3 changed files with 45 additions and 1 deletions
1
gc.c
1
gc.c
|
@ -8491,6 +8491,7 @@ gc_update_references(rb_objspace_t * objspace)
|
||||||
objspace_each_objects_without_setup(objspace, gc_ref_update, objspace);
|
objspace_each_objects_without_setup(objspace, gc_ref_update, objspace);
|
||||||
rb_vm_update_references(vm);
|
rb_vm_update_references(vm);
|
||||||
rb_transient_heap_update_references();
|
rb_transient_heap_update_references();
|
||||||
|
rb_gc_update_global_tbl();
|
||||||
global_symbols.ids = rb_gc_location(global_symbols.ids);
|
global_symbols.ids = rb_gc_location(global_symbols.ids);
|
||||||
global_symbols.dsymbol_fstr_hash = rb_gc_location(global_symbols.dsymbol_fstr_hash);
|
global_symbols.dsymbol_fstr_hash = rb_gc_location(global_symbols.dsymbol_fstr_hash);
|
||||||
gc_update_tbl_refs(objspace, objspace->obj_to_id_tbl);
|
gc_update_tbl_refs(objspace, objspace->obj_to_id_tbl);
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct rb_global_entry {
|
||||||
|
|
||||||
/* variable.c */
|
/* variable.c */
|
||||||
void rb_gc_mark_global_tbl(void);
|
void rb_gc_mark_global_tbl(void);
|
||||||
|
void rb_gc_update_global_tbl(void);
|
||||||
size_t rb_generic_ivar_memsize(VALUE);
|
size_t rb_generic_ivar_memsize(VALUE);
|
||||||
VALUE rb_search_class_path(VALUE);
|
VALUE rb_search_class_path(VALUE);
|
||||||
VALUE rb_attr_delete(VALUE, ID);
|
VALUE rb_attr_delete(VALUE, ID);
|
||||||
|
|
44
variable.c
44
variable.c
|
@ -36,6 +36,8 @@
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include "vm_core.h"
|
#include "vm_core.h"
|
||||||
|
|
||||||
|
typedef void rb_gvar_compact_t(void *var);
|
||||||
|
|
||||||
static struct rb_id_table *rb_global_tbl;
|
static struct rb_id_table *rb_global_tbl;
|
||||||
static ID autoload, classpath, tmp_classpath;
|
static ID autoload, classpath, tmp_classpath;
|
||||||
static VALUE autoload_featuremap; /* feature => autoload_i */
|
static VALUE autoload_featuremap; /* feature => autoload_i */
|
||||||
|
@ -316,6 +318,7 @@ struct rb_global_variable {
|
||||||
rb_gvar_getter_t *getter;
|
rb_gvar_getter_t *getter;
|
||||||
rb_gvar_setter_t *setter;
|
rb_gvar_setter_t *setter;
|
||||||
rb_gvar_marker_t *marker;
|
rb_gvar_marker_t *marker;
|
||||||
|
rb_gvar_compact_t *compactor;
|
||||||
struct trace_var *trace;
|
struct trace_var *trace;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -333,6 +336,11 @@ rb_find_global_entry(ID id)
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_gvar_undef_compactor(void *var)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
MJIT_FUNC_EXPORTED struct rb_global_entry*
|
MJIT_FUNC_EXPORTED struct rb_global_entry*
|
||||||
rb_global_entry(ID id)
|
rb_global_entry(ID id)
|
||||||
{
|
{
|
||||||
|
@ -348,6 +356,7 @@ rb_global_entry(ID id)
|
||||||
var->getter = rb_gvar_undef_getter;
|
var->getter = rb_gvar_undef_getter;
|
||||||
var->setter = rb_gvar_undef_setter;
|
var->setter = rb_gvar_undef_setter;
|
||||||
var->marker = rb_gvar_undef_marker;
|
var->marker = rb_gvar_undef_marker;
|
||||||
|
var->compactor = rb_gvar_undef_compactor;
|
||||||
|
|
||||||
var->block_trace = 0;
|
var->block_trace = 0;
|
||||||
var->trace = 0;
|
var->trace = 0;
|
||||||
|
@ -364,6 +373,21 @@ rb_gvar_undef_getter(ID id, VALUE *_)
|
||||||
return Qnil;
|
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
|
void
|
||||||
rb_gvar_undef_setter(VALUE val, ID id, VALUE *_)
|
rb_gvar_undef_setter(VALUE val, ID id, VALUE *_)
|
||||||
{
|
{
|
||||||
|
@ -371,6 +395,7 @@ rb_gvar_undef_setter(VALUE val, ID id, VALUE *_)
|
||||||
var->getter = rb_gvar_val_getter;
|
var->getter = rb_gvar_val_getter;
|
||||||
var->setter = rb_gvar_val_setter;
|
var->setter = rb_gvar_val_setter;
|
||||||
var->marker = rb_gvar_val_marker;
|
var->marker = rb_gvar_val_marker;
|
||||||
|
var->compactor = rb_gvar_val_compactor;
|
||||||
|
|
||||||
var->data = (void*)val;
|
var->data = (void*)val;
|
||||||
}
|
}
|
||||||
|
@ -397,7 +422,7 @@ void
|
||||||
rb_gvar_val_marker(VALUE *var)
|
rb_gvar_val_marker(VALUE *var)
|
||||||
{
|
{
|
||||||
VALUE data = (VALUE)var;
|
VALUE data = (VALUE)var;
|
||||||
if (data) rb_gc_mark(data);
|
if (data) rb_gc_mark_movable(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -448,6 +473,23 @@ rb_gc_mark_global_tbl(void)
|
||||||
rb_id_table_foreach_values(rb_global_tbl, mark_global_entry, 0);
|
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
|
static ID
|
||||||
global_id(const char *name)
|
global_id(const char *name)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue