Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f4cc803

Browse files
committed
Fix missing WB going to too_complex on class/geniv
We were creating a new fields object, and then inserting into it without a write barrier. OpenSSL::TestSSL#test_tlsext_hostname WBCHECK ERROR: Missed write barrier detected! Parent object: 0x7ce8b3a390c0 (wb_protected: true) rb_obj_info_dump: 0x00007ce8b3a390c0 T_IMEMO/<fields> Reference counts - snapshot: 1, writebarrier: 1, current: 4, missed: 2 Missing reference to: 0x7c08b4110750 rb_obj_info_dump: 0x00007c08b4110750 OpenSSL/X509/OpenSSL::X509::Certificate OpenSSL/X509 Missing reference to: 0x7c08b4128dd0 rb_obj_info_dump: 0x00007c08b4128dd0 OpenSSL/EVP_PKEY/OpenSSL::PKey::RSA OpenSSL/EVP_PKEY
1 parent 2ed4862 commit f4cc803

File tree

1 file changed

+31
-18
lines changed

1 file changed

+31
-18
lines changed

variable.c

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,6 +1645,34 @@ rb_obj_init_too_complex(VALUE obj, st_table *table)
16451645
obj_transition_too_complex(obj, table);
16461646
}
16471647

1648+
static int
1649+
imemo_fields_complex_from_obj_i(ID key, VALUE val, st_data_t arg)
1650+
{
1651+
VALUE fields = (VALUE)arg;
1652+
st_table *table = rb_imemo_fields_complex_tbl(fields);
1653+
1654+
RUBY_ASSERT(!st_lookup(table, (st_data_t)key, NULL));
1655+
st_add_direct(table, (st_data_t)key, (st_data_t)val);
1656+
RB_OBJ_WRITTEN(fields, Qundef, key);
1657+
RB_OBJ_WRITTEN(fields, Qundef, val);
1658+
1659+
return ST_CONTINUE;
1660+
}
1661+
1662+
static VALUE
1663+
imemo_fields_complex_from_obj(VALUE klass, VALUE source_fields_obj, shape_id_t shape_id)
1664+
{
1665+
RUBY_ASSERT(source_fields_obj);
1666+
1667+
attr_index_t len = RSHAPE_LEN(RBASIC_SHAPE_ID(source_fields_obj));
1668+
VALUE fields_obj = rb_imemo_fields_new_complex(klass, len + 1);
1669+
1670+
rb_field_foreach(source_fields_obj, imemo_fields_complex_from_obj_i, (st_data_t)fields_obj, false);
1671+
RBASIC_SET_SHAPE_ID(fields_obj, shape_id);
1672+
1673+
return fields_obj;
1674+
}
1675+
16481676
void rb_obj_copy_fields_to_hash_table(VALUE obj, st_table *table);
16491677

16501678
// Copy all object fields, including ivars and internal object_id, etc
@@ -1825,12 +1853,7 @@ generic_ivar_set(VALUE obj, ID id, VALUE val)
18251853

18261854
next_shape_id = rb_shape_transition_add_ivar(fields_obj, id);
18271855
if (UNLIKELY(rb_shape_too_complex_p(next_shape_id))) {
1828-
attr_index_t current_len = RSHAPE_LEN(current_shape_id);
1829-
fields_obj = rb_imemo_fields_new_complex(rb_obj_class(obj), current_len + 1);
1830-
if (current_len) {
1831-
rb_obj_copy_fields_to_hash_table(original_fields_obj, rb_imemo_fields_complex_tbl(fields_obj));
1832-
}
1833-
RBASIC_SET_SHAPE_ID(fields_obj, next_shape_id);
1856+
fields_obj = imemo_fields_complex_from_obj(rb_obj_class(obj), original_fields_obj, next_shape_id);
18341857
goto too_complex;
18351858
}
18361859

@@ -1902,12 +1925,7 @@ generic_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val)
19021925

19031926
if (UNLIKELY(rb_shape_too_complex_p(target_shape_id))) {
19041927
if (UNLIKELY(!rb_shape_too_complex_p(current_shape_id))) {
1905-
attr_index_t current_len = RSHAPE_LEN(current_shape_id);
1906-
fields_obj = rb_imemo_fields_new_complex(rb_obj_class(obj), current_len + 1);
1907-
if (current_len) {
1908-
rb_obj_copy_fields_to_hash_table(original_fields_obj, rb_imemo_fields_complex_tbl(fields_obj));
1909-
}
1910-
1928+
fields_obj = imemo_fields_complex_from_obj(rb_obj_class(obj), original_fields_obj, target_shape_id);
19111929
current_shape_id = target_shape_id;
19121930
}
19131931

@@ -4698,12 +4716,7 @@ class_fields_ivar_set(VALUE klass, VALUE fields_obj, ID id, VALUE val, bool conc
46984716

46994717
next_shape_id = rb_shape_transition_add_ivar(fields_obj, id);
47004718
if (UNLIKELY(rb_shape_too_complex_p(next_shape_id))) {
4701-
attr_index_t current_len = RSHAPE_LEN(current_shape_id);
4702-
fields_obj = rb_imemo_fields_new_complex(rb_singleton_class(klass), current_len + 1);
4703-
if (current_len) {
4704-
rb_obj_copy_fields_to_hash_table(original_fields_obj, rb_imemo_fields_complex_tbl(fields_obj));
4705-
RBASIC_SET_SHAPE_ID(fields_obj, next_shape_id);
4706-
}
4719+
fields_obj = imemo_fields_complex_from_obj(rb_singleton_class(klass), original_fields_obj, next_shape_id);
47074720
goto too_complex;
47084721
}
47094722

0 commit comments

Comments
 (0)