From 81097c5596d1e5fe7b21fee4e402b4fc2ab8864a Mon Sep 17 00:00:00 2001 From: zgu Date: Thu, 28 Jun 2012 17:03:16 -0400 Subject: 6995781: Native Memory Tracking (Phase 1) 7151532: DCmd for hotspot native memory tracking Summary: Implementation of native memory tracking phase 1, which tracks VM native memory usage, and related DCmd Reviewed-by: acorn, coleenp, fparain --- src/os/linux/vm/os_linux.cpp | 40 +++++++++++----------- src/os/linux/vm/os_linux.hpp | 4 +-- src/os/linux/vm/os_linux.inline.hpp | 2 +- src/os/linux/vm/perfMemory_linux.cpp | 66 ++++++++++++++++++------------------ 4 files changed, 56 insertions(+), 56 deletions(-) (limited to 'src/os/linux') diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp index 53457ec8d..ce7c71b9d 100644 --- a/src/os/linux/vm/os_linux.cpp +++ b/src/os/linux/vm/os_linux.cpp @@ -371,7 +371,7 @@ void os::init_system_properties_values() { // code needs to be changed accordingly. // The next few definitions allow the code to be verbatim: -#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n)) +#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal) #define getenv(n) ::getenv(n) /* @@ -639,7 +639,7 @@ void os::Linux::libpthread_init() { size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0); if (n > 0) { - char *str = (char *)malloc(n); + char *str = (char *)malloc(n, mtInternal); confstr(_CS_GNU_LIBC_VERSION, str, n); os::Linux::set_glibc_version(str); } else { @@ -652,7 +652,7 @@ void os::Linux::libpthread_init() { n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0); if (n > 0) { - char *str = (char *)malloc(n); + char *str = (char *)malloc(n, mtInternal); confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n); // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells // us "NPTL-0.29" even we are running with LinuxThreads. Check if this @@ -1685,11 +1685,11 @@ void os::dll_build_name(char* buffer, size_t buflen, // release the storage for (int i = 0 ; i < n ; i++) { if (pelements[i] != NULL) { - FREE_C_HEAP_ARRAY(char, pelements[i]); + FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal); } } if (pelements != NULL) { - FREE_C_HEAP_ARRAY(char*, pelements); + FREE_C_HEAP_ARRAY(char*, pelements, mtInternal); } } else { snprintf(buffer, buflen, "%s/lib%s.so", pname, fname); @@ -2469,7 +2469,7 @@ void linux_wrap_code(char* base, size_t size) { // All it does is to check if there are enough free pages // left at the time of mmap(). This could be a potential // problem. -bool os::commit_memory(char* addr, size_t size, bool exec) { +bool os::pd_commit_memory(char* addr, size_t size, bool exec) { int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); @@ -2492,7 +2492,7 @@ bool os::commit_memory(char* addr, size_t size, bool exec) { #define MADV_HUGEPAGE 14 #endif -bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, +bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, bool exec) { if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; @@ -2516,7 +2516,7 @@ bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, return false; } -void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { +void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { // We don't check the return value: madvise(MADV_HUGEPAGE) may not // be supported or the memory may already be backed by huge pages. @@ -2524,7 +2524,7 @@ void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { } } -void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) { +void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { // This method works by doing an mmap over an existing mmaping and effectively discarding // the existing pages. However it won't work for SHM-based large pages that cannot be // uncommitted at all. We don't do anything in this case to avoid creating a segment with @@ -2646,7 +2646,7 @@ bool os::Linux::libnuma_init() { if (numa_available() != -1) { set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes")); // Create a cpu -> node mapping - _cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray(0, true); + _cpu_to_node = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(0, true); rebuild_cpu_to_node_map(); return true; } @@ -2676,7 +2676,7 @@ void os::Linux::rebuild_cpu_to_node_map() { cpu_to_node()->at_grow(cpu_num - 1); size_t node_num = numa_get_groups_num(); - unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size); + unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size, mtInternal); for (size_t i = 0; i < node_num; i++) { if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) { for (size_t j = 0; j < cpu_map_valid_size; j++) { @@ -2690,7 +2690,7 @@ void os::Linux::rebuild_cpu_to_node_map() { } } } - FREE_C_HEAP_ARRAY(unsigned long, cpu_map); + FREE_C_HEAP_ARRAY(unsigned long, cpu_map, mtInternal); } int os::Linux::get_node_by_cpu(int cpu_id) { @@ -2709,7 +2709,7 @@ os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; unsigned long* os::Linux::_numa_all_nodes; -bool os::uncommit_memory(char* addr, size_t size) { +bool os::pd_uncommit_memory(char* addr, size_t size) { uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); return res != (uintptr_t) MAP_FAILED; @@ -2774,7 +2774,7 @@ bool get_stack_bounds(uintptr_t *bottom, uintptr_t *top) { // munmap() the guard pages we don't leave a hole in the stack // mapping. This only affects the main/initial thread, but guard // against future OS changes -bool os::create_stack_guard_pages(char* addr, size_t size) { +bool os::pd_create_stack_guard_pages(char* addr, size_t size) { uintptr_t stack_extent, stack_base; bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true); if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) { @@ -2847,12 +2847,12 @@ static int anon_munmap(char * addr, size_t size) { return ::munmap(addr, size) == 0; } -char* os::reserve_memory(size_t bytes, char* requested_addr, +char* os::pd_reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) { return anon_mmap(requested_addr, bytes, (requested_addr != NULL)); } -bool os::release_memory(char* addr, size_t size) { +bool os::pd_release_memory(char* addr, size_t size) { return anon_munmap(addr, size); } @@ -3149,7 +3149,7 @@ bool os::can_execute_large_page_memory() { // Reserve memory at an arbitrary address, only if that area is // available (and not reserved for something else). -char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) { +char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) { const int max_tries = 10; char* base[max_tries]; size_t size[max_tries]; @@ -4671,7 +4671,7 @@ int os::socket_available(int fd, jint *pbytes) { } // Map a block of memory. -char* os::map_memory(int fd, const char* file_name, size_t file_offset, +char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only, bool allow_exec) { int prot; @@ -4701,7 +4701,7 @@ char* os::map_memory(int fd, const char* file_name, size_t file_offset, // Remap a block of memory. -char* os::remap_memory(int fd, const char* file_name, size_t file_offset, +char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only, bool allow_exec) { // same as map_memory() on this OS @@ -4711,7 +4711,7 @@ char* os::remap_memory(int fd, const char* file_name, size_t file_offset, // Unmap a block of memory. -bool os::unmap_memory(char* addr, size_t bytes) { +bool os::pd_unmap_memory(char* addr, size_t bytes) { return munmap(addr, bytes) == 0; } diff --git a/src/os/linux/vm/os_linux.hpp b/src/os/linux/vm/os_linux.hpp index 7c19517e2..0f0fa214a 100644 --- a/src/os/linux/vm/os_linux.hpp +++ b/src/os/linux/vm/os_linux.hpp @@ -287,7 +287,7 @@ public: }; -class PlatformEvent : public CHeapObj { +class PlatformEvent : public CHeapObj { private: double CachePad [4] ; // increase odds that _mutex is sole occupant of cache line volatile int _Event ; @@ -322,7 +322,7 @@ class PlatformEvent : public CHeapObj { void SetAssociation (Thread * a) { _Assoc = a ; } } ; -class PlatformParker : public CHeapObj { +class PlatformParker : public CHeapObj { protected: pthread_mutex_t _mutex [1] ; pthread_cond_t _cond [1] ; diff --git a/src/os/linux/vm/os_linux.inline.hpp b/src/os/linux/vm/os_linux.inline.hpp index 566c0ad31..c663c9b69 100644 --- a/src/os/linux/vm/os_linux.inline.hpp +++ b/src/os/linux/vm/os_linux.inline.hpp @@ -99,7 +99,7 @@ inline bool os::allocate_stack_guard_pages() { // On Linux, reservations are made on a page by page basis, nothing to do. -inline void os::split_reserved_memory(char *base, size_t size, +inline void os::pd_split_reserved_memory(char *base, size_t size, size_t split, bool realloc) { } diff --git a/src/os/linux/vm/perfMemory_linux.cpp b/src/os/linux/vm/perfMemory_linux.cpp index 1cd430cfb..8839aac6c 100644 --- a/src/os/linux/vm/perfMemory_linux.cpp +++ b/src/os/linux/vm/perfMemory_linux.cpp @@ -126,7 +126,7 @@ static void save_memory_to_file(char* addr, size_t size) { } } } - FREE_C_HEAP_ARRAY(char, destfile); + FREE_C_HEAP_ARRAY(char, destfile, mtInternal); } @@ -153,7 +153,7 @@ static char* get_user_tmp_dir(const char* user) { const char* tmpdir = os::get_temp_directory(); const char* perfdir = PERFDATA_NAME; size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3; - char* dirname = NEW_C_HEAP_ARRAY(char, nbytes); + char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); // construct the path name to user specific tmp directory snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user); @@ -246,7 +246,7 @@ static char* get_user_name(uid_t uid) { if (bufsize == -1) bufsize = 1024; - char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize); + char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal); // POSIX interface to getpwuid_r is used on LINUX struct passwd* p; @@ -278,14 +278,14 @@ static char* get_user_name(uid_t uid) { "pw_name zero length"); } } - FREE_C_HEAP_ARRAY(char, pwbuf); + FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal); return NULL; } - char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1); + char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal); strcpy(user_name, p->pw_name); - FREE_C_HEAP_ARRAY(char, pwbuf); + FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal); return user_name; } @@ -328,7 +328,7 @@ static char* get_user_name_slow(int vmid, TRAPS) { // to determine the user name for the process id. // struct dirent* dentry; - char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname)); + char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal); errno = 0; while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) { @@ -338,7 +338,7 @@ static char* get_user_name_slow(int vmid, TRAPS) { } char* usrdir_name = NEW_C_HEAP_ARRAY(char, - strlen(tmpdirname) + strlen(dentry->d_name) + 2); + strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal); strcpy(usrdir_name, tmpdirname); strcat(usrdir_name, "/"); strcat(usrdir_name, dentry->d_name); @@ -346,7 +346,7 @@ static char* get_user_name_slow(int vmid, TRAPS) { DIR* subdirp = os::opendir(usrdir_name); if (subdirp == NULL) { - FREE_C_HEAP_ARRAY(char, usrdir_name); + FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); continue; } @@ -357,13 +357,13 @@ static char* get_user_name_slow(int vmid, TRAPS) { // symlink can be exploited. // if (!is_directory_secure(usrdir_name)) { - FREE_C_HEAP_ARRAY(char, usrdir_name); + FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); os::closedir(subdirp); continue; } struct dirent* udentry; - char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name)); + char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal); errno = 0; while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) { @@ -372,7 +372,7 @@ static char* get_user_name_slow(int vmid, TRAPS) { int result; char* filename = NEW_C_HEAP_ARRAY(char, - strlen(usrdir_name) + strlen(udentry->d_name) + 2); + strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal); strcpy(filename, usrdir_name); strcat(filename, "/"); @@ -381,13 +381,13 @@ static char* get_user_name_slow(int vmid, TRAPS) { // don't follow symbolic links for the file RESTARTABLE(::lstat(filename, &statbuf), result); if (result == OS_ERR) { - FREE_C_HEAP_ARRAY(char, filename); + FREE_C_HEAP_ARRAY(char, filename, mtInternal); continue; } // skip over files that are not regular files. if (!S_ISREG(statbuf.st_mode)) { - FREE_C_HEAP_ARRAY(char, filename); + FREE_C_HEAP_ARRAY(char, filename, mtInternal); continue; } @@ -397,23 +397,23 @@ static char* get_user_name_slow(int vmid, TRAPS) { if (statbuf.st_ctime > oldest_ctime) { char* user = strchr(dentry->d_name, '_') + 1; - if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user); - oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1); + if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal); + oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal); strcpy(oldest_user, user); oldest_ctime = statbuf.st_ctime; } } - FREE_C_HEAP_ARRAY(char, filename); + FREE_C_HEAP_ARRAY(char, filename, mtInternal); } } os::closedir(subdirp); - FREE_C_HEAP_ARRAY(char, udbuf); - FREE_C_HEAP_ARRAY(char, usrdir_name); + FREE_C_HEAP_ARRAY(char, udbuf, mtInternal); + FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal); } os::closedir(tmpdirp); - FREE_C_HEAP_ARRAY(char, tdbuf); + FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal); return(oldest_user); } @@ -434,7 +434,7 @@ static char* get_sharedmem_filename(const char* dirname, int vmid) { // add 2 for the file separator and a null terminator. size_t nbytes = strlen(dirname) + UINT_CHARS + 2; - char* name = NEW_C_HEAP_ARRAY(char, nbytes); + char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); snprintf(name, nbytes, "%s/%d", dirname, vmid); return name; @@ -472,7 +472,7 @@ static void remove_file(const char* path) { static void remove_file(const char* dirname, const char* filename) { size_t nbytes = strlen(dirname) + strlen(filename) + 2; - char* path = NEW_C_HEAP_ARRAY(char, nbytes); + char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal); strcpy(path, dirname); strcat(path, "/"); @@ -480,7 +480,7 @@ static void remove_file(const char* dirname, const char* filename) { remove_file(path); - FREE_C_HEAP_ARRAY(char, path); + FREE_C_HEAP_ARRAY(char, path, mtInternal); } @@ -517,7 +517,7 @@ static void cleanup_sharedmem_resources(const char* dirname) { // opendir/readdir. // struct dirent* entry; - char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname)); + char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal); errno = 0; while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) { @@ -556,7 +556,7 @@ static void cleanup_sharedmem_resources(const char* dirname) { errno = 0; } os::closedir(dirp); - FREE_C_HEAP_ARRAY(char, dbuf); + FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); } // make the user specific temporary directory. Returns true if @@ -723,11 +723,11 @@ static char* mmap_create_shared(size_t size) { fd = create_sharedmem_resources(dirname, filename, size); - FREE_C_HEAP_ARRAY(char, user_name); - FREE_C_HEAP_ARRAY(char, dirname); + FREE_C_HEAP_ARRAY(char, user_name, mtInternal); + FREE_C_HEAP_ARRAY(char, dirname, mtInternal); if (fd == -1) { - FREE_C_HEAP_ARRAY(char, filename); + FREE_C_HEAP_ARRAY(char, filename, mtInternal); return NULL; } @@ -743,7 +743,7 @@ static char* mmap_create_shared(size_t size) { warning("mmap failed - %s\n", strerror(errno)); } remove_file(filename); - FREE_C_HEAP_ARRAY(char, filename); + FREE_C_HEAP_ARRAY(char, filename, mtInternal); return NULL; } @@ -869,7 +869,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor // store file, we don't follow them when attaching either. // if (!is_directory_secure(dirname)) { - FREE_C_HEAP_ARRAY(char, dirname); + FREE_C_HEAP_ARRAY(char, dirname, mtInternal); THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Process not found"); } @@ -884,9 +884,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor strcpy(rfilename, filename); // free the c heap resources that are no longer needed - if (luser != user) FREE_C_HEAP_ARRAY(char, luser); - FREE_C_HEAP_ARRAY(char, dirname); - FREE_C_HEAP_ARRAY(char, filename); + if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal); + FREE_C_HEAP_ARRAY(char, dirname, mtInternal); + FREE_C_HEAP_ARRAY(char, filename, mtInternal); // open the shared memory file for the give vmid fd = open_sharedmem_file(rfilename, file_flags, CHECK); -- cgit v1.2.3