@@ -337,28 +337,37 @@ rb_imemo_mark_and_move(VALUE obj, bool reference_updating)
337
337
* cc->klass (klass) should not be marked because if the klass is
338
338
* free'ed, the cc->klass will be cleared by `vm_cc_invalidate()`.
339
339
*
340
- * cc->cme (cme) should not be marked because if cc is invalidated
341
- * when cme is free'ed .
340
+ * For "normal" CCs cc->cme (cme) should not be marked because the cc is
341
+ * invalidated through the klass when the cme is free'd .
342
342
* - klass marks cme if klass uses cme.
343
- * - caller classe 's ccs->cme marks cc->cme.
344
- * - if cc is invalidated (klass doesn't refer the cc),
345
- * cc is invalidated by `vm_cc_invalidate()` and cc->cme is
346
- * not be accessed.
347
- * - On the multi-Ractors, cme will be collected with global GC
343
+ * - caller class 's ccs->cme marks cc->cme.
344
+ * - if cc is invalidated (klass doesn't refer the cc), cc is
345
+ * invalidated by `vm_cc_invalidate()` after which cc->cme must not
346
+ * be accessed.
347
+ * - With multi-Ractors, cme will be collected with global GC
348
348
* so that it is safe if GC is not interleaving while accessing
349
349
* cc and cme.
350
- * - However, cc_type_super and cc_type_refinement are not chained
351
- * from ccs so cc->cme should be marked; the cme might be
352
- * reachable only through cc in these cases.
350
+ *
351
+ * However cc_type_super and cc_type_refinement are not chained
352
+ * from ccs so cc->cme should be marked as long as the cc is valid;
353
+ * the cme might be reachable only through cc in these cases.
353
354
*/
354
355
struct rb_callcache * cc = (struct rb_callcache * )obj ;
355
- if (reference_updating ) {
356
+ if (UNDEF_P (cc -> klass )) {
357
+ /* If it's invalidated, we must not mark anything.
358
+ * All fields should are considered invalid
359
+ */
360
+ }
361
+ else if (reference_updating ) {
356
362
if (moved_or_living_object_strictly_p ((VALUE )cc -> cme_ )) {
357
363
* ((VALUE * )& cc -> klass ) = rb_gc_location (cc -> klass );
358
364
* ((struct rb_callable_method_entry_struct * * )& cc -> cme_ ) =
359
365
(struct rb_callable_method_entry_struct * )rb_gc_location ((VALUE )cc -> cme_ );
366
+
367
+ RUBY_ASSERT (RB_TYPE_P (cc -> klass , T_CLASS ) || RB_TYPE_P (cc -> klass , T_ICLASS ));
368
+ RUBY_ASSERT (IMEMO_TYPE_P ((VALUE )cc -> cme_ , imemo_ment ));
360
369
}
361
- else if ( vm_cc_valid ( cc )) {
370
+ else {
362
371
vm_cc_invalidate (cc );
363
372
}
364
373
}
0 commit comments