hotspot/src/os/solaris/vm/os_solaris.cpp
changeset 18069 e6d4971c8650
parent 18025 b7bcf7497f93
child 18078 10417cf9967d
equal deleted inserted replaced
18025:b7bcf7497f93 18069:e6d4971c8650
  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 }