llvm.org GIT mirror llvm / 9085750
Try again at privatizing the layout info map, with a rewritten patch. This preserves the existing behavior much more closely than my previous attempt. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79663 91177308-0d34-0410-b5e6-96231b3b80d8 Owen Anderson 10 years ago
2 changed file(s) with 25 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
9090 */
9191 static const TargetAlignElem InvalidAlignmentElem;
9292
93 // Opaque pointer for the StructType -> StructLayout map.
94 mutable void* LayoutMap;
95
9396 //! Set/initialize target alignments
9497 void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
9598 unsigned char pref_align, uint32_t bit_width);
131134 PointerMemSize(TD.PointerMemSize),
132135 PointerABIAlign(TD.PointerABIAlign),
133136 PointerPrefAlign(TD.PointerPrefAlign),
134 Alignments(TD.Alignments)
137 Alignments(TD.Alignments),
138 LayoutMap(0)
135139 { }
136140
137141 ~TargetData(); // Not virtual, do not subclass this class
171171 void TargetData::init(const std::string &TargetDescription) {
172172 std::string temp = TargetDescription;
173173
174 LayoutMap = 0;
174175 LittleEndian = false;
175176 PointerMemSize = 8;
176177 PointerABIAlign = 8;
316317 : Alignments[BestMatchIdx].PrefAlign;
317318 }
318319
319 namespace {
320
321 /// LayoutInfo - The lazy cache of structure layout information maintained by
322 /// TargetData. Note that the struct types must have been free'd before
323 /// llvm_shutdown is called (and thus this is deallocated) because all the
324 /// targets with cached elements should have been destroyed.
325 ///
326 typedef std::pair LayoutKey;
327
328 struct DenseMapLayoutKeyInfo {
329 static inline LayoutKey getEmptyKey() { return LayoutKey(0, 0); }
330 static inline LayoutKey getTombstoneKey() {
331 return LayoutKey((TargetData*)(intptr_t)-1, 0);
332 }
333 static unsigned getHashValue(const LayoutKey &Val) {
334 return DenseMapInfo::getHashValue(Val.first) ^
335 DenseMapInfo::getHashValue(Val.second);
336 }
337 static bool isEqual(const LayoutKey &LHS, const LayoutKey &RHS) {
338 return LHS == RHS;
339 }
340
341 static bool isPod() { return true; }
342 };
343
344 typedef DenseMap LayoutInfoTy;
345
346 }
347
348 static ManagedStatic LayoutInfo;
349 static ManagedStatic > LayoutLock;
320 typedef DenseMapLayoutInfoTy;
350321
351322 TargetData::~TargetData() {
352 if (!LayoutInfo.isConstructed())
323 if (!LayoutMap)
353324 return;
354325
355 sys::SmartScopedLock Lock(*LayoutLock);
356326 // Remove any layouts for this TD.
357 LayoutInfoTy &TheMap = *LayoutInfo;
327 LayoutInfoTy &TheMap = *static_cast(LayoutMap);
358328 for (LayoutInfoTy::iterator I = TheMap.begin(), E = TheMap.end(); I != E; ) {
359 if (I->first.first == this) {
360 I->second->~StructLayout();
361 free(I->second);
362 TheMap.erase(I++);
363 } else {
364 ++I;
365 }
366 }
329 I->second->~StructLayout();
330 free(I->second);
331 TheMap.erase(I++);
332 }
333
334 delete static_cast(LayoutMap);
367335 }
368336
369337 const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
370 LayoutInfoTy &TheMap = *LayoutInfo;
371
372 sys::SmartScopedLock Lock(*LayoutLock);
373 StructLayout *&SL = TheMap[LayoutKey(this, Ty)];
338 if (!LayoutMap)
339 LayoutMap = static_cast(new LayoutInfoTy());
340
341 LayoutInfoTy &TheMap = *static_cast(LayoutMap);
342
343 StructLayout *&SL = TheMap[Ty];
374344 if (SL) return SL;
375345
376346 // Otherwise, create the struct layout. Because it is variable length, we
392362 /// removed, this method must be called whenever a StructType is removed to
393363 /// avoid a dangling pointer in this cache.
394364 void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
395 if (!LayoutInfo.isConstructed()) return; // No cache.
396
397 sys::SmartScopedLock Lock(*LayoutLock);
398 LayoutInfoTy::iterator I = LayoutInfo->find(LayoutKey(this, Ty));
365 if (!LayoutMap) return; // No cache.
366
367 LayoutInfoTy* LayoutInfo = static_cast(LayoutMap);
368 LayoutInfoTy::iterator I = LayoutInfo->find(Ty);
399369 if (I == LayoutInfo->end()) return;
400370
401371 I->second->~StructLayout();