From b85b8ca3508a37b13133fcc15d5cdc6ef16997f8 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Mon, 9 Aug 2021 18:00:38 -0400 Subject: [PATCH] LibJS: Reduce UTF-8 to UTF-16 transcoding when only UTF-16 is wanted When appending two strings together to form a new string, if both of the strings are already UTF-16, create the new string as UTF-16 as well. This shaves about 0.5 seconds off the following test262 test: RegExp/property-escapes/generated/General_Category_-_Decimal_Number.js --- .../Libraries/LibJS/Runtime/PrimitiveString.h | 2 ++ Userland/Libraries/LibJS/Runtime/Value.cpp | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/Userland/Libraries/LibJS/Runtime/PrimitiveString.h b/Userland/Libraries/LibJS/Runtime/PrimitiveString.h index 5f27e63b50..dd15cb4d49 100644 --- a/Userland/Libraries/LibJS/Runtime/PrimitiveString.h +++ b/Userland/Libraries/LibJS/Runtime/PrimitiveString.h @@ -22,9 +22,11 @@ public: PrimitiveString& operator=(PrimitiveString const&) = delete; String const& string() const; + bool has_utf8_string() const { return m_has_utf8_string; } Utf16String const& utf16_string() const; Utf16View utf16_string_view() const; + bool has_utf16_string() const { return m_has_utf16_string; } private: virtual const char* class_name() const override { return "PrimitiveString"; } diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index db3e22cb9c..eb8416fadd 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -1100,6 +1100,21 @@ Value add(GlobalObject& global_object, Value lhs, Value rhs) if (vm.exception()) return {}; + if (lhs_primitive.is_string() && rhs_primitive.is_string()) { + auto const& lhs_string = lhs_primitive.as_string(); + auto const& rhs_string = rhs_primitive.as_string(); + + if (lhs_string.has_utf16_string() && rhs_string.has_utf16_string()) { + auto const& lhs_utf16_string = lhs_string.utf16_string(); + auto const& rhs_utf16_string = rhs_string.utf16_string(); + + Vector combined; + combined.ensure_capacity(lhs_utf16_string.length_in_code_units() + rhs_utf16_string.length_in_code_units()); + combined.extend(lhs_utf16_string.string()); + combined.extend(rhs_utf16_string.string()); + return js_string(vm.heap(), Utf16String(move(combined))); + } + } if (lhs_primitive.is_string() || rhs_primitive.is_string()) { auto lhs_string = lhs_primitive.to_string(global_object); if (vm.exception())