OLD | NEW |
(Empty) | |
| 1 //===- subzero/src/IceMemory.h - Memory management declarations -*- C++ -*-===// |
| 2 // |
| 3 // The Subzero Code Generator |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 /// |
| 10 /// \file |
| 11 /// \brief Declares some useful data structures and routines dealing with |
| 12 /// memory management in Subzero (mostly, allocator types.) |
| 13 /// |
| 14 //===----------------------------------------------------------------------===// |
| 15 |
| 16 #ifndef SUBZERO_SRC_ICEMEMORY_H |
| 17 #define SUBZERO_SRC_ICEMEMORY_H |
| 18 |
| 19 #include "IceTLS.h" |
| 20 |
| 21 #include "llvm/Support/Allocator.h" |
| 22 |
| 23 #include <cstddef> |
| 24 #include <mutex> |
| 25 |
| 26 namespace Ice { |
| 27 |
| 28 class Cfg; |
| 29 class GlobalContext; |
| 30 |
| 31 using ArenaAllocator = |
| 32 llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, /*SlabSize=*/1024 * 1024>; |
| 33 |
| 34 class LockedArenaAllocator { |
| 35 LockedArenaAllocator() = delete; |
| 36 LockedArenaAllocator(const LockedArenaAllocator &) = delete; |
| 37 LockedArenaAllocator &operator=(const LockedArenaAllocator &) = delete; |
| 38 |
| 39 public: |
| 40 LockedArenaAllocator(ArenaAllocator *Alloc, std::mutex *Mutex) |
| 41 : Alloc(Alloc), AutoLock(*Mutex) {} |
| 42 LockedArenaAllocator(LockedArenaAllocator &&) = default; |
| 43 LockedArenaAllocator &operator=(LockedArenaAllocator &&) = default; |
| 44 ~LockedArenaAllocator() = default; |
| 45 |
| 46 ArenaAllocator *operator->() { return Alloc; } |
| 47 |
| 48 private: |
| 49 ArenaAllocator *Alloc; |
| 50 std::unique_lock<std::mutex> AutoLock; |
| 51 }; |
| 52 |
| 53 template <typename T, typename Traits> struct sz_allocator { |
| 54 /// std::allocator interface implementation. |
| 55 /// @{ |
| 56 using value_type = T; |
| 57 using pointer = T *; |
| 58 using const_pointer = const T *; |
| 59 using reference = T &; |
| 60 using const_reference = const T &; |
| 61 using size_type = std::size_t; |
| 62 using difference_type = std::ptrdiff_t; |
| 63 |
| 64 sz_allocator() = default; |
| 65 template <class U> sz_allocator(const sz_allocator<U, Traits> &) {} |
| 66 |
| 67 pointer address(reference x) const { |
| 68 return reinterpret_cast<pointer>(&reinterpret_cast<char &>(x)); |
| 69 } |
| 70 const_pointer address(const_reference x) const { |
| 71 return reinterpret_cast<const_pointer>(&reinterpret_cast<const char &>(x)); |
| 72 } |
| 73 |
| 74 pointer allocate(size_type num) { |
| 75 return current()->template Allocate<T>(num); |
| 76 } |
| 77 |
| 78 template <typename... A> void construct(pointer P, A &&... Args) { |
| 79 new (static_cast<void *>(P)) T(std::forward<A>(Args)...); |
| 80 } |
| 81 |
| 82 void deallocate(pointer, size_type) {} |
| 83 |
| 84 template <class U> struct rebind { typedef sz_allocator<U, Traits> other; }; |
| 85 |
| 86 void destroy(pointer P) { P->~T(); } |
| 87 /// @} |
| 88 |
| 89 /// Manages the current underlying allocator. |
| 90 /// @{ |
| 91 static typename Traits::allocator_type current() { return Traits::current(); } |
| 92 static void init() { Traits::init(); } |
| 93 /// @} |
| 94 }; |
| 95 |
| 96 template <class Traits> struct sz_allocator_scope { |
| 97 explicit sz_allocator_scope(typename Traits::manager_type *Manager) { |
| 98 Traits::set_current(Manager); |
| 99 } |
| 100 |
| 101 ~sz_allocator_scope() { Traits::set_current(nullptr); } |
| 102 }; |
| 103 |
| 104 template <typename T, typename U, typename Traits> |
| 105 inline bool operator==(const sz_allocator<T, Traits> &, |
| 106 const sz_allocator<U, Traits> &) { |
| 107 return true; |
| 108 } |
| 109 |
| 110 template <typename T, typename U, typename Traits> |
| 111 inline bool operator!=(const sz_allocator<T, Traits> &, |
| 112 const sz_allocator<U, Traits> &) { |
| 113 return false; |
| 114 } |
| 115 |
| 116 class CfgAllocatorTraits { |
| 117 CfgAllocatorTraits() = delete; |
| 118 CfgAllocatorTraits(const CfgAllocatorTraits &) = delete; |
| 119 CfgAllocatorTraits &operator=(const CfgAllocatorTraits &) = delete; |
| 120 ~CfgAllocatorTraits() = delete; |
| 121 |
| 122 public: |
| 123 using allocator_type = ArenaAllocator *; |
| 124 using manager_type = Cfg; |
| 125 |
| 126 static void init() { ICE_TLS_INIT_FIELD(CfgAllocator); }; |
| 127 |
| 128 static allocator_type current(); |
| 129 static void set_current(const manager_type *Manager); |
| 130 |
| 131 private: |
| 132 ICE_TLS_DECLARE_FIELD(ArenaAllocator *, CfgAllocator); |
| 133 }; |
| 134 |
| 135 template <typename T> |
| 136 using CfgLocalAllocator = sz_allocator<T, CfgAllocatorTraits>; |
| 137 |
| 138 using CfgLocalAllocatorScope = sz_allocator_scope<CfgAllocatorTraits>; |
| 139 |
| 140 } // end of namespace Ice |
| 141 |
| 142 #endif // SUBZERO_SRC_ICEMEMORY_H |
OLD | NEW |