ソースを参照

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.
Kenneth Myhra 1 年間 前
コミット
9a007ccdbe
1 ファイル変更27 行追加9 行削除
  1. 27 9
      Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp

+ 27 - 9
Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp

@@ -7,6 +7,7 @@
  */
 
 #include <AK/HashTable.h>
+#include <AK/StdLibExtras.h>
 #include <AK/String.h>
 #include <AK/Vector.h>
 #include <LibJS/Forward.h>
@@ -148,12 +149,22 @@ private:
 
     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.
         TRY_OR_THROW_OOM(m_vm, vector.try_append(bit_cast<u32*>(&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<u64*>(&size_bits);
 
-        u8 bits[size];
-        for (u32 i = 0; i < size; ++i)
-            bits[i] = vector[position++];
-
-        ReadonlyBytes const bytes = { bits, size };
+        Vector<u8> 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 });