From c568944b8f49074eb41495dd4c17508cd0eada14 Mon Sep 17 00:00:00 2001 From: Scott Myron Date: Sun, 19 Apr 2026 22:49:05 -0500 Subject: [PATCH] [ruby/json] Force ensure_valid_encoding to be inlined. And move the encoding convertion logic in another function with NOINLINE. The overwelming majority of strings are correctly encoded, so we want to inline the very cheap check, however we don't want to inline the much larger piece of code required to re-encode the string. https://github.com/ruby/json/commit/cfbe356b4f Co-Authored-By: Jean Boussier --- ext/json/generator/generator.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 04cc6e7b852677..882d47a61102ec 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -842,12 +842,8 @@ static inline bool valid_json_string_p(VALUE str) return false; } -static inline VALUE ensure_valid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key) +NOINLINE(static) VALUE convert_invalid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key) { - if (RB_LIKELY(valid_json_string_p(str))) { - return str; - } - if (!as_json_called && data->state->strict && RTEST(data->state->as_json)) { VALUE coerced_str = json_call_as_json(data->state, str, Qfalse); if (coerced_str != str) { @@ -883,6 +879,16 @@ static inline VALUE ensure_valid_encoding(struct generate_json_data *data, VALUE return rb_rescue(encode_json_string_try, str, encode_json_string_rescue, str); } +ALWAYS_INLINE(static) VALUE ensure_valid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key) +{ + if (RB_LIKELY(valid_json_string_p(str))) { + return str; + } + else { + return convert_invalid_encoding(data, str, as_json_called, is_key); + } +} + static void raw_generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj) { fbuffer_append_char(buffer, '"');