From dde5e1928fdbb4bed6949ec8fa9a1ed151a080bb Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 22 Apr 2010 04:12:42 +0000 Subject: [PATCH] - Make TypeTable a GC root. - Instantiate some basic types. SVN r2298 (scripting) --- src/dobjgc.cpp | 7 +- src/dobjtype.cpp | 311 +++++++++++++++++++++++++++++++++++++++++++++-- src/dobjtype.h | 43 ++++++- 3 files changed, 345 insertions(+), 16 deletions(-) diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index 105ec1096c..1a5f3a5575 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -356,11 +356,8 @@ static void MarkRoot() Mark(*(afunc->VMPointer)); } } - // Mark classes - for (unsigned j = 0; j < PClass::AllClasses.Size(); ++j) - { - Mark(PClass::AllClasses[j]); - } + // Mark types + TypeTable.Mark(); // Mark bot stuff. Mark(bglobal.firstthing); Mark(bglobal.body1); diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index a211c55da6..d3aa01ce67 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -61,6 +61,16 @@ FTypeTable TypeTable; TArray PClass::AllClasses; bool PClass::bShutdown; +PInt *TypeSInt8, *TypeUInt8; +PInt *TypeSInt16, *TypeUInt16; +PInt *TypeSInt32, *TypeUInt32; +PFloat *TypeFloat32, *TypeFloat64; +PString *TypeString; +PName *TypeName; +PSound *TypeSound; +PColor *TypeColor; + + // PRIVATE DATA DEFINITIONS ------------------------------------------------ // A harmless non-NULL FlatPointer for classes without pointers. @@ -159,11 +169,13 @@ PClassClass::PClassClass() /* PType ******************************************************************/ -IMPLEMENT_ABSTRACT_CLASS(PType) +IMPLEMENT_ABSTRACT_POINTY_CLASS(PType) + DECLARE_POINTER(HashNext) +END_POINTERS //========================================================================== // -// PType Constructor +// PType Default Constructor // //========================================================================== @@ -172,6 +184,17 @@ PType::PType() { } +//========================================================================== +// +// PType Parameterized Constructor +// +//========================================================================== + +PType::PType(unsigned int size, unsigned int align) +: Size(size), Align(align), HashNext(NULL) +{ +} + //========================================================================== // // PType Destructor @@ -193,11 +216,23 @@ bool PType::IsMatch(const void *id1, const void *id2) const return false; } +//========================================================================== +// +// PType :: GetTypeIDs +// +//========================================================================== + +void PType::GetTypeIDs(const void *&id1, const void *&id2) const +{ + id1 = NULL; + id2 = NULL; +} + //========================================================================== // // PType :: StaticInit STATIC // -// Set up TypeTableType values for every PType child. +// Set up TypeTableType values for every PType child and create basic types. // //========================================================================== @@ -220,6 +255,20 @@ void PType::StaticInit() RUNTIME_CLASS(PPrototype)->TypeTableType = RUNTIME_CLASS(PPrototype); RUNTIME_CLASS(PFunction)->TypeTableType = RUNTIME_CLASS(PFunction); RUNTIME_CLASS(PClass)->TypeTableType = RUNTIME_CLASS(PClass); + + TypeTable.AddType(TypeSInt8 = new PInt(1, false)); + TypeTable.AddType(TypeUInt8 = new PInt(1, true)); + TypeTable.AddType(TypeSInt16 = new PInt(2, false)); + TypeTable.AddType(TypeUInt16 = new PInt(2, true)); + TypeTable.AddType(TypeSInt32 = new PInt(4, false)); + TypeTable.AddType(TypeUInt32 = new PInt(4, true)); + TypeTable.AddType(TypeFloat32 = new PFloat(4)); + TypeTable.AddType(TypeFloat64 = new PFloat(8)); + TypeTable.AddType(TypeString = new PString); + TypeTable.AddType(TypeName = new PName); + TypeTable.AddType(TypeSound = new PSound); + TypeTable.AddType(TypeColor = new PColor); + } @@ -227,6 +276,27 @@ void PType::StaticInit() IMPLEMENT_ABSTRACT_CLASS(PBasicType) +//========================================================================== +// +// PBasicType Default Constructor +// +//========================================================================== + +PBasicType::PBasicType() +{ +} + +//========================================================================== +// +// PBasicType Parameterized Constructor +// +//========================================================================== + +PBasicType::PBasicType(unsigned int size, unsigned int align) +: PType(size, align) +{ +} + /* PCompoundType **********************************************************/ IMPLEMENT_ABSTRACT_CLASS(PCompoundType) @@ -251,30 +321,133 @@ bool PNamedType::IsMatch(const void *id1, const void *id2) const return Outer == outer && TypeName == name; } +//========================================================================== +// +// PNamedType :: GetTypeIDs +// +//========================================================================== + +void PNamedType::GetTypeIDs(const void *&id1, const void *&id2) const +{ + id1 = Outer; + id2 = (void *)(intptr_t)TypeName; +} + /* PInt *******************************************************************/ IMPLEMENT_CLASS(PInt) +//========================================================================== +// +// PInt Default Constructor +// +//========================================================================== + +PInt::PInt() +: PBasicType(4, 4) +{ +} + +//========================================================================== +// +// PInt Parameterized Constructor +// +//========================================================================== + +PInt::PInt(unsigned int size, bool unsign) +: PBasicType(size, size), Unsigned(unsign) +{ +} + /* PFloat *****************************************************************/ IMPLEMENT_CLASS(PFloat) +//========================================================================== +// +// PFloat Default Constructor +// +//========================================================================== + +PFloat::PFloat() +: PBasicType(4, 4) +{ +} + +//========================================================================== +// +// PFloat Parameterized Constructor +// +//========================================================================== + +PFloat::PFloat(unsigned int size) +: PBasicType(size, size) +{ +} + /* PString ****************************************************************/ IMPLEMENT_CLASS(PString) +//========================================================================== +// +// PString Default Constructor +// +//========================================================================== + +PString::PString() +: PBasicType(sizeof(FString), __alignof(FString)) +{ +} + /* PName ******************************************************************/ IMPLEMENT_CLASS(PName) +//========================================================================== +// +// PName Default Constructor +// +//========================================================================== + +PName::PName() +: PInt(sizeof(FName), true) +{ + assert(sizeof(FName) == __alignof(FName)); +} + /* PSound *****************************************************************/ IMPLEMENT_CLASS(PSound) +//========================================================================== +// +// PSound Default Constructor +// +//========================================================================== + +PSound::PSound() +: PInt(sizeof(FSoundID), true) +{ + assert(sizeof(FSoundID) == __alignof(FSoundID)); +} + /* PColor *****************************************************************/ IMPLEMENT_CLASS(PColor) +//========================================================================== +// +// PColor Default Constructor +// +//========================================================================== + +PColor::PColor() +: PInt(sizeof(PalEntry), true) +{ + assert(sizeof(PalEntry) == __alignof(PalEntry)); +} + /* PPointer ***************************************************************/ IMPLEMENT_POINTY_CLASS(PPointer) @@ -295,6 +468,19 @@ bool PPointer::IsMatch(const void *id1, const void *id2) const return pointat == PointedType; } +//========================================================================== +// +// PPointer :: GetTypeIDs +// +//========================================================================== + +void PPointer::GetTypeIDs(const void *&id1, const void *&id2) const +{ + id1 = PointedType; + id2 = NULL; +} + + /* PClassPointer **********************************************************/ IMPLEMENT_POINTY_CLASS(PClassPointer) @@ -316,6 +502,20 @@ bool PClassPointer::IsMatch(const void *id1, const void *id2) const return classat == ClassRestriction; } +//========================================================================== +// +// PClassPointer :: GetTypeIDs +// +//========================================================================== + +void PClassPointer::GetTypeIDs(const void *&id1, const void *&id2) const +{ + assert(PointedType == RUNTIME_CLASS(PClass)); + id1 = PointedType; + id2 = ClassRestriction; +} + + /* PEnum ******************************************************************/ IMPLEMENT_POINTY_CLASS(PEnum) @@ -342,6 +542,18 @@ bool PArray::IsMatch(const void *id1, const void *id2) const return elemtype == ElementType && count == ElementCount; } +//========================================================================== +// +// PArray :: GetTypeIDs +// +//========================================================================== + +void PArray::GetTypeIDs(const void *&id1, const void *&id2) const +{ + id1 = ElementType; + id2 = (void *)(intptr_t)ElementCount; +} + /* PVector ****************************************************************/ IMPLEMENT_CLASS(PVector) @@ -352,6 +564,12 @@ IMPLEMENT_POINTY_CLASS(PDynArray) DECLARE_POINTER(ElementType) END_POINTERS +//========================================================================== +// +// PDynArray :: IsMatch +// +//========================================================================== + bool PDynArray::IsMatch(const void *id1, const void *id2) const { assert(id2 == NULL); @@ -360,6 +578,19 @@ bool PDynArray::IsMatch(const void *id1, const void *id2) const return elemtype == ElementType; } +//========================================================================== +// +// PDynArray :: GetTypeIDs +// +//========================================================================== + +void PDynArray::GetTypeIDs(const void *&id1, const void *&id2) const +{ + id1 = ElementType; + id2 = NULL; +} + + /* PMap *******************************************************************/ IMPLEMENT_POINTY_CLASS(PMap) @@ -381,6 +612,18 @@ bool PMap::IsMatch(const void *id1, const void *id2) const return keyty == KeyType && valty == ValueType; } +//========================================================================== +// +// PMap :: GetTypeIDs +// +//========================================================================== + +void PMap::GetTypeIDs(const void *&id1, const void *&id2) const +{ + id1 = KeyType; + id2 = ValueType; +} + /* PStruct ****************************************************************/ IMPLEMENT_CLASS(PStruct) @@ -415,6 +658,18 @@ bool PPrototype::IsMatch(const void *id1, const void *id2) const return *args == ArgumentTypes && *rets == ReturnTypes; } +//========================================================================== +// +// PPrototype :: GetTypeIDs +// +//========================================================================== + +void PPrototype::GetTypeIDs(const void *&id1, const void *&id2) const +{ + id1 = &ArgumentTypes; + id2 = &ReturnTypes; +} + //========================================================================== // // PPrototype :: PropagateMark @@ -970,7 +1225,7 @@ size_t PClass::PropagateMark() // //========================================================================== -PType *FTypeTable::FindType(PClass *metatype, void *parm1, void *parm2, size_t *bucketnum) +PType *FTypeTable::FindType(PClass *metatype, const void *parm1, const void *parm2, size_t *bucketnum) { size_t bucket = Hash(metatype, parm1, parm2) % HASH_SIZE; if (bucketnum != NULL) @@ -989,11 +1244,11 @@ PType *FTypeTable::FindType(PClass *metatype, void *parm1, void *parm2, size_t * //========================================================================== // -// FTypeTable :: AddType +// FTypeTable :: AddType - Fully Parameterized Version // //========================================================================== -void FTypeTable::AddType(PType *type, PClass *metatype, void *parm1, void *parm2, size_t bucket) +void FTypeTable::AddType(PType *type, PClass *metatype, const void *parm1, const void *parm2, size_t bucket) { #ifdef _DEBUG size_t bucketcheck; @@ -1003,6 +1258,29 @@ void FTypeTable::AddType(PType *type, PClass *metatype, void *parm1, void *parm2 #endif type->HashNext = TypeHash[bucket]; TypeHash[bucket] = type; + GC::WriteBarrier(type); +} + +//========================================================================== +// +// FTypeTable :: AddType - Simple Version +// +//========================================================================== + +void FTypeTable::AddType(PType *type) +{ + PClass *metatype; + const void *parm1, *parm2; + size_t bucket; + + metatype = type->GetClass()->TypeTableType; + type->GetTypeIDs(parm1, parm2); + bucket = Hash(metatype, parm1, parm2) % HASH_SIZE; + assert(FindType(metatype, parm1, parm2, NULL) == NULL && "Type must not be inserted more than once"); + + type->HashNext = TypeHash[bucket]; + TypeHash[bucket] = type; + GC::WriteBarrier(type); } //========================================================================== @@ -1011,7 +1289,7 @@ void FTypeTable::AddType(PType *type, PClass *metatype, void *parm1, void *parm2 // //========================================================================== -size_t FTypeTable::Hash(void *p1, void *p2, void *p3) +size_t FTypeTable::Hash(const void *p1, const void *p2, const void *p3) { size_t i1 = (size_t)p1; size_t i2 = (size_t)p2; @@ -1024,6 +1302,25 @@ size_t FTypeTable::Hash(void *p1, void *p2, void *p3) return (~i1 ^ i2) + i3 * 961748927; // i3 is multiplied by a prime } +//========================================================================== +// +// 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] != NULL) + { + GC::Mark(TypeHash[i]); + } + } +} + #include "c_dispatch.h" CCMD(typetable) { diff --git a/src/dobjtype.h b/src/dobjtype.h index 538e4574ea..4bf4fccd99 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -172,6 +172,7 @@ class PType : public DObject // and we can't define it until we've defined PClass. But we can't define that // without defining PType. DECLARE_ABSTRACT_CLASS(PType, DObject) + HAS_OBJECT_POINTERS; protected: enum { MetaClassNum = CLASSREG_PClassType }; public: @@ -183,6 +184,7 @@ public: PType *HashNext; // next type in this type table PType(); + PType(unsigned int size, unsigned int align); virtual ~PType(); // Returns true if this type matches the two identifiers. Referring to the @@ -193,6 +195,9 @@ public: // management. virtual bool IsMatch(const void *id1, const void *id2) const; + // Get the type IDs used by IsMatch + virtual void GetTypeIDs(const void *&id1, const void *&id2) const; + static void StaticInit(); }; @@ -201,6 +206,9 @@ public: class PBasicType : public PType { DECLARE_ABSTRACT_CLASS(PBasicType, PType); +public: + PBasicType(); + PBasicType(unsigned int size, unsigned int align); }; class PCompoundType : public PType @@ -219,6 +227,7 @@ public: PNamedType() : Outer(NULL) {} virtual bool IsMatch(const void *id1, const void *id2) const; + virtual void GetTypeIDs(const void *&id1, const void *&id2) const; }; // Basic types -------------------------------------------------------------- @@ -226,16 +235,28 @@ public: class PInt : public PBasicType { DECLARE_CLASS(PInt, PBasicType); +public: + PInt(unsigned int size, bool unsign); + + bool Unsigned; +protected: + PInt(); }; class PFloat : public PBasicType { DECLARE_CLASS(PFloat, PBasicType); +public: + PFloat(unsigned int size); +protected: + PFloat(); }; class PString : public PBasicType { DECLARE_CLASS(PString, PBasicType); +public: + PString(); }; // Variations of integer types ---------------------------------------------- @@ -243,16 +264,22 @@ class PString : public PBasicType class PName : public PInt { DECLARE_CLASS(PName, PInt); +public: + PName(); }; class PSound : public PInt { DECLARE_CLASS(PSound, PInt); +public: + PSound(); }; class PColor : public PInt { DECLARE_CLASS(PColor, PInt); +public: + PColor(); }; // Pointers ----------------------------------------------------------------- @@ -265,6 +292,7 @@ public: PType *PointedType; virtual bool IsMatch(const void *id1, const void *id2) const; + virtual void GetTypeIDs(const void *&id1, const void *&id2) const; }; class PClass; @@ -278,6 +306,7 @@ public: typedef PClass *Type2; virtual bool IsMatch(const void *id1, const void *id2) const; + virtual void GetTypeIDs(const void *&id1, const void *&id2) const; }; // Struct/class fields ------------------------------------------------------ @@ -318,6 +347,7 @@ public: unsigned int ElementCount; virtual bool IsMatch(const void *id1, const void *id2) const; + virtual void GetTypeIDs(const void *&id1, const void *&id2) const; }; // A vector is an array with extra operations. @@ -335,6 +365,7 @@ public: PType *ElementType; virtual bool IsMatch(const void *id1, const void *id2) const; + virtual void GetTypeIDs(const void *&id1, const void *&id2) const; }; class PMap : public PCompoundType @@ -346,6 +377,7 @@ public: PType *ValueType; virtual bool IsMatch(const void *id1, const void *id2) const; + virtual void GetTypeIDs(const void *&id1, const void *&id2) const; }; class PStruct : public PNamedType @@ -366,9 +398,10 @@ public: size_t PropagateMark(); virtual bool IsMatch(const void *id1, const void *id2) const; + virtual void GetTypeIDs(const void *&id1, const void *&id2) const; }; -// TBD: Should we support overloading? +// TBD: Should we really support overloading? class PFunction : public PNamedType { DECLARE_CLASS(PFunction, PNamedType); @@ -492,10 +525,12 @@ struct FTypeTable PType *TypeHash[HASH_SIZE]; - PType *FindType(PClass *metatype, void *parm1, void *parm2, size_t *bucketnum); - void AddType(PType *type, PClass *metatype, void *parm1, void *parm2, size_t bucket); + PType *FindType(PClass *metatype, const void *parm1, const void *parm2, size_t *bucketnum); + void AddType(PType *type, PClass *metatype, const void *parm1, const void *parm2, size_t bucket); + void AddType(PType *type); + void Mark(); - static size_t Hash(void *p1, void *p2, void *p3); + static size_t Hash(const void *p1, const void *p2, const void *p3); };