diff --git a/uppsrc/Core/Heap.h b/uppsrc/Core/Heap.h index 98ab8c898..e7d34f62d 100644 --- a/uppsrc/Core/Heap.h +++ b/uppsrc/Core/Heap.h @@ -20,7 +20,7 @@ void *MemoryAlloc48(); void MemoryFree48(void *ptr); void MemoryFreeThread(); void MemoryCheck(); -void MemoryDump(); +void MemoryDumpLarge(); void MemoryDumpHuge(); int MemoryUsedKb(); int MemoryUsedKbMax(); diff --git a/uppsrc/Core/HeapImp.h b/uppsrc/Core/HeapImp.h index 84e6b48b9..e37045a30 100644 --- a/uppsrc/Core/HeapImp.h +++ b/uppsrc/Core/HeapImp.h @@ -265,7 +265,6 @@ struct Heap : BlkHeap { 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 { }; struct LargeHeapDetail { - BlkHeader_ freelist[LCVCOUNT][1]; - static int Cv(int n) { return SignificantBits(n); } - - void Free64KB(BlkHeader_ *h); - void LinkFree(BlkHeader_ *h) { - Dbl_LinkAfter(h, freelist[Cv(h->GetSize())]); - } + BlkHeader_ freelist[25][1]; + void LinkFree(BlkHeader_ *h); }; struct LargeHeap : BlkHeap {}; @@ -348,6 +342,10 @@ struct Heap : BlkHeap { 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 { size_t LGetBlockSize(void *ptr); void Make(MemoryProfile& f); - void Dump(); + void DumpLarge(); void DumpHuge(); static void Shrink(); diff --git a/uppsrc/Core/heaputil.cpp b/uppsrc/Core/heaputil.cpp index fbd9a37a6..28610a990 100644 --- a/uppsrc/Core/heaputil.cpp +++ b/uppsrc/Core/heaputil.cpp @@ -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() diff --git a/uppsrc/Core/lheap.cpp b/uppsrc/Core/lheap.cpp index 2f4a9e767..a8f1841eb 100644 --- a/uppsrc/Core/lheap.cpp +++ b/uppsrc/Core/lheap.cpp @@ -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_ *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 diff --git a/uppsrc/Core/sheap.cpp b/uppsrc/Core/sheap.cpp index 5fe65fc73..c4afdc0ed 100644 --- a/uppsrc/Core/sheap.cpp +++ b/uppsrc/Core/sheap.cpp @@ -429,9 +429,9 @@ MemoryProfile::MemoryProfile() ThreadHeap()->Make(*this); } -void MemoryDump() +void MemoryDumpLarge() { - ThreadHeap()->Dump(); + ThreadHeap()->DumpLarge(); } void MemoryDumpHuge()