#ifndef JKREXPHEAP_H #define JKREXPHEAP_H #include "JSystem/JKernel/JKRHeap.h" #include "types.h" #ifdef __cplusplus class JKRExpHeap : public JKRHeap { public: class CMemBlock { public: CMemBlock* allocBack(u32, u8, u8, u8, u8); CMemBlock* allocFore(u32, u8, u8, u8, u8); void* free(JKRExpHeap*); static CMemBlock* getHeapBlock(void*); void initiate(CMemBlock*, CMemBlock*, u32, u8, u8); void newGroupId(u8 groupId) { mGroupID = groupId; } bool isValid() const { return mUsageHeader == 'HM'; } bool _isTempMemBlock() const { return (mFlags & 0x80) ? true : false; } int getAlignment() const { return mFlags & 0x7f; } void* getContent() const { return (void*)(this + 1); } CMemBlock* getPrevBlock() const { return mPrev; } CMemBlock* getNextBlock() const { return mNext; } u32 getSize() const { return mAllocatedSpace; } u8 getGroupId() const { return mGroupID; } static CMemBlock* getBlock(void* data) { return (CMemBlock*)((u32)data + -0x10); } u16 mUsageHeader; // _00 u8 mFlags; // _02, a|bbbbbbb = a=temp, b=aln u8 mGroupID; // _03 int mAllocatedSpace; // _04 CMemBlock* mPrev; // _08 CMemBlock* mNext; // _0C }; JKRExpHeap(void*, u32, JKRHeap*, bool); virtual ~JKRExpHeap(); // _08 virtual void* do_alloc(u32, int); // _10 virtual void do_free(void*); // _14 virtual void do_freeTail(); // _18 virtual void do_freeAll(); // _1C virtual s32 do_resize(void*, u32); // _20 virtual s32 do_getSize(void*); // _24 virtual s32 do_getFreeSize(); // _28 virtual s32 do_getTotalFreeSize(); // _2C virtual bool check(); // _34 virtual bool dump_sort(); // _38 virtual bool dump(); // _3C virtual s32 do_changeGroupID(u8); // _40 virtual void state_register(TState*, u32) const; // _48 virtual bool state_compare(const TState&, const TState&) const; // _4C virtual u8 do_getCurrentGroupId() { return mCurrentGroupID; } // _44 (weak) virtual u32 getHeapType() { return 'EXPH'; } // _30 (weak) void* allocFromHead(u32, int); void* allocFromHead(u32); void* allocFromTail(u32, int); void* allocFromTail(u32); void appendUsedList(CMemBlock*); static JKRExpHeap* create(u32, JKRHeap*, bool); static JKRExpHeap* create(void*, u32, JKRHeap*, bool); static JKRExpHeap* createRoot(int, bool); int freeGroup(u8 groupID); void joinTwoBlocks(CMemBlock*); void recycleFreeBlock(CMemBlock*); void removeFreeBlock(CMemBlock*); void setFreeBlock(CMemBlock*, CMemBlock*, CMemBlock*); // unused/inlined: void removeUsedBlock(CMemBlock*); bool isEmpty(); s32 getUsedSize(u8 groupId) const; CMemBlock* getHeadUsedList() const { return mHeadUsedList; } void setAllocationMode(EAllocMode mode) { mCurrentAllocMode = mode; } static s32 getUsedSize_(JKRExpHeap* expHeap) { // s32 totalFreeSize = expHeap->getTotalFreeSize(); return expHeap->mSize - expHeap->getTotalFreeSize(); } static u32 getState_(TState* state) { return getState_buf_(state); } // might instead be a pointer to a next state? private: // _00 = VTBL // _00-_6C = JKRHeap u8 mCurrentAllocMode; // _6C u8 mCurrentGroupID; // _6D u8 _6E; // _6E void* _70; // _70 u32 _74; // _74 CMemBlock* mHead; // _78, free list CMemBlock* mTail; // _7C, free list CMemBlock* mHeadUsedList; // _80 CMemBlock* mTailUsedList; // _84 }; inline JKRExpHeap* JKRCreateExpHeap(u32 size, JKRHeap* parent, bool errorFlag) { return JKRExpHeap::create(size, parent, errorFlag); } #endif #endif /* JKREXPHEAP_H */