ManagedStatic.h revision fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7
1771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
2771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//
3771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//                     The LLVM Compiler Infrastructure
4771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// 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;
34fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman
35771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  void RegisterManagedStatic(void *ObjPtr, void (*deleter)(void*)) const;
36771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerpublic:
37fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman  /// isConstructed - Return true if this object has not been created yet.
3868ce9ba666a7eb8c7eb3fb7888e4418fffd2e716Chris Lattner  bool isConstructed() const { return Ptr != 0; }
39fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman
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:
51fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman
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  }
69fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman
70771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnerpublic:
71771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  void LazyInit() const {
72771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner    RegisterManagedStatic(new C(), object_deleter<C>);
73771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner  }
74771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner};
75771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
76b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattnertemplate<void (*CleanupFn)(void*)>
77b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattnerclass ManagedCleanup : public ManagedStaticBase {
78b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattnerpublic:
79b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattner  void Register() { RegisterManagedStatic(0, CleanupFn); }
80b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattner};
81b4d7e35dde3ccbe0dc10bf13332ade9812586dd0Chris Lattner
82771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
83771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
84771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattnervoid llvm_shutdown();
85771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
86fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman
87bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner/// llvm_shutdown_obj - This is a simple helper class that calls
88bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner/// llvm_shutdown() when it is destroyed.
89bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattnerstruct llvm_shutdown_obj {
90bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner  llvm_shutdown_obj() {}
91bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner  ~llvm_shutdown_obj() { llvm_shutdown(); }
92bdbf5fd1c9cfa30a348596b127394fa1f4caf033Chris Lattner};
93fe2cce63aa26d0916fa7be32c6bf7fa8fb059ee7Misha Brukman
94771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner}
95771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner
96771cbf30bc1ff025316d1a80aeb5102375c1598eChris Lattner#endif
97