summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/VMCore/Constants.cpp39
-rw-r--r--lib/VMCore/ConstantsContext.h31
-rw-r--r--lib/VMCore/LLVMContextImpl.cpp6
-rw-r--r--lib/VMCore/LLVMContextImpl.h8
4 files changed, 44 insertions, 40 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index d04298f149..f2d8794284 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -1127,13 +1127,29 @@ Constant *ConstantVector::getSplatValue() const {
//
ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
- return Ty->getContext().pImpl->NullPtrConstants.getOrCreate(Ty, 0);
+ OwningPtr<ConstantPointerNull> &Entry =
+ Ty->getContext().pImpl->CPNConstants[Ty];
+ if (Entry == 0)
+ Entry.reset(new ConstantPointerNull(Ty));
+
+ return Entry.get();
}
// destroyConstant - Remove the constant from the constant table...
//
void ConstantPointerNull::destroyConstant() {
- getType()->getContext().pImpl->NullPtrConstants.remove(this);
+ // Drop ownership of the CPN object before removing the entry so that it
+ // doesn't get double deleted.
+ LLVMContextImpl::CPNMapTy &CPNConstants = getContext().pImpl->CPNConstants;
+ LLVMContextImpl::CPNMapTy::iterator I = CPNConstants.find(getType());
+ assert(I != CPNConstants.end() && "CPN object not in uniquing map");
+ I->second.take();
+
+ // Actually remove the entry from the DenseMap now, which won't free the
+ // constant.
+ CPNConstants.erase(I);
+
+ // Free the constant and any dangling references to it.
destroyConstantImpl();
}
@@ -1142,13 +1158,28 @@ void ConstantPointerNull::destroyConstant() {
//
UndefValue *UndefValue::get(Type *Ty) {
- return Ty->getContext().pImpl->UndefValueConstants.getOrCreate(Ty, 0);
+ OwningPtr<UndefValue> &Entry = Ty->getContext().pImpl->UVConstants[Ty];
+ if (Entry == 0)
+ Entry.reset(new UndefValue(Ty));
+
+ return Entry.get();
}
// destroyConstant - Remove the constant from the constant table.
//
void UndefValue::destroyConstant() {
- getType()->getContext().pImpl->UndefValueConstants.remove(this);
+ // Drop ownership of the object before removing the entry so that it
+ // doesn't get double deleted.
+ LLVMContextImpl::UVMapTy &UVConstants = getContext().pImpl->UVConstants;
+ LLVMContextImpl::UVMapTy::iterator I = UVConstants.find(getType());
+ assert(I != UVConstants.end() && "UV object not in uniquing map");
+ I->second.take();
+
+ // Actually remove the entry from the DenseMap now, which won't free the
+ // constant.
+ UVConstants.erase(I);
+
+ // Free the constant and any dangling references to it.
destroyConstantImpl();
}
diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h
index fec2be58cf..4bdeaa7830 100644
--- a/lib/VMCore/ConstantsContext.h
+++ b/lib/VMCore/ConstantsContext.h
@@ -514,37 +514,6 @@ struct ConstantKeyData<ConstantStruct> {
}
};
-// ConstantPointerNull does not take extra "value" argument...
-template<class ValType>
-struct ConstantCreator<ConstantPointerNull, PointerType, ValType> {
- static ConstantPointerNull *create(PointerType *Ty, const ValType &V){
- return new ConstantPointerNull(Ty);
- }
-};
-
-template<>
-struct ConstantKeyData<ConstantPointerNull> {
- typedef char ValType;
- static ValType getValType(ConstantPointerNull *C) {
- return 0;
- }
-};
-
-// UndefValue does not take extra "value" argument...
-template<class ValType>
-struct ConstantCreator<UndefValue, Type, ValType> {
- static UndefValue *create(Type *Ty, const ValType &V) {
- return new UndefValue(Ty);
- }
-};
-
-template<>
-struct ConstantKeyData<UndefValue> {
- typedef char ValType;
- static ValType getValType(UndefValue *C) {
- return 0;
- }
-};
template<>
struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> {
diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp
index 7ab3ccec62..de851ee4bb 100644
--- a/lib/VMCore/LLVMContextImpl.cpp
+++ b/lib/VMCore/LLVMContextImpl.cpp
@@ -58,6 +58,8 @@ LLVMContextImpl::~LLVMContextImpl() {
std::vector<Module*> Modules(OwnedModules.begin(), OwnedModules.end());
DeleteContainerPointers(Modules);
+ // Free the constants. This is important to do here to ensure that they are
+ // freed before the LeakDetector is torn down.
std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(),
DropReferences());
std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(),
@@ -71,8 +73,8 @@ LLVMContextImpl::~LLVMContextImpl() {
StructConstants.freeConstants();
VectorConstants.freeConstants();
CAZConstants.clear();
- NullPtrConstants.freeConstants();
- UndefValueConstants.freeConstants();
+ CPNConstants.clear();
+ UVConstants.clear();
InlineAsms.freeConstants();
DeleteContainerSeconds(IntConstants);
DeleteContainerSeconds(FPConstants);
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h
index f963f63921..9d8722b272 100644
--- a/lib/VMCore/LLVMContextImpl.h
+++ b/lib/VMCore/LLVMContextImpl.h
@@ -154,9 +154,11 @@ public:
VectorType, ConstantVector> VectorConstantsTy;
VectorConstantsTy VectorConstants;
- ConstantUniqueMap<char, char, PointerType, ConstantPointerNull>
- NullPtrConstants;
- ConstantUniqueMap<char, char, Type, UndefValue> UndefValueConstants;
+ typedef DenseMap<PointerType*, OwningPtr<ConstantPointerNull> > CPNMapTy;
+ CPNMapTy CPNConstants;
+
+ typedef DenseMap<Type*, OwningPtr<UndefValue> > UVMapTy;
+ UVMapTy UVConstants;
DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses;
ConstantUniqueMap<ExprMapKeyType, const ExprMapKeyType&, Type, ConstantExpr>