Skip to content

Commit 635bf6c

Browse files
byrootetiennebarrie
andcommitted
Make RClass’s table of callcaches a VALUE object
Co-authored-by: Étienne Barrié <etienne.barrie@gmail.com>
1 parent 6d15d64 commit 635bf6c

7 files changed

Lines changed: 170 additions & 238 deletions

File tree

gc.c

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

12131213
rb_id_table_free(RCLASSEXT_M_TBL(ext));
1214-
rb_cc_tbl_free(RCLASSEXT_CC_TBL(ext), args->klass);
12151214
if (!RCLASSEXT_SHARED_CONST_TBL(ext) && (tbl = RCLASSEXT_CONST_TBL(ext)) != NULL) {
12161215
rb_free_const_table(tbl);
12171216
}
@@ -1241,7 +1240,6 @@ classext_iclass_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *a
12411240
if (RCLASSEXT_CALLABLE_M_TBL(ext) != NULL) {
12421241
rb_id_table_free(RCLASSEXT_CALLABLE_M_TBL(ext));
12431242
}
1244-
rb_cc_tbl_free(RCLASSEXT_CC_TBL(ext), args->klass);
12451243

12461244
rb_class_classext_free_subclasses(ext, args->klass);
12471245

@@ -2238,24 +2236,6 @@ rb_obj_id_p(VALUE obj)
22382236
return !RB_TYPE_P(obj, T_IMEMO) && rb_shape_obj_has_id(obj);
22392237
}
22402238

2241-
static enum rb_id_table_iterator_result
2242-
cc_table_memsize_i(VALUE ccs_ptr, void *data_ptr)
2243-
{
2244-
size_t *total_size = data_ptr;
2245-
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
2246-
*total_size += sizeof(*ccs);
2247-
*total_size += sizeof(ccs->entries[0]) * ccs->capa;
2248-
return ID_TABLE_CONTINUE;
2249-
}
2250-
2251-
static size_t
2252-
cc_table_memsize(struct rb_id_table *cc_table)
2253-
{
2254-
size_t total = rb_id_table_memsize(cc_table);
2255-
rb_id_table_foreach_values(cc_table, cc_table_memsize_i, &total);
2256-
return total;
2257-
}
2258-
22592239
static void
22602240
classext_memsize(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
22612241
{
@@ -2271,9 +2251,6 @@ classext_memsize(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
22712251
if (RCLASSEXT_CONST_TBL(ext)) {
22722252
s += rb_id_table_memsize(RCLASSEXT_CONST_TBL(ext));
22732253
}
2274-
if (RCLASSEXT_CC_TBL(ext)) {
2275-
s += cc_table_memsize(RCLASSEXT_CC_TBL(ext));
2276-
}
22772254
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) {
22782255
s += (RCLASSEXT_SUPERCLASS_DEPTH(ext) + 1) * sizeof(VALUE);
22792256
}
@@ -2324,9 +2301,6 @@ rb_obj_memsize_of(VALUE obj)
23242301
size += rb_id_table_memsize(RCLASS_M_TBL(obj));
23252302
}
23262303
}
2327-
if (RCLASS_WRITABLE_CC_TBL(obj)) {
2328-
size += cc_table_memsize(RCLASS_WRITABLE_CC_TBL(obj));
2329-
}
23302304
break;
23312305
case T_STRING:
23322306
size += rb_str_memsize(obj);
@@ -2803,47 +2777,6 @@ mark_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
28032777
rb_id_table_foreach_values(tbl, mark_const_entry_i, objspace);
28042778
}
28052779

2806-
struct mark_cc_entry_args {
2807-
rb_objspace_t *objspace;
2808-
VALUE klass;
2809-
};
2810-
2811-
static enum rb_id_table_iterator_result
2812-
mark_cc_entry_i(VALUE ccs_ptr, void *data)
2813-
{
2814-
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
2815-
2816-
VM_ASSERT(vm_ccs_p(ccs));
2817-
2818-
if (METHOD_ENTRY_INVALIDATED(ccs->cme)) {
2819-
rb_vm_ccs_free(ccs);
2820-
return ID_TABLE_DELETE;
2821-
}
2822-
else {
2823-
gc_mark_internal((VALUE)ccs->cme);
2824-
2825-
for (int i=0; i<ccs->len; i++) {
2826-
VM_ASSERT(((struct mark_cc_entry_args *)data)->klass == ccs->entries[i].cc->klass);
2827-
VM_ASSERT(vm_cc_check_cme(ccs->entries[i].cc, ccs->cme));
2828-
2829-
gc_mark_internal((VALUE)ccs->entries[i].cc);
2830-
}
2831-
return ID_TABLE_CONTINUE;
2832-
}
2833-
}
2834-
2835-
static void
2836-
mark_cc_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl, VALUE klass)
2837-
{
2838-
struct mark_cc_entry_args args;
2839-
2840-
if (!tbl) return;
2841-
2842-
args.objspace = objspace;
2843-
args.klass = klass;
2844-
rb_id_table_foreach_values(tbl, mark_cc_entry_i, (void *)&args);
2845-
}
2846-
28472780
static enum rb_id_table_iterator_result
28482781
mark_cvc_tbl_i(VALUE cvc_entry, void *objspace)
28492782
{
@@ -3081,7 +3014,6 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE namespace, void *a
30813014
{
30823015
struct gc_mark_classext_foreach_arg *foreach_arg = (struct gc_mark_classext_foreach_arg *)arg;
30833016
rb_objspace_t *objspace = foreach_arg->objspace;
3084-
VALUE obj = foreach_arg->obj;
30853017

30863018
if (RCLASSEXT_SUPER(ext)) {
30873019
gc_mark_internal(RCLASSEXT_SUPER(ext));
@@ -3092,7 +3024,7 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE namespace, void *a
30923024
mark_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
30933025
}
30943026
mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
3095-
mark_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext), obj);
3027+
gc_mark_internal(RCLASSEXT_CC_TBL(ext));
30963028
mark_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext));
30973029
gc_mark_internal(RCLASSEXT_CLASSPATH(ext));
30983030
}
@@ -3102,7 +3034,6 @@ gc_mark_classext_iclass(rb_classext_t *ext, bool prime, VALUE namespace, void *a
31023034
{
31033035
struct gc_mark_classext_foreach_arg *foreach_arg = (struct gc_mark_classext_foreach_arg *)arg;
31043036
rb_objspace_t *objspace = foreach_arg->objspace;
3105-
VALUE iclass = foreach_arg->obj;
31063037

31073038
if (RCLASSEXT_SUPER(ext)) {
31083039
gc_mark_internal(RCLASSEXT_SUPER(ext));
@@ -3114,7 +3045,7 @@ gc_mark_classext_iclass(rb_classext_t *ext, bool prime, VALUE namespace, void *a
31143045
gc_mark_internal(RCLASSEXT_INCLUDER(ext));
31153046
}
31163047
mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
3117-
mark_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext), iclass);
3048+
gc_mark_internal(RCLASSEXT_CC_TBL(ext));
31183049
}
31193050

31203051
#define TYPED_DATA_REFS_OFFSET_LIST(d) (size_t *)(uintptr_t)RTYPEDDATA_TYPE(d)->function.dmark
@@ -3679,33 +3610,6 @@ update_m_tbl(void *objspace, struct rb_id_table *tbl)
36793610
}
36803611
}
36813612

3682-
static enum rb_id_table_iterator_result
3683-
update_cc_tbl_i(VALUE ccs_ptr, void *objspace)
3684-
{
3685-
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
3686-
VM_ASSERT(vm_ccs_p(ccs));
3687-
3688-
if (rb_gc_impl_object_moved_p(objspace, (VALUE)ccs->cme)) {
3689-
ccs->cme = (const rb_callable_method_entry_t *)gc_location_internal(objspace, (VALUE)ccs->cme);
3690-
}
3691-
3692-
for (int i=0; i<ccs->len; i++) {
3693-
if (rb_gc_impl_object_moved_p(objspace, (VALUE)ccs->entries[i].cc)) {
3694-
ccs->entries[i].cc = (struct rb_callcache *)gc_location_internal(objspace, (VALUE)ccs->entries[i].cc);
3695-
}
3696-
}
3697-
3698-
// do not replace
3699-
return ID_TABLE_CONTINUE;
3700-
}
3701-
3702-
static void
3703-
update_cc_tbl(void *objspace, struct rb_id_table *tbl)
3704-
{
3705-
if (!tbl) return;
3706-
rb_id_table_foreach_values(tbl, update_cc_tbl_i, objspace);
3707-
}
3708-
37093613
static enum rb_id_table_iterator_result
37103614
update_cvc_tbl_i(VALUE cvc_entry, void *objspace)
37113615
{
@@ -3804,7 +3708,7 @@ update_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
38043708
if (!RCLASSEXT_SHARED_CONST_TBL(ext)) {
38053709
update_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
38063710
}
3807-
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
3711+
UPDATE_IF_MOVED(objspace, RCLASSEXT_CC_TBL(ext));
38083712
update_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext));
38093713
update_superclasses(objspace, ext);
38103714
update_subclasses(objspace, ext);
@@ -3823,7 +3727,7 @@ update_iclass_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void
38233727
}
38243728
update_m_tbl(objspace, RCLASSEXT_M_TBL(ext));
38253729
update_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
3826-
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
3730+
UPDATE_IF_MOVED(objspace, RCLASSEXT_CC_TBL(ext));
38273731
update_subclasses(objspace, ext);
38283732

38293733
update_classext_values(objspace, ext, true);

imemo.c

Lines changed: 0 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -278,47 +278,6 @@ rb_imemo_memsize(VALUE obj)
278278
* mark
279279
* ========================================================================= */
280280

281-
static enum rb_id_table_iterator_result
282-
cc_table_mark_i(VALUE ccs_ptr, void *data)
283-
{
284-
// looks duplicate to mark_cc_entry_i (gc.c)
285-
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
286-
VM_ASSERT(vm_ccs_p(ccs));
287-
#if VM_CHECK_MODE > 0
288-
VALUE klass = (VALUE)data;
289-
290-
VALUE lookup_val;
291-
VM_ASSERT(rb_id_table_lookup(RCLASS_WRITABLE_CC_TBL(klass), ccs->cme->called_id, &lookup_val));
292-
VM_ASSERT(lookup_val == ccs_ptr);
293-
#endif
294-
295-
if (METHOD_ENTRY_INVALIDATED(ccs->cme)) {
296-
rb_vm_ccs_free(ccs);
297-
return ID_TABLE_DELETE;
298-
}
299-
else {
300-
rb_gc_mark_movable((VALUE)ccs->cme);
301-
302-
for (int i=0; i<ccs->len; i++) {
303-
VM_ASSERT(klass == ccs->entries[i].cc->klass);
304-
VM_ASSERT(vm_cc_check_cme(ccs->entries[i].cc, ccs->cme));
305-
306-
rb_gc_mark_movable((VALUE)ccs->entries[i].cc);
307-
}
308-
return ID_TABLE_CONTINUE;
309-
}
310-
}
311-
312-
void
313-
rb_cc_table_mark(VALUE klass)
314-
{
315-
// TODO: delete this (and cc_table_mark_i) if it's ok
316-
struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
317-
if (cc_tbl) {
318-
rb_id_table_foreach_values(cc_tbl, cc_table_mark_i, (void *)klass);
319-
}
320-
}
321-
322281
static bool
323282
moved_or_living_object_strictly_p(VALUE obj)
324283
{
@@ -576,75 +535,6 @@ rb_free_const_table(struct rb_id_table *tbl)
576535
rb_id_table_free(tbl);
577536
}
578537

579-
// alive: if false, target pointers can be freed already.
580-
static void
581-
vm_ccs_free(struct rb_class_cc_entries *ccs, int alive, VALUE klass)
582-
{
583-
if (ccs->entries) {
584-
for (int i=0; i<ccs->len; i++) {
585-
const struct rb_callcache *cc = ccs->entries[i].cc;
586-
if (!alive) {
587-
// ccs can be free'ed.
588-
if (rb_gc_pointer_to_heap_p((VALUE)cc) &&
589-
!rb_objspace_garbage_object_p((VALUE)cc) &&
590-
IMEMO_TYPE_P(cc, imemo_callcache) &&
591-
cc->klass == klass) {
592-
// OK. maybe target cc.
593-
}
594-
else {
595-
continue;
596-
}
597-
}
598-
599-
VM_ASSERT(!vm_cc_super_p(cc) && !vm_cc_refinement_p(cc));
600-
vm_cc_invalidate(cc);
601-
}
602-
ruby_xfree(ccs->entries);
603-
}
604-
ruby_xfree(ccs);
605-
}
606-
607-
void
608-
rb_vm_ccs_free(struct rb_class_cc_entries *ccs)
609-
{
610-
RB_DEBUG_COUNTER_INC(ccs_free);
611-
vm_ccs_free(ccs, true, Qundef);
612-
}
613-
614-
static enum rb_id_table_iterator_result
615-
cc_table_free_i(VALUE ccs_ptr, void *data)
616-
{
617-
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
618-
VALUE klass = (VALUE)data;
619-
VM_ASSERT(vm_ccs_p(ccs));
620-
621-
vm_ccs_free(ccs, false, klass);
622-
623-
return ID_TABLE_CONTINUE;
624-
}
625-
626-
void
627-
rb_cc_table_free(VALUE klass)
628-
{
629-
// This can be called and work well only for IClass
630-
// And classext_iclass_free uses rb_cc_tbl_free now.
631-
// TODO: remove this if it's ok
632-
struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
633-
634-
if (cc_tbl) {
635-
rb_id_table_foreach_values(cc_tbl, cc_table_free_i, (void *)klass);
636-
rb_id_table_free(cc_tbl);
637-
}
638-
}
639-
640-
void
641-
rb_cc_tbl_free(struct rb_id_table *cc_tbl, VALUE klass)
642-
{
643-
if (!cc_tbl) return;
644-
rb_id_table_foreach_values(cc_tbl, cc_table_free_i, (void *)klass);
645-
rb_id_table_free(cc_tbl);
646-
}
647-
648538
static inline void
649539
imemo_fields_free(struct rb_fields *fields)
650540
{

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
/**
@@ -265,7 +265,7 @@ static inline void RCLASS_WRITE_M_TBL_WORKAROUND(VALUE klass, struct rb_id_table
265265
static inline void RCLASS_SET_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared);
266266
static inline void RCLASS_WRITE_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared);
267267
static inline void RCLASS_WRITE_CALLABLE_M_TBL(VALUE klass, struct rb_id_table *table);
268-
static inline void RCLASS_WRITE_CC_TBL(VALUE klass, struct rb_id_table *table);
268+
static inline void RCLASS_WRITE_CC_TBL(VALUE klass, VALUE table);
269269
static inline void RCLASS_SET_CVC_TBL(VALUE klass, struct rb_id_table *table);
270270
static inline void RCLASS_WRITE_CVC_TBL(VALUE klass, struct rb_id_table *table);
271271

@@ -641,9 +641,9 @@ RCLASS_WRITE_CALLABLE_M_TBL(VALUE klass, struct rb_id_table *table)
641641
}
642642

643643
static inline void
644-
RCLASS_WRITE_CC_TBL(VALUE klass, struct rb_id_table *table)
644+
RCLASS_WRITE_CC_TBL(VALUE klass, VALUE table)
645645
{
646-
RCLASSEXT_CC_TBL(RCLASS_EXT_WRITABLE(klass)) = table;
646+
RB_OBJ_WRITE(klass, &RCLASSEXT_CC_TBL(RCLASS_EXT_WRITABLE(klass)), table);
647647
}
648648

649649
static inline void

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.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ VALUE vm_exec(rb_execution_context_t *);
6565

6666
extern const char *const rb_debug_counter_names[];
6767

68+
static VALUE vm_cc_table_create(size_t capa);
69+
6870
PUREFUNC(static inline const VALUE *VM_EP_LEP(const VALUE *));
6971
static inline const VALUE *
7072
VM_EP_LEP(const VALUE *ep)

0 commit comments

Comments
 (0)