Core: Heap improvements

git-svn-id: svn://ultimatepp.org/upp/trunk@13443 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2019-06-26 14:16:47 +00:00
parent 9bbd49ee36
commit 7ef4f806ef
5 changed files with 45 additions and 28 deletions

View file

@ -20,7 +20,7 @@ void *MemoryAlloc48();
void MemoryFree48(void *ptr);
void MemoryFreeThread();
void MemoryCheck();
void MemoryDump();
void MemoryDumpLarge();
void MemoryDumpHuge();
int MemoryUsedKb();
int MemoryUsedKbMax();

View file

@ -265,7 +265,6 @@ struct Heap : BlkHeap<HugeHeapDetail, 4096> {
enum {
LUNIT = 256, // granularity of large blocks (size always a multiple of this)
LPAGE = LUNIT - 1, // number of LUNITs in large page
LCVCOUNT = 9, // SignificantBits(LPAGE) + 1
LOFFSET = 64, // offset from 64KB start to the first block header
NKLASS = 23, // number of small size classes
@ -318,13 +317,8 @@ struct Heap : BlkHeap<HugeHeapDetail, 4096> {
};
struct LargeHeapDetail {
BlkHeader_<LUNIT> freelist[LCVCOUNT][1];
static int Cv(int n) { return SignificantBits(n); }
void Free64KB(BlkHeader_<LUNIT> *h);
void LinkFree(BlkHeader_<LUNIT> *h) {
Dbl_LinkAfter(h, freelist[Cv(h->GetSize())]);
}
BlkHeader_<LUNIT> freelist[25][1];
void LinkFree(BlkHeader_<LUNIT> *h);
};
struct LargeHeap : BlkHeap<LargeHeapDetail, LUNIT> {};
@ -348,6 +342,10 @@ struct Heap : BlkHeap<HugeHeapDetail, 4096> {
LargeHeap::BlkHeader *GetFirst() { return (LargeHeap::BlkHeader *)((byte *)this + LOFFSET); } // pointer to data area
};
static int lclass[];
static int free_lclass[255];
static int alloc_lclass[255];
static_assert(sizeof(BlkPrefix) == 16, "Wrong sizeof(BlkPrefix)");
static_assert(sizeof(DLink) == 64, "Wrong sizeof(DLink)");
@ -436,7 +434,7 @@ struct Heap : BlkHeap<HugeHeapDetail, 4096> {
size_t LGetBlockSize(void *ptr);
void Make(MemoryProfile& f);
void Dump();
void DumpLarge();
void DumpHuge();
static void Shrink();

View file

@ -181,33 +181,25 @@ void Heap::Make(MemoryProfile& f)
}
}
void Heap::Dump()
void Heap::DumpLarge()
{
Mutex::Lock __(mutex);
DLink *m = large->next;
auto& out = VppLog();
while(m != large) {
LargeHeap::BlkHeader *h = m->GetFirst();
RLOG("--------------------------");
out << h << ": ";
for(;;) {
RLOG(asString(h) << " " << h->GetSize() << (h->IsFree() ? " FREE" : ""));
if(h->IsFree())
out << "#";
out << h->GetSize() * 0.25 << ' ';
if(h->IsLast())
break;
h = h->GetNextHeader();
}
out << "\r\n";
m = m->next;
}
HugePage *pg = huge_pages;
while(pg) {
BlkPrefix *h = (BlkPrefix *)pg->page;
RLOG("==========================");
for(;;) {
RLOG(asString(h) << " " << h->GetSize() << (h->IsFree() ? " FREE" : ""));
if(h->IsLast())
break;
h = h->GetNextHeader(4096);
}
pg = pg->next;
}
}
void Heap::DumpHuge()

View file

@ -11,8 +11,31 @@ namespace Upp {
#include "HeapImp.h"
int Heap::lclass[] = { 0, 4, 5, 6, 7, 8, 9, 11, 13, 15, 18, 22, 27, 33, 40, 49, 60, 73, 89, 109, 134, 164, 201, 225, 255 };
int Heap::free_lclass[255]; // free block size -> lclass, size is >= class sz
int Heap::alloc_lclass[255]; // allocation size -> lclass, size <= class sz
void Heap::LargeHeapDetail::LinkFree(BlkHeader_<LUNIT> *h)
{
Dbl_LinkAfter(h, freelist[free_lclass[h->GetSize()]]);
}
void Heap::LInit()
{
ASSERT(__countof(lheap.freelist) == __countof(lclass));
ONCELOCK {
int ai = 0;
int fi = 0;
for(int i = 0; i <= 255; i++) {
if(i > lclass[ai])
ai++;
if(i >= lclass[fi + 1])
fi++;
alloc_lclass[i] = ai;
free_lclass[i] = fi;
}
}
for(int i = 0; i <= __countof(lheap.freelist); i++)
Dbl_Self(lheap.freelist[i]);
big->LinkSelf();
@ -31,6 +54,10 @@ void *Heap::TryLAlloc(int i0, word wcount)
return (BlkPrefix *)h + 1;
}
h = h->next;
RHITCOUNT("next");
static int q = 0;
if(++q < 1000)
RLOG(asString(sz) << " " << asString(wcount));
}
}
return NULL;
@ -76,7 +103,7 @@ void *Heap::LAlloc(size_t& size)
#endif
size = ((int)wcount * LUNIT) - sizeof(BlkPrefix);
int i0 = lheap.Cv(wcount);
int i0 = alloc_lclass[wcount];
if(large_remote_list) // there might be blocks of this heap freed in other threads
LargeFreeRemote(); // free them first

View file

@ -429,9 +429,9 @@ MemoryProfile::MemoryProfile()
ThreadHeap()->Make(*this);
}
void MemoryDump()
void MemoryDumpLarge()
{
ThreadHeap()->Dump();
ThreadHeap()->DumpLarge();
}
void MemoryDumpHuge()