/*---------------------------------------------------------------------------* Project: Horizon File: fnd_HeapBase.h Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 24328 $ *---------------------------------------------------------------------------*/ /*! @file @brief ヒープの基底クラスの宣言 */ #ifndef NN_FND_FND_HEAPBASE_H_ #define NN_FND_FND_HEAPBASE_H_ #include #include #include // デフォルトアラインメント #define NN_FND_HEAP_DEFAULT_ALIGNMENT 4 // メモリ確保時にメモリを0でクリア #define NN_FND_HEAP_OPTION_ZERO_CLEAR (1 << 0) // ヒープ作成時・メモリ確保・解放時にメモリ充填 #define NN_FND_HEAP_OPTION_DEBUG_FILL (1 << 1) // このビットが立っているとエラー出力 #define NN_FND_HEAP_OPTION_ERROR_PRINT (1 << 0) #ifdef __cplusplus namespace nn { namespace fnd { /*! @brief ヒープをフィルする種別を表わす定数 */ enum HeapFillType { HEAP_FILL_TYPE_NOUSE, //!< デバッグフィル未使用時 HEAP_FILL_TYPE_ALLOC, //!< デバッグフィル確保時 HEAP_FILL_TYPE_FREE, //!< デバッグフィル解放時 HEAP_FILL_TYPE_MAX }; enum HeapInfoPlacement { HEAP_INFOPLACEMENT_HEAD, HEAP_INFOPLACEMENT_TAIL }; /*! @brief ヒープ領域を縮小する種別を表す定数 */ enum HeapAdjustMode { HEAP_ADJUST_TAIL = 1, //!< ヒープのメモリ領域を末尾に縮める HEAP_ADJUST_HEAD = -1 //!< ヒープをメモリ領域を先頭に縮める }; /*! @brief ヒープの基底クラスです。 このクラスをインスタンス化することはできません。 */ class HeapBase : public IntrusiveLinkedList::Item { public: static const s32 DEFAULT_ALIGNMENT = 4; static const bit32 OPTION_ERROR_PRINT = NN_FND_HEAP_OPTION_ERROR_PRINT; /*! @brief ヒープをフィルする種別、値を設定します。 @param[in] type ヒープをフィルする種別 @param[in] val ヒープをフィルする値 */ static void SetFillValue(HeapFillType type, bit32 val); /*! @brief ヒープをフィルする種別を取得します。 @return ヒープをフィルする種別を返します。 */ static bit32 GetFillValue(HeapFillType type); /*! @brief デストラクタです。 */ virtual ~HeapBase() = 0; /*! @brief 確保したメモリブロックを解放します。 */ virtual void FreeV(void*) = 0; /*! @brief このヒープが利用しているメモリ領域の先頭アドレスを返します。 */ virtual void* GetStartAddress() const = 0; /*! @brief このヒープが利用しているメモリ領域のサイズを返します。 */ virtual size_t GetTotalSize() const = 0; /*! @brief デバッグ用にヒープの内容をダンプします。 */ virtual void Dump() const = 0; /*! @brief 指定したアドレスがヒープに含まれているか調べます。 @param[in] addr 調べたいアドレスを指定します。 @return ヒープに含まれていれば true を返し、含まれていなければ false を返します。 */ virtual bool HasAddress(const void* addr) const = 0; /*! @brief 親のヒープを取得します。 @return 親のヒープのアドレスを返します。自分がルートである場合には NULL を返します。 */ HeapBase* GetParent() { return m_Parent; } /*! @brief このヒープのルートとなるヒープを返します。 @return このヒープのルートとなるヒープへのポインタを返します。自分がルートである場合には this を返します。 */ HeapBase* GetRoot(); /*! @brief 指定したアドレスが所属するヒープを探索します。 @param[in] addr 探索対象である領域の先頭アドレスを指定します。 @return 指定したアドレスが所属するヒープへのポインタを返します。見つからなかった場合は NULL を返します。 このヒープおよび、子孫にあたるヒープから指定されたアドレスを含むヒープを探索します。 アドレスは階層的にヒープによって持たれますが、最も子孫にあたるヒープのポインタを返します。 指定されたアドレスが含まれない場合 NULL を返します。 */ HeapBase* FindHeap(void* addr); /*! @brief ヒープ内に作成したヒープを破壊します。 各種ヒープで提供されている Create によりヒープ内に作成されたヒープを捨てる場合に、これを呼び出してください。 @param[in] child 破壊するヒープのアドレスを指定します。 呼び出しもとのヒープが直接の親であるような子ヒープを指定してください。 */ void Destroy(HeapBase* child); protected: HeapBase(bit32 option = 0) : m_Parent(0), m_Option(0) { Initialize(option); } void Initialize(bit32 option) { m_Option = option; } /*! :private @brief ヒープ内にヒープを作成した場合に親のヒープを設定します。 各種ヒープにて ヒープ内にヒープを作成する Create の内部で使用します。 */ void SetParent(HeapBase* parent); static uptr RoundDown(uptr addr, s32 alignment) { return (addr / alignment) * alignment; } static uptr RoundUp(uptr addr, s32 alignment) { return RoundDown(addr + alignment - 1, alignment); } void FillMemoryZero(uptr addr, size_t size) { if(m_Option & NN_FND_HEAP_OPTION_ZERO_CLEAR) { FillMemory32(addr, addr + size, 0); } } #ifdef NN_BUILD_VERBOSE void DebugFillMemory(uptr addr, size_t size, HeapFillType type) { // TODO: もっと早い関数があるなら置き換え if(this->m_Option & NN_FND_HEAP_OPTION_DEBUG_FILL) { FillMemory32(addr, addr + size, GetFillValue(type)); } } #else inline void DebugFillMemory(uptr, size_t, HeapFillType) {} #endif private: HeapBase* m_Parent; IntrusiveLinkedList m_Children; bit32 m_Option; static void FillMemory(uptr addr, uptr end, bit8 value); static void FillMemory32(uptr addr, uptr end, bit32 value); }; }} #endif #endif