diff options
author | tenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-04-09 20:32:04 +0000 |
---|---|---|
committer | tenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-04-09 20:32:04 +0000 |
commit | 3ef4db15e95740839a0ed6d0224b2c9562bb2544 (patch) | |
tree | 18c23ed1b2e3c7b55860c27238a98cafafe63d9f /variable.c | |
parent | c09e35d7bbb5c18124d7ab54740bef966e145529 (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@67479 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'variable.c')
-rw-r--r-- | variable.c | 32 |
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); } |