@@ -2015,41 +2015,29 @@ object_id_to_ref(void *objspace_ptr, VALUE object_id)
20152015static inline void
20162016obj_free_object_id (VALUE obj )
20172017{
2018- if (RB_BUILTIN_TYPE (obj ) == T_IMEMO ) {
2019- return ;
2020- }
2021-
2022- #if RUBY_DEBUG
2023- switch (BUILTIN_TYPE (obj )) {
2024- case T_CLASS :
2025- case T_MODULE :
2026- break ;
2027- default :
2028- if (rb_shape_obj_has_id (obj )) {
2029- VALUE id = object_id_get (obj , RBASIC_SHAPE_ID (obj )); // Crash if missing
2030- if (!(FIXNUM_P (id ) || RB_TYPE_P (id , T_BIGNUM ))) {
2031- rb_p (obj );
2032- rb_bug ("Corrupted object_id" );
2033- }
2034- }
2035- break ;
2036- }
2037- #endif
2038-
20392018 VALUE obj_id = 0 ;
20402019 if (RB_UNLIKELY (id2ref_tbl )) {
20412020 switch (BUILTIN_TYPE (obj )) {
20422021 case T_CLASS :
20432022 case T_MODULE :
20442023 obj_id = RCLASS (obj )-> object_id ;
20452024 break ;
2046- default : {
2025+ case T_IMEMO :
2026+ if (!IMEMO_TYPE_P (obj , imemo_fields )) {
2027+ return ;
2028+ }
2029+ // fallthrough
2030+ case T_OBJECT :
2031+ {
20472032 shape_id_t shape_id = RBASIC_SHAPE_ID (obj );
20482033 if (rb_shape_has_object_id (shape_id )) {
20492034 obj_id = object_id_get (obj , shape_id );
20502035 }
20512036 break ;
20522037 }
2038+ default :
2039+ // For generic_fields, the T_IMEMO/fields is responsible for freeing the id.
2040+ return ;
20532041 }
20542042
20552043 if (RB_UNLIKELY (obj_id )) {
@@ -2316,10 +2304,6 @@ rb_obj_memsize_of(VALUE obj)
23162304 return 0 ;
23172305 }
23182306
2319- if (rb_obj_exivar_p (obj )) {
2320- size += rb_generic_ivar_memsize (obj );
2321- }
2322-
23232307 switch (BUILTIN_TYPE (obj )) {
23242308 case T_OBJECT :
23252309 if (rb_shape_obj_too_complex_p (obj )) {
@@ -3936,38 +3920,6 @@ vm_weak_table_foreach_update_weak_value(st_data_t *key, st_data_t *value, st_dat
39363920 return iter_data -> update_callback ((VALUE * )value , iter_data -> data );
39373921}
39383922
3939- static void
3940- free_gen_fields_tbl (VALUE obj , struct gen_fields_tbl * fields_tbl )
3941- {
3942- if (UNLIKELY (rb_shape_obj_too_complex_p (obj ))) {
3943- st_free_table (fields_tbl -> as .complex .table );
3944- }
3945-
3946- xfree (fields_tbl );
3947- }
3948-
3949- static int
3950- vm_weak_table_gen_fields_foreach_too_complex_i (st_data_t _key , st_data_t value , st_data_t data , int error )
3951- {
3952- struct global_vm_table_foreach_data * iter_data = (struct global_vm_table_foreach_data * )data ;
3953-
3954- GC_ASSERT (!iter_data -> weak_only );
3955-
3956- if (SPECIAL_CONST_P ((VALUE )value )) return ST_CONTINUE ;
3957-
3958- return iter_data -> callback ((VALUE )value , iter_data -> data );
3959- }
3960-
3961- static int
3962- vm_weak_table_gen_fields_foreach_too_complex_replace_i (st_data_t * _key , st_data_t * value , st_data_t data , int existing )
3963- {
3964- struct global_vm_table_foreach_data * iter_data = (struct global_vm_table_foreach_data * )data ;
3965-
3966- GC_ASSERT (!iter_data -> weak_only );
3967-
3968- return iter_data -> update_callback ((VALUE * )value , iter_data -> data );
3969- }
3970-
39713923struct st_table * rb_generic_fields_tbl_get (void );
39723924
39733925static int
@@ -4004,60 +3956,50 @@ vm_weak_table_gen_fields_foreach(st_data_t key, st_data_t value, st_data_t data)
40043956
40053957 int ret = iter_data -> callback ((VALUE )key , iter_data -> data );
40063958
3959+ VALUE new_value = (VALUE )value ;
3960+ VALUE new_key = (VALUE )key ;
3961+
40073962 switch (ret ) {
40083963 case ST_CONTINUE :
40093964 break ;
40103965
40113966 case ST_DELETE :
4012- free_gen_fields_tbl ((VALUE )key , (struct gen_fields_tbl * )value );
40133967 RBASIC_SET_SHAPE_ID ((VALUE )key , ROOT_SHAPE_ID );
40143968 return ST_DELETE ;
40153969
40163970 case ST_REPLACE : {
4017- VALUE new_key = (VALUE )key ;
40183971 ret = iter_data -> update_callback (& new_key , iter_data -> data );
4019- if (key != new_key ) ret = ST_DELETE ;
4020- DURING_GC_COULD_MALLOC_REGION_START ();
4021- {
4022- st_insert (rb_generic_fields_tbl_get (), (st_data_t )new_key , value );
3972+ if (key != new_key ) {
3973+ ret = ST_DELETE ;
40233974 }
4024- DURING_GC_COULD_MALLOC_REGION_END ();
4025- key = (st_data_t )new_key ;
40263975 break ;
40273976 }
40283977
40293978 default :
4030- return ret ;
3979+ rb_bug ( "vm_weak_table_gen_fields_foreach: return value %d not supported" , ret ) ;
40313980 }
40323981
40333982 if (!iter_data -> weak_only ) {
4034- struct gen_fields_tbl * fields_tbl = (struct gen_fields_tbl * )value ;
3983+ int ivar_ret = iter_data -> callback (new_value , iter_data -> data );
3984+ switch (ivar_ret ) {
3985+ case ST_CONTINUE :
3986+ break ;
40353987
4036- if (rb_shape_obj_too_complex_p ((VALUE )key )) {
4037- st_foreach_with_replace (
4038- fields_tbl -> as .complex .table ,
4039- vm_weak_table_gen_fields_foreach_too_complex_i ,
4040- vm_weak_table_gen_fields_foreach_too_complex_replace_i ,
4041- data
4042- );
3988+ case ST_REPLACE :
3989+ iter_data -> update_callback (& new_value , iter_data -> data );
3990+ break ;
3991+
3992+ default :
3993+ rb_bug ("vm_weak_table_gen_fields_foreach: return value %d not supported" , ivar_ret );
40433994 }
4044- else {
4045- uint32_t fields_count = RSHAPE_LEN (RBASIC_SHAPE_ID ((VALUE )key ));
4046- for (uint32_t i = 0 ; i < fields_count ; i ++ ) {
4047- if (SPECIAL_CONST_P (fields_tbl -> as .shape .fields [i ])) continue ;
3995+ }
40483996
4049- int ivar_ret = iter_data -> callback (fields_tbl -> as .shape .fields [i ], iter_data -> data );
4050- switch (ivar_ret ) {
4051- case ST_CONTINUE :
4052- break ;
4053- case ST_REPLACE :
4054- iter_data -> update_callback (& fields_tbl -> as .shape .fields [i ], iter_data -> data );
4055- break ;
4056- default :
4057- rb_bug ("vm_weak_table_gen_fields_foreach: return value %d not supported" , ivar_ret );
4058- }
4059- }
3997+ if (key != new_key || value != new_value ) {
3998+ DURING_GC_COULD_MALLOC_REGION_START ();
3999+ {
4000+ st_insert (rb_generic_fields_tbl_get (), (st_data_t )new_key , new_value );
40604001 }
4002+ DURING_GC_COULD_MALLOC_REGION_END ();
40614003 }
40624004
40634005 return ret ;
0 commit comments