diff options
author | Eileen M. Uchitelle <eileencodes@users.noreply.github.com> | 2023-07-25 07:05:27 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-25 11:05:27 +0000 |
commit | cba152ff1f69fad98f4c67747dcf763407cd1883 (patch) | |
tree | b7a784de2e842a2bfc589b6d4d0909960734aa45 /variable.c | |
parent | 7e926c4d8c2e785d174161b38a8a688b19ea4b99 (diff) |
Backport cvar clone bug fix for 19379 to 3.1 (#7889)
* Copy cvar table on clone
When a class with a class variable is cloned we need to also copy the
cvar cache table from the original table to the clone. I found this bug
while working on fixing [Bug #19379]. While this does not fix that bug
directly it is still a required change to fix another bug revealed by
the fix in https://github.com/ruby/ruby/pull/7265
This needs to be backported to 3.2.x and 3.1.x.
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Fix cvar caching when class is cloned
The class variable cache that was added in
https://github.com/ruby/ruby/pull/4544 changed the behavior of class
variables on cloned classes. As reported when a class is cloned AND a
class variable was set, and the class variable was read from the
original class, reading a class variable from the cloned class would
return the value from the original class.
This was happening because the IC (inline cache) is stored on the ISEQ
which is shared between the original and cloned class, therefore they
share the cache too.
To fix this we are now storing the `cref` in the cache so that we can
check if it's equal to the current `cref`. If it's different we don't
want to read from the cache. If it's the same we do. Cloned classes
don't share the same cref with their original class.
This will need to be backported to 3.1 in addition to 3.2 since the bug
exists in both versions.
We also added a marking function which was missing.
Fixes [Bug #19379]
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Add missing write barrier
We were missing the write barrier for class_value to cref. This should
fix the segv we were seeing in http://ci.rvm.jp/logfiles/brlog.trunk-gc-asserts.20230601-165052
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
---------
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
Diffstat (limited to 'variable.c')
-rw-r--r-- | variable.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/variable.c b/variable.c index eaad6eb497..74d5b699b8 100644 --- a/variable.c +++ b/variable.c @@ -3517,6 +3517,7 @@ rb_cvar_set(VALUE klass, ID id, VALUE val) ent = ALLOC(struct rb_cvar_class_tbl_entry); ent->class_value = target; ent->global_cvar_state = GET_GLOBAL_CVAR_STATE(); + ent->cref = 0; rb_id_table_insert(rb_cvc_tbl, id, (VALUE)ent); RB_DEBUG_COUNTER_INC(cvar_inline_miss); } |