- Removed generational garbage collection from the string pool because it didn't

actually work.
- Turned the list of TabCommands into a TArray because I saw lots of console
  commands in the memory leak report at exit. Then I realized those were actually
  key bindings, so I changed the Bindings and DoubleBindings arrays into FString
  arrays.
- Fixed: FStringCVar was missing a destructor.
- Added TArray::Insert().
- Fixed: TArray::Delete() used memmove().
- Renamed Malloc(), Realloc(), and Calloc() to M_Malloc(), M_Realloc(), and
  M_Calloc() so that the debug versions can be defined as macros.
- Enabled the CRT's memory leak detection in WinMain().
- Moved contents of PO_DeInit() into P_FreeLevelData().
- Removed "PolyBlockMap = NULL;" from P_SetupLevel(), because the P_FreeLevelData()
  call it makes next does the exact same thing, but also freeing it if needed.
- Fixed: Unneeded memcpy in UnpackUserCmd() when ucmd and basis are the same


SVN r75 (trunk)
This commit is contained in:
Randy Heit 2006-05-04 03:49:46 +00:00
parent ea3b76815d
commit c8cdb52863
38 changed files with 264 additions and 242 deletions

View file

@ -1,4 +1,20 @@
May 3, 2006
- Removed generational garbage collection from the string pool because it didn't
actually work.
- Turned the list of TabCommands into a TArray because I saw lots of console
commands in the memory leak report at exit. Then I realized those were actually
key bindings, so I changed the Bindings and DoubleBindings arrays into FString
arrays.
- Fixed: FStringCVar was missing a destructor.
- Added TArray::Insert().
- Fixed: TArray::Delete() used memmove().
- Renamed Malloc(), Realloc(), and Calloc() to M_Malloc(), M_Realloc(), and
M_Calloc() so that the debug versions can be defined as macros.
- Enabled the CRT's memory leak detection in WinMain().
- Moved contents of PO_DeInit() into P_FreeLevelData().
- Removed "PolyBlockMap = NULL;" from P_SetupLevel(), because the P_FreeLevelData()
call it makes next does the exact same thing, but also freeing it if needed.
- Fixed: Unneeded memcpy in UnpackUserCmd() when ucmd and basis are the same
- Removed -bpal parameter. Blood's blood.pal is loaded from blood.rff, and
its tiles are loaded from the same directory.
- RFF files now load their entire directories into the lumplist.

View file

@ -244,9 +244,8 @@ const char *KeyNames[NUM_KEYS] =
"mwheelup", "mwheeldown", // the mouse wheel
};
static char *Bindings[NUM_KEYS];
static char *DoubleBindings[NUM_KEYS];
static FString Bindings[NUM_KEYS];
static FString DoubleBindings[NUM_KEYS];
static unsigned int DClickTime[NUM_KEYS];
static byte DClicked[(NUM_KEYS+7)/8];
@ -343,7 +342,7 @@ CCMD (bind)
}
else
{
ReplaceString (&Bindings[i], argv[2]);
Bindings[i] = argv[2];
}
}
else
@ -438,7 +437,7 @@ CCMD (doublebind)
}
else
{
ReplaceString (&DoubleBindings[i], argv[2]);
DoubleBindings[i] = argv[2];
}
}
else
@ -455,7 +454,7 @@ CCMD (doublebind)
CCMD (rebind)
{
char **bindings;
FString *bindings;
if (key == 0)
{
@ -475,7 +474,7 @@ CCMD (rebind)
if (argv.argc() > 1)
{
ReplaceString (&bindings[key], argv[1]);
bindings[key] = argv[1];
}
}
@ -603,7 +602,7 @@ BOOL C_DoKey (event_t *ev)
void C_ArchiveBindings (FConfigFile *f, bool dodouble, const char *matchcmd)
{
char **bindings;
FString *bindings;
const char *name;
int i;
@ -660,7 +659,7 @@ void C_DoBind (const char *key, const char *bind, bool dodouble)
}
if (keynum != 0)
{
ReplaceString ((dodouble ? DoubleBindings : Bindings) + keynum, bind);
(dodouble ? DoubleBindings : Bindings)[keynum] = bind;
}
}
@ -734,5 +733,5 @@ void C_ChangeBinding (const char *str, int newone)
char *C_GetBinding (int key)
{
return (unsigned int)key < NUM_KEYS ? Bindings[key] : NULL;
return (unsigned int)key < NUM_KEYS ? Bindings[key].GetChars() : NULL;
}

View file

@ -574,7 +574,7 @@ void AddToConsole (int printlevel, const char *text)
}
if (size > worklen)
{
work = (char *)Realloc (work, size);
work = (char *)M_Realloc (work, size);
worklen = size;
}
if (work == NULL)
@ -1487,7 +1487,7 @@ static BOOL C_HandleKey (event_t *ev, byte *buffer, int len)
// or there is nothing in the history list,
// so add it to the history list.
History *temp = (History *)Malloc (sizeof(struct History) + buffer[0]);
History *temp = (History *)M_Malloc (sizeof(struct History) + buffer[0]);
strcpy (temp->String, (char *)&buffer[2]);
temp->Older = HistHead;
@ -1700,12 +1700,28 @@ void C_MidPrintBold (const char *msg)
/****** Tab completion code ******/
static struct TabData
struct TabData
{
int UseCount;
char *Name;
} *TabCommands = NULL;
static int NumTabCommands = 0;
FString Name;
TabData()
: UseCount(0)
{
}
TabData(const char *name)
: UseCount(1), Name(name)
{
}
TabData(const TabData &other)
: UseCount(other.UseCount), Name(other.Name)
{
}
};
static TArray<TabData> TabCommands;
static int TabPos; // Last TabCommand tabbed to
static int TabStart; // First char in CmdLine to use for tab completion
static int TabSize; // Size of tab string
@ -1714,7 +1730,7 @@ static BOOL FindTabCommand (const char *name, int *stoppos, int len)
{
int i, cval = 1;
for (i = 0; i < NumTabCommands; i++)
for (i = 0; i < TabCommands.Size(); i++)
{
cval = strnicmp (TabCommands[i].Name, name, len);
if (cval >= 0)
@ -1736,15 +1752,8 @@ void C_AddTabCommand (const char *name)
}
else
{
NumTabCommands++;
TabCommands = (TabData *)Realloc (TabCommands, sizeof(struct TabData) * NumTabCommands);
if (pos < NumTabCommands - 1)
{
memmove (TabCommands + pos + 1, TabCommands + pos,
(NumTabCommands - pos - 1) * sizeof(struct TabData));
}
TabCommands[pos].Name = copystring (name);
TabCommands[pos].UseCount = 1;
TabData tab(name);
TabCommands.Insert (pos, tab);
}
}
@ -1756,13 +1765,7 @@ void C_RemoveTabCommand (const char *name)
{
if (--TabCommands[pos].UseCount == 0)
{
NumTabCommands--;
delete[] TabCommands[pos].Name;
if (pos < NumTabCommands - 1)
{
memmove (TabCommands + pos, TabCommands + pos + 1,
(NumTabCommands - pos - 1) * sizeof(struct TabData));
}
TabCommands.Delete(pos);
}
}
}
@ -1827,7 +1830,7 @@ static void C_TabComplete (bool goForward)
}
else
{ // Find the last matching tab, then go one past it.
while (++TabPos < NumTabCommands)
while (++TabPos < TabCommands.Size())
{
if (FindDiffPoint (TabCommands[TabPos].Name, (char *)(CmdLine + TabStart)) < TabSize)
{
@ -1842,7 +1845,7 @@ static void C_TabComplete (bool goForward)
}
}
if ((goForward && ++TabPos == NumTabCommands) ||
if ((goForward && ++TabPos == TabCommands.Size()) ||
(!goForward && --TabPos < 0))
{
TabbedLast = false;
@ -1878,7 +1881,7 @@ static bool C_TabCompleteList ()
nummatches = 0;
maxwidth = 0;
for (i = TabPos; i < NumTabCommands; ++i)
for (i = TabPos; i < TabCommands.Size(); ++i)
{
if (FindDiffPoint (TabCommands[i].Name, (char *)(CmdLine + TabStart)) < TabSize)
{

View file

@ -783,6 +783,17 @@ FStringCVar::FStringCVar (const char *name, const char *def, DWORD flags, void (
DefaultValue = copystring (def);
if (Flags & CVAR_ISDEFAULT)
Value = copystring (def);
else
Value = NULL;
}
FStringCVar::~FStringCVar ()
{
if (Value != NULL)
{
delete[] Value;
}
delete[] DefaultValue;
}
ECVarType FStringCVar::GetRealType () const

View file

@ -257,6 +257,7 @@ class FStringCVar : public FBaseCVar
{
public:
FStringCVar (const char *name, const char *def, DWORD flags, void (*callback)(FStringCVar &)=NULL);
~FStringCVar ();
virtual ECVarType GetRealType () const;

View file

@ -306,7 +306,7 @@ static const char *IsNum (const char *str)
static FStringProd *NewStringProd (const char *str)
{
FStringProd *prod = (FStringProd *)Malloc (sizeof(FStringProd)+strlen(str));
FStringProd *prod = (FStringProd *)M_Malloc (sizeof(FStringProd)+strlen(str));
prod->Type = PROD_String;
strcpy (prod->Value, str);
return prod;
@ -320,7 +320,7 @@ static FStringProd *NewStringProd (const char *str)
static FStringProd *NewStringProd (size_t len)
{
FStringProd *prod = (FStringProd *)Malloc (sizeof(FStringProd)+len);
FStringProd *prod = (FStringProd *)M_Malloc (sizeof(FStringProd)+len);
prod->Type = PROD_String;
prod->Value[0] = 0;
return prod;
@ -334,7 +334,7 @@ static FStringProd *NewStringProd (size_t len)
static FDoubleProd *NewDoubleProd (double val)
{
FDoubleProd *prod = (FDoubleProd *)Malloc (sizeof(FDoubleProd));
FDoubleProd *prod = (FDoubleProd *)M_Malloc (sizeof(FDoubleProd));
prod->Type = PROD_Double;
prod->Value = val;
return prod;

View file

@ -1942,7 +1942,7 @@ static int PatchStrings (int dummy)
DPrintf ("[Strings]\n");
if (!holdstring)
holdstring = (char *)Malloc (maxstrlen);
holdstring = (char *)M_Malloc (maxstrlen);
while ((result = GetLine()) == 1)
{
@ -1952,7 +1952,7 @@ static int PatchStrings (int dummy)
while (maxstrlen < strlen (holdstring) + strlen (Line2) + 8)
{
maxstrlen += 128;
holdstring = (char *)Realloc (holdstring, maxstrlen);
holdstring = (char *)M_Realloc (holdstring, maxstrlen);
}
strcat (holdstring, skipwhite (Line2));
stripwhite (holdstring);

View file

@ -662,7 +662,7 @@ CCMD (atexit)
}
for (int i = 1; i < argv.argc(); ++i)
{
GameAtExit *record = (GameAtExit *)Malloc (
GameAtExit *record = (GameAtExit *)M_Malloc (
sizeof(GameAtExit)+strlen(argv[i]));
strcpy (record->Command, argv[i]);
record->Next = ExitCmdList;
@ -1105,7 +1105,7 @@ void D_AddFile (const char *file)
}
file = f;
}
wadlist_t *wad = (wadlist_t *)Malloc (sizeof(*wad) + strlen(file));
wadlist_t *wad = (wadlist_t *)M_Malloc (sizeof(*wad) + strlen(file));
*wadtail = wad;
wad->next = NULL;

View file

@ -178,7 +178,7 @@ static struct TicSpecial
for (i = 0; i < BACKUPTICS; i++)
{
streams[i] = (byte *)Malloc (256);
streams[i] = (byte *)M_Malloc (256);
used[i] = 0;
}
okay = true;
@ -210,7 +210,7 @@ static struct TicSpecial
DPrintf ("Expanding special size to %d\n", specialsize);
for (i = 0; i < BACKUPTICS; i++)
streams[i] = (byte *)Realloc (streams[i], specialsize);
streams[i] = (byte *)M_Realloc (streams[i], specialsize);
streamptr = streams[(maketic/ticdup)%BACKUPTICS] + streamoffs;
}
@ -1911,7 +1911,7 @@ void FDynamicBuffer::SetData (const byte *data, int len)
if (len > m_BufferLen)
{
m_BufferLen = (len + 255) & ~255;
m_Data = (byte *)Realloc (m_Data, m_BufferLen);
m_Data = (byte *)M_Realloc (m_Data, m_BufferLen);
}
if (data)
{

View file

@ -124,9 +124,16 @@ int UnpackUserCmd (usercmd_t *ucmd, const usercmd_t *basis, byte **stream)
byte flags;
if (basis != NULL)
memcpy (ucmd, basis, sizeof(usercmd_t));
{
if (basis != ucmd)
{
memcpy (ucmd, basis, sizeof(usercmd_t));
}
}
else
{
memset (ucmd, 0, sizeof(usercmd_t));
}
flags = ReadByte (stream);

View file

@ -85,7 +85,7 @@ void TypeInfo::RegisterType ()
if (m_NumTypes == m_MaxTypes)
{
m_MaxTypes = m_MaxTypes ? m_MaxTypes*2 : 256;
m_Types = (TypeInfo **)Realloc (m_Types, m_MaxTypes * sizeof(*m_Types));
m_Types = (TypeInfo **)M_Realloc (m_Types, m_MaxTypes * sizeof(*m_Types));
}
m_Types[m_NumTypes] = this;
TypeIndex = m_NumTypes;
@ -162,7 +162,7 @@ const TypeInfo *TypeInfo::IFindType (const char *name)
// Create a new object that this type represents
DObject *TypeInfo::CreateNew () const
{
BYTE *mem = (BYTE *)Malloc (SizeOf);
BYTE *mem = (BYTE *)M_Malloc (SizeOf);
ConstructNative (mem);
((DObject *)mem)->SetClass (const_cast<TypeInfo *>(this));

View file

@ -310,7 +310,7 @@ public:
void *operator new(size_t len)
{
return Malloc(len);
return M_Malloc(len);
}
void operator delete (void *mem)

View file

@ -202,7 +202,7 @@ void FCompressedFile::PostOpen ()
sizes[0] = SWAP_DWORD (sizes[0]);
sizes[1] = SWAP_DWORD (sizes[1]);
unsigned int len = sizes[0] == 0 ? sizes[1] : sizes[0];
m_Buffer = (byte *)Malloc (len+8);
m_Buffer = (byte *)M_Malloc (len+8);
fread (m_Buffer+8, len, 1, m_File);
sizes[0] = SWAP_DWORD (sizes[0]);
sizes[1] = SWAP_DWORD (sizes[1]);
@ -256,7 +256,7 @@ FFile &FCompressedFile::Write (const void *mem, unsigned int len)
m_MaxBufferSize = m_MaxBufferSize ? m_MaxBufferSize * 2 : 16384;
}
while (m_Pos + len > m_MaxBufferSize);
m_Buffer = (byte *)Realloc (m_Buffer, m_MaxBufferSize);
m_Buffer = (byte *)M_Realloc (m_Buffer, m_MaxBufferSize);
}
if (len == 1)
m_Buffer[m_Pos] = *(BYTE *)mem;
@ -357,7 +357,7 @@ void FCompressedFile::Implode ()
}
m_MaxBufferSize = m_BufferSize = ((outlen == 0) ? len : outlen);
m_Buffer = (BYTE *)Malloc (m_BufferSize + 8);
m_Buffer = (BYTE *)M_Malloc (m_BufferSize + 8);
m_Pos = 0;
DWORD *lens = (DWORD *)(m_Buffer);
@ -384,7 +384,7 @@ void FCompressedFile::Explode ()
cprlen = BigLong(ints[0]);
expandsize = BigLong(ints[1]);
expand = (unsigned char *)Malloc (expandsize);
expand = (unsigned char *)M_Malloc (expandsize);
if (cprlen)
{
int r;
@ -467,7 +467,7 @@ bool FCompressedMemFile::Open ()
m_Mode = EWriting;
m_BufferSize = 0;
m_MaxBufferSize = 16384;
m_Buffer = (unsigned char *)Malloc (16384);
m_Buffer = (unsigned char *)M_Malloc (16384);
m_Pos = 0;
return true;
}
@ -527,7 +527,7 @@ void FCompressedMemFile::Serialize (FArchive &arc)
arc << sizes[0] << sizes[1];
DWORD len = sizes[0] == 0 ? sizes[1] : sizes[0];
m_Buffer = (BYTE *)Malloc (len+8);
m_Buffer = (BYTE *)M_Malloc (len+8);
((DWORD *)m_Buffer)[0] = SWAP_DWORD(sizes[0]);
((DWORD *)m_Buffer)[1] = SWAP_DWORD(sizes[1]);
arc.Read (m_Buffer+8, len);
@ -550,7 +550,7 @@ FPNGChunkFile::FPNGChunkFile (FILE *file, DWORD id)
FPNGChunkFile::FPNGChunkFile (FILE *file, DWORD id, unsigned int chunklen)
: FCompressedFile (file, EReading, true, false), m_ChunkID (id)
{
m_Buffer = (byte *)Malloc (chunklen);
m_Buffer = (byte *)M_Malloc (chunklen);
m_BufferSize = chunklen;
fread (m_Buffer, chunklen, 1, m_File);
// Skip the CRC for now. Maybe later it will be used.
@ -1371,7 +1371,7 @@ DWORD FArchive::MapObject (const DObject *obj)
if (m_ObjectCount >= m_MaxObjectCount)
{
m_MaxObjectCount = m_MaxObjectCount ? m_MaxObjectCount * 2 : 1024;
m_ObjectMap = (ObjectMap *)Realloc (m_ObjectMap, sizeof(ObjectMap)*m_MaxObjectCount);
m_ObjectMap = (ObjectMap *)M_Realloc (m_ObjectMap, sizeof(ObjectMap)*m_MaxObjectCount);
for (i = m_ObjectCount; i < m_MaxObjectCount; i++)
{
m_ObjectMap[i].hashNext = ~0;

View file

@ -2138,7 +2138,7 @@ void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf)
ptrdiff_t body = demobodyspot - demobuffer;
// [RH] Allocate more space for the demo
maxdemosize += 0x20000;
demobuffer = (byte *)Realloc (demobuffer, maxdemosize);
demobuffer = (byte *)M_Realloc (demobuffer, maxdemosize);
demo_p = demobuffer + pos;
lenspot = demobuffer + spot;
democompspot = demobuffer + comp;
@ -2164,7 +2164,7 @@ void G_RecordDemo (char* name)
maxdemosize = atoi(v)*1024;
if (maxdemosize < 0x20000)
maxdemosize = 0x20000;
demobuffer = (byte *)Malloc (maxdemosize);
demobuffer = (byte *)M_Malloc (maxdemosize);
demorecording = true;
}

View file

@ -537,7 +537,7 @@ static void G_DoParseMapInfo (int lump)
if (levelindex == -1)
{
levelindex = numwadlevelinfos++;
wadlevelinfos = (level_info_t *)Realloc (wadlevelinfos, sizeof(level_info_t)*numwadlevelinfos);
wadlevelinfos = (level_info_t *)M_Realloc (wadlevelinfos, sizeof(level_info_t)*numwadlevelinfos);
}
levelinfo = wadlevelinfos + levelindex;
memcpy (levelinfo, &defaultinfo, sizeof(*levelinfo));
@ -602,7 +602,7 @@ static void G_DoParseMapInfo (int lump)
if (clusterindex == -1)
{
clusterindex = numwadclusterinfos++;
wadclusterinfos = (cluster_info_t *)Realloc (wadclusterinfos, sizeof(cluster_info_t)*numwadclusterinfos);
wadclusterinfos = (cluster_info_t *)M_Realloc (wadclusterinfos, sizeof(cluster_info_t)*numwadclusterinfos);
clusterinfo = wadclusterinfos + clusterindex;
}
else
@ -836,7 +836,7 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
if (FindWadClusterInfo (sc_Number) == -1)
{
int clusterindex = numwadclusterinfos++;
wadclusterinfos = (cluster_info_t *)Realloc (wadclusterinfos, sizeof(cluster_info_t)*numwadclusterinfos);
wadclusterinfos = (cluster_info_t *)M_Realloc (wadclusterinfos, sizeof(cluster_info_t)*numwadclusterinfos);
clusterinfo = wadclusterinfos + clusterindex;
memset (clusterinfo, 0, sizeof(cluster_info_t));
clusterinfo->cluster = sc_Number;

View file

@ -41,18 +41,19 @@
// except they bomb out with an error requester
// when they can't get the memory.
void *Malloc (size_t size);
void *Calloc (size_t num, size_t size);
void *Realloc (void *memblock, size_t size);
void *M_Malloc (size_t size);
void *M_Calloc (size_t num, size_t size);
void *M_Realloc (void *memblock, size_t size);
#else
#include <stdlib.h>
#include <crtdbg.h>
inline void *Malloc(size_t size) { return malloc (size); }
inline void *Calloc(size_t num, size_t size) { return calloc (num, size); }
inline void *Realloc(void *memblock, size_t size) { return realloc (memblock, size); }
#define M_Malloc(size) malloc(size)
#define M_Calloc(num, size) calloc(num, size)
#define M_Realloc(memblock, size) realloc(memblock, size)
#endif
#endif //__M_ALLOC_H__

View file

@ -182,7 +182,7 @@ void M_FindResponseFile (void)
if (argc != 0)
{
argv = (char **)Malloc (argc*sizeof(char *) + argsize);
argv = (char **)M_Malloc (argc*sizeof(char *) + argsize);
argv[i] = (char *)argv + argc*sizeof(char *);
ParseCommandLine (file, NULL, argv+i);

View file

@ -82,45 +82,22 @@ private:
static bool Inited;
#ifndef __GNUC__
template<> friend bool NeedsDestructor<MainName> () { return true; }
template<> friend void CopyForTArray<MainName> (MainName &dst, MainName &src)
{
dst.NextHash = src.NextHash;
CopyForTArray (dst.Text, src.Text);
}
template<> friend void ConstructInTArray<MainName> (MainName *dst, const MainName &src)
{
new (dst) FName::MainName(src);
}
template<> friend void ConstructEmptyInTArray<MainName> (MainName *dst)
{
new (dst) FName::MainName;
}
#else
template<class MainName> friend inline bool NeedsDestructor ();
template<class MainName> friend inline void CopyForTArray (MainName &dst, MainName &src);
template<class MainName> friend inline void ConstructInTArray (MainName *dst, const MainName &src);
template<class MainName> friend inline void ConstructEmptyInTArray (MainName *dst);
#endif
};
#ifdef __GNUC__
template<> inline bool NeedsDestructor<FName::MainName> () { return true; }
template<> inline void CopyForTArray<FName::MainName> (FName::MainName &dst, FName::MainName &src)
{
dst.NextHash = src.NextHash;
CopyForTArray (dst.Text, src.Text);
}
template<> inline void ConstructInTArray<FName::MainName> (FName::MainName *dst, const FName::MainName &src)
{
new (dst) FName::MainName(src);
}
template<> inline void ConstructEmptyInTArray<FName::MainName> (FName::MainName *dst)
{
new (dst) FName::MainName;
}
#endif
#endif

View file

@ -476,7 +476,6 @@ extern polyspawns_t *polyspawns; // [RH] list of polyobject things to spawn
BOOL PO_MovePolyobj (int num, int x, int y);
BOOL PO_RotatePolyobj (int num, angle_t angle);
void PO_Init ();
void PO_DeInit ();
BOOL PO_Busy (int polyobj);
//

View file

@ -4260,7 +4260,7 @@ msecnode_t *P_GetSecnode()
}
else
{
node = (msecnode_t *)Malloc (sizeof(*node));
node = (msecnode_t *)M_Malloc (sizeof(*node));
}
return node;
}

View file

@ -2853,6 +2853,12 @@ void P_FreeLevelData ()
delete[] PolyBlockMap;
PolyBlockMap = NULL;
}
po_NumPolyobjs = 0;
if (polyobjs != NULL)
{
delete[] polyobjs;
polyobjs = NULL;
}
if (rejectmatrix != NULL)
{
delete[] rejectmatrix;
@ -2951,7 +2957,6 @@ void P_SetupLevel (char *lumpname, int position)
// [RH] clear out the mid-screen message
C_MidPrint (NULL);
PolyBlockMap = NULL;
// Free all level data from the previous map
P_FreeLevelData ();
@ -3181,8 +3186,6 @@ void P_SetupLevel (char *lumpname, int position)
for (i = 0; i < BODYQUESIZE; i++)
bodyque[i] = NULL;
PO_DeInit (); // Flush polyobjs from previous map
deathmatchstarts.Clear ();
if (!buildmap)

View file

@ -461,7 +461,7 @@ static void ParseAnim (bool istex)
sink.Countdown = frames[0].SpeedMin;
sink.NumFrames = frames.Size();
newAnim = (FAnimDef *)Malloc (sizeof(FAnimDef) + (frames.Size()-1)*sizeof(FAnimDef::FAnimFrame));
newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1)*sizeof(FAnimDef::FAnimFrame));
*newAnim = sink;
for (i = 0; i < frames.Size(); ++i)
@ -471,7 +471,7 @@ static void ParseAnim (bool istex)
}
else
{
newAnim = (FAnimDef *)Malloc (sizeof(FAnimDef));
newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
*newAnim = sink;
}
@ -588,7 +588,7 @@ void P_InitPicAnims (void)
anim.Frames[0].FramePic = anim.BasePic;
anim.Countdown = anim.Frames[0].SpeedMin - 1;
newAnim = (FAnimDef *)Malloc (sizeof(FAnimDef));
newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
*newAnim = anim;
Anims.Push (newAnim);
}
@ -600,7 +600,7 @@ void P_InitPicAnims (void)
void P_AddSimpleAnim (int picnum, int animcount, int animtype, int animspeed)
{
FAnimDef *anim = (FAnimDef *)Malloc (sizeof(FAnimDef));
FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
anim->bUniqueFrames = false;
anim->CurFrame = 0;
anim->BasePic = picnum;

View file

@ -149,8 +149,8 @@ void P_InitSwitchList ()
((gameinfo.maxSwitch & ~15) == (list_p[18] & ~15)) &&
TexMan.CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags) >= 0)
{
def1 = (FSwitchDef *)Malloc (sizeof(FSwitchDef));
def2 = (FSwitchDef *)Malloc (sizeof(FSwitchDef));
def1 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
def1->PreTexture = def2->u.Textures[2] = TexMan.CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags);
def2->PreTexture = def1->u.Textures[2] = TexMan.CheckForTexture (list_p + 9, FTexture::TEX_Wall, texflags);
def1->Sound = def2->Sound = 0;
@ -300,7 +300,7 @@ void P_ProcessSwitchDef ()
// it to the original texture without doing anything interesting
if (def2 == NULL)
{
def2 = (FSwitchDef *)Malloc (sizeof(FSwitchDef));
def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
def2->Sound = def1->Sound;
def2->NumFrames = 1;
def2->u.Times[0] = 0;
@ -399,7 +399,7 @@ FSwitchDef *ParseSwitchDef (bool ignoreBad)
{
return NULL;
}
def = (FSwitchDef *)Malloc (myoffsetof (FSwitchDef, u.Times[0]) + numframes * 6);
def = (FSwitchDef *)M_Malloc (myoffsetof (FSwitchDef, u.Times[0]) + numframes * 6);
def->Sound = sound;
def->NumFrames = numframes;
memcpy (&def->u.Times[0], times, numframes * 4);

View file

@ -268,7 +268,7 @@ void P_InitTerrainTypes ()
int size;
size = (TexMan.NumTextures()+1)*sizeof(byte);
TerrainTypes = (byte *)Malloc (size);
TerrainTypes = (byte *)M_Malloc (size);
memset (TerrainTypes, 0, size);
MakeDefaultTerrain ();

View file

@ -1541,27 +1541,6 @@ void PO_Init (void)
KillSegLists ();
}
//==========================================================================
//
// PO_DeInit
//
//==========================================================================
void PO_DeInit ()
{
po_NumPolyobjs = 0;
if (polyobjs != NULL)
{
delete[] polyobjs;
polyobjs = NULL;
}
if (PolyBlockMap != NULL)
{
delete[] PolyBlockMap;
PolyBlockMap = NULL;
}
}
//==========================================================================
//
// PO_Busy

View file

@ -119,7 +119,7 @@ void R_ClearDrawSegs (void)
if (drawsegs == NULL)
{
MaxDrawSegs = 256; // [RH] Default. Increased as needed.
firstdrawseg = drawsegs = (drawseg_t *)Malloc (MaxDrawSegs * sizeof(drawseg_t));
firstdrawseg = drawsegs = (drawseg_t *)M_Malloc (MaxDrawSegs * sizeof(drawseg_t));
}
FirstInterestingDrawseg = 0;
InterestingDrawsegs.Clear ();

View file

@ -308,7 +308,7 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
int height;
int width;
foo = (patch_t *)Malloc (data.GetLength());
foo = (patch_t *)M_Malloc (data.GetLength());
data.Seek (-4, SEEK_CUR);
data.Read (foo, data.GetLength());
@ -823,7 +823,7 @@ FTexture::Span **FTexture::CreateSpans (const BYTE *pixels) const
if (!bMasked)
{ // Texture does not have holes, so it can use a simpler span structure
spans = (Span **)Malloc (sizeof(Span*)*Width + sizeof(Span)*2);
spans = (Span **)M_Malloc (sizeof(Span*)*Width + sizeof(Span)*2);
span = (Span *)&spans[Width];
for (int x = 0; x < Width; ++x)
{
@ -867,7 +867,7 @@ FTexture::Span **FTexture::CreateSpans (const BYTE *pixels) const
}
// Allocate space for the spans
spans = (Span **)Malloc (sizeof(Span*)*numcols + sizeof(Span)*numspans);
spans = (Span **)M_Malloc (sizeof(Span*)*numcols + sizeof(Span)*numspans);
// Fill in the spans
for (x = 0, span = (Span *)&spans[numcols], data_p = pixels; x < numcols; ++x)
@ -1271,7 +1271,7 @@ void FPatchTexture::MakeTexture ()
}
// Create the spans
Spans = (Span **)Malloc (sizeof(Span*)*Width + sizeof(Span)*numspans);
Spans = (Span **)M_Malloc (sizeof(Span*)*Width + sizeof(Span)*numspans);
spanstuffer = (Span *)((BYTE *)Spans + sizeof(Span*)*Width);
warned = false;
@ -1393,7 +1393,7 @@ void FPatchTexture::HackHack (int newheight)
}
// Create the spans
Spans = (Span **)Malloc (sizeof(Span *)*Width + sizeof(Span)*Width*2);
Spans = (Span **)M_Malloc (sizeof(Span *)*Width + sizeof(Span)*Width*2);
Span *span = (Span *)&Spans[Width];

View file

@ -474,7 +474,7 @@ static visplane_t *new_visplane (unsigned hash)
if (check == NULL)
{
check = (visplane_t *)Calloc (1, sizeof(*check) + sizeof(*check->top)*(MAXWIDTH*2));
check = (visplane_t *)M_Calloc (1, sizeof(*check) + sizeof(*check->top)*(MAXWIDTH*2));
check->bottom = &check->top[MAXWIDTH+2];
}
else if (NULL == (freetail = freetail->next))

View file

@ -1104,7 +1104,7 @@ void R_CheckDrawSegs ()
{ // [RH] Grab some more drawsegs
size_t newdrawsegs = MaxDrawSegs ? MaxDrawSegs*2 : 32;
ptrdiff_t firstofs = firstdrawseg - drawsegs;
drawsegs = (drawseg_t *)Realloc (drawsegs, newdrawsegs * sizeof(drawseg_t));
drawsegs = (drawseg_t *)M_Realloc (drawsegs, newdrawsegs * sizeof(drawseg_t));
firstdrawseg = drawsegs + firstofs;
ds_p = drawsegs + MaxDrawSegs;
MaxDrawSegs = newdrawsegs;
@ -1125,7 +1125,7 @@ void R_CheckOpenings (size_t need)
do
maxopenings = maxopenings ? maxopenings*2 : 16384;
while (need > maxopenings);
openings = (short *)Realloc (openings, maxopenings * sizeof(*openings));
openings = (short *)M_Realloc (openings, maxopenings * sizeof(*openings));
DPrintf ("MaxOpenings increased to %u\n", maxopenings);
}
}

View file

@ -808,7 +808,7 @@ vissprite_t *R_NewVisSprite (void)
ptrdiff_t prevvisspritenum = vissprite_p - vissprites;
MaxVisSprites = MaxVisSprites ? MaxVisSprites * 2 : 128;
vissprites = (vissprite_t **)Realloc (vissprites, MaxVisSprites * sizeof(vissprite_t));
vissprites = (vissprite_t **)M_Realloc (vissprites, MaxVisSprites * sizeof(vissprite_t));
lastvissprite = &vissprites[MaxVisSprites];
firstvissprite = &vissprites[firstvisspritenum];
vissprite_p = &vissprites[prevvisspritenum];

View file

@ -946,7 +946,7 @@ static void S_AddSNDINFO (int lump)
SC_MustGetString();
FString musname (sc_String);
SC_MustGetFloat();
FMusicVolume *mv = (FMusicVolume *)Malloc (sizeof(*mv) + musname.Len());
FMusicVolume *mv = (FMusicVolume *)M_Malloc (sizeof(*mv) + musname.Len());
mv->Volume = sc_Float;
strcpy (mv->MusicName, musname);
mv->Next = MusicVolumes;

View file

@ -648,7 +648,7 @@ void S_ParseSndSeq (int levellump)
static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, const TArray<DWORD> &ScriptTemp)
{
Sequences[curseq] = (FSoundSequence *)Malloc (sizeof(FSoundSequence) + sizeof(DWORD)*ScriptTemp.Size());
Sequences[curseq] = (FSoundSequence *)M_Malloc (sizeof(FSoundSequence) + sizeof(DWORD)*ScriptTemp.Size());
Sequences[curseq]->SeqName = seqname;
Sequences[curseq]->Slot = slot;
Sequences[curseq]->StopSound = stopsound;

View file

@ -258,7 +258,7 @@ void FStringTable::LoadLanguage (int lumpnum, DWORD code, bool exactMatch, int p
}
if (entry == NULL || cmpval > 0)
{
entry = (StringEntry *)Malloc (sizeof(*entry) + strText.Len() + strName.Len());
entry = (StringEntry *)M_Malloc (sizeof(*entry) + strText.Len() + strName.Len());
entry->Next = *pentry;
*pentry = entry;
strcpy (entry->String, strText.GetChars());
@ -380,7 +380,7 @@ void FStringTable::SetString (const char *name, const char *newString)
size_t namelen = strlen (name);
// Create a new string entry
StringEntry *entry = (StringEntry *)Malloc (sizeof(*entry) + newlen + namelen);
StringEntry *entry = (StringEntry *)M_Malloc (sizeof(*entry) + newlen + namelen);
strcpy (entry->String, newString);
strcpy (entry->Name = entry->String + newlen + 1, name);
entry->PassNum = 0;

View file

@ -36,14 +36,11 @@
#define __TARRAY_H__
#include <stdlib.h>
#include <assert.h>
#include <new>
#include "m_alloc.h"
// Specialize this function for any type that needs to have its destructor called.
template<class T>
bool NeedsDestructor ()
{
return false;
}
// This function is called once for each entry in the TArray after it grows.
// The old entries will be immediately freed afterwards, so if they need to
@ -51,11 +48,8 @@ bool NeedsDestructor ()
template<class T>
void CopyForTArray (T &dst, T &src)
{
dst = src;
if (NeedsDestructor<T>())
{
src.~T();
}
::new((void*)&dst) T(src);
src.~T();
}
// This function is called by Push to copy the the element to an unconstructed
@ -64,8 +58,7 @@ void CopyForTArray (T &dst, T &src)
template<class T>
void ConstructInTArray (T *dst, const T &src)
{
//new (dst) T(src);
*dst = src;
::new((void*)dst) T(src);
}
// This function is much like the above function, except it is called when
@ -73,6 +66,7 @@ void ConstructInTArray (T *dst, const T &src)
template<class T>
void ConstructEmptyInTArray (T *dst)
{
::new((void*)dst) T;
}
template <class T>
@ -89,7 +83,7 @@ public:
{
Most = max;
Count = 0;
Array = (T *)Malloc (sizeof(T)*max);
Array = (T *)M_Malloc (sizeof(T)*max);
}
TArray (const TArray<T> &other)
{
@ -101,7 +95,10 @@ public:
{
if (Array != NULL)
{
DoDelete (0, Count-1);
if (Count > 0)
{
DoDelete (0, Count-1);
}
free (Array);
}
DoCopy (other);
@ -112,8 +109,14 @@ public:
{
if (Array)
{
DoDelete (0, Count-1);
if (Count > 0)
{
DoDelete (0, Count-1);
}
free (Array);
Array = NULL;
Count = 0;
Most = 0;
}
}
T &operator[] (unsigned int index) const
@ -142,11 +145,43 @@ public:
}
void Delete (unsigned int index)
{
DoDelete (index, index);
if (index < Count-1)
memmove (Array + index, Array + index + 1, (Count - index - 1) * sizeof(T));
if (index < Count)
{
for (unsigned int i = index; i < Count - 1; ++i)
{
Array[i] = Array[i+1];
}
Count--;
DoDelete (Count, Count);
}
}
// Inserts an item into the array, shifting elements as needed
void Insert (unsigned int index, const T &item)
{
if (index >= Count)
{
// Inserting somewhere past the end of the array, so we can
// just add it without moving things.
Resize (index + 1);
ConstructInTArray (&Array[index], item);
}
else
{
// Inserting somewhere in the middle of the array, so make
// room for it and shift old entries out of the way.
Resize (Count + 1);
// Now copy items from the index and onward
for (unsigned int i = Count - 1; i-- > index; )
{
Array[i+1] = Array[i];
}
// Now put the new element in
DoDelete (index, index);
ConstructInTArray (&Array[index], item);
}
}
void ShrinkToFit ()
{
@ -186,12 +221,9 @@ public:
{
Grow (amount - Count);
}
if (NeedsDestructor<T>())
for (unsigned int i = Count; i < amount; ++i)
{
for (unsigned int i = Count; i < amount; ++i)
{
ConstructEmptyInTArray (&Array[i]);
}
ConstructEmptyInTArray (&Array[i]);
}
Count = amount;
}
@ -217,8 +249,11 @@ public:
}
void Clear ()
{
DoDelete (0, Count-1);
Count = 0;
if (Count > 0)
{
DoDelete (0, Count-1);
Count = 0;
}
}
private:
T *Array;
@ -230,7 +265,7 @@ private:
Most = Count = other.Count;
if (Count != 0)
{
Array = (T *)Malloc (sizeof(T)*Most);
Array = (T *)M_Malloc (sizeof(T)*Most);
for (unsigned int i = 0; i < Count; ++i)
{
Array[i] = other.Array[i];
@ -244,7 +279,7 @@ private:
void DoResize ()
{
T *newarray = (T *)Malloc (sizeof(T)*Most);
T *newarray = (T *)M_Malloc (sizeof(T)*Most);
for (unsigned int i = 0; i < Count; ++i)
{
CopyForTArray (newarray[i], Array[i]);
@ -255,12 +290,10 @@ private:
void DoDelete (unsigned int first, unsigned int last)
{
if (NeedsDestructor<T>())
assert (last != ~0u);
for (unsigned int i = first; i <= last; ++i)
{
for (unsigned int i = first; i <= last; ++i)
{
Array[i].~T();
}
Array[i].~T();
}
}
};

View file

@ -256,7 +256,7 @@ static DWORD Zip_FindCentralDir(FileReader * fin)
FileSize = fin->Tell();
uMaxBack = MIN<DWORD>(0xffff, FileSize);
buf = (unsigned char*)Malloc(BUFREADCOMMENT+4);
buf = (unsigned char*)M_Malloc(BUFREADCOMMENT+4);
if (buf == NULL) return 0;
uBackRead = 4;
@ -379,7 +379,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
BloodCrypt (lumps, header.rff.DirOfs, header.rff.NumLumps * sizeof(rfflump_t));
NumLumps += header.rff.NumLumps;
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
lump_p = &LumpInfo[startlump];
for (i = 0, rff_p = lumps; i < header.rff.NumLumps; ++i, ++rff_p)
@ -433,7 +433,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
pos = sizeof(grpinfo_t) + header.grp.NumLumps * sizeof(grplump_t);
NumLumps += header.grp.NumLumps;
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
lump_p = &LumpInfo[startlump];
for (i = 0, grp_p = lumps; i < header.grp.NumLumps; ++i, ++grp_p)
@ -479,7 +479,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
}
NumLumps += LittleShort(info.wEntryCount);
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
lump_p = &LumpInfo[startlump];
// Load the entire central directory. Too bad that this contains variable length entries...
@ -599,7 +599,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
}
// Resize the lump record array to its actual size
NumLumps -= skipped;
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
// Entries in Zips are sorted alphabetically.
qsort(LumpInfo + startlump, NumLumps - startlump, sizeof(LumpRecord), lumpcmp);
@ -623,7 +623,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
header.magic[0] != ZIP_ID &&
(header.magic[0] != GRP_ID_0 || header.magic[1] != GRP_ID_1 || header.magic[2] != GRP_ID_2))
{
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
lump_p = &LumpInfo[startlump];
for (i = startlump; i < (unsigned)NumLumps; i++, lump_p++, fileinfo++)
{
@ -649,7 +649,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
wadinfo->FirstLump = startlump;
wadinfo->LastLump = NumLumps - 1;
Wads = (WadFileRecord **)Realloc (Wads, (++NumWads)*sizeof(WadFileRecord*));
Wads = (WadFileRecord **)M_Realloc (Wads, (++NumWads)*sizeof(WadFileRecord*));
Wads[NumWads-1] = wadinfo;
// [RH] Put the Strife Teaser voices into the voices namespace
@ -1153,7 +1153,7 @@ void FWadCollection::ScanForFlatHack (int startlump)
}
}
++NumLumps;
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
for (; i > j; --i)
{
LumpInfo[i+1] = LumpInfo[i];
@ -1374,7 +1374,7 @@ int FWadCollection::MergeLumps (const char *start, const char *end, int space)
if (newlumps)
{
if (size_t(oldlumps + newlumps) >= NumLumps)
LumpInfo = (LumpRecord *)Realloc (LumpInfo, (oldlumps + newlumps + 1) * sizeof(LumpRecord) );
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, (oldlumps + newlumps + 1) * sizeof(LumpRecord) );
memcpy (LumpInfo + oldlumps, newlumpinfos, sizeof(LumpRecord) * newlumps);
markerpos = oldlumps;

View file

@ -646,11 +646,12 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
SetUnhandledExceptionFilter (CatchAllExceptions);
}
#ifdef _DEBUG
#if defined(_DEBUG) && defined(_MSC_VER)
// Uncomment this line to make the Visual C++ CRT check the heap before
// every allocation and deallocation. This will be slow, but it can be a
// great help in finding problem areas.
//_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF);
_CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF);
#endif
DoMain (hInstance);

View file

@ -161,8 +161,6 @@ protected:
char *Chars;
#ifndef __GNUC__
template<> friend bool NeedsDestructor<FString> () { return true; }
template<> friend void CopyForTArray<FString> (FString &dst, FString &src)
{
// When a TArray is resized, we just need to update the Owner, because
@ -176,18 +174,8 @@ protected:
((FString::StringHeader *)(chars - sizeof(FString::StringHeader)))->Owner = &dst;
}
}
template<> friend void ConstructInTArray<FString> (FString *dst, const FString &src)
{
new (dst) FString(src);
}
template<> friend void ConstructEmptyInTArray<FString> (FString *dst)
{
new (dst) FString;
}
#else
template<class FString> friend inline void CopyForTArray (FString &dst, FString &src);
template<class FString> friend inline void ConstructInTArray (FString *dst, const FString &src);
template<class FString> friend inline void ConstructEmptyInTArray (FString *dst);
#endif
private:
@ -201,7 +189,6 @@ private:
};
#ifdef __GNUC__
template<> inline bool NeedsDestructor<FString> () { return true; }
template<> inline void CopyForTArray<FString> (FString &dst, FString &src)
{
// When a TArray is resized, we just need to update the Owner, because
@ -215,14 +202,6 @@ template<> inline void CopyForTArray<FString> (FString &dst, FString &src)
((FString::StringHeader *)(chars - sizeof(FString::StringHeader)))->Owner = &dst;
}
}
template<> inline void ConstructInTArray<FString> (FString *dst, const FString &src)
{
new (dst) FString(src);
}
template<> inline void ConstructEmptyInTArray<FString> (FString *dst)
{
new (dst) FString;
}
#endif
namespace StringFormat

View file

@ -31,7 +31,7 @@ struct FString::Pool
char *Realloc (char *chars, size_t newlen);
void Free (char *chars);
void MergeFreeBlocks (StringHeader *block);
void CollectGarbage (bool noGenerations);
void CollectGarbage ();
bool BigEnough (size_t len) const;
size_t RoundLen (size_t len) const;
@ -40,8 +40,6 @@ struct FString::Pool
char *PoolData;
char *MaxAlloc;
StringHeader *NextAlloc;
StringHeader *GarbageStart;
int GenerationNum;
};
// The PoolGroup does not get a constructor, because there is no way to
@ -100,13 +98,8 @@ char *FString::PoolGroup::Alloc (FString *owner, size_t len)
}
if (best->BigEnough (len))
{
best->CollectGarbage (false);
best->CollectGarbage ();
mem = best->Alloc (owner, len);
if (mem == NULL)
{
best->CollectGarbage (true);
mem = best->Alloc (owner, len);
}
// Move the pool to the front of the list
*bestprev = best->Next;
best->Next = Pools;
@ -151,7 +144,10 @@ char *FString::PoolGroup::Realloc (FString *owner, char *chars, size_t newlen)
void FString::PoolGroup::Free (char *chars)
{
Pool *pool = FindPool (chars);
pool->Free (chars);
if (pool != NULL)
{
pool->Free (chars);
}
}
FString::Pool *FString::PoolGroup::FindPool (char *chars) const
@ -187,8 +183,6 @@ FString::Pool::Pool (size_t minSize)
NextAlloc = (StringHeader *)PoolData;
NextAlloc->Owner = NULL;
NextAlloc->Len = minSize;
GarbageStart = NextAlloc;
GenerationNum = 0;
}
FString::Pool::~Pool ()
@ -199,19 +193,19 @@ FString::Pool::~Pool ()
// all the strings stored in it. So we need to walk through the pool
// and make any owned strings un-owned.
StringHeader *str;
StringHeader *laststr;
for (str = (StringHeader *)PoolData; str < NextAlloc; )
{
if (str->Owner != NULL)
{
str->Owner->Chars = NULL;
str->Owner = NULL;
str = (StringHeader *)((char *)str + RoundLen(str->Len));
}
else
{
str = (StringHeader *)((char *)str + str->Len);
FString *owner = str->Owner;
assert (owner->Chars == (char *)str + sizeof(StringHeader));
Free ((char *)str + sizeof(StringHeader));
owner->Chars = "";
}
laststr = str;
str = (StringHeader *)((char *)str + str->Len);
}
delete[] PoolData;
@ -308,6 +302,21 @@ char *FString::Pool::Realloc (char *chars, size_t newlen)
void FString::Pool::Free (char *chars)
{
#ifdef _DEBUG
for (StringHeader *str = (StringHeader *)PoolData; str < NextAlloc; )
{
if (str->Owner != NULL)
{
assert (str->Owner->Chars == (char *)str + sizeof(StringHeader));
str = (StringHeader *)((char *)str + RoundLen(str->Len));
}
else
{
str = (StringHeader *)((char *)str + str->Len);
}
}
#endif
StringHeader *head = (StringHeader *)(chars - sizeof(StringHeader));
size_t truelen = RoundLen (head->Len);
@ -316,6 +325,25 @@ void FString::Pool::Free (char *chars)
head->Owner = NULL;
head->Len = truelen;
MergeFreeBlocks (head);
#ifdef _DEBUG
memset (head + 1, 0xCE, head->Len - sizeof(StringHeader));
#endif
#ifdef _DEBUG
for (StringHeader *str = (StringHeader *)PoolData; str < NextAlloc; )
{
if (str->Owner != NULL)
{
assert (str->Owner->Chars == (char *)str + sizeof(StringHeader));
str = (StringHeader *)((char *)str + RoundLen(str->Len));
}
else
{
str = (StringHeader *)((char *)str + str->Len);
}
}
#endif
}
void FString::Pool::MergeFreeBlocks (StringHeader *head)
@ -331,10 +359,6 @@ void FString::Pool::MergeFreeBlocks (StringHeader *head)
// If this chain of blocks meets up with the free space, then they can join up with it.
if (block == NextAlloc)
{
if (GarbageStart == NextAlloc)
{
GarbageStart = head;
}
NextAlloc = head;
head->Len = MaxAlloc - (char *)head;
}
@ -354,19 +378,13 @@ size_t FString::Pool::RoundLen (size_t len) const
return (len + 1 + sizeof(StringHeader) + BLOCK_GRANULARITY - 1) & ~(BLOCK_GRANULARITY - 1);
}
void FString::Pool::CollectGarbage (bool noGenerations)
void FString::Pool::CollectGarbage ()
{
// This is a generational garbage collector. The space occupied by strings from
// the first two generations will not be collected unless noGenerations is set true.
if (noGenerations)
{
GarbageStart = (StringHeader *)PoolData;
GenerationNum = 0;
}
StringHeader *moveto, *movefrom;
moveto = movefrom = GarbageStart;
moveto = movefrom = (StringHeader *)PoolData;
while (movefrom < NextAlloc)
{
@ -397,11 +415,6 @@ void FString::Pool::CollectGarbage (bool noGenerations)
}
else if (FreeSpace != 0)
FreeSpace = FreeSpace;
if (++GenerationNum <= 3)
{
GarbageStart = moveto;
}
}
#else
char *FString::PoolGroup::Alloc (FString *owner, size_t len)