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