From e3c36998b6ce182f9dfe513c19891e3d54db81e4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 24 Jan 2017 11:57:42 +0100 Subject: [PATCH] - delete all compile-time symbols for scripting after finishing compiling data. Even the bare-bones gzdoom.pk3 gets rid of over 2000 symbols this way that otherwise would need to be tracked by the garbage collector. --- src/d_main.cpp | 3 +++ src/dobjtype.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/dobjtype.h | 6 ++++++ 3 files changed, 51 insertions(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index 971e0ece0e..6041af9b4d 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2517,6 +2517,9 @@ void D_DoomMain (void) // Create replacements for dehacked pickups FinishDehPatch(); + + // clean up the compiler symbols which are not needed any longer. + RemoveUnusedSymbols(); InitActorNumsFromMapinfo(); InitSpawnablesFromMapinfo(); diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index dbd3e6d6fd..76330867e7 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -3898,3 +3898,45 @@ void FNamespaceManager::ReleaseSymbols() GlobalNamespace = nullptr; AllNamespaces.Clear(); } + +// removes all symbols from the symbol tables. +// After running the compiler these are not needed anymore. +// Only the namespaces themselves are kept because the type table references them. +int FNamespaceManager::RemoveSymbols() +{ + int count = 0; + for (auto ns : AllNamespaces) + { + count += ns->Symbols.Symbols.CountUsed(); + ns->Symbols.ReleaseSymbols(); + } + return count; +} + +void RemoveUnusedSymbols() +{ + // Global symbols are not needed anymore after running the compiler. + int count = Namespaces.RemoveSymbols(); + + // We do not need any non-field and non-function symbols in structs and classes anymore. + for (size_t i = 0; i < countof(TypeTable.TypeHash); ++i) + { + for (PType *ty = TypeTable.TypeHash[i]; ty != NULL; ty = ty->HashNext) + { + if (ty->IsKindOf(RUNTIME_CLASS(PStruct))) + { + auto it = ty->Symbols.GetIterator(); + PSymbolTable::MapType::Pair *pair; + while (it.NextPair(pair)) + { + if (!pair->Value->IsKindOf(RUNTIME_CLASS(PField)) && !pair->Value->IsKindOf(RUNTIME_CLASS(PFunction))) + { + ty->Symbols.RemoveSymbol(pair->Value); + count++; + } + } + } + } + } + DPrintf(DMSG_SPAMMY, "%d symbols removed after compilation\n", count); +} diff --git a/src/dobjtype.h b/src/dobjtype.h index 61747134cc..632ef96bbd 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -76,6 +76,7 @@ class VMFrameStack; struct VMValue; struct VMReturn; class VMFunction; +struct FNamespaceManager; // A VM function ------------------------------------------------------------ @@ -157,6 +158,7 @@ private: MapType Symbols; friend class DObject; + friend struct FNamespaceManager; }; // A symbol for a compiler tree node ---------------------------------------- @@ -1010,6 +1012,7 @@ struct FNamespaceManager PNamespace *NewNamespace(int filenum); size_t MarkSymbols(); void ReleaseSymbols(); + int RemoveSymbols(); }; extern FNamespaceManager Namespaces; @@ -1047,4 +1050,7 @@ inline T *&DObject::PointerVar(FName field) { return *(T**)ScriptVar(field, nullptr); // pointer check is more tricky and for the handful of uses in the DECORATE parser not worth the hassle. } + +void RemoveUnusedSymbols(); + #endif