# HG changeset patch # User zgu # Date 1362683204 18000 # Node ID f256c20146f4097e80ac9aacb3df5870dbae896b # Parent 8e87d545195f8c0b789212e2f924e7641c511be2 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option Summary: Corrected virtual memory recording and tagging code when large pages are used Reviewed-by: coleenp, ccheung diff -r 8e87d545195f -r f256c20146f4 hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Tue Mar 05 13:55:56 2013 -0800 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Mar 07 14:06:44 2013 -0500 @@ -57,6 +57,7 @@ #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" #include "services/attachListener.hpp" +#include "services/memTracker.hpp" #include "services/runtimeService.hpp" #include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" @@ -2275,13 +2276,25 @@ return NULL; } + // The memory is committed + address pc = CALLER_PC; + MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc); + MemTracker::record_virtual_memory_commit((address)addr, bytes, pc); + return addr; } bool os::release_memory_special(char* base, size_t bytes) { // detaching the SHM segment will also delete it, see reserve_memory_special() int rslt = shmdt(base); - return rslt == 0; + if (rslt == 0) { + MemTracker::record_virtual_memory_uncommit((address)base, bytes); + MemTracker::record_virtual_memory_release((address)base, bytes); + return true; + } else { + return false; + } + } size_t os::large_page_size() { diff -r 8e87d545195f -r f256c20146f4 hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Tue Mar 05 13:55:56 2013 -0800 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu Mar 07 14:06:44 2013 -0500 @@ -58,6 +58,7 @@ #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" #include "services/attachListener.hpp" +#include "services/memTracker.hpp" #include "services/runtimeService.hpp" #include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" @@ -3212,13 +3213,24 @@ numa_make_global(addr, bytes); } + // The memory is committed + address pc = CALLER_PC; + MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc); + MemTracker::record_virtual_memory_commit((address)addr, bytes, pc); + return addr; } bool os::release_memory_special(char* base, size_t bytes) { // detaching the SHM segment will also delete it, see reserve_memory_special() int rslt = shmdt(base); - return rslt == 0; + if (rslt == 0) { + MemTracker::record_virtual_memory_uncommit((address)base, bytes); + MemTracker::record_virtual_memory_release((address)base, bytes); + return true; + } else { + return false; + } } size_t os::large_page_size() { diff -r 8e87d545195f -r f256c20146f4 hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Tue Mar 05 13:55:56 2013 -0800 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Mar 07 14:06:44 2013 -0500 @@ -3420,13 +3420,25 @@ if ((retAddr != NULL) && UseNUMAInterleaving) { numa_make_global(retAddr, size); } + + // The memory is committed + address pc = CALLER_PC; + MemTracker::record_virtual_memory_reserve((address)retAddr, size, pc); + MemTracker::record_virtual_memory_commit((address)retAddr, size, pc); + return retAddr; } bool os::release_memory_special(char* base, size_t bytes) { // detaching the SHM segment will also delete it, see reserve_memory_special() int rslt = shmdt(base); - return rslt == 0; + if (rslt == 0) { + MemTracker::record_virtual_memory_uncommit((address)base, bytes); + MemTracker::record_virtual_memory_release((address)base, bytes); + return true; + } else { + return false; + } } size_t os::large_page_size() { diff -r 8e87d545195f -r f256c20146f4 hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Tue Mar 05 13:55:56 2013 -0800 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu Mar 07 14:06:44 2013 -0500 @@ -60,6 +60,7 @@ #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" #include "services/attachListener.hpp" +#include "services/memTracker.hpp" #include "services/runtimeService.hpp" #include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" @@ -2836,7 +2837,7 @@ PAGE_READWRITE); // If reservation failed, return NULL if (p_buf == NULL) return NULL; - + MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC); os::release_memory(p_buf, bytes + chunk_size); // we still need to round up to a page boundary (in case we are using large pages) @@ -2898,6 +2899,11 @@ if (next_alloc_addr > p_buf) { // Some memory was committed so release it. size_t bytes_to_release = bytes - bytes_remaining; + // NMT has yet to record any individual blocks, so it + // need to create a dummy 'reserve' record to match + // the release. + MemTracker::record_virtual_memory_reserve((address)p_buf, + bytes_to_release, CALLER_PC); os::release_memory(p_buf, bytes_to_release); } #ifdef ASSERT @@ -2909,10 +2915,19 @@ #endif return NULL; } + bytes_remaining -= bytes_to_rq; next_alloc_addr += bytes_to_rq; count++; } + // Although the memory is allocated individually, it is returned as one. + // NMT records it as one block. + address pc = CALLER_PC; + MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, pc); + if ((flags & MEM_COMMIT) != 0) { + MemTracker::record_virtual_memory_commit((address)p_buf, bytes, pc); + } + // made it this far, success return p_buf; } @@ -3099,11 +3114,20 @@ // normal policy just allocate it all at once DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot); + if (res != NULL) { + address pc = CALLER_PC; + MemTracker::record_virtual_memory_reserve((address)res, bytes, pc); + MemTracker::record_virtual_memory_commit((address)res, bytes, pc); + } + return res; } } bool os::release_memory_special(char* base, size_t bytes) { + assert(base != NULL, "Sanity check"); + // Memory allocated via reserve_memory_special() is committed + MemTracker::record_virtual_memory_uncommit((address)base, bytes); return release_memory(base, bytes); }