summaryrefslogtreecommitdiff
path: root/AK/ByteBuffer.h
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-05-27 10:52:46 +0200
committerAndreas Kling <kling@serenityos.org>2021-05-27 22:39:25 +0200
commitbacb2dea70d1cc5b46755dc591a50de3499c54d5 (patch)
tree7f58da3e78854036b343a4a0e12ca93b3e4200aa /AK/ByteBuffer.h
parentc1a4dfeffbd8a2fcf10cfed014692f7cdaf37f50 (diff)
downloadserenity-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.h39
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;