diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-05-27 10:52:46 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-27 22:39:25 +0200 |
commit | bacb2dea70d1cc5b46755dc591a50de3499c54d5 (patch) | |
tree | 7f58da3e78854036b343a4a0e12ca93b3e4200aa /AK/ByteBuffer.h | |
parent | c1a4dfeffbd8a2fcf10cfed014692f7cdaf37f50 (diff) | |
download | serenity-bacb2dea70d1cc5b46755dc591a50de3499c54d5.zip |
AK: Convince GCC that m_outline_capacity isn't being read
Previously GCC came to the conclusion that we were reading
m_outline_capacity via ByteBuffer(ByteBuffer const&) -> grow()
-> capacity() even though that could never be the case because
m_size is 0 at that point which means we have an inline buffer
and capacity() would return inline_capacity in that case without
reading m_outline_capacity.
This makes GCC inline parts of the grow() function into the
ByteBuffer copy constructor which seems sufficient for GCC to
realize that m_outline_capacity isn't actually being read.
Diffstat (limited to 'AK/ByteBuffer.h')
-rw-r--r-- | AK/ByteBuffer.h | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/AK/ByteBuffer.h b/AK/ByteBuffer.h index 124702596e..76dc9c55c8 100644 --- a/AK/ByteBuffer.h +++ b/AK/ByteBuffer.h @@ -146,7 +146,7 @@ public: m_size = 0; } - void grow(size_t new_size) + ALWAYS_INLINE void grow(size_t new_size) { if (new_size <= m_size) return; @@ -154,19 +154,7 @@ public: m_size = new_size; return; } - u8* new_buffer; - auto new_capacity = kmalloc_good_size(new_size); - if (!is_inline()) { - new_buffer = (u8*)krealloc(m_outline_buffer, new_capacity); - VERIFY(new_buffer); - } else { - new_buffer = (u8*)kmalloc(new_capacity); - VERIFY(new_buffer); - __builtin_memcpy(new_buffer, data(), m_size); - } - m_outline_buffer = new_buffer; - m_outline_capacity = new_capacity; - m_size = new_size; + grow_slowpath(new_size); } void append(void const* data, size_t data_size) @@ -230,12 +218,29 @@ private: m_size = size; } - bool is_inline() const { return m_size <= inline_capacity; } - size_t capacity() const { return is_inline() ? inline_capacity : m_outline_capacity; } + NEVER_INLINE void grow_slowpath(size_t new_size) + { + u8* new_buffer; + auto new_capacity = kmalloc_good_size(new_size); + if (!is_inline()) { + new_buffer = (u8*)krealloc(m_outline_buffer, new_capacity); + VERIFY(new_buffer); + } else { + new_buffer = (u8*)kmalloc(new_capacity); + VERIFY(new_buffer); + __builtin_memcpy(new_buffer, data(), m_size); + } + m_outline_buffer = new_buffer; + m_outline_capacity = new_capacity; + m_size = new_size; + } + + 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 { - u8 m_inline_buffer[inline_capacity] {}; + u8 m_inline_buffer[inline_capacity]; struct { u8* m_outline_buffer; size_t m_outline_capacity; |