mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 12:32:34 +00:00
- When purging ACS strings, free the strings themselves as well as marking them as free.
- Fixed: ACSStringPool::InsertString()'s overflow check was far too low. - Fixed: When ACSStringPool::InsertString() triggered a garbage collection, it ignored the newly freed space and expanded the array anyway. SVN r4328 (trunk)
This commit is contained in:
parent
5e7ee8f33e
commit
e2be8b9e7e
1 changed files with 12 additions and 5 deletions
|
@ -481,21 +481,27 @@ void ACSStringPool::PurgeStrings()
|
||||||
// Clear the hash buckets. We'll rebuild them as we decide what strings
|
// Clear the hash buckets. We'll rebuild them as we decide what strings
|
||||||
// to keep and which to toss.
|
// to keep and which to toss.
|
||||||
memset(PoolBuckets, 0xFF, sizeof(PoolBuckets));
|
memset(PoolBuckets, 0xFF, sizeof(PoolBuckets));
|
||||||
|
size_t usedcount = 0, freedcount = 0;
|
||||||
for (unsigned int i = 0; i < Pool.Size(); ++i)
|
for (unsigned int i = 0; i < Pool.Size(); ++i)
|
||||||
{
|
{
|
||||||
PoolEntry *entry = &Pool[i];
|
PoolEntry *entry = &Pool[i];
|
||||||
if (entry->Next != FREE_ENTRY)
|
if (entry->Next != FREE_ENTRY)
|
||||||
{
|
{
|
||||||
if (entry->LockCount == 0)
|
if (entry->LockCount == 0)
|
||||||
{ // Mark this entry as free.
|
{
|
||||||
|
freedcount++;
|
||||||
|
// Mark this entry as free.
|
||||||
entry->Next = FREE_ENTRY;
|
entry->Next = FREE_ENTRY;
|
||||||
if (i < FirstFreeEntry)
|
if (i < FirstFreeEntry)
|
||||||
{
|
{
|
||||||
FirstFreeEntry = i;
|
FirstFreeEntry = i;
|
||||||
}
|
}
|
||||||
|
// And free the string.
|
||||||
|
entry->Str = "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
usedcount++;
|
||||||
// Rehash this entry.
|
// Rehash this entry.
|
||||||
unsigned int h = entry->Hash % NUM_BUCKETS;
|
unsigned int h = entry->Hash % NUM_BUCKETS;
|
||||||
entry->Next = PoolBuckets[h];
|
entry->Next = PoolBuckets[h];
|
||||||
|
@ -543,14 +549,15 @@ int ACSStringPool::FindString(const char *str, size_t len, unsigned int h, unsig
|
||||||
|
|
||||||
int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucketnum, const SDWORD *stack, int stackdepth)
|
int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucketnum, const SDWORD *stack, int stackdepth)
|
||||||
{
|
{
|
||||||
if (Pool.Size() >= STRPOOL_LIBRARYID)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
unsigned int index = FirstFreeEntry;
|
unsigned int index = FirstFreeEntry;
|
||||||
if (index >= MIN_GC_SIZE && index == Pool.Max())
|
if (index >= MIN_GC_SIZE && index == Pool.Max())
|
||||||
{ // We will need to grow the array. Try a garbage collection first.
|
{ // We will need to grow the array. Try a garbage collection first.
|
||||||
P_CollectACSGlobalStrings(stack, stackdepth);
|
P_CollectACSGlobalStrings(stack, stackdepth);
|
||||||
|
index = FirstFreeEntry;
|
||||||
|
}
|
||||||
|
if (FirstFreeEntry >= STRPOOL_LIBRARYID_OR)
|
||||||
|
{ // If we go any higher, we'll collide with the library ID marker.
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
if (index == Pool.Size())
|
if (index == Pool.Size())
|
||||||
{ // There were no free entries; make a new one.
|
{ // There were no free entries; make a new one.
|
||||||
|
|
Loading…
Reference in a new issue