1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_DetailHeapCommon.cpp
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 18703 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <nn/types.h>
17 #include <nn/assert.h>
18 #include "./fnd_DetailHeap.h"
19 #include "./fnd_DetailHeapCommon.h"
20 #include "./fnd_DetailHeapCommonImpl.h"
21 
22 
23 namespace nn { namespace fnd { namespace detail {
24 
25 /* ========================================================================
26     static変数
27    ======================================================================== */
28 
29 /* ------------------------------------------------------------------------
30     リスト関連
31    ------------------------------------------------------------------------ */
32 
33 static NNSFndList sRootList;                // ルートのヒープリスト
34 static bool sRootListInitialized = false;   // sRootListが初期化されていれば真
35 
36 
37 /* ------------------------------------------------------------------------
38     フィル関連
39    ------------------------------------------------------------------------ */
40 
41 #ifdef NN_BUILD_VERBOSE
42 
43     static u32 sFillVals[NN_OS_HEAP_FILL_MAX] =
44     {
45         0xC3C3C3C3, // ヒープ作成時に埋める値
46         0xF3F3F3F3, // メモリブロック確保時に埋める値
47         0xD3D3D3D3, // メモリブロック解放時に埋める値
48     };
49 
50 // #ifdef NN_BUILD_VERBOSE
51 #endif
52 
53 
54 /* ========================================================================
55     static関数
56    ======================================================================== */
57 
58 /* ------------------------------------------------------------------------
59     リスト関連
60    ------------------------------------------------------------------------ */
61 
62 /*---------------------------------------------------------------------------*
63   Name:         FindContainHeap
64 
65   Description:  指定されたメモリブロックを含有するヒープをリストから再帰的に
66                 探し出します。
67 
68   Arguments:    pList:     リストへのポインタ
69                 memBlock:  メモリブロックへのポインタ
70 
71   Returns:      指定されたメモリブロックを確保したヒープが見つかれば、
72                 そのヒープへのポインタを返します。
73                 見つからなかった時は NULL を返します。
74  *---------------------------------------------------------------------------*/
75 static NNSiFndHeapHead*
FindContainHeap(NNSFndList * pList,const void * memBlock)76 FindContainHeap(
77     NNSFndList* pList,
78     const void* memBlock
79 )
80 {
81     NNSiFndHeapHead* pHeapHd = NULL;
82     while (NULL != (pHeapHd = reinterpret_cast<NNSiFndHeapHead*>(
83                     GetNextListObject(pList, pHeapHd))))
84     {
85         if ( NNSiGetUIntPtr(pHeapHd->heapStart) <= NNSiGetUIntPtr(memBlock)
86          &&  NNSiGetUIntPtr(memBlock) < NNSiGetUIntPtr(pHeapHd->heapEnd)
87         )
88         {
89             NNSiFndHeapHead* pChildHeapHd = FindContainHeap(&pHeapHd->childList, memBlock);
90             if(pChildHeapHd)
91             {
92                 return pChildHeapHd;
93             }
94 
95             return pHeapHd;
96         }
97     }
98 
99     return NULL;
100 }
101 
102 /*---------------------------------------------------------------------------*
103   Name:         FindListContainHeap
104 
105   Description:  ヒープを含有する親ヒープを検索し、その親ヒープのリストへの
106                 ポインタを返します。
107 
108   Arguments:    pHeapHd:  検索対象のヒープのヘッダへのポインタ。
109 
110   Returns:      指定したヒープを含有する親ヒープが見つかれば、
111                 親ヒープの子リストへのポインタを返します。
112                 親ヒープが見つからなければルートリストへのポインタが返ります。
113  *---------------------------------------------------------------------------*/
114 static NNSFndList*
FindListContainHeap(NNSiFndHeapHead * pHeapHd)115 FindListContainHeap(NNSiFndHeapHead* pHeapHd)
116 {
117     NNSFndList* pList = &sRootList;
118 
119     NNSiFndHeapHead* pContainHeap = FindContainHeap(&sRootList, pHeapHd);
120 
121     if(pContainHeap)
122     {
123         pList = &pContainHeap->childList;
124     }
125 
126     return pList;
127 }
128 
129 #if 1
130     static inline void
131 //    static void
DumpHeapList()132     DumpHeapList() {}
133 #else
134     static void
DumpHeapList()135     DumpHeapList()
136     {
137         NNSiFndHeapHead* pHeapHd = NULL;
138         int count = 0;
139 
140         NN_TLOG_("Dump Heap List\n");
141         while (NULL != (pHeapHd = GetNextListObject(&sRootList, pHeapHd)))
142         {
143             count++;
144             NN_TLOG_("[%d] -> %p %08X\n", count, pHeapHd, pHeapHd->signature);
145         }
146     }
147 #endif
148 
149 /* ========================================================================
150     外部関数(非公開)
151    ======================================================================== */
152 
153 /*---------------------------------------------------------------------------*
154   Name:         NNSi_FndInitHeapHead
155 
156   Description:  ヒープヘッダの初期化を行います。
157 
158   Arguments:    pHeapHd:    ヒープヘッダへのポインタ。
159                 signature:  シグネチャ。
160                 heapStart:  ヒープメモリの開始アドレス。
161                 heapEnd:    ヒープメモリの終了アドレス +1。
162                 optFlag:    ヒープオプション。
163 
164   Returns:      なし。
165  *---------------------------------------------------------------------------*/
166 void
NNSi_FndInitHeapHead(NNSiFndHeapHead * pHeapHd,u32 signature,void * heapStart,void * heapEnd,u16 optFlag)167 NNSi_FndInitHeapHead(
168     NNSiFndHeapHead*    pHeapHd,
169     u32                 signature,
170     void*               heapStart,
171     void*               heapEnd,
172     u16                 optFlag
173 )
174 {
175     pHeapHd->signature = signature;
176 
177     pHeapHd->heapStart = heapStart;
178     pHeapHd->heapEnd   = heapEnd;
179 
180     pHeapHd->attribute = 0;
181     SetOptForHeap(pHeapHd, optFlag);
182 
183     FillNoUseMemory(
184         pHeapHd,
185         heapStart,
186         GetOffsetFromPtr(heapStart, heapEnd));
187 
188     NN_OS_INIT_LIST(&pHeapHd->childList, NNSiFndHeapHead, link);
189 
190     // ヒープのリスト操作
191     if(! sRootListInitialized)
192     {
193         NN_OS_INIT_LIST(&sRootList, NNSiFndHeapHead, link);
194         sRootListInitialized = true;
195     }
196 
197     AppendListObject(FindListContainHeap(pHeapHd), pHeapHd);
198     DumpHeapList();
199 
200 }
201 
202 /*---------------------------------------------------------------------------*
203   Name:         NNSi_FndFinalizeHeap
204 
205   Description:  ヒープ共通の後始末を行います。
206 
207   Arguments:    pHeapHd:  ヒープヘッダへのポインタ。
208 
209   Returns:      なし。
210  *---------------------------------------------------------------------------*/
211 void
NNSi_FndFinalizeHeap(NNSiFndHeapHead * pHeapHd)212 NNSi_FndFinalizeHeap(NNSiFndHeapHead* pHeapHd)
213 {
214     // ヒープのリスト操作
215     RemoveListObject(FindListContainHeap(pHeapHd), pHeapHd);
216     DumpHeapList();
217 }
218 
219 
220 /*---------------------------------------------------------------------------*
221   Name:         NNSi_FndDumpHeapHead
222 
223   Description:  ヒープヘッダの情報を表示します。
224 
225   Arguments:    pHeapHd:  ヒープヘッダへのポインタ。
226 
227   Returns:      なし。
228  *---------------------------------------------------------------------------*/
229 void
NNSi_FndDumpHeapHead(NNSiFndHeapHead const * pHeapHd)230 NNSi_FndDumpHeapHead(NNSiFndHeapHead const* pHeapHd)
231 {
232     NN_TLOG_("[NNS Foundation ");
233 
234     switch(pHeapHd->signature)
235     {
236     case NNSI_EXPHEAP_SIGNATURE: NN_TLOG_("Exp");   break;
237     case NNSI_FRMHEAP_SIGNATURE: NN_TLOG_("Frame"); break;
238     case NNSI_UNTHEAP_SIGNATURE: NN_TLOG_("Unit");  break;
239     default:
240         NN_TASSERT_(false);
241     }
242 
243     NN_TLOG_(" Heap]\n");
244 
245     NN_TLOG_("    whole [%p - %p)\n", pHeapHd, pHeapHd->heapEnd);
246 }
247 
248 
249 /* ========================================================================
250     外部関数(公開)
251    ======================================================================== */
252 
253 /*---------------------------------------------------------------------------*
254   Name:         FindContainHeap
255 
256   Description:  メモリブロックを含有するヒープを検索します。
257 
258   Arguments:    memBlock:  検索対象のメモリブロック。
259 
260   Returns:      指定したメモリブロックを含むヒープが見つかれば、
261                 そのヒープのハンドルを返します。
262                 見つからなければ、NN_OS_HEAP_INVALID_HANDLE が返ります。
263  *---------------------------------------------------------------------------*/
264 Heap
FindContainHeap(const void * memBlock)265 FindContainHeap(const void* memBlock)
266 {
267     return FindContainHeap(&sRootList, memBlock);
268 }
269 
270 /*---------------------------------------------------------------------------*
271   Name:         DumpHeap
272 
273   Description:  ヒープ内部の情報を表示します。
274                 これはデバッグ用の関数です。
275 
276   Arguments:    heap:    フレームヒープのハンドル。
277 
278   Returns:      なし。
279  *---------------------------------------------------------------------------*/
280 #if ! defined(NN_SWITCH_DISABLE_DEBUG_PRINT_FOR_SDK)
281 
282     void
DumpHeap(Heap heap)283     DumpHeap(Heap heap)
284     {
285         NNSiFndHeapHead* pHeapHd = heap;
286         switch(pHeapHd->signature)
287         {
288         case NNSI_EXPHEAP_SIGNATURE: NNSi_FndDumpHeap(heap);  break;
289         default:
290             NN_TLOG_("[NNS Foundation] dump heap : unknown heap. - %p\n", heap);
291         }
292     }
293 
294 // #if ! defined(NN_SWITCH_DISABLE_DEBUG_PRINT_FOR_SDK)
295 #endif
296 
297 /*---------------------------------------------------------------------------*
298   Name:         SetFillValForHeap
299 
300   Description:  ヒープの作成時やメモリブロックの確保・解放時にメモリに
301                 セットする値をセットします。
302                 この関数はデバッグ用の関数です。
303                 最終ROM版(FINALROM)ライブラリでは常に0を返します。
304 
305   Arguments:    type:  取得する値の種類
306                 val:   セットする値
307 
308   Returns:      以前の、メモリブロックの確保時にメモリにセットする値を返します。
309  *---------------------------------------------------------------------------*/
310 
311 #ifdef NN_BUILD_VERBOSE
312 
313     u32
SetFillValForHeap(int type,u32 val)314     SetFillValForHeap(
315         int     type,
316         u32     val
317     )
318     {
319         NN_TASSERT_(type < NN_OS_HEAP_FILL_MAX);
320 
321         {
322             u32 oldVal = sFillVals[type];
323             sFillVals[type] = val;
324             return oldVal;
325         }
326     }
327 
328 // #ifdef NN_BUILD_VERBOSE
329 #endif
330 
331 
332 /*---------------------------------------------------------------------------*
333   Name:         GetFillValForHeap
334 
335   Description:  ヒープの作成時やメモリブロックの確保・解放時にメモリに
336                 セットする値を取得します。
337                 この関数はデバッグ用の関数です。
338                 最終ROM版(FINALROM)ライブラリでは常に0を返します。
339 
340   Arguments:    type:  取得する値の種類
341 
342   Returns:      指定された種類のメモリにセットする値を返します。
343  *---------------------------------------------------------------------------*/
344 
345 #ifdef NN_BUILD_VERBOSE
346 
347     u32
GetFillValForHeap(int type)348     GetFillValForHeap(int type)
349     {
350         NN_TASSERT_(type < NN_OS_HEAP_FILL_MAX);
351 
352         return sFillVals[type];
353     }
354 
355 // #ifdef NN_BUILD_VERBOSE
356 #endif
357 
358 }}} // namespace nn::os::fnd
359 
360