25 #define SHARE_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_HPP |
25 #define SHARE_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_HPP |
26 |
26 |
27 #include "jfr/utilities/jfrAllocation.hpp" |
27 #include "jfr/utilities/jfrAllocation.hpp" |
28 #include "jfr/utilities/jfrDoublyLinkedList.hpp" |
28 #include "jfr/utilities/jfrDoublyLinkedList.hpp" |
29 #include "jfr/utilities/jfrIterator.hpp" |
29 #include "jfr/utilities/jfrIterator.hpp" |
30 #include "jfr/utilities/jfrTypes.hpp" |
|
31 #include "runtime/os.hpp" |
|
32 #include "utilities/globalDefinitions.hpp" |
|
33 #include "utilities/macros.hpp" |
|
34 |
30 |
35 template <typename T, template <typename> class RetrievalType, typename Callback> |
31 template <typename T, template <typename> class RetrievalType, typename Callback> |
36 class JfrMemorySpace : public JfrCHeapObj { |
32 class JfrMemorySpace : public JfrCHeapObj { |
37 public: |
33 public: |
38 typedef T Type; |
34 typedef T Type; |
105 |
101 |
106 debug_only(bool in_full_list(const Type* t) const { return _full.in_list(t); }) |
102 debug_only(bool in_full_list(const Type* t) const { return _full.in_list(t); }) |
107 debug_only(bool in_free_list(const Type* t) const { return _free.in_list(t); }) |
103 debug_only(bool in_free_list(const Type* t) const { return _free.in_list(t); }) |
108 }; |
104 }; |
109 |
105 |
110 // allocations are even multiples of the mspace min size |
|
111 inline u8 align_allocation_size(u8 requested_size, size_t min_elem_size) { |
|
112 assert((int)min_elem_size % os::vm_page_size() == 0, "invariant"); |
|
113 u8 alloc_size_bytes = min_elem_size; |
|
114 while (requested_size > alloc_size_bytes) { |
|
115 alloc_size_bytes <<= 1; |
|
116 } |
|
117 assert((int)alloc_size_bytes % os::vm_page_size() == 0, "invariant"); |
|
118 return alloc_size_bytes; |
|
119 } |
|
120 |
|
121 template <typename T, template <typename> class RetrievalType, typename Callback> |
|
122 T* JfrMemorySpace<T, RetrievalType, Callback>::allocate(size_t size) { |
|
123 const u8 aligned_size_bytes = align_allocation_size(size, _min_elem_size); |
|
124 void* const allocation = JfrCHeapObj::new_array<u1>(aligned_size_bytes + sizeof(T)); |
|
125 if (allocation == NULL) { |
|
126 return NULL; |
|
127 } |
|
128 T* const t = new (allocation) T; |
|
129 assert(t != NULL, "invariant"); |
|
130 if (!t->initialize(sizeof(T), aligned_size_bytes)) { |
|
131 JfrCHeapObj::free(t, aligned_size_bytes + sizeof(T)); |
|
132 return NULL; |
|
133 } |
|
134 return t; |
|
135 } |
|
136 |
|
137 template <typename T, template <typename> class RetrievalType, typename Callback> |
|
138 void JfrMemorySpace<T, RetrievalType, Callback>::deallocate(T* t) { |
|
139 assert(t != NULL, "invariant"); |
|
140 assert(!_free.in_list(t), "invariant"); |
|
141 assert(!_full.in_list(t), "invariant"); |
|
142 assert(t != NULL, "invariant"); |
|
143 JfrCHeapObj::free(t, t->total_size()); |
|
144 } |
|
145 |
|
146 template <typename Mspace> |
|
147 class MspaceLock { |
|
148 private: |
|
149 Mspace* _mspace; |
|
150 public: |
|
151 MspaceLock(Mspace* mspace) : _mspace(mspace) { _mspace->lock(); } |
|
152 ~MspaceLock() { _mspace->unlock(); } |
|
153 }; |
|
154 |
|
155 template <typename Mspace> |
|
156 class ReleaseOp : public StackObj { |
|
157 private: |
|
158 Mspace* _mspace; |
|
159 Thread* _thread; |
|
160 bool _release_full; |
|
161 public: |
|
162 typedef typename Mspace::Type Type; |
|
163 ReleaseOp(Mspace* mspace, Thread* thread, bool release_full = true) : _mspace(mspace), _thread(thread), _release_full(release_full) {} |
|
164 bool process(Type* t); |
|
165 size_t processed() const { return 0; } |
|
166 }; |
|
167 |
|
168 #endif // SHARE_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_HPP |
106 #endif // SHARE_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_HPP |