mandatory_only_cme should not be in def

`def` (`rb_method_definition_t`) is shared by multiple callable
method entries (cme, `rb_callable_method_entry_t`).

There are two issues:

* old -> young reference: `cme1->def->mandatory_only_cme = monly_cme`
  if `cme1` is young and `monly_cme` is young, there is no problem.
  Howevr, another old `cme2` can refer `def`, in this case, old `cme2`
  points young `monly_cme` and it violates gengc assumption.
* cme can have different `defined_class` but `monly_cme` only has
  one `defined_class`. It does not make sense and `monly_cme`
  should be created for a cme (not `def`).

To solve these issues, this patch allocates `monly_cme` per `cme`.
`cme` does not have another room to store a pointer to the `monly_cme`,
so this patch introduces `overloaded_cme_table`, which is weak key map
`[cme] -> [monly_cme]`.

`def::body::iseqptr::monly_cme` is deleted.

The first issue is reported by Alan Wu.
This commit is contained in:
Koichi Sasada 2021-12-21 06:03:51 +09:00
parent 711342d935
commit df48db987d
Notes: git 2021-12-21 11:03:31 +09:00
6 changed files with 166 additions and 36 deletions

View file

@ -725,4 +725,21 @@ class TestISeq < Test::Unit::TestCase
assert_equal at0, Time.public_send(:at, 0, 0)
RUBY
end
def test_mandatory_only_redef
assert_separately ['-W0'], <<~RUBY
r = Ractor.new{
Float(10)
module Kernel
undef Float
def Float(n)
:new
end
end
GC.start
Float(30)
}
assert_equal :new, r.take
RUBY
end
end