summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'string.c')
-rw-r--r--string.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/string.c b/string.c
index f3f5ea92cc..f5e089aa21 100644
--- a/string.c
+++ b/string.c
@@ -3329,9 +3329,24 @@ VALUE
rb_str_buf_append(VALUE str, VALUE str2)
{
int str2_cr = rb_enc_str_coderange(str2);
- if (str2_cr == ENC_CODERANGE_7BIT && str_enc_fastpath(str)) {
- str_buf_cat4(str, RSTRING_PTR(str2), RSTRING_LEN(str2), true);
- return str;
+
+ if (str_enc_fastpath(str)) {
+ switch (str2_cr) {
+ case ENC_CODERANGE_7BIT:
+ // If RHS is 7bit we can do simple concatenation
+ str_buf_cat4(str, RSTRING_PTR(str2), RSTRING_LEN(str2), true);
+ return str;
+ case ENC_CODERANGE_VALID:
+ // If RHS is valid, we can do simple concatenation if encodings are the same
+ if (ENCODING_GET_INLINED(str) == ENCODING_GET_INLINED(str2)) {
+ str_buf_cat4(str, RSTRING_PTR(str2), RSTRING_LEN(str2), true);
+ int str_cr = ENC_CODERANGE(str);
+ if (UNLIKELY(str_cr != ENC_CODERANGE_VALID)) {
+ ENC_CODERANGE_SET(str, RB_ENC_CODERANGE_AND(str_cr, str2_cr));
+ }
+ return str;
+ }
+ }
}
rb_enc_cr_str_buf_cat(str, RSTRING_PTR(str2), RSTRING_LEN(str2),