Files
GTASource/rage/scaleform/Src/GKernel/HeapMH/GHeapFreeBinMH.h
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

142 lines
4.0 KiB
C++

/**********************************************************************
Filename : GHeapFreeBinMH.h
Content :
Created : 2010
Authors : Maxim Shemanarev
Copyright : (c) 2001-2009 Scaleform Corp. All Rights Reserved.
Notes : Containers to store information about free memory areas
Licensees may use this file in accordance with the valid Scaleform
Commercial License Agreement provided with the software.
This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR ANY PURPOSE.
For information regarding Commercial License Agreements go to:
online - http://www.scaleform.com/licensing.html or
email - sales@scaleform.com
**********************************************************************/
#ifndef INC_GHeapFreeBinMH_H
#define INC_GHeapFreeBinMH_H
#include "GHeapRootMH.h"
struct GHeapBinNodeMH
{
#ifdef GFC_64BIT_POINTERS
enum { MinBlocks = 2 };
#else
enum { MinBlocks = 1 };
#endif
UPInt Prev;
UPInt Next;
GHeapPageMH* Page;
UPInt GetBlocks() const
{
return (Prev & 0xF) | ((Next & 0xF) << 4);
}
UPInt GetBytes() const
{
return GetBlocks() << GHeapPageMH::UnitShift;
}
UPInt GetPrevBlocks() const
{
const UPInt* tail = ((const UPInt*)this) - 2;
return (tail[0] & 0xF) | ((tail[1] & 0xF) << 4);
}
UPInt GetPrevBytes() const
{
return GetPrevBlocks() << GHeapPageMH::UnitShift;
}
void SetBlocks(UPInt blocks)
{
UPInt bytes = blocks << GHeapPageMH::UnitShift;
UPInt* tail = ((UPInt*)this) + bytes / sizeof(UPInt) - 2;
tail[0] = Prev = (Prev & ~UPInt(0xF)) | (blocks & 0xF);
tail[1] = Next = (Next & ~UPInt(0xF)) | (blocks >> 4);
}
void SetBytes(UPInt bytes)
{
UPInt blocks = bytes >> GHeapPageMH::UnitShift;
UPInt* tail = ((UPInt*)this) + bytes / sizeof(UPInt) - 2;
tail[0] = Prev = (Prev & ~UPInt(0xF)) | (blocks & 0xF);
tail[1] = Next = (Next & ~UPInt(0xF)) | (blocks >> 4);
}
GHeapPageMH* GetPage()
{
return (GetBlocks() > MinBlocks) ? Page : 0;
}
void SetPage(GHeapPageMH* page)
{
if (GetBlocks() > MinBlocks)
Page = page;
}
GHeapBinNodeMH* GetPrev() const { return (GHeapBinNodeMH*)(Prev & ~UPInt(0xF)); }
GHeapBinNodeMH* GetNext() const { return (GHeapBinNodeMH*)(Next & ~UPInt(0xF)); }
void SetPrev(GHeapBinNodeMH* prev) { Prev = UPInt(prev) | (Prev & 0xF); }
void SetNext(GHeapBinNodeMH* next) { Next = UPInt(next) | (Next & 0xF); }
static GHeapBinNodeMH* MakeNode(UByte* start, UPInt bytes, GHeapPageMH* page)
{
GHeapBinNodeMH* node = (GHeapBinNodeMH*)start;
node->SetBytes(bytes);
node->SetPage(page);
return node;
}
};
//------------------------------------------------------------------------
struct GHeapListBinMH
{
enum { BinSize = 8*sizeof(UPInt) }; // Assume Byte is 8 bits.
GHeapListBinMH();
void Reset();
//--------------------------------------------------------------------
void Push(UByte* node);
void Pull(UByte* node);
GHeapBinNodeMH* PullBest(UPInt blocks);
GHeapBinNodeMH* PullBest(UPInt blocks, UPInt alignMask);
void Merge(UByte* node, UPInt bytes, bool left, bool right, GHeapPageMH* page);
static UByte* GetAlignedPtr(UByte* start, UPInt alignMask);
static bool AlignmentIsOK(const GHeapBinNodeMH* node, UPInt blocks, UPInt alignMask);
private:
void pushNode(UPInt idx, GHeapBinNodeMH* node);
void pullNode(UPInt idx, GHeapBinNodeMH* node);
GHeapBinNodeMH* findAligned(GHeapBinNodeMH* root, UPInt blocks, UPInt alignMask);
GHeapBinNodeMH* getPrevAdjacent(UByte* node) const;
GHeapBinNodeMH* getNextAdjacent(UByte* node) const;
//--------------------------------------------------------------------
UPInt Mask;
GHeapBinNodeMH* Roots[BinSize];
};
#endif