< prev index next >

src/hotspot/os/linux/os_linux.cpp

Print this page

        

*** 811,822 **** if (lgrp_id != -1) { thread->set_lgrp_id(lgrp_id); } } ! if (os::Linux::is_initial_thread()) { ! // If current thread is initial thread, its stack is mapped on demand, // see notes about MAP_GROWSDOWN. Here we try to force kernel to map // the entire stack region to avoid SEGV in stack banging. // It is also useful to get around the heap-stack-gap problem on SuSE // kernel (see 4821821 for details). We first expand stack to the top // of yellow zone, then enable stack yellow zone (order is significant, --- 811,822 ---- if (lgrp_id != -1) { thread->set_lgrp_id(lgrp_id); } } ! if (os::is_primordial_thread()) { ! // If current thread is primordial thread, its stack is mapped on demand, // see notes about MAP_GROWSDOWN. Here we try to force kernel to map // the entire stack region to avoid SEGV in stack banging. // It is also useful to get around the heap-stack-gap problem on SuSE // kernel (see 4821821 for details). We first expand stack to the top // of yellow zone, then enable stack yellow zone (order is significant,
*** 873,895 **** delete osthread; } ////////////////////////////////////////////////////////////////////////////// ! // initial thread ! // Check if current thread is the initial thread, similar to Solaris thr_main. ! bool os::Linux::is_initial_thread(void) { char dummy; // If called before init complete, thread stack bottom will be null. // Can be called if fatal error occurs before initialization. ! if (initial_thread_stack_bottom() == NULL) return false; ! assert(initial_thread_stack_bottom() != NULL && ! initial_thread_stack_size() != 0, ! "os::init did not locate initial thread's stack region"); ! if ((address)&dummy >= initial_thread_stack_bottom() && ! (address)&dummy < initial_thread_stack_bottom() + initial_thread_stack_size()) { return true; } else { return false; } } --- 873,896 ---- delete osthread; } ////////////////////////////////////////////////////////////////////////////// ! // primordial thread ! // Check if current thread is the primordial thread, similar to Solaris thr_main. ! bool os::is_primordial_thread(void) { char dummy; // If called before init complete, thread stack bottom will be null. // Can be called if fatal error occurs before initialization. ! if (os::Linux::initial_thread_stack_bottom() == NULL) return false; ! assert(os::Linux::initial_thread_stack_bottom() != NULL && ! os::Linux::initial_thread_stack_size() != 0, ! "os::init did not locate primordial thread's stack region"); ! if ((address)&dummy >= os::Linux::initial_thread_stack_bottom() && ! (address)&dummy < os::Linux::initial_thread_stack_bottom() + ! os::Linux::initial_thread_stack_size()) { return true; } else { return false; } }
*** 916,926 **** fclose(fp); } return false; } ! // Locate initial thread stack. This special handling of initial thread stack // is needed because pthread_getattr_np() on most (all?) Linux distros returns // bogus value for the primordial process thread. While the launcher has created // the VM in a new thread since JDK 6, we still have to allow for the use of the // JNI invocation API from a primordial thread. void os::Linux::capture_initial_stack(size_t max_size) { --- 917,927 ---- fclose(fp); } return false; } ! // Locate primordial thread stack. This special handling of primordial thread stack // is needed because pthread_getattr_np() on most (all?) Linux distros returns // bogus value for the primordial process thread. While the launcher has created // the VM in a new thread since JDK 6, we still have to allow for the use of the // JNI invocation API from a primordial thread. void os::Linux::capture_initial_stack(size_t max_size) {
*** 940,949 **** --- 941,952 ---- size_t stack_size = rlim.rlim_cur; // 6308388: a bug in ld.so will relocate its own .data section to the // lower end of primordial stack; reduce ulimit -s value a little bit // so we won't install guard page on ld.so's data section. + // But ensure we don't underflow the stack size - allow 1 page spare + if (stack_size >= (size_t)(3 * page_size())) stack_size -= 2 * page_size(); // Try to figure out where the stack base (top) is. This is harder. // // When an application is started, glibc saves the initial stack pointer in
*** 1061,1080 **** #undef _UFM #undef _DFM if (i != 28 - 2) { assert(false, "Bad conversion from /proc/self/stat"); ! // product mode - assume we are the initial thread, good luck in the // embedded case. ! warning("Can't detect initial thread stack location - bad conversion"); stack_start = (uintptr_t) &rlim; } } else { // For some reason we can't open /proc/self/stat (for example, running on // FreeBSD with a Linux emulator, or inside chroot), this should work for // most cases, so don't abort: ! warning("Can't detect initial thread stack location - no /proc/self/stat"); stack_start = (uintptr_t) &rlim; } } // Now we have a pointer (stack_start) very close to the stack top, the --- 1064,1083 ---- #undef _UFM #undef _DFM if (i != 28 - 2) { assert(false, "Bad conversion from /proc/self/stat"); ! // product mode - assume we are the primordial thread, good luck in the // embedded case. ! warning("Can't detect primordial thread stack location - bad conversion"); stack_start = (uintptr_t) &rlim; } } else { // For some reason we can't open /proc/self/stat (for example, running on // FreeBSD with a Linux emulator, or inside chroot), this should work for // most cases, so don't abort: ! warning("Can't detect primordial thread stack location - no /proc/self/stat"); stack_start = (uintptr_t) &rlim; } } // Now we have a pointer (stack_start) very close to the stack top, the
*** 1090,1100 **** // success, "high" is the true stack top. (ignore "low", because initial // thread stack grows on demand, its real bottom is high - RLIMIT_STACK.) stack_top = (uintptr_t)high; } else { // failed, likely because /proc/self/maps does not exist ! warning("Can't detect initial thread stack location - find_vma failed"); // best effort: stack_start is normally within a few pages below the real // stack top, use it as stack top, and reduce stack size so we won't put // guard page outside stack. stack_top = stack_start; stack_size -= 16 * page_size(); --- 1093,1103 ---- // success, "high" is the true stack top. (ignore "low", because initial // thread stack grows on demand, its real bottom is high - RLIMIT_STACK.) stack_top = (uintptr_t)high; } else { // failed, likely because /proc/self/maps does not exist ! warning("Can't detect primordial thread stack location - find_vma failed"); // best effort: stack_start is normally within a few pages below the real // stack top, use it as stack top, and reduce stack size so we won't put // guard page outside stack. stack_top = stack_start; stack_size -= 16 * page_size();
*** 3032,3045 **** // If the (growable) stack mapping already extends beyond the point // where we're going to put our guard pages, truncate the mapping at // that point by munmap()ping it. This ensures that when we later // munmap() the guard pages we don't leave a hole in the stack ! // mapping. This only affects the main/initial thread bool os::pd_create_stack_guard_pages(char* addr, size_t size) { ! if (os::Linux::is_initial_thread()) { // As we manually grow stack up to bottom inside create_attached_thread(), // it's likely that os::Linux::initial_thread_stack_bottom is mapped and // we don't need to do anything special. // Check it first, before calling heavy function. uintptr_t stack_extent = (uintptr_t) os::Linux::initial_thread_stack_bottom(); --- 3035,3048 ---- // If the (growable) stack mapping already extends beyond the point // where we're going to put our guard pages, truncate the mapping at // that point by munmap()ping it. This ensures that when we later // munmap() the guard pages we don't leave a hole in the stack ! // mapping. This only affects the main/primordial thread bool os::pd_create_stack_guard_pages(char* addr, size_t size) { ! if (os::is_primordial_thread()) { // As we manually grow stack up to bottom inside create_attached_thread(), // it's likely that os::Linux::initial_thread_stack_bottom is mapped and // we don't need to do anything special. // Check it first, before calling heavy function. uintptr_t stack_extent = (uintptr_t) os::Linux::initial_thread_stack_bottom();
*** 3060,3077 **** return os::commit_memory(addr, size, !ExecMem); } // If this is a growable mapping, remove the guard pages entirely by // munmap()ping them. If not, just call uncommit_memory(). This only ! // affects the main/initial thread, but guard against future OS changes ! // It's safe to always unmap guard pages for initial thread because we // always place it right after end of the mapped region bool os::remove_stack_guard_pages(char* addr, size_t size) { uintptr_t stack_extent, stack_base; ! if (os::Linux::is_initial_thread()) { return ::munmap(addr, size) == 0; } return os::uncommit_memory(addr, size); } --- 3063,3080 ---- return os::commit_memory(addr, size, !ExecMem); } // If this is a growable mapping, remove the guard pages entirely by // munmap()ping them. If not, just call uncommit_memory(). This only ! // affects the main/primordial thread, but guard against future OS changes ! // It's safe to always unmap guard pages for primordial thread because we // always place it right after end of the mapped region bool os::remove_stack_guard_pages(char* addr, size_t size) { uintptr_t stack_extent, stack_base; ! if (os::is_primordial_thread()) { return ::munmap(addr, size) == 0; } return os::uncommit_memory(addr, size); }
*** 5709,5720 **** // of the stack size given in pthread_attr. We work around this for // threads created by the VM. (We adapt bottom to be P1 and size accordingly.) // #ifndef ZERO static void current_stack_region(address * bottom, size_t * size) { ! if (os::Linux::is_initial_thread()) { ! // initial thread needs special handling because pthread_getattr_np() // may return bogus value. *bottom = os::Linux::initial_thread_stack_bottom(); *size = os::Linux::initial_thread_stack_size(); } else { pthread_attr_t attr; --- 5712,5723 ---- // of the stack size given in pthread_attr. We work around this for // threads created by the VM. (We adapt bottom to be P1 and size accordingly.) // #ifndef ZERO static void current_stack_region(address * bottom, size_t * size) { ! if (os::is_primordial_thread()) { ! // primordial thread needs special handling because pthread_getattr_np() // may return bogus value. *bottom = os::Linux::initial_thread_stack_bottom(); *size = os::Linux::initial_thread_stack_size(); } else { pthread_attr_t attr;
< prev index next >