mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Core: Heap improvements
git-svn-id: svn://ultimatepp.org/upp/trunk@13443 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
9bbd49ee36
commit
7ef4f806ef
5 changed files with 45 additions and 28 deletions
|
|
@ -20,7 +20,7 @@ void *MemoryAlloc48();
|
|||
void MemoryFree48(void *ptr);
|
||||
void MemoryFreeThread();
|
||||
void MemoryCheck();
|
||||
void MemoryDump();
|
||||
void MemoryDumpLarge();
|
||||
void MemoryDumpHuge();
|
||||
int MemoryUsedKb();
|
||||
int MemoryUsedKbMax();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -429,9 +429,9 @@ MemoryProfile::MemoryProfile()
|
|||
ThreadHeap()->Make(*this);
|
||||
}
|
||||
|
||||
void MemoryDump()
|
||||
void MemoryDumpLarge()
|
||||
{
|
||||
ThreadHeap()->Dump();
|
||||
ThreadHeap()->DumpLarge();
|
||||
}
|
||||
|
||||
void MemoryDumpHuge()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue