summaryrefslogtreecommitdiff
path: root/class.c
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2023-06-02 14:25:19 -0400
committerAaron Patterson <aaron.patterson@gmail.com>2023-06-05 11:11:12 -0700
commit40f090f4339820d19da8ecdf81a981489c22eb57 (patch)
treeee8f90b5d49c2bb6cc44f135e3638fcd9599722e /class.c
parent29ea3c5aaa9513fcd497781e7051c0f436725eb3 (diff)
Revert "Revert "Fix cvar caching when class is cloned""
This reverts commit 10621f7cb9a0c70e568f89cce47a02e878af6778. This was reverted because the gc integrity build started failing. We have figured out a fix so I'm reopening the PR. Original commit message: Fix cvar caching when class is cloned The class variable cache that was added in ruby#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>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7900
Diffstat (limited to 'class.c')
-rw-r--r--class.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/class.c b/class.c
index 114df2bbd7..4ffb47c27a 100644
--- a/class.c
+++ b/class.c
@@ -446,9 +446,12 @@ cvc_table_copy(ID id, VALUE val, void *data)
ent = ALLOC(struct rb_cvar_class_tbl_entry);
ent->class_value = ctx->clone;
+ ent->cref = orig_entry->cref;
ent->global_cvar_state = orig_entry->global_cvar_state;
rb_id_table_insert(ctx->new_table, id, (VALUE)ent);
+ RB_OBJ_WRITTEN(ctx->clone, Qundef, ent->cref);
+
return ID_TABLE_CONTINUE;
}