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
This commit is contained in:
parent
5b3f1c4c51
commit
6a62a46c3c
Notes:
git
2025-05-29 20:02:20 +00:00
4
class.c
4
class.c
@ -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);
|
||||
|
10
gc.c
10
gc.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
2
iseq.c
2
iseq.c
@ -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);
|
||||
|
||||
|
@ -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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user