Skip to content

Commit 744f64d

Browse files
committed
Make RClass.cc_table a managed object
For now this doesn't change anything, but now that the table is managed by GC, it opens the door to use RCU when in multi-ractor mode, hence allow unsynchornized reads.
1 parent f38dd3b commit 744f64d

10 files changed

Lines changed: 191 additions & 159 deletions

File tree

gc.c

Lines changed: 4 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,7 +1208,6 @@ classext_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
12081208
struct classext_foreach_args *args = (struct classext_foreach_args *)arg;
12091209

12101210
rb_id_table_free(RCLASSEXT_M_TBL(ext));
1211-
rb_cc_tbl_free(RCLASSEXT_CC_TBL(ext), args->klass);
12121211

12131212
if (!RCLASSEXT_SHARED_CONST_TBL(ext) && (tbl = RCLASSEXT_CONST_TBL(ext)) != NULL) {
12141213
rb_free_const_table(tbl);
@@ -1239,7 +1238,6 @@ classext_iclass_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *a
12391238
if (RCLASSEXT_CALLABLE_M_TBL(ext) != NULL) {
12401239
rb_id_table_free(RCLASSEXT_CALLABLE_M_TBL(ext));
12411240
}
1242-
rb_cc_tbl_free(RCLASSEXT_CC_TBL(ext), args->klass);
12431241

12441242
rb_class_classext_free_subclasses(ext, args->klass);
12451243

@@ -2266,24 +2264,6 @@ rb_gc_after_updating_jit_code(void)
22662264
#endif
22672265
}
22682266

2269-
static enum rb_id_table_iterator_result
2270-
cc_table_memsize_i(VALUE ccs_ptr, void *data_ptr)
2271-
{
2272-
size_t *total_size = data_ptr;
2273-
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
2274-
*total_size += sizeof(*ccs);
2275-
*total_size += sizeof(ccs->entries[0]) * ccs->capa;
2276-
return ID_TABLE_CONTINUE;
2277-
}
2278-
2279-
static size_t
2280-
cc_table_memsize(struct rb_id_table *cc_table)
2281-
{
2282-
size_t total = rb_id_table_memsize(cc_table);
2283-
rb_id_table_foreach_values(cc_table, cc_table_memsize_i, &total);
2284-
return total;
2285-
}
2286-
22872267
static void
22882268
classext_memsize(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
22892269
{
@@ -2299,9 +2279,6 @@ classext_memsize(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
22992279
if (RCLASSEXT_CONST_TBL(ext)) {
23002280
s += rb_id_table_memsize(RCLASSEXT_CONST_TBL(ext));
23012281
}
2302-
if (RCLASSEXT_CC_TBL(ext)) {
2303-
s += cc_table_memsize(RCLASSEXT_CC_TBL(ext));
2304-
}
23052282
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) {
23062283
s += (RCLASSEXT_SUPERCLASS_DEPTH(ext) + 1) * sizeof(VALUE);
23072284
}
@@ -2352,9 +2329,6 @@ rb_obj_memsize_of(VALUE obj)
23522329
size += rb_id_table_memsize(RCLASS_M_TBL(obj));
23532330
}
23542331
}
2355-
if (RCLASS_WRITABLE_CC_TBL(obj)) {
2356-
size += cc_table_memsize(RCLASS_WRITABLE_CC_TBL(obj));
2357-
}
23582332
break;
23592333
case T_STRING:
23602334
size += rb_str_memsize(obj);
@@ -2839,47 +2813,6 @@ mark_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
28392813
rb_id_table_foreach_values(tbl, mark_const_entry_i, objspace);
28402814
}
28412815

2842-
struct mark_cc_entry_args {
2843-
rb_objspace_t *objspace;
2844-
VALUE klass;
2845-
};
2846-
2847-
static enum rb_id_table_iterator_result
2848-
mark_cc_entry_i(VALUE ccs_ptr, void *data)
2849-
{
2850-
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
2851-
2852-
VM_ASSERT(vm_ccs_p(ccs));
2853-
2854-
if (METHOD_ENTRY_INVALIDATED(ccs->cme)) {
2855-
rb_vm_ccs_free(ccs);
2856-
return ID_TABLE_DELETE;
2857-
}
2858-
else {
2859-
gc_mark_internal((VALUE)ccs->cme);
2860-
2861-
for (int i=0; i<ccs->len; i++) {
2862-
VM_ASSERT(((struct mark_cc_entry_args *)data)->klass == ccs->entries[i].cc->klass);
2863-
VM_ASSERT(vm_cc_check_cme(ccs->entries[i].cc, ccs->cme));
2864-
2865-
gc_mark_internal((VALUE)ccs->entries[i].cc);
2866-
}
2867-
return ID_TABLE_CONTINUE;
2868-
}
2869-
}
2870-
2871-
static void
2872-
mark_cc_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl, VALUE klass)
2873-
{
2874-
struct mark_cc_entry_args args;
2875-
2876-
if (!tbl) return;
2877-
2878-
args.objspace = objspace;
2879-
args.klass = klass;
2880-
rb_id_table_foreach_values(tbl, mark_cc_entry_i, (void *)&args);
2881-
}
2882-
28832816
static enum rb_id_table_iterator_result
28842817
mark_cvc_tbl_i(VALUE cvc_entry, void *objspace)
28852818
{
@@ -3117,7 +3050,6 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE namespace, void *a
31173050
{
31183051
struct gc_mark_classext_foreach_arg *foreach_arg = (struct gc_mark_classext_foreach_arg *)arg;
31193052
rb_objspace_t *objspace = foreach_arg->objspace;
3120-
VALUE obj = foreach_arg->obj;
31213053

31223054
if (RCLASSEXT_SUPER(ext)) {
31233055
gc_mark_internal(RCLASSEXT_SUPER(ext));
@@ -3128,7 +3060,7 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE namespace, void *a
31283060
mark_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
31293061
}
31303062
mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
3131-
mark_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext), obj);
3063+
gc_mark_internal(RCLASSEXT_CC_TBL(ext));
31323064
mark_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext));
31333065
gc_mark_internal(RCLASSEXT_CLASSPATH(ext));
31343066
}
@@ -3138,7 +3070,6 @@ gc_mark_classext_iclass(rb_classext_t *ext, bool prime, VALUE namespace, void *a
31383070
{
31393071
struct gc_mark_classext_foreach_arg *foreach_arg = (struct gc_mark_classext_foreach_arg *)arg;
31403072
rb_objspace_t *objspace = foreach_arg->objspace;
3141-
VALUE iclass = foreach_arg->obj;
31423073

31433074
if (RCLASSEXT_SUPER(ext)) {
31443075
gc_mark_internal(RCLASSEXT_SUPER(ext));
@@ -3150,7 +3081,7 @@ gc_mark_classext_iclass(rb_classext_t *ext, bool prime, VALUE namespace, void *a
31503081
gc_mark_internal(RCLASSEXT_INCLUDER(ext));
31513082
}
31523083
mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
3153-
mark_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext), iclass);
3084+
gc_mark_internal(RCLASSEXT_CC_TBL(ext));
31543085
}
31553086

31563087
#define TYPED_DATA_REFS_OFFSET_LIST(d) (size_t *)(uintptr_t)RTYPEDDATA_TYPE(d)->function.dmark
@@ -3714,33 +3645,6 @@ update_m_tbl(void *objspace, struct rb_id_table *tbl)
37143645
}
37153646
}
37163647

3717-
static enum rb_id_table_iterator_result
3718-
update_cc_tbl_i(VALUE ccs_ptr, void *objspace)
3719-
{
3720-
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
3721-
VM_ASSERT(vm_ccs_p(ccs));
3722-
3723-
if (rb_gc_impl_object_moved_p(objspace, (VALUE)ccs->cme)) {
3724-
ccs->cme = (const rb_callable_method_entry_t *)gc_location_internal(objspace, (VALUE)ccs->cme);
3725-
}
3726-
3727-
for (int i=0; i<ccs->len; i++) {
3728-
if (rb_gc_impl_object_moved_p(objspace, (VALUE)ccs->entries[i].cc)) {
3729-
ccs->entries[i].cc = (struct rb_callcache *)gc_location_internal(objspace, (VALUE)ccs->entries[i].cc);
3730-
}
3731-
}
3732-
3733-
// do not replace
3734-
return ID_TABLE_CONTINUE;
3735-
}
3736-
3737-
static void
3738-
update_cc_tbl(void *objspace, struct rb_id_table *tbl)
3739-
{
3740-
if (!tbl) return;
3741-
rb_id_table_foreach_values(tbl, update_cc_tbl_i, objspace);
3742-
}
3743-
37443648
static enum rb_id_table_iterator_result
37453649
update_cvc_tbl_i(VALUE cvc_entry, void *objspace)
37463650
{
@@ -3839,7 +3743,7 @@ update_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
38393743
if (!RCLASSEXT_SHARED_CONST_TBL(ext)) {
38403744
update_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
38413745
}
3842-
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
3746+
UPDATE_IF_MOVED(objspace, RCLASSEXT_CC_TBL(ext));
38433747
update_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext));
38443748
update_superclasses(objspace, ext);
38453749
update_subclasses(objspace, ext);
@@ -3858,7 +3762,7 @@ update_iclass_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void
38583762
}
38593763
update_m_tbl(objspace, RCLASSEXT_M_TBL(ext));
38603764
update_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
3861-
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
3765+
UPDATE_IF_MOVED(objspace, RCLASSEXT_CC_TBL(ext));
38623766
update_subclasses(objspace, ext);
38633767

38643768
update_classext_values(objspace, ext, true);

id_table.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct rb_id_table {
4747

4848
#if SIZEOF_VALUE == 8
4949
#define ITEM_GET_KEY(tbl, i) ((tbl)->items[i].key)
50-
#define ITEM_KEY_ISSET(tbl, i) ((tbl)->items[i].key)
50+
#define ITEM_KEY_ISSET(tbl, i) ((tbl)->items && (tbl)->items[i].key)
5151
#define ITEM_COLLIDED(tbl, i) ((tbl)->items[i].collision)
5252
#define ITEM_SET_COLLIDED(tbl, i) ((tbl)->items[i].collision = 1)
5353
static inline void
@@ -298,6 +298,10 @@ rb_id_table_foreach_values(struct rb_id_table *tbl, rb_id_table_foreach_values_f
298298
{
299299
int i, capa = tbl->capa;
300300

301+
if (!tbl->items) {
302+
return;
303+
}
304+
301305
for (i=0; i<capa; i++) {
302306
if (ITEM_KEY_ISSET(tbl, i)) {
303307
enum rb_id_table_iterator_result ret = (*func)(tbl->items[i].val, data);
@@ -345,7 +349,7 @@ managed_id_table_memsize(const void *data)
345349
return rb_id_table_memsize(tbl) - sizeof(struct rb_id_table);
346350
}
347351

348-
static const rb_data_type_t managed_id_table_type = {
352+
const rb_data_type_t rb_managed_id_table_type = {
349353
.wrap_struct_name = "VM/managed_id_table",
350354
.function = {
351355
.dmark = NULL, // Nothing to mark
@@ -359,20 +363,26 @@ static inline struct rb_id_table *
359363
managed_id_table_ptr(VALUE obj)
360364
{
361365
RUBY_ASSERT(RB_TYPE_P(obj, T_DATA));
362-
RUBY_ASSERT(rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), &managed_id_table_type));
366+
RUBY_ASSERT(rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), &rb_managed_id_table_type));
363367

364368
return RTYPEDDATA_GET_DATA(obj);
365369
}
366370

367371
VALUE
368-
rb_managed_id_table_new(size_t capa)
372+
rb_managed_id_table_create(const rb_data_type_t *type, size_t capa)
369373
{
370374
struct rb_id_table *tbl;
371-
VALUE obj = TypedData_Make_Struct(0, struct rb_id_table, &managed_id_table_type, tbl);
375+
VALUE obj = TypedData_Make_Struct(0, struct rb_id_table, type, tbl);
372376
rb_id_table_init(tbl, capa);
373377
return obj;
374378
}
375379

380+
VALUE
381+
rb_managed_id_table_new(size_t capa)
382+
{
383+
return rb_managed_id_table_create(&rb_managed_id_table_type, capa);
384+
}
385+
376386
static enum rb_id_table_iterator_result
377387
managed_id_table_dup_i(ID id, VALUE val, void *data)
378388
{
@@ -385,7 +395,7 @@ VALUE
385395
rb_managed_id_table_dup(VALUE old_table)
386396
{
387397
struct rb_id_table *new_tbl;
388-
VALUE obj = TypedData_Make_Struct(0, struct rb_id_table, &managed_id_table_type, new_tbl);
398+
VALUE obj = TypedData_Make_Struct(0, struct rb_id_table, &rb_managed_id_table_type, new_tbl);
389399
struct rb_id_table *old_tbl = managed_id_table_ptr(old_table);
390400
rb_id_table_init(new_tbl, old_tbl->num + 1);
391401
rb_id_table_foreach(old_tbl, managed_id_table_dup_i, new_tbl);
@@ -415,3 +425,15 @@ rb_managed_id_table_foreach(VALUE table, rb_id_table_foreach_func_t *func, void
415425
{
416426
rb_id_table_foreach(managed_id_table_ptr(table), func, data);
417427
}
428+
429+
void
430+
rb_managed_id_table_foreach_values(VALUE table, rb_id_table_foreach_values_func_t *func, void *data)
431+
{
432+
rb_id_table_foreach_values(managed_id_table_ptr(table), func, data);
433+
}
434+
435+
int
436+
rb_managed_id_table_delete(VALUE table, ID id)
437+
{
438+
return rb_id_table_delete(managed_id_table_ptr(table), id);
439+
}

id_table.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,17 @@ void rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *fu
3535
void rb_id_table_foreach_values(struct rb_id_table *tbl, rb_id_table_foreach_values_func_t *func, void *data);
3636
void rb_id_table_foreach_values_with_replace(struct rb_id_table *tbl, rb_id_table_foreach_values_func_t *func, rb_id_table_update_value_callback_func_t *replace, void *data);
3737

38+
VALUE rb_managed_id_table_create(const rb_data_type_t *type, size_t capa);
3839
VALUE rb_managed_id_table_new(size_t capa);
3940
VALUE rb_managed_id_table_dup(VALUE table);
4041
int rb_managed_id_table_insert(VALUE table, ID id, VALUE val);
4142
int rb_managed_id_table_lookup(VALUE table, ID id, VALUE *valp);
4243
size_t rb_managed_id_table_size(VALUE table);
4344
void rb_managed_id_table_foreach(VALUE table, rb_id_table_foreach_func_t *func, void *data);
45+
void rb_managed_id_table_foreach_values(VALUE table, rb_id_table_foreach_values_func_t *func, void *data);
46+
int rb_managed_id_table_delete(VALUE table, ID id);
47+
48+
extern const rb_data_type_t rb_managed_id_table_type;
4449

4550
RUBY_SYMBOL_EXPORT_BEGIN
4651
size_t rb_id_table_size(const struct rb_id_table *tbl);

imemo.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -551,26 +551,6 @@ rb_vm_ccs_free(struct rb_class_cc_entries *ccs)
551551
vm_ccs_free(ccs, true, Qundef);
552552
}
553553

554-
static enum rb_id_table_iterator_result
555-
cc_tbl_free_i(VALUE ccs_ptr, void *data)
556-
{
557-
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
558-
VALUE klass = (VALUE)data;
559-
VM_ASSERT(vm_ccs_p(ccs));
560-
561-
vm_ccs_free(ccs, false, klass);
562-
563-
return ID_TABLE_CONTINUE;
564-
}
565-
566-
void
567-
rb_cc_tbl_free(struct rb_id_table *cc_tbl, VALUE klass)
568-
{
569-
if (!cc_tbl) return;
570-
rb_id_table_foreach_values(cc_tbl, cc_tbl_free_i, (void *)klass);
571-
rb_id_table_free(cc_tbl);
572-
}
573-
574554
static inline void
575555
imemo_fields_free(struct rb_fields *fields)
576556
{

internal/class.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ struct rb_classext_struct {
8383
struct rb_id_table *m_tbl;
8484
struct rb_id_table *const_tbl;
8585
struct rb_id_table *callable_m_tbl;
86-
struct rb_id_table *cc_tbl; /* ID -> [[ci1, cc1], [ci2, cc2] ...] */
86+
VALUE cc_tbl; /* { ID => { cme, [cc1, cc2, ...] }, ... } */
8787
struct rb_id_table *cvc_tbl;
8888
VALUE *superclasses;
8989
/**
@@ -262,7 +262,7 @@ static inline void RCLASS_WRITE_SUPER(VALUE klass, VALUE super);
262262
static inline void RCLASS_SET_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared);
263263
static inline void RCLASS_WRITE_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared);
264264
static inline void RCLASS_WRITE_CALLABLE_M_TBL(VALUE klass, struct rb_id_table *table);
265-
static inline void RCLASS_WRITE_CC_TBL(VALUE klass, struct rb_id_table *table);
265+
static inline void RCLASS_WRITE_CC_TBL(VALUE klass, VALUE table);
266266
static inline void RCLASS_SET_CVC_TBL(VALUE klass, struct rb_id_table *table);
267267
static inline void RCLASS_WRITE_CVC_TBL(VALUE klass, struct rb_id_table *table);
268268

@@ -628,9 +628,9 @@ RCLASS_WRITE_CALLABLE_M_TBL(VALUE klass, struct rb_id_table *table)
628628
}
629629

630630
static inline void
631-
RCLASS_WRITE_CC_TBL(VALUE klass, struct rb_id_table *table)
631+
RCLASS_WRITE_CC_TBL(VALUE klass, VALUE table)
632632
{
633-
RCLASSEXT_CC_TBL(RCLASS_EXT_WRITABLE(klass)) = table;
633+
RB_OBJ_WRITE(klass, &RCLASSEXT_CC_TBL(RCLASS_EXT_WRITABLE(klass)), table);
634634
}
635635

636636
static inline void

internal/imemo.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ static inline void MEMO_V2_SET(struct MEMO *m, VALUE v);
148148

149149
size_t rb_imemo_memsize(VALUE obj);
150150
void rb_imemo_mark_and_move(VALUE obj, bool reference_updating);
151-
void rb_cc_tbl_free(struct rb_id_table *cc_tbl, VALUE klass);
152151
void rb_imemo_free(VALUE obj);
153152

154153
RUBY_SYMBOL_EXPORT_BEGIN

method.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,6 @@ void rb_vm_delete_cc_refinement(const struct rb_callcache *cc);
259259

260260
void rb_clear_method_cache(VALUE klass_or_module, ID mid);
261261
void rb_clear_all_refinement_method_cache(void);
262-
void rb_invalidate_method_caches(struct rb_id_table *cm_tbl, struct rb_id_table *cc_tbl);
262+
void rb_invalidate_method_caches(struct rb_id_table *cm_tbl, VALUE cc_tbl);
263263

264264
#endif /* RUBY_METHOD_H */

vm_callinfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ cc_check_class(VALUE klass)
329329
return klass;
330330
}
331331

332+
VALUE rb_vm_cc_table_create(size_t capa);
333+
332334
static inline const struct rb_callcache *
333335
vm_cc_new(VALUE klass,
334336
const struct rb_callable_method_entry_struct *cme,

0 commit comments

Comments
 (0)