From bbb9fcad4694eb0f58ac8aef90f7c2dcd4649720 Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 30 Nov 2020 11:21:43 +0000 Subject: [PATCH] Core: String middle tier optimised (some routines moved to allocator to inline MemoryAlloc32 / MemoryFree32) git-svn-id: svn://ultimatepp.org/upp/trunk@15553 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/Core.upp | 1 + uppsrc/Core/String.cpp | 115 +++------------------------------------- uppsrc/Core/StringMem.i | 111 ++++++++++++++++++++++++++++++++++++++ uppsrc/Core/sheap.cpp | 12 ++++- 4 files changed, 129 insertions(+), 110 deletions(-) create mode 100644 uppsrc/Core/StringMem.i diff --git a/uppsrc/Core/Core.upp b/uppsrc/Core/Core.upp index 46a4cddc4..5a197f330 100644 --- a/uppsrc/Core/Core.upp +++ b/uppsrc/Core/Core.upp @@ -51,6 +51,7 @@ file String.h, AString.hpp, StringFind.cpp, + StringMem.i highlight cpp, String.cpp, WString.cpp, StrUtil.cpp, diff --git a/uppsrc/Core/String.cpp b/uppsrc/Core/String.cpp index 066dc6e70..533c6c772 100644 --- a/uppsrc/Core/String.cpp +++ b/uppsrc/Core/String.cpp @@ -13,33 +13,14 @@ void String0::Dsyn() String0::Rc String0::voidptr[2]; -void String0::LSet(const String0& s) -{ - w[2] = s.w[2]; - w[3] = s.w[3]; - if(s.IsRef()) { - ptr = s.ptr; - if(ptr != (char *)(voidptr + 1)) - AtomicInc(s.Ref()->refcount); - } - else { - ptr = (char *)MemoryAlloc32(); - memcpy(qptr, s.qptr, 32); // optimizes to movups - } -} +#ifndef UPP_HEAP -void String0::LFree() -{ - if(IsRef()) { - if(ptr != (char *)(voidptr + 1)) { - Rc *rc = Ref(); - ASSERT(rc->refcount > 0); - if(AtomicDec(rc->refcount) == 0) MemoryFree(rc); - } - } - else - MemoryFree32(ptr); -} +inline void *MemoryAlloc32_i() { return new byte[32]; } +inline void MemoryFree32_i(void *ptr) { delete[] (byte *)ptr; } + +#include "StringMem.i" + +#endif bool String0::LEq(const String0& s) const { @@ -78,20 +59,6 @@ int String0::CompareL(const String0& s) const return q ? q : SgnCompare(la, lb); } -char *String0::Alloc(int count, char& kind) -{ - if(count < 32) { - kind = MEDIUM; - return (char *)MemoryAlloc32(); - } - size_t sz = sizeof(Rc) + count + 1; - Rc *rc = (Rc *)MemoryAllocSz(sz); - rc->alloc = count == INT_MAX ? INT_MAX : (int)sz - sizeof(Rc) - 1; - rc->refcount = 1; - kind = min(rc->alloc, 255); - return rc->GetPtr(); -} - char *String0::Insert(int pos, int count, const char *s) { ASSERT(pos >= 0 && count >= 0 && pos <= GetCount()); @@ -186,29 +153,6 @@ void String0::Trim(int pos) Dsyn(); } -void String0::LCat(int c) -{ - if(IsSmall()) { - qword *x = (qword *)MemoryAlloc32(); - x[0] = q[0]; - x[1] = q[1]; - LLen() = SLen(); - SLen() = 15; - chr[KIND] = MEDIUM; - qptr = x; - } - int l = LLen(); - if(IsRef() ? !IsShared() && l < (int)Ref()->alloc : l < 31) { - ptr[l] = c; - ptr[LLen() = l + 1] = 0; - } - else { - char *s = Insert(l, 1, NULL); - s[0] = c; - s[1] = 0; - } -} - void String0::Cat(const char *s, int len) { if(IsSmall()) { @@ -327,33 +271,6 @@ String::String(StringBuffer& b) // DLOG(sprintf(h, "String(StringBuffer) end2 %p (%p)", ptr, this)); } -char *StringBuffer::Alloc(int count, int& alloc) -{ - if(count <= 31) { - char *s = (char *)MemoryAlloc32(); - alloc = 31; - return s; - } - else { - size_t sz = sizeof(Rc) + count + 1; - Rc *rc = (Rc *)MemoryAlloc(sz); - alloc = rc->alloc = (int)min((size_t)INT_MAX, sz - sizeof(Rc) - 1); - rc->refcount = 1; - return (char *)(rc + 1); - } -} - -void StringBuffer::Free() -{ - if(pbegin == buffer) - return; - int all = (int)(limit - pbegin); - if(all == 31) - MemoryFree32(pbegin); - if(all > 31) - MemoryFree((Rc *)pbegin - 1); -} - void StringBuffer::Realloc(dword n, const char *cat, int l) { int al; @@ -416,24 +333,6 @@ void StringBuffer::ReallocL(const char *s, int l) Realloc(max(GetLength(), l) + GetLength(), s, l); } -void StringBuffer::Set(String& s) -{ - s.UnShare(); - int l = s.GetLength(); - if(s.GetAlloc() == 14) { - pbegin = (char *)MemoryAlloc32(); - limit = pbegin + 31; - memcpy8(pbegin, s.Begin(), l); - pend = pbegin + l; - } - else { - pbegin = s.ptr; - pend = pbegin + l; - limit = pbegin + s.GetAlloc(); - } - s.Zero(); -} - String TrimLeft(const String& str) { const char *s = str; diff --git a/uppsrc/Core/StringMem.i b/uppsrc/Core/StringMem.i new file mode 100644 index 000000000..6cc6f902d --- /dev/null +++ b/uppsrc/Core/StringMem.i @@ -0,0 +1,111 @@ +// These are String methods which are best inlined in heap allocator + +void String0::LSet(const String0& s) +{ + w[2] = s.w[2]; + w[3] = s.w[3]; + if(s.IsRef()) { + ptr = s.ptr; + if(ptr != (char *)(voidptr + 1)) + AtomicInc(s.Ref()->refcount); + } + else { + ptr = (char *)MemoryAlloc32_i(); + memcpy(qptr, s.qptr, 32); // optimizes to movups + } +} + +void String0::LFree() +{ + if(IsRef()) { + if(ptr != (char *)(voidptr + 1)) { + Rc *rc = Ref(); + ASSERT(rc->refcount > 0); + if(AtomicDec(rc->refcount) == 0) MemoryFree(rc); + } + } + else + MemoryFree32_i(ptr); +} + +char *String0::Alloc(int count, char& kind) +{ + if(count < 32) { + kind = MEDIUM; + return (char *)MemoryAlloc32_i(); + } + size_t sz = sizeof(Rc) + count + 1; + Rc *rc = (Rc *)MemoryAllocSz(sz); + rc->alloc = count == INT_MAX ? INT_MAX : (int)sz - sizeof(Rc) - 1; + rc->refcount = 1; + kind = min(rc->alloc, 255); + return rc->GetPtr(); +} + +void String0::LCat(int c) +{ + if(IsSmall()) { + qword *x = (qword *)MemoryAlloc32_i(); + x[0] = q[0]; + x[1] = q[1]; + LLen() = SLen(); + SLen() = 15; + chr[KIND] = MEDIUM; + qptr = x; + } + int l = LLen(); + if(IsRef() ? !IsShared() && l < (int)Ref()->alloc : l < 31) { + ptr[l] = c; + ptr[LLen() = l + 1] = 0; + } + else { + char *s = Insert(l, 1, NULL); + s[0] = c; + s[1] = 0; + } +} + +char *StringBuffer::Alloc(int count, int& alloc) +{ + if(count <= 31) { + char *s = (char *)MemoryAlloc32_i(); + alloc = 31; + return s; + } + else { + size_t sz = sizeof(Rc) + count + 1; + Rc *rc = (Rc *)MemoryAlloc(sz); + alloc = rc->alloc = (int)min((size_t)INT_MAX, sz - sizeof(Rc) - 1); + rc->refcount = 1; + return (char *)(rc + 1); + } +} + +void StringBuffer::Set(String& s) +{ + s.UnShare(); + int l = s.GetLength(); + if(s.GetAlloc() == 14) { + pbegin = (char *)MemoryAlloc32_i(); + limit = pbegin + 31; + memcpy8(pbegin, s.Begin(), l); + pend = pbegin + l; + } + else { + pbegin = s.ptr; + pend = pbegin + l; + limit = pbegin + s.GetAlloc(); + } + s.Zero(); +} + +void StringBuffer::Free() +{ + if(pbegin == buffer) + return; + int all = (int)(limit - pbegin); + if(all == 31) + MemoryFree32_i(pbegin); + if(all > 31) + MemoryFree((Rc *)pbegin - 1); +} diff --git a/uppsrc/Core/sheap.cpp b/uppsrc/Core/sheap.cpp index f048dd85b..247abd0d8 100644 --- a/uppsrc/Core/sheap.cpp +++ b/uppsrc/Core/sheap.cpp @@ -575,7 +575,8 @@ void *MemoryAlloc32_2() return LogAlloc(MakeHeap()->Alloc32(), 32); } -void *MemoryAlloc32() +force_inline +void *MemoryAlloc32_i() { LTIMING("MemoryAlloc32"); Heap *heap = heap_tls__; @@ -584,6 +585,8 @@ void *MemoryAlloc32() return MemoryAlloc32_2(); } +void *MemoryAlloc32() { return MemoryAlloc32_i(); } + never_inline void MemoryFree32_2(void *ptr) { @@ -591,7 +594,8 @@ void MemoryFree32_2(void *ptr) MakeHeap()->Free32(ptr); } -void MemoryFree32(void *ptr) +force_inline +void MemoryFree32_i(void *ptr) { LTIMING("MemoryFree32"); LogFree(ptr); @@ -602,6 +606,8 @@ void MemoryFree32(void *ptr) MemoryFree32_2(ptr); } +void MemoryFree32(void *ptr) { MemoryFree32_i(ptr); } + void *MemoryAlloc48() { LTIMING("MemoryAlloc48"); @@ -656,6 +662,8 @@ void MemoryDumpHuge() CurrentHeap()->DumpHuge(); } +#include "StringMem.i" + #endif }