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
This commit is contained in:
Jean Boussier 2020-08-19 11:29:54 +02:00 committed by Aaron Patterson
parent 7f0ea20581
commit aaf0e33c0a
Notes: git 2020-08-20 00:09:32 +09:00
2 changed files with 18 additions and 1 deletions

View File

@ -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);

View File

@ -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)