1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

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.

llvm-svn: 113283
This commit is contained in:
Owen Anderson 2010-09-07 20:48:10 +00:00
parent 92dd0fd9ba
commit 94ae132fc8
2 changed files with 17 additions and 35 deletions

View File

@ -37,6 +37,7 @@ class PassRegistry {
public: public:
PassRegistry() : pImpl(0) { } PassRegistry() : pImpl(0) { }
~PassRegistry();
/// getPassRegistry - Access the global registry object, which is /// getPassRegistry - Access the global registry object, which is
/// automatically initialized at application launch and destroyed by /// automatically initialized at application launch and destroyed by

View File

@ -22,45 +22,14 @@
using namespace llvm; using namespace llvm;
static PassRegistry *PassRegistryObj = 0; // FIXME: We use ManagedStatic to erase the pass registrar on shutdown.
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.
// Unfortunately, passes are registered with static ctors, and having // Unfortunately, passes are registered with static ctors, and having
// llvm_shutdown clear this map prevents successful ressurection after // llvm_shutdown clear this map prevents successful ressurection after
// llvm_shutdown is run. Ideally we should find a solution so that we don't // llvm_shutdown is run. Ideally we should find a solution so that we don't
// leak the map, AND can still resurrect after shutdown. // leak the map, AND can still resurrect after shutdown.
void cleanupPassRegistry(void*) { static ManagedStatic<PassRegistry> PassRegistryObj;
if (PassRegistryObj) { PassRegistry *PassRegistry::getPassRegistry() {
delete PassRegistryObj; return &*PassRegistryObj;
PassRegistryObj = 0;
}
}
ManagedCleanup<&cleanupPassRegistry> registryCleanup ATTRIBUTE_USED;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -94,6 +63,12 @@ void *PassRegistry::getImpl() const {
// Accessors // Accessors
// //
PassRegistry::~PassRegistry() {
PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl);
if (Impl) delete Impl;
pImpl = 0;
}
const PassInfo *PassRegistry::getPassInfo(const void *TI) const { const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI); PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI);
@ -188,6 +163,12 @@ void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
} }
void PassRegistry::removeRegistrationListener(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()); PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
std::vector<PassRegistrationListener*>::iterator I = std::vector<PassRegistrationListener*>::iterator I =
std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L); std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L);