comparison src/os/bsd/vm/os_bsd.cpp @ 6197:d2a62e0f25eb

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
author zgu
date Thu, 28 Jun 2012 17:03:16 -0400
parents 7432b9db36ff
children 65906dc96aa1
comparison
equal deleted inserted replaced
6174:74533f63b116 6197:d2a62e0f25eb
438 // 438 //
439 // Important note: if the location of libjvm.so changes this 439 // Important note: if the location of libjvm.so changes this
440 // code needs to be changed accordingly. 440 // code needs to be changed accordingly.
441 441
442 // The next few definitions allow the code to be verbatim: 442 // The next few definitions allow the code to be verbatim:
443 #define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n)) 443 #define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal)
444 #define getenv(n) ::getenv(n) 444 #define getenv(n) ::getenv(n)
445 445
446 /* 446 /*
447 * See ld(1): 447 * See ld(1):
448 * The linker uses the following search paths to locate required 448 * The linker uses the following search paths to locate required
1911 } 1911 }
1912 } 1912 }
1913 // release the storage 1913 // release the storage
1914 for (int i = 0 ; i < n ; i++) { 1914 for (int i = 0 ; i < n ; i++) {
1915 if (pelements[i] != NULL) { 1915 if (pelements[i] != NULL) {
1916 FREE_C_HEAP_ARRAY(char, pelements[i]); 1916 FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
1917 } 1917 }
1918 } 1918 }
1919 if (pelements != NULL) { 1919 if (pelements != NULL) {
1920 FREE_C_HEAP_ARRAY(char*, pelements); 1920 FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
1921 } 1921 }
1922 } else { 1922 } else {
1923 snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname); 1923 snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname);
1924 } 1924 }
1925 } 1925 }
2764 2764
2765 // NOTE: Bsd kernel does not really reserve the pages for us. 2765 // NOTE: Bsd kernel does not really reserve the pages for us.
2766 // All it does is to check if there are enough free pages 2766 // All it does is to check if there are enough free pages
2767 // left at the time of mmap(). This could be a potential 2767 // left at the time of mmap(). This could be a potential
2768 // problem. 2768 // problem.
2769 bool os::commit_memory(char* addr, size_t size, bool exec) { 2769 bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
2770 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2770 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
2771 #ifdef __OpenBSD__ 2771 #ifdef __OpenBSD__
2772 // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD 2772 // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
2773 return ::mprotect(addr, size, prot) == 0; 2773 return ::mprotect(addr, size, prot) == 0;
2774 #else 2774 #else
2788 #ifndef MADV_HUGEPAGE 2788 #ifndef MADV_HUGEPAGE
2789 #define MADV_HUGEPAGE 14 2789 #define MADV_HUGEPAGE 14
2790 #endif 2790 #endif
2791 #endif 2791 #endif
2792 2792
2793 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, 2793 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
2794 bool exec) { 2794 bool exec) {
2795 #ifndef _ALLBSD_SOURCE 2795 #ifndef _ALLBSD_SOURCE
2796 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { 2796 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
2797 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2797 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
2798 uintptr_t res = 2798 uintptr_t res =
2804 #endif 2804 #endif
2805 2805
2806 return commit_memory(addr, size, exec); 2806 return commit_memory(addr, size, exec);
2807 } 2807 }
2808 2808
2809 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { 2809 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
2810 #ifndef _ALLBSD_SOURCE 2810 #ifndef _ALLBSD_SOURCE
2811 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { 2811 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
2812 // We don't check the return value: madvise(MADV_HUGEPAGE) may not 2812 // We don't check the return value: madvise(MADV_HUGEPAGE) may not
2813 // be supported or the memory may already be backed by huge pages. 2813 // be supported or the memory may already be backed by huge pages.
2814 ::madvise(addr, bytes, MADV_HUGEPAGE); 2814 ::madvise(addr, bytes, MADV_HUGEPAGE);
2815 } 2815 }
2816 #endif 2816 #endif
2817 } 2817 }
2818 2818
2819 void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) { 2819 void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {
2820 ::madvise(addr, bytes, MADV_DONTNEED); 2820 ::madvise(addr, bytes, MADV_DONTNEED);
2821 } 2821 }
2822 2822
2823 void os::numa_make_global(char *addr, size_t bytes) { 2823 void os::numa_make_global(char *addr, size_t bytes) {
2824 } 2824 }
2956 os::Bsd::numa_tonode_memory_func_t os::Bsd::_numa_tonode_memory; 2956 os::Bsd::numa_tonode_memory_func_t os::Bsd::_numa_tonode_memory;
2957 os::Bsd::numa_interleave_memory_func_t os::Bsd::_numa_interleave_memory; 2957 os::Bsd::numa_interleave_memory_func_t os::Bsd::_numa_interleave_memory;
2958 unsigned long* os::Bsd::_numa_all_nodes; 2958 unsigned long* os::Bsd::_numa_all_nodes;
2959 #endif 2959 #endif
2960 2960
2961 bool os::uncommit_memory(char* addr, size_t size) { 2961 bool os::pd_uncommit_memory(char* addr, size_t size) {
2962 #ifdef __OpenBSD__ 2962 #ifdef __OpenBSD__
2963 // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD 2963 // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
2964 return ::mprotect(addr, size, PROT_NONE) == 0; 2964 return ::mprotect(addr, size, PROT_NONE) == 0;
2965 #else 2965 #else
2966 uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE, 2966 uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
2967 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); 2967 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
2968 return res != (uintptr_t) MAP_FAILED; 2968 return res != (uintptr_t) MAP_FAILED;
2969 #endif 2969 #endif
2970 } 2970 }
2971 2971
2972 bool os::create_stack_guard_pages(char* addr, size_t size) { 2972 bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
2973 return os::commit_memory(addr, size); 2973 return os::commit_memory(addr, size);
2974 } 2974 }
2975 2975
2976 // If this is a growable mapping, remove the guard pages entirely by 2976 // If this is a growable mapping, remove the guard pages entirely by
2977 // munmap()ping them. If not, just call uncommit_memory(). 2977 // munmap()ping them. If not, just call uncommit_memory().
3021 // 3021 //
3022 static int anon_munmap(char * addr, size_t size) { 3022 static int anon_munmap(char * addr, size_t size) {
3023 return ::munmap(addr, size) == 0; 3023 return ::munmap(addr, size) == 0;
3024 } 3024 }
3025 3025
3026 char* os::reserve_memory(size_t bytes, char* requested_addr, 3026 char* os::pd_reserve_memory(size_t bytes, char* requested_addr,
3027 size_t alignment_hint) { 3027 size_t alignment_hint) {
3028 return anon_mmap(requested_addr, bytes, (requested_addr != NULL)); 3028 return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
3029 } 3029 }
3030 3030
3031 bool os::release_memory(char* addr, size_t size) { 3031 bool os::pd_release_memory(char* addr, size_t size) {
3032 return anon_munmap(addr, size); 3032 return anon_munmap(addr, size);
3033 } 3033 }
3034 3034
3035 static address highest_vm_reserved_address() { 3035 static address highest_vm_reserved_address() {
3036 return _highest_vm_reserved_address; 3036 return _highest_vm_reserved_address;
3329 } 3329 }
3330 3330
3331 // Reserve memory at an arbitrary address, only if that area is 3331 // Reserve memory at an arbitrary address, only if that area is
3332 // available (and not reserved for something else). 3332 // available (and not reserved for something else).
3333 3333
3334 char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) { 3334 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
3335 const int max_tries = 10; 3335 const int max_tries = 10;
3336 char* base[max_tries]; 3336 char* base[max_tries];
3337 size_t size[max_tries]; 3337 size_t size[max_tries];
3338 const size_t gap = 0x000000; 3338 const size_t gap = 0x000000;
3339 3339
4985 4985
4986 return (ret == OS_ERR) ? 0 : 1; 4986 return (ret == OS_ERR) ? 0 : 1;
4987 } 4987 }
4988 4988
4989 // Map a block of memory. 4989 // Map a block of memory.
4990 char* os::map_memory(int fd, const char* file_name, size_t file_offset, 4990 char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
4991 char *addr, size_t bytes, bool read_only, 4991 char *addr, size_t bytes, bool read_only,
4992 bool allow_exec) { 4992 bool allow_exec) {
4993 int prot; 4993 int prot;
4994 int flags; 4994 int flags;
4995 4995
5017 return mapped_address; 5017 return mapped_address;
5018 } 5018 }
5019 5019
5020 5020
5021 // Remap a block of memory. 5021 // Remap a block of memory.
5022 char* os::remap_memory(int fd, const char* file_name, size_t file_offset, 5022 char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
5023 char *addr, size_t bytes, bool read_only, 5023 char *addr, size_t bytes, bool read_only,
5024 bool allow_exec) { 5024 bool allow_exec) {
5025 // same as map_memory() on this OS 5025 // same as map_memory() on this OS
5026 return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only, 5026 return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
5027 allow_exec); 5027 allow_exec);
5028 } 5028 }
5029 5029
5030 5030
5031 // Unmap a block of memory. 5031 // Unmap a block of memory.
5032 bool os::unmap_memory(char* addr, size_t bytes) { 5032 bool os::pd_unmap_memory(char* addr, size_t bytes) {
5033 return munmap(addr, bytes) == 0; 5033 return munmap(addr, bytes) == 0;
5034 } 5034 }
5035 5035
5036 #ifndef _ALLBSD_SOURCE 5036 #ifndef _ALLBSD_SOURCE
5037 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time); 5037 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time);