1//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the ManagedStatic class and the llvm_shutdown() function. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_SUPPORT_MANAGED_STATIC_H 15#define LLVM_SUPPORT_MANAGED_STATIC_H 16 17#include "llvm/Support/Atomic.h" 18#include "llvm/Support/Threading.h" 19#include "llvm/Support/Valgrind.h" 20 21namespace llvm { 22 23/// object_creator - Helper method for ManagedStatic. 24template<class C> 25void* object_creator() { 26 return new C(); 27} 28 29/// object_deleter - Helper method for ManagedStatic. 30/// 31template<typename T> struct object_deleter { 32 static void call(void * Ptr) { delete (T*)Ptr; } 33}; 34template<typename T, size_t N> struct object_deleter<T[N]> { 35 static void call(void * Ptr) { delete[] (T*)Ptr; } 36}; 37 38/// ManagedStaticBase - Common base class for ManagedStatic instances. 39class ManagedStaticBase { 40protected: 41 // This should only be used as a static variable, which guarantees that this 42 // will be zero initialized. 43 mutable void *Ptr; 44 mutable void (*DeleterFn)(void*); 45 mutable const ManagedStaticBase *Next; 46 47 void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const; 48public: 49 /// isConstructed - Return true if this object has not been created yet. 50 bool isConstructed() const { return Ptr != nullptr; } 51 52 void destroy() const; 53}; 54 55/// ManagedStatic - This transparently changes the behavior of global statics to 56/// be lazily constructed on demand (good for reducing startup times of dynamic 57/// libraries that link in LLVM components) and for making destruction be 58/// explicit through the llvm_shutdown() function call. 59/// 60template<class C> 61class ManagedStatic : public ManagedStaticBase { 62public: 63 64 // Accessors. 65 C &operator*() { 66 void* tmp = Ptr; 67 if (llvm_is_multithreaded()) sys::MemoryFence(); 68 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 69 TsanHappensAfter(this); 70 71 return *static_cast<C*>(Ptr); 72 } 73 C *operator->() { 74 void* tmp = Ptr; 75 if (llvm_is_multithreaded()) sys::MemoryFence(); 76 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 77 TsanHappensAfter(this); 78 79 return static_cast<C*>(Ptr); 80 } 81 const C &operator*() const { 82 void* tmp = Ptr; 83 if (llvm_is_multithreaded()) sys::MemoryFence(); 84 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 85 TsanHappensAfter(this); 86 87 return *static_cast<C*>(Ptr); 88 } 89 const C *operator->() const { 90 void* tmp = Ptr; 91 if (llvm_is_multithreaded()) sys::MemoryFence(); 92 if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call); 93 TsanHappensAfter(this); 94 95 return static_cast<C*>(Ptr); 96 } 97}; 98 99/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. 100void llvm_shutdown(); 101 102/// llvm_shutdown_obj - This is a simple helper class that calls 103/// llvm_shutdown() when it is destroyed. 104struct llvm_shutdown_obj { 105 llvm_shutdown_obj() { } 106 ~llvm_shutdown_obj() { llvm_shutdown(); } 107}; 108 109} 110 111#endif 112