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) { |