diff -r 6a6c91ccc0bc -r 8f95d0407e21 hotspot/src/share/vm/runtime/os.cpp --- a/hotspot/src/share/vm/runtime/os.cpp Mon Aug 18 10:07:43 2014 +0100 +++ b/hotspot/src/share/vm/runtime/os.cpp Tue Aug 19 11:17:44 2014 -0700 @@ -52,6 +52,7 @@ #include "runtime/thread.inline.hpp" #include "runtime/vm_version.hpp" #include "services/attachListener.hpp" +#include "services/nmtCommon.hpp" #include "services/memTracker.hpp" #include "services/threadService.hpp" #include "utilities/defaultStream.hpp" @@ -516,6 +517,14 @@ return dup_str; } +char* os::strdup_check_oom(const char* str, MEMFLAGS flags) { + char* p = os::strdup(str, flags); + if (p == NULL) { + vm_exit_out_of_memory(strlen(str) + 1, OOM_MALLOC_ERROR, "os::strdup_check_oom"); + } + return p; +} + #define paranoid 0 /* only set to 1 if you suspect checking code has bug */ @@ -553,7 +562,11 @@ return ptr; } -void* os::malloc(size_t size, MEMFLAGS memflags, address caller) { +void* os::malloc(size_t size, MEMFLAGS flags) { + return os::malloc(size, flags, CALLER_PC); +} + +void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) { NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); @@ -579,11 +592,15 @@ size = 1; } + // NMT support + NMT_TrackingLevel level = MemTracker::tracking_level(); + size_t nmt_header_size = MemTracker::malloc_header_size(level); + #ifndef ASSERT - const size_t alloc_size = size; + const size_t alloc_size = size + nmt_header_size; #else - const size_t alloc_size = GuardedMemory::get_total_size(size); - if (size > alloc_size) { // Check for rollover. + const size_t alloc_size = GuardedMemory::get_total_size(size + nmt_header_size); + if (size + nmt_header_size > alloc_size) { // Check for rollover. return NULL; } #endif @@ -602,7 +619,7 @@ return NULL; } // Wrap memory with guard - GuardedMemory guarded(ptr, size); + GuardedMemory guarded(ptr, size + nmt_header_size); ptr = guarded.get_user_ptr(); #endif if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) { @@ -615,48 +632,50 @@ } // we do not track guard memory - MemTracker::record_malloc((address)ptr, size, memflags, caller == 0 ? CALLER_PC : caller); - - return ptr; + return MemTracker::record_malloc((address)ptr, size, memflags, stack, level); } +void* os::realloc(void *memblock, size_t size, MEMFLAGS flags) { + return os::realloc(memblock, size, flags, CALLER_PC); +} -void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller) { +void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCallStack& stack) { #ifndef ASSERT NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); - MemTracker::Tracker tkr = MemTracker::get_realloc_tracker(); - void* ptr = ::realloc(memblock, size); - if (ptr != NULL) { - tkr.record((address)memblock, (address)ptr, size, memflags, - caller == 0 ? CALLER_PC : caller); - } else { - tkr.discard(); - } - return ptr; + // NMT support + void* membase = MemTracker::record_free(memblock); + NMT_TrackingLevel level = MemTracker::tracking_level(); + size_t nmt_header_size = MemTracker::malloc_header_size(level); + void* ptr = ::realloc(membase, size + nmt_header_size); + return MemTracker::record_malloc(ptr, size, memflags, stack, level); #else if (memblock == NULL) { - return os::malloc(size, memflags, (caller == 0 ? CALLER_PC : caller)); + return os::malloc(size, memflags, stack); } if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { tty->print_cr("os::realloc caught " PTR_FORMAT, memblock); breakpoint(); } - verify_memory(memblock); + // NMT support + void* membase = MemTracker::malloc_base(memblock); + verify_memory(membase); NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); if (size == 0) { return NULL; } // always move the block - void* ptr = os::malloc(size, memflags, caller == 0 ? CALLER_PC : caller); + void* ptr = os::malloc(size, memflags, stack); if (PrintMalloc) { tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr); } // Copy to new memory if malloc didn't fail if ( ptr != NULL ) { - GuardedMemory guarded(memblock); - memcpy(ptr, memblock, MIN2(size, guarded.get_user_size())); - if (paranoid) verify_memory(ptr); + GuardedMemory guarded(MemTracker::malloc_base(memblock)); + // Guard's user data contains NMT header + size_t memblock_size = guarded.get_user_size() - MemTracker::malloc_header_size(memblock); + memcpy(ptr, memblock, MIN2(size, memblock_size)); + if (paranoid) verify_memory(MemTracker::malloc_base(ptr)); if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) { tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr); breakpoint(); @@ -669,7 +688,6 @@ void os::free(void *memblock, MEMFLAGS memflags) { - address trackp = (address) memblock; NOT_PRODUCT(inc_stat_counter(&num_frees, 1)); #ifdef ASSERT if (memblock == NULL) return; @@ -677,20 +695,22 @@ if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock); breakpoint(); } - verify_memory(memblock); + void* membase = MemTracker::record_free(memblock); + verify_memory(membase); NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); - GuardedMemory guarded(memblock); + GuardedMemory guarded(membase); size_t size = guarded.get_user_size(); inc_stat_counter(&free_bytes, size); - memblock = guarded.release_for_freeing(); + membase = guarded.release_for_freeing(); if (PrintMalloc && tty != NULL) { - fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock); + fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)membase); } + ::free(membase); +#else + void* membase = MemTracker::record_free(memblock); + ::free(membase); #endif - MemTracker::record_free(trackp, memflags); - - ::free(memblock); } void os::init_random(long initval) { @@ -1478,7 +1498,7 @@ char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) { char* result = pd_reserve_memory(bytes, addr, alignment_hint); if (result != NULL) { - MemTracker::record_virtual_memory_reserve((address)result, bytes, mtNone, CALLER_PC); + MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); } return result; @@ -1488,7 +1508,7 @@ MEMFLAGS flags) { char* result = pd_reserve_memory(bytes, addr, alignment_hint); if (result != NULL) { - MemTracker::record_virtual_memory_reserve((address)result, bytes, mtNone, CALLER_PC); + MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); MemTracker::record_virtual_memory_type((address)result, flags); } @@ -1498,7 +1518,7 @@ char* os::attempt_reserve_memory_at(size_t bytes, char* addr) { char* result = pd_attempt_reserve_memory_at(bytes, addr); if (result != NULL) { - MemTracker::record_virtual_memory_reserve((address)result, bytes, mtNone, CALLER_PC); + MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); } return result; } @@ -1538,23 +1558,29 @@ } bool os::uncommit_memory(char* addr, size_t bytes) { - MemTracker::Tracker tkr = MemTracker::get_virtual_memory_uncommit_tracker(); - bool res = pd_uncommit_memory(addr, bytes); - if (res) { - tkr.record((address)addr, bytes); + bool res; + if (MemTracker::tracking_level() > NMT_minimal) { + Tracker tkr = MemTracker::get_virtual_memory_uncommit_tracker(); + res = pd_uncommit_memory(addr, bytes); + if (res) { + tkr.record((address)addr, bytes); + } } else { - tkr.discard(); + res = pd_uncommit_memory(addr, bytes); } return res; } bool os::release_memory(char* addr, size_t bytes) { - MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker(); - bool res = pd_release_memory(addr, bytes); - if (res) { - tkr.record((address)addr, bytes); + bool res; + if (MemTracker::tracking_level() > NMT_minimal) { + Tracker tkr = MemTracker::get_virtual_memory_release_tracker(); + res = pd_release_memory(addr, bytes); + if (res) { + tkr.record((address)addr, bytes); + } } else { - tkr.discard(); + res = pd_release_memory(addr, bytes); } return res; } @@ -1565,7 +1591,7 @@ bool allow_exec) { char* result = pd_map_memory(fd, file_name, file_offset, addr, bytes, read_only, allow_exec); if (result != NULL) { - MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, mtNone, CALLER_PC); + MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC); } return result; } @@ -1578,12 +1604,15 @@ } bool os::unmap_memory(char *addr, size_t bytes) { - MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker(); - bool result = pd_unmap_memory(addr, bytes); - if (result) { - tkr.record((address)addr, bytes); + bool result; + if (MemTracker::tracking_level() > NMT_minimal) { + Tracker tkr = MemTracker::get_virtual_memory_release_tracker(); + result = pd_unmap_memory(addr, bytes); + if (result) { + tkr.record((address)addr, bytes); + } } else { - tkr.discard(); + result = pd_unmap_memory(addr, bytes); } return result; }