@@ -2015,49 +2015,39 @@ object_id_to_ref(void *objspace_ptr, VALUE object_id)
2015
2015
static inline void
2016
2016
obj_free_object_id (VALUE obj )
2017
2017
{
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
-
2039
2018
VALUE obj_id = 0 ;
2040
2019
if (RB_UNLIKELY (id2ref_tbl )) {
2041
2020
switch (BUILTIN_TYPE (obj )) {
2042
2021
case T_CLASS :
2043
2022
case T_MODULE :
2044
2023
obj_id = RCLASS (obj )-> object_id ;
2045
2024
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
+ {
2047
2032
shape_id_t shape_id = RBASIC_SHAPE_ID (obj );
2048
2033
if (rb_shape_has_object_id (shape_id )) {
2049
2034
obj_id = object_id_get (obj , shape_id );
2050
2035
}
2051
2036
break ;
2052
2037
}
2038
+ default :
2039
+ // For generic_fields, the T_IMEMO/fields is responsible for freeing the id.
2040
+ return ;
2053
2041
}
2054
2042
2055
2043
if (RB_UNLIKELY (obj_id )) {
2056
2044
RUBY_ASSERT (FIXNUM_P (obj_id ) || RB_TYPE_P (obj_id , T_BIGNUM ));
2057
2045
2058
2046
if (!st_delete (id2ref_tbl , (st_data_t * )& obj_id , NULL )) {
2059
- // If we're currently building the table then it's not a bug
2060
- if (id2ref_tbl_built ) {
2047
+ // If we're currently building the table then it's not a bug.
2048
+ // The the object is a T_IMEMO/fields, then it's possible the actual object
2049
+ // has been garbage collected already.
2050
+ if (id2ref_tbl_built && !RB_TYPE_P (obj , T_IMEMO )) {
2061
2051
rb_bug ("Object ID seen, but not in _id2ref table: object_id=%llu object=%s" , NUM2ULL (obj_id ), rb_obj_info (obj ));
2062
2052
}
2063
2053
}
@@ -2071,7 +2061,7 @@ rb_gc_obj_free_vm_weak_references(VALUE obj)
2071
2061
obj_free_object_id (obj );
2072
2062
2073
2063
if (rb_obj_exivar_p (obj )) {
2074
- rb_free_generic_ivar (( VALUE ) obj );
2064
+ rb_free_generic_ivar (obj );
2075
2065
}
2076
2066
2077
2067
switch (BUILTIN_TYPE (obj )) {
@@ -2316,10 +2306,6 @@ rb_obj_memsize_of(VALUE obj)
2316
2306
return 0 ;
2317
2307
}
2318
2308
2319
- if (rb_obj_exivar_p (obj )) {
2320
- size += rb_generic_ivar_memsize (obj );
2321
- }
2322
-
2323
2309
switch (BUILTIN_TYPE (obj )) {
2324
2310
case T_OBJECT :
2325
2311
if (rb_shape_obj_too_complex_p (obj )) {
@@ -3935,38 +3921,6 @@ vm_weak_table_foreach_update_weak_value(st_data_t *key, st_data_t *value, st_dat
3935
3921
return iter_data -> update_callback ((VALUE * )value , iter_data -> data );
3936
3922
}
3937
3923
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
-
3970
3924
struct st_table * rb_generic_fields_tbl_get (void );
3971
3925
3972
3926
static int
@@ -4003,60 +3957,50 @@ vm_weak_table_gen_fields_foreach(st_data_t key, st_data_t value, st_data_t data)
4003
3957
4004
3958
int ret = iter_data -> callback ((VALUE )key , iter_data -> data );
4005
3959
3960
+ VALUE new_value = (VALUE )value ;
3961
+ VALUE new_key = (VALUE )key ;
3962
+
4006
3963
switch (ret ) {
4007
3964
case ST_CONTINUE :
4008
3965
break ;
4009
3966
4010
3967
case ST_DELETE :
4011
- free_gen_fields_tbl ((VALUE )key , (struct gen_fields_tbl * )value );
4012
3968
RBASIC_SET_SHAPE_ID ((VALUE )key , ROOT_SHAPE_ID );
4013
3969
return ST_DELETE ;
4014
3970
4015
3971
case ST_REPLACE : {
4016
- VALUE new_key = (VALUE )key ;
4017
3972
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 );
3973
+ if (key != new_key ) {
3974
+ ret = ST_DELETE ;
4022
3975
}
4023
- DURING_GC_COULD_MALLOC_REGION_END ();
4024
- key = (st_data_t )new_key ;
4025
3976
break ;
4026
3977
}
4027
3978
4028
3979
default :
4029
- return ret ;
3980
+ rb_bug ( "vm_weak_table_gen_fields_foreach: return value %d not supported" , ret ) ;
4030
3981
}
4031
3982
4032
3983
if (!iter_data -> weak_only ) {
4033
- struct gen_fields_tbl * fields_tbl = (struct gen_fields_tbl * )value ;
3984
+ int ivar_ret = iter_data -> callback (new_value , iter_data -> data );
3985
+ switch (ivar_ret ) {
3986
+ case ST_CONTINUE :
3987
+ break ;
4034
3988
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
- );
3989
+ case ST_REPLACE :
3990
+ iter_data -> update_callback (& new_value , iter_data -> data );
3991
+ break ;
3992
+
3993
+ default :
3994
+ rb_bug ("vm_weak_table_gen_fields_foreach: return value %d not supported" , ivar_ret );
4042
3995
}
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 ;
3996
+ }
4047
3997
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
- }
3998
+ if (key != new_key || value != new_value ) {
3999
+ DURING_GC_COULD_MALLOC_REGION_START ();
4000
+ {
4001
+ st_insert (rb_generic_fields_tbl_get (), (st_data_t )new_key , new_value );
4059
4002
}
4003
+ DURING_GC_COULD_MALLOC_REGION_END ();
4060
4004
}
4061
4005
4062
4006
return ret ;
0 commit comments