diff options
author | Owen Anderson <resistor@mac.com> | 2010-09-07 20:48:10 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2010-09-07 20:48:10 +0000 |
commit | 381f17ee7c07b5a80d7dcdeae3d62e497902ef85 (patch) | |
tree | 004dfc9ead5654ca88b54ae2fea40a98446dc3f3 /lib | |
parent | a830f2c4ea8ce1d1bea6823e8b8585eafa7caf33 (diff) |
Fix PR7972, in which the PassRegistry was being leaked. As part of this,
switch to using a ManagedStatic for the global PassRegistry instead of a
ManagedCleanup, and fix a destruction ordering bug this exposed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113283 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/VMCore/PassRegistry.cpp | 51 |
1 files changed, 16 insertions, 35 deletions
diff --git a/lib/VMCore/PassRegistry.cpp b/lib/VMCore/PassRegistry.cpp index 562c58c0b9..9196d42114 100644 --- a/lib/VMCore/PassRegistry.cpp +++ b/lib/VMCore/PassRegistry.cpp @@ -22,45 +22,14 @@ using namespace llvm; -static PassRegistry *PassRegistryObj = 0; -PassRegistry *PassRegistry::getPassRegistry() { - // Use double-checked locking to safely initialize the registrar when - // we're running in multithreaded mode. - PassRegistry* tmp = PassRegistryObj; - if (llvm_is_multithreaded()) { - sys::MemoryFence(); - if (!tmp) { - llvm_acquire_global_lock(); - tmp = PassRegistryObj; - if (!tmp) { - tmp = new PassRegistry(); - sys::MemoryFence(); - PassRegistryObj = tmp; - } - llvm_release_global_lock(); - } - } else if (!tmp) { - PassRegistryObj = new PassRegistry(); - } - - return PassRegistryObj; -} - -namespace { - -// FIXME: We use ManagedCleanup to erase the pass registrar on shutdown. +// FIXME: We use ManagedStatic to erase the pass registrar on shutdown. // Unfortunately, passes are registered with static ctors, and having // llvm_shutdown clear this map prevents successful ressurection after // llvm_shutdown is run. Ideally we should find a solution so that we don't // leak the map, AND can still resurrect after shutdown. -void cleanupPassRegistry(void*) { - if (PassRegistryObj) { - delete PassRegistryObj; - PassRegistryObj = 0; - } -} -ManagedCleanup<&cleanupPassRegistry> registryCleanup ATTRIBUTE_USED; - +static ManagedStatic<PassRegistry> PassRegistryObj; +PassRegistry *PassRegistry::getPassRegistry() { + return &*PassRegistryObj; } //===----------------------------------------------------------------------===// @@ -94,6 +63,12 @@ void *PassRegistry::getImpl() const { // Accessors // +PassRegistry::~PassRegistry() { + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl); + if (Impl) delete Impl; + pImpl = 0; +} + const PassInfo *PassRegistry::getPassInfo(const void *TI) const { PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI); @@ -188,6 +163,12 @@ void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { } void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { + // NOTE: This is necessary, because removeRegistrationListener() can be called + // as part of the llvm_shutdown sequence. Since we have no control over the + // order of that sequence, we need to gracefully handle the case where the + // PassRegistry is destructed before the object that triggers this call. + if (!pImpl) return; + PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); std::vector<PassRegistrationListener*>::iterator I = std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L); |