[llvm-commits] [llvm] r113283 - in /llvm/trunk: include/llvm/PassRegistry.h lib/VMCore/PassRegistry.cpp
Owen Anderson
resistor at mac.com
Tue Sep 7 13:48:10 PDT 2010
Author: resistor
Date: Tue Sep 7 15:48:10 2010
New Revision: 113283
URL: http://llvm.org/viewvc/llvm-project?rev=113283&view=rev
Log:
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.
Modified:
llvm/trunk/include/llvm/PassRegistry.h
llvm/trunk/lib/VMCore/PassRegistry.cpp
Modified: llvm/trunk/include/llvm/PassRegistry.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/PassRegistry.h?rev=113283&r1=113282&r2=113283&view=diff
==============================================================================
--- llvm/trunk/include/llvm/PassRegistry.h (original)
+++ llvm/trunk/include/llvm/PassRegistry.h Tue Sep 7 15:48:10 2010
@@ -37,6 +37,7 @@
public:
PassRegistry() : pImpl(0) { }
+ ~PassRegistry();
/// getPassRegistry - Access the global registry object, which is
/// automatically initialized at application launch and destroyed by
Modified: llvm/trunk/lib/VMCore/PassRegistry.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/PassRegistry.cpp?rev=113283&r1=113282&r2=113283&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/PassRegistry.cpp (original)
+++ llvm/trunk/lib/VMCore/PassRegistry.cpp Tue Sep 7 15:48:10 2010
@@ -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 @@
// 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::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);
More information about the llvm-commits
mailing list