diff options
author | John Hawthorn <[email protected]> | 2025-05-23 10:49:21 -0700 |
---|---|---|
committer | John Hawthorn <[email protected]> | 2025-05-29 16:02:07 -0400 |
commit | 6a62a46c3cd8a0fe3623b5363ff21ead1e755169 (patch) | |
tree | de2f13c708a66ac05db368a5a75c60b715d53450 | |
parent | 5b3f1c4c51480cbdbd1ace92b1767f14f9fff280 (diff) |
Read {max_iv,variation}_count from prime classext
MAX_IV_COUNT is a hint which determines the size of variable width
allocation we should use for a given class. We don't need to scope this
by namespace, if we end up with larger builtin objects on some
namespaces that isn't a user-visible problem, just extra memory use.
Similarly variation_count is used to track if a given object has had too
many branches in shapes it has used, and to use too_complex when that
happens. That's also just a hint, so we can use the same value across
namespaces without it being visible to users.
Previously variation_count was being incremented (written to) on the
RCLASS_EXT_READABLE ext, which seems incorrect if we wanted it to be
different across namespaces
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13434
-rw-r--r-- | class.c | 4 | ||||
-rw-r--r-- | gc.c | 10 | ||||
-rw-r--r-- | internal/class.h | 17 | ||||
-rw-r--r-- | iseq.c | 2 | ||||
-rw-r--r-- | vm_insnhelper.c | 2 |
5 files changed, 12 insertions, 23 deletions
@@ -338,9 +338,9 @@ rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_namespace * * refined_class * * as.class.allocator / as.singleton_class.attached_object * * includer + * * max IV count + * * variation count */ - RCLASSEXT_MAX_IV_COUNT(ext) = RCLASSEXT_MAX_IV_COUNT(orig); - RCLASSEXT_VARIATION_COUNT(ext) = RCLASSEXT_VARIATION_COUNT(orig); RCLASSEXT_PERMANENT_CLASSPATH(ext) = RCLASSEXT_PERMANENT_CLASSPATH(orig); RCLASSEXT_CLONED(ext) = RCLASSEXT_CLONED(orig); RCLASSEXT_CLASSPATH(ext) = RCLASSEXT_CLASSPATH(orig); @@ -3263,13 +3263,9 @@ rb_gc_mark_children(void *objspace, VALUE obj) if (fields_count) { VALUE klass = RBASIC_CLASS(obj); - // Skip updating max_iv_count if the prime classext is not writable - // because GC context doesn't provide information about namespaces. - if (RCLASS_PRIME_CLASSEXT_WRITABLE_P(klass)) { - // Increment max_iv_count if applicable, used to determine size pool allocation - if (RCLASS_MAX_IV_COUNT(klass) < fields_count) { - RCLASS_SET_MAX_IV_COUNT(klass, fields_count); - } + // Increment max_iv_count if applicable, used to determine size pool allocation + if (RCLASS_MAX_IV_COUNT(klass) < fields_count) { + RCLASS_SET_MAX_IV_COUNT(klass, fields_count); } } diff --git a/internal/class.h b/internal/class.h index 0e6506d739..ac2e4bb8bb 100644 --- a/internal/class.h +++ b/internal/class.h @@ -190,8 +190,6 @@ static inline rb_classext_t * RCLASS_EXT_WRITABLE(VALUE obj); #define RCLASSEXT_REFINED_CLASS(ext) (ext->refined_class) // class.allocator/singleton_class.attached_object are not accessed directly via RCLASSEXT_* #define RCLASSEXT_INCLUDER(ext) (ext->as.iclass.includer) -#define RCLASSEXT_MAX_IV_COUNT(ext) (ext->max_iv_count) -#define RCLASSEXT_VARIATION_COUNT(ext) (ext->variation_count) #define RCLASSEXT_PERMANENT_CLASSPATH(ext) (ext->permanent_classpath) #define RCLASSEXT_CLONED(ext) (ext->cloned) #define RCLASSEXT_SHARED_CONST_TBL(ext) (ext->shared_const_tbl) @@ -229,8 +227,6 @@ static inline void RCLASSEXT_SET_INCLUDER(rb_classext_t *ext, VALUE klass, VALUE #define RCLASS_SUBCLASSES_FIRST(c) (RCLASS_EXT_READABLE(c)->subclasses->head->next) #define RCLASS_ORIGIN(c) (RCLASS_EXT_READABLE(c)->origin_) #define RICLASS_IS_ORIGIN_P(c) (RCLASS_EXT_READABLE(c)->iclass_is_origin) -#define RCLASS_MAX_IV_COUNT(c) (RCLASS_EXT_READABLE(c)->max_iv_count) -#define RCLASS_VARIATION_COUNT(c) (RCLASS_EXT_READABLE(c)->variation_count) #define RCLASS_PERMANENT_CLASSPATH_P(c) (RCLASS_EXT_READABLE(c)->permanent_classpath) #define RCLASS_CLONED_P(c) (RCLASS_EXT_READABLE(c)->cloned) #define RCLASS_CLASSPATH(c) (RCLASS_EXT_READABLE(c)->classpath) @@ -245,6 +241,10 @@ static inline void RCLASSEXT_SET_INCLUDER(rb_classext_t *ext, VALUE klass, VALUE #define RCLASS_ATTACHED_OBJECT(c) (RCLASS_EXT_PRIME(c)->as.singleton_class.attached_object) #define RCLASS_INCLUDER(c) (RCLASS_EXT_PRIME(c)->as.iclass.includer) +// max IV count and variation count are just hints, so they don't need to be per-namespace +#define RCLASS_MAX_IV_COUNT(ext) (RCLASS_EXT_PRIME(ext)->max_iv_count) +#define RCLASS_VARIATION_COUNT(ext) (RCLASS_EXT_PRIME(ext)->variation_count) + // Writable classext entries (instead of RCLASS_SET_*) because member data will be operated directly #define RCLASS_WRITABLE_M_TBL(c) (RCLASS_EXT_WRITABLE(c)->m_tbl) #define RCLASS_WRITABLE_CONST_TBL(c) (RCLASS_EXT_WRITABLE(c)->const_tbl) @@ -288,7 +288,6 @@ static inline VALUE RCLASS_SET_ATTACHED_OBJECT(VALUE klass, VALUE attached_objec static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass); static inline void RCLASS_SET_MAX_IV_COUNT(VALUE klass, attr_index_t count); -static inline void RCLASS_WRITE_MAX_IV_COUNT(VALUE klass, attr_index_t count); static inline void RCLASS_SET_CLONED(VALUE klass, bool cloned); static inline void RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent); static inline void RCLASS_WRITE_CLASSPATH(VALUE klass, VALUE classpath, bool permanent); @@ -782,13 +781,7 @@ RCLASS_SET_ATTACHED_OBJECT(VALUE klass, VALUE attached_object) static inline void RCLASS_SET_MAX_IV_COUNT(VALUE klass, attr_index_t count) { - RCLASSEXT_MAX_IV_COUNT(RCLASS_EXT_PRIME(klass)) = count; -} - -static inline void -RCLASS_WRITE_MAX_IV_COUNT(VALUE klass, attr_index_t count) -{ - RCLASSEXT_MAX_IV_COUNT(RCLASS_EXT_WRITABLE(klass)) = count; + RCLASS_MAX_IV_COUNT(klass) = count; } static inline void @@ -2918,7 +2918,7 @@ rb_estimate_iv_count(VALUE klass, const rb_iseq_t * initialize_iseq) attr_index_t count = (attr_index_t)rb_id_table_size(iv_names); VALUE superclass = rb_class_superclass(klass); - count += RCLASSEXT_MAX_IV_COUNT(RCLASS_EXT_READABLE(superclass)); + count += RCLASS_MAX_IV_COUNT(superclass); rb_id_table_free(iv_names); diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 519455282b..e638ac1e82 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -5912,7 +5912,7 @@ vm_define_method(const rb_execution_context_t *ec, VALUE obj, ID id, VALUE iseqv rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, visi); // Set max_iv_count on klasses based on number of ivar sets that are in the initialize method if (id == idInitialize && klass != rb_cObject && RB_TYPE_P(klass, T_CLASS) && (rb_get_alloc_func(klass) == rb_class_allocate_instance)) { - RCLASS_WRITE_MAX_IV_COUNT(klass, rb_estimate_iv_count(klass, (const rb_iseq_t *)iseqval)); + RCLASS_SET_MAX_IV_COUNT(klass, rb_estimate_iv_count(klass, (const rb_iseq_t *)iseqval)); } if (!is_singleton && vm_scope_module_func_check(ec)) { |