From 9a007ccdbe90c884f2c0a150515d10ea19ccd38e Mon Sep 17 00:00:00 2001 From: Kenneth Myhra Date: Sun, 30 Jul 2023 18:34:56 +0200 Subject: [PATCH] LibWeb: Serialize strings into a more storage efficient format This patch changes the way StructuredSerializeInternal() serialize strings by storing four bytes into a 32-bit entry, instead of one code point per 32-bit entry. StructuredDeserialize() has also been changed to deserialize strings by the same ruleset. --- .../LibWeb/HTML/StructuredSerialize.cpp | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp index a76073f9d06..ce41317445c 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -148,12 +149,22 @@ private: WebIDL::ExceptionOr serialize_string(Vector& vector, String const& string) { - u64 const size = string.code_points().length(); + u64 const size = string.code_points().byte_length(); // Append size of the string to the serialized structure. TRY_OR_THROW_OOM(m_vm, vector.try_append(bit_cast(&size), 2)); - for (auto code_point : string.code_points()) { - // Append each code point to the serialized structure. - TRY_OR_THROW_OOM(m_vm, vector.try_append(code_point)); + // Append the bytes of the string to the serialized structure. + u64 byte_position = 0; + ReadonlyBytes const bytes = { string.code_points().bytes(), string.code_points().byte_length() }; + while (byte_position < size) { + u32 combined_value = 0; + for (u8 i = 0; i < 4; ++i) { + u8 const byte = bytes[byte_position]; + combined_value |= byte << (i * 8); + byte_position++; + if (byte_position == size) + break; + } + TRY_OR_THROW_OOM(m_vm, vector.try_append(combined_value)); } return {}; } @@ -271,11 +282,18 @@ private: size_bits[1] = vector[position++]; u64 const size = *bit_cast(&size_bits); - u8 bits[size]; - for (u32 i = 0; i < size; ++i) - bits[i] = vector[position++]; - - ReadonlyBytes const bytes = { bits, size }; + Vector bytes; + TRY_OR_THROW_OOM(vm, bytes.try_ensure_capacity(size)); + u64 byte_position = 0; + while (position < vector.size()) { + for (u8 i = 0; i < 4; ++i) { + bytes.append(vector[position] >> (i * 8) & 0xFF); + byte_position++; + if (byte_position == size) + break; + } + position++; + } return TRY(Bindings::throw_dom_exception_if_needed(vm, [&vm, &bytes]() { return JS::PrimitiveString::create(vm, StringView { bytes });