summaryrefslogtreecommitdiff
path: root/variable.c
diff options
context:
space:
mode:
authortenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-17 03:17:25 +0000
committertenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-17 03:17:25 +0000
commit3c55b643aec09bbe779dab25b2397947eded2b9b (patch)
treed7705428a035cd7c4384a0e34d59415bf3de9ca4 /variable.c
parentfcd679ed11e3e801431f2f931dbe925edb8df0bf (diff)
Adding `GC.compact` and compacting GC support.
This commit adds the new method `GC.compact` and compacting GC support. Please see this issue for caveats: https://bugs.ruby-lang.org/issues/15626 [Feature #15626] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67576 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'variable.c')
-rw-r--r--variable.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/variable.c b/variable.c
index f4988b699d..2c69e2169c 100644
--- a/variable.c
+++ b/variable.c
@@ -1201,6 +1201,16 @@ rb_mark_generic_ivar(VALUE obj)
}
void
+rb_mv_generic_ivar(VALUE rsrc, VALUE dst)
+{
+ st_data_t key = (st_data_t)rsrc;
+ struct gen_ivtbl *ivtbl;
+
+ if (st_delete(generic_iv_tbl, &key, (st_data_t *)&ivtbl))
+ st_insert(generic_iv_tbl, (st_data_t)dst, (st_data_t)ivtbl);
+}
+
+void
rb_free_generic_ivar(VALUE obj)
{
st_data_t key = (st_data_t)obj;
@@ -1950,7 +1960,7 @@ rb_mod_const_missing(VALUE klass, VALUE name)
static void
autoload_mark(void *ptr)
{
- rb_mark_tbl((st_table *)ptr);
+ rb_mark_tbl_no_pin((st_table *)ptr);
}
static void
@@ -1966,9 +1976,15 @@ autoload_memsize(const void *ptr)
return st_memsize(tbl);
}
+static void
+autoload_compact(void *ptr)
+{
+ rb_gc_update_tbl_refs((st_table *)ptr);
+}
+
static const rb_data_type_t autoload_data_type = {
"autoload",
- {autoload_mark, autoload_free, autoload_memsize,},
+ {autoload_mark, autoload_free, autoload_memsize, autoload_compact,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -2015,11 +2031,18 @@ struct autoload_data_i {
};
static void
+autoload_i_compact(void *ptr)
+{
+ struct autoload_data_i *p = ptr;
+ p->feature = rb_gc_new_location(p->feature);
+}
+
+static void
autoload_i_mark(void *ptr)
{
struct autoload_data_i *p = ptr;
- rb_gc_mark(p->feature);
+ rb_gc_mark_no_pin(p->feature);
/* allow GC to free us if no modules refer to this via autoload_const.ad */
if (list_empty(&p->constants)) {
@@ -2046,7 +2069,7 @@ autoload_i_memsize(const void *ptr)
static const rb_data_type_t autoload_data_i_type = {
"autoload_i",
- {autoload_i_mark, autoload_i_free, autoload_i_memsize,},
+ {autoload_i_mark, autoload_i_free, autoload_i_memsize, autoload_i_compact},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@@ -2971,6 +2994,7 @@ rb_define_const(VALUE klass, const char *name, VALUE val)
if (!rb_is_const_id(id)) {
rb_warn("rb_define_const: invalid name `%s' for constant", name);
}
+ rb_gc_register_mark_object(val);
rb_const_set(klass, id, val);
}