Skip to content

Commit a55cc8b

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

7 files changed

Lines changed: 136 additions & 198 deletions

File tree

gc.c

Lines changed: 4 additions & 95 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);
@@ -2808,42 +2782,6 @@ struct mark_cc_entry_args {
28082782
VALUE klass;
28092783
};
28102784

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-
28472785
static enum rb_id_table_iterator_result
28482786
mark_cvc_tbl_i(VALUE cvc_entry, void *objspace)
28492787
{
@@ -3081,7 +3019,6 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE namespace, void *a
30813019
{
30823020
struct gc_mark_classext_foreach_arg *foreach_arg = (struct gc_mark_classext_foreach_arg *)arg;
30833021
rb_objspace_t *objspace = foreach_arg->objspace;
3084-
VALUE obj = foreach_arg->obj;
30853022

30863023
if (RCLASSEXT_SUPER(ext)) {
30873024
gc_mark_internal(RCLASSEXT_SUPER(ext));
@@ -3092,7 +3029,7 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE namespace, void *a
30923029
mark_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
30933030
}
30943031
mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
3095-
mark_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext), obj);
3032+
gc_mark_internal(RCLASSEXT_CC_TBL(ext));
30963033
mark_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext));
30973034
gc_mark_internal(RCLASSEXT_CLASSPATH(ext));
30983035
}
@@ -3102,7 +3039,6 @@ gc_mark_classext_iclass(rb_classext_t *ext, bool prime, VALUE namespace, void *a
31023039
{
31033040
struct gc_mark_classext_foreach_arg *foreach_arg = (struct gc_mark_classext_foreach_arg *)arg;
31043041
rb_objspace_t *objspace = foreach_arg->objspace;
3105-
VALUE iclass = foreach_arg->obj;
31063042

31073043
if (RCLASSEXT_SUPER(ext)) {
31083044
gc_mark_internal(RCLASSEXT_SUPER(ext));
@@ -3114,7 +3050,7 @@ gc_mark_classext_iclass(rb_classext_t *ext, bool prime, VALUE namespace, void *a
31143050
gc_mark_internal(RCLASSEXT_INCLUDER(ext));
31153051
}
31163052
mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
3117-
mark_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext), iclass);
3053+
gc_mark_internal(RCLASSEXT_CC_TBL(ext));
31183054
}
31193055

31203056
#define TYPED_DATA_REFS_OFFSET_LIST(d) (size_t *)(uintptr_t)RTYPEDDATA_TYPE(d)->function.dmark
@@ -3679,33 +3615,6 @@ update_m_tbl(void *objspace, struct rb_id_table *tbl)
36793615
}
36803616
}
36813617

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-
37093618
static enum rb_id_table_iterator_result
37103619
update_cvc_tbl_i(VALUE cvc_entry, void *objspace)
37113620
{
@@ -3804,7 +3713,7 @@ update_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
38043713
if (!RCLASSEXT_SHARED_CONST_TBL(ext)) {
38053714
update_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
38063715
}
3807-
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
3716+
UPDATE_IF_MOVED(objspace, RCLASSEXT_CC_TBL(ext));
38083717
update_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext));
38093718
update_superclasses(objspace, ext);
38103719
update_subclasses(objspace, ext);
@@ -3823,7 +3732,7 @@ update_iclass_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void
38233732
}
38243733
update_m_tbl(objspace, RCLASSEXT_M_TBL(ext));
38253734
update_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
3826-
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
3735+
UPDATE_IF_MOVED(objspace, RCLASSEXT_CC_TBL(ext));
38273736
update_subclasses(objspace, ext);
38283737

38293738
update_classext_values(objspace, ext, true);

imemo.c

Lines changed: 0 additions & 75 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
{
@@ -611,40 +570,6 @@ rb_vm_ccs_free(struct rb_class_cc_entries *ccs)
611570
vm_ccs_free(ccs, true, Qundef);
612571
}
613572

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-
648573
static inline void
649574
imemo_fields_free(struct rb_fields *fields)
650575
{

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)

vm_insnhelper.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,7 +1982,7 @@ static VALUE vm_call_general(rb_execution_context_t *ec, rb_control_frame_t *reg
19821982
static VALUE vm_mtbl_dump(VALUE klass, ID target_mid);
19831983

19841984
static struct rb_class_cc_entries *
1985-
vm_ccs_create(VALUE klass, struct rb_id_table *cc_tbl, ID mid, const rb_callable_method_entry_t *cme)
1985+
vm_ccs_create(VALUE klass, VALUE cc_tbl, ID mid, const rb_callable_method_entry_t *cme)
19861986
{
19871987
struct rb_class_cc_entries *ccs = ALLOC(struct rb_class_cc_entries);
19881988
#if VM_CHECK_MODE > 0
@@ -1994,7 +1994,8 @@ vm_ccs_create(VALUE klass, struct rb_id_table *cc_tbl, ID mid, const rb_callable
19941994
METHOD_ENTRY_CACHED_SET((rb_callable_method_entry_t *)cme);
19951995
ccs->entries = NULL;
19961996

1997-
rb_id_table_insert(cc_tbl, mid, (VALUE)ccs);
1997+
rb_managed_id_table_insert(cc_tbl, mid, (VALUE)ccs);
1998+
RB_OBJ_WRITTEN(cc_tbl, Qundef, cme);
19981999
RB_OBJ_WRITTEN(klass, Qundef, cme);
19992000
return ccs;
20002001
}
@@ -2067,20 +2068,20 @@ static const struct rb_callcache *
20672068
vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
20682069
{
20692070
const ID mid = vm_ci_mid(ci);
2070-
struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
2071+
VALUE cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
20712072
struct rb_class_cc_entries *ccs = NULL;
20722073
VALUE ccs_data;
20732074

20742075
if (cc_tbl) {
20752076
// CCS data is keyed on method id, so we don't need the method id
20762077
// for doing comparisons in the `for` loop below.
2077-
if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
2078+
if (rb_managed_id_table_lookup(cc_tbl, mid, &ccs_data)) {
20782079
ccs = (struct rb_class_cc_entries *)ccs_data;
20792080
const int ccs_len = ccs->len;
20802081

20812082
if (UNLIKELY(METHOD_ENTRY_INVALIDATED(ccs->cme))) {
20822083
rb_vm_ccs_free(ccs);
2083-
rb_id_table_delete(cc_tbl, mid);
2084+
rb_managed_id_table_delete(cc_tbl, mid);
20842085
ccs = NULL;
20852086
}
20862087
else {
@@ -2113,7 +2114,7 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
21132114
}
21142115
}
21152116
else {
2116-
cc_tbl = rb_id_table_create(2);
2117+
cc_tbl = vm_cc_table_create(2);
21172118
RCLASS_WRITE_CC_TBL(klass, cc_tbl);
21182119
}
21192120

@@ -2144,9 +2145,9 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
21442145
METHOD_ENTRY_CACHED_SET((struct rb_callable_method_entry_struct *)cme);
21452146

21462147
if (ccs == NULL) {
2147-
VM_ASSERT(cc_tbl != NULL);
2148+
VM_ASSERT(cc_tbl != 0);
21482149

2149-
if (LIKELY(rb_id_table_lookup(cc_tbl, mid, &ccs_data))) {
2150+
if (LIKELY(rb_managed_id_table_lookup(cc_tbl, mid, &ccs_data))) {
21502151
// rb_callable_method_entry() prepares ccs.
21512152
ccs = (struct rb_class_cc_entries *)ccs_data;
21522153
}
@@ -2160,6 +2161,7 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
21602161

21612162
const struct rb_callcache *cc = vm_cc_new(klass, cme, vm_call_general, cc_type_normal);
21622163
vm_ccs_push(klass, ccs, ci, cc);
2164+
RB_OBJ_WRITTEN(cc_tbl, Qundef, cc);
21632165

21642166
VM_ASSERT(vm_cc_cme(cc) != NULL);
21652167
VM_ASSERT(cme->called_id == mid);

0 commit comments

Comments
 (0)