fixed bad assumption about object destruction state in garbage collector.

The assumption was made that every object in the ToDestroy list wasn't destroyed yet.
This assumption is wrong in case one object destroys an owned one on its own destruction.
Instead this case must be properly dealt with and duplicate destruction be avoided.

This happened with the panel sprite sentinel in SW's player object.
This commit is contained in:
Christoph Oelckers 2023-10-03 12:23:29 +02:00
parent 0463623daf
commit 88d5d15094

View file

@ -287,11 +287,22 @@ static size_t DestroyObjects(size_t count)
while ((curr = ToDestroy) != nullptr && count-- > 0)
{
assert(!(curr->ObjectFlags & OF_EuthanizeMe));
bytes_destroyed += curr->GetClass()->Size + GCDESTROYCOST;
ToDestroy = curr->GCNext;
curr->GCNext = nullptr;
curr->Destroy();
// Note that we cannot assume here that the object has not yet been destroyed.
// If destruction happens as the result of another object's destruction we may
// get entries here that have been destroyed already if that owning object was
// first in the list.
if (!(curr->ObjectFlags & OF_EuthanizeMe))
{
bytes_destroyed += curr->GetClass()->Size + GCDESTROYCOST;
ToDestroy = curr->GCNext;
curr->GCNext = nullptr;
curr->Destroy();
}
else
{
ToDestroy = curr->GCNext;
curr->GCNext = nullptr;
}
}
return bytes_destroyed;
}