< prev index next >

src/hotspot/share/gc/z/zPhysicalMemory.cpp

Print this page




   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 #include "precompiled.hpp"
  25 #include "gc/shared/gcLogPrecious.hpp"
  26 #include "gc/z/zAddress.inline.hpp"

  27 #include "gc/z/zGlobals.hpp"
  28 #include "gc/z/zLargePages.inline.hpp"
  29 #include "gc/z/zNUMA.inline.hpp"
  30 #include "gc/z/zPhysicalMemory.inline.hpp"
  31 #include "logging/log.hpp"
  32 #include "runtime/globals.hpp"
  33 #include "runtime/globals_extension.hpp"
  34 #include "runtime/init.hpp"
  35 #include "runtime/os.hpp"
  36 #include "services/memTracker.hpp"
  37 #include "utilities/align.hpp"
  38 #include "utilities/debug.hpp"
  39 #include "utilities/globalDefinitions.hpp"
  40 #include "utilities/powerOfTwo.hpp"
  41 
  42 ZPhysicalMemory::ZPhysicalMemory() :
  43     _nsegments_max(0),
  44     _nsegments(0),
  45     _segments(NULL) {}
  46 
  47 ZPhysicalMemory::ZPhysicalMemory(const ZPhysicalMemorySegment& segment) :
  48     _nsegments_max(0),
  49     _nsegments(0),
  50     _segments(NULL) {
  51   add_segment(segment);
  52 }
  53 
  54 ZPhysicalMemory::ZPhysicalMemory(const ZPhysicalMemory& pmem) :
  55     _nsegments_max(0),
  56     _nsegments(0),
  57     _segments(NULL) {
  58   add_segments(pmem);
  59 }
  60 
  61 const ZPhysicalMemory& ZPhysicalMemory::operator=(const ZPhysicalMemory& pmem) {
  62   remove_segments();



  63   add_segments(pmem);
  64   return *this;
  65 }
  66 
  67 ZPhysicalMemory::~ZPhysicalMemory() {
  68   remove_segments();
  69 }
  70 
  71 size_t ZPhysicalMemory::size() const {
  72   size_t size = 0;
  73 
  74   for (uint32_t i = 0; i < _nsegments; i++) {
  75     size += _segments[i].size();
  76   }
  77 
  78   return size;
  79 }
  80 
  81 void ZPhysicalMemory::insert_segment(uint32_t index, uintptr_t start, size_t size, bool committed) {
  82   assert(index <= _nsegments, "Invalid index");
  83 
  84   ZPhysicalMemorySegment* const from_segments = _segments;
  85 
  86   if (_nsegments + 1 > _nsegments_max) {
  87     // Resize array
  88     _nsegments_max = round_up_power_of_2(_nsegments_max + 1);
  89     _segments = new ZPhysicalMemorySegment[_nsegments_max];
  90 
  91     // Copy segments before index
  92     for (uint32_t i = 0; i < index; i++) {
  93       _segments[i] = from_segments[i];
  94     }
  95   }
  96 
  97   // Copy/Move segments after index
  98   for (uint32_t i = _nsegments; i > index; i--) {
  99     _segments[i] = from_segments[i - 1];
 100   }
 101 
 102   // Insert new segment
 103   _segments[index] = ZPhysicalMemorySegment(start, size, committed);
 104   _nsegments++;
 105 
 106   // Delete old array
 107   if (from_segments != _segments) {
 108     delete [] from_segments;
 109   }
 110 }
 111 
 112 void ZPhysicalMemory::replace_segment(uint32_t index, uintptr_t start, size_t size, bool committed) {
 113   assert(index < _nsegments, "Invalid index");
 114   _segments[index] = ZPhysicalMemorySegment(start, size, committed);;
 115 }
 116 
 117 void ZPhysicalMemory::remove_segment(uint32_t index) {
 118   assert(index < _nsegments, "Invalid index");
 119 
 120   // Move segments after index
 121   for (uint32_t i = index + 1; i < _nsegments; i++) {
 122     _segments[i - 1] = _segments[i];
 123   }
 124 
 125   _nsegments--;
 126 }
 127 
 128 void ZPhysicalMemory::add_segments(const ZPhysicalMemory& pmem) {
 129   for (uint32_t i = 0; i < pmem.nsegments(); i++) {
 130     add_segment(pmem.segment(i));
 131   }
 132 }
 133 
 134 void ZPhysicalMemory::remove_segments() {
 135   delete [] _segments;
 136   _segments = NULL;
 137   _nsegments_max = 0;
 138   _nsegments = 0;
 139 }
 140 
 141 static bool is_mergable(const ZPhysicalMemorySegment& before, const ZPhysicalMemorySegment& after) {
 142   return before.end() == after.start() && before.is_committed() == after.is_committed();
 143 }
 144 
 145 void ZPhysicalMemory::add_segment(const ZPhysicalMemorySegment& segment) {
 146   // Insert segments in address order, merge segments when possible
 147   for (uint32_t i = _nsegments; i > 0; i--) {
 148     const uint32_t current = i - 1;
 149 
 150     if (_segments[current].end() <= segment.start()) {
 151       if (is_mergable(_segments[current], segment)) {
 152         if (current + 1 < _nsegments && is_mergable(segment, _segments[current + 1])) {
 153           // Merge with end of current segment and start of next segment
 154           const size_t start = _segments[current].start();
 155           const size_t size = _segments[current].size() + segment.size() + _segments[current + 1].size();
 156           replace_segment(current, start, size, segment.is_committed());
 157           remove_segment(current + 1);
 158           return;
 159         }
 160 
 161         // Merge with end of current segment
 162         const size_t start = _segments[current].start();
 163         const size_t size = _segments[current].size() + segment.size();
 164         replace_segment(current, start, size, segment.is_committed());
 165         return;
 166       } else if (current + 1 < _nsegments && is_mergable(segment, _segments[current + 1])) {
 167         // Merge with start of next segment
 168         const size_t start = segment.start();
 169         const size_t size = segment.size() + _segments[current + 1].size();
 170         replace_segment(current + 1, start, size, segment.is_committed());
 171         return;
 172       }
 173 
 174       // Insert after current segment
 175       insert_segment(current + 1, segment.start(), segment.size(), segment.is_committed());
 176       return;
 177     }
 178   }
 179 
 180   if (_nsegments > 0 && is_mergable(segment, _segments[0])) {
 181     // Merge with start of first segment
 182     const size_t start = segment.start();
 183     const size_t size = segment.size() + _segments[0].size();
 184     replace_segment(0, start, size, segment.is_committed());
 185     return;
 186   }
 187 
 188   // Insert before first segment
 189   insert_segment(0, segment.start(), segment.size(), segment.is_committed());
 190 }
 191 
 192 bool ZPhysicalMemory::commit_segment(uint32_t index, size_t size) {
 193   assert(index < _nsegments, "Invalid index");
 194   assert(size <= _segments[index].size(), "Invalid size");
 195   assert(!_segments[index].is_committed(), "Invalid state");
 196 
 197   if (size == _segments[index].size()) {



 198     // Completely committed
 199     _segments[index].set_committed(true);
 200     return true;
 201   }
 202 
 203   if (size > 0) {
 204     // Partially committed, split segment
 205     insert_segment(index + 1, _segments[index].start() + size, _segments[index].size() - size, false /* committed */);
 206     replace_segment(index, _segments[index].start(), size, true /* committed */);
 207   }
 208 
 209   return false;
 210 }
 211 
 212 bool ZPhysicalMemory::uncommit_segment(uint32_t index, size_t size) {
 213   assert(index < _nsegments, "Invalid index");
 214   assert(size <= _segments[index].size(), "Invalid size");
 215   assert(_segments[index].is_committed(), "Invalid state");

 216 
 217   if (size == _segments[index].size()) {
 218     // Completely uncommitted
 219     _segments[index].set_committed(false);
 220     return true;
 221   }
 222 
 223   if (size > 0) {
 224     // Partially uncommitted, split segment
 225     insert_segment(index + 1, _segments[index].start() + size, _segments[index].size() - size, true /* committed */);
 226     replace_segment(index, _segments[index].start(), size, false /* committed */);
 227   }
 228 
 229   return false;
 230 }
 231 
 232 ZPhysicalMemory ZPhysicalMemory::split(size_t size) {
 233   ZPhysicalMemory pmem;
 234   uint32_t nsegments = 0;
 235 
 236   for (uint32_t i = 0; i < _nsegments; i++) {
 237     const ZPhysicalMemorySegment& segment = _segments[i];
 238     if (pmem.size() < size) {
 239       if (pmem.size() + segment.size() <= size) {
 240         // Transfer segment
 241         pmem.add_segment(segment);
 242       } else {
 243         // Split segment
 244         const size_t split_size = size - pmem.size();
 245         pmem.add_segment(ZPhysicalMemorySegment(segment.start(), split_size, segment.is_committed()));
 246         _segments[nsegments++] = ZPhysicalMemorySegment(segment.start() + split_size, segment.size() - split_size, segment.is_committed());
 247       }
 248     } else {
 249       // Keep segment
 250       _segments[nsegments++] = segment;
 251     }
 252   }
 253 
 254   _nsegments = nsegments;
 255 
 256   return pmem;
 257 }
 258 
 259 ZPhysicalMemory ZPhysicalMemory::split_committed() {
 260   ZPhysicalMemory pmem;
 261   uint32_t nsegments = 0;
 262 
 263   for (uint32_t i = 0; i < _nsegments; i++) {
 264     const ZPhysicalMemorySegment& segment = _segments[i];
 265     if (segment.is_committed()) {
 266       // Transfer segment
 267       pmem.add_segment(segment);
 268     } else {
 269       // Keep segment
 270       _segments[nsegments++] = segment;
 271     }
 272   }
 273 
 274   _nsegments = nsegments;
 275 
 276   return pmem;
 277 }
 278 
 279 ZPhysicalMemoryManager::ZPhysicalMemoryManager(size_t max_capacity) :
 280     _backing(max_capacity) {
 281   // Make the whole range free
 282   _manager.free(0, max_capacity);
 283 }
 284 
 285 bool ZPhysicalMemoryManager::is_initialized() const {
 286   return _backing.is_initialized();
 287 }
 288 
 289 void ZPhysicalMemoryManager::warn_commit_limits(size_t max_capacity) const {
 290   _backing.warn_commit_limits(max_capacity);
 291 }
 292 
 293 void ZPhysicalMemoryManager::try_enable_uncommit(size_t min_capacity, size_t max_capacity) {
 294   assert(!is_init_completed(), "Invalid state");


 332     Tracker tracker(Tracker::uncommit);
 333     tracker.record((address)addr, size);
 334   }
 335 }
 336 
 337 void ZPhysicalMemoryManager::alloc(ZPhysicalMemory& pmem, size_t size) {
 338   assert(is_aligned(size, ZGranuleSize), "Invalid size");
 339 
 340   // Allocate segments
 341   while (size > 0) {
 342     size_t allocated = 0;
 343     const uintptr_t start = _manager.alloc_from_front_at_most(size, &allocated);
 344     assert(start != UINTPTR_MAX, "Allocation should never fail");
 345     pmem.add_segment(ZPhysicalMemorySegment(start, allocated, false /* committed */));
 346     size -= allocated;
 347   }
 348 }
 349 
 350 void ZPhysicalMemoryManager::free(const ZPhysicalMemory& pmem) {
 351   // Free segments
 352   for (uint32_t i = 0; i < pmem.nsegments(); i++) {
 353     const ZPhysicalMemorySegment& segment = pmem.segment(i);
 354     _manager.free(segment.start(), segment.size());
 355   }
 356 }
 357 
 358 bool ZPhysicalMemoryManager::commit(ZPhysicalMemory& pmem) {
 359   // Commit segments
 360   for (uint32_t i = 0; i < pmem.nsegments(); i++) {
 361     const ZPhysicalMemorySegment& segment = pmem.segment(i);
 362     if (segment.is_committed()) {
 363       // Segment already committed
 364       continue;
 365     }
 366 
 367     // Commit segment
 368     const size_t committed = _backing.commit(segment.start(), segment.size());
 369     if (!pmem.commit_segment(i, committed)) {
 370       // Failed or partially failed
 371       return false;
 372     }
 373   }
 374 
 375   // Success
 376   return true;
 377 }
 378 
 379 bool ZPhysicalMemoryManager::uncommit(ZPhysicalMemory& pmem) {
 380   // Commit segments
 381   for (uint32_t i = 0; i < pmem.nsegments(); i++) {
 382     const ZPhysicalMemorySegment& segment = pmem.segment(i);
 383     if (!segment.is_committed()) {
 384       // Segment already uncommitted
 385       continue;
 386     }
 387 
 388     // Uncommit segment
 389     const size_t uncommitted = _backing.uncommit(segment.start(), segment.size());
 390     if (!pmem.uncommit_segment(i, uncommitted)) {
 391       // Failed or partially failed
 392       return false;
 393     }
 394   }
 395 
 396   // Success
 397   return true;
 398 }
 399 
 400 void ZPhysicalMemoryManager::pretouch_view(uintptr_t addr, size_t size) const {
 401   const size_t page_size = ZLargePages::is_explicit() ? ZGranuleSize : os::vm_page_size();
 402   os::pretouch_memory((void*)addr, (void*)(addr + size), page_size);
 403 }
 404 
 405 void ZPhysicalMemoryManager::map_view(uintptr_t addr, const ZPhysicalMemory& pmem) const {
 406   size_t size = 0;
 407 
 408   // Map segments
 409   for (uint32_t i = 0; i < pmem.nsegments(); i++) {
 410     const ZPhysicalMemorySegment& segment = pmem.segment(i);
 411     _backing.map(addr + size, segment.size(), segment.start());
 412     size += segment.size();
 413   }
 414 
 415   // Setup NUMA interleaving for large pages
 416   if (ZNUMA::is_enabled() && ZLargePages::is_explicit()) {
 417     // To get granule-level NUMA interleaving when using large pages,
 418     // we simply let the kernel interleave the memory for us at page
 419     // fault time.
 420     os::numa_make_global((char*)addr, size);
 421   }
 422 }
 423 
 424 void ZPhysicalMemoryManager::unmap_view(uintptr_t addr, size_t size) const {
 425   _backing.unmap(addr, size);
 426 }
 427 
 428 void ZPhysicalMemoryManager::pretouch(uintptr_t offset, size_t size) const {
 429   if (ZVerifyViews) {




   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 #include "precompiled.hpp"
  25 #include "gc/shared/gcLogPrecious.hpp"
  26 #include "gc/z/zAddress.inline.hpp"
  27 #include "gc/z/zArray.inline.hpp"
  28 #include "gc/z/zGlobals.hpp"
  29 #include "gc/z/zLargePages.inline.hpp"
  30 #include "gc/z/zNUMA.inline.hpp"
  31 #include "gc/z/zPhysicalMemory.inline.hpp"
  32 #include "logging/log.hpp"
  33 #include "runtime/globals.hpp"
  34 #include "runtime/globals_extension.hpp"
  35 #include "runtime/init.hpp"
  36 #include "runtime/os.hpp"
  37 #include "services/memTracker.hpp"
  38 #include "utilities/align.hpp"
  39 #include "utilities/debug.hpp"
  40 #include "utilities/globalDefinitions.hpp"
  41 #include "utilities/powerOfTwo.hpp"
  42 
  43 ZPhysicalMemory::ZPhysicalMemory() :
  44     _segments() {}


  45 
  46 ZPhysicalMemory::ZPhysicalMemory(const ZPhysicalMemorySegment& segment) :
  47     _segments() {


  48   add_segment(segment);
  49 }
  50 
  51 ZPhysicalMemory::ZPhysicalMemory(const ZPhysicalMemory& pmem) :
  52     _segments() {


  53   add_segments(pmem);
  54 }
  55 
  56 const ZPhysicalMemory& ZPhysicalMemory::operator=(const ZPhysicalMemory& pmem) {
  57   // Free segments
  58   _segments.clear_and_deallocate();
  59 
  60   // Copy segments
  61   add_segments(pmem);


  62 
  63   return *this;

  64 }
  65 
  66 size_t ZPhysicalMemory::size() const {
  67   size_t size = 0;
  68 
  69   for (int i = 0; i < _segments.length(); i++) {
  70     size += _segments.at(i).size();
  71   }
  72 
  73   return size;
  74 }
  75 
  76 void ZPhysicalMemory::insert_segment(int index, uintptr_t start, size_t size, bool committed) {
  77   _segments.insert_before(index, ZPhysicalMemorySegment(start, size, committed));



























  78 }
  79 
  80 void ZPhysicalMemory::replace_segment(int index, uintptr_t start, size_t size, bool committed) {
  81   _segments.at_put(index, ZPhysicalMemorySegment(start, size, committed));

  82 }
  83 
  84 void ZPhysicalMemory::remove_segment(int index) {
  85   _segments.remove_at(index);







  86 }
  87 
  88 void ZPhysicalMemory::add_segments(const ZPhysicalMemory& pmem) {
  89   for (int i = 0; i < pmem.nsegments(); i++) {
  90     add_segment(pmem.segment(i));
  91   }
  92 }
  93 
  94 void ZPhysicalMemory::remove_segments() {
  95   _segments.clear_and_deallocate();



  96 }
  97 
  98 static bool is_mergable(const ZPhysicalMemorySegment& before, const ZPhysicalMemorySegment& after) {
  99   return before.end() == after.start() && before.is_committed() == after.is_committed();
 100 }
 101 
 102 void ZPhysicalMemory::add_segment(const ZPhysicalMemorySegment& segment) {
 103   // Insert segments in address order, merge segments when possible
 104   for (int i = _segments.length(); i > 0; i--) {
 105     const int current = i - 1;
 106 
 107     if (_segments.at(current).end() <= segment.start()) {
 108       if (is_mergable(_segments.at(current), segment)) {
 109         if (current + 1 < _segments.length() && is_mergable(segment, _segments.at(current + 1))) {
 110           // Merge with end of current segment and start of next segment
 111           const size_t start = _segments.at(current).start();
 112           const size_t size = _segments.at(current).size() + segment.size() + _segments.at(current + 1).size();
 113           replace_segment(current, start, size, segment.is_committed());
 114           remove_segment(current + 1);
 115           return;
 116         }
 117 
 118         // Merge with end of current segment
 119         const size_t start = _segments.at(current).start();
 120         const size_t size = _segments.at(current).size() + segment.size();
 121         replace_segment(current, start, size, segment.is_committed());
 122         return;
 123       } else if (current + 1 < _segments.length() && is_mergable(segment, _segments.at(current + 1))) {
 124         // Merge with start of next segment
 125         const size_t start = segment.start();
 126         const size_t size = segment.size() + _segments.at(current + 1).size();
 127         replace_segment(current + 1, start, size, segment.is_committed());
 128         return;
 129       }
 130 
 131       // Insert after current segment
 132       insert_segment(current + 1, segment.start(), segment.size(), segment.is_committed());
 133       return;
 134     }
 135   }
 136 
 137   if (_segments.length() > 0 && is_mergable(segment, _segments.at(0))) {
 138     // Merge with start of first segment
 139     const size_t start = segment.start();
 140     const size_t size = segment.size() + _segments.at(0).size();
 141     replace_segment(0, start, size, segment.is_committed());
 142     return;
 143   }
 144 
 145   // Insert before first segment
 146   insert_segment(0, segment.start(), segment.size(), segment.is_committed());
 147 }
 148 
 149 bool ZPhysicalMemory::commit_segment(int index, size_t size) {
 150   ZPhysicalMemorySegment& segment = _segments.at(index);


 151 
 152   assert(size <= segment.size(), "Invalid size");
 153   assert(!segment.is_committed(), "Invalid state");
 154 
 155   if (size == segment.size()) {
 156     // Completely committed
 157     segment.set_committed(true);
 158     return true;
 159   }
 160 
 161   if (size > 0) {
 162     // Partially committed, split segment
 163     insert_segment(index + 1, segment.start() + size, segment.size() - size, false /* committed */);
 164     replace_segment(index, segment.start(), size, true /* committed */);
 165   }
 166 
 167   return false;
 168 }
 169 
 170 bool ZPhysicalMemory::uncommit_segment(int index, size_t size) {
 171   ZPhysicalMemorySegment& segment = _segments.at(index);
 172 
 173   assert(size <= segment.size(), "Invalid size");
 174   assert(segment.is_committed(), "Invalid state");
 175 
 176   if (size == segment.size()) {
 177     // Completely uncommitted
 178     segment.set_committed(false);
 179     return true;
 180   }
 181 
 182   if (size > 0) {
 183     // Partially uncommitted, split segment
 184     insert_segment(index + 1, segment.start() + size, segment.size() - size, true /* committed */);
 185     replace_segment(index, segment.start(), size, false /* committed */);
 186   }
 187 
 188   return false;
 189 }
 190 
 191 ZPhysicalMemory ZPhysicalMemory::split(size_t size) {
 192   ZPhysicalMemory pmem;
 193   int nsegments = 0;
 194 
 195   for (int i = 0; i < _segments.length(); i++) {
 196     const ZPhysicalMemorySegment& segment = _segments.at(i);
 197     if (pmem.size() < size) {
 198       if (pmem.size() + segment.size() <= size) {
 199         // Transfer segment
 200         pmem.add_segment(segment);
 201       } else {
 202         // Split segment
 203         const size_t split_size = size - pmem.size();
 204         pmem.add_segment(ZPhysicalMemorySegment(segment.start(), split_size, segment.is_committed()));
 205         _segments.at_put(nsegments++, ZPhysicalMemorySegment(segment.start() + split_size, segment.size() - split_size, segment.is_committed()));
 206       }
 207     } else {
 208       // Keep segment
 209       _segments.at_put(nsegments++, segment);
 210     }
 211   }
 212 
 213   _segments.trunc_to(nsegments);
 214 
 215   return pmem;
 216 }
 217 
 218 ZPhysicalMemory ZPhysicalMemory::split_committed() {
 219   ZPhysicalMemory pmem;
 220   int nsegments = 0;
 221 
 222   for (int i = 0; i < _segments.length(); i++) {
 223     const ZPhysicalMemorySegment& segment = _segments.at(i);
 224     if (segment.is_committed()) {
 225       // Transfer segment
 226       pmem.add_segment(segment);
 227     } else {
 228       // Keep segment
 229       _segments.at_put(nsegments++, segment);
 230     }
 231   }
 232 
 233   _segments.trunc_to(nsegments);
 234 
 235   return pmem;
 236 }
 237 
 238 ZPhysicalMemoryManager::ZPhysicalMemoryManager(size_t max_capacity) :
 239     _backing(max_capacity) {
 240   // Make the whole range free
 241   _manager.free(0, max_capacity);
 242 }
 243 
 244 bool ZPhysicalMemoryManager::is_initialized() const {
 245   return _backing.is_initialized();
 246 }
 247 
 248 void ZPhysicalMemoryManager::warn_commit_limits(size_t max_capacity) const {
 249   _backing.warn_commit_limits(max_capacity);
 250 }
 251 
 252 void ZPhysicalMemoryManager::try_enable_uncommit(size_t min_capacity, size_t max_capacity) {
 253   assert(!is_init_completed(), "Invalid state");


 291     Tracker tracker(Tracker::uncommit);
 292     tracker.record((address)addr, size);
 293   }
 294 }
 295 
 296 void ZPhysicalMemoryManager::alloc(ZPhysicalMemory& pmem, size_t size) {
 297   assert(is_aligned(size, ZGranuleSize), "Invalid size");
 298 
 299   // Allocate segments
 300   while (size > 0) {
 301     size_t allocated = 0;
 302     const uintptr_t start = _manager.alloc_from_front_at_most(size, &allocated);
 303     assert(start != UINTPTR_MAX, "Allocation should never fail");
 304     pmem.add_segment(ZPhysicalMemorySegment(start, allocated, false /* committed */));
 305     size -= allocated;
 306   }
 307 }
 308 
 309 void ZPhysicalMemoryManager::free(const ZPhysicalMemory& pmem) {
 310   // Free segments
 311   for (int i = 0; i < pmem.nsegments(); i++) {
 312     const ZPhysicalMemorySegment& segment = pmem.segment(i);
 313     _manager.free(segment.start(), segment.size());
 314   }
 315 }
 316 
 317 bool ZPhysicalMemoryManager::commit(ZPhysicalMemory& pmem) {
 318   // Commit segments
 319   for (int i = 0; i < pmem.nsegments(); i++) {
 320     const ZPhysicalMemorySegment& segment = pmem.segment(i);
 321     if (segment.is_committed()) {
 322       // Segment already committed
 323       continue;
 324     }
 325 
 326     // Commit segment
 327     const size_t committed = _backing.commit(segment.start(), segment.size());
 328     if (!pmem.commit_segment(i, committed)) {
 329       // Failed or partially failed
 330       return false;
 331     }
 332   }
 333 
 334   // Success
 335   return true;
 336 }
 337 
 338 bool ZPhysicalMemoryManager::uncommit(ZPhysicalMemory& pmem) {
 339   // Commit segments
 340   for (int i = 0; i < pmem.nsegments(); i++) {
 341     const ZPhysicalMemorySegment& segment = pmem.segment(i);
 342     if (!segment.is_committed()) {
 343       // Segment already uncommitted
 344       continue;
 345     }
 346 
 347     // Uncommit segment
 348     const size_t uncommitted = _backing.uncommit(segment.start(), segment.size());
 349     if (!pmem.uncommit_segment(i, uncommitted)) {
 350       // Failed or partially failed
 351       return false;
 352     }
 353   }
 354 
 355   // Success
 356   return true;
 357 }
 358 
 359 void ZPhysicalMemoryManager::pretouch_view(uintptr_t addr, size_t size) const {
 360   const size_t page_size = ZLargePages::is_explicit() ? ZGranuleSize : os::vm_page_size();
 361   os::pretouch_memory((void*)addr, (void*)(addr + size), page_size);
 362 }
 363 
 364 void ZPhysicalMemoryManager::map_view(uintptr_t addr, const ZPhysicalMemory& pmem) const {
 365   size_t size = 0;
 366 
 367   // Map segments
 368   for (int i = 0; i < pmem.nsegments(); i++) {
 369     const ZPhysicalMemorySegment& segment = pmem.segment(i);
 370     _backing.map(addr + size, segment.size(), segment.start());
 371     size += segment.size();
 372   }
 373 
 374   // Setup NUMA interleaving for large pages
 375   if (ZNUMA::is_enabled() && ZLargePages::is_explicit()) {
 376     // To get granule-level NUMA interleaving when using large pages,
 377     // we simply let the kernel interleave the memory for us at page
 378     // fault time.
 379     os::numa_make_global((char*)addr, size);
 380   }
 381 }
 382 
 383 void ZPhysicalMemoryManager::unmap_view(uintptr_t addr, size_t size) const {
 384   _backing.unmap(addr, size);
 385 }
 386 
 387 void ZPhysicalMemoryManager::pretouch(uintptr_t offset, size_t size) const {
 388   if (ZVerifyViews) {


< prev index next >