new helper class to provide more explicit management of static ctor/dtors.
authorChris Lattner <sabre@nondot.org>
Thu, 28 Sep 2006 00:31:55 +0000 (00:31 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 28 Sep 2006 00:31:55 +0000 (00:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30638 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/ManagedStatic.h [new file with mode: 0644]
lib/Support/ManagedStatic.cpp [new file with mode: 0644]

diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
new file mode 100644 (file)
index 0000000..7753105
--- /dev/null
@@ -0,0 +1,79 @@
+//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ManagedStatic class and the llvm_shutdown() function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
+#define LLVM_SUPPORT_MANAGED_STATIC_H
+
+namespace llvm {
+
+/// object_deleter - Helper method for ManagedStatic.
+///
+template<class C>
+void object_deleter(void *Ptr) {
+  delete (C*)Ptr;
+}
+
+/// ManagedStaticBase - Common base class for ManagedStatic instances.
+class ManagedStaticBase {
+protected:
+  // This should only be used as a static variable, which guarantees that this
+  // will be zero initialized.
+  mutable void *Ptr;
+  mutable void (*DeleterFn)(void*);
+  mutable const ManagedStaticBase *Next;
+  
+  void RegisterManagedStatic(void *ObjPtr, void (*deleter)(void*)) const;
+public:
+  void destroy() const;
+};
+
+/// ManagedStatic - This transparently changes the behavior of global statics to
+/// be lazily constructed on demand (good for reducing startup times of dynamic
+/// libraries that link in LLVM components) and for making destruction be
+/// explicit through the llvm_shutdown() function call.
+///
+template<class C>
+class ManagedStatic : public ManagedStaticBase {
+public:
+  
+  // Accessors.
+  C &operator*() {
+    if (!Ptr) LazyInit();
+    return *static_cast<C*>(Ptr);
+  }
+  C *operator->() {
+    if (!Ptr) LazyInit();
+    return static_cast<C*>(Ptr);
+  }
+  const C &operator*() const {
+    if (!Ptr) LazyInit();
+    return *static_cast<C*>(Ptr);
+  }
+  const C *operator->() const {
+    if (!Ptr) LazyInit();
+    return static_cast<C*>(Ptr);
+  }
+  
+public:
+  void LazyInit() const {
+    RegisterManagedStatic(new C(), object_deleter<C>);
+  }
+};
+
+
+/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
+void llvm_shutdown();
+
+}
+
+#endif
diff --git a/lib/Support/ManagedStatic.cpp b/lib/Support/ManagedStatic.cpp
new file mode 100644 (file)
index 0000000..85daaf8
--- /dev/null
@@ -0,0 +1,53 @@
+//===-- ManagedStatic.cpp - Static Global wrapper -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ManagedStatic class and llvm_shutdown().
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ManagedStatic.h"
+#include <cassert>
+using namespace llvm;
+
+static const ManagedStaticBase *StaticList = 0;
+
+void ManagedStaticBase::RegisterManagedStatic(void *ObjPtr,
+                                              void (*Deleter)(void*)) const {
+  assert(Ptr == 0 && DeleterFn == 0 && Next == 0 &&
+         "Partially init static?");
+  Ptr = ObjPtr;
+  DeleterFn = Deleter;
+  
+  // Add to list of managed statics.
+  Next = StaticList;
+  StaticList = this;
+}
+
+void ManagedStaticBase::destroy() const {
+  assert(Ptr && DeleterFn && "ManagedStatic not initialized correctly!");
+  assert(StaticList == this &&
+         "Not destroyed in reverse order of construction?");
+  // Unlink from list.
+  StaticList = Next;
+  Next = 0;
+
+  // Destroy memory.
+  DeleterFn(Ptr);
+  
+  // Cleanup.
+  Ptr = 0;
+  DeleterFn = 0;
+}
+
+/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
+void llvm_shutdown() {
+  while (StaticList)
+    StaticList->destroy();
+}
+