@@ -1212,59 +1212,53 @@ rb_generic_fields_tbl_get(void)
12121212 return generic_fields_tbl_ ;
12131213}
12141214
1215- static inline VALUE
1216- generic_fields_lookup (VALUE obj , ID id , bool force_check_ractor )
1215+ VALUE
1216+ rb_obj_fields (VALUE obj , ID id )
12171217{
1218- VALUE fields_obj = Qfalse ;
1219- RB_VM_LOCKING () {
1220- st_table * generic_tbl = generic_fields_tbl (obj , id , false);
1221- st_lookup (generic_tbl , obj , (st_data_t * )& fields_obj );
1218+ VALUE fields_obj = 0 ;
1219+ if (rb_obj_exivar_p (obj )) {
1220+ RB_VM_LOCKING () {
1221+ st_table * tbl = generic_fields_tbl (obj , id , false);
1222+ if (!st_lookup (tbl , (st_data_t )obj , (st_data_t * )& fields_obj )) {
1223+ rb_bug ("Object is missing entry in generic_fields_tbl" );
1224+ }
1225+ }
12221226 }
12231227 return fields_obj ;
12241228}
12251229
1226- static inline void
1227- generic_fields_insert (VALUE obj , VALUE fields_obj )
1230+ VALUE
1231+ rb_obj_fields_no_ractor_check (VALUE obj )
12281232{
1229- RUBY_ASSERT (IMEMO_TYPE_P (fields_obj , imemo_fields ));
1230-
1231- RB_VM_LOCKING () {
1232- st_table * generic_tbl = generic_fields_tbl_no_ractor_check (obj );
1233- st_insert (generic_tbl , obj , fields_obj );
1234- }
1235- RB_OBJ_WRITTEN (obj , Qundef , fields_obj );
1233+ return rb_obj_fields (obj , 0 );
12361234}
12371235
1238- int
1239- rb_gen_fields_tbl_get (VALUE obj , ID id , VALUE * fields_obj )
1236+ void
1237+ rb_obj_set_fields (VALUE obj , VALUE fields_obj , ID field_name , VALUE original_fields_obj )
12401238{
1241- RUBY_ASSERT (!RB_TYPE_P (obj , T_ICLASS ));
1242-
1243- st_data_t data ;
1244- int r = 0 ;
1239+ RUBY_ASSERT (IMEMO_TYPE_P (fields_obj , imemo_fields ));
12451240
1246- RB_VM_LOCKING ( ) {
1247- if ( st_lookup ( generic_fields_tbl ( obj , id , false), ( st_data_t ) obj , & data ) ) {
1248- * fields_obj = ( VALUE ) data ;
1249- r = 1 ;
1241+ if ( fields_obj != original_fields_obj ) {
1242+ RB_VM_LOCKING ( ) {
1243+ st_table * tbl = generic_fields_tbl ( obj , field_name , false) ;
1244+ st_insert ( tbl , ( st_data_t ) obj , ( st_data_t ) fields_obj ) ;
12501245 }
1251- }
12521246
1253- return r ;
1254- }
1247+ RB_OBJ_WRITTEN (obj , original_fields_obj , fields_obj );
12551248
1256- int
1257- rb_ivar_generic_fields_tbl_lookup (VALUE obj , VALUE * fields_obj )
1258- {
1259- return rb_gen_fields_tbl_get (obj , 0 , fields_obj );
1249+ if (original_fields_obj ) {
1250+ // Clear root shape to avoid triggering cleanup such as free_object_id.
1251+ rb_imemo_fields_clear (original_fields_obj );
1252+ }
1253+ }
12601254}
12611255
12621256void
1263- rb_mark_generic_ivar (VALUE obj )
1257+ rb_obj_replace_fields (VALUE obj , VALUE fields_obj , ID field_name )
12641258{
1265- VALUE data ;
1266- if ( st_lookup ( generic_fields_tbl_no_ractor_check ( obj ), ( st_data_t ) obj , ( st_data_t * ) & data )) {
1267- rb_gc_mark_movable ( data );
1259+ RB_VM_LOCKING () {
1260+ VALUE original_fields_obj = rb_obj_fields ( fields_obj , field_name );
1261+ rb_obj_set_fields ( obj , fields_obj , field_name , original_fields_obj );
12681262 }
12691263}
12701264
@@ -1311,8 +1305,7 @@ rb_obj_field_get(VALUE obj, shape_id_t target_shape_id)
13111305 break ;
13121306 default :
13131307 RUBY_ASSERT (rb_obj_exivar_p (obj ));
1314- VALUE fields_obj = 0 ;
1315- rb_ivar_generic_fields_tbl_lookup (obj , & fields_obj );
1308+ VALUE fields_obj = rb_obj_fields (obj , RSHAPE_EDGE_NAME (target_shape_id ));
13161309 RUBY_ASSERT (fields_obj );
13171310 fields_hash = rb_imemo_fields_complex_tbl (fields_obj );
13181311 break ;
@@ -1346,8 +1339,7 @@ rb_obj_field_get(VALUE obj, shape_id_t target_shape_id)
13461339 break ;
13471340 default :
13481341 RUBY_ASSERT (rb_obj_exivar_p (obj ));
1349- VALUE fields_obj = 0 ;
1350- rb_ivar_generic_fields_tbl_lookup (obj , & fields_obj );
1342+ VALUE fields_obj = rb_obj_fields (obj , RSHAPE_EDGE_NAME (target_shape_id ));
13511343 RUBY_ASSERT (fields_obj );
13521344 fields = rb_imemo_fields_ptr (fields_obj );
13531345 break ;
@@ -1424,8 +1416,7 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
14241416 default :
14251417 shape_id = RBASIC_SHAPE_ID (obj );
14261418 if (rb_obj_exivar_p (obj )) {
1427- VALUE fields_obj = 0 ;
1428- rb_gen_fields_tbl_get (obj , id , & fields_obj );
1419+ VALUE fields_obj = rb_obj_fields (obj , id );
14291420
14301421 RUBY_ASSERT (fields_obj );
14311422
@@ -1524,8 +1515,7 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef)
15241515 fields = ROBJECT_FIELDS (obj );
15251516 break ;
15261517 default : {
1527- VALUE fields_obj ;
1528- rb_gen_fields_tbl_get (obj , id , & fields_obj );
1518+ VALUE fields_obj = rb_obj_fields (obj , id );
15291519 fields = rb_imemo_fields_ptr (fields_obj );
15301520 break ;
15311521 }
@@ -1579,10 +1569,8 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef)
15791569 break ;
15801570
15811571 default : {
1582- VALUE fields_obj ;
1583- if (rb_gen_fields_tbl_get (obj , 0 , & fields_obj )) {
1584- table = rb_imemo_fields_complex_tbl (fields_obj );
1585- }
1572+ VALUE fields_obj = rb_obj_fields_no_ractor_check (obj );
1573+ table = rb_imemo_fields_complex_tbl (fields_obj );
15861574 break ;
15871575 }
15881576 }
@@ -1603,8 +1591,6 @@ rb_attr_delete(VALUE obj, ID id)
16031591 return rb_ivar_delete (obj , id , Qnil );
16041592}
16051593
1606- static inline void generic_update_fields_obj (VALUE obj , VALUE fields_obj , const VALUE original_fields_obj );
1607-
16081594static shape_id_t
16091595obj_transition_too_complex (VALUE obj , st_table * table )
16101596{
@@ -1639,8 +1625,8 @@ obj_transition_too_complex(VALUE obj, st_table *table)
16391625 RBASIC_SET_SHAPE_ID (fields_obj , shape_id );
16401626
16411627 RB_VM_LOCKING () {
1642- const VALUE original_fields_obj = generic_fields_lookup (obj , 0 , false );
1643- generic_update_fields_obj (obj , fields_obj , original_fields_obj );
1628+ const VALUE original_fields_obj = rb_obj_fields_no_ractor_check (obj );
1629+ rb_obj_set_fields (obj , fields_obj , 0 , original_fields_obj );
16441630 }
16451631 RBASIC_SET_SHAPE_ID (obj , shape_id );
16461632 }
@@ -1839,19 +1825,6 @@ general_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val, void *data,
18391825 }
18401826}
18411827
1842- static inline void
1843- generic_update_fields_obj (VALUE obj , VALUE fields_obj , const VALUE original_fields_obj )
1844- {
1845- if (fields_obj != original_fields_obj ) {
1846- if (original_fields_obj ) {
1847- // Clear root shape to avoid triggering cleanup such as free_object_id.
1848- rb_imemo_fields_clear (original_fields_obj );
1849- }
1850-
1851- generic_fields_insert (obj , fields_obj );
1852- }
1853- }
1854-
18551828static VALUE
18561829imemo_fields_set (VALUE klass , VALUE fields_obj , shape_id_t target_shape_id , ID field_name , VALUE val , bool concurrent )
18571830{
@@ -1904,10 +1877,10 @@ generic_field_set(VALUE obj, shape_id_t target_shape_id, ID field_name, VALUE va
19041877 RUBY_ASSERT (field_name );
19051878 }
19061879
1907- const VALUE original_fields_obj = generic_fields_lookup (obj , field_name , false );
1880+ const VALUE original_fields_obj = rb_obj_fields (obj , field_name );
19081881 VALUE fields_obj = imemo_fields_set (rb_obj_class (obj ), original_fields_obj , target_shape_id , field_name , val , false);
19091882
1910- generic_update_fields_obj (obj , fields_obj , original_fields_obj );
1883+ rb_obj_set_fields (obj , fields_obj , field_name , original_fields_obj );
19111884
19121885 if (RBASIC_SHAPE_ID (fields_obj ) == target_shape_id ) {
19131886 RBASIC_SET_SHAPE_ID (obj , target_shape_id );
@@ -2162,10 +2135,8 @@ ivar_defined0(VALUE obj, ID id)
21622135 break ;
21632136
21642137 default : {
2165- VALUE fields_obj ;
2166- if (rb_gen_fields_tbl_get (obj , 0 , & fields_obj )) {
2167- table = rb_imemo_fields_complex_tbl (fields_obj );
2168- }
2138+ VALUE fields_obj = rb_obj_fields_no_ractor_check (obj );
2139+ table = rb_imemo_fields_complex_tbl (fields_obj );
21692140 }
21702141 }
21712142
@@ -2306,7 +2277,6 @@ imemo_fields_each(VALUE fields_obj, rb_ivar_foreach_callback_func *func, st_data
23062277void
23072278rb_copy_generic_ivar (VALUE dest , VALUE obj )
23082279{
2309- VALUE fields_obj ;
23102280 VALUE new_fields_obj ;
23112281
23122282 rb_check_frozen (dest );
@@ -2317,7 +2287,8 @@ rb_copy_generic_ivar(VALUE dest, VALUE obj)
23172287
23182288 shape_id_t src_shape_id = rb_obj_shape_id (obj );
23192289
2320- if (rb_gen_fields_tbl_get (obj , 0 , & fields_obj )) {
2290+ VALUE fields_obj = rb_obj_fields_no_ractor_check (obj );
2291+ if (fields_obj ) {
23212292 unsigned long src_num_ivs = rb_ivar_count (fields_obj );
23222293 if (!src_num_ivs ) {
23232294 goto clear ;
@@ -2354,12 +2325,7 @@ rb_copy_generic_ivar(VALUE dest, VALUE obj)
23542325 rb_shape_copy_fields (new_fields_obj , dest_buf , dest_shape_id , src_buf , src_shape_id );
23552326 RBASIC_SET_SHAPE_ID (new_fields_obj , dest_shape_id );
23562327
2357- RB_VM_LOCKING () {
2358- generic_fields_tbl_no_ractor_check (dest );
2359- st_insert (generic_fields_tbl_no_ractor_check (obj ), (st_data_t )dest , (st_data_t )new_fields_obj );
2360- RB_OBJ_WRITTEN (dest , Qundef , new_fields_obj );
2361- }
2362-
2328+ rb_obj_replace_fields (obj , 0 , new_fields_obj );
23632329 RBASIC_SET_SHAPE_ID (dest , dest_shape_id );
23642330 }
23652331 return ;
@@ -2408,8 +2374,8 @@ rb_field_foreach(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg,
24082374 break ;
24092375 default :
24102376 if (rb_obj_exivar_p (obj )) {
2411- VALUE fields_obj = 0 ;
2412- if (!rb_gen_fields_tbl_get ( obj , 0 , & fields_obj ) ) return ;
2377+ VALUE fields_obj = rb_obj_fields_no_ractor_check ( obj ) ;
2378+ if (!fields_obj ) return ;
24132379
24142380 imemo_fields_each (fields_obj , func , arg , ivar_only );
24152381 }
@@ -2465,9 +2431,8 @@ rb_ivar_count(VALUE obj)
24652431 if (rb_obj_exivar_p (obj )) {
24662432
24672433 if (rb_shape_obj_too_complex_p (obj )) {
2468- VALUE fields_obj ;
2469-
2470- if (rb_gen_fields_tbl_get (obj , 0 , & fields_obj )) {
2434+ VALUE fields_obj = rb_obj_fields_no_ractor_check (obj );
2435+ if (fields_obj ) {
24712436 iv_count = rb_st_table_size (rb_imemo_fields_complex_tbl (fields_obj ));
24722437 }
24732438 }
0 commit comments