From af44af238befeed20cc2606ea2b440e16d341213 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 8 Aug 2024 12:14:50 +0200 Subject: [PATCH] str_independent: add a fastpath with a single flag check If we assume that most strings we modify are not frozen and are independent, then we can optimize this case by replacing multiple flag checks by a single mask check. --- string.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/string.c b/string.c index 26c3aa43d6..10023d26a3 100644 --- a/string.c +++ b/string.c @@ -2500,32 +2500,43 @@ rb_check_lockedtmp(VALUE str) } } +// If none of these flags are set, we know we have an modifiable string. +// If any is set, we need to do more detailed checks. +#define STR_UNMODIFIABLE_MASK (FL_FREEZE | STR_TMPLOCK | STR_CHILLED) static inline void str_modifiable(VALUE str) { - if (CHILLED_STRING_P(str)) { - CHILLED_STRING_MUTATED(str); + if (RB_UNLIKELY(FL_ANY_RAW(str, STR_UNMODIFIABLE_MASK))) { + if (CHILLED_STRING_P(str)) { + CHILLED_STRING_MUTATED(str); + } + rb_check_lockedtmp(str); + rb_check_frozen(str); } - rb_check_lockedtmp(str); - rb_check_frozen(str); } static inline int str_dependent_p(VALUE str) { if (STR_EMBED_P(str) || !FL_TEST(str, STR_SHARED|STR_NOFREE)) { - return 0; + return FALSE; } else { - return 1; + return TRUE; } } +// If none of these flags are set, we know we have an independent string. +// If any is set, we need to do more detailed checks. +#define STR_DEPENDANT_MASK (STR_UNMODIFIABLE_MASK | STR_SHARED | STR_NOFREE) static inline int str_independent(VALUE str) { - str_modifiable(str); - return !str_dependent_p(str); + if (RB_UNLIKELY(FL_ANY_RAW(str, STR_DEPENDANT_MASK))) { + str_modifiable(str); + return !str_dependent_p(str); + } + return TRUE; } static void