summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2023-02-07 15:46:50 -0500
committerAaron Patterson <aaron.patterson@gmail.com>2023-06-01 08:52:48 -0700
commit77d1b082470790c17c24a2f406b4fec5d522636b (patch)
tree828c633fb2a2566dd53628df4e9d63501257e4a5 /internal
parentb7ee51e81dd63990ec27daaa151864214cbf85d2 (diff)
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>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7265
Diffstat (limited to 'internal')
-rw-r--r--internal/class.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/internal/class.h b/internal/class.h
index b33c807e97..d76da84bd1 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -17,6 +17,9 @@
#include "ruby/intern.h" /* for rb_alloc_func_t */
#include "ruby/ruby.h" /* for struct RBasic */
#include "shape.h"
+#include "ruby_assert.h"
+#include "vm_core.h"
+#include "method.h" /* for rb_cref_t */
#ifdef RCLASS_SUPER
# undef RCLASS_SUPER
@@ -32,6 +35,7 @@ typedef struct rb_subclass_entry rb_subclass_entry_t;
struct rb_cvar_class_tbl_entry {
uint32_t index;
rb_serial_t global_cvar_state;
+ const rb_cref_t * cref;
VALUE class_value;
};