Mark cc->cme_ for refinement callcaches as well

This is required for the same reason that super CC needs it.
See 36023d5cb751d62fca0c27901c07527b20170f4d.

Reproducer:

    def cached_foo_callsite(obj) = obj.foo

    class Foo
      def foo = :v1

      module R
        refine Foo do
          def foo = :unused
        end
      end
    end

    obj = Foo.new
    cached_foo_callsite(obj) # set up cc with cme for foo=:v1

    class Foo
      def foo = :v2
    end
    GC.start # cme for foo=:v1 collected, if not reachable by cached_foo_callsite

    cached_foo_callsite(obj)

[Bug #19994]
This commit is contained in:
KJ Tsanaktsidis 2023-11-11 16:12:12 +11:00 committed by Alan Wu
parent 99e1f7b607
commit e201b81f79

7
gc.c
View File

@ -7216,12 +7216,13 @@ gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
* - On the multi-Ractors, cme will be collected with global GC
* so that it is safe if GC is not interleaving while accessing
* cc and cme.
* - However, cc_type_super is not chained from cc so the cc->cme
* should be marked.
* - However, cc_type_super and cc_type_refinement are not chained
* from ccs so cc->cme should be marked; the cme might be
* reachable only through cc in these cases.
*/
{
const struct rb_callcache *cc = (const struct rb_callcache *)obj;
if (vm_cc_super_p(cc)) {
if (vm_cc_super_p(cc) || vm_cc_refinement_p(cc)) {
gc_mark(objspace, (VALUE)cc->cme_);
}
}