2791 //////////////////////////////////////////////////////////////////////////////// 2792 // Virtual Memory 2793 2794 static int page_size = -1; 2795 2796 // The mmap MAP_ALIGN flag is supported on Solaris 9 and later. init_2() will 2797 // clear this var if support is not available. 2798 static bool has_map_align = true; 2799 2800 int os::vm_page_size() { 2801 assert(page_size != -1, "must call os::init"); 2802 return page_size; 2803 } 2804 2805 // Solaris allocates memory by pages. 2806 int os::vm_allocation_granularity() { 2807 assert(page_size != -1, "must call os::init"); 2808 return page_size; 2809 } 2810 2811 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) { 2812 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2813 size_t size = bytes; 2814 char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot); 2815 if (res != NULL) { 2816 if (UseNUMAInterleaving) { 2817 numa_make_global(addr, bytes); 2818 } 2819 return true; 2820 } 2821 return false; 2822 } 2823 2824 bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint, 2825 bool exec) { 2826 if (commit_memory(addr, bytes, exec)) { 2827 if (UseMPSS && alignment_hint > (size_t)vm_page_size()) { 2828 // If the large page size has been set and the VM 2829 // is using large pages, use the large page size 2830 // if it is smaller than the alignment hint. This is 2831 // a case where the VM wants to use a larger alignment size 2832 // for its own reasons but still want to use large pages 2833 // (which is what matters to setting the mpss range. 2834 size_t page_size = 0; 2835 if (large_page_size() < alignment_hint) { 2836 assert(UseLargePages, "Expected to be here for large page use only"); 2837 page_size = large_page_size(); 2838 } else { 2839 // If the alignment hint is less than the large page 2840 // size, the VM wants a particular alignment (thus the hint) 2841 // for internal reasons. Try to set the mpss range using 2842 // the alignment_hint. 2843 page_size = alignment_hint; 2844 } 2845 // Since this is a hint, ignore any failures. 2846 (void)Solaris::set_mpss_range(addr, bytes, page_size); 2847 } 2848 return true; 2849 } 2850 return false; 2851 } 2852 2853 // Uncommit the pages in a specified region. 2854 void os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) { 2855 if (madvise(addr, bytes, MADV_FREE) < 0) { 2856 debug_only(warning("MADV_FREE failed.")); 2857 return; 2858 } 2859 } 2860 2861 bool os::pd_create_stack_guard_pages(char* addr, size_t size) { 2862 return os::commit_memory(addr, size); 2863 } 2864 2865 bool os::remove_stack_guard_pages(char* addr, size_t size) { 2866 return os::uncommit_memory(addr, size); 2867 } 2868 2869 // Change the page size in a given range. 2870 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { 2871 assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); 2872 assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned."); 2873 if (UseLargePages && UseMPSS) { 2874 Solaris::set_mpss_range(addr, bytes, alignment_hint); 2875 } 2876 } 2877 2878 // Tell the OS to make the range local to the first-touching LWP 2879 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { 2880 assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned."); 2881 if (madvise(addr, bytes, MADV_ACCESS_LWP) < 0) { 2882 debug_only(warning("MADV_ACCESS_LWP failed.")); | 2791 //////////////////////////////////////////////////////////////////////////////// 2792 // Virtual Memory 2793 2794 static int page_size = -1; 2795 2796 // The mmap MAP_ALIGN flag is supported on Solaris 9 and later. init_2() will 2797 // clear this var if support is not available. 2798 static bool has_map_align = true; 2799 2800 int os::vm_page_size() { 2801 assert(page_size != -1, "must call os::init"); 2802 return page_size; 2803 } 2804 2805 // Solaris allocates memory by pages. 2806 int os::vm_allocation_granularity() { 2807 assert(page_size != -1, "must call os::init"); 2808 return page_size; 2809 } 2810 2811 static bool recoverable_mmap_error(int err) { 2812 // See if the error is one we can let the caller handle. This 2813 // list of errno values comes from the Solaris mmap(2) man page. 2814 switch (err) { 2815 case EBADF: 2816 case EINVAL: 2817 case ENOTSUP: 2818 // let the caller deal with these errors 2819 return true; 2820 2821 default: 2822 // Any remaining errors on this OS can cause our reserved mapping 2823 // to be lost. That can cause confusion where different data 2824 // structures think they have the same memory mapped. The worst 2825 // scenario is if both the VM and a library think they have the 2826 // same memory mapped. 2827 return false; 2828 } 2829 } 2830 2831 static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec, 2832 int err) { 2833 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT 2834 ", %d) failed; error='%s' (errno=%d)", addr, bytes, exec, 2835 strerror(err), err); 2836 } 2837 2838 static void warn_fail_commit_memory(char* addr, size_t bytes, 2839 size_t alignment_hint, bool exec, 2840 int err) { 2841 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT 2842 ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, bytes, 2843 alignment_hint, exec, strerror(err), err); 2844 } 2845 2846 int os::Solaris::commit_memory_impl(char* addr, size_t bytes, bool exec) { 2847 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2848 size_t size = bytes; 2849 char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot); 2850 if (res != NULL) { 2851 if (UseNUMAInterleaving) { 2852 numa_make_global(addr, bytes); 2853 } 2854 return 0; 2855 } 2856 2857 int err = errno; // save errno from mmap() call in mmap_chunk() 2858 2859 if (!recoverable_mmap_error(err)) { 2860 warn_fail_commit_memory(addr, bytes, exec, err); 2861 vm_exit_out_of_memory(bytes, "committing reserved memory."); 2862 } 2863 2864 return err; 2865 } 2866 2867 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) { 2868 return Solaris::commit_memory_impl(addr, bytes, exec) == 0; 2869 } 2870 2871 void os::pd_commit_memory_or_exit(char* addr, size_t bytes, bool exec, 2872 const char* mesg) { 2873 assert(mesg != NULL, "mesg must be specified"); 2874 int err = os::Solaris::commit_memory_impl(addr, bytes, exec); 2875 if (err != 0) { 2876 // the caller wants all commit errors to exit with the specified mesg: 2877 warn_fail_commit_memory(addr, bytes, exec, err); 2878 vm_exit_out_of_memory(bytes, mesg); 2879 } 2880 } 2881 2882 int os::Solaris::commit_memory_impl(char* addr, size_t bytes, 2883 size_t alignment_hint, bool exec) { 2884 int err = Solaris::commit_memory_impl(addr, bytes, exec); 2885 if (err == 0) { 2886 if (UseMPSS && alignment_hint > (size_t)vm_page_size()) { 2887 // If the large page size has been set and the VM 2888 // is using large pages, use the large page size 2889 // if it is smaller than the alignment hint. This is 2890 // a case where the VM wants to use a larger alignment size 2891 // for its own reasons but still want to use large pages 2892 // (which is what matters to setting the mpss range. 2893 size_t page_size = 0; 2894 if (large_page_size() < alignment_hint) { 2895 assert(UseLargePages, "Expected to be here for large page use only"); 2896 page_size = large_page_size(); 2897 } else { 2898 // If the alignment hint is less than the large page 2899 // size, the VM wants a particular alignment (thus the hint) 2900 // for internal reasons. Try to set the mpss range using 2901 // the alignment_hint. 2902 page_size = alignment_hint; 2903 } 2904 // Since this is a hint, ignore any failures. 2905 (void)Solaris::set_mpss_range(addr, bytes, page_size); 2906 } 2907 } 2908 return err; 2909 } 2910 2911 bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint, 2912 bool exec) { 2913 return Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec) == 0; 2914 } 2915 2916 void os::pd_commit_memory_or_exit(char* addr, size_t bytes, 2917 size_t alignment_hint, bool exec, 2918 const char* mesg) { 2919 assert(mesg != NULL, "mesg must be specified"); 2920 int err = os::Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec); 2921 if (err != 0) { 2922 // the caller wants all commit errors to exit with the specified mesg: 2923 warn_fail_commit_memory(addr, bytes, alignment_hint, exec, err); 2924 vm_exit_out_of_memory(bytes, mesg); 2925 } 2926 } 2927 2928 // Uncommit the pages in a specified region. 2929 void os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) { 2930 if (madvise(addr, bytes, MADV_FREE) < 0) { 2931 debug_only(warning("MADV_FREE failed.")); 2932 return; 2933 } 2934 } 2935 2936 bool os::pd_create_stack_guard_pages(char* addr, size_t size) { 2937 return os::commit_memory(addr, size, !ExecMem); 2938 } 2939 2940 bool os::remove_stack_guard_pages(char* addr, size_t size) { 2941 return os::uncommit_memory(addr, size); 2942 } 2943 2944 // Change the page size in a given range. 2945 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { 2946 assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); 2947 assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned."); 2948 if (UseLargePages && UseMPSS) { 2949 Solaris::set_mpss_range(addr, bytes, alignment_hint); 2950 } 2951 } 2952 2953 // Tell the OS to make the range local to the first-touching LWP 2954 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { 2955 assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned."); 2956 if (madvise(addr, bytes, MADV_ACCESS_LWP) < 0) { 2957 debug_only(warning("MADV_ACCESS_LWP failed.")); |