LLVM API Documentation
00001 //===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the ManagedStatic class and the llvm_shutdown() function. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_SUPPORT_MANAGEDSTATIC_H 00015 #define LLVM_SUPPORT_MANAGEDSTATIC_H 00016 00017 #include "llvm/Support/Atomic.h" 00018 #include "llvm/Support/Threading.h" 00019 #include "llvm/Support/Valgrind.h" 00020 00021 namespace llvm { 00022 00023 /// object_creator - Helper method for ManagedStatic. 00024 template<class C> 00025 void* object_creator() { 00026 return new C(); 00027 } 00028 00029 /// object_deleter - Helper method for ManagedStatic. 00030 /// 00031 template<typename T> struct object_deleter { 00032 static void call(void * Ptr) { delete (T*)Ptr; } 00033 }; 00034 template<typename T, size_t N> struct object_deleter<T[N]> { 00035 static void call(void * Ptr) { delete[] (T*)Ptr; } 00036 }; 00037 00038 /// ManagedStaticBase - Common base class for ManagedStatic instances. 00039 class ManagedStaticBase { 00040 protected: 00041 // This should only be used as a static variable, which guarantees that this 00042 // will be zero initialized. 00043 mutable void *Ptr; 00044 mutable void (*DeleterFn)(void*); 00045 mutable const ManagedStaticBase *Next; 00046 00047 void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const; 00048 public: 00049 /// isConstructed - Return true if this object has not been created yet. 00050 bool isConstructed() const { return Ptr != nullptr; } 00051 00052 void destroy() const; 00053 }; 00054 00055 /// ManagedStatic - This transparently changes the behavior of global statics to 00056 /// be lazily constructed on demand (good for reducing startup times of dynamic 00057 /// libraries that link in LLVM components) and for making destruction be 00058 /// explicit through the llvm_shutdown() function call. 00059 /// 00060 template<class C> 00061 class ManagedStatic : public ManagedStaticBase { 00062 public: 00063 00064 // Accessors. 00065 C &operator*() { 00066 void* tmp = Ptr; 00067 if (llvm_is_multithreaded()) sys::MemoryFence(); 00068 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 00069 TsanHappensAfter(this); 00070 00071 return *static_cast<C*>(Ptr); 00072 } 00073 C *operator->() { 00074 void* tmp = Ptr; 00075 if (llvm_is_multithreaded()) sys::MemoryFence(); 00076 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 00077 TsanHappensAfter(this); 00078 00079 return static_cast<C*>(Ptr); 00080 } 00081 const C &operator*() const { 00082 void* tmp = Ptr; 00083 if (llvm_is_multithreaded()) sys::MemoryFence(); 00084 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 00085 TsanHappensAfter(this); 00086 00087 return *static_cast<C*>(Ptr); 00088 } 00089 const C *operator->() const { 00090 void* tmp = Ptr; 00091 if (llvm_is_multithreaded()) sys::MemoryFence(); 00092 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 00093 TsanHappensAfter(this); 00094 00095 return static_cast<C*>(Ptr); 00096 } 00097 }; 00098 00099 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. 00100 void llvm_shutdown(); 00101 00102 /// llvm_shutdown_obj - This is a simple helper class that calls 00103 /// llvm_shutdown() when it is destroyed. 00104 struct llvm_shutdown_obj { 00105 llvm_shutdown_obj() { } 00106 ~llvm_shutdown_obj() { llvm_shutdown(); } 00107 }; 00108 00109 } 00110 00111 #endif