From a4dd89f214e72005f551cd071d7642652c2922c5 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 20 Jul 2021 19:53:06 +1000 Subject: Improve code-generation for Strings Make String::Data use trivial copy of the short/long union to avoid unnecessary branching there, inline release() as it can be elided by the compiler on moved-from Strings. --- src/string.cc | 49 ++++++++++++++++--------------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) (limited to 'src/string.cc') diff --git a/src/string.cc b/src/string.cc index 37467451..fe763165 100644 --- a/src/string.cc +++ b/src/string.cc @@ -14,29 +14,18 @@ String::Data::Data(const char* data, size_t size, size_t capacity) ++capacity; kak_assert(capacity < Long::max_capacity); - l.ptr = Alloc{}.allocate(capacity+1); - l.size = size; - l.capacity = capacity; + u.l.ptr = Alloc{}.allocate(capacity+1); + u.l.size = size; + u.l.capacity = capacity; if (data != nullptr) - memcpy(l.ptr, data, size); - l.ptr[size] = 0; + memcpy(u.l.ptr, data, size); + u.l.ptr[size] = 0; } else set_short(data, size); } -String::Data::Data(Data&& other) noexcept -{ - if (other.is_long()) - { - l = other.l; - other.set_empty(); - } - else - s = other.s; -} - String::Data& String::Data::operator=(const Data& other) { if (&other == this) @@ -59,11 +48,11 @@ String::Data& String::Data::operator=(Data&& other) noexcept if (other.is_long()) { - l = other.l; + u.l = other.u.l; other.set_empty(); } else - s = other.s; + u.s = other.u.s; return *this; } @@ -75,7 +64,7 @@ void String::Data::reserve(size_t new_capacity) return; if (is_long()) - new_capacity = std::max(l.capacity * 2, new_capacity); + new_capacity = std::max(u.l.capacity * 2, new_capacity); if (new_capacity & 1) ++new_capacity; @@ -85,12 +74,12 @@ void String::Data::reserve(size_t new_capacity) if (copy) { memcpy(new_ptr, data(), size()+1); - l.size = size(); + u.l.size = size(); } release(); - l.ptr = new_ptr; - l.capacity = new_capacity; + u.l.ptr = new_ptr; + u.l.capacity = new_capacity; } template void String::Data::reserve(size_t); @@ -121,12 +110,6 @@ void String::Data::clear() set_empty(); } -void String::Data::release() -{ - if (is_long() and l.capacity != 0) - Alloc{}.deallocate(l.ptr, l.capacity+1); -} - void String::resize(ByteCount size, char c) { const size_t target_size = (size_t)size; @@ -146,17 +129,17 @@ void String::resize(ByteCount size, char c) void String::Data::set_size(size_t size) { if (is_long()) - l.size = size; + u.l.size = size; else - s.size = (size << 1) | 1; + u.s.size = (size << 1) | 1; } void String::Data::set_short(const char* data, size_t size) { - s.size = (size << 1) | 1; + u.s.size = (size << 1) | 1; if (data != nullptr) - memcpy(s.string, data, size); - s.string[size] = 0; + memcpy(u.s.string, data, size); + u.s.string[size] = 0; } const String String::ms_empty; -- cgit v1.2.3