Mercurial > hg > graal-compiler
comparison src/os/linux/vm/os_linux.cpp @ 3464:be4ca325525a
Merge.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 27 Jul 2011 17:32:44 -0700 |
parents | 0654ee04b214 97b64f73103b |
children | 04b9a2566eec |
comparison
equal
deleted
inserted
replaced
3239:7c4b4daac19b | 3464:be4ca325525a |
---|---|
2463 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, | 2463 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, |
2464 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); | 2464 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); |
2465 return res != (uintptr_t) MAP_FAILED; | 2465 return res != (uintptr_t) MAP_FAILED; |
2466 } | 2466 } |
2467 | 2467 |
2468 // Define MAP_HUGETLB here so we can build HotSpot on old systems. | |
2469 #ifndef MAP_HUGETLB | |
2470 #define MAP_HUGETLB 0x40000 | |
2471 #endif | |
2472 | |
2473 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems. | |
2474 #ifndef MADV_HUGEPAGE | |
2475 #define MADV_HUGEPAGE 14 | |
2476 #endif | |
2477 | |
2468 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, | 2478 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, |
2469 bool exec) { | 2479 bool exec) { |
2480 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { | |
2481 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; | |
2482 uintptr_t res = | |
2483 (uintptr_t) ::mmap(addr, size, prot, | |
2484 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB, | |
2485 -1, 0); | |
2486 return res != (uintptr_t) MAP_FAILED; | |
2487 } | |
2488 | |
2470 return commit_memory(addr, size, exec); | 2489 return commit_memory(addr, size, exec); |
2471 } | 2490 } |
2472 | 2491 |
2473 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { } | 2492 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { |
2493 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { | |
2494 // We don't check the return value: madvise(MADV_HUGEPAGE) may not | |
2495 // be supported or the memory may already be backed by huge pages. | |
2496 ::madvise(addr, bytes, MADV_HUGEPAGE); | |
2497 } | |
2498 } | |
2474 | 2499 |
2475 void os::free_memory(char *addr, size_t bytes) { | 2500 void os::free_memory(char *addr, size_t bytes) { |
2476 ::mmap(addr, bytes, PROT_READ | PROT_WRITE, | 2501 ::madvise(addr, bytes, MADV_DONTNEED); |
2477 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); | |
2478 } | 2502 } |
2479 | 2503 |
2480 void os::numa_make_global(char *addr, size_t bytes) { | 2504 void os::numa_make_global(char *addr, size_t bytes) { |
2481 Linux::numa_interleave_memory(addr, bytes); | 2505 Linux::numa_interleave_memory(addr, bytes); |
2482 } | 2506 } |
2808 return linux_mprotect(addr, size, PROT_NONE); | 2832 return linux_mprotect(addr, size, PROT_NONE); |
2809 } | 2833 } |
2810 | 2834 |
2811 bool os::unguard_memory(char* addr, size_t size) { | 2835 bool os::unguard_memory(char* addr, size_t size) { |
2812 return linux_mprotect(addr, size, PROT_READ|PROT_WRITE); | 2836 return linux_mprotect(addr, size, PROT_READ|PROT_WRITE); |
2837 } | |
2838 | |
2839 bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) { | |
2840 bool result = false; | |
2841 void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE, | |
2842 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB, | |
2843 -1, 0); | |
2844 | |
2845 if (p != (void *) -1) { | |
2846 // We don't know if this really is a huge page or not. | |
2847 FILE *fp = fopen("/proc/self/maps", "r"); | |
2848 if (fp) { | |
2849 while (!feof(fp)) { | |
2850 char chars[257]; | |
2851 long x = 0; | |
2852 if (fgets(chars, sizeof(chars), fp)) { | |
2853 if (sscanf(chars, "%lx-%*x", &x) == 1 | |
2854 && x == (long)p) { | |
2855 if (strstr (chars, "hugepage")) { | |
2856 result = true; | |
2857 break; | |
2858 } | |
2859 } | |
2860 } | |
2861 } | |
2862 fclose(fp); | |
2863 } | |
2864 munmap (p, page_size); | |
2865 if (result) | |
2866 return true; | |
2867 } | |
2868 | |
2869 if (warn) { | |
2870 warning("HugeTLBFS is not supported by the operating system."); | |
2871 } | |
2872 | |
2873 return result; | |
2813 } | 2874 } |
2814 | 2875 |
2815 /* | 2876 /* |
2816 * Set the coredump_filter bits to include largepages in core dump (bit 6) | 2877 * Set the coredump_filter bits to include largepages in core dump (bit 6) |
2817 * | 2878 * |
2851 | 2912 |
2852 // Large page support | 2913 // Large page support |
2853 | 2914 |
2854 static size_t _large_page_size = 0; | 2915 static size_t _large_page_size = 0; |
2855 | 2916 |
2856 bool os::large_page_init() { | 2917 void os::large_page_init() { |
2857 if (!UseLargePages) return false; | 2918 if (!UseLargePages) { |
2919 UseHugeTLBFS = false; | |
2920 UseSHM = false; | |
2921 return; | |
2922 } | |
2923 | |
2924 if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) { | |
2925 // If UseLargePages is specified on the command line try both methods, | |
2926 // if it's default, then try only HugeTLBFS. | |
2927 if (FLAG_IS_DEFAULT(UseLargePages)) { | |
2928 UseHugeTLBFS = true; | |
2929 } else { | |
2930 UseHugeTLBFS = UseSHM = true; | |
2931 } | |
2932 } | |
2858 | 2933 |
2859 if (LargePageSizeInBytes) { | 2934 if (LargePageSizeInBytes) { |
2860 _large_page_size = LargePageSizeInBytes; | 2935 _large_page_size = LargePageSizeInBytes; |
2861 } else { | 2936 } else { |
2862 // large_page_size on Linux is used to round up heap size. x86 uses either | 2937 // large_page_size on Linux is used to round up heap size. x86 uses either |
2897 } | 2972 } |
2898 fclose(fp); | 2973 fclose(fp); |
2899 } | 2974 } |
2900 } | 2975 } |
2901 | 2976 |
2977 // print a warning if any large page related flag is specified on command line | |
2978 bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS); | |
2979 | |
2902 const size_t default_page_size = (size_t)Linux::page_size(); | 2980 const size_t default_page_size = (size_t)Linux::page_size(); |
2903 if (_large_page_size > default_page_size) { | 2981 if (_large_page_size > default_page_size) { |
2904 _page_sizes[0] = _large_page_size; | 2982 _page_sizes[0] = _large_page_size; |
2905 _page_sizes[1] = default_page_size; | 2983 _page_sizes[1] = default_page_size; |
2906 _page_sizes[2] = 0; | 2984 _page_sizes[2] = 0; |
2907 } | 2985 } |
2986 UseHugeTLBFS = UseHugeTLBFS && | |
2987 Linux::hugetlbfs_sanity_check(warn_on_failure, _large_page_size); | |
2988 | |
2989 if (UseHugeTLBFS) | |
2990 UseSHM = false; | |
2991 | |
2992 UseLargePages = UseHugeTLBFS || UseSHM; | |
2908 | 2993 |
2909 set_coredump_filter(); | 2994 set_coredump_filter(); |
2910 | |
2911 // Large page support is available on 2.6 or newer kernel, some vendors | |
2912 // (e.g. Redhat) have backported it to their 2.4 based distributions. | |
2913 // We optimistically assume the support is available. If later it turns out | |
2914 // not true, VM will automatically switch to use regular page size. | |
2915 return true; | |
2916 } | 2995 } |
2917 | 2996 |
2918 #ifndef SHM_HUGETLB | 2997 #ifndef SHM_HUGETLB |
2919 #define SHM_HUGETLB 04000 | 2998 #define SHM_HUGETLB 04000 |
2920 #endif | 2999 #endif |
2921 | 3000 |
2922 char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) { | 3001 char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) { |
2923 // "exec" is passed in but not used. Creating the shared image for | 3002 // "exec" is passed in but not used. Creating the shared image for |
2924 // the code cache doesn't have an SHM_X executable permission to check. | 3003 // the code cache doesn't have an SHM_X executable permission to check. |
2925 assert(UseLargePages, "only for large pages"); | 3004 assert(UseLargePages && UseSHM, "only for SHM large pages"); |
2926 | 3005 |
2927 key_t key = IPC_PRIVATE; | 3006 key_t key = IPC_PRIVATE; |
2928 char *addr; | 3007 char *addr; |
2929 | 3008 |
2930 bool warn_on_failure = UseLargePages && | 3009 bool warn_on_failure = UseLargePages && |
2987 | 3066 |
2988 size_t os::large_page_size() { | 3067 size_t os::large_page_size() { |
2989 return _large_page_size; | 3068 return _large_page_size; |
2990 } | 3069 } |
2991 | 3070 |
2992 // Linux does not support anonymous mmap with large page memory. The only way | 3071 // HugeTLBFS allows application to commit large page memory on demand; |
2993 // to reserve large page memory without file backing is through SysV shared | 3072 // with SysV SHM the entire memory region must be allocated as shared |
2994 // memory API. The entire memory region is committed and pinned upfront. | 3073 // memory. |
2995 // Hopefully this will change in the future... | |
2996 bool os::can_commit_large_page_memory() { | 3074 bool os::can_commit_large_page_memory() { |
2997 return false; | 3075 return UseHugeTLBFS; |
2998 } | 3076 } |
2999 | 3077 |
3000 bool os::can_execute_large_page_memory() { | 3078 bool os::can_execute_large_page_memory() { |
3001 return false; | 3079 return UseHugeTLBFS; |
3002 } | 3080 } |
3003 | 3081 |
3004 // Reserve memory at an arbitrary address, only if that area is | 3082 // Reserve memory at an arbitrary address, only if that area is |
3005 // available (and not reserved for something else). | 3083 // available (and not reserved for something else). |
3006 | 3084 |
4043 if(Verbose && PrintMiscellaneous) | 4121 if(Verbose && PrintMiscellaneous) |
4044 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); | 4122 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); |
4045 #endif | 4123 #endif |
4046 } | 4124 } |
4047 | 4125 |
4048 FLAG_SET_DEFAULT(UseLargePages, os::large_page_init()); | 4126 os::large_page_init(); |
4049 | 4127 |
4050 // initialize suspend/resume support - must do this before signal_sets_init() | 4128 // initialize suspend/resume support - must do this before signal_sets_init() |
4051 if (SR_initialize() != 0) { | 4129 if (SR_initialize() != 0) { |
4052 perror("SR_initialize failed"); | 4130 perror("SR_initialize failed"); |
4053 return JNI_ERR; | 4131 return JNI_ERR; |
4092 if (!Linux::libnuma_init()) { | 4170 if (!Linux::libnuma_init()) { |
4093 UseNUMA = false; | 4171 UseNUMA = false; |
4094 } else { | 4172 } else { |
4095 if ((Linux::numa_max_node() < 1)) { | 4173 if ((Linux::numa_max_node() < 1)) { |
4096 // There's only one node(they start from 0), disable NUMA. | 4174 // There's only one node(they start from 0), disable NUMA. |
4175 UseNUMA = false; | |
4176 } | |
4177 } | |
4178 // With SHM large pages we cannot uncommit a page, so there's not way | |
4179 // we can make the adaptive lgrp chunk resizing work. If the user specified | |
4180 // both UseNUMA and UseLargePages (or UseSHM) on the command line - warn and | |
4181 // disable adaptive resizing. | |
4182 if (UseNUMA && UseLargePages && UseSHM) { | |
4183 if (!FLAG_IS_DEFAULT(UseNUMA)) { | |
4184 if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseSHM)) { | |
4185 UseLargePages = false; | |
4186 } else { | |
4187 warning("UseNUMA is not fully compatible with SHM large pages, disabling adaptive resizing"); | |
4188 UseAdaptiveSizePolicy = false; | |
4189 UseAdaptiveNUMAChunkSizing = false; | |
4190 } | |
4191 } else { | |
4097 UseNUMA = false; | 4192 UseNUMA = false; |
4098 } | 4193 } |
4099 } | 4194 } |
4100 if (!UseNUMA && ForceNUMA) { | 4195 if (!UseNUMA && ForceNUMA) { |
4101 UseNUMA = true; | 4196 UseNUMA = true; |