src/hotspot/share/gc/z/zMemory.cpp
changeset 58812 4adca7312d8f
parent 54834 39ba09047e19
equal deleted inserted replaced
58811:38f4701d6587 58812:4adca7312d8f
    23 
    23 
    24 #include "precompiled.hpp"
    24 #include "precompiled.hpp"
    25 #include "gc/z/zList.inline.hpp"
    25 #include "gc/z/zList.inline.hpp"
    26 #include "gc/z/zMemory.inline.hpp"
    26 #include "gc/z/zMemory.inline.hpp"
    27 #include "memory/allocation.inline.hpp"
    27 #include "memory/allocation.inline.hpp"
       
    28 
       
    29 ZMemory* ZMemoryManager::create(uintptr_t start, size_t size) {
       
    30   ZMemory* const area = new ZMemory(start, size);
       
    31   if (_callbacks._create != NULL) {
       
    32     _callbacks._create(area);
       
    33   }
       
    34   return area;
       
    35 }
       
    36 
       
    37 void ZMemoryManager::destroy(ZMemory* area) {
       
    38   if (_callbacks._destroy != NULL) {
       
    39     _callbacks._destroy(area);
       
    40   }
       
    41   delete area;
       
    42 }
       
    43 
       
    44 void ZMemoryManager::shrink_from_front(ZMemory* area, size_t size) {
       
    45   if (_callbacks._shrink_from_front != NULL) {
       
    46     _callbacks._shrink_from_front(area, size);
       
    47   }
       
    48   area->shrink_from_front(size);
       
    49 }
       
    50 
       
    51 void ZMemoryManager::shrink_from_back(ZMemory* area, size_t size) {
       
    52   if (_callbacks._shrink_from_back != NULL) {
       
    53     _callbacks._shrink_from_back(area, size);
       
    54   }
       
    55   area->shrink_from_back(size);
       
    56 }
       
    57 
       
    58 void ZMemoryManager::grow_from_front(ZMemory* area, size_t size) {
       
    59   if (_callbacks._grow_from_front != NULL) {
       
    60     _callbacks._grow_from_front(area, size);
       
    61   }
       
    62   area->grow_from_front(size);
       
    63 }
       
    64 
       
    65 void ZMemoryManager::grow_from_back(ZMemory* area, size_t size) {
       
    66   if (_callbacks._grow_from_back != NULL) {
       
    67     _callbacks._grow_from_back(area, size);
       
    68   }
       
    69   area->grow_from_back(size);
       
    70 }
       
    71 
       
    72 ZMemoryManager::Callbacks::Callbacks() :
       
    73     _create(NULL),
       
    74     _destroy(NULL),
       
    75     _shrink_from_front(NULL),
       
    76     _shrink_from_back(NULL),
       
    77     _grow_from_front(NULL),
       
    78     _grow_from_back(NULL) {}
       
    79 
       
    80 ZMemoryManager::ZMemoryManager() :
       
    81     _freelist(),
       
    82     _callbacks() {}
       
    83 
       
    84 void ZMemoryManager::register_callbacks(const Callbacks& callbacks) {
       
    85   _callbacks = callbacks;
       
    86 }
    28 
    87 
    29 uintptr_t ZMemoryManager::alloc_from_front(size_t size) {
    88 uintptr_t ZMemoryManager::alloc_from_front(size_t size) {
    30   ZListIterator<ZMemory> iter(&_freelist);
    89   ZListIterator<ZMemory> iter(&_freelist);
    31   for (ZMemory* area; iter.next(&area);) {
    90   for (ZMemory* area; iter.next(&area);) {
    32     if (area->size() >= size) {
    91     if (area->size() >= size) {
    33       if (area->size() == size) {
    92       if (area->size() == size) {
    34         // Exact match, remove area
    93         // Exact match, remove area
    35         const uintptr_t start = area->start();
    94         const uintptr_t start = area->start();
    36         _freelist.remove(area);
    95         _freelist.remove(area);
    37         delete area;
    96         destroy(area);
    38         return start;
    97         return start;
    39       } else {
    98       } else {
    40         // Larger than requested, shrink area
    99         // Larger than requested, shrink area
    41         const uintptr_t start = area->start();
   100         const uintptr_t start = area->start();
    42         area->shrink_from_front(size);
   101         shrink_from_front(area, size);
    43         return start;
   102         return start;
    44       }
   103       }
    45     }
   104     }
    46   }
   105   }
    47 
   106 
    55     if (area->size() <= size) {
   114     if (area->size() <= size) {
    56       // Smaller than or equal to requested, remove area
   115       // Smaller than or equal to requested, remove area
    57       const uintptr_t start = area->start();
   116       const uintptr_t start = area->start();
    58       *allocated = area->size();
   117       *allocated = area->size();
    59       _freelist.remove(area);
   118       _freelist.remove(area);
    60       delete area;
   119       destroy(area);
    61       return start;
   120       return start;
    62     } else {
   121     } else {
    63       // Larger than requested, shrink area
   122       // Larger than requested, shrink area
    64       const uintptr_t start = area->start();
   123       const uintptr_t start = area->start();
    65       area->shrink_from_front(size);
   124       shrink_from_front(area, size);
    66       *allocated = size;
   125       *allocated = size;
    67       return start;
   126       return start;
    68     }
   127     }
    69   }
   128   }
    70 
   129 
    79     if (area->size() >= size) {
   138     if (area->size() >= size) {
    80       if (area->size() == size) {
   139       if (area->size() == size) {
    81         // Exact match, remove area
   140         // Exact match, remove area
    82         const uintptr_t start = area->start();
   141         const uintptr_t start = area->start();
    83         _freelist.remove(area);
   142         _freelist.remove(area);
    84         delete area;
   143         destroy(area);
    85         return start;
   144         return start;
    86       } else {
   145       } else {
    87         // Larger than requested, shrink area
   146         // Larger than requested, shrink area
    88         area->shrink_from_back(size);
   147         shrink_from_back(area, size);
    89         return area->end();
   148         return area->end();
    90       }
   149       }
    91     }
   150     }
    92   }
   151   }
    93 
   152 
   101     if (area->size() <= size) {
   160     if (area->size() <= size) {
   102       // Smaller than or equal to requested, remove area
   161       // Smaller than or equal to requested, remove area
   103       const uintptr_t start = area->start();
   162       const uintptr_t start = area->start();
   104       *allocated = area->size();
   163       *allocated = area->size();
   105       _freelist.remove(area);
   164       _freelist.remove(area);
   106       delete area;
   165       destroy(area);
   107       return start;
   166       return start;
   108     } else {
   167     } else {
   109       // Larger than requested, shrink area
   168       // Larger than requested, shrink area
   110       area->shrink_from_back(size);
   169       shrink_from_back(area, size);
   111       *allocated = size;
   170       *allocated = size;
   112       return area->end();
   171       return area->end();
   113     }
   172     }
   114   }
   173   }
   115 
   174 
   127     if (start < area->start()) {
   186     if (start < area->start()) {
   128       ZMemory* const prev = _freelist.prev(area);
   187       ZMemory* const prev = _freelist.prev(area);
   129       if (prev != NULL && start == prev->end()) {
   188       if (prev != NULL && start == prev->end()) {
   130         if (end == area->start()) {
   189         if (end == area->start()) {
   131           // Merge with prev and current area
   190           // Merge with prev and current area
   132           prev->grow_from_back(size + area->size());
   191           grow_from_back(prev, size + area->size());
   133           _freelist.remove(area);
   192           _freelist.remove(area);
   134           delete area;
   193           delete area;
   135         } else {
   194         } else {
   136           // Merge with prev area
   195           // Merge with prev area
   137           prev->grow_from_back(size);
   196           grow_from_back(prev, size);
   138         }
   197         }
   139       } else if (end == area->start()) {
   198       } else if (end == area->start()) {
   140         // Merge with current area
   199         // Merge with current area
   141         area->grow_from_front(size);
   200         grow_from_front(area, size);
   142       } else {
   201       } else {
   143         // Insert new area before current area
   202         // Insert new area before current area
   144         assert(end < area->start(), "Areas must not overlap");
   203         assert(end < area->start(), "Areas must not overlap");
   145         ZMemory* new_area = new ZMemory(start, size);
   204         ZMemory* const new_area = create(start, size);
   146         _freelist.insert_before(area, new_area);
   205         _freelist.insert_before(area, new_area);
   147       }
   206       }
   148 
   207 
   149       // Done
   208       // Done
   150       return;
   209       return;
   153 
   212 
   154   // Insert last
   213   // Insert last
   155   ZMemory* const last = _freelist.last();
   214   ZMemory* const last = _freelist.last();
   156   if (last != NULL && start == last->end()) {
   215   if (last != NULL && start == last->end()) {
   157     // Merge with last area
   216     // Merge with last area
   158     last->grow_from_back(size);
   217     grow_from_back(last, size);
   159   } else {
   218   } else {
   160     // Insert new area last
   219     // Insert new area last
   161     ZMemory* new_area = new ZMemory(start, size);
   220     ZMemory* const new_area = create(start, size);
   162     _freelist.insert_last(new_area);
   221     _freelist.insert_last(new_area);
   163   }
   222   }
   164 }
   223 }