Browse Source

AK: Replace ByteBuffer::grow with resize()/ensure_capacity()

Previously ByteBuffer::grow() behaved like Vector<T>::resize().
However the function name was somewhat ambiguous - and so this patch
updates ByteBuffer to behave more like Vector<T> by replacing grow()
with resize() and adding an ensure_capacity() method.

This also lets the user change the buffer's capacity without affecting
the size which was not previously possible.

Additionally this patch makes the capacity() method public (again).
Gunnar Beutner 4 năm trước cách đây
mục cha
commit
5f18cf75c5

+ 35 - 24
AK/ByteBuffer.h

@@ -26,7 +26,7 @@ public:
 
 
     ByteBuffer(ByteBuffer const& other)
     ByteBuffer(ByteBuffer const& other)
     {
     {
-        grow(other.size());
+        resize(other.size());
         VERIFY(m_size == other.size());
         VERIFY(m_size == other.size());
         __builtin_memcpy(data(), other.data(), other.size());
         __builtin_memcpy(data(), other.data(), other.size());
     }
     }
@@ -39,7 +39,7 @@ public:
     ByteBuffer& operator=(ByteBuffer&& other)
     ByteBuffer& operator=(ByteBuffer&& other)
     {
     {
         if (this != &other) {
         if (this != &other) {
-            if (!is_inline())
+            if (!m_inline)
                 kfree(m_outline_buffer);
                 kfree(m_outline_buffer);
             move_from(move(other));
             move_from(move(other));
         }
         }
@@ -52,7 +52,7 @@ public:
             if (m_size > other.size())
             if (m_size > other.size())
                 internal_trim(other.size(), true);
                 internal_trim(other.size(), true);
             else
             else
-                grow(other.size());
+                resize(other.size());
             __builtin_memcpy(data(), other.data(), other.size());
             __builtin_memcpy(data(), other.data(), other.size());
         }
         }
         return *this;
         return *this;
@@ -111,8 +111,8 @@ public:
     [[nodiscard]] bool is_empty() const { return !m_size; }
     [[nodiscard]] bool is_empty() const { return !m_size; }
     [[nodiscard]] size_t size() const { return m_size; }
     [[nodiscard]] size_t size() const { return m_size; }
 
 
-    [[nodiscard]] u8* data() { return is_inline() ? m_inline_buffer : m_outline_buffer; }
-    [[nodiscard]] u8 const* data() const { return is_inline() ? m_inline_buffer : m_outline_buffer; }
+    [[nodiscard]] u8* data() { return m_inline ? m_inline_buffer : m_outline_buffer; }
+    [[nodiscard]] u8 const* data() const { return m_inline ? m_inline_buffer : m_outline_buffer; }
 
 
     [[nodiscard]] Bytes bytes() { return { data(), size() }; }
     [[nodiscard]] Bytes bytes() { return { data(), size() }; }
     [[nodiscard]] ReadonlyBytes bytes() const { return { data(), size() }; }
     [[nodiscard]] ReadonlyBytes bytes() const { return { data(), size() }; }
@@ -141,20 +141,28 @@ public:
 
 
     void clear()
     void clear()
     {
     {
-        if (!is_inline())
+        if (!m_inline) {
             kfree(m_outline_buffer);
             kfree(m_outline_buffer);
+            m_inline = true;
+        }
         m_size = 0;
         m_size = 0;
     }
     }
 
 
-    ALWAYS_INLINE void grow(size_t new_size)
+    ALWAYS_INLINE void resize(size_t new_size)
     {
     {
-        if (new_size <= m_size)
-            return;
-        if (new_size <= capacity()) {
-            m_size = new_size;
+        if (new_size <= m_size) {
+            trim(new_size);
             return;
             return;
         }
         }
-        grow_slowpath(new_size);
+        ensure_capacity(new_size);
+        m_size = new_size;
+    }
+
+    ALWAYS_INLINE void ensure_capacity(size_t new_capacity)
+    {
+        if (new_capacity <= capacity())
+            return;
+        ensure_capacity_slowpath(new_capacity);
     }
     }
 
 
     void append(void const* data, size_t data_size)
     void append(void const* data, size_t data_size)
@@ -163,7 +171,7 @@ public:
             return;
             return;
         VERIFY(data != nullptr);
         VERIFY(data != nullptr);
         int old_size = size();
         int old_size = size();
-        grow(size() + data_size);
+        resize(size() + data_size);
         __builtin_memcpy(this->data() + old_size, data, data_size);
         __builtin_memcpy(this->data() + old_size, data, data_size);
     }
     }
 
 
@@ -187,42 +195,47 @@ public:
     operator Bytes() { return bytes(); }
     operator Bytes() { return bytes(); }
     operator ReadonlyBytes() const { return bytes(); }
     operator ReadonlyBytes() const { return bytes(); }
 
 
+    ALWAYS_INLINE size_t capacity() const { return m_inline ? inline_capacity : m_outline_capacity; }
+
 private:
 private:
     ByteBuffer(size_t size)
     ByteBuffer(size_t size)
     {
     {
-        grow(size);
+        resize(size);
         VERIFY(m_size == size);
         VERIFY(m_size == size);
     }
     }
 
 
     void move_from(ByteBuffer&& other)
     void move_from(ByteBuffer&& other)
     {
     {
         m_size = other.m_size;
         m_size = other.m_size;
-        if (other.m_size > inline_capacity) {
+        m_inline = other.m_inline;
+        if (!other.m_inline) {
             m_outline_buffer = other.m_outline_buffer;
             m_outline_buffer = other.m_outline_buffer;
             m_outline_capacity = other.m_outline_capacity;
             m_outline_capacity = other.m_outline_capacity;
         } else
         } else
             __builtin_memcpy(m_inline_buffer, other.m_inline_buffer, other.m_size);
             __builtin_memcpy(m_inline_buffer, other.m_inline_buffer, other.m_size);
         other.m_size = 0;
         other.m_size = 0;
+        other.m_inline = true;
     }
     }
 
 
     void internal_trim(size_t size, bool may_discard_existing_data)
     void internal_trim(size_t size, bool may_discard_existing_data)
     {
     {
         VERIFY(size <= m_size);
         VERIFY(size <= m_size);
-        if (!is_inline() && size <= inline_capacity) {
+        if (!m_inline && size <= inline_capacity) {
             // m_inline_buffer and m_outline_buffer are part of a union, so save the pointer
             // m_inline_buffer and m_outline_buffer are part of a union, so save the pointer
             auto outline_buffer = m_outline_buffer;
             auto outline_buffer = m_outline_buffer;
             if (!may_discard_existing_data)
             if (!may_discard_existing_data)
                 __builtin_memcpy(m_inline_buffer, outline_buffer, size);
                 __builtin_memcpy(m_inline_buffer, outline_buffer, size);
             kfree(outline_buffer);
             kfree(outline_buffer);
+            m_inline = true;
         }
         }
         m_size = size;
         m_size = size;
     }
     }
 
 
-    NEVER_INLINE void grow_slowpath(size_t new_size)
+    NEVER_INLINE void ensure_capacity_slowpath(size_t new_capacity)
     {
     {
         u8* new_buffer;
         u8* new_buffer;
-        auto new_capacity = kmalloc_good_size(new_size);
-        if (!is_inline()) {
+        new_capacity = kmalloc_good_size(new_capacity);
+        if (!m_inline) {
             new_buffer = (u8*)krealloc(m_outline_buffer, new_capacity);
             new_buffer = (u8*)krealloc(m_outline_buffer, new_capacity);
             VERIFY(new_buffer);
             VERIFY(new_buffer);
         } else {
         } else {
@@ -232,13 +245,9 @@ private:
         }
         }
         m_outline_buffer = new_buffer;
         m_outline_buffer = new_buffer;
         m_outline_capacity = new_capacity;
         m_outline_capacity = new_capacity;
-        m_size = new_size;
+        m_inline = false;
     }
     }
 
 
-    ALWAYS_INLINE bool is_inline() const { return m_size <= inline_capacity; }
-    ALWAYS_INLINE size_t capacity() const { return is_inline() ? inline_capacity : m_outline_capacity; }
-
-    size_t m_size { 0 };
     union {
     union {
         u8 m_inline_buffer[inline_capacity];
         u8 m_inline_buffer[inline_capacity];
         struct {
         struct {
@@ -246,6 +255,8 @@ private:
             size_t m_outline_capacity;
             size_t m_outline_capacity;
         };
         };
     };
     };
+    size_t m_size { 0 };
+    bool m_inline { true };
 };
 };
 
 
 }
 }

+ 1 - 1
AK/StringBuilder.cpp

@@ -26,7 +26,7 @@ inline void StringBuilder::will_append(size_t size)
     if (needed_capacity > inline_capacity)
     if (needed_capacity > inline_capacity)
         expanded_capacity *= 2;
         expanded_capacity *= 2;
     VERIFY(!expanded_capacity.has_overflow());
     VERIFY(!expanded_capacity.has_overflow());
-    m_buffer.grow(expanded_capacity.value());
+    m_buffer.resize(expanded_capacity.value());
 }
 }
 
 
 StringBuilder::StringBuilder(size_t initial_capacity)
 StringBuilder::StringBuilder(size_t initial_capacity)

+ 1 - 1
Meta/Lagom/Fuzzers/FuzzilliJs.cpp

@@ -207,7 +207,7 @@ int main(int, char**)
         VERIFY(script_size < REPRL_MAX_DATA_SIZE);
         VERIFY(script_size < REPRL_MAX_DATA_SIZE);
         ByteBuffer data_buffer;
         ByteBuffer data_buffer;
         if (data_buffer.size() < script_size)
         if (data_buffer.size() < script_size)
-            data_buffer.grow(script_size - data_buffer.size());
+            data_buffer.resize(script_size - data_buffer.size());
         VERIFY(data_buffer.size() >= script_size);
         VERIFY(data_buffer.size() >= script_size);
         memcpy(data_buffer.data(), reprl_input, script_size);
         memcpy(data_buffer.data(), reprl_input, script_size);
 
 

+ 1 - 2
Userland/Libraries/LibCrypto/NumberTheory/ModularFunctions.cpp

@@ -165,8 +165,7 @@ UnsignedBigInteger random_number(const UnsignedBigInteger& min, const UnsignedBi
     UnsignedBigInteger base;
     UnsignedBigInteger base;
     auto size = range.trimmed_length() * sizeof(u32) + 2;
     auto size = range.trimmed_length() * sizeof(u32) + 2;
     // "+2" is intentional (see below).
     // "+2" is intentional (see below).
-    ByteBuffer buffer;
-    buffer.grow(size);
+    auto buffer = ByteBuffer::create_uninitialized(size);
     auto* buf = buffer.data();
     auto* buf = buffer.data();
 
 
     fill_with_random(buf, size);
     fill_with_random(buf, size);

+ 1 - 2
Userland/Libraries/LibTLS/HandshakeClient.cpp

@@ -117,8 +117,7 @@ bool TLSv12::compute_master_secret_from_pre_master_secret(size_t length)
         return false;
         return false;
     }
     }
 
 
-    m_context.master_key.clear();
-    m_context.master_key.grow(length);
+    m_context.master_key.resize(length);
 
 
     pseudorandom_function(
     pseudorandom_function(
         m_context.master_key,
         m_context.master_key,

+ 1 - 1
Userland/Libraries/LibTLS/TLSPacketBuilder.h

@@ -75,7 +75,7 @@ public:
         m_current_length += bytes;
         m_current_length += bytes;
 
 
         if (m_packet_data.size() < m_current_length) {
         if (m_packet_data.size() < m_current_length) {
-            m_packet_data.grow(m_current_length);
+            m_packet_data.resize(m_current_length);
         }
         }
 
 
         m_packet_data.overwrite(old_length, data, bytes);
         m_packet_data.overwrite(old_length, data, bytes);

+ 1 - 1
Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h

@@ -332,7 +332,7 @@ public:
         if (m_type.limits().max().value_or(new_size) < new_size)
         if (m_type.limits().max().value_or(new_size) < new_size)
             return false;
             return false;
         auto previous_size = m_size;
         auto previous_size = m_size;
-        m_data.grow(new_size);
+        m_data.resize(new_size);
         m_size = new_size;
         m_size = new_size;
         // The spec requires that we zero out everything on grow
         // The spec requires that we zero out everything on grow
         __builtin_memset(m_data.offset_pointer(previous_size), 0, size_to_grow);
         __builtin_memset(m_data.offset_pointer(previous_size), 0, size_to_grow);