From f05100ee33462a2816a757b6b2a58608349845c0 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Wed, 20 Aug 2025 17:47:17 -0700 Subject: [PATCH] Only set ME cached flag when unset The same method entry may be reused in multiple caches, so once the CACHED flag is set, other Ractors may be checking for it being invalidated and we should avoid writing to the field again. I believe there are still other race conditions on how we manipulate these flags (particularly the invalidation bit), but this should make them less frequent. --- method.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/method.h b/method.h index 8328b86ee96102..9e2fd249683c0c 100644 --- a/method.h +++ b/method.h @@ -73,10 +73,17 @@ typedef struct rb_callable_method_entry_struct { /* same fields with rb_method_e #define METHOD_ENTRY_COMPLEMENTED(me) ((me)->flags & IMEMO_FL_USER3) #define METHOD_ENTRY_COMPLEMENTED_SET(me) ((me)->flags |= IMEMO_FL_USER3) #define METHOD_ENTRY_CACHED(me) ((me)->flags & IMEMO_FL_USER4) -#define METHOD_ENTRY_CACHED_SET(me) ((me)->flags |= IMEMO_FL_USER4) #define METHOD_ENTRY_INVALIDATED(me) ((me)->flags & IMEMO_FL_USER5) #define METHOD_ENTRY_INVALIDATED_SET(me) ((me)->flags |= IMEMO_FL_USER5) +static inline void +METHOD_ENTRY_CACHED_SET(rb_callable_method_entry_t *me) +{ + if (!METHOD_ENTRY_CACHED(me)) { + me->flags |= IMEMO_FL_USER4; + } +} + static inline void METHOD_ENTRY_VISI_SET(rb_method_entry_t *me, rb_method_visibility_t visi) {