8382614: Consolidate implementation of current_stack_base_and_size on BSD

Reviewed-by: dholmes, aartemov
This commit is contained in:
Harald Eilertsen 2026-04-24 11:15:36 +00:00 committed by David Holmes
parent 19ffa60b2e
commit cd01fab465
4 changed files with 109 additions and 205 deletions

View File

@ -106,6 +106,14 @@
#include <libproc.h>
#include <mach/task_info.h>
#include <mach-o/dyld.h>
// needed by current_stack_base_and_size() workaround for Mavericks
#define DEFAULT_MAIN_THREAD_STACK_PAGES 2048
#define OS_X_10_9_0_KERNEL_MAJOR_VERSION 13
#endif
#if !defined(__APPLE__) && !defined(__NetBSD__)
#include <pthread_np.h>
#endif
#ifndef MAP_ANONYMOUS
@ -2545,6 +2553,106 @@ bool os::start_debugging(char *buf, int buflen) {
return yes;
}
// Java thread:
//
// Low memory addresses
// +------------------------+
// | |\ Java thread created by VM does not have glibc
// | glibc guard page | - guard, attached Java thread usually has
// | |/ 1 glibc guard page.
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
// | |\
// | HotSpot Guard Pages | - red, yellow and reserved pages
// | |/
// +------------------------+ StackOverflow::stack_reserved_zone_base()
// | |\
// | Normal Stack | -
// | |/
// P2 +------------------------+ Thread::stack_base()
//
// Non-Java thread:
//
// Low memory addresses
// +------------------------+
// | |\
// | glibc guard page | - usually 1 page
// | |/
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
// | |\
// | Normal Stack | -
// | |/
// P2 +------------------------+ Thread::stack_base()
//
// ** P1 (aka bottom) and size are the address and stack size
// returned from pthread_attr_getstack().
// ** P2 (aka stack top or base) = P1 + size
void os::current_stack_base_and_size(address* base, size_t* size) {
address bottom;
#ifdef __APPLE__
pthread_t self = pthread_self();
*base = (address) pthread_get_stackaddr_np(self);
*size = pthread_get_stacksize_np(self);
# ifdef __x86_64__
// workaround for OS X 10.9.0 (Mavericks)
// pthread_get_stacksize_np returns 128 pages even though the actual size is 2048 pages
if (pthread_main_np() == 1) {
// At least on Mac OS 10.12 we have observed stack sizes not aligned
// to pages boundaries. This can be provoked by e.g. setrlimit() (ulimit -s xxxx in the
// shell). Apparently Mac OS actually rounds upwards to next multiple of page size,
// however, we round downwards here to be on the safe side.
*size = align_down(*size, getpagesize());
if ((*size) < (DEFAULT_MAIN_THREAD_STACK_PAGES * (size_t)getpagesize())) {
char kern_osrelease[256];
size_t kern_osrelease_size = sizeof(kern_osrelease);
int ret = sysctlbyname("kern.osrelease", kern_osrelease, &kern_osrelease_size, nullptr, 0);
if (ret == 0) {
// get the major number, atoi will ignore the minor amd micro portions of the version string
if (atoi(kern_osrelease) >= OS_X_10_9_0_KERNEL_MAJOR_VERSION) {
*size = (DEFAULT_MAIN_THREAD_STACK_PAGES*getpagesize());
}
}
}
}
# endif
bottom = *base - *size;
#elif defined(__OpenBSD__)
stack_t ss;
int rslt = pthread_stackseg_np(pthread_self(), &ss);
if (rslt != 0)
fatal("pthread_stackseg_np failed with error = %d", rslt);
*base = (address) ss.ss_sp;
*size = ss.ss_size;
bottom = *base - *size;
#else
pthread_attr_t attr;
int rslt = pthread_attr_init(&attr);
// JVM needs to know exact stack location, abort if it fails
if (rslt != 0)
fatal("pthread_attr_init failed with error = %d", rslt);
rslt = pthread_attr_get_np(pthread_self(), &attr);
if (rslt != 0)
fatal("pthread_attr_get_np failed with error = %d", rslt);
if (pthread_attr_getstackaddr(&attr, (void **)&bottom) != 0 ||
pthread_attr_getstacksize(&attr, size) != 0) {
fatal("Can not locate current stack attributes!");
}
*base = bottom + *size;
pthread_attr_destroy(&attr);
#endif
assert(os::current_stack_pointer() >= bottom &&
os::current_stack_pointer() < *base, "just checking");
}
void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {}
#if INCLUDE_JFR

View File

@ -81,10 +81,6 @@
# include <ucontext.h>
#endif
#if !defined(__APPLE__) && !defined(__NetBSD__)
# include <pthread_np.h>
#endif
#define SPELL_REG_SP "sp"
#ifdef __APPLE__
@ -415,49 +411,6 @@ size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
return s;
}
void os::current_stack_base_and_size(address* base, size_t* size) {
address bottom;
#ifdef __APPLE__
pthread_t self = pthread_self();
*base = (address) pthread_get_stackaddr_np(self);
*size = pthread_get_stacksize_np(self);
bottom = *base - *size;
#elif defined(__OpenBSD__)
stack_t ss;
int rslt = pthread_stackseg_np(pthread_self(), &ss);
if (rslt != 0)
fatal("pthread_stackseg_np failed with error = %d", rslt);
*base = (address) ss.ss_sp;
*size = ss.ss_size;
bottom = *base - *size;
#else
pthread_attr_t attr;
int rslt = pthread_attr_init(&attr);
// JVM needs to know exact stack location, abort if it fails
if (rslt != 0)
fatal("pthread_attr_init failed with error = %d", rslt);
rslt = pthread_attr_get_np(pthread_self(), &attr);
if (rslt != 0)
fatal("pthread_attr_get_np failed with error = %d", rslt);
if (pthread_attr_getstackaddr(&attr, (void **)&bottom) != 0 ||
pthread_attr_getstacksize(&attr, size) != 0) {
fatal("Can not locate current stack attributes!");
}
*base = bottom + *size;
pthread_attr_destroy(&attr);
#endif
assert(os::current_stack_pointer() >= bottom &&
os::current_stack_pointer() < *base, "just checking");
}
/////////////////////////////////////////////////////////////////////////////
// helper functions for fatal error handler

View File

@ -55,6 +55,7 @@
// put OS-includes here
# include <sys/types.h>
# include <sys/mman.h>
# include <sys/sysctl.h>
# include <pthread.h>
# include <signal.h>
# include <errno.h>
@ -73,19 +74,6 @@
# include <ucontext.h>
#endif
#if !defined(__APPLE__) && !defined(__NetBSD__)
# include <pthread_np.h>
#endif
// needed by current_stack_base_and_size() workaround for Mavericks
#if defined(__APPLE__)
# include <errno.h>
# include <sys/types.h>
# include <sys/sysctl.h>
# define DEFAULT_MAIN_THREAD_STACK_PAGES 2048
# define OS_X_10_9_0_KERNEL_MAJOR_VERSION 13
#endif
#define SPELL_REG_SP "rsp"
#define SPELL_REG_FP "rbp"
#define REG_BCP context_r13
@ -499,104 +487,6 @@ size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
}
// Java thread:
//
// Low memory addresses
// +------------------------+
// | |\ Java thread created by VM does not have glibc
// | glibc guard page | - guard, attached Java thread usually has
// | |/ 1 glibc guard page.
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
// | |\
// | HotSpot Guard Pages | - red, yellow and reserved pages
// | |/
// +------------------------+ StackOverflow::stack_reserved_zone_base()
// | |\
// | Normal Stack | -
// | |/
// P2 +------------------------+ Thread::stack_base()
//
// Non-Java thread:
//
// Low memory addresses
// +------------------------+
// | |\
// | glibc guard page | - usually 1 page
// | |/
// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
// | |\
// | Normal Stack | -
// | |/
// P2 +------------------------+ Thread::stack_base()
//
// ** P1 (aka bottom) and size are the address and stack size
// returned from pthread_attr_getstack().
// ** P2 (aka stack top or base) = P1 + size
void os::current_stack_base_and_size(address* base, size_t* size) {
address bottom;
#ifdef __APPLE__
pthread_t self = pthread_self();
*base = (address) pthread_get_stackaddr_np(self);
*size = pthread_get_stacksize_np(self);
// workaround for OS X 10.9.0 (Mavericks)
// pthread_get_stacksize_np returns 128 pages even though the actual size is 2048 pages
if (pthread_main_np() == 1) {
// At least on Mac OS 10.12 we have observed stack sizes not aligned
// to pages boundaries. This can be provoked by e.g. setrlimit() (ulimit -s xxxx in the
// shell). Apparently Mac OS actually rounds upwards to next multiple of page size,
// however, we round downwards here to be on the safe side.
*size = align_down(*size, getpagesize());
if ((*size) < (DEFAULT_MAIN_THREAD_STACK_PAGES * (size_t)getpagesize())) {
char kern_osrelease[256];
size_t kern_osrelease_size = sizeof(kern_osrelease);
int ret = sysctlbyname("kern.osrelease", kern_osrelease, &kern_osrelease_size, nullptr, 0);
if (ret == 0) {
// get the major number, atoi will ignore the minor amd micro portions of the version string
if (atoi(kern_osrelease) >= OS_X_10_9_0_KERNEL_MAJOR_VERSION) {
*size = (DEFAULT_MAIN_THREAD_STACK_PAGES*getpagesize());
}
}
}
}
bottom = *base - *size;
#elif defined(__OpenBSD__)
stack_t ss;
int rslt = pthread_stackseg_np(pthread_self(), &ss);
if (rslt != 0)
fatal("pthread_stackseg_np failed with error = %d", rslt);
*base = (address) ss.ss_sp;
*size = ss.ss_size;
bottom = *base - *size;
#else
pthread_attr_t attr;
int rslt = pthread_attr_init(&attr);
// JVM needs to know exact stack location, abort if it fails
if (rslt != 0)
fatal("pthread_attr_init failed with error = %d", rslt);
rslt = pthread_attr_get_np(pthread_self(), &attr);
if (rslt != 0)
fatal("pthread_attr_get_np failed with error = %d", rslt);
if (pthread_attr_getstackaddr(&attr, (void **)&bottom) != 0 ||
pthread_attr_getstacksize(&attr, size) != 0) {
fatal("Can not locate current stack attributes!");
}
*base = bottom + *size;
pthread_attr_destroy(&attr);
#endif
assert(os::current_stack_pointer() >= bottom &&
os::current_stack_pointer() < *base, "just checking");
}
/////////////////////////////////////////////////////////////////////////////
// helper functions for fatal error handler

View File

@ -52,7 +52,6 @@
#if !defined(__APPLE__) && !defined(__NetBSD__)
#include <pthread.h>
# include <pthread_np.h> /* For pthread_attr_get_np */
#endif
address os::current_stack_pointer() {
@ -179,52 +178,6 @@ size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
return s;
}
void os::current_stack_base_and_size(address* base, size_t* size) {
address bottom;
#ifdef __APPLE__
pthread_t self = pthread_self();
*base = (address) pthread_get_stackaddr_np(self);
*size = pthread_get_stacksize_np(self);
bottom = *base - *size;
#elif defined(__OpenBSD__)
stack_t ss;
int rslt = pthread_stackseg_np(pthread_self(), &ss);
if (rslt != 0)
fatal("pthread_stackseg_np failed with error = %d", rslt);
*base = (address) ss.ss_sp;
*size = ss.ss_size;
bottom = *base - *size;
#else
pthread_attr_t attr;
int rslt = pthread_attr_init(&attr);
// JVM needs to know exact stack location, abort if it fails
if (rslt != 0)
fatal("pthread_attr_init failed with error = %d", rslt);
rslt = pthread_attr_get_np(pthread_self(), &attr);
if (rslt != 0)
fatal("pthread_attr_get_np failed with error = %d", rslt);
if (pthread_attr_getstackaddr(&attr, (void **) &bottom) != 0 ||
pthread_attr_getstacksize(&attr, size) != 0) {
fatal("Can not locate current stack attributes!");
}
*base = bottom + *size;
pthread_attr_destroy(&attr);
#endif
assert(os::current_stack_pointer() >= bottom &&
os::current_stack_pointer() < *base, "just checking");
}
/////////////////////////////////////////////////////////////////////////////
// helper functions for fatal error handler