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.
This commit is contained in:
Kenneth Myhra 2023-07-30 18:34:56 +02:00 committed by Andreas Kling
parent 4cde5f6d76
commit 9a007ccdbe
Notes: sideshowbarker 2024-07-17 12:02:22 +09:00

View File

@ -7,6 +7,7 @@
*/ */
#include <AK/HashTable.h> #include <AK/HashTable.h>
#include <AK/StdLibExtras.h>
#include <AK/String.h> #include <AK/String.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibJS/Forward.h> #include <LibJS/Forward.h>
@ -148,12 +149,22 @@ private:
WebIDL::ExceptionOr<void> serialize_string(Vector<u32>& vector, String const& string) WebIDL::ExceptionOr<void> serialize_string(Vector<u32>& 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. // Append size of the string to the serialized structure.
TRY_OR_THROW_OOM(m_vm, vector.try_append(bit_cast<u32*>(&size), 2)); TRY_OR_THROW_OOM(m_vm, vector.try_append(bit_cast<u32*>(&size), 2));
for (auto code_point : string.code_points()) { // Append the bytes of the string to the serialized structure.
// Append each code point to the serialized structure. u64 byte_position = 0;
TRY_OR_THROW_OOM(m_vm, vector.try_append(code_point)); 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 {}; return {};
} }
@ -271,11 +282,18 @@ private:
size_bits[1] = vector[position++]; size_bits[1] = vector[position++];
u64 const size = *bit_cast<u64*>(&size_bits); u64 const size = *bit_cast<u64*>(&size_bits);
u8 bits[size]; Vector<u8> bytes;
for (u32 i = 0; i < size; ++i) TRY_OR_THROW_OOM(vm, bytes.try_ensure_capacity(size));
bits[i] = vector[position++]; u64 byte_position = 0;
while (position < vector.size()) {
ReadonlyBytes const bytes = { bits, 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 TRY(Bindings::throw_dom_exception_if_needed(vm, [&vm, &bytes]() {
return JS::PrimitiveString::create(vm, StringView { bytes }); return JS::PrimitiveString::create(vm, StringView { bytes });