Skip to content

Commit b74d4ab

Browse files
committed
Extract generic_fields_insert / generic_fields_lookup
1 parent 0d44641 commit b74d4ab

2 files changed

Lines changed: 50 additions & 53 deletions

File tree

gc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2059,7 +2059,7 @@ rb_gc_obj_free_vm_weak_references(VALUE obj)
20592059
obj_free_object_id(obj);
20602060

20612061
if (rb_obj_exivar_p(obj)) {
2062-
rb_free_generic_ivar((VALUE)obj);
2062+
rb_free_generic_ivar(obj);
20632063
}
20642064

20652065
switch (BUILTIN_TYPE(obj)) {

variable.c

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,29 @@ rb_generic_fields_tbl_get(void)
11971197
return generic_fields_tbl_;
11981198
}
11991199

1200+
static inline VALUE
1201+
generic_fields_lookup(VALUE obj, ID id, bool force_check_ractor)
1202+
{
1203+
VALUE fields_obj = Qfalse;
1204+
RB_VM_LOCKING() {
1205+
st_table *generic_tbl = generic_fields_tbl(obj, id, false);
1206+
st_lookup(generic_tbl, obj, (st_data_t *)&fields_obj);
1207+
}
1208+
return fields_obj;
1209+
}
1210+
1211+
static inline void
1212+
generic_fields_insert(VALUE obj, VALUE fields_obj)
1213+
{
1214+
RUBY_ASSERT(IMEMO_TYPE_P(fields_obj, imemo_fields));
1215+
1216+
RB_VM_LOCKING() {
1217+
st_table *generic_tbl = generic_fields_tbl_no_ractor_check(obj);
1218+
st_insert(generic_tbl, obj, fields_obj);
1219+
}
1220+
RB_OBJ_WRITTEN(obj, Qundef, fields_obj);
1221+
}
1222+
12001223
int
12011224
rb_gen_fields_tbl_get(VALUE obj, ID id, VALUE *fields_obj)
12021225
{
@@ -1566,6 +1589,8 @@ rb_attr_delete(VALUE obj, ID id)
15661589
return rb_ivar_delete(obj, id, Qnil);
15671590
}
15681591

1592+
static inline void generic_update_fields_obj(VALUE obj, VALUE fields_obj, const VALUE original_fields_obj);
1593+
15691594
static shape_id_t
15701595
obj_transition_too_complex(VALUE obj, st_table *table)
15711596
{
@@ -1599,12 +1624,11 @@ obj_transition_too_complex(VALUE obj, st_table *table)
15991624
VALUE fields_obj = rb_imemo_fields_new_complex_tbl(rb_obj_class(obj), table);
16001625
RBASIC_SET_SHAPE_ID(fields_obj, shape_id);
16011626

1602-
struct st_table *gen_fields_tbl = generic_fields_tbl_no_ractor_check(obj);
16031627
RB_VM_LOCKING() {
1604-
st_insert(gen_fields_tbl, (st_data_t)obj, (st_data_t)fields_obj);
1628+
const VALUE original_fields_obj = generic_fields_lookup(obj, 0, false);
1629+
generic_update_fields_obj(obj, fields_obj, original_fields_obj);
16051630
}
16061631
RBASIC_SET_SHAPE_ID(obj, shape_id);
1607-
RB_OBJ_WRITTEN(obj, Qundef, fields_obj);
16081632
}
16091633
}
16101634

@@ -1758,17 +1782,25 @@ general_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val, void *data,
17581782
}
17591783
}
17601784

1785+
static inline void
1786+
generic_update_fields_obj(VALUE obj, VALUE fields_obj, const VALUE original_fields_obj)
1787+
{
1788+
if (fields_obj != original_fields_obj) {
1789+
if (original_fields_obj) {
1790+
// Clear root shape to avoid triggering cleanup such as free_object_id.
1791+
RBASIC_SET_SHAPE_ID(original_fields_obj, ROOT_SHAPE_ID);
1792+
}
1793+
1794+
generic_fields_insert(obj, fields_obj);
1795+
}
1796+
}
1797+
17611798
static void
17621799
generic_ivar_set(VALUE obj, ID id, VALUE val)
17631800
{
1764-
VALUE fields_obj = 0;
1765-
st_table *generic_tbl;
17661801
bool existing = true;
17671802

1768-
RB_VM_LOCKING() {
1769-
generic_tbl = generic_fields_tbl(obj, id, false);
1770-
st_lookup(generic_tbl, obj, (st_data_t *)&fields_obj);
1771-
}
1803+
VALUE fields_obj = generic_fields_lookup(obj, id, false);
17721804

17731805
const VALUE original_fields_obj = fields_obj;
17741806
if (!fields_obj) {
@@ -1831,17 +1863,7 @@ generic_ivar_set(VALUE obj, ID id, VALUE val)
18311863
RBASIC_SET_SHAPE_ID(fields_obj, next_shape_id);
18321864
}
18331865

1834-
if (fields_obj != original_fields_obj) {
1835-
RB_VM_LOCKING() {
1836-
st_insert(generic_tbl, obj, fields_obj);
1837-
}
1838-
RB_OBJ_WRITTEN(obj, original_fields_obj, fields_obj);
1839-
1840-
if (original_fields_obj) {
1841-
// Clear root shape to avoid triggering cleanup such as free_object_id.
1842-
RBASIC_SET_SHAPE_ID(original_fields_obj, ROOT_SHAPE_ID);
1843-
}
1844-
}
1866+
generic_update_fields_obj(obj, fields_obj, original_fields_obj);
18451867

18461868
if (!existing) {
18471869
RBASIC_SET_SHAPE_ID(obj, next_shape_id);
@@ -1857,17 +1879,8 @@ generic_ivar_set(VALUE obj, ID id, VALUE val)
18571879
existing = st_insert(table, (st_data_t)id, (st_data_t)val);
18581880
RB_OBJ_WRITTEN(fields_obj, Qundef, val);
18591881

1860-
if (fields_obj != original_fields_obj) {
1861-
RB_VM_LOCKING() {
1862-
st_insert(generic_tbl, obj, fields_obj);
1863-
}
1864-
RB_OBJ_WRITTEN(obj, original_fields_obj, fields_obj);
1882+
generic_update_fields_obj(obj, fields_obj, original_fields_obj);
18651883

1866-
if (original_fields_obj) {
1867-
// Clear root shape to avoid triggering cleanup such as free_object_id.
1868-
RBASIC_SET_SHAPE_ID(original_fields_obj, ROOT_SHAPE_ID);
1869-
}
1870-
}
18711884
if (!existing) {
18721885
RBASIC_SET_SHAPE_ID(obj, next_shape_id);
18731886
}
@@ -1881,15 +1894,9 @@ generic_ivar_set(VALUE obj, ID id, VALUE val)
18811894
static void
18821895
generic_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val)
18831896
{
1884-
VALUE fields_obj = 0;
1885-
st_table *generic_tbl;
18861897
bool existing = true;
18871898

1888-
RB_VM_LOCKING() {
1889-
generic_tbl = generic_fields_tbl(obj, RSHAPE_EDGE_NAME(target_shape_id), false);
1890-
st_lookup(generic_tbl, obj, (st_data_t *)&fields_obj);
1891-
}
1892-
1899+
VALUE fields_obj = generic_fields_lookup(obj, RSHAPE_EDGE_NAME(target_shape_id), false);
18931900
const VALUE original_fields_obj = fields_obj;
18941901

18951902
shape_id_t current_shape_id = fields_obj ? RBASIC_SHAPE_ID(fields_obj) : ROOT_SHAPE_ID;
@@ -1908,10 +1915,10 @@ generic_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val)
19081915
existing = false;
19091916
st_table *table = rb_imemo_fields_complex_tbl(fields_obj);
19101917

1911-
RBASIC_SET_SHAPE_ID(fields_obj, target_shape_id);
19121918
RUBY_ASSERT(RSHAPE_EDGE_NAME(target_shape_id));
19131919
st_insert(table, (st_data_t)RSHAPE_EDGE_NAME(target_shape_id), (st_data_t)val);
19141920
RB_OBJ_WRITTEN(fields_obj, Qundef, val);
1921+
RBASIC_SET_SHAPE_ID(fields_obj, target_shape_id);
19151922
}
19161923
else {
19171924
attr_index_t index = RSHAPE_INDEX(target_shape_id);
@@ -1927,26 +1934,16 @@ generic_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val)
19271934
}
19281935
}
19291936

1937+
VALUE *table = rb_imemo_fields_ptr(fields_obj);
1938+
RB_OBJ_WRITE(fields_obj, &table[index], val);
1939+
19301940
if (RSHAPE_LEN(target_shape_id) > RSHAPE_LEN(current_shape_id)) {
19311941
existing = false;
19321942
RBASIC_SET_SHAPE_ID(fields_obj, target_shape_id);
19331943
}
1934-
1935-
VALUE *table = rb_imemo_fields_ptr(fields_obj);
1936-
RB_OBJ_WRITE(fields_obj, &table[index], val);
19371944
}
19381945

1939-
if (fields_obj != original_fields_obj) {
1940-
RB_VM_LOCKING() {
1941-
st_insert(generic_tbl, obj, fields_obj);
1942-
}
1943-
RB_OBJ_WRITTEN(obj, original_fields_obj, fields_obj);
1944-
1945-
if (original_fields_obj) {
1946-
// Clear root shape to avoid triggering cleanup such as free_object_id.
1947-
RBASIC_SET_SHAPE_ID(original_fields_obj, ROOT_SHAPE_ID);
1948-
}
1949-
}
1946+
generic_update_fields_obj(obj, fields_obj, original_fields_obj);
19501947

19511948
if (!existing) {
19521949
RBASIC_SET_SHAPE_ID(obj, target_shape_id);

0 commit comments

Comments
 (0)