Skip to content

Commit 77ae876

Browse files
byrootetiennebarrie
andcommitted
variable.c: refactor accesses to the generic_fields_tbl
It's now mostly all encapsulated inside: - rb_obj_fields - rb_obj_set_fields - rb_obj_replace_fields Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
1 parent d5e7e88 commit 77ae876

6 files changed

Lines changed: 58 additions & 98 deletions

File tree

gc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3087,7 +3087,7 @@ rb_gc_mark_children(void *objspace, VALUE obj)
30873087
struct gc_mark_classext_foreach_arg foreach_args;
30883088

30893089
if (rb_obj_exivar_p(obj)) {
3090-
rb_mark_generic_ivar(obj);
3090+
rb_gc_mark_movable(rb_obj_fields_no_ractor_check(obj));
30913091
}
30923092

30933093
switch (BUILTIN_TYPE(obj)) {

internal/variable.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ void rb_gvar_namespace_ready(const char *name);
4646
*/
4747
VALUE rb_mod_set_temporary_name(VALUE, VALUE);
4848

49-
int rb_gen_fields_tbl_get(VALUE obj, ID id, VALUE *fields_obj);
5049
void rb_obj_copy_ivs_to_hash_table(VALUE obj, st_table *table);
5150
void rb_obj_init_too_complex(VALUE obj, st_table *table);
5251
void rb_evict_ivars_to_hash(VALUE obj);
@@ -57,7 +56,6 @@ void rb_obj_field_set(VALUE obj, shape_id_t target_shape_id, ID field_name, VALU
5756

5857
RUBY_SYMBOL_EXPORT_BEGIN
5958
/* variable.c (export) */
60-
void rb_mark_generic_ivar(VALUE obj);
6159
VALUE rb_const_missing(VALUE klass, VALUE name);
6260
bool rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
6361
void rb_fields_tbl_copy(VALUE dst, VALUE src);

ractor.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,8 +1679,7 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
16791679
} while (0)
16801680

16811681
if (UNLIKELY(rb_obj_exivar_p(obj))) {
1682-
VALUE fields_obj;
1683-
rb_ivar_generic_fields_tbl_lookup(obj, &fields_obj);
1682+
VALUE fields_obj = rb_obj_fields_no_ractor_check(obj);
16841683

16851684
if (UNLIKELY(rb_shape_obj_too_complex_p(obj))) {
16861685
struct obj_traverse_replace_callback_data d = {

variable.c

Lines changed: 49 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -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

12621256
void
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-
16081594
static shape_id_t
16091595
obj_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-
18551828
static VALUE
18561829
imemo_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
23062277
void
23072278
rb_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
}

variable.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313
#include "shape.h"
1414

15-
int rb_ivar_generic_fields_tbl_lookup(VALUE obj, VALUE *);
1615
void rb_copy_complex_ivars(VALUE dest, VALUE obj, shape_id_t src_shape_id, st_table *fields_table);
17-
16+
VALUE rb_obj_fields_no_ractor_check(VALUE obj);
17+
VALUE rb_obj_fields(VALUE obj, ID id);
1818
void rb_free_rb_global_tbl(void);
1919
void rb_free_generic_fields_tbl_(void);
2020

vm_insnhelper.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,8 +1267,8 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call
12671267
}
12681268
default:
12691269
if (rb_obj_exivar_p(obj)) {
1270-
VALUE fields_obj = 0;
1271-
if (!rb_gen_fields_tbl_get(obj, id, &fields_obj)) {
1270+
VALUE fields_obj = rb_obj_fields(obj, id);
1271+
if (!fields_obj) {
12721272
return default_value;
12731273
}
12741274
ivar_list = rb_imemo_fields_ptr(fields_obj);
@@ -1343,10 +1343,8 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call
13431343
break;
13441344

13451345
default: {
1346-
VALUE fields_obj;
1347-
if (rb_gen_fields_tbl_get(obj, 0, &fields_obj)) {
1348-
table = rb_imemo_fields_complex_tbl(fields_obj);
1349-
}
1346+
VALUE fields_obj = rb_obj_fields(obj, id);
1347+
table = rb_imemo_fields_complex_tbl(fields_obj);
13501348
break;
13511349
}
13521350
}
@@ -1484,7 +1482,7 @@ vm_setivar_default(VALUE obj, ID id, VALUE val, shape_id_t dest_shape_id, attr_i
14841482
return Qundef;
14851483
}
14861484

1487-
rb_gen_fields_tbl_get(obj, 0, &fields_obj);
1485+
fields_obj = rb_obj_fields(obj, id);
14881486

14891487
if (shape_id != dest_shape_id) {
14901488
RBASIC_SET_SHAPE_ID(obj, dest_shape_id);

0 commit comments

Comments
 (0)