0N/A/*
4552N/A * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
1879N/A#ifndef SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP
1879N/A#define SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP
1879N/A
1879N/A#include "runtime/os.hpp"
1879N/A
0N/A// Explicit C-heap memory management
0N/A
0N/Avoid trace_heap_malloc(size_t size, const char* name, void *p);
0N/Avoid trace_heap_free(void *p);
0N/A
2127N/A#ifndef PRODUCT
2122N/A// Increments unsigned long value for statistics (not atomic on MP).
2122N/Ainline void inc_stat_counter(volatile julong* dest, julong add_value) {
2127N/A#if defined(SPARC) || defined(X86)
2127N/A // Sparc and X86 have atomic jlong (8 bytes) instructions
2122N/A julong value = Atomic::load((volatile jlong*)dest);
2122N/A value += add_value;
2122N/A Atomic::store((jlong)value, (volatile jlong*)dest);
2127N/A#else
2127N/A // possible word-tearing during load/store
2127N/A *dest += add_value;
2127N/A#endif
2122N/A}
2127N/A#endif
0N/A
0N/A// allocate using malloc; will fail if no memory available
4565N/Ainline char* AllocateHeap(size_t size, MEMFLAGS flags, address pc = 0,
4565N/A AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
3863N/A if (pc == 0) {
3863N/A pc = CURRENT_PC;
3863N/A }
3863N/A char* p = (char*) os::malloc(size, flags, pc);
0N/A #ifdef ASSERT
3863N/A if (PrintMallocFree) trace_heap_malloc(size, "AllocateHeap", p);
0N/A #endif
4565N/A if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM)
4565N/A vm_exit_out_of_memory(size, "AllocateHeap");
3863N/A return p;
3863N/A}
3863N/A
4565N/Ainline char* ReallocateHeap(char *old, size_t size, MEMFLAGS flags,
4565N/A AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
3863N/A char* p = (char*) os::realloc(old, size, flags, CURRENT_PC);
3863N/A #ifdef ASSERT
3863N/A if (PrintMallocFree) trace_heap_malloc(size, "ReallocateHeap", p);
3863N/A #endif
4565N/A if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM)
4565N/A vm_exit_out_of_memory(size, "ReallocateHeap");
0N/A return p;
0N/A}
0N/A
3863N/Ainline void FreeHeap(void* p, MEMFLAGS memflags = mtInternal) {
0N/A #ifdef ASSERT
0N/A if (PrintMallocFree) trace_heap_free(p);
0N/A #endif
3863N/A os::free(p, memflags);
0N/A}
1879N/A
3863N/A
3863N/Atemplate <MEMFLAGS F> void* CHeapObj<F>::operator new(size_t size,
3863N/A address caller_pc){
3863N/A#ifdef ASSERT
3863N/A void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
3863N/A if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
3863N/A return p;
3863N/A#else
3863N/A return (void *) AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
3863N/A#endif
3863N/A }
3863N/A
3863N/Atemplate <MEMFLAGS F> void* CHeapObj<F>::operator new (size_t size,
3863N/A const std::nothrow_t& nothrow_constant, address caller_pc) {
3863N/A#ifdef ASSERT
3863N/A void* p = os::malloc(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
3863N/A if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
3863N/A return p;
3863N/A#else
3863N/A return os::malloc(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
3863N/A#endif
3863N/A}
3863N/A
3863N/Atemplate <MEMFLAGS F> void CHeapObj<F>::operator delete(void* p){
3863N/A FreeHeap(p, F);
3863N/A}
3863N/A
4523N/Atemplate <class E, MEMFLAGS F>
4523N/AE* ArrayAllocator<E, F>::allocate(size_t length) {
4523N/A assert(_addr == NULL, "Already in use");
4523N/A
4523N/A _size = sizeof(E) * length;
4523N/A _use_malloc = _size < ArrayAllocatorMallocLimit;
4523N/A
4523N/A if (_use_malloc) {
4523N/A _addr = AllocateHeap(_size, F);
4523N/A if (_addr == NULL && _size >= (size_t)os::vm_allocation_granularity()) {
4523N/A // malloc failed let's try with mmap instead
4523N/A _use_malloc = false;
4523N/A } else {
4523N/A return (E*)_addr;
4523N/A }
4523N/A }
4523N/A
4523N/A int alignment = os::vm_allocation_granularity();
4523N/A _size = align_size_up(_size, alignment);
4523N/A
4523N/A _addr = os::reserve_memory(_size, NULL, alignment, F);
4523N/A if (_addr == NULL) {
4523N/A vm_exit_out_of_memory(_size, "Allocator (reserve)");
4523N/A }
4523N/A
4552N/A os::commit_memory_or_exit(_addr, _size, !ExecMem, "Allocator (commit)");
4523N/A
4523N/A return (E*)_addr;
4523N/A}
4523N/A
4523N/Atemplate<class E, MEMFLAGS F>
4523N/Avoid ArrayAllocator<E, F>::free() {
4523N/A if (_addr != NULL) {
4523N/A if (_use_malloc) {
4523N/A FreeHeap(_addr, F);
4523N/A } else {
4523N/A os::release_memory(_addr, _size);
4523N/A }
4523N/A _addr = NULL;
4523N/A }
4523N/A}
3863N/A
1879N/A#endif // SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP