gwnavruntime/kernel/HeapMH/HeapMH_Root.h Source File

HeapMH_Root.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 /**************************************************************************
8 
9 Filename : HeapMH_Root.h
10 Content : Heap root used for bootstrapping and bookkeeping.
11  :
12 Created : 2009
13 Authors : Maxim Shemanarev
14 
15 **************************************************************************/
16 
17 #pragma once
18 
23 
24 namespace Kaim { namespace HeapMH {
25 
26 //------------------------------------------------------------------------
27 struct PageMH : public ListNode<PageMH>
28 {
29  enum
30  {
31  PageSize = 4096,
32  PageMask = PageSize-1,
33  UnitShift = 4,
34  UnitSize = 1 << UnitShift,
35  UnitMask = UnitSize - 1,
36  BitSetBytes = PageSize/UnitSize/4,
37  MaxBytes = 512
38  };
39 
40  MemoryHeapMH *pHeap; // Heap this page belongs to.
41  UByte* Start;
42 };
43 
44 
45 //------------------------------------------------------------------------
46 struct PageTableMH
47 {
48  enum
49  {
50  Index1Shift = 7,
51  TableSize = 1 << Index1Shift,
52  Index0Mask = TableSize - 1
53  };
54 
55  struct Level0Entry
56  {
57  PageMH* FirstPage;
58  UPInt SizeMask;
59  };
60 
61  Level0Entry Entries[TableSize];
62 };
63 
64 struct DebugDataMH;
65 
66 //------------------------------------------------------------------------
67 struct MagicHeader
68 {
69  enum { MagicValue = 0x5FC0 }; // "SFCO" - Scaleform Corporation
70 
71  UInt16 Magic; // Magic marker
72  UInt16 UseCount; // Existing allocation count
73  UInt32 Index; // 2-component index in page tables
74  DebugDataMH* DebugHeader;
75 #ifndef KY_64BIT_POINTERS
76  UInt32 Filler;
77 #endif
78 
79  UInt32 GetIndex0() const { return Index & PageTableMH::Index0Mask; }
80  UInt32 GetIndex1() const { return Index >> PageTableMH::Index1Shift; }
81 };
82 
83 //------------------------------------------------------------------------
84 struct NodeMH
85 {
86  enum { Align4 = 0, Align8 = 1, Align16 = 2, MoreInfo = 3 };
87 
88  NodeMH* Parent;
89  NodeMH* Child[2];
90  UPInt pHeap;
91 #ifdef KY_MEMORY_ENABLE_DEBUG_INFO
92  DebugDataMH* DebugHeader;
93 #endif
94  //------------------ Optional data
95  UPInt Align;
96 
97  static UPInt GetNodeSize(UPInt align)
98  {
99  UPInt size = 4*sizeof(void*);
100 #ifdef KY_MEMORY_ENABLE_DEBUG_INFO
101  size += sizeof(void*);
102 #endif
103  return (align <= 16) ? size : size + sizeof(UPInt);
104  }
105 
106  MemoryHeapMH* GetHeap() const
107  {
108  return (MemoryHeapMH*)(pHeap & ~UPInt(3));
109  }
110 
111  UPInt GetAlign() const
112  {
113  return ((pHeap & 3) < 3) ? (UPInt(1) << ((pHeap & 3) + 2)) : Align;
114  }
115 
116  void SetHeap(MemoryHeapMH* heap, UPInt align)
117  {
118  switch(align)
119  {
120  case 1: case 2: case 4:
121  pHeap = UPInt(heap);
122  break;
123 
124  case 8:
125  pHeap = UPInt(heap) | Align8;
126  break;
127 
128  case 16:
129  pHeap = UPInt(heap) | Align16;
130  break;
131 
132  default:
133  pHeap = UPInt(heap) | MoreInfo;
134  Align = align;
135  break;
136  }
137  }
138 };
139 
140 
141 //--------------------------------------------------------------------
142 struct TreeNodeAccessor
143 {
144  static UPInt GetKey (const NodeMH* n) { return UPInt(n); }
145  static NodeMH* GetChild ( NodeMH* n, UPInt i) { return n->Child[i]; }
146  static const NodeMH* GetChild (const NodeMH* n, UPInt i) { return n->Child[i]; }
147  static NodeMH** GetChildPtr( NodeMH* n, UPInt i) { return &n->Child[i]; }
148 
149  static NodeMH* GetParent ( NodeMH* n) { return n->Parent; }
150  static const NodeMH* GetParent (const NodeMH* n) { return n->Parent; }
151 
152  static void SetParent (NodeMH* n, NodeMH* p) { n->Parent = p; }
153  static void SetChild (NodeMH* n, UPInt i, NodeMH* c) { n->Child[i] = c; }
154  static void ClearLinks(NodeMH* n) { n->Parent = n->Child[0] = n->Child[1] = 0; }
155 };
156 
157 
158 //------------------------------------------------------------------------
159 struct MagicHeadersInfo
160 {
161  MagicHeader* Header1; // Header on the left ptr or 0
162  MagicHeader* Header2; // Header on the right ptr or 0
163  UInt32* BitSet; // Pointer to the bitset
164  UByte* AlignedStart; // Pointer to the beginning of the page, aligned
165  UByte* AlignedEnd; // Pointer to the end of the page, aligned
166  UByte* Bound; // The bound between physical pages
167  PageMH* Page; // Page, null after GetMagicHeaders()
168 };
169 
170 
171 //------------------------------------------------------------------------
172 struct PageInfoMH
173 {
174 #ifdef KY_MEMORY_ENABLE_DEBUG_INFO
175  DebugDataMH** DebugHeaders[3];
176 #endif
177  PageMH* Page;
178  NodeMH* Node;
179  UPInt UsableSize;
180 };
181 
182 //------------------------------------------------------------------------
183 void GetMagicHeaders(UPInt pageStart, MagicHeadersInfo* headers);
184 
185 
186 //------------------------------------------------------------------------
187 class RootMH
188 {
189  typedef RadixTree<NodeMH, TreeNodeAccessor> HeapTreeType;
190 public:
191  RootMH(SysAlloc* sysAlloc);
192  ~RootMH();
193 
194  void FreeTables();
195 
196  SysAlloc* GetSysAlloc() { return pSysAlloc; }
197 
198  MemoryHeapMH* CreateHeap(const char* name,
199  MemoryHeapMH* parent,
200  const MemoryHeap::HeapDesc& desc);
201 
202  void DestroyHeap(MemoryHeapMH* heap);
203 
204  LockSafe* GetLock() { return &RootLock; }
205 
206  PageMH* AllocPage(MemoryHeapMH* heap);
207  void FreePage(PageMH* page);
208  UInt32 GetPageIndex(const PageMH* page) const;
209 
210  PageMH* ResolveAddress(UPInt addr) const;
211 
212  NodeMH* AddToGlobalTree(UByte* ptr, UPInt size, UPInt align, MemoryHeapMH* heap)
213  {
214  NodeMH* node = (NodeMH*)(ptr + size);
215  node->SetHeap(heap, align);
216 #ifdef KY_MEMORY_ENABLE_DEBUG_INFO
217  node->DebugHeader = 0;
218 #endif
219  HeapTree.Insert(node);
220  return node;
221  }
222 
223  NodeMH* FindNodeInGlobalTree(UByte* ptr)
224  {
225  return (NodeMH*)HeapTree.FindGrEq(UPInt(ptr));
226  }
227 
228  void RemoveFromGlobalTree(NodeMH* node)
229  {
230  HeapTree.Remove(node);
231  }
232 
233 #ifdef KY_MEMORY_ENABLE_DEBUG_INFO
234  void OnAlloc(const MemoryHeapMH* heap, UPInt size, UPInt align, unsigned sid, const void* ptr);
235  void OnRealloc(const MemoryHeapMH* heap, const void* oldPtr, UPInt newSize, const void* newPtr);
236  void OnFree(const MemoryHeapMH* heap, const void* ptr);
237 #endif
238 
239 
240 private:
241  bool allocPagePool();
242  static void setMagic(UByte* pageStart, unsigned magicValue);
243 
244  SysAlloc* pSysAlloc;
245  mutable LockSafe RootLock;
246  List<PageMH> FreePages;
247  unsigned TableCount;
248  HeapTreeType HeapTree;
249 
250  static MemoryHeap::HeapTracer* pTracer;
251 };
252 
253 extern RootMH* GlobalRootMH;
254 extern PageTableMH GlobalPageTableMH;
255 extern PageMH GlobalEmptyPage;
256 
257 }} // Kaim::HeapMH
258 
std::uint16_t UInt16
uint16_t
Definition: SF_Types.h:136
std::uint8_t UByte
uint8_t
Definition: SF_Types.h:134
std::uint32_t UInt32
uint32_t
Definition: SF_Types.h:137
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17