Path: blob/master/src/hotspot/share/memory/allocation.inline.hpp
40949 views
/*1* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_MEMORY_ALLOCATION_INLINE_HPP25#define SHARE_MEMORY_ALLOCATION_INLINE_HPP2627#include "memory/allocation.hpp"2829#include "runtime/atomic.hpp"30#include "runtime/globals.hpp"31#include "runtime/os.hpp"32#include "utilities/align.hpp"33#include "utilities/globalDefinitions.hpp"3435// Explicit C-heap memory management3637#ifndef PRODUCT38// Increments unsigned long value for statistics (not atomic on MP, but avoids word-tearing on 32 bit).39inline void inc_stat_counter(volatile julong* dest, julong add_value) {40#ifdef _LP6441*dest += add_value;42#else43julong value = Atomic::load(dest);44Atomic::store(dest, value + add_value);45#endif46}47#endif4849template <class E>50size_t MmapArrayAllocator<E>::size_for(size_t length) {51size_t size = length * sizeof(E);52int alignment = os::vm_allocation_granularity();53return align_up(size, alignment);54}5556template <class E>57E* MmapArrayAllocator<E>::allocate_or_null(size_t length, MEMFLAGS flags) {58size_t size = size_for(length);5960char* addr = os::reserve_memory(size, !ExecMem, flags);61if (addr == NULL) {62return NULL;63}6465if (os::commit_memory(addr, size, !ExecMem)) {66return (E*)addr;67} else {68os::release_memory(addr, size);69return NULL;70}71}7273template <class E>74E* MmapArrayAllocator<E>::allocate(size_t length, MEMFLAGS flags) {75size_t size = size_for(length);7677char* addr = os::reserve_memory(size, !ExecMem, flags);78if (addr == NULL) {79vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "Allocator (reserve)");80}8182os::commit_memory_or_exit(addr, size, !ExecMem, "Allocator (commit)");8384return (E*)addr;85}8687template <class E>88void MmapArrayAllocator<E>::free(E* addr, size_t length) {89bool result = os::release_memory((char*)addr, size_for(length));90assert(result, "Failed to release memory");91}9293template <class E>94size_t MallocArrayAllocator<E>::size_for(size_t length) {95return length * sizeof(E);96}9798template <class E>99E* MallocArrayAllocator<E>::allocate(size_t length, MEMFLAGS flags) {100return (E*)AllocateHeap(size_for(length), flags);101}102103template<class E>104void MallocArrayAllocator<E>::free(E* addr) {105FreeHeap(addr);106}107108template <class E>109bool ArrayAllocator<E>::should_use_malloc(size_t length) {110return MallocArrayAllocator<E>::size_for(length) < ArrayAllocatorMallocLimit;111}112113template <class E>114E* ArrayAllocator<E>::allocate_malloc(size_t length, MEMFLAGS flags) {115return MallocArrayAllocator<E>::allocate(length, flags);116}117118template <class E>119E* ArrayAllocator<E>::allocate_mmap(size_t length, MEMFLAGS flags) {120return MmapArrayAllocator<E>::allocate(length, flags);121}122123template <class E>124E* ArrayAllocator<E>::allocate(size_t length, MEMFLAGS flags) {125if (should_use_malloc(length)) {126return allocate_malloc(length, flags);127}128129return allocate_mmap(length, flags);130}131132template <class E>133E* ArrayAllocator<E>::reallocate(E* old_addr, size_t old_length, size_t new_length, MEMFLAGS flags) {134E* new_addr = (new_length > 0)135? allocate(new_length, flags)136: NULL;137138if (new_addr != NULL && old_addr != NULL) {139memcpy(new_addr, old_addr, MIN2(old_length, new_length) * sizeof(E));140}141142if (old_addr != NULL) {143free(old_addr, old_length);144}145146return new_addr;147}148149template<class E>150void ArrayAllocator<E>::free_malloc(E* addr, size_t length) {151MallocArrayAllocator<E>::free(addr);152}153154template<class E>155void ArrayAllocator<E>::free_mmap(E* addr, size_t length) {156MmapArrayAllocator<E>::free(addr, length);157}158159template<class E>160void ArrayAllocator<E>::free(E* addr, size_t length) {161if (addr != NULL) {162if (should_use_malloc(length)) {163free_malloc(addr, length);164} else {165free_mmap(addr, length);166}167}168}169170#endif // SHARE_MEMORY_ALLOCATION_INLINE_HPP171172173