Try again at privatizing the layout info map, with a rewritten patch.

This preserves the existing behavior much more closely than my previous attempt.

llvm-svn: 79663
This commit is contained in:
Owen Anderson 2009-08-21 19:59:12 +00:00
parent cee0600755
commit e1a4b0a055
2 changed files with 22 additions and 48 deletions

View File

@ -91,6 +91,9 @@ private:
*/ */
static const TargetAlignElem InvalidAlignmentElem; static const TargetAlignElem InvalidAlignmentElem;
// Opaque pointer for the StructType -> StructLayout map.
mutable void* LayoutMap;
//! Set/initialize target alignments //! Set/initialize target alignments
void setAlignment(AlignTypeEnum align_type, unsigned char abi_align, void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
unsigned char pref_align, uint32_t bit_width); unsigned char pref_align, uint32_t bit_width);
@ -132,7 +135,8 @@ public:
PointerMemSize(TD.PointerMemSize), PointerMemSize(TD.PointerMemSize),
PointerABIAlign(TD.PointerABIAlign), PointerABIAlign(TD.PointerABIAlign),
PointerPrefAlign(TD.PointerPrefAlign), PointerPrefAlign(TD.PointerPrefAlign),
Alignments(TD.Alignments) Alignments(TD.Alignments),
LayoutMap(0)
{ } { }
~TargetData(); // Not virtual, do not subclass this class ~TargetData(); // Not virtual, do not subclass this class

View File

@ -172,6 +172,7 @@ const TargetAlignElem TargetData::InvalidAlignmentElem =
void TargetData::init(const std::string &TargetDescription) { void TargetData::init(const std::string &TargetDescription) {
std::string temp = TargetDescription; std::string temp = TargetDescription;
LayoutMap = 0;
LittleEndian = false; LittleEndian = false;
PointerMemSize = 8; PointerMemSize = 8;
PointerABIAlign = 8; PointerABIAlign = 8;
@ -317,61 +318,30 @@ unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType,
: Alignments[BestMatchIdx].PrefAlign; : Alignments[BestMatchIdx].PrefAlign;
} }
namespace { typedef DenseMap<const StructType*, StructLayout*>LayoutInfoTy;
/// LayoutInfo - The lazy cache of structure layout information maintained by
/// TargetData. Note that the struct types must have been free'd before
/// llvm_shutdown is called (and thus this is deallocated) because all the
/// targets with cached elements should have been destroyed.
///
typedef std::pair<const TargetData*,const StructType*> LayoutKey;
struct DenseMapLayoutKeyInfo {
static inline LayoutKey getEmptyKey() { return LayoutKey(0, 0); }
static inline LayoutKey getTombstoneKey() {
return LayoutKey((TargetData*)(intptr_t)-1, 0);
}
static unsigned getHashValue(const LayoutKey &Val) {
return DenseMapInfo<void*>::getHashValue(Val.first) ^
DenseMapInfo<void*>::getHashValue(Val.second);
}
static bool isEqual(const LayoutKey &LHS, const LayoutKey &RHS) {
return LHS == RHS;
}
static bool isPod() { return true; }
};
typedef DenseMap<LayoutKey, StructLayout*, DenseMapLayoutKeyInfo> LayoutInfoTy;
}
static ManagedStatic<LayoutInfoTy> LayoutInfo;
static ManagedStatic<sys::SmartMutex<true> > LayoutLock;
TargetData::~TargetData() { TargetData::~TargetData() {
if (!LayoutInfo.isConstructed()) if (!LayoutMap)
return; return;
sys::SmartScopedLock<true> Lock(*LayoutLock);
// Remove any layouts for this TD. // Remove any layouts for this TD.
LayoutInfoTy &TheMap = *LayoutInfo; LayoutInfoTy &TheMap = *static_cast<LayoutInfoTy*>(LayoutMap);
for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end(); I != E; ) { for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end(); I != E; ) {
if (I->first.first == this) { I->second->~StructLayout();
I->second->~StructLayout(); free(I->second);
free(I->second); TheMap.erase(I++);
TheMap.erase(I++);
} else {
++I;
}
} }
delete static_cast<LayoutInfoTy*>(LayoutMap);
} }
const StructLayout *TargetData::getStructLayout(const StructType *Ty) const { const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
LayoutInfoTy &TheMap = *LayoutInfo; if (!LayoutMap)
LayoutMap = static_cast<void*>(new LayoutInfoTy());
sys::SmartScopedLock<true> Lock(*LayoutLock); LayoutInfoTy &TheMap = *static_cast<LayoutInfoTy*>(LayoutMap);
StructLayout *&SL = TheMap[LayoutKey(this, Ty)];
StructLayout *&SL = TheMap[Ty];
if (SL) return SL; if (SL) return SL;
// Otherwise, create the struct layout. Because it is variable length, we // Otherwise, create the struct layout. Because it is variable length, we
@ -393,10 +363,10 @@ const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
/// removed, this method must be called whenever a StructType is removed to /// removed, this method must be called whenever a StructType is removed to
/// avoid a dangling pointer in this cache. /// avoid a dangling pointer in this cache.
void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const { void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
if (!LayoutInfo.isConstructed()) return; // No cache. if (!LayoutMap) return; // No cache.
sys::SmartScopedLock<true> Lock(*LayoutLock); LayoutInfoTy* LayoutInfo = static_cast<LayoutInfoTy*>(LayoutMap);
LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty)); LayoutInfoTy::iterator I = LayoutInfo->find(Ty);
if (I == LayoutInfo->end()) return; if (I == LayoutInfo->end()) return;
I->second->~StructLayout(); I->second->~StructLayout();