@@ -22,20 +22,18 @@ static inline rb_method_entry_t *lookup_method_table(VALUE klass, ID id);
2222#define ruby_running (GET_VM()->running)
2323/* int ruby_running = 0; */
2424
25- // alive: if false, target pointers can be freed already.
2625static void
27- vm_ccs_free (struct rb_class_cc_entries * ccs , int alive , VALUE klass )
26+ vm_ccs_free (struct rb_class_cc_entries * ccs , bool invalidate_ccs )
2827{
2928 if (ccs -> entries ) {
3029 for (int i = 0 ; i < ccs -> len ; i ++ ) {
3130 const struct rb_callcache * cc = ccs -> entries [i ].cc ;
32- if (!alive ) {
33- // ccs can be free'ed.
31+ if (invalidate_ccs ) {
3432 if (rb_gc_pointer_to_heap_p ((VALUE )cc ) &&
3533 !rb_objspace_garbage_object_p ((VALUE )cc ) &&
3634 IMEMO_TYPE_P (cc , imemo_callcache ) &&
37- cc -> klass == klass ) {
38- // OK. maybe target cc.
35+ cc -> klass == ccs -> klass ) {
36+ // can be invalidated
3937 }
4038 else {
4139 continue ;
5452rb_vm_ccs_free (struct rb_class_cc_entries * ccs )
5553{
5654 RB_DEBUG_COUNTER_INC (ccs_free );
57- vm_ccs_free (ccs , true, Qundef );
55+ vm_ccs_free (ccs , false); // don't invalidate callcaches
5856}
5957
6058static enum rb_id_table_iterator_result
@@ -72,6 +70,7 @@ mark_cc_entry_i(VALUE ccs_ptr, void *data)
7270 rb_gc_mark_movable ((VALUE )ccs -> cme );
7371
7472 for (int i = 0 ; i < ccs -> len ; i ++ ) {
73+ VM_ASSERT (ccs -> klass == ccs -> entries [i ].cc -> klass );
7574 VM_ASSERT (vm_cc_check_cme (ccs -> entries [i ].cc , ccs -> cme ));
7675
7776 rb_gc_mark_movable ((VALUE )ccs -> entries [i ].cc );
@@ -95,7 +94,7 @@ cc_table_free_i(VALUE ccs_ptr, void *data)
9594 struct rb_class_cc_entries * ccs = (struct rb_class_cc_entries * )ccs_ptr ;
9695 VM_ASSERT (vm_ccs_p (ccs ));
9796
98- rb_vm_ccs_free (ccs );
97+ vm_ccs_free (ccs , true); // invalidate callcaches
9998
10099 return ID_TABLE_CONTINUE ;
101100}
0 commit comments