5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 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/z/zAddressSpaceLimit.hpp" 26 #include "gc/z/zGlobals.hpp" 27 #include "gc/z/zVirtualMemory.inline.hpp" 28 #include "logging/log.hpp" 29 #include "services/memTracker.hpp" 30 #include "utilities/debug.hpp" 31 #include "utilities/align.hpp" 32 33 ZVirtualMemoryManager::ZVirtualMemoryManager(size_t max_capacity) : 34 _manager(), 35 _initialized(false) { 36 37 // Check max supported heap size 38 if (max_capacity > ZAddressOffsetMax) { 39 log_error(gc)("Java heap too large (max supported heap size is " SIZE_FORMAT "G)", 40 ZAddressOffsetMax / G); 41 return; 42 } 43 44 // Reserve address space 45 if (!reserve(max_capacity)) { 46 log_error(gc)("Failed to reserve enough address space for Java heap"); 47 return; 48 } 49 50 // Initialize OS specific parts 51 initialize_os(); 52 53 // Successfully initialized 54 _initialized = true; 55 } 56 57 size_t ZVirtualMemoryManager::reserve_discontiguous(uintptr_t start, size_t size, size_t min_range) { 58 if (size < min_range) { 59 // Too small 60 return 0; 61 } 62 63 assert(is_aligned(size, ZGranuleSize), "Misaligned"); 64 65 if (reserve_contiguous_platform(start, size)) { 66 // Make the address range free 115 } 116 117 // Failed 118 return false; 119 } 120 121 bool ZVirtualMemoryManager::reserve(size_t max_capacity) { 122 const size_t limit = MIN2(ZAddressOffsetMax, ZAddressSpaceLimit::heap_view()); 123 const size_t size = MIN2(max_capacity * ZVirtualToPhysicalRatio, limit); 124 125 size_t reserved = size; 126 bool contiguous = true; 127 128 // Prefer a contiguous address space 129 if (!reserve_contiguous(size)) { 130 // Fall back to a discontiguous address space 131 reserved = reserve_discontiguous(size); 132 contiguous = false; 133 } 134 135 log_info(gc, init)("Address Space Type: %s/%s/%s", 136 (contiguous ? "Contiguous" : "Discontiguous"), 137 (limit == ZAddressOffsetMax ? "Unrestricted" : "Restricted"), 138 (reserved == size ? "Complete" : "Degraded")); 139 log_info(gc, init)("Address Space Size: " SIZE_FORMAT "M x " SIZE_FORMAT " = " SIZE_FORMAT "M", 140 reserved / M, ZHeapViews, (reserved * ZHeapViews) / M); 141 142 return reserved >= max_capacity; 143 } 144 145 void ZVirtualMemoryManager::nmt_reserve(uintptr_t start, size_t size) { 146 MemTracker::record_virtual_memory_reserve((void*)start, size, CALLER_PC); 147 MemTracker::record_virtual_memory_type((void*)start, mtJavaHeap); 148 } 149 150 bool ZVirtualMemoryManager::is_initialized() const { 151 return _initialized; 152 } 153 154 ZVirtualMemory ZVirtualMemoryManager::alloc(size_t size, bool alloc_from_front) { 155 uintptr_t start; 156 157 if (alloc_from_front || size <= ZPageSizeSmall) { 158 // Small page 159 start = _manager.alloc_from_front(size); 160 } else { | 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 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/zAddressSpaceLimit.hpp" 27 #include "gc/z/zGlobals.hpp" 28 #include "gc/z/zVirtualMemory.inline.hpp" 29 #include "services/memTracker.hpp" 30 #include "utilities/debug.hpp" 31 #include "utilities/align.hpp" 32 33 ZVirtualMemoryManager::ZVirtualMemoryManager(size_t max_capacity) : 34 _manager(), 35 _initialized(false) { 36 37 // Check max supported heap size 38 if (max_capacity > ZAddressOffsetMax) { 39 log_error_p(gc)("Java heap too large (max supported heap size is " SIZE_FORMAT "G)", 40 ZAddressOffsetMax / G); 41 return; 42 } 43 44 // Reserve address space 45 if (!reserve(max_capacity)) { 46 log_error_p(gc)("Failed to reserve enough address space for Java heap"); 47 return; 48 } 49 50 // Initialize OS specific parts 51 initialize_os(); 52 53 // Successfully initialized 54 _initialized = true; 55 } 56 57 size_t ZVirtualMemoryManager::reserve_discontiguous(uintptr_t start, size_t size, size_t min_range) { 58 if (size < min_range) { 59 // Too small 60 return 0; 61 } 62 63 assert(is_aligned(size, ZGranuleSize), "Misaligned"); 64 65 if (reserve_contiguous_platform(start, size)) { 66 // Make the address range free 115 } 116 117 // Failed 118 return false; 119 } 120 121 bool ZVirtualMemoryManager::reserve(size_t max_capacity) { 122 const size_t limit = MIN2(ZAddressOffsetMax, ZAddressSpaceLimit::heap_view()); 123 const size_t size = MIN2(max_capacity * ZVirtualToPhysicalRatio, limit); 124 125 size_t reserved = size; 126 bool contiguous = true; 127 128 // Prefer a contiguous address space 129 if (!reserve_contiguous(size)) { 130 // Fall back to a discontiguous address space 131 reserved = reserve_discontiguous(size); 132 contiguous = false; 133 } 134 135 log_info_p(gc, init)("Address Space Type: %s/%s/%s", 136 (contiguous ? "Contiguous" : "Discontiguous"), 137 (limit == ZAddressOffsetMax ? "Unrestricted" : "Restricted"), 138 (reserved == size ? "Complete" : "Degraded")); 139 log_info_p(gc, init)("Address Space Size: " SIZE_FORMAT "M x " SIZE_FORMAT " = " SIZE_FORMAT "M", 140 reserved / M, ZHeapViews, (reserved * ZHeapViews) / M); 141 142 return reserved >= max_capacity; 143 } 144 145 void ZVirtualMemoryManager::nmt_reserve(uintptr_t start, size_t size) { 146 MemTracker::record_virtual_memory_reserve((void*)start, size, CALLER_PC); 147 MemTracker::record_virtual_memory_type((void*)start, mtJavaHeap); 148 } 149 150 bool ZVirtualMemoryManager::is_initialized() const { 151 return _initialized; 152 } 153 154 ZVirtualMemory ZVirtualMemoryManager::alloc(size_t size, bool alloc_from_front) { 155 uintptr_t start; 156 157 if (alloc_from_front || size <= ZPageSizeSmall) { 158 // Small page 159 start = _manager.alloc_from_front(size); 160 } else { |