Skip to content

Commit e28a96a

Browse files
committed
WIP
1 parent 548b162 commit e28a96a

2 files changed

Lines changed: 51 additions & 10 deletions

File tree

gc.c

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,20 +1937,33 @@ object_id_get(VALUE obj, shape_id_t shape_id)
19371937
else {
19381938
id = rb_obj_field_get(obj, rb_shape_object_id_inline(shape_id));
19391939
}
1940+
1941+
#if RUBY_DEBUG
1942+
if (!(FIXNUM_P(id) || RB_TYPE_P(id, T_BIGNUM))) {
1943+
rb_p(obj);
1944+
rb_bug("Object's shape includes object_id, but it's missing %s", rb_obj_info(obj));
1945+
}
1946+
#endif
1947+
19401948
break;
19411949
case SHAPE_EXTERNAL_OBJ_ID:
1942-
RUBY_ASSERT(obj_to_id_tbl);
1943-
st_lookup(obj_to_id_tbl, obj, &id);
1944-
break;
1945-
}
1950+
{
1951+
RUBY_ASSERT(obj_to_id_tbl);
1952+
unsigned int lock_lev = RB_GC_VM_LOCK();
1953+
st_lookup(obj_to_id_tbl, obj, &id);
19461954

19471955
#if RUBY_DEBUG
19481956
if (!(FIXNUM_P(id) || RB_TYPE_P(id, T_BIGNUM))) {
19491957
rb_p(obj);
1950-
rb_bug("Object's shape includes object_id, but it's missing %s", rb_obj_info(obj));
1958+
rb_bug("Object's shape includes external object_id, but it's missing in obj_to_id_tbl %s", rb_obj_info(obj));
19511959
}
19521960
#endif
19531961

1962+
RB_GC_VM_UNLOCK(lock_lev);
1963+
}
1964+
break;
1965+
}
1966+
19541967
return id;
19551968
}
19561969

@@ -1968,9 +1981,9 @@ object_id0(VALUE obj, bool shareable)
19681981

19691982
attr_index_t capacity = RSHAPE_CAPACITY(shape_id);
19701983
attr_index_t free_capacity = capacity - RSHAPE_LEN(shape_id);
1971-
if (shareable && capacity && !free_capacity) {
1972-
// The object is shared and has no free capacity, we can't
1973-
// safely store the object_id inline.
1984+
if (shareable && RB_TYPE_P(obj, T_OBJECT) && capacity && !free_capacity) {
1985+
// If the object was shared and has no free capacity, we can't safely store the object_id inline.
1986+
// This is only a problem for T_OBJECT, given other types have external fields and can do RCU.
19741987
shape_id_t next_shape_id = rb_shape_transition_object_id_external(obj);
19751988
if (RB_UNLIKELY(!obj_to_id_tbl)) {
19761989
obj_to_id_tbl = st_init_numtable();
@@ -4097,6 +4110,30 @@ vm_weak_table_id2ref_foreach_update(st_data_t *key, st_data_t *value, st_data_t
40974110
return ST_CONTINUE;
40984111
}
40994112

4113+
static int
4114+
vm_weak_table_obj2id_foreach(st_data_t key, st_data_t value, st_data_t data, int error)
4115+
{
4116+
struct global_vm_table_foreach_data *iter_data = (struct global_vm_table_foreach_data *)data;
4117+
4118+
if (!iter_data->weak_only && !FIXNUM_P((VALUE)value)) {
4119+
iter_data->callback((VALUE)value, iter_data->data);
4120+
}
4121+
4122+
return iter_data->callback((VALUE)key, iter_data->data);
4123+
}
4124+
4125+
static int
4126+
vm_weak_table_obj2id_foreach_update(st_data_t *key, st_data_t *value, st_data_t data, int existing)
4127+
{
4128+
struct global_vm_table_foreach_data *iter_data = (struct global_vm_table_foreach_data *)data;
4129+
4130+
if (!iter_data->weak_only && !FIXNUM_P((VALUE)*value)) {
4131+
iter_data->update_callback((VALUE *)value, iter_data->data);
4132+
}
4133+
4134+
return iter_data->update_callback((VALUE *)key, iter_data->data);
4135+
}
4136+
41004137
static int
41014138
vm_weak_table_gen_fields_foreach(st_data_t key, st_data_t value, st_data_t data)
41024139
{
@@ -4240,8 +4277,8 @@ rb_gc_vm_weak_table_foreach(vm_table_foreach_callback_func callback,
42404277
if (obj_to_id_tbl) {
42414278
st_foreach_with_replace(
42424279
obj_to_id_tbl,
4243-
vm_weak_table_foreach_weak_key,
4244-
vm_weak_table_foreach_update_weak_key,
4280+
vm_weak_table_obj2id_foreach,
4281+
vm_weak_table_obj2id_foreach_update,
42454282
(st_data_t)&foreach_data
42464283
);
42474284
}

gc/default/default.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7048,6 +7048,10 @@ gc_ref_update(void *vstart, void *vend, size_t stride, rb_objspace_t *objspace,
70487048
static int
70497049
gc_update_references_weak_table_i(VALUE obj, void *data)
70507050
{
7051+
if (SPECIAL_CONST_P(obj)) {
7052+
return ST_CONTINUE;
7053+
}
7054+
70517055
int ret;
70527056
asan_unpoisoning_object(obj) {
70537057
ret = BUILTIN_TYPE(obj) == T_MOVED ? ST_REPLACE : ST_CONTINUE;

0 commit comments

Comments
 (0)