diff options
author | Jean Boussier <[email protected]> | 2024-08-08 12:14:50 +0200 |
---|---|---|
committer | Jean Boussier <[email protected]> | 2024-08-09 15:20:58 +0200 |
commit | af44af238befeed20cc2606ea2b440e16d341213 (patch) | |
tree | cfcc77efd3dfe6da305a8588b0cea1ee0d4ae708 | |
parent | f57167d3380b6351a915e3e4e0c04c799bd151bd (diff) |
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.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/11350
-rw-r--r-- | string.c | 27 |
1 files changed, 19 insertions, 8 deletions
@@ -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 |