comparison src/os/solaris/vm/os_solaris.cpp @ 10969:a837fa3d3f86

8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint Summary: Detect mmap() commit failures in Linux and Solaris os::commit_memory() impls and call vm_exit_out_of_memory(). Add os::commit_memory_or_exit(). Also tidy up some NMT accounting and some mmap() return value checking. Reviewed-by: zgu, stefank, dholmes, dsamersoff
author dcubed
date Thu, 13 Jun 2013 11:16:38 -0700
parents f2110083203d
children e95fc50106cf
comparison
equal deleted inserted replaced
10405:f2110083203d 10969:a837fa3d3f86
2782 int os::vm_allocation_granularity() { 2782 int os::vm_allocation_granularity() {
2783 assert(page_size != -1, "must call os::init"); 2783 assert(page_size != -1, "must call os::init");
2784 return page_size; 2784 return page_size;
2785 } 2785 }
2786 2786
2787 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) { 2787 static bool recoverable_mmap_error(int err) {
2788 // See if the error is one we can let the caller handle. This
2789 // list of errno values comes from the Solaris mmap(2) man page.
2790 switch (err) {
2791 case EBADF:
2792 case EINVAL:
2793 case ENOTSUP:
2794 // let the caller deal with these errors
2795 return true;
2796
2797 default:
2798 // Any remaining errors on this OS can cause our reserved mapping
2799 // to be lost. That can cause confusion where different data
2800 // structures think they have the same memory mapped. The worst
2801 // scenario is if both the VM and a library think they have the
2802 // same memory mapped.
2803 return false;
2804 }
2805 }
2806
2807 static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec,
2808 int err) {
2809 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
2810 ", %d) failed; error='%s' (errno=%d)", addr, bytes, exec,
2811 strerror(err), err);
2812 }
2813
2814 static void warn_fail_commit_memory(char* addr, size_t bytes,
2815 size_t alignment_hint, bool exec,
2816 int err) {
2817 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
2818 ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, bytes,
2819 alignment_hint, exec, strerror(err), err);
2820 }
2821
2822 int os::Solaris::commit_memory_impl(char* addr, size_t bytes, bool exec) {
2788 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2823 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
2789 size_t size = bytes; 2824 size_t size = bytes;
2790 char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot); 2825 char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot);
2791 if (res != NULL) { 2826 if (res != NULL) {
2792 if (UseNUMAInterleaving) { 2827 if (UseNUMAInterleaving) {
2793 numa_make_global(addr, bytes); 2828 numa_make_global(addr, bytes);
2794 } 2829 }
2795 return true; 2830 return 0;
2796 } 2831 }
2797 return false; 2832
2798 } 2833 int err = errno; // save errno from mmap() call in mmap_chunk()
2799 2834
2800 bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint, 2835 if (!recoverable_mmap_error(err)) {
2801 bool exec) { 2836 warn_fail_commit_memory(addr, bytes, exec, err);
2802 if (commit_memory(addr, bytes, exec)) { 2837 vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "committing reserved memory.");
2838 }
2839
2840 return err;
2841 }
2842
2843 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
2844 return Solaris::commit_memory_impl(addr, bytes, exec) == 0;
2845 }
2846
2847 void os::pd_commit_memory_or_exit(char* addr, size_t bytes, bool exec,
2848 const char* mesg) {
2849 assert(mesg != NULL, "mesg must be specified");
2850 int err = os::Solaris::commit_memory_impl(addr, bytes, exec);
2851 if (err != 0) {
2852 // the caller wants all commit errors to exit with the specified mesg:
2853 warn_fail_commit_memory(addr, bytes, exec, err);
2854 vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg);
2855 }
2856 }
2857
2858 int os::Solaris::commit_memory_impl(char* addr, size_t bytes,
2859 size_t alignment_hint, bool exec) {
2860 int err = Solaris::commit_memory_impl(addr, bytes, exec);
2861 if (err == 0) {
2803 if (UseMPSS && alignment_hint > (size_t)vm_page_size()) { 2862 if (UseMPSS && alignment_hint > (size_t)vm_page_size()) {
2804 // If the large page size has been set and the VM 2863 // If the large page size has been set and the VM
2805 // is using large pages, use the large page size 2864 // is using large pages, use the large page size
2806 // if it is smaller than the alignment hint. This is 2865 // if it is smaller than the alignment hint. This is
2807 // a case where the VM wants to use a larger alignment size 2866 // a case where the VM wants to use a larger alignment size
2819 page_size = alignment_hint; 2878 page_size = alignment_hint;
2820 } 2879 }
2821 // Since this is a hint, ignore any failures. 2880 // Since this is a hint, ignore any failures.
2822 (void)Solaris::set_mpss_range(addr, bytes, page_size); 2881 (void)Solaris::set_mpss_range(addr, bytes, page_size);
2823 } 2882 }
2824 return true; 2883 }
2825 } 2884 return err;
2826 return false; 2885 }
2886
2887 bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint,
2888 bool exec) {
2889 return Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec) == 0;
2890 }
2891
2892 void os::pd_commit_memory_or_exit(char* addr, size_t bytes,
2893 size_t alignment_hint, bool exec,
2894 const char* mesg) {
2895 assert(mesg != NULL, "mesg must be specified");
2896 int err = os::Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec);
2897 if (err != 0) {
2898 // the caller wants all commit errors to exit with the specified mesg:
2899 warn_fail_commit_memory(addr, bytes, alignment_hint, exec, err);
2900 vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg);
2901 }
2827 } 2902 }
2828 2903
2829 // Uncommit the pages in a specified region. 2904 // Uncommit the pages in a specified region.
2830 void os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) { 2905 void os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) {
2831 if (madvise(addr, bytes, MADV_FREE) < 0) { 2906 if (madvise(addr, bytes, MADV_FREE) < 0) {
2833 return; 2908 return;
2834 } 2909 }
2835 } 2910 }
2836 2911
2837 bool os::pd_create_stack_guard_pages(char* addr, size_t size) { 2912 bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
2838 return os::commit_memory(addr, size); 2913 return os::commit_memory(addr, size, !ExecMem);
2839 } 2914 }
2840 2915
2841 bool os::remove_stack_guard_pages(char* addr, size_t size) { 2916 bool os::remove_stack_guard_pages(char* addr, size_t size) {
2842 return os::uncommit_memory(addr, size); 2917 return os::uncommit_memory(addr, size);
2843 } 2918 }