< prev index next >

src/hotspot/os/linux/os_linux.cpp

Print this page

        

*** 798,807 **** --- 798,862 ---- os::current_thread_id(), (uintx) pthread_self()); return 0; } + #ifdef __GLIBC__ + // The code below is used to figure out the size of the TLS space used + // by the main executable (DSO's TLS space is allocated separately). + // TLS variables live in the stack space allocated for each thread, so + // the function is used to automatically adjust requested stack sizes. + // This code only works with glibc since it relies on an internal symbol + // in glibc. When doing a profile collection run with FDO, the + // compiler will define several TLS variables per object file (making + // this function call frequently necessary during FDO collection). + // p_dl_get_tls_static_info is initialized in InitGetTLSSize(). + // + // The goal is to make sure that stacks have enough space for TLS. + // There is an upstream bug to make this happen in glibc: + // http://sourceware.org/bugzilla/show_bug.cgi?id=11787 + // This code can presumably be retired when that fix is available + // pervasively. + extern "C" void _dl_get_tls_static_info(size_t*, size_t*) __attribute__((weak)); + + typedef void (*GetTLSType)(size_t*, size_t*); + + GetTLSType p_dl_get_tls_static_info = NULL; + + static void InitGetTLSSize() { + // This complicated sequence is used to support both static and + // dynamic linking when using the gold linker. + // _dl_get_tls_static_info is defined in libc.a and ld-linux.so. + // When linking statically, the symbol is available. When linking + // dynamically, the symbol is *not* available because gold does not + // consider ld-linux.so to be part of the link unless explicitly + // specified. The code below uses the static symbol if available. + // If not, it will use dlsym to search for the symbol at runtime. + p_dl_get_tls_static_info = &_dl_get_tls_static_info; + if (p_dl_get_tls_static_info == NULL) { + p_dl_get_tls_static_info = + (GetTLSType)dlsym(RTLD_NEXT, "_dl_get_tls_static_info"); + } + } + + static size_t GetTLSSize() { + size_t tls_size = 0; + size_t tls_align; + + if (p_dl_get_tls_static_info) { + (*p_dl_get_tls_static_info)(&tls_size, &tls_align); + } + return tls_size; + } + #else + static void InitGetTLSSize() { + } + static size_t GetTLSSize() { + return 0; + } + #endif + bool os::create_thread(Thread* thread, ThreadType thr_type, size_t req_stack_size) { assert(thread->osthread() == NULL, "caller responsible"); // Allocate the OSThread object
*** 834,843 **** --- 889,901 ---- // of zero due to overflow. Don't add the guard page in that case. size_t guard_size = os::Linux::default_guard_size(thr_type); if (stack_size <= SIZE_MAX - guard_size) { stack_size += guard_size; } + // Always, always, always give the user more for TLS, even if they + // haven't asked for it. + stack_size += GetTLSSize(); assert(is_aligned(stack_size, os::vm_page_size()), "stack_size not aligned"); int status = pthread_attr_setstacksize(&attr, stack_size); assert_status(status == 0, status, "pthread_attr_setstacksize");
*** 5151,5160 **** --- 5209,5220 ---- // Initialize data for jdk.internal.misc.Signal if (!ReduceSignalUsage) { jdk_misc_signal_init(); } + InitGetTLSSize(); + // Check and sets minimum stack sizes against command line options if (Posix::set_minimum_stack_sizes() == JNI_ERR) { return JNI_ERR; }
< prev index next >