src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp
branchJEP-349-branch
changeset 57870 00860d9caf4d
parent 57360 5d043a159d5c
child 58154 060d9d139109
equal deleted inserted replaced
57862:84ef29ccac56 57870:00860d9caf4d
    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");
   121   while (iterator.has_next()) {
   158   while (iterator.has_next()) {
   122     callback.process(iterator.next());
   159     callback.process(iterator.next());
   123   }
   160   }
   124 }
   161 }
   125 
   162 
       
   163 template <typename Mspace, typename Callback>
       
   164 static inline Mspace* create_mspace(size_t buffer_size, size_t limit, size_t cache_count, Callback* cb) {
       
   165   Mspace* const mspace = new Mspace(buffer_size, limit, cache_count, cb);
       
   166   if (mspace != NULL) {
       
   167     mspace->initialize();
       
   168   }
       
   169   return mspace;
       
   170 }
       
   171 
   126 template <typename Mspace>
   172 template <typename Mspace>
   127 inline size_t size_adjustment(size_t size, Mspace* mspace) {
   173 inline size_t size_adjustment(size_t size, Mspace* mspace) {
   128   assert(mspace != NULL, "invariant");
   174   assert(mspace != NULL, "invariant");
   129   static const size_t min_elem_size = mspace->min_elem_size();
   175   static const size_t min_elem_size = mspace->min_elem_size();
   130   if (size < min_elem_size) {
   176   if (size < min_elem_size) {
   171   typename Mspace::Type* const t = mspace_allocate_acquired(size, mspace, thread);
   217   typename Mspace::Type* const t = mspace_allocate_acquired(size, mspace, thread);
   172   if (t == NULL) return NULL;
   218   if (t == NULL) return NULL;
   173   mspace->insert_full_head(t);
   219   mspace->insert_full_head(t);
   174   return t;
   220   return t;
   175 }
   221 }
       
   222 
       
   223 template <typename Mspace>
       
   224 class MspaceLock {
       
   225  private:
       
   226   Mspace* _mspace;
       
   227  public:
       
   228   MspaceLock(Mspace* mspace) : _mspace(mspace) { _mspace->lock(); }
       
   229   ~MspaceLock() { _mspace->unlock(); }
       
   230 };
   176 
   231 
   177 template <typename Mspace>
   232 template <typename Mspace>
   178 inline typename Mspace::Type* mspace_allocate_transient_to_full(size_t size, Mspace* mspace, Thread* thread) {
   233 inline typename Mspace::Type* mspace_allocate_transient_to_full(size_t size, Mspace* mspace, Thread* thread) {
   179   typename Mspace::Type* const t = mspace_allocate_transient(size, mspace, thread);
   234   typename Mspace::Type* const t = mspace_allocate_transient(size, mspace, thread);
   180   if (t == NULL) return NULL;
   235   if (t == NULL) return NULL;
   341 inline void process_free_list(Processor& processor, Mspace* mspace, jfr_iter_direction direction = forward) {
   396 inline void process_free_list(Processor& processor, Mspace* mspace, jfr_iter_direction direction = forward) {
   342   assert(mspace != NULL, "invariant");
   397   assert(mspace != NULL, "invariant");
   343   assert(mspace->has_free(), "invariant");
   398   assert(mspace->has_free(), "invariant");
   344   process_free_list_iterator_control<Processor, Mspace, typename Mspace::Iterator>(processor, mspace, direction);
   399   process_free_list_iterator_control<Processor, Mspace, typename Mspace::Iterator>(processor, mspace, direction);
   345 }
   400 }
       
   401 
       
   402 template <typename Mspace>
       
   403 class ReleaseOp : public StackObj {
       
   404  private:
       
   405   Mspace* _mspace;
       
   406   Thread* _thread;
       
   407   bool _release_full;
       
   408  public:
       
   409   typedef typename Mspace::Type Type;
       
   410   ReleaseOp(Mspace* mspace, Thread* thread, bool release_full = true) :
       
   411     _mspace(mspace), _thread(thread), _release_full(release_full) {}
       
   412   bool process(Type* t);
       
   413   size_t processed() const { return 0; }
       
   414 };
   346 
   415 
   347 template <typename Mspace>
   416 template <typename Mspace>
   348 inline bool ReleaseOp<Mspace>::process(typename Mspace::Type* t) {
   417 inline bool ReleaseOp<Mspace>::process(typename Mspace::Type* t) {
   349   assert(t != NULL, "invariant");
   418   assert(t != NULL, "invariant");
   350   // assumes some means of exclusive access to t
   419   // assumes some means of exclusive access to t