blob: 32f6a625c598fd9b13984206ed3003ed65cb97f9 [file] [log] [blame]
J. Duke81537792007-12-01 00:00:00 +00001/*
David Holmes5f1f4482016-08-21 20:56:37 -04002 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
J. Duke81537792007-12-01 00:00:00 +00003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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 *
Erik Trimbleba7c1732010-05-27 19:08:38 -070019 * 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.
J. Duke81537792007-12-01 00:00:00 +000022 *
23 */
24
Stefan Karlsson8006fe82010-11-23 13:22:55 -080025#ifndef SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP
26#define SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP
27
David Holmes5f1f4482016-08-21 20:56:37 -040028#include "runtime/atomic.hpp"
Stefan Karlsson8006fe82010-11-23 13:22:55 -080029#include "runtime/os.hpp"
Zhengyu Guf0cf82f2014-08-07 12:18:58 -070030#include "services/memTracker.hpp"
Stefan Karlssona18f1c22017-07-05 11:33:17 +020031#include "utilities/align.hpp"
Yasumasa Suenaga161976b2016-06-21 19:29:39 -040032#include "utilities/globalDefinitions.hpp"
Stefan Karlsson8006fe82010-11-23 13:22:55 -080033
J. Duke81537792007-12-01 00:00:00 +000034// Explicit C-heap memory management
35
36void trace_heap_malloc(size_t size, const char* name, void *p);
37void trace_heap_free(void *p);
38
Vladimir Kozlovc1306202011-02-10 19:34:48 -080039#ifndef PRODUCT
Vladimir Kozlovb9633d42011-02-07 10:34:39 -080040// Increments unsigned long value for statistics (not atomic on MP).
41inline void inc_stat_counter(volatile julong* dest, julong add_value) {
Vladimir Kozlovc1306202011-02-10 19:34:48 -080042#if defined(SPARC) || defined(X86)
43 // Sparc and X86 have atomic jlong (8 bytes) instructions
Vladimir Kozlovb9633d42011-02-07 10:34:39 -080044 julong value = Atomic::load((volatile jlong*)dest);
45 value += add_value;
46 Atomic::store((jlong)value, (volatile jlong*)dest);
Vladimir Kozlovc1306202011-02-10 19:34:48 -080047#else
48 // possible word-tearing during load/store
49 *dest += add_value;
50#endif
Vladimir Kozlovb9633d42011-02-07 10:34:39 -080051}
Vladimir Kozlovc1306202011-02-10 19:34:48 -080052#endif
J. Duke81537792007-12-01 00:00:00 +000053
54// allocate using malloc; will fail if no memory available
Zhengyu Guf0cf82f2014-08-07 12:18:58 -070055inline char* AllocateHeap(size_t size, MEMFLAGS flags,
56 const NativeCallStack& stack,
Nils Loodin953bec32012-10-17 17:36:48 +020057 AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
Zhengyu Guf0cf82f2014-08-07 12:18:58 -070058 char* p = (char*) os::malloc(size, flags, stack);
J. Duke81537792007-12-01 00:00:00 +000059 #ifdef ASSERT
Zhengyu Gua39b1762012-06-28 17:03:16 -040060 if (PrintMallocFree) trace_heap_malloc(size, "AllocateHeap", p);
J. Duke81537792007-12-01 00:00:00 +000061 #endif
Calvin Cheung0f7adcc2013-04-30 11:56:52 -070062 if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
63 vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, "AllocateHeap");
64 }
J. Duke81537792007-12-01 00:00:00 +000065 return p;
66}
Yasumasa Suenaga649f4e82015-04-28 19:04:39 +090067
Yasumasa Suenaga161976b2016-06-21 19:29:39 -040068ALWAYSINLINE char* AllocateHeap(size_t size, MEMFLAGS flags,
Nils Loodin953bec32012-10-17 17:36:48 +020069 AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
Zhengyu Guf0cf82f2014-08-07 12:18:58 -070070 return AllocateHeap(size, flags, CURRENT_PC, alloc_failmode);
71}
72
Yasumasa Suenaga161976b2016-06-21 19:29:39 -040073ALWAYSINLINE char* ReallocateHeap(char *old, size_t size, MEMFLAGS flag,
Zhengyu Guf0cf82f2014-08-07 12:18:58 -070074 AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
75 char* p = (char*) os::realloc(old, size, flag, CURRENT_PC);
J. Duke81537792007-12-01 00:00:00 +000076 #ifdef ASSERT
Zhengyu Gua39b1762012-06-28 17:03:16 -040077 if (PrintMallocFree) trace_heap_malloc(size, "ReallocateHeap", p);
J. Duke81537792007-12-01 00:00:00 +000078 #endif
Calvin Cheung0f7adcc2013-04-30 11:56:52 -070079 if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
80 vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, "ReallocateHeap");
81 }
J. Duke81537792007-12-01 00:00:00 +000082 return p;
83}
84
Max Ockner91dbd4f2014-12-01 12:16:15 -050085inline void FreeHeap(void* p) {
J. Duke81537792007-12-01 00:00:00 +000086 #ifdef ASSERT
87 if (PrintMallocFree) trace_heap_free(p);
88 #endif
Max Ockner91dbd4f2014-12-01 12:16:15 -050089 os::free(p);
J. Duke81537792007-12-01 00:00:00 +000090}
Stefan Karlsson8006fe82010-11-23 13:22:55 -080091
Zhengyu Gua39b1762012-06-28 17:03:16 -040092
93template <MEMFLAGS F> void* CHeapObj<F>::operator new(size_t size,
Zhengyu Guf0cf82f2014-08-07 12:18:58 -070094 const NativeCallStack& stack) throw() {
95 void* p = (void*)AllocateHeap(size, F, stack);
96#ifdef ASSERT
97 if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
98#endif
99 return p;
100}
101
102template <MEMFLAGS F> void* CHeapObj<F>::operator new(size_t size) throw() {
103 return CHeapObj<F>::operator new(size, CALLER_PC);
104}
105
106template <MEMFLAGS F> void* CHeapObj<F>::operator new (size_t size,
107 const std::nothrow_t& nothrow_constant, const NativeCallStack& stack) throw() {
108 void* p = (void*)AllocateHeap(size, F, stack,
109 AllocFailStrategy::RETURN_NULL);
Yumin Qi98151c32013-05-14 09:41:12 -0700110#ifdef ASSERT
Zhengyu Gua39b1762012-06-28 17:03:16 -0400111 if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
Zhengyu Gua39b1762012-06-28 17:03:16 -0400112#endif
Yumin Qi98151c32013-05-14 09:41:12 -0700113 return p;
Zhengyu Gua39b1762012-06-28 17:03:16 -0400114 }
115
116template <MEMFLAGS F> void* CHeapObj<F>::operator new (size_t size,
Zhengyu Guf0cf82f2014-08-07 12:18:58 -0700117 const std::nothrow_t& nothrow_constant) throw() {
118 return CHeapObj<F>::operator new(size, nothrow_constant, CALLER_PC);
Yumin Qi98151c32013-05-14 09:41:12 -0700119}
120
121template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size,
Zhengyu Guf0cf82f2014-08-07 12:18:58 -0700122 const NativeCallStack& stack) throw() {
123 return CHeapObj<F>::operator new(size, stack);
124}
125
126template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size)
127 throw() {
128 return CHeapObj<F>::operator new(size, CALLER_PC);
Yumin Qi98151c32013-05-14 09:41:12 -0700129}
130
131template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size,
Zhengyu Guf0cf82f2014-08-07 12:18:58 -0700132 const std::nothrow_t& nothrow_constant, const NativeCallStack& stack) throw() {
133 return CHeapObj<F>::operator new(size, nothrow_constant, stack);
134}
135
136template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size,
137 const std::nothrow_t& nothrow_constant) throw() {
138 return CHeapObj<F>::operator new(size, nothrow_constant, CALLER_PC);
Zhengyu Gua39b1762012-06-28 17:03:16 -0400139}
140
141template <MEMFLAGS F> void CHeapObj<F>::operator delete(void* p){
Max Ockner91dbd4f2014-12-01 12:16:15 -0500142 FreeHeap(p);
Yumin Qi98151c32013-05-14 09:41:12 -0700143}
144
145template <MEMFLAGS F> void CHeapObj<F>::operator delete [](void* p){
Max Ockner91dbd4f2014-12-01 12:16:15 -0500146 FreeHeap(p);
Zhengyu Gua39b1762012-06-28 17:03:16 -0400147}
148
Milan Mimicaf647f782017-07-21 21:01:59 -0400149template <class E>
150size_t MmapArrayAllocator<E>::size_for(size_t length) {
Stefan Karlsson7419b912016-03-09 12:44:12 +0100151 size_t size = length * sizeof(E);
Bengt Rutisson4a685f12013-04-08 07:49:28 +0200152 int alignment = os::vm_allocation_granularity();
Stefan Karlssondbd3b5a2017-07-04 15:58:10 +0200153 return align_up(size, alignment);
Stefan Karlsson7419b912016-03-09 12:44:12 +0100154}
Bengt Rutisson4a685f12013-04-08 07:49:28 +0200155
Milan Mimicaf647f782017-07-21 21:01:59 -0400156template <class E>
157E* MmapArrayAllocator<E>::allocate_or_null(size_t length, MEMFLAGS flags) {
Thomas Schatzl94bbcbd2016-09-15 16:44:19 +0200158 size_t size = size_for(length);
159 int alignment = os::vm_allocation_granularity();
160
Milan Mimicaf647f782017-07-21 21:01:59 -0400161 char* addr = os::reserve_memory(size, NULL, alignment, flags);
Thomas Schatzl94bbcbd2016-09-15 16:44:19 +0200162 if (addr == NULL) {
163 return NULL;
164 }
165
166 if (os::commit_memory(addr, size, !ExecMem, "Allocator (commit)")) {
167 return (E*)addr;
168 } else {
169 os::release_memory(addr, size);
170 return NULL;
171 }
172}
173
Milan Mimicaf647f782017-07-21 21:01:59 -0400174template <class E>
175E* MmapArrayAllocator<E>::allocate(size_t length, MEMFLAGS flags) {
Stefan Karlsson3fa2f0c2016-03-09 17:03:04 +0100176 size_t size = size_for(length);
Stefan Karlsson7419b912016-03-09 12:44:12 +0100177 int alignment = os::vm_allocation_granularity();
178
Milan Mimicaf647f782017-07-21 21:01:59 -0400179 char* addr = os::reserve_memory(size, NULL, alignment, flags);
Mikael Gerdina52fd332014-04-02 14:17:34 +0200180 if (addr == NULL) {
181 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "Allocator (reserve)");
Bengt Rutisson4a685f12013-04-08 07:49:28 +0200182 }
183
Mikael Gerdina52fd332014-04-02 14:17:34 +0200184 os::commit_memory_or_exit(addr, size, !ExecMem, "Allocator (commit)");
Stefan Karlsson7419b912016-03-09 12:44:12 +0100185
186 return (E*)addr;
Mikael Gerdina52fd332014-04-02 14:17:34 +0200187}
188
Milan Mimicaf647f782017-07-21 21:01:59 -0400189template <class E>
190void MmapArrayAllocator<E>::free(E* addr, size_t length) {
Stefan Karlsson3fa2f0c2016-03-09 17:03:04 +0100191 bool result = os::release_memory((char*)addr, size_for(length));
192 assert(result, "Failed to release memory");
193}
194
Milan Mimicaf647f782017-07-21 21:01:59 -0400195template <class E>
196size_t MallocArrayAllocator<E>::size_for(size_t length) {
Stefan Karlsson3fa2f0c2016-03-09 17:03:04 +0100197 return length * sizeof(E);
198}
199
Milan Mimicaf647f782017-07-21 21:01:59 -0400200template <class E>
201E* MallocArrayAllocator<E>::allocate(size_t length, MEMFLAGS flags) {
202 return (E*)AllocateHeap(size_for(length), flags);
Stefan Karlsson3fa2f0c2016-03-09 17:03:04 +0100203}
204
Milan Mimicaf647f782017-07-21 21:01:59 -0400205template<class E>
206void MallocArrayAllocator<E>::free(E* addr, size_t /*length*/) {
Stefan Karlsson3fa2f0c2016-03-09 17:03:04 +0100207 FreeHeap(addr);
208}
209
Milan Mimicaf647f782017-07-21 21:01:59 -0400210template <class E>
211bool ArrayAllocator<E>::should_use_malloc(size_t length) {
212 return MallocArrayAllocator<E>::size_for(length) < ArrayAllocatorMallocLimit;
Stefan Karlsson3fa2f0c2016-03-09 17:03:04 +0100213}
214
Milan Mimicaf647f782017-07-21 21:01:59 -0400215template <class E>
216E* ArrayAllocator<E>::allocate_malloc(size_t length, MEMFLAGS flags) {
217 return MallocArrayAllocator<E>::allocate(length, flags);
Stefan Karlsson3fa2f0c2016-03-09 17:03:04 +0100218}
219
Milan Mimicaf647f782017-07-21 21:01:59 -0400220template <class E>
221E* ArrayAllocator<E>::allocate_mmap(size_t length, MEMFLAGS flags) {
222 return MmapArrayAllocator<E>::allocate(length, flags);
Stefan Karlsson3fa2f0c2016-03-09 17:03:04 +0100223}
224
Milan Mimicaf647f782017-07-21 21:01:59 -0400225template <class E>
226E* ArrayAllocator<E>::allocate(size_t length, MEMFLAGS flags) {
Stefan Karlsson7419b912016-03-09 12:44:12 +0100227 if (should_use_malloc(length)) {
Milan Mimicaf647f782017-07-21 21:01:59 -0400228 return allocate_malloc(length, flags);
Stefan Karlsson7419b912016-03-09 12:44:12 +0100229 }
Mikael Gerdina52fd332014-04-02 14:17:34 +0200230
Milan Mimicaf647f782017-07-21 21:01:59 -0400231 return allocate_mmap(length, flags);
Bengt Rutisson4a685f12013-04-08 07:49:28 +0200232}
233
Milan Mimicaf647f782017-07-21 21:01:59 -0400234template <class E>
235E* ArrayAllocator<E>::reallocate(E* old_addr, size_t old_length, size_t new_length, MEMFLAGS flags) {
Stefan Karlsson7419b912016-03-09 12:44:12 +0100236 E* new_addr = (new_length > 0)
Milan Mimicaf647f782017-07-21 21:01:59 -0400237 ? allocate(new_length, flags)
Stefan Karlsson7419b912016-03-09 12:44:12 +0100238 : NULL;
Mikael Gerdina52fd332014-04-02 14:17:34 +0200239
Stefan Karlsson7419b912016-03-09 12:44:12 +0100240 if (new_addr != NULL && old_addr != NULL) {
241 memcpy(new_addr, old_addr, MIN2(old_length, new_length) * sizeof(E));
242 }
Mikael Gerdina52fd332014-04-02 14:17:34 +0200243
Stefan Karlsson7419b912016-03-09 12:44:12 +0100244 if (old_addr != NULL) {
245 free(old_addr, old_length);
246 }
247
248 return new_addr;
Mikael Gerdina52fd332014-04-02 14:17:34 +0200249}
250
Milan Mimicaf647f782017-07-21 21:01:59 -0400251template<class E>
252void ArrayAllocator<E>::free_malloc(E* addr, size_t length) {
253 MallocArrayAllocator<E>::free(addr, length);
Stefan Karlsson7419b912016-03-09 12:44:12 +0100254}
255
Milan Mimicaf647f782017-07-21 21:01:59 -0400256template<class E>
257void ArrayAllocator<E>::free_mmap(E* addr, size_t length) {
258 MmapArrayAllocator<E>::free(addr, length);
Stefan Karlsson7419b912016-03-09 12:44:12 +0100259}
260
Milan Mimicaf647f782017-07-21 21:01:59 -0400261template<class E>
262void ArrayAllocator<E>::free(E* addr, size_t length) {
Stefan Karlsson7419b912016-03-09 12:44:12 +0100263 if (addr != NULL) {
264 if (should_use_malloc(length)) {
265 free_malloc(addr, length);
Bengt Rutisson4a685f12013-04-08 07:49:28 +0200266 } else {
Stefan Karlsson7419b912016-03-09 12:44:12 +0100267 free_mmap(addr, length);
Bengt Rutisson4a685f12013-04-08 07:49:28 +0200268 }
Bengt Rutisson4a685f12013-04-08 07:49:28 +0200269 }
270}
Zhengyu Gua39b1762012-06-28 17:03:16 -0400271
Stefan Karlsson8006fe82010-11-23 13:22:55 -0800272#endif // SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP