From a7dc1a7d6b021cbc303f8f560acd6ef0b1a2aeb7 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 20 Jun 2019 13:21:56 +0200 Subject: [PATCH] AK: Make StringImpl a bit smaller. There's no need for a member char* m_characters if we always store them in the inline buffer. So with this patch, we now do. After that, rearrange the members a bit for ideal packing. :^) --- AK/StringImpl.cpp | 38 +++++++++++++++++++------------------- AK/StringImpl.h | 23 +++++++++++------------ 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/AK/StringImpl.cpp b/AK/StringImpl.cpp index 0130cb90ba..cf15329fdb 100644 --- a/AK/StringImpl.cpp +++ b/AK/StringImpl.cpp @@ -29,15 +29,15 @@ static StringImpl* s_the_empty_stringimpl = nullptr; StringImpl& StringImpl::the_empty_stringimpl() { - if (!s_the_empty_stringimpl) - s_the_empty_stringimpl = new StringImpl(ConstructTheEmptyStringImpl); - ; + if (!s_the_empty_stringimpl) { + void* slot = kmalloc(sizeof(StringImpl) + sizeof(char)); + s_the_empty_stringimpl = new (slot) StringImpl(ConstructTheEmptyStringImpl); + } return *s_the_empty_stringimpl; } -StringImpl::StringImpl(ConstructWithInlineBufferTag, ssize_t length) +StringImpl::StringImpl(ConstructWithInlineBufferTag, int length) : m_length(length) - , m_characters(m_inline_buffer) { #ifdef DEBUG_STRINGIMPL if (!g_all_live_stringimpls) @@ -55,23 +55,23 @@ StringImpl::~StringImpl() #endif } -static inline ssize_t allocation_size_for_stringimpl(ssize_t length) +static inline int allocation_size_for_stringimpl(int length) { return sizeof(StringImpl) + (sizeof(char) * length) + sizeof(char); } -Retained StringImpl::create_uninitialized(ssize_t length, char*& buffer) +Retained StringImpl::create_uninitialized(int length, char*& buffer) { ASSERT(length); void* slot = kmalloc(allocation_size_for_stringimpl(length)); ASSERT(slot); auto new_stringimpl = adopt(*new (slot) StringImpl(ConstructWithInlineBuffer, length)); - buffer = const_cast(new_stringimpl->m_characters); + buffer = const_cast(new_stringimpl->characters()); buffer[length] = '\0'; return new_stringimpl; } -RetainPtr StringImpl::create(const char* cstring, ssize_t length, ShouldChomp should_chomp) +RetainPtr StringImpl::create(const char* cstring, int length, ShouldChomp should_chomp) { if (!cstring) return nullptr; @@ -133,8 +133,8 @@ static inline char to_ascii_uppercase(char c) Retained StringImpl::to_lowercase() const { - for (ssize_t i = 0; i < m_length; ++i) { - if (!is_ascii_lowercase(m_characters[i])) + for (int i = 0; i < m_length; ++i) { + if (!is_ascii_lowercase(characters()[i])) goto slow_path; } return const_cast(*this); @@ -142,15 +142,15 @@ Retained StringImpl::to_lowercase() const slow_path: char* buffer; auto lowercased = create_uninitialized(m_length, buffer); - for (ssize_t i = 0; i < m_length; ++i) - buffer[i] = to_ascii_lowercase(m_characters[i]); + for (int i = 0; i < m_length; ++i) + buffer[i] = to_ascii_lowercase(characters()[i]); return lowercased; } Retained StringImpl::to_uppercase() const { - for (ssize_t i = 0; i < m_length; ++i) { - if (!is_ascii_uppercase(m_characters[i])) + for (int i = 0; i < m_length; ++i) { + if (!is_ascii_uppercase(characters()[i])) goto slow_path; } return const_cast(*this); @@ -158,8 +158,8 @@ Retained StringImpl::to_uppercase() const slow_path: char* buffer; auto uppercased = create_uninitialized(m_length, buffer); - for (ssize_t i = 0; i < m_length; ++i) - buffer[i] = to_ascii_uppercase(m_characters[i]); + for (int i = 0; i < m_length; ++i) + buffer[i] = to_ascii_uppercase(characters()[i]); return uppercased; } @@ -168,8 +168,8 @@ void StringImpl::compute_hash() const if (!length()) m_hash = 0; else - m_hash = string_hash(m_characters, m_length); - m_hasHash = true; + m_hash = string_hash(characters(), m_length); + m_has_hash = true; } } diff --git a/AK/StringImpl.h b/AK/StringImpl.h index 825b17af4b..19d09331ac 100644 --- a/AK/StringImpl.h +++ b/AK/StringImpl.h @@ -14,9 +14,9 @@ enum ShouldChomp { class StringImpl : public Retainable { public: - static Retained create_uninitialized(ssize_t length, char*& buffer); + static Retained create_uninitialized(int length, char*& buffer); static RetainPtr create(const char* cstring, ShouldChomp = NoChomp); - static RetainPtr create(const char* cstring, ssize_t length, ShouldChomp = NoChomp); + static RetainPtr create(const char* cstring, int length, ShouldChomp = NoChomp); Retained to_lowercase() const; Retained to_uppercase() const; @@ -29,17 +29,17 @@ public: ~StringImpl(); - ssize_t length() const { return m_length; } - const char* characters() const { return m_characters; } - char operator[](ssize_t i) const + int length() const { return m_length; } + const char* characters() const { return &m_inline_buffer[0]; } + char operator[](int i) const { ASSERT(i >= 0 && i < m_length); - return m_characters[i]; + return characters()[i]; } unsigned hash() const { - if (!m_hasHash) + if (!m_has_hash) compute_hash(); return m_hash; } @@ -49,21 +49,20 @@ private: ConstructTheEmptyStringImpl }; explicit StringImpl(ConstructTheEmptyStringImplTag) - : m_characters("") { + m_inline_buffer[0] = '\0'; } enum ConstructWithInlineBufferTag { ConstructWithInlineBuffer }; - StringImpl(ConstructWithInlineBufferTag, ssize_t length); + StringImpl(ConstructWithInlineBufferTag, int length); void compute_hash() const; - ssize_t m_length { 0 }; - mutable bool m_hasHash { false }; - const char* m_characters { nullptr }; + int m_length { 0 }; mutable unsigned m_hash { 0 }; + mutable bool m_has_hash { false }; char m_inline_buffer[0]; };