< prev index next >

src/os/solaris/vm/os_solaris.cpp

Print this page




 218   } else {
 219     guarantee(os::Solaris::_main_stack_base != NULL, "Attempt to use null cached stack base");
 220     return os::Solaris::_main_stack_base;
 221   }
 222 }
 223 
 224 size_t os::current_stack_size() {
 225   size_t size;
 226 
 227   int r = thr_main();
 228   guarantee(r == 0 || r == 1, "CR6501650 or CR6493689");
 229   if (!r) {
 230     size = get_stack_info().ss_size;
 231   } else {
 232     struct rlimit limits;
 233     getrlimit(RLIMIT_STACK, &limits);
 234     size = adjust_stack_size(os::Solaris::_main_stack_base, (size_t)limits.rlim_cur);
 235   }
 236   // base may not be page aligned
 237   address base = current_stack_base();
 238   address bottom = align_ptr_up(base - size, os::vm_page_size());;
 239   return (size_t)(base - bottom);
 240 }
 241 
 242 struct tm* os::localtime_pd(const time_t* clock, struct tm*  res) {
 243   return localtime_r(clock, res);
 244 }
 245 
 246 void os::Solaris::try_enable_extended_io() {
 247   typedef int (*enable_extended_FILE_stdio_t)(int, int);
 248 
 249   if (!UseExtendedFileIO) {
 250     return;
 251   }
 252 
 253   enable_extended_FILE_stdio_t enabler =
 254     (enable_extended_FILE_stdio_t) dlsym(RTLD_DEFAULT,
 255                                          "enable_extended_FILE_stdio");
 256   if (enabler) {
 257     enabler(-1, -1);
 258   }


1093 
1094 
1095 // First crack at OS-specific initialization, from inside the new thread.
1096 void os::initialize_thread(Thread* thr) {
1097   int r = thr_main();
1098   guarantee(r == 0 || r == 1, "CR6501650 or CR6493689");
1099   if (r) {
1100     JavaThread* jt = (JavaThread *)thr;
1101     assert(jt != NULL, "Sanity check");
1102     size_t stack_size;
1103     address base = jt->stack_base();
1104     if (Arguments::created_by_java_launcher()) {
1105       // Use 2MB to allow for Solaris 7 64 bit mode.
1106       stack_size = JavaThread::stack_size_at_create() == 0
1107         ? 2048*K : JavaThread::stack_size_at_create();
1108 
1109       // There are rare cases when we may have already used more than
1110       // the basic stack size allotment before this method is invoked.
1111       // Attempt to allow for a normally sized java_stack.
1112       size_t current_stack_offset = (size_t)(base - (address)&stack_size);
1113       stack_size += ReservedSpace::page_align_size_down(current_stack_offset);
1114     } else {
1115       // 6269555: If we were not created by a Java launcher, i.e. if we are
1116       // running embedded in a native application, treat the primordial thread
1117       // as much like a native attached thread as possible.  This means using
1118       // the current stack size from thr_stksegment(), unless it is too large
1119       // to reliably setup guard pages.  A reasonable max size is 8MB.
1120       size_t current_size = current_stack_size();
1121       // This should never happen, but just in case....
1122       if (current_size == 0) current_size = 2 * K * K;
1123       stack_size = current_size > (8 * K * K) ? (8 * K * K) : current_size;
1124     }
1125     address bottom = align_ptr_up(base - stack_size, os::vm_page_size());;
1126     stack_size = (size_t)(base - bottom);
1127 
1128     assert(stack_size > 0, "Stack size calculation problem");
1129 
1130     if (stack_size > jt->stack_size()) {
1131 #ifndef PRODUCT
1132       struct rlimit limits;
1133       getrlimit(RLIMIT_STACK, &limits);
1134       size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur);
1135       assert(size >= jt->stack_size(), "Stack size problem in main thread");
1136 #endif
1137       tty->print_cr("Stack size of %d Kb exceeds current limit of %d Kb.\n"
1138                     "(Stack sizes are rounded up to a multiple of the system page size.)\n"
1139                     "See limit(1) to increase the stack size limit.",
1140                     stack_size / K, jt->stack_size() / K);
1141       vm_exit(1);
1142     }
1143     assert(jt->stack_size() >= stack_size,
1144            "Attempt to map more stack than was allocated");
1145     jt->set_stack_size(stack_size);


2314 
2315   return err;
2316 }
2317 
2318 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
2319   return Solaris::commit_memory_impl(addr, bytes, exec) == 0;
2320 }
2321 
2322 void os::pd_commit_memory_or_exit(char* addr, size_t bytes, bool exec,
2323                                   const char* mesg) {
2324   assert(mesg != NULL, "mesg must be specified");
2325   int err = os::Solaris::commit_memory_impl(addr, bytes, exec);
2326   if (err != 0) {
2327     // the caller wants all commit errors to exit with the specified mesg:
2328     warn_fail_commit_memory(addr, bytes, exec, err);
2329     vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "%s", mesg);
2330   }
2331 }
2332 
2333 size_t os::Solaris::page_size_for_alignment(size_t alignment) {
2334   assert(is_size_aligned(alignment, (size_t) vm_page_size()),
2335          SIZE_FORMAT " is not aligned to " SIZE_FORMAT,
2336          alignment, (size_t) vm_page_size());
2337 
2338   for (int i = 0; _page_sizes[i] != 0; i++) {
2339     if (is_size_aligned(alignment, _page_sizes[i])) {
2340       return _page_sizes[i];
2341     }
2342   }
2343 
2344   return (size_t) vm_page_size();
2345 }
2346 
2347 int os::Solaris::commit_memory_impl(char* addr, size_t bytes,
2348                                     size_t alignment_hint, bool exec) {
2349   int err = Solaris::commit_memory_impl(addr, bytes, exec);
2350   if (err == 0 && UseLargePages && alignment_hint > 0) {
2351     assert(is_size_aligned(bytes, alignment_hint),
2352            SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, alignment_hint);
2353 
2354     // The syscall memcntl requires an exact page size (see man memcntl for details).
2355     size_t page_size = page_size_for_alignment(alignment_hint);
2356     if (page_size > (size_t) vm_page_size()) {
2357       (void)Solaris::setup_large_pages(addr, bytes, page_size);
2358     }
2359   }
2360   return err;
2361 }
2362 
2363 bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint,
2364                           bool exec) {
2365   return Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec) == 0;
2366 }
2367 
2368 void os::pd_commit_memory_or_exit(char* addr, size_t bytes,
2369                                   size_t alignment_hint, bool exec,
2370                                   const char* mesg) {
2371   assert(mesg != NULL, "mesg must be specified");


2748     }
2749   }
2750 
2751   // Give back the unused reserved pieces.
2752 
2753   for (int j = 0; j < i; ++j) {
2754     if (base[j] != NULL) {
2755       unmap_memory(base[j], size[j]);
2756     }
2757   }
2758 
2759   return (i < max_tries) ? requested_addr : NULL;
2760 }
2761 
2762 bool os::pd_release_memory(char* addr, size_t bytes) {
2763   size_t size = bytes;
2764   return munmap(addr, size) == 0;
2765 }
2766 
2767 static bool solaris_mprotect(char* addr, size_t bytes, int prot) {
2768   assert(addr == (char*)align_size_down((uintptr_t)addr, os::vm_page_size()),
2769          "addr must be page aligned");
2770   int retVal = mprotect(addr, bytes, prot);
2771   return retVal == 0;
2772 }
2773 
2774 // Protect memory (Used to pass readonly pages through
2775 // JNI GetArray<type>Elements with empty arrays.)
2776 // Also, used for serialization page and for compressed oops null pointer
2777 // checking.
2778 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
2779                         bool is_committed) {
2780   unsigned int p = 0;
2781   switch (prot) {
2782   case MEM_PROT_NONE: p = PROT_NONE; break;
2783   case MEM_PROT_READ: p = PROT_READ; break;
2784   case MEM_PROT_RW:   p = PROT_READ|PROT_WRITE; break;
2785   case MEM_PROT_RWX:  p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
2786   default:
2787     ShouldNotReachHere();
2788   }


2885   if (UseLargePages) {
2886     // print a warning if any large page related flag is specified on command line
2887     bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages)        ||
2888                            !FLAG_IS_DEFAULT(LargePageSizeInBytes);
2889 
2890     UseLargePages = Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size);
2891   }
2892 }
2893 
2894 bool os::Solaris::is_valid_page_size(size_t bytes) {
2895   for (int i = 0; _page_sizes[i] != 0; i++) {
2896     if (_page_sizes[i] == bytes) {
2897       return true;
2898     }
2899   }
2900   return false;
2901 }
2902 
2903 bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) {
2904   assert(is_valid_page_size(align), SIZE_FORMAT " is not a valid page size", align);
2905   assert(is_ptr_aligned((void*) start, align),
2906          PTR_FORMAT " is not aligned to " SIZE_FORMAT, p2i((void*) start), align);
2907   assert(is_size_aligned(bytes, align),
2908          SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, align);
2909 
2910   // Signal to OS that we want large pages for addresses
2911   // from addr, addr + bytes
2912   struct memcntl_mha mpss_struct;
2913   mpss_struct.mha_cmd = MHA_MAPSIZE_VA;
2914   mpss_struct.mha_pagesize = align;
2915   mpss_struct.mha_flags = 0;
2916   // Upon successful completion, memcntl() returns 0
2917   if (memcntl(start, bytes, MC_HAT_ADVISE, (caddr_t) &mpss_struct, 0, 0)) {
2918     debug_only(warning("Attempt to use MPSS failed."));
2919     return false;
2920   }
2921   return true;
2922 }
2923 
2924 char* os::reserve_memory_special(size_t size, size_t alignment, char* addr, bool exec) {
2925   fatal("os::reserve_memory_special should not be called on Solaris.");
2926   return NULL;
2927 }




 218   } else {
 219     guarantee(os::Solaris::_main_stack_base != NULL, "Attempt to use null cached stack base");
 220     return os::Solaris::_main_stack_base;
 221   }
 222 }
 223 
 224 size_t os::current_stack_size() {
 225   size_t size;
 226 
 227   int r = thr_main();
 228   guarantee(r == 0 || r == 1, "CR6501650 or CR6493689");
 229   if (!r) {
 230     size = get_stack_info().ss_size;
 231   } else {
 232     struct rlimit limits;
 233     getrlimit(RLIMIT_STACK, &limits);
 234     size = adjust_stack_size(os::Solaris::_main_stack_base, (size_t)limits.rlim_cur);
 235   }
 236   // base may not be page aligned
 237   address base = current_stack_base();
 238   address bottom = align_up(base - size, os::vm_page_size());;
 239   return (size_t)(base - bottom);
 240 }
 241 
 242 struct tm* os::localtime_pd(const time_t* clock, struct tm*  res) {
 243   return localtime_r(clock, res);
 244 }
 245 
 246 void os::Solaris::try_enable_extended_io() {
 247   typedef int (*enable_extended_FILE_stdio_t)(int, int);
 248 
 249   if (!UseExtendedFileIO) {
 250     return;
 251   }
 252 
 253   enable_extended_FILE_stdio_t enabler =
 254     (enable_extended_FILE_stdio_t) dlsym(RTLD_DEFAULT,
 255                                          "enable_extended_FILE_stdio");
 256   if (enabler) {
 257     enabler(-1, -1);
 258   }


1093 
1094 
1095 // First crack at OS-specific initialization, from inside the new thread.
1096 void os::initialize_thread(Thread* thr) {
1097   int r = thr_main();
1098   guarantee(r == 0 || r == 1, "CR6501650 or CR6493689");
1099   if (r) {
1100     JavaThread* jt = (JavaThread *)thr;
1101     assert(jt != NULL, "Sanity check");
1102     size_t stack_size;
1103     address base = jt->stack_base();
1104     if (Arguments::created_by_java_launcher()) {
1105       // Use 2MB to allow for Solaris 7 64 bit mode.
1106       stack_size = JavaThread::stack_size_at_create() == 0
1107         ? 2048*K : JavaThread::stack_size_at_create();
1108 
1109       // There are rare cases when we may have already used more than
1110       // the basic stack size allotment before this method is invoked.
1111       // Attempt to allow for a normally sized java_stack.
1112       size_t current_stack_offset = (size_t)(base - (address)&stack_size);
1113       stack_size += ReservedSpace::page_align_down(current_stack_offset);
1114     } else {
1115       // 6269555: If we were not created by a Java launcher, i.e. if we are
1116       // running embedded in a native application, treat the primordial thread
1117       // as much like a native attached thread as possible.  This means using
1118       // the current stack size from thr_stksegment(), unless it is too large
1119       // to reliably setup guard pages.  A reasonable max size is 8MB.
1120       size_t current_size = current_stack_size();
1121       // This should never happen, but just in case....
1122       if (current_size == 0) current_size = 2 * K * K;
1123       stack_size = current_size > (8 * K * K) ? (8 * K * K) : current_size;
1124     }
1125     address bottom = align_up(base - stack_size, os::vm_page_size());;
1126     stack_size = (size_t)(base - bottom);
1127 
1128     assert(stack_size > 0, "Stack size calculation problem");
1129 
1130     if (stack_size > jt->stack_size()) {
1131 #ifndef PRODUCT
1132       struct rlimit limits;
1133       getrlimit(RLIMIT_STACK, &limits);
1134       size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur);
1135       assert(size >= jt->stack_size(), "Stack size problem in main thread");
1136 #endif
1137       tty->print_cr("Stack size of %d Kb exceeds current limit of %d Kb.\n"
1138                     "(Stack sizes are rounded up to a multiple of the system page size.)\n"
1139                     "See limit(1) to increase the stack size limit.",
1140                     stack_size / K, jt->stack_size() / K);
1141       vm_exit(1);
1142     }
1143     assert(jt->stack_size() >= stack_size,
1144            "Attempt to map more stack than was allocated");
1145     jt->set_stack_size(stack_size);


2314 
2315   return err;
2316 }
2317 
2318 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
2319   return Solaris::commit_memory_impl(addr, bytes, exec) == 0;
2320 }
2321 
2322 void os::pd_commit_memory_or_exit(char* addr, size_t bytes, bool exec,
2323                                   const char* mesg) {
2324   assert(mesg != NULL, "mesg must be specified");
2325   int err = os::Solaris::commit_memory_impl(addr, bytes, exec);
2326   if (err != 0) {
2327     // the caller wants all commit errors to exit with the specified mesg:
2328     warn_fail_commit_memory(addr, bytes, exec, err);
2329     vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "%s", mesg);
2330   }
2331 }
2332 
2333 size_t os::Solaris::page_size_for_alignment(size_t alignment) {
2334   assert(is_aligned(alignment, (size_t) vm_page_size()),
2335          SIZE_FORMAT " is not aligned to " SIZE_FORMAT,
2336          alignment, (size_t) vm_page_size());
2337 
2338   for (int i = 0; _page_sizes[i] != 0; i++) {
2339     if (is_aligned(alignment, _page_sizes[i])) {
2340       return _page_sizes[i];
2341     }
2342   }
2343 
2344   return (size_t) vm_page_size();
2345 }
2346 
2347 int os::Solaris::commit_memory_impl(char* addr, size_t bytes,
2348                                     size_t alignment_hint, bool exec) {
2349   int err = Solaris::commit_memory_impl(addr, bytes, exec);
2350   if (err == 0 && UseLargePages && alignment_hint > 0) {
2351     assert(is_aligned(bytes, alignment_hint),
2352            SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, alignment_hint);
2353 
2354     // The syscall memcntl requires an exact page size (see man memcntl for details).
2355     size_t page_size = page_size_for_alignment(alignment_hint);
2356     if (page_size > (size_t) vm_page_size()) {
2357       (void)Solaris::setup_large_pages(addr, bytes, page_size);
2358     }
2359   }
2360   return err;
2361 }
2362 
2363 bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint,
2364                           bool exec) {
2365   return Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec) == 0;
2366 }
2367 
2368 void os::pd_commit_memory_or_exit(char* addr, size_t bytes,
2369                                   size_t alignment_hint, bool exec,
2370                                   const char* mesg) {
2371   assert(mesg != NULL, "mesg must be specified");


2748     }
2749   }
2750 
2751   // Give back the unused reserved pieces.
2752 
2753   for (int j = 0; j < i; ++j) {
2754     if (base[j] != NULL) {
2755       unmap_memory(base[j], size[j]);
2756     }
2757   }
2758 
2759   return (i < max_tries) ? requested_addr : NULL;
2760 }
2761 
2762 bool os::pd_release_memory(char* addr, size_t bytes) {
2763   size_t size = bytes;
2764   return munmap(addr, size) == 0;
2765 }
2766 
2767 static bool solaris_mprotect(char* addr, size_t bytes, int prot) {
2768   assert(addr == (char*)align_down((uintptr_t)addr, os::vm_page_size()),
2769          "addr must be page aligned");
2770   int retVal = mprotect(addr, bytes, prot);
2771   return retVal == 0;
2772 }
2773 
2774 // Protect memory (Used to pass readonly pages through
2775 // JNI GetArray<type>Elements with empty arrays.)
2776 // Also, used for serialization page and for compressed oops null pointer
2777 // checking.
2778 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
2779                         bool is_committed) {
2780   unsigned int p = 0;
2781   switch (prot) {
2782   case MEM_PROT_NONE: p = PROT_NONE; break;
2783   case MEM_PROT_READ: p = PROT_READ; break;
2784   case MEM_PROT_RW:   p = PROT_READ|PROT_WRITE; break;
2785   case MEM_PROT_RWX:  p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
2786   default:
2787     ShouldNotReachHere();
2788   }


2885   if (UseLargePages) {
2886     // print a warning if any large page related flag is specified on command line
2887     bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages)        ||
2888                            !FLAG_IS_DEFAULT(LargePageSizeInBytes);
2889 
2890     UseLargePages = Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size);
2891   }
2892 }
2893 
2894 bool os::Solaris::is_valid_page_size(size_t bytes) {
2895   for (int i = 0; _page_sizes[i] != 0; i++) {
2896     if (_page_sizes[i] == bytes) {
2897       return true;
2898     }
2899   }
2900   return false;
2901 }
2902 
2903 bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) {
2904   assert(is_valid_page_size(align), SIZE_FORMAT " is not a valid page size", align);
2905   assert(is_aligned((void*) start, align),
2906          PTR_FORMAT " is not aligned to " SIZE_FORMAT, p2i((void*) start), align);
2907   assert(is_aligned(bytes, align),
2908          SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, align);
2909 
2910   // Signal to OS that we want large pages for addresses
2911   // from addr, addr + bytes
2912   struct memcntl_mha mpss_struct;
2913   mpss_struct.mha_cmd = MHA_MAPSIZE_VA;
2914   mpss_struct.mha_pagesize = align;
2915   mpss_struct.mha_flags = 0;
2916   // Upon successful completion, memcntl() returns 0
2917   if (memcntl(start, bytes, MC_HAT_ADVISE, (caddr_t) &mpss_struct, 0, 0)) {
2918     debug_only(warning("Attempt to use MPSS failed."));
2919     return false;
2920   }
2921   return true;
2922 }
2923 
2924 char* os::reserve_memory_special(size_t size, size_t alignment, char* addr, bool exec) {
2925   fatal("os::reserve_memory_special should not be called on Solaris.");
2926   return NULL;
2927 }


< prev index next >