src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp
changeset 58132 caa25ab47aca
parent 54964 ec7d6d8effc7
child 58157 9dca61a7df19
child 58863 c16ac7a2eba4
equal deleted inserted replaced
58131:3054503bad7d 58132:caa25ab47aca
    24 
    24 
    25 #ifndef SHARE_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_INLINE_HPP
    25 #ifndef SHARE_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_INLINE_HPP
    26 #define SHARE_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_INLINE_HPP
    26 #define SHARE_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_INLINE_HPP
    27 
    27 
    28 #include "jfr/recorder/storage/jfrMemorySpace.hpp"
    28 #include "jfr/recorder/storage/jfrMemorySpace.hpp"
       
    29 #include "runtime/os.hpp"
    29 
    30 
    30 template <typename T, template <typename> class RetrievalType, typename Callback>
    31 template <typename T, template <typename> class RetrievalType, typename Callback>
    31 JfrMemorySpace<T, RetrievalType, Callback>::
    32 JfrMemorySpace<T, RetrievalType, Callback>::
    32 JfrMemorySpace(size_t min_elem_size, size_t limit_size, size_t cache_count, Callback* callback) :
    33 JfrMemorySpace(size_t min_elem_size, size_t limit_size, size_t cache_count, Callback* callback) :
    33   _free(),
    34   _free(),
    67   }
    68   }
    68   assert(_free.count() == _cache_count, "invariant");
    69   assert(_free.count() == _cache_count, "invariant");
    69   return true;
    70   return true;
    70 }
    71 }
    71 
    72 
       
    73 // allocations are even multiples of the mspace min size
       
    74 static inline size_t align_allocation_size(size_t requested_size, size_t min_elem_size) {
       
    75   assert((int)min_elem_size % os::vm_page_size() == 0, "invariant");
       
    76   u8 alloc_size_bytes = min_elem_size;
       
    77   while (requested_size > alloc_size_bytes) {
       
    78     alloc_size_bytes <<= 1;
       
    79   }
       
    80   assert((int)alloc_size_bytes % os::vm_page_size() == 0, "invariant");
       
    81   return (size_t)alloc_size_bytes;
       
    82 }
       
    83 
       
    84 template <typename T, template <typename> class RetrievalType, typename Callback>
       
    85 inline T* JfrMemorySpace<T, RetrievalType, Callback>::allocate(size_t size) {
       
    86   const size_t aligned_size_bytes = align_allocation_size(size, _min_elem_size);
       
    87   void* const allocation = JfrCHeapObj::new_array<u1>(aligned_size_bytes + sizeof(T));
       
    88   if (allocation == NULL) {
       
    89     return NULL;
       
    90   }
       
    91   T* const t = new (allocation) T;
       
    92   assert(t != NULL, "invariant");
       
    93   if (!t->initialize(sizeof(T), aligned_size_bytes)) {
       
    94     JfrCHeapObj::free(t, aligned_size_bytes + sizeof(T));
       
    95     return NULL;
       
    96   }
       
    97   return t;
       
    98 }
       
    99 
       
   100 template <typename T, template <typename> class RetrievalType, typename Callback>
       
   101 inline void JfrMemorySpace<T, RetrievalType, Callback>::deallocate(T* t) {
       
   102   assert(t != NULL, "invariant");
       
   103   assert(!_free.in_list(t), "invariant");
       
   104   assert(!_full.in_list(t), "invariant");
       
   105   assert(t != NULL, "invariant");
       
   106   JfrCHeapObj::free(t, t->total_size());
       
   107 }
       
   108 
    72 template <typename T, template <typename> class RetrievalType, typename Callback>
   109 template <typename T, template <typename> class RetrievalType, typename Callback>
    73 inline void JfrMemorySpace<T, RetrievalType, Callback>::release_full(T* t) {
   110 inline void JfrMemorySpace<T, RetrievalType, Callback>::release_full(T* t) {
    74   assert(is_locked(), "invariant");
   111   assert(is_locked(), "invariant");
    75   assert(t != NULL, "invariant");
   112   assert(t != NULL, "invariant");
    76   assert(_full.in_list(t), "invariant");
   113   assert(_full.in_list(t), "invariant");
   120   while (iterator.has_next()) {
   157   while (iterator.has_next()) {
   121     callback.process(iterator.next());
   158     callback.process(iterator.next());
   122   }
   159   }
   123 }
   160 }
   124 
   161 
       
   162 template <typename Mspace, typename Callback>
       
   163 static inline Mspace* create_mspace(size_t buffer_size, size_t limit, size_t cache_count, Callback* cb) {
       
   164   Mspace* const mspace = new Mspace(buffer_size, limit, cache_count, cb);
       
   165   if (mspace != NULL) {
       
   166     mspace->initialize();
       
   167   }
       
   168   return mspace;
       
   169 }
       
   170 
   125 template <typename Mspace>
   171 template <typename Mspace>
   126 inline size_t size_adjustment(size_t size, Mspace* mspace) {
   172 inline size_t size_adjustment(size_t size, Mspace* mspace) {
   127   assert(mspace != NULL, "invariant");
   173   assert(mspace != NULL, "invariant");
   128   static const size_t min_elem_size = mspace->min_elem_size();
   174   static const size_t min_elem_size = mspace->min_elem_size();
   129   if (size < min_elem_size) {
   175   if (size < min_elem_size) {
   170   typename Mspace::Type* const t = mspace_allocate_acquired(size, mspace, thread);
   216   typename Mspace::Type* const t = mspace_allocate_acquired(size, mspace, thread);
   171   if (t == NULL) return NULL;
   217   if (t == NULL) return NULL;
   172   mspace->insert_full_head(t);
   218   mspace->insert_full_head(t);
   173   return t;
   219   return t;
   174 }
   220 }
       
   221 
       
   222 template <typename Mspace>
       
   223 class MspaceLock {
       
   224  private:
       
   225   Mspace* _mspace;
       
   226  public:
       
   227   MspaceLock(Mspace* mspace) : _mspace(mspace) { _mspace->lock(); }
       
   228   ~MspaceLock() { _mspace->unlock(); }
       
   229 };
   175 
   230 
   176 template <typename Mspace>
   231 template <typename Mspace>
   177 inline typename Mspace::Type* mspace_allocate_transient_to_full(size_t size, Mspace* mspace, Thread* thread) {
   232 inline typename Mspace::Type* mspace_allocate_transient_to_full(size_t size, Mspace* mspace, Thread* thread) {
   178   typename Mspace::Type* const t = mspace_allocate_transient(size, mspace, thread);
   233   typename Mspace::Type* const t = mspace_allocate_transient(size, mspace, thread);
   179   if (t == NULL) return NULL;
   234   if (t == NULL) return NULL;
   340 inline void process_free_list(Processor& processor, Mspace* mspace, jfr_iter_direction direction = forward) {
   395 inline void process_free_list(Processor& processor, Mspace* mspace, jfr_iter_direction direction = forward) {
   341   assert(mspace != NULL, "invariant");
   396   assert(mspace != NULL, "invariant");
   342   assert(mspace->has_free(), "invariant");
   397   assert(mspace->has_free(), "invariant");
   343   process_free_list_iterator_control<Processor, Mspace, typename Mspace::Iterator>(processor, mspace, direction);
   398   process_free_list_iterator_control<Processor, Mspace, typename Mspace::Iterator>(processor, mspace, direction);
   344 }
   399 }
       
   400 
       
   401 template <typename Mspace>
       
   402 class ReleaseOp : public StackObj {
       
   403  private:
       
   404   Mspace* _mspace;
       
   405   Thread* _thread;
       
   406   bool _release_full;
       
   407  public:
       
   408   typedef typename Mspace::Type Type;
       
   409   ReleaseOp(Mspace* mspace, Thread* thread, bool release_full = true) :
       
   410     _mspace(mspace), _thread(thread), _release_full(release_full) {}
       
   411   bool process(Type* t);
       
   412   size_t processed() const { return 0; }
       
   413 };
   345 
   414 
   346 template <typename Mspace>
   415 template <typename Mspace>
   347 inline bool ReleaseOp<Mspace>::process(typename Mspace::Type* t) {
   416 inline bool ReleaseOp<Mspace>::process(typename Mspace::Type* t) {
   348   assert(t != NULL, "invariant");
   417   assert(t != NULL, "invariant");
   349   // assumes some means of exclusive access to t
   418   // assumes some means of exclusive access to t