From dd5eb023048d0ac69721eb919d3ef1bbaee2e1ce Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 3 Dec 2009 00:17:12 +0000 Subject: [PATCH] This initial code is meant to convert TargetData to use an AbstractTypesUser so that it doesn't have dangling pointers when abstract types are resolved. This modifies it somewhat to address comments: making the "StructLayoutMap" an anonymous structure, calling "removeAbstractTypeUser" when appropriate, and adding asserts where helpful. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90362 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetData.h | 3 +- lib/Target/TargetData.cpp | 97 +++++++++++++------------------- 2 files changed, 39 insertions(+), 61 deletions(-) diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index e1d052edbe1..5ed0f13ef0f 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -30,7 +30,6 @@ class Type; class IntegerType; class StructType; class StructLayout; -class StructLayoutMap; class GlobalVariable; class LLVMContext; @@ -86,7 +85,7 @@ private: static const TargetAlignElem InvalidAlignmentElem; // The StructType -> StructLayout map. - mutable StructLayoutMap *LayoutMap; + mutable void *LayoutMap; //! Set/initialize target alignments void setAlignment(AlignTypeEnum align_type, unsigned char abi_align, diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index fc71bc3ab1f..ec00f9e2e9a 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -325,7 +325,7 @@ unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType, typedef DenseMap LayoutInfoTy; -namespace llvm { +namespace { class StructLayoutMap : public AbstractTypeUser { LayoutInfoTy LayoutInfo; @@ -337,18 +337,12 @@ class StructLayoutMap : public AbstractTypeUser { virtual void refineAbstractType(const DerivedType *OldTy, const Type *) { const StructType *STy = dyn_cast(OldTy); - if (!STy) { - OldTy->removeAbstractTypeUser(this); - return; - } - - StructLayout *SL = LayoutInfo[STy]; - if (SL) { - SL->~StructLayout(); - free(SL); - LayoutInfo[STy] = NULL; - } + assert(STy && "This can only track struct types."); + LayoutInfoTy::iterator Iter = LayoutInfo.find(STy); + Iter->second->~StructLayout(); + free(Iter->second); + LayoutInfo.erase(Iter); OldTy->removeAbstractTypeUser(this); } @@ -359,69 +353,46 @@ class StructLayoutMap : public AbstractTypeUser { /// virtual void typeBecameConcrete(const DerivedType *AbsTy) { const StructType *STy = dyn_cast(AbsTy); - if (!STy) { - AbsTy->removeAbstractTypeUser(this); - return; - } - - StructLayout *SL = LayoutInfo[STy]; - if (SL) { - SL->~StructLayout(); - free(SL); - LayoutInfo[STy] = NULL; - } + assert(STy && "This can only track struct types."); + LayoutInfoTy::iterator Iter = LayoutInfo.find(STy); + Iter->second->~StructLayout(); + free(Iter->second); + LayoutInfo.erase(Iter); AbsTy->removeAbstractTypeUser(this); } - bool insert(const Type *Ty) { - if (Ty->isAbstract()) - Ty->addAbstractTypeUser(this); - return true; - } - public: virtual ~StructLayoutMap() { // Remove any layouts. for (LayoutInfoTy::iterator - I = LayoutInfo.begin(), E = LayoutInfo.end(); I != E; ++I) - if (StructLayout *SL = I->second) { - SL->~StructLayout(); - free(SL); + I = LayoutInfo.begin(), E = LayoutInfo.end(); I != E; ++I) { + const Type *Key = I->first; + StructLayout *Value = I->second; + + if (Key && Key->isAbstract()) + Key->removeAbstractTypeUser(this); + + if (Value) { + Value->~StructLayout(); + free(Value); } + } } - inline LayoutInfoTy::iterator begin() { - return LayoutInfo.begin(); - } - inline LayoutInfoTy::iterator end() { - return LayoutInfo.end(); - } - inline LayoutInfoTy::const_iterator begin() const { - return LayoutInfo.begin(); - } - inline LayoutInfoTy::const_iterator end() const { + LayoutInfoTy::iterator end() { return LayoutInfo.end(); } LayoutInfoTy::iterator find(const StructType *&Val) { return LayoutInfo.find(Val); } - LayoutInfoTy::const_iterator find(const StructType *&Val) const { - return LayoutInfo.find(Val); - } - bool erase(const StructType *&Val) { - return LayoutInfo.erase(Val); - } bool erase(LayoutInfoTy::iterator I) { return LayoutInfo.erase(I); } - StructLayout *&operator[](const Type *Key) { - const StructType *STy = dyn_cast(Key); - assert(STy && "Trying to access the struct layout map with a non-struct!"); - insert(STy); + StructLayout *&operator[](const StructType *STy) { return LayoutInfo[STy]; } @@ -432,14 +403,15 @@ public: } // end namespace llvm TargetData::~TargetData() { - delete LayoutMap; + delete static_cast(LayoutMap); } const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { if (!LayoutMap) LayoutMap = new StructLayoutMap(); - StructLayout *&SL = (*LayoutMap)[Ty]; + StructLayoutMap *STM = static_cast(LayoutMap); + StructLayout *&SL = (*STM)[Ty]; if (SL) return SL; // Otherwise, create the struct layout. Because it is variable length, we @@ -453,6 +425,10 @@ const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { SL = L; new (L) StructLayout(Ty, *this); + + if (Ty->isAbstract()) + Ty->addAbstractTypeUser(STM); + return L; } @@ -463,14 +439,17 @@ const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const { if (!LayoutMap) return; // No cache. - DenseMap::iterator I = LayoutMap->find(Ty); - if (I == LayoutMap->end()) return; + StructLayoutMap *STM = static_cast(LayoutMap); + LayoutInfoTy::iterator I = STM->find(Ty); + if (I == STM->end()) return; I->second->~StructLayout(); free(I->second); - LayoutMap->erase(I); -} + STM->erase(I); + if (Ty->isAbstract()) + Ty->removeAbstractTypeUser(STM); +} std::string TargetData::getStringRepresentation() const { std::string Result;