提交 ab8da9af 编写于 作者: D dbuck

8189170: Add option to disable stack overflow checking in primordial thread...

8189170: Add option to disable stack overflow checking in primordial thread for use with JNI_CreateJavaJVM
Reviewed-by: dcubed
上级 ff75d9d5
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 2014 SAP AG. All rights reserved. * Copyright 2012, 2014 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
...@@ -410,7 +410,7 @@ void os::Aix::query_multipage_support() { ...@@ -410,7 +410,7 @@ void os::Aix::query_multipage_support() {
// thread (because primordial thread's stack may have different page size than // thread (because primordial thread's stack may have different page size than
// pthread thread stacks). Running a VM on the primordial thread won't work for a // pthread thread stacks). Running a VM on the primordial thread won't work for a
// number of reasons so we may just as well guarantee it here // number of reasons so we may just as well guarantee it here
guarantee(!os::Aix::is_primordial_thread(), "Must not be called for primordial thread"); guarantee(!os::is_primordial_thread(), "Must not be called for primordial thread");
// query stack page size // query stack page size
{ {
...@@ -3835,7 +3835,7 @@ void os::init(void) { ...@@ -3835,7 +3835,7 @@ void os::init(void) {
ThreadCritical::initialize(); ThreadCritical::initialize();
// Main_thread points to the aboriginal thread. // _main_thread points to the thread that created/loaded the JVM.
Aix::_main_thread = pthread_self(); Aix::_main_thread = pthread_self();
initial_time_count = os::elapsed_counter(); initial_time_count = os::elapsed_counter();
...@@ -4511,7 +4511,7 @@ void os::pause() { ...@@ -4511,7 +4511,7 @@ void os::pause() {
} }
} }
bool os::Aix::is_primordial_thread() { bool os::is_primordial_thread(void) {
if (pthread_self() == (pthread_t)1) { if (pthread_self() == (pthread_t)1) {
return true; return true;
} else { } else {
...@@ -4646,7 +4646,7 @@ static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size) ...@@ -4646,7 +4646,7 @@ static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size)
// This only works when invoked on a pthread. As we agreed not to use // This only works when invoked on a pthread. As we agreed not to use
// primordial threads anyway, I assert here // primordial threads anyway, I assert here
guarantee(!os::Aix::is_primordial_thread(), "not allowed on the primordial thread"); guarantee(!os::is_primordial_thread(), "not allowed on the primordial thread");
// information about this api can be found (a) in the pthread.h header and // information about this api can be found (a) in the pthread.h header and
// (b) in http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_getthrds_np.htm // (b) in http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_getthrds_np.htm
......
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2013 SAP AG. All rights reserved. * Copyright 2013 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
...@@ -170,12 +170,6 @@ class Aix { ...@@ -170,12 +170,6 @@ class Aix {
// Given an address, returns the size of the page backing that address // Given an address, returns the size of the page backing that address
static size_t query_pagesize(void* p); static size_t query_pagesize(void* p);
// Return `true' if the calling thread is the primordial thread. The
// primordial thread is the thread which contains the main function,
// *not* necessarily the thread which initialized the VM by calling
// JNI_CreateJavaVM.
static bool is_primordial_thread(void);
static int page_size(void) { static int page_size(void) {
assert(_page_size != -1, "not initialized"); assert(_page_size != -1, "not initialized");
return _page_size; return _page_size;
......
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -3611,7 +3611,7 @@ void os::init(void) { ...@@ -3611,7 +3611,7 @@ void os::init(void) {
Bsd::initialize_system_info(); Bsd::initialize_system_info();
// main_thread points to the aboriginal thread // _main_thread points to the thread that created/loaded the JVM.
Bsd::_main_thread = pthread_self(); Bsd::_main_thread = pthread_self();
Bsd::clock_init(); Bsd::clock_init();
......
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -92,7 +92,6 @@ class Bsd { ...@@ -92,7 +92,6 @@ class Bsd {
static void hotspot_sigmask(Thread* thread); static void hotspot_sigmask(Thread* thread);
static bool is_initial_thread(void);
static pid_t gettid(); static pid_t gettid();
static int page_size(void) { return _page_size; } static int page_size(void) { return _page_size; }
......
/* /*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -946,8 +946,8 @@ bool os::create_attached_thread(JavaThread* thread) { ...@@ -946,8 +946,8 @@ bool os::create_attached_thread(JavaThread* thread) {
} }
} }
if (os::Linux::is_initial_thread()) { if (os::is_primordial_thread()) {
// If current thread is initial thread, its stack is mapped on demand, // 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 // see notes about MAP_GROWSDOWN. Here we try to force kernel to map
// the entire stack region to avoid SEGV in stack banging. // the entire stack region to avoid SEGV in stack banging.
// It is also useful to get around the heap-stack-gap problem on SuSE // It is also useful to get around the heap-stack-gap problem on SuSE
...@@ -1032,21 +1032,24 @@ extern "C" Thread* get_thread() { ...@@ -1032,21 +1032,24 @@ extern "C" Thread* get_thread() {
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// initial thread // primordial thread
// Check if current thread is the initial thread, similar to Solaris thr_main. // Check if current thread is the primordial thread, similar to Solaris thr_main.
bool os::Linux::is_initial_thread(void) { bool os::is_primordial_thread(void) {
char dummy; char dummy;
// If called before init complete, thread stack bottom will be null. // If called before init complete, thread stack bottom will be null.
// Can be called if fatal error occurs before initialization. // Can be called if fatal error occurs before initialization.
if (initial_thread_stack_bottom() == NULL) return false; if (os::Linux::initial_thread_stack_bottom() == NULL) return false;
assert(initial_thread_stack_bottom() != NULL && assert(os::Linux::initial_thread_stack_bottom() != NULL &&
initial_thread_stack_size() != 0, os::Linux::initial_thread_stack_size() != 0,
"os::init did not locate initial thread's stack region"); "os::init did not locate primordial thread's stack region");
if ((address)&dummy >= initial_thread_stack_bottom() && if ((address)&dummy >= os::Linux::initial_thread_stack_bottom() &&
(address)&dummy < initial_thread_stack_bottom() + initial_thread_stack_size()) (address)&dummy < os::Linux::initial_thread_stack_bottom() +
os::Linux::initial_thread_stack_size()) {
return true; return true;
else return false; } else {
return false;
}
} }
// Find the virtual memory area that contains addr // Find the virtual memory area that contains addr
...@@ -1073,7 +1076,7 @@ static bool find_vma(address addr, address* vma_low, address* vma_high) { ...@@ -1073,7 +1076,7 @@ static bool find_vma(address addr, address* vma_low, address* vma_high) {
return false; return false;
} }
// Locate initial thread stack. This special handling of initial thread stack // Locate primordial thread stack. This special handling of primordial thread stack
// is needed because pthread_getattr_np() on most (all?) Linux distros returns // is needed because pthread_getattr_np() on most (all?) Linux distros returns
// bogus value for the primordial process thread. While the launcher has created // 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 // the VM in a new thread since JDK 6, we still have to allow for the use of the
...@@ -1097,7 +1100,10 @@ void os::Linux::capture_initial_stack(size_t max_size) { ...@@ -1097,7 +1100,10 @@ void os::Linux::capture_initial_stack(size_t max_size) {
// 6308388: a bug in ld.so will relocate its own .data section to the // 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 // 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. // 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(); stack_size -= 2 * page_size();
}
// Try to figure out where the stack base (top) is. This is harder. // Try to figure out where the stack base (top) is. This is harder.
// //
...@@ -1218,16 +1224,16 @@ void os::Linux::capture_initial_stack(size_t max_size) { ...@@ -1218,16 +1224,16 @@ void os::Linux::capture_initial_stack(size_t max_size) {
if (i != 28 - 2) { if (i != 28 - 2) {
assert(false, "Bad conversion from /proc/self/stat"); assert(false, "Bad conversion from /proc/self/stat");
// product mode - assume we are the initial thread, good luck in the // product mode - assume we are the primordial thread, good luck in the
// embedded case. // embedded case.
warning("Can't detect initial thread stack location - bad conversion"); warning("Can't detect primordial thread stack location - bad conversion");
stack_start = (uintptr_t) &rlim; stack_start = (uintptr_t) &rlim;
} }
} else { } else {
// For some reason we can't open /proc/self/stat (for example, running on // 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 // FreeBSD with a Linux emulator, or inside chroot), this should work for
// most cases, so don't abort: // most cases, so don't abort:
warning("Can't detect initial thread stack location - no /proc/self/stat"); warning("Can't detect primordial thread stack location - no /proc/self/stat");
stack_start = (uintptr_t) &rlim; stack_start = (uintptr_t) &rlim;
} }
} }
...@@ -1247,7 +1253,7 @@ void os::Linux::capture_initial_stack(size_t max_size) { ...@@ -1247,7 +1253,7 @@ void os::Linux::capture_initial_stack(size_t max_size) {
stack_top = (uintptr_t)high; stack_top = (uintptr_t)high;
} else { } else {
// failed, likely because /proc/self/maps does not exist // failed, likely because /proc/self/maps does not exist
warning("Can't detect initial thread stack location - find_vma failed"); warning("Can't detect primordial thread stack location - find_vma failed");
// best effort: stack_start is normally within a few pages below the real // 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 // stack top, use it as stack top, and reduce stack size so we won't put
// guard page outside stack. // guard page outside stack.
...@@ -3066,11 +3072,11 @@ address get_stack_commited_bottom(address bottom, size_t size) { ...@@ -3066,11 +3072,11 @@ address get_stack_commited_bottom(address bottom, size_t size) {
// where we're going to put our guard pages, truncate the mapping at // 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 // 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 // munmap() the guard pages we don't leave a hole in the stack
// mapping. This only affects the main/initial thread // mapping. This only affects the main/primordial thread
bool os::pd_create_stack_guard_pages(char* addr, size_t size) { bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
if (os::Linux::is_initial_thread()) { if (os::is_primordial_thread()) {
// As we manually grow stack up to bottom inside create_attached_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 // it's likely that os::Linux::initial_thread_stack_bottom is mapped and
// we don't need to do anything special. // we don't need to do anything special.
...@@ -3095,14 +3101,14 @@ bool os::pd_create_stack_guard_pages(char* addr, size_t size) { ...@@ -3095,14 +3101,14 @@ bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
// If this is a growable mapping, remove the guard pages entirely by // If this is a growable mapping, remove the guard pages entirely by
// munmap()ping them. If not, just call uncommit_memory(). This only // munmap()ping them. If not, just call uncommit_memory(). This only
// affects the main/initial thread, but guard against future OS changes // affects the main/primordial thread, but guard against future OS changes.
// It's safe to always unmap guard pages for initial thread because we // It's safe to always unmap guard pages for primordial thread because we
// always place it right after end of the mapped region // always place it right after end of the mapped region.
bool os::remove_stack_guard_pages(char* addr, size_t size) { bool os::remove_stack_guard_pages(char* addr, size_t size) {
uintptr_t stack_extent, stack_base; uintptr_t stack_extent, stack_base;
if (os::Linux::is_initial_thread()) { if (os::is_primordial_thread()) {
return ::munmap(addr, size) == 0; return ::munmap(addr, size) == 0;
} }
...@@ -4877,10 +4883,9 @@ const char* os::exception_name(int exception_code, char* buf, size_t size) { ...@@ -4877,10 +4883,9 @@ const char* os::exception_name(int exception_code, char* buf, size_t size) {
} }
} }
// this is called _before_ the most of global arguments have been parsed // this is called _before_ most of the global arguments have been parsed
void os::init(void) { void os::init(void) {
char dummy; /* used to get a guess on initial stack address */ char dummy; /* used to get a guess on initial stack address */
// first_hrtime = gethrtime();
// With LinuxThreads the JavaMain thread pid (primordial thread) // With LinuxThreads the JavaMain thread pid (primordial thread)
// is different than the pid of the java launcher thread. // is different than the pid of the java launcher thread.
...@@ -4907,7 +4912,7 @@ void os::init(void) { ...@@ -4907,7 +4912,7 @@ void os::init(void) {
Linux::initialize_system_info(); Linux::initialize_system_info();
// main_thread points to the aboriginal thread // _main_thread points to the thread that created/loaded the JVM.
Linux::_main_thread = pthread_self(); Linux::_main_thread = pthread_self();
Linux::clock_init(); Linux::clock_init();
......
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -137,7 +137,6 @@ class Linux { ...@@ -137,7 +137,6 @@ class Linux {
static address initial_thread_stack_bottom(void) { return _initial_thread_stack_bottom; } static address initial_thread_stack_bottom(void) { return _initial_thread_stack_bottom; }
static uintptr_t initial_thread_stack_size(void) { return _initial_thread_stack_size; } static uintptr_t initial_thread_stack_size(void) { return _initial_thread_stack_size; }
static bool is_initial_thread(void);
static int page_size(void) { return _page_size; } static int page_size(void) { return _page_size; }
static void set_page_size(int val) { _page_size = val; } static void set_page_size(int val) { _page_size = val; }
......
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -200,17 +200,21 @@ static inline stack_t get_stack_info() { ...@@ -200,17 +200,21 @@ static inline stack_t get_stack_info() {
return st; return st;
} }
address os::current_stack_base() { bool os::is_primordial_thread(void) {
int r = thr_main() ; int r = thr_main() ;
guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ; guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
bool is_primordial_thread = r; return r == 1;
}
address os::current_stack_base() {
bool _is_primordial_thread = is_primordial_thread();
// Workaround 4352906, avoid calls to thr_stksegment by // Workaround 4352906, avoid calls to thr_stksegment by
// thr_main after the first one (it looks like we trash // thr_main after the first one (it looks like we trash
// some data, causing the value for ss_sp to be incorrect). // some data, causing the value for ss_sp to be incorrect).
if (!is_primordial_thread || os::Solaris::_main_stack_base == NULL) { if (!_is_primordial_thread || os::Solaris::_main_stack_base == NULL) {
stack_t st = get_stack_info(); stack_t st = get_stack_info();
if (is_primordial_thread) { if (_is_primordial_thread) {
// cache initial value of stack base // cache initial value of stack base
os::Solaris::_main_stack_base = (address)st.ss_sp; os::Solaris::_main_stack_base = (address)st.ss_sp;
} }
...@@ -224,9 +228,7 @@ address os::current_stack_base() { ...@@ -224,9 +228,7 @@ address os::current_stack_base() {
size_t os::current_stack_size() { size_t os::current_stack_size() {
size_t size; size_t size;
int r = thr_main() ; if (!is_primordial_thread()) {
guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
if(!r) {
size = get_stack_info().ss_size; size = get_stack_info().ss_size;
} else { } else {
struct rlimit limits; struct rlimit limits;
...@@ -1277,9 +1279,7 @@ void _handle_uncaught_cxx_exception() { ...@@ -1277,9 +1279,7 @@ void _handle_uncaught_cxx_exception() {
// First crack at OS-specific initialization, from inside the new thread. // First crack at OS-specific initialization, from inside the new thread.
void os::initialize_thread(Thread* thr) { void os::initialize_thread(Thread* thr) {
int r = thr_main() ; if (is_primordial_thread()) {
guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
if (r) {
JavaThread* jt = (JavaThread *)thr; JavaThread* jt = (JavaThread *)thr;
assert(jt != NULL,"Sanity check"); assert(jt != NULL,"Sanity check");
size_t stack_size; size_t stack_size;
...@@ -4904,6 +4904,7 @@ void os::init(void) { ...@@ -4904,6 +4904,7 @@ void os::init(void) {
// (Solaris only) this switches to calls that actually do locking. // (Solaris only) this switches to calls that actually do locking.
ThreadCritical::initialize(); ThreadCritical::initialize();
// main_thread points to the thread that created/loaded the JVM.
main_thread = thr_self(); main_thread = thr_self();
// Constant minimum stack size allowed. It must be at least // Constant minimum stack size allowed. It must be at least
......
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 2015 SAP AG. All rights reserved. * Copyright 2012, 2015 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
...@@ -510,8 +510,8 @@ size_t os::Linux::default_guard_size(os::ThreadType thr_type) { ...@@ -510,8 +510,8 @@ size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
// pthread_attr_getstack() // pthread_attr_getstack()
static void current_stack_region(address * bottom, size_t * size) { static void current_stack_region(address * bottom, size_t * size) {
if (os::Linux::is_initial_thread()) { if (os::is_primordial_thread()) {
// initial thread needs special handling because pthread_getattr_np() // primordial thread needs special handling because pthread_getattr_np()
// may return bogus value. // may return bogus value.
*bottom = os::Linux::initial_thread_stack_bottom(); *bottom = os::Linux::initial_thread_stack_bottom();
*size = os::Linux::initial_thread_stack_size(); *size = os::Linux::initial_thread_stack_size();
......
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -162,8 +162,8 @@ address os::current_stack_pointer() { ...@@ -162,8 +162,8 @@ address os::current_stack_pointer() {
} }
static void current_stack_region(address* bottom, size_t* size) { static void current_stack_region(address* bottom, size_t* size) {
if (os::Linux::is_initial_thread()) { if (os::is_primordial_thread()) {
// initial thread needs special handling because pthread_getattr_np() // primordial thread needs special handling because pthread_getattr_np()
// may return bogus value. // may return bogus value.
*bottom = os::Linux::initial_thread_stack_bottom(); *bottom = os::Linux::initial_thread_stack_bottom();
*size = os::Linux::initial_thread_stack_size(); *size = os::Linux::initial_thread_stack_size();
......
/* /*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -712,8 +712,8 @@ size_t os::Linux::default_guard_size(os::ThreadType thr_type) { ...@@ -712,8 +712,8 @@ size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
// pthread_attr_getstack() // pthread_attr_getstack()
static void current_stack_region(address * bottom, size_t * size) { static void current_stack_region(address * bottom, size_t * size) {
if (os::Linux::is_initial_thread()) { if (os::is_primordial_thread()) {
// initial thread needs special handling because pthread_getattr_np() // primordial thread needs special handling because pthread_getattr_np()
// may return bogus value. // may return bogus value.
*bottom = os::Linux::initial_thread_stack_bottom(); *bottom = os::Linux::initial_thread_stack_bottom();
*size = os::Linux::initial_thread_stack_size(); *size = os::Linux::initial_thread_stack_size();
......
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
...@@ -360,7 +360,7 @@ static void current_stack_region(address *bottom, size_t *size) { ...@@ -360,7 +360,7 @@ static void current_stack_region(address *bottom, size_t *size) {
// The initial thread has a growable stack, and the size reported // The initial thread has a growable stack, and the size reported
// by pthread_attr_getstack is the maximum size it could possibly // by pthread_attr_getstack is the maximum size it could possibly
// be given what currently mapped. This can be huge, so we cap it. // be given what currently mapped. This can be huge, so we cap it.
if (os::Linux::is_initial_thread()) { if (os::is_primordial_thread()) {
stack_bytes = stack_top - stack_bottom; stack_bytes = stack_top - stack_bottom;
if (stack_bytes > JavaThread::stack_size_at_create()) if (stack_bytes > JavaThread::stack_size_at_create())
......
/* /*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -200,7 +200,7 @@ void ThreadLocalAllocBuffer::initialize() { ...@@ -200,7 +200,7 @@ void ThreadLocalAllocBuffer::initialize() {
set_desired_size(initial_desired_size()); set_desired_size(initial_desired_size());
// Following check is needed because at startup the main (primordial) // Following check is needed because at startup the main
// thread is initialized before the heap is. The initialization for // thread is initialized before the heap is. The initialization for
// this thread is redone in startup_initialization below. // this thread is redone in startup_initialization below.
if (Universe::heap() != NULL) { if (Universe::heap() != NULL) {
...@@ -223,7 +223,7 @@ void ThreadLocalAllocBuffer::startup_initialization() { ...@@ -223,7 +223,7 @@ void ThreadLocalAllocBuffer::startup_initialization() {
_global_stats = new GlobalTLABStats(); _global_stats = new GlobalTLABStats();
// During jvm startup, the main (primordial) thread is initialized // During jvm startup, the main thread is initialized
// before the heap is initialized. So reinitialize it now. // before the heap is initialized. So reinitialize it now.
guarantee(Thread::current()->is_Java_thread(), "tlab initialization thread not Java thread"); guarantee(Thread::current()->is_Java_thread(), "tlab initialization thread not Java thread");
Thread::current()->tlab().initialize(); Thread::current()->tlab().initialize();
......
/* /*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1124,6 +1124,10 @@ class CommandLineFlags { ...@@ -1124,6 +1124,10 @@ class CommandLineFlags {
"Use detached threads that are recycled upon termination " \ "Use detached threads that are recycled upon termination " \
"(for Solaris only)") \ "(for Solaris only)") \
\ \
experimental(bool, DisablePrimordialThreadGuardPages, false, \
"Disable the use of stack guard pages if the JVM is loaded " \
"on the primordial process thread") \
\
product(bool, UseLWPSynchronization, true, \ product(bool, UseLWPSynchronization, true, \
"Use LWP-based instead of libthread-based synchronization " \ "Use LWP-based instead of libthread-based synchronization " \
"(SPARC only)") \ "(SPARC only)") \
......
/* /*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -449,7 +449,24 @@ class os: AllStatic { ...@@ -449,7 +449,24 @@ class os: AllStatic {
static bool create_thread(Thread* thread, static bool create_thread(Thread* thread,
ThreadType thr_type, ThreadType thr_type,
size_t stack_size = 0); size_t stack_size = 0);
// The "main thread", also known as "starting thread", is the thread
// that loads/creates the JVM via JNI_CreateJavaVM.
static bool create_main_thread(JavaThread* thread); static bool create_main_thread(JavaThread* thread);
// The primordial thread is the initial process thread. The java
// launcher never uses the primordial thread as the main thread, but
// applications that host the JVM directly may do so. Some platforms
// need special-case handling of the primordial thread if it attaches
// to the VM.
static bool is_primordial_thread(void)
#if defined(_WINDOWS) || defined(BSD)
// No way to identify the primordial thread.
{ return false; }
#else
;
#endif
static bool create_attached_thread(JavaThread* thread); static bool create_attached_thread(JavaThread* thread);
static void pd_start_thread(Thread* thread); static void pd_start_thread(Thread* thread);
static void start_thread(Thread* thread); static void start_thread(Thread* thread);
......
/* /*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -2485,7 +2485,15 @@ void JavaThread::java_resume() { ...@@ -2485,7 +2485,15 @@ void JavaThread::java_resume() {
} }
void JavaThread::create_stack_guard_pages() { void JavaThread::create_stack_guard_pages() {
if (! os::uses_stack_guard_pages() || _stack_guard_state != stack_guard_unused) return; if (!os::uses_stack_guard_pages() ||
_stack_guard_state != stack_guard_unused ||
(DisablePrimordialThreadGuardPages && os::is_primordial_thread())) {
if (TraceThreadEvents) {
tty->print_cr("Stack guard page creation for thread "
UINTX_FORMAT " disabled", os::current_thread_id());
}
return;
}
address low_addr = stack_base() - stack_size(); address low_addr = stack_base() - stack_size();
size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size(); size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
......
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1801,7 +1801,8 @@ inline bool JavaThread::stack_yellow_zone_disabled() { ...@@ -1801,7 +1801,8 @@ inline bool JavaThread::stack_yellow_zone_disabled() {
inline bool JavaThread::stack_yellow_zone_enabled() { inline bool JavaThread::stack_yellow_zone_enabled() {
#ifdef ASSERT #ifdef ASSERT
if (os::uses_stack_guard_pages()) { if (os::uses_stack_guard_pages() &&
!(DisablePrimordialThreadGuardPages && os::is_primordial_thread())) {
assert(_stack_guard_state != stack_guard_unused, "guard pages must be in use"); assert(_stack_guard_state != stack_guard_unused, "guard pages must be in use");
} }
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册