ultimatepp/uppsrc/Core/StringMem.i
cxl bbb9fcad46 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
2020-11-30 11:21:43 +00:00

111 lines
2.2 KiB
OpenEdge ABL

// 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);
}