From e2be8b9e7e2bee1df92da3dc00e04962ebda1700 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 4 Jun 2013 02:49:07 +0000 Subject: [PATCH] - 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) --- src/p_acs.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index e982d6993..6237fedbe 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -481,21 +481,27 @@ void ACSStringPool::PurgeStrings() // Clear the hash buckets. We'll rebuild them as we decide what strings // to keep and which to toss. memset(PoolBuckets, 0xFF, sizeof(PoolBuckets)); + size_t usedcount = 0, freedcount = 0; for (unsigned int i = 0; i < Pool.Size(); ++i) { PoolEntry *entry = &Pool[i]; if (entry->Next != FREE_ENTRY) { if (entry->LockCount == 0) - { // Mark this entry as free. + { + freedcount++; + // Mark this entry as free. entry->Next = FREE_ENTRY; if (i < FirstFreeEntry) { FirstFreeEntry = i; } + // And free the string. + entry->Str = ""; } else { + usedcount++; // Rehash this entry. unsigned int h = entry->Hash % NUM_BUCKETS; 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) { - if (Pool.Size() >= STRPOOL_LIBRARYID) - { - return -1; - } unsigned int index = FirstFreeEntry; if (index >= MIN_GC_SIZE && index == Pool.Max()) { // We will need to grow the array. Try a garbage collection first. 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()) { // There were no free entries; make a new one.