1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_HeapBase.h
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: 24328 $
14  *---------------------------------------------------------------------------*/
15 
16 /*! @file
17   @brief    ヒープの基底クラスの宣言
18 
19 */
20 
21 #ifndef NN_FND_FND_HEAPBASE_H_
22 #define NN_FND_FND_HEAPBASE_H_
23 
24 #include <nn/types.h>
25 #include <nn/util/util_NonCopyable.h>
26 #include <nn/fnd/fnd_LinkedList.h>
27 
28 // デフォルトアラインメント
29 #define NN_FND_HEAP_DEFAULT_ALIGNMENT 4
30 
31 // メモリ確保時にメモリを0でクリア
32 #define NN_FND_HEAP_OPTION_ZERO_CLEAR (1 << 0)
33 
34 // ヒープ作成時・メモリ確保・解放時にメモリ充填
35 #define NN_FND_HEAP_OPTION_DEBUG_FILL (1 << 1)
36 
37 //  このビットが立っているとエラー出力
38 #define NN_FND_HEAP_OPTION_ERROR_PRINT (1 << 0)
39 
40 #ifdef __cplusplus
41 
42 namespace nn { namespace fnd {
43 
44 /*!
45     @brief ヒープをフィルする種別を表わす定数
46 */
47 enum HeapFillType
48 {
49     HEAP_FILL_TYPE_NOUSE,    //!< デバッグフィル未使用時
50     HEAP_FILL_TYPE_ALLOC,    //!< デバッグフィル確保時
51     HEAP_FILL_TYPE_FREE,     //!< デバッグフィル解放時
52 
53     HEAP_FILL_TYPE_MAX
54 };
55 
56 enum HeapInfoPlacement
57 {
58     HEAP_INFOPLACEMENT_HEAD,
59     HEAP_INFOPLACEMENT_TAIL
60 };
61 
62 /*!
63 	@brief ヒープ領域を縮小する種別を表す定数
64 */
65 enum HeapAdjustMode
66 {
67     HEAP_ADJUST_TAIL = 1,    //!< ヒープのメモリ領域を末尾に縮める
68     HEAP_ADJUST_HEAD = -1    //!< ヒープをメモリ領域を先頭に縮める
69 };
70 
71 /*!
72     @brief    ヒープの基底クラスです。
73 
74               このクラスをインスタンス化することはできません。
75  */
76 class HeapBase : public IntrusiveLinkedList<HeapBase>::Item
77 {
78 public:
79 
80     static const s32 DEFAULT_ALIGNMENT = 4;
81     static const bit32 OPTION_ERROR_PRINT = NN_FND_HEAP_OPTION_ERROR_PRINT;
82 
83 	/*!
84 	    @brief ヒープをフィルする種別、値を設定します。
85 
86 		@param[in] type ヒープをフィルする種別
87 		@param[in] val  ヒープをフィルする値
88 	*/
89     static void SetFillValue(HeapFillType type, bit32 val);
90 
91 	/*!
92 	    @brief ヒープをフィルする種別を取得します。
93 
94 		@return ヒープをフィルする種別を返します。
95 	*/
96     static bit32 GetFillValue(HeapFillType type);
97 
98     /*!
99         @brief デストラクタです。
100     */
101     virtual ~HeapBase() = 0;
102 
103     /*!
104         @brief  確保したメモリブロックを解放します。
105     */
106     virtual void FreeV(void*) = 0;
107 
108     /*!
109         @brief このヒープが利用しているメモリ領域の先頭アドレスを返します。
110     */
111     virtual void* GetStartAddress() const = 0;
112 
113     /*!
114         @brief このヒープが利用しているメモリ領域のサイズを返します。
115     */
116     virtual size_t GetTotalSize() const = 0;
117 
118     /*!
119         @brief デバッグ用にヒープの内容をダンプします。
120     */
121     virtual void Dump() const = 0;
122 
123     /*!
124         @brief  指定したアドレスがヒープに含まれているか調べます。
125 
126         @param[in]  addr    調べたいアドレスを指定します。
127 
128         @return ヒープに含まれていれば true を返し、含まれていなければ false を返します。
129     */
130     virtual bool HasAddress(const void* addr) const = 0;
131 
132     /*!
133         @brief 親のヒープを取得します。
134 
135         @return 親のヒープのアドレスを返します。自分がルートである場合には NULL を返します。
136     */
GetParent()137     HeapBase* GetParent() { return m_Parent; }
138 
139     /*!
140         @brief このヒープのルートとなるヒープを返します。
141 
142         @return このヒープのルートとなるヒープへのポインタを返します。自分がルートである場合には this を返します。
143     */
144     HeapBase* GetRoot();
145 
146     /*!
147         @brief  指定したアドレスが所属するヒープを探索します。
148 
149         @param[in]  addr    探索対象である領域の先頭アドレスを指定します。
150 
151         @return 指定したアドレスが所属するヒープへのポインタを返します。見つからなかった場合は NULL を返します。
152 
153             このヒープおよび、子孫にあたるヒープから指定されたアドレスを含むヒープを探索します。
154             アドレスは階層的にヒープによって持たれますが、最も子孫にあたるヒープのポインタを返します。
155             指定されたアドレスが含まれない場合 NULL を返します。
156     */
157     HeapBase* FindHeap(void* addr);
158 
159     /*!
160         @brief  ヒープ内に作成したヒープを破壊します。
161 
162                 各種ヒープで提供されている Create によりヒープ内に作成されたヒープを捨てる場合に、これを呼び出してください。
163 
164         @param[in]  child   破壊するヒープのアドレスを指定します。
165                             呼び出しもとのヒープが直接の親であるような子ヒープを指定してください。
166 
167     */
168     void Destroy(HeapBase* child);
169 
170 protected:
171 
172     HeapBase(bit32 option = 0) : m_Parent(0), m_Option(0) { Initialize(option); }
173 
Initialize(bit32 option)174     void Initialize(bit32 option) { m_Option = option; }
175 
176     /*!
177         :private
178 
179         @brief  ヒープ内にヒープを作成した場合に親のヒープを設定します。
180 
181                 各種ヒープにて ヒープ内にヒープを作成する Create の内部で使用します。
182     */
183     void SetParent(HeapBase* parent);
184 
RoundDown(uptr addr,s32 alignment)185     static uptr RoundDown(uptr addr, s32 alignment)
186     {
187         return (addr / alignment) * alignment;
188     }
189 
RoundUp(uptr addr,s32 alignment)190     static uptr RoundUp(uptr addr, s32 alignment)
191     {
192         return RoundDown(addr + alignment - 1, alignment);
193     }
194 
FillMemoryZero(uptr addr,size_t size)195     void FillMemoryZero(uptr addr, size_t size)
196     {
197         if(m_Option & NN_FND_HEAP_OPTION_ZERO_CLEAR)
198         {
199             FillMemory32(addr, addr + size, 0);
200         }
201     }
202 
203 #ifdef NN_BUILD_VERBOSE
DebugFillMemory(uptr addr,size_t size,HeapFillType type)204     void DebugFillMemory(uptr addr, size_t size, HeapFillType type)
205     {
206         // TODO: もっと早い関数があるなら置き換え
207         if(this->m_Option & NN_FND_HEAP_OPTION_DEBUG_FILL)
208         {
209             FillMemory32(addr, addr + size, GetFillValue(type));
210         }
211     }
212 #else
DebugFillMemory(uptr,size_t,HeapFillType)213     inline void DebugFillMemory(uptr, size_t, HeapFillType) {}
214 #endif
215 
216 private:
217     HeapBase* m_Parent;
218 
219     IntrusiveLinkedList<HeapBase> m_Children;
220 
221     bit32 m_Option;
222 
223     static void FillMemory(uptr addr, uptr end, bit8 value);
224     static void FillMemory32(uptr addr, uptr end, bit32 value);
225 };
226 
227 }}
228 
229 #endif
230 
231 #endif
232