From bacb2dea70d1cc5b46755dc591a50de3499c54d5 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 27 May 2021 10:52:46 +0200 Subject: [PATCH] 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. --- AK/ByteBuffer.h | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/AK/ByteBuffer.h b/AK/ByteBuffer.h index 124702596e8..76dc9c55c87 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;