< prev index next >

src/os/linux/vm/os_linux.cpp

Print this page

        

*** 1073,1105 **** 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 initial thread. void os::Linux::capture_initial_stack(size_t max_size) { ! // stack size is the easy part, get it from RLIMIT_STACK ! size_t stack_size; struct rlimit rlim; getrlimit(RLIMIT_STACK, &rlim); ! 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. stack_size -= 2 * page_size(); - // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat - // 7.1, in both cases we will get 2G in return value. - // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0, - // SuSE 7.2, Debian) can not handle alternate signal stack correctly - // for initial thread if its stack size exceeds 6M. Cap it at 2M, - // in case other parts in glibc still assumes 2M max stack size. - // FIXME: alt signal stack is gone, maybe we can relax this constraint? - // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small - if (stack_size > 2 * K * K IA64_ONLY(*2)) - stack_size = 2 * K * K IA64_ONLY(*2); // 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 // a global variable "__libc_stack_end", which is then used by system // libraries. __libc_stack_end should be pretty close to stack top. The --- 1073,1106 ---- 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) { ! ! // max_size is either 0 (which means accept OS default for thread stacks) or ! // a user-specified value known to be at least the minimum needed. If we ! // are actually on the primordial thread we can make it appear that we have a ! // smaller max_size stack by inserting the guard pages at that location. But we ! // cannot do anything to emulate a larger stack than what has been provided by ! // the OS or threading library. In fact if we try to use a stack greater than ! // what is set by rlimit then we will crash the hosting process. ! ! // Maximum stack size is the easy part, get it from RLIMIT_STACK. ! // If this is "unlimited" then it will be a huge value. struct rlimit rlim; getrlimit(RLIMIT_STACK, &rlim); ! 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. 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 // a global variable "__libc_stack_end", which is then used by system // libraries. __libc_stack_end should be pretty close to stack top. The
*** 1255,1272 **** } // stack_top could be partially down the page so align it stack_top = align_size_up(stack_top, page_size()); ! if (max_size && stack_size > max_size) { ! _initial_thread_stack_size = max_size; } else { ! _initial_thread_stack_size = stack_size; } _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size()); _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size; } //////////////////////////////////////////////////////////////////////////////// // time support --- 1256,1277 ---- } // stack_top could be partially down the page so align it stack_top = align_size_up(stack_top, page_size()); ! // Allowed stack value is minimum of max_size and what we derived from rlimit ! if (max_size > 0) { ! _initial_thread_stack_size = MIN2(max_size, stack_size); } else { ! // Accept the rlimit max, but if stack is unlimited then it will be huge, so ! // clamp it at 8MB as we do on Solaris ! _initial_thread_stack_size = MIN2(stack_size, 8*M); } _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size()); _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size; + assert(_initial_thread_stack_bottom < (address)stack_top, "overflow!"); } //////////////////////////////////////////////////////////////////////////////// // time support
< prev index next >