16 #ifndef INC_KY_Kernel_HeapPT_DebugInfo_H
17 #define INC_KY_Kernel_HeapPT_DebugInfo_H
21 #ifdef KY_MEMORY_ENABLE_DEBUG_INFO
29 namespace Kaim {
namespace HeapPT {
37 struct DebugDataPool : ListNode<DebugDataPool<T> >
39 typedef DebugDataPool<T> SelfType;
41 DebugDataPool() : UseCount(0) {}
43 static UPInt GetSize(UPInt bytes)
45 return (bytes -
sizeof(SelfType)) /
sizeof(T);
48 T* GetElement(UPInt i)
50 return (T*)((UByte*)
this +
sizeof(SelfType) + i*
sizeof(T));
57 struct DebugNode : ListNode<DebugNode>
78 NodePageFlag = 0x8000U,
79 NodePageMask = 0x7FFFU,
85 return DataCount & UPInt(NodePageFlag);
88 UPInt GetDataCount()
const
90 return DataCount & UPInt(NodePageMask);
95 return (++DataCount) & UPInt(NodePageMask);
100 return (--DataCount) & UPInt(NodePageMask);
104 UPIntHalf ChainCount;
109 struct DebugData : DebugNode
111 typedef DebugDataPool<DebugData> DataPool;
122 memset(&Info, 0,
sizeof(Info));
127 memset(&DataCount, 0xFE,
sizeof(DataCount));
128 memset(&ChainCount, 0xFE,
sizeof(ChainCount));
129 memset(&pParent, 0xFE,
sizeof(pParent));
130 memset(&pNextData, 0xFE,
sizeof(pNextData));
131 memset(&RefCount, 0xFE,
sizeof(RefCount));
132 memset(&Address, 0xFE,
sizeof(Address));
133 memset(&Size, 0xFE,
sizeof(Size));
134 memset(&Info, 0xFE,
sizeof(Info));
140 DebugData* pNextData;
150 struct DebugPage : DebugNode
152 typedef DebugDataPool<DebugPage> DataPool;
157 PageSize = 1 << PageShift,
159 AddrShift = Heap_PageShift - PageShift,
160 AddrSize = 1 << AddrShift,
161 AddrMask = AddrSize-1
166 DataCount = UPInt(NodePageFlag);
169 memset(pData, 0,
sizeof(pData));
174 memset(&DataCount, 0xFE,
sizeof(DataCount));
175 memset(&ChainCount, 0xFE,
sizeof(ChainCount));
176 memset(&Mask, 0xFE,
sizeof(Mask));
177 memset(pData, 0xFE,
sizeof(pData));
182 DebugData* pData[PageSize];
193 PoolSize = Heap_DebugAllocPoolSize,
194 AddrShift = DebugPage::AddrShift,
195 AddrSize = DebugPage::AddrSize,
196 AddrMask = DebugPage::AddrMask,
197 PageUpperLimit = DebugNode::PageUpperLimit,
198 PageLowerLimit = DebugNode::PageLowerLimit,
201 typedef DebugDataPool<DebugData> DataPoolType;
202 typedef DebugDataPool<DebugPage> PagePoolType;
207 DebugDataPtr() : pNode(0), Index(~UPInt(0)), pSelf(0), pPrev(0) {}
214 DebugStorage(Granulator* alloc, LockSafe* rootLocker);
216 unsigned GetStatId(UPInt parentAddr,
const AllocInfo* info);
218 bool AddAlloc(UPInt parentAddr,
bool autoHeap, UPInt thisAddr,
219 UPInt size, UPInt usable,
const AllocInfo* info);
221 void RemoveAlloc(UPInt addr, UPInt usable);
223 void RelinkAlloc(DebugDataPtr* ptr, UPInt oldAddr,
224 UPInt newAddr, UPInt newSize, UPInt usable);
226 void CheckDataTail(
const DebugDataPtr* ptr, UPInt usable);
230 void GetDebugData(UPInt addr, DebugDataPtr* ptr);
232 void UnlinkAlloc(UPInt addr, DebugDataPtr* ptr);
234 void GetStats(AllocEngine* allocator, StatBag* bag)
const;
236 const DebugData* GetFirstEntry()
const;
237 const DebugData* GetNextEntry(
const DebugData* entry)
const;
239 void VisitMem(MemVisitor* visitor,
unsigned flags)
const;
241 bool DumpMemoryLeaks(
const char* heapName);
243 void UltimateCheck();
245 UPInt GetUsedSpace()
const;
248 bool allocDataPool();
249 void freeDataPool(DataPoolType* pool);
250 bool allocPagePool();
251 void freePagePool(PagePoolType* pool);
253 DebugPage* allocDebugPage();
254 void freeDebugPage(DebugPage* page);
256 DebugData* allocDebugData();
257 void freeDebugData(DebugData* data);
258 void unlinkDebugData(DebugDataPtr* ptr);
259 void linkDebugData(DebugData* data);
260 void findInChainWithin(DebugData* chain, UPInt addr, DebugDataPtr* ptr);
261 void findInChainExact(DebugData* chain, UPInt addr, DebugDataPtr* ptr);
262 void findInNodeWithin(DebugNode* node, UPInt idx, UPInt addr, DebugDataPtr* ptr);
263 void findDebugData(UPInt addr,
bool autoHeap, DebugDataPtr* ret);
264 void linkToPage(DebugPage* page, DebugData* data);
265 void convertToChain(DebugPage* page, DebugData* oldData);
266 bool convertToPage(DebugData* chain, DebugData* newData);
267 void fillDataTail(DebugData* data, UPInt usable);
268 void reportViolation(DebugData* data,
const char* msg);
270 template<
class T,
class B>
271 void visitMem(
const List<T,B>& lst, UPInt dataSize,
273 MemVisitor::Category cat,
274 HeapSegment* seg)
const
276 const T* ptr = lst.GetFirst();
277 while(!lst.IsNull(ptr))
279 const TreeSeg* allocSeg = pAllocator->GetAllocSegment(ptr);
280 seg->pData = allocSeg->Buffer;
281 seg->DataSize = allocSeg->Size;
282 visitor->Visit(seg, UPInt(ptr), dataSize, cat);
283 ptr = (
const T*)(ptr->pNext);
287 Granulator* pAllocator;
288 List<DataPoolType> DataPools;
289 List<PagePoolType> PagePools;
290 List<DebugData, DebugNode> UsedDataList;
291 List<DebugData, DebugNode> FreeDataList;
292 List<DebugPage, DebugNode> FreePageList;
293 LockSafe* pRootLocker;
298 #endif // KY_MEMORY_ENABLE_DEBUG_INFO
Definition: gamekitcrowddispersion.h:20