ManagedStatic.h revision 68ce9ba666a7eb8c7eb3fb7888e4418fffd2e716
1771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
2771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//
3771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//                     The LLVM Compiler Infrastructure
4771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//
5771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner// This file was developed by Chris Lattner and is distributed under
6771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner// the University of Illinois Open Source License. See LICENSE.TXT for details.
7771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//
8771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//===----------------------------------------------------------------------===//
9771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//
10771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner// This file defines the ManagedStatic class and the llvm_shutdown() function.
11771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//
12771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//===----------------------------------------------------------------------===//
13771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
14771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
15771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner#define LLVM_SUPPORT_MANAGED_STATIC_H
16771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
17771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnernamespace llvm {
18771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
19771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// object_deleter - Helper method for ManagedStatic.
20771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner///
21771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnertemplate<class C>
22771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnervoid object_deleter(void *Ptr) {
23771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  delete (C*)Ptr;
24771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner}
25771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
26771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// ManagedStaticBase - Common base class for ManagedStatic instances.
27771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerclass ManagedStaticBase {
28771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerprotected:
29771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  // This should only be used as a static variable, which guarantees that this
30771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  // will be zero initialized.
31771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  mutable void *Ptr;
32771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  mutable void (*DeleterFn)(void*);
33771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  mutable const ManagedStaticBase *Next;
34771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
35771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  void RegisterManagedStatic(void *ObjPtr, void (*deleter)(void*)) const;
36771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerpublic:
3768ce9ba666a7eb8c7eb3fb7888e4418fffd2e716Chris Lattner  /// isConstructed - Return true if this object has not been created yet.
3868ce9ba666a7eb8c7eb3fb7888e4418fffd2e716Chris Lattner  bool isConstructed() const { return Ptr != 0; }
3968ce9ba666a7eb8c7eb3fb7888e4418fffd2e716Chris Lattner
40771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  void destroy() const;
41771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner};
42771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
43771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// ManagedStatic - This transparently changes the behavior of global statics to
44771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// be lazily constructed on demand (good for reducing startup times of dynamic
45771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// libraries that link in LLVM components) and for making destruction be
46771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// explicit through the llvm_shutdown() function call.
47771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner///
48771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnertemplate<class C>
49771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerclass ManagedStatic : public ManagedStaticBase {
50771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerpublic:
51771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
52771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  // Accessors.
53771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  C &operator*() {
54771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner    if (!Ptr) LazyInit();
55771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner    return *static_cast<C*>(Ptr);
56771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  }
57771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  C *operator->() {
58771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner    if (!Ptr) LazyInit();
59771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner    return static_cast<C*>(Ptr);
60771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  }
61771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  const C &operator*() const {
62771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner    if (!Ptr) LazyInit();
63771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner    return *static_cast<C*>(Ptr);
64771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  }
65771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  const C *operator->() const {
66771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner    if (!Ptr) LazyInit();
67771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner    return static_cast<C*>(Ptr);
68771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  }
69771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
70771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerpublic:
71771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  void LazyInit() const {
72771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner    RegisterManagedStatic(new C(), object_deleter<C>);
73771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  }
74771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner};
75771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
76771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
77771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
78771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnervoid llvm_shutdown();
79771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
80bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner
81bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner/// llvm_shutdown_obj - This is a simple helper class that calls
82bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner/// llvm_shutdown() when it is destroyed.
83bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattnerstruct llvm_shutdown_obj {
84bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner  llvm_shutdown_obj() {}
85bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner  ~llvm_shutdown_obj() { llvm_shutdown(); }
86bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner};
87bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner
88771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner}
89771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
90771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner#endif
91