@@ -340,12 +340,28 @@ rb_iseq_mark_and_move_each_body_value(const rb_iseq_t *iseq, VALUE *original_ise
340340}
341341
342342static bool
343- cc_is_active (const struct rb_callcache * cc )
343+ cc_is_active (const struct rb_callcache * cc , bool reference_updating )
344344{
345- RUBY_ASSERT (cc );
346- RUBY_ASSERT (vm_cc_markable (cc ));
345+ if (cc ) {
346+ if (cc == rb_vm_empty_cc () || cc == rb_vm_empty_cc_for_super ()) {
347+ return false;
348+ }
349+
350+ if (reference_updating ) {
351+ cc = (const struct rb_callcache * )rb_gc_location ((VALUE )cc );
352+ }
347353
348- return vm_cc_valid (cc ) && !METHOD_ENTRY_INVALIDATED (vm_cc_cme (cc ));
354+ if (vm_cc_markable (cc ) && vm_cc_valid (cc )) {
355+ const struct rb_callable_method_entry_struct * cme = vm_cc_cme (cc );
356+ if (reference_updating ) {
357+ cme = (const struct rb_callable_method_entry_struct * )rb_gc_location ((VALUE )cme );
358+ }
359+ if (!METHOD_ENTRY_INVALIDATED (cme )) {
360+ return true;
361+ }
362+ }
363+ }
364+ return false;
349365}
350366
351367void
@@ -369,30 +385,16 @@ rb_iseq_mark_and_move(rb_iseq_t *iseq, bool reference_updating)
369385 if (body -> mandatory_only_iseq ) rb_gc_mark_and_move_ptr (& body -> mandatory_only_iseq );
370386
371387 if (body -> call_data ) {
372- struct rb_call_data * cds = body -> call_data ;
373388 for (unsigned int i = 0 ; i < body -> ci_size ; i ++ ) {
389+ struct rb_call_data * cds = body -> call_data ;
374390
375391 if (cds [i ].ci ) rb_gc_mark_and_move_ptr (& cds [i ].ci );
376392
377- const struct rb_callcache * cc = cds [i ].cc ;
378- if (!cc || cc == rb_vm_empty_cc () || cc == rb_vm_empty_cc_for_super ()) {
379- // No need for marking, reference updating, or clearing
380- // We also want to avoid reassigning to improve CoW
381- continue ;
382- }
383-
384- if (reference_updating ) {
385- rb_gc_move_ptr (& cds [i ].cc );
393+ if (cc_is_active (cds [i ].cc , reference_updating )) {
394+ rb_gc_mark_and_move_ptr (& cds [i ].cc );
386395 }
387- else {
388- if (cc_is_active (cc )) {
389- rb_gc_mark_movable ((VALUE )cc );
390- }
391- else {
392- // Either the CC or CME has been invalidated. Replace
393- // it with the empty CC so that it can be GC'd.
394- cds [i ].cc = rb_vm_empty_cc ();
395- }
396+ else if (cds [i ].cc != rb_vm_empty_cc ()) {
397+ cds [i ].cc = rb_vm_empty_cc ();
396398 }
397399 }
398400 }
0 commit comments