summaryrefslogtreecommitdiff
path: root/lib/VMCore/Attributes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore/Attributes.cpp')
-rw-r--r--lib/VMCore/Attributes.cpp96
1 files changed, 82 insertions, 14 deletions
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index f1268e6ef8..5a552c34e1 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -355,8 +355,62 @@ uint64_t AttributesImpl::getStackAlignment() const {
// AttributeListImpl Definition
//===----------------------------------------------------------------------===//
-AttrListPtr AttrListPtr::get(LLVMContext &C,
- ArrayRef<AttributeWithIndex> Attrs) {
+namespace llvm {
+ class AttributeListImpl;
+}
+
+static ManagedStatic<FoldingSet<AttributeListImpl> > AttributesLists;
+
+namespace llvm {
+static ManagedStatic<sys::SmartMutex<true> > ALMutex;
+
+class AttributeListImpl : public FoldingSetNode {
+ sys::cas_flag RefCount;
+
+ // AttributesList is uniqued, these should not be publicly available.
+ void operator=(const AttributeListImpl &) LLVM_DELETED_FUNCTION;
+ AttributeListImpl(const AttributeListImpl &) LLVM_DELETED_FUNCTION;
+ ~AttributeListImpl(); // Private implementation
+public:
+ SmallVector<AttributeWithIndex, 4> Attrs;
+
+ AttributeListImpl(ArrayRef<AttributeWithIndex> attrs)
+ : Attrs(attrs.begin(), attrs.end()) {
+ RefCount = 0;
+ }
+
+ void AddRef() {
+ sys::SmartScopedLock<true> Lock(*ALMutex);
+ ++RefCount;
+ }
+ void DropRef() {
+ sys::SmartScopedLock<true> Lock(*ALMutex);
+ if (!AttributesLists.isConstructed())
+ return;
+ sys::cas_flag new_val = --RefCount;
+ if (new_val == 0)
+ delete this;
+ }
+
+ void Profile(FoldingSetNodeID &ID) const {
+ Profile(ID, Attrs);
+ }
+ static void Profile(FoldingSetNodeID &ID, ArrayRef<AttributeWithIndex> Attrs){
+ for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
+ ID.AddInteger(Attrs[i].Attrs.Raw());
+ ID.AddInteger(Attrs[i].Index);
+ }
+ }
+};
+
+} // end llvm namespace
+
+AttributeListImpl::~AttributeListImpl() {
+ // NOTE: Lock must be acquired by caller.
+ AttributesLists->RemoveNode(this);
+}
+
+AttrListPtr AttrListPtr::get(ArrayRef<AttributeWithIndex> Attrs) {
// If there are no attributes then return a null AttributesList pointer.
if (Attrs.empty())
return AttrListPtr();
@@ -371,36 +425,51 @@ AttrListPtr AttrListPtr::get(LLVMContext &C,
#endif
// Otherwise, build a key to look up the existing attributes.
- LLVMContextImpl *pImpl = C.pImpl;
FoldingSetNodeID ID;
AttributeListImpl::Profile(ID, Attrs);
+ void *InsertPos;
- void *InsertPoint;
- AttributeListImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID,
- InsertPoint);
+ sys::SmartScopedLock<true> Lock(*ALMutex);
+
+ AttributeListImpl *PAL =
+ AttributesLists->FindNodeOrInsertPos(ID, InsertPos);
// If we didn't find any existing attributes of the same shape then
// create a new one and insert it.
- if (!PA) {
- PA = new AttributeListImpl(Attrs);
- pImpl->AttrsLists.InsertNode(PA, InsertPoint);
+ if (!PAL) {
+ PAL = new AttributeListImpl(Attrs);
+ AttributesLists->InsertNode(PAL, InsertPos);
}
// Return the AttributesList that we found or created.
- return AttrListPtr(PA);
+ return AttrListPtr(PAL);
}
//===----------------------------------------------------------------------===//
// AttrListPtr Method Implementations
//===----------------------------------------------------------------------===//
+AttrListPtr::AttrListPtr(AttributeListImpl *LI) : AttrList(LI) {
+ if (LI) LI->AddRef();
+}
+
+AttrListPtr::AttrListPtr(const AttrListPtr &P) : AttrList(P.AttrList) {
+ if (AttrList) AttrList->AddRef();
+}
+
const AttrListPtr &AttrListPtr::operator=(const AttrListPtr &RHS) {
+ sys::SmartScopedLock<true> Lock(*ALMutex);
if (AttrList == RHS.AttrList) return *this;
-
+ if (AttrList) AttrList->DropRef();
AttrList = RHS.AttrList;
+ if (AttrList) AttrList->AddRef();
return *this;
}
+AttrListPtr::~AttrListPtr() {
+ if (AttrList) AttrList->DropRef();
+}
+
/// getNumSlots - Return the number of slots used in this attribute list.
/// This is the number of arguments that have an attribute set on them
/// (including the function itself).
@@ -438,7 +507,6 @@ bool AttrListPtr::hasAttrSomewhere(Attributes::AttrVal Attr) const {
for (unsigned i = 0, e = Attrs.size(); i != e; ++i)
if (Attrs[i].Attrs.hasAttribute(Attr))
return true;
-
return false;
}
@@ -494,7 +562,7 @@ AttrListPtr AttrListPtr::addAttr(LLVMContext &C, unsigned Idx,
OldAttrList.begin()+i, OldAttrList.end());
}
- return get(C, NewAttrList);
+ return get(NewAttrList);
}
AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx,
@@ -533,7 +601,7 @@ AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx,
NewAttrList.insert(NewAttrList.end(),
OldAttrList.begin()+i, OldAttrList.end());
- return get(C, NewAttrList);
+ return get(NewAttrList);
}
void AttrListPtr::dump() const {