From 9d7da26b4ecde03255df2572d5bc9fd23da0ff7c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 18 Jan 2019 03:27:51 +0100 Subject: [PATCH] StringBuilder: Use a ByteBuffer internally instead of a Vector. --- AK/Buffer.h | 14 +++++++++++++ AK/ByteBuffer.h | 8 ++++++++ AK/FileSystemPath.cpp | 2 +- AK/StringBuilder.cpp | 42 ++++++++++++++++++--------------------- AK/StringBuilder.h | 7 +++++-- Kernel/ProcFileSystem.cpp | 22 ++++++++++---------- 6 files changed, 58 insertions(+), 37 deletions(-) diff --git a/AK/Buffer.h b/AK/Buffer.h index 3c1feb34c5..37fef0ea28 100644 --- a/AK/Buffer.h +++ b/AK/Buffer.h @@ -47,6 +47,8 @@ public: m_size = size; } + void grow(size_t size); + private: enum ConstructionMode { Uninitialized, Copy, Wrap, Adopt }; explicit Buffer(size_t); // For ConstructionMode=Uninitialized @@ -87,7 +89,19 @@ inline Buffer::Buffer(T* elements, size_t size, ConstructionMode mode) } else if (mode == Wrap) { m_owned = false; } +} +template +inline void Buffer::grow(size_t size) +{ + ASSERT(size > m_size); + ASSERT(m_owned); + T* new_elements = static_cast(kmalloc(size * sizeof(T))); + memcpy(new_elements, m_elements, m_size * sizeof(T)); + T* old_elements = m_elements; + m_elements = new_elements; + m_size = size; + kfree(old_elements); } template diff --git a/AK/ByteBuffer.h b/AK/ByteBuffer.h index 62075563e6..9f776c45a8 100644 --- a/AK/ByteBuffer.h +++ b/AK/ByteBuffer.h @@ -73,6 +73,14 @@ public: return copy(offset_pointer(offset), size); } + void grow(size_t size) + { + if (!m_impl) + m_impl = Buffer::create_uninitialized(size); + else + m_impl->grow(size); + } + private: explicit ByteBuffer(RetainPtr>&& impl) : m_impl(move(impl)) diff --git a/AK/FileSystemPath.cpp b/AK/FileSystemPath.cpp index 5f467c8594..232c05ecb3 100644 --- a/AK/FileSystemPath.cpp +++ b/AK/FileSystemPath.cpp @@ -38,7 +38,7 @@ bool FileSystemPath::canonicalize(bool resolve_symbolic_links) StringBuilder builder; for (auto& cpart : canonical_parts) { builder.append('/'); - builder.append(move(cpart)); + builder.append(cpart); } m_string = builder.build(); return true; diff --git a/AK/StringBuilder.cpp b/AK/StringBuilder.cpp index 558f071bd4..0e155df72c 100644 --- a/AK/StringBuilder.cpp +++ b/AK/StringBuilder.cpp @@ -1,22 +1,30 @@ #include "StringBuilder.h" #include #include "printf.cpp" +#include namespace AK { -void StringBuilder::append(String&& str) +inline void StringBuilder::will_append(size_t size) { - m_strings.append(move(str)); + if ((m_length + size) > m_buffer.size()) + m_buffer.grow(max(16u, m_buffer.size() * 2 + size)); } void StringBuilder::append(const String& str) { - m_strings.append(str); + if (str.is_empty()) + return; + will_append(str.length()); + memcpy(m_buffer.pointer() + m_length, str.characters(), str.length()); + m_length += str.length(); } void StringBuilder::append(char ch) { - m_strings.append(StringImpl::create(&ch, 1)); + will_append(1); + m_buffer.pointer()[m_length] = ch; + m_length += 1; } void StringBuilder::appendf(const char* fmt, ...) @@ -29,27 +37,15 @@ void StringBuilder::appendf(const char* fmt, ...) va_end(ap); } +ByteBuffer StringBuilder::to_byte_buffer() +{ + m_buffer.trim(m_length); + return m_buffer; +} + String StringBuilder::build() { - auto strings = move(m_strings); - if (strings.is_empty()) - return String::empty(); - - size_t sizeNeeded = 0; - for (auto& string : strings) - sizeNeeded += string.length(); - - char* buffer; - auto impl = StringImpl::create_uninitialized(sizeNeeded, buffer); - if (!impl) - return String(); - - for (auto& string : strings) { - memcpy(buffer, string.characters(), string.length()); - buffer += string.length(); - } - *buffer = '\0'; - return String(move(impl)); + return String((const char*)m_buffer.pointer(), m_length); } } diff --git a/AK/StringBuilder.h b/AK/StringBuilder.h index 624e71b206..434f7a917b 100644 --- a/AK/StringBuilder.h +++ b/AK/StringBuilder.h @@ -11,14 +11,17 @@ public: ~StringBuilder() { } void append(const String&); - void append(String&&); void append(char); void appendf(const char*, ...); String build(); + ByteBuffer to_byte_buffer(); private: - Vector m_strings; + void will_append(size_t); + + ByteBuffer m_buffer; + size_t m_length { 0 }; }; } diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index 528cd34dbf..7c2293df32 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -42,7 +42,7 @@ ByteBuffer procfs$pid_fds(Process& process) continue; builder.appendf("% 3u %s\n", i, descriptor->absolute_path().characters()); } - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } ByteBuffer procfs$pid_vm(Process& process) @@ -58,7 +58,7 @@ ByteBuffer procfs$pid_vm(Process& process) region->committed(), region->name.characters()); } - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } ByteBuffer procfs$pid_vmo(Process& process) @@ -87,7 +87,7 @@ ByteBuffer procfs$pid_vmo(Process& process) } builder.appendf("\n"); } - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } ByteBuffer procfs$pid_stack(Process& process) @@ -111,7 +111,7 @@ ByteBuffer procfs$pid_stack(Process& process) unsigned offset = symbol.address - symbol.ksym->address; builder.appendf("%p %s +%u\n", symbol.address, symbol.ksym->name, offset); } - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } ByteBuffer procfs$pid_regs(Process& process) @@ -130,7 +130,7 @@ ByteBuffer procfs$pid_regs(Process& process) builder.appendf("flg: %x\n", tss.eflags); builder.appendf("sp: %w:%x\n", tss.ss, tss.esp); builder.appendf("pc: %w:%x\n", tss.cs, tss.eip); - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } ByteBuffer procfs$pid_exe(Process& process) @@ -195,7 +195,7 @@ ByteBuffer procfs$mm() builder.appendf("VMO count: %u\n", MM.m_vmos.size()); builder.appendf("Free physical pages: %u\n", MM.m_free_physical_pages.size()); builder.appendf("Free supervisor physical pages: %u\n", MM.m_free_supervisor_physical_pages.size()); - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } ByteBuffer procfs$mounts() @@ -210,7 +210,7 @@ ByteBuffer procfs$mounts() else builder.appendf("%u:%u\n", mount.host().fsid(), mount.host().index()); }); - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } ByteBuffer procfs$cpuinfo() @@ -273,7 +273,7 @@ ByteBuffer procfs$cpuinfo() copy_brand_string_part_to_buffer(2); builder.appendf("brandstr: \"%s\"\n", buffer); } - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } ByteBuffer procfs$kmalloc() @@ -287,7 +287,7 @@ ByteBuffer procfs$kmalloc() sum_alloc, sum_free ); - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } ByteBuffer procfs$summary() @@ -310,7 +310,7 @@ ByteBuffer procfs$summary() process->tty() ? strrchr(process->tty()->tty_name().characters(), '/') + 1 : "n/a", process->name().characters()); } - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } ByteBuffer procfs$inodes() @@ -323,7 +323,7 @@ ByteBuffer procfs$inodes() String path = vfs.absolute_path(*inode); builder.appendf("Inode{K%x} %02u:%08u (%u) %s\n", inode.ptr(), inode->fsid(), inode->index(), inode->retain_count(), path.characters()); } - return builder.build().to_byte_buffer(); + return builder.to_byte_buffer(); } bool ProcFS::initialize()