@@ -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 )) {
@@ -3935,38 +3919,6 @@ vm_weak_table_foreach_update_weak_value(st_data_t *key, st_data_t *value, st_dat
39353919 return iter_data -> update_callback ((VALUE * )value , iter_data -> data );
39363920}
39373921
3938- static void
3939- free_gen_fields_tbl (VALUE obj , struct gen_fields_tbl * fields_tbl )
3940- {
3941- if (UNLIKELY (rb_shape_obj_too_complex_p (obj ))) {
3942- st_free_table (fields_tbl -> as .complex .table );
3943- }
3944-
3945- xfree (fields_tbl );
3946- }
3947-
3948- static int
3949- vm_weak_table_gen_fields_foreach_too_complex_i (st_data_t _key , st_data_t value , st_data_t data , int error )
3950- {
3951- struct global_vm_table_foreach_data * iter_data = (struct global_vm_table_foreach_data * )data ;
3952-
3953- GC_ASSERT (!iter_data -> weak_only );
3954-
3955- if (SPECIAL_CONST_P ((VALUE )value )) return ST_CONTINUE ;
3956-
3957- return iter_data -> callback ((VALUE )value , iter_data -> data );
3958- }
3959-
3960- static int
3961- vm_weak_table_gen_fields_foreach_too_complex_replace_i (st_data_t * _key , st_data_t * value , st_data_t data , int existing )
3962- {
3963- struct global_vm_table_foreach_data * iter_data = (struct global_vm_table_foreach_data * )data ;
3964-
3965- GC_ASSERT (!iter_data -> weak_only );
3966-
3967- return iter_data -> update_callback ((VALUE * )value , iter_data -> data );
3968- }
3969-
39703922struct st_table * rb_generic_fields_tbl_get (void );
39713923
39723924static int
@@ -4003,60 +3955,50 @@ vm_weak_table_gen_fields_foreach(st_data_t key, st_data_t value, st_data_t data)
40033955
40043956 int ret = iter_data -> callback ((VALUE )key , iter_data -> data );
40053957
3958+ VALUE new_value = (VALUE )value ;
3959+ VALUE new_key = (VALUE )key ;
3960+
40063961 switch (ret ) {
40073962 case ST_CONTINUE :
40083963 break ;
40093964
40103965 case ST_DELETE :
4011- free_gen_fields_tbl ((VALUE )key , (struct gen_fields_tbl * )value );
40123966 RBASIC_SET_SHAPE_ID ((VALUE )key , ROOT_SHAPE_ID );
40133967 return ST_DELETE ;
40143968
40153969 case ST_REPLACE : {
4016- VALUE new_key = (VALUE )key ;
40173970 ret = iter_data -> update_callback (& new_key , iter_data -> data );
4018- if (key != new_key ) ret = ST_DELETE ;
4019- DURING_GC_COULD_MALLOC_REGION_START ();
4020- {
4021- st_insert (rb_generic_fields_tbl_get (), (st_data_t )new_key , value );
3971+ if (key != new_key ) {
3972+ ret = ST_DELETE ;
40223973 }
4023- DURING_GC_COULD_MALLOC_REGION_END ();
4024- key = (st_data_t )new_key ;
40253974 break ;
40263975 }
40273976
40283977 default :
4029- return ret ;
3978+ rb_bug ( "vm_weak_table_gen_fields_foreach: return value %d not supported" , ret ) ;
40303979 }
40313980
40323981 if (!iter_data -> weak_only ) {
4033- struct gen_fields_tbl * fields_tbl = (struct gen_fields_tbl * )value ;
3982+ int ivar_ret = iter_data -> callback (new_value , iter_data -> data );
3983+ switch (ivar_ret ) {
3984+ case ST_CONTINUE :
3985+ break ;
40343986
4035- if (rb_shape_obj_too_complex_p ((VALUE )key )) {
4036- st_foreach_with_replace (
4037- fields_tbl -> as .complex .table ,
4038- vm_weak_table_gen_fields_foreach_too_complex_i ,
4039- vm_weak_table_gen_fields_foreach_too_complex_replace_i ,
4040- data
4041- );
3987+ case ST_REPLACE :
3988+ iter_data -> update_callback (& new_value , iter_data -> data );
3989+ break ;
3990+
3991+ default :
3992+ rb_bug ("vm_weak_table_gen_fields_foreach: return value %d not supported" , ivar_ret );
40423993 }
4043- else {
4044- uint32_t fields_count = RSHAPE_LEN (RBASIC_SHAPE_ID ((VALUE )key ));
4045- for (uint32_t i = 0 ; i < fields_count ; i ++ ) {
4046- if (SPECIAL_CONST_P (fields_tbl -> as .shape .fields [i ])) continue ;
3994+ }
40473995
4048- int ivar_ret = iter_data -> callback (fields_tbl -> as .shape .fields [i ], iter_data -> data );
4049- switch (ivar_ret ) {
4050- case ST_CONTINUE :
4051- break ;
4052- case ST_REPLACE :
4053- iter_data -> update_callback (& fields_tbl -> as .shape .fields [i ], iter_data -> data );
4054- break ;
4055- default :
4056- rb_bug ("vm_weak_table_gen_fields_foreach: return value %d not supported" , ivar_ret );
4057- }
4058- }
3996+ if (key != new_key || value != new_value ) {
3997+ DURING_GC_COULD_MALLOC_REGION_START ();
3998+ {
3999+ st_insert (rb_generic_fields_tbl_get (), (st_data_t )new_key , new_value );
40594000 }
4001+ DURING_GC_COULD_MALLOC_REGION_END ();
40604002 }
40614003
40624004 return ret ;
0 commit comments