From e7fb87ee3a826a387e5bfb9edea059f1aa065462 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 27 Aug 2025 18:13:16 +0200 Subject: Populate ivar caches for types other than T_OBJECT `vm_setinstancevariable` had a codepath to try to match the inline cache for types other than T_OBJECT, but the cache population path in `vm_setivar_slowpath` was exclusive to T_OBJECT, so `vm_setivar_default` would never match anything. This commit improves `vm_setivar_slowpath` so that it is capable of filling the cache for all types, and adds a `vm_setivar_class` codepath for `T_CLASS` and `T_MODULE`. `vm_setivar`, `vm_setivar_default` and `vm_setivar_class` could be unified, but based on the very explicit `NOINLINE` I assume they were split to minimize codesize. ``` compare-ruby: ruby 3.5.0dev (2025-08-27T14:58:58Z merge-vm-setivar-d.. 5b749d8e53) +PRISM [arm64-darwin24] built-ruby: ruby 3.5.0dev (2025-08-27T16:30:31Z setivar-cache-gene.. 4fe78ff296) +PRISM [arm64-darwin24] | |compare-ruby|built-ruby| |:------------------------|-----------:|---------:| |vm_ivar_set_on_instance | 161.809| 164.688| | | -| 1.02x| |vm_ivar_set_on_generic | 58.769| 115.638| | | -| 1.97x| |vm_ivar_set_on_class | 70.034| 141.042| | | -| 2.01x| ``` --- internal/variable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'internal') diff --git a/internal/variable.h b/internal/variable.h index bad63981a1..2cb50f66ae 100644 --- a/internal/variable.h +++ b/internal/variable.h @@ -51,7 +51,8 @@ void rb_obj_init_too_complex(VALUE obj, st_table *table); void rb_evict_ivars_to_hash(VALUE obj); VALUE rb_obj_field_get(VALUE obj, shape_id_t target_shape_id); void rb_ivar_set_internal(VALUE obj, ID id, VALUE val); -void rb_obj_field_set(VALUE obj, shape_id_t target_shape_id, ID field_name, VALUE val); +attr_index_t rb_ivar_set_index(VALUE obj, ID id, VALUE val); +attr_index_t rb_obj_field_set(VALUE obj, shape_id_t target_shape_id, ID field_name, VALUE val); RUBY_SYMBOL_EXPORT_BEGIN /* variable.c (export) */ @@ -67,6 +68,5 @@ VALUE rb_gvar_set(ID, VALUE); VALUE rb_gvar_defined(ID); void rb_const_warn_if_deprecated(const rb_const_entry_t *, VALUE, ID); void rb_ensure_iv_list_size(VALUE obj, uint32_t current_len, uint32_t newsize); -attr_index_t rb_obj_ivar_set(VALUE obj, ID id, VALUE val); #endif /* INTERNAL_VARIABLE_H */ -- cgit v1.2.3