From aaf0e33c0a45e13d27e1009c7298fcb0a57c0d4f Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 19 Aug 2020 11:29:54 +0200 Subject: [PATCH] register_fstring: avoid duping the passed string when possible If the passed string is frozen, bare and not shared, then there is no need to duplicate it. Ref: 4ab69ebbd7cef8539f687e1f948845d076461dc6 Ref: https://bugs.ruby-lang.org/issues/11386 --- string.c | 3 ++- test/ruby/test_string.rb | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/string.c b/string.c index 1a1b9fd6ed..df7e81410a 100644 --- a/string.c +++ b/string.c @@ -305,7 +305,8 @@ fstr_update_callback(st_data_t *key, st_data_t *value, st_data_t arg, int existi OBJ_FREEZE_RAW(str); } else { - str = str_new_frozen(rb_cString, str); + if (!OBJ_FROZEN(str)) + str = str_new_frozen(rb_cString, str); if (STR_SHARED_P(str)) { /* str should not be shared */ /* shared substring */ str_make_independent(str); diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index 489eee33dc..529b1be828 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -3187,6 +3187,22 @@ CODE assert_same(str, -bar, "uminus deduplicates [Feature #13077]") end + def test_uminus_frozen + # embedded + str1 = ("foobar" * 3).freeze + str2 = ("foobar" * 3).freeze + assert_not_same str1, str2 + assert_same str1, -str1 + assert_same str1, -str2 + + # regular + str1 = ("foobar" * 4).freeze + str2 = ("foobar" * 4).freeze + assert_not_same str1, str2 + assert_same str1, -str1 + assert_same str1, -str2 + end + def test_uminus_no_freeze_not_bare str = @cls.new("foo") assert_instance_of(@cls, -str)