18 #ifndef INC_KY_Kernel_HeapPT_FreeBin_H
19 #define INC_KY_Kernel_HeapPT_FreeBin_H
25 namespace Heap {
class SegVisitor; }
53 HeapSegment* pSegment;
59 struct BinTNode : BinLNode
71 enum { BinSize = 8*
sizeof(UPInt) };
77 void PushNode(UPInt idx, BinLNode* node);
78 void PullNode(UPInt idx, BinLNode* node);
80 BinLNode* PullBest(UPInt idx);
81 BinLNode* PullBest(UPInt idx, UPInt blocks, UPInt shift, UPInt alignMask);
83 BinLNode* FindAligned(BinLNode* root, UPInt blocks, UPInt shift, UPInt alignMask);
85 static UByte* GetAlignedPtr(UByte* start, UPInt alignMask);
86 static bool AlignmentIsOK(
const BinLNode* node, UPInt blocks,
87 UPInt shift, UPInt alignMask);
91 BinLNode* Roots[BinSize];
100 BinSize = ListBin::BinSize,
101 SizeShift = (
sizeof(
void*) > 4) ? 6 : 5,
102 SizeLimit = (
sizeof(
void*) > 4) ? 0xFFFFFFFFU : 0xFFFFU
109 static UPInt ShiftForTreeIndex(UPInt i);
110 static UPInt ComputeTreeIndex(UPInt blocks);
112 void PushNode(BinTNode* node);
113 void PullNode(BinTNode* node);
114 BinTNode* FindBest(UPInt size);
115 BinTNode* PullBest(UPInt size);
117 const BinTNode* FindExactSize(UPInt size)
const;
121 BinTNode* Roots[BinSize];
130 enum { BinSize = ListBin::BinSize };
137 UInt32* GetBitSet(
const HeapSegment* seg)
139 return (UInt32*)(((UByte*)seg) +
sizeof(HeapSegment));
144 UPInt GetSize(
const void* node)
146 UPInt size = ((
const BinLNode*)node)->ShortSize;
147 if (size < BinSize+1)
151 return *(
const UPInt*)((
const UByte*)node +
sizeof(BinLNode));
156 UPInt GetBytes(
const void* node, UPInt shift)
158 return GetSize(node) << shift;
163 void SetSize(UByte* node, UPInt blocks, UPInt shift)
165 UPInt bytes = blocks << shift;
166 BinLNode* listNode = (BinLNode*)node;
167 if (blocks < BinSize+1)
169 listNode->ShortSize =
170 *(UPIntHalf*)(node + bytes -
sizeof(UPIntHalf)) = UPIntHalf(blocks);
174 listNode->ShortSize =
175 *(UPIntHalf*)(node + bytes -
sizeof(UPIntHalf)) = UPIntHalf(BinSize+1);
177 *(UPInt*)(node +
sizeof(BinLNode)) =
178 *(UPInt*)(node + bytes - 2*
sizeof(UPInt)) = blocks;
183 KY_INLINE
static void
184 MakeNode(HeapSegment* seg, UByte* data, UPInt blocks, UPInt shift)
186 SetSize(data, blocks, shift);
187 ((BinLNode*)data)->pSegment = seg;
188 #ifdef KY_MEMORY_CHECK_CORRUPTION
189 MemsetNode((BinLNode*)data, shift);
194 UByte* PullBest(UPInt blocks);
195 UByte* PullBest(UPInt blocks, UPInt shift, UPInt alignMask);
198 void Push(UByte* node);
199 KY_INLINE
void Push(HeapSegment* seg, UByte* node,
200 UPInt blocks, UPInt shift)
202 MakeNode(seg, node, blocks, shift);
207 void Pull(UByte* node);
208 void Merge(UByte* node, UPInt shift,
bool left,
bool right);
210 UPInt GetTotalFreeSpace(UPInt shift)
const
212 return FreeBlocks << shift;
216 void VisitMem(MemVisitor* visitor, UPInt shift,
217 MemVisitor::Category cat)
const;
219 void VisitUnused(SegVisitor* visitor, UPInt shift,
unsigned cat)
const;
221 void CheckIntegrity(UPInt shift)
const;
223 #ifdef KY_MEMORY_CHECK_CORRUPTION
224 static void CheckArea(
const void* area, UPInt bytes);
225 static void MemsetNode(BinLNode* node, UPInt shift);
226 static void CheckNode(
const BinLNode* node, UPInt shift);
231 static void compilerAsserts();
233 static BinLNode* getPrevAdjacent(UByte* node, UPInt shift);
234 static BinLNode* getNextAdjacent(UByte* node, UPInt shift);
236 void visitTree(
const BinTNode* root, MemVisitor* visitor,
237 UPInt shift, MemVisitor::Category cat)
const;
239 void visitUnusedNode(
const BinLNode* node,
241 UPInt shift,
unsigned cat)
const;
243 void visitUnusedInTree(
const BinTNode* root,
245 UPInt shift,
unsigned cat)
const;
247 void checkBlockIntegrity(
const BinLNode* node, UPInt shift)
const;
248 void checkTreeIntegrity(
const BinTNode* root, UPInt shift)
const;
Definition: gamekitcrowddispersion.h:20