- remove all type table entries from garbage collection.

Like the symbols and the VM functions this is data that is static from startup until shutdown and has no need to be subjected to garbage collection. All things combined this reduces the amount of GC-sensitive objects at startup from 9600 to 600.
This commit is contained in:
Christoph Oelckers 2017-02-08 22:43:20 +01:00
parent 8277299135
commit 36a07b8e6e
6 changed files with 34 additions and 129 deletions

View file

@ -254,6 +254,14 @@ static DObject **SweepList(DObject **p, size_t count, size_t *finalize_count)
curr->Destroy();
}
/*
if (curr->IsKindOf(RUNTIME_CLASS(PSymbol)))
Printf("Collecting %s, name = %s\n", curr->GetClass()->TypeName.GetChars(), static_cast<PSymbol*>(curr)->SymbolName.GetChars());
else if (curr->IsKindOf(RUNTIME_CLASS(PType)))
Printf("Collecting %s, name = %s\n", curr->GetClass()->TypeName.GetChars(), static_cast<PType*>(curr)->DescriptiveName());
else
Printf("Collecting %s\n", curr->GetClass()->TypeName.GetChars());
*/
curr->ObjectFlags |= OF_Cleanup;
delete curr;
finalized++;
@ -363,12 +371,6 @@ static void MarkRoot()
}
Mark(SectorMarker);
Mark(interpolator.Head);
// Mark types
TypeTable.Mark();
for (unsigned int i = 0; i < PClass::AllClasses.Size(); ++i)
{
Mark(PClass::AllClasses[i]);
}
// Mark global symbols
Namespaces.MarkSymbols();
// Mark bot stuff.
@ -449,8 +451,8 @@ static size_t SingleStep()
{ // Nothing more to sweep?
State = GCS_Finalize;
}
assert(old >= AllocBytes);
Estimate -= old - AllocBytes;
//assert(old >= AllocBytes);
Estimate -= MAX<size_t>(0, old - AllocBytes);
return (GCSWEEPMAX - finalize_count) * GCSWEEPCOST + finalize_count * GCFINALIZECOST;
}
@ -550,6 +552,7 @@ void FullGC()
void Barrier(DObject *pointing, DObject *pointed)
{
assert(pointed->GetClass() < (void*)0x1000000000000000);
assert(pointing == NULL || (pointing->IsBlack() && !pointing->IsDead()));
assert(pointed->IsWhite() && !pointed->IsDead());
assert(State != GCS_Finalize && State != GCS_Pause);

View file

@ -151,11 +151,7 @@ void DumpTypeTable()
/* PType ******************************************************************/
IMPLEMENT_CLASS(PType, true, true)
IMPLEMENT_POINTERS_START(PType)
IMPLEMENT_POINTER(HashNext)
IMPLEMENT_POINTERS_END
IMPLEMENT_CLASS(PType, true, false)
//==========================================================================
//
@ -444,11 +440,7 @@ IMPLEMENT_CLASS(PCompoundType, true, false)
/* PNamedType *************************************************************/
IMPLEMENT_CLASS(PNamedType, true, true)
IMPLEMENT_POINTERS_START(PNamedType)
IMPLEMENT_POINTER(Outer)
IMPLEMENT_POINTERS_END
IMPLEMENT_CLASS(PNamedType, true, false)
//==========================================================================
//
@ -1303,11 +1295,7 @@ PStateLabel::PStateLabel()
/* PPointer ***************************************************************/
IMPLEMENT_CLASS(PPointer, false, true)
IMPLEMENT_POINTERS_START(PPointer)
IMPLEMENT_POINTER(PointedType)
IMPLEMENT_POINTERS_END
IMPLEMENT_CLASS(PPointer, false, false)
//==========================================================================
//
@ -1510,11 +1498,7 @@ bool PStatePointer::ReadValue(FSerializer &ar, const char *key, void *addr) cons
/* PClassPointer **********************************************************/
IMPLEMENT_CLASS(PClassPointer,false, true)
IMPLEMENT_POINTERS_START(PClassPointer)
IMPLEMENT_POINTER(ClassRestriction)
IMPLEMENT_POINTERS_END
IMPLEMENT_CLASS(PClassPointer,false, false)
//==========================================================================
//
@ -1595,11 +1579,7 @@ PClassPointer *NewClassPointer(PClass *restrict)
/* PEnum ******************************************************************/
IMPLEMENT_CLASS(PEnum, false, true)
IMPLEMENT_POINTERS_START(PEnum)
IMPLEMENT_POINTER(Outer)
IMPLEMENT_POINTERS_END
IMPLEMENT_CLASS(PEnum, false, false)
//==========================================================================
//
@ -1651,11 +1631,7 @@ PEnum *NewEnum(FName name, PTypeBase *outer)
/* PArray *****************************************************************/
IMPLEMENT_CLASS(PArray, false, true)
IMPLEMENT_POINTERS_START(PArray)
IMPLEMENT_POINTER(ElementType)
IMPLEMENT_POINTERS_END
IMPLEMENT_CLASS(PArray, false, false)
//==========================================================================
//
@ -1888,11 +1864,7 @@ PResizableArray *NewResizableArray(PType *type)
/* PDynArray **************************************************************/
IMPLEMENT_CLASS(PDynArray, false, true)
IMPLEMENT_POINTERS_START(PDynArray)
IMPLEMENT_POINTER(ElementType)
IMPLEMENT_POINTERS_END
IMPLEMENT_CLASS(PDynArray, false, false)
//==========================================================================
//
@ -2143,12 +2115,7 @@ PDynArray *NewDynArray(PType *type)
/* PMap *******************************************************************/
IMPLEMENT_CLASS(PMap, false, true)
IMPLEMENT_POINTERS_START(PMap)
IMPLEMENT_POINTER(KeyType)
IMPLEMENT_POINTER(ValueType)
IMPLEMENT_POINTERS_END
IMPLEMENT_CLASS(PMap, false, false)
//==========================================================================
//
@ -2645,11 +2612,7 @@ PPrototype *NewPrototype(const TArray<PType *> &rettypes, const TArray<PType *>
/* PClass *****************************************************************/
IMPLEMENT_CLASS(PClass, false, true)
IMPLEMENT_POINTERS_START(PClass)
IMPLEMENT_POINTER(ParentClass)
IMPLEMENT_POINTERS_END
IMPLEMENT_CLASS(PClass, false, false)
//==========================================================================
//
@ -2855,18 +2818,10 @@ void PClass::StaticShutdown ()
bVMOperational = false;
// Unless something went wrong, anything left here should be class and type objects only, which do not own any scripts.
bShutdown = true;
TypeTable.Clear();
Namespaces.ReleaseSymbols();
ClassDataAllocator.FreeAllBlocks();
bShutdown = true;
for (unsigned i = 0; i < PClass::AllClasses.Size(); ++i)
{
PClass *type = PClass::AllClasses[i];
PClass::AllClasses[i] = NULL;
type->Destroy();
}
AllClasses.Clear();
PClassActor::AllActorClasses.Clear();
@ -3591,31 +3546,6 @@ PType *FTypeTable::FindType(PClass *metatype, intptr_t parm1, intptr_t parm2, si
return nullptr;
}
//==========================================================================
//
// FTypeTable :: ReplaceType
//
// Replaces an existing type in the table with a new version of the same
// type. For use when redefining actors in DECORATE. Does nothing if the
// old version is not in the table.
//
//==========================================================================
void FTypeTable::ReplaceType(PType *newtype, PType *oldtype, size_t bucket)
{
for (PType **type_p = &TypeHash[bucket]; *type_p != nullptr; type_p = &(*type_p)->HashNext)
{
PType *type = *type_p;
if (type == oldtype)
{
newtype->HashNext = type->HashNext;
type->HashNext = nullptr;
*type_p = newtype;
break;
}
}
}
//==========================================================================
//
// FTypeTable :: AddType - Fully Parameterized Version
@ -3632,7 +3562,7 @@ void FTypeTable::AddType(PType *type, PClass *metatype, intptr_t parm1, intptr_t
type->TypeTableType = metatype;
type->HashNext = TypeHash[bucket];
TypeHash[bucket] = type;
GC::WriteBarrier(type);
type->Release();
}
//==========================================================================
@ -3655,7 +3585,7 @@ void FTypeTable::AddType(PType *type)
type->HashNext = TypeHash[bucket];
TypeHash[bucket] = type;
GC::WriteBarrier(type);
type->Release();
}
//==========================================================================
@ -3694,36 +3624,23 @@ size_t FTypeTable::Hash(const PClass *p1, intptr_t p2, intptr_t p3)
}
}
//==========================================================================
//
// FTypeTable :: Mark
//
// Mark all types in this table for the garbage collector.
//
//==========================================================================
void FTypeTable::Mark()
{
for (int i = HASH_SIZE - 1; i >= 0; --i)
{
if (TypeHash[i] != nullptr)
{
GC::Mark(TypeHash[i]);
}
}
}
//==========================================================================
//
// FTypeTable :: Clear
//
// Removes everything from the table. We let the garbage collector worry
// about deleting them.
//
//==========================================================================
void FTypeTable::Clear()
{
for (size_t i = 0; i < countof(TypeTable.TypeHash); ++i)
{
for (PType *ty = TypeTable.TypeHash[i]; ty != nullptr;)
{
auto next = ty->HashNext;
delete ty;
ty = next;
}
}
memset(TypeHash, 0, sizeof(TypeHash));
}

View file

@ -77,7 +77,6 @@ struct ZCC_ExprConstant;
class PType : public PTypeBase
{
DECLARE_ABSTRACT_CLASS(PType, PTypeBase)
HAS_OBJECT_POINTERS;
protected:
public:
@ -208,7 +207,6 @@ class PCompoundType : public PType
class PNamedType : public PCompoundType
{
DECLARE_ABSTRACT_CLASS(PNamedType, PCompoundType);
HAS_OBJECT_POINTERS;
public:
PTypeBase *Outer; // object this type is contained within
FName TypeName; // this type's name
@ -364,7 +362,6 @@ public:
class PPointer : public PBasicType
{
DECLARE_CLASS(PPointer, PBasicType);
HAS_OBJECT_POINTERS;
public:
PPointer();
PPointer(PType *pointsat, bool isconst = false);
@ -397,7 +394,6 @@ public:
class PClassPointer : public PPointer
{
DECLARE_CLASS(PClassPointer, PPointer);
HAS_OBJECT_POINTERS;
public:
PClassPointer(class PClass *restrict = nullptr);
@ -414,7 +410,6 @@ public:
class PEnum : public PInt
{
DECLARE_CLASS(PEnum, PInt);
HAS_OBJECT_POINTERS;
public:
PEnum(FName name, PTypeBase *outer);
@ -427,7 +422,6 @@ protected:
class PArray : public PCompoundType
{
DECLARE_CLASS(PArray, PCompoundType);
HAS_OBJECT_POINTERS;
public:
PArray(PType *etype, unsigned int ecount);
@ -451,7 +445,6 @@ protected:
class PResizableArray : public PArray
{
DECLARE_CLASS(PResizableArray, PArray);
HAS_OBJECT_POINTERS;
public:
PResizableArray(PType *etype);
@ -465,7 +458,6 @@ protected:
class PDynArray : public PCompoundType
{
DECLARE_CLASS(PDynArray, PCompoundType);
HAS_OBJECT_POINTERS;
public:
PDynArray(PType *etype, PStruct *backing);
@ -489,7 +481,6 @@ protected:
class PMap : public PCompoundType
{
DECLARE_CLASS(PMap, PCompoundType);
HAS_OBJECT_POINTERS;
public:
PMap(PType *keytype, PType *valtype);
@ -565,7 +556,6 @@ enum
class PClass : public PNativeStruct
{
DECLARE_CLASS(PClass, PNativeStruct);
HAS_OBJECT_POINTERS;
protected:
// We unravel _WITH_META here just as we did for PType.
TArray<FTypeAndOffset> SpecialInits;
@ -672,10 +662,8 @@ struct FTypeTable
PType *TypeHash[HASH_SIZE];
PType *FindType(PClass *metatype, intptr_t parm1, intptr_t parm2, size_t *bucketnum);
void ReplaceType(PType *newtype, PType *oldtype, size_t bucket);
void AddType(PType *type, PClass *metatype, intptr_t parm1, intptr_t parm2, size_t bucket);
void AddType(PType *type);
void Mark();
void Clear();
static size_t Hash(const PClass *p1, intptr_t p2, intptr_t p3);

View file

@ -64,9 +64,6 @@ IMPLEMENT_POINTERS_START(AWeapon)
IMPLEMENT_POINTER(Ammo1)
IMPLEMENT_POINTER(Ammo2)
IMPLEMENT_POINTER(SisterWeapon)
IMPLEMENT_POINTER(AmmoType1)
IMPLEMENT_POINTER(AmmoType2)
IMPLEMENT_POINTER(SisterWeaponType)
IMPLEMENT_POINTERS_END
DEFINE_FIELD(AWeapon, WeaponFlags)

View file

@ -6717,7 +6717,7 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
{
auto parentfield = static_cast<FxMemberBase *>(classx)->membervar;
// PFields are garbage collected so this will be automatically taken care of later.
auto newfield = new PField(membervar->SymbolName, membervar->Type, membervar->Flags | parentfield->Flags, membervar->Offset + parentfield->Offset);
auto newfield = new PField(NAME_None, membervar->Type, membervar->Flags | parentfield->Flags, membervar->Offset + parentfield->Offset);
newfield->BitValue = membervar->BitValue;
static_cast<FxMemberBase *>(classx)->membervar = newfield;
classx->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away.

View file

@ -110,7 +110,7 @@ FScriptPosition & GetStateSource(FState *state);
// Extra info maintained while defining an actor.
//
//==========================================================================
class FDropItem;
struct FDropItem;
struct Baggage
{