8234372: Investigate use of Thread::stack_base() and queries for "in stack"

Reviewed-by: dcubed, stuefe
This commit is contained in:
David Holmes 2020-02-12 20:19:50 -05:00
parent 25c5a23695
commit 4e4d1f2b4d
12 changed files with 68 additions and 109 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2014, Red Hat Inc. 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.
* *
@ -59,16 +59,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
address unextended_sp = (address)_unextended_sp; address unextended_sp = (address)_unextended_sp;
// consider stack guards when trying to determine "safe" stack pointers // consider stack guards when trying to determine "safe" stack pointers
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
(JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size()) : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;
// sp must be within the usable part of the stack (not in guards) // sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp < thread->stack_base()) && if (!thread->is_in_usable_stack(sp)) {
(sp >= thread->stack_base() - usable_stack_size);
if (!sp_safe) {
return false; return false;
} }
@ -566,7 +558,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
address locals = (address) *interpreter_frame_locals_addr(); address locals = (address) *interpreter_frame_locals_addr();
if (locals > thread->stack_base() || locals < (address) fp()) return false; if (locals >= thread->stack_base() || locals < (address) fp()) return false;
// We'd have to be pretty unlucky to be mislead at this point // We'd have to be pretty unlucky to be mislead at this point
return true; return true;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2020, 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
@ -57,21 +57,14 @@ bool frame::safe_for_sender(JavaThread *thread) {
address fp = (address)_fp; address fp = (address)_fp;
address unextended_sp = (address)_unextended_sp; address unextended_sp = (address)_unextended_sp;
static size_t stack_guard_size = os::uses_stack_guard_pages() ? // consider stack guards when trying to determine "safe" stack pointers
(JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size()) : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;
// sp must be within the usable part of the stack (not in guards) // sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp != NULL && if (!thread->is_in_usable_stack(sp)) {
(sp <= thread->stack_base()) &&
(sp >= thread->stack_base() - usable_stack_size));
if (!sp_safe) {
return false; return false;
} }
bool unextended_sp_safe = (unextended_sp != NULL && bool unextended_sp_safe = (unextended_sp != NULL &&
(unextended_sp <= thread->stack_base()) && (unextended_sp < thread->stack_base()) &&
(unextended_sp >= sp)); (unextended_sp >= sp));
if (!unextended_sp_safe) { if (!unextended_sp_safe) {
return false; return false;
@ -80,7 +73,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// We know sp/unextended_sp are safe. Only fp is questionable here. // We know sp/unextended_sp are safe. Only fp is questionable here.
bool fp_safe = (fp != NULL && bool fp_safe = (fp != NULL &&
(fp <= thread->stack_base()) && (fp < thread->stack_base()) &&
fp >= sp); fp >= sp);
if (_cb != NULL ) { if (_cb != NULL ) {
@ -148,7 +141,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// is really a frame pointer. // is really a frame pointer.
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset + link_offset); intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset + link_offset);
bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp); bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) { if (!saved_fp_safe) {
return false; return false;
@ -178,7 +171,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// Could be the call_stub // Could be the call_stub
if (StubRoutines::returns_to_call_stub(sender_pc)) { if (StubRoutines::returns_to_call_stub(sender_pc)) {
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset + link_offset); intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset + link_offset);
bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp >= sender_sp); bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) { if (!saved_fp_safe) {
return false; return false;
@ -191,7 +184,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// Validate the JavaCallWrapper an entry frame must have // Validate the JavaCallWrapper an entry frame must have
address jcw = (address)sender.entry_frame_call_wrapper(); address jcw = (address)sender.entry_frame_call_wrapper();
bool jcw_safe = (jcw <= thread->stack_base()) && (jcw > (address)sender.fp()); bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)sender.fp());
return jcw_safe; return jcw_safe;
} }
@ -501,7 +494,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
address locals = (address) *interpreter_frame_locals_addr(); address locals = (address) *interpreter_frame_locals_addr();
if (locals > thread->stack_base() || locals < (address) fp()) return false; if (locals >= thread->stack_base() || locals < (address) fp()) return false;
// We'd have to be pretty unlucky to be mislead at this point // We'd have to be pretty unlucky to be mislead at this point

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. All rights reserved. * Copyright (c) 2012, 2017 SAP SE. 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.
* *
@ -55,17 +55,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
address fp = (address)_fp; address fp = (address)_fp;
address unextended_sp = (address)_unextended_sp; address unextended_sp = (address)_unextended_sp;
// Consider stack guards when trying to determine "safe" stack pointers // consider stack guards when trying to determine "safe" stack pointers
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_reserved_zone_size() : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;
// sp must be within the usable part of the stack (not in guards) // sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp < thread->stack_base()) && if (!thread->is_in_usable_stack(sp)) {
(sp >= thread->stack_base() - usable_stack_size);
if (!sp_safe) {
return false; return false;
} }
@ -77,10 +69,10 @@ bool frame::safe_for_sender(JavaThread *thread) {
} }
// An fp must be within the stack and above (but not equal) sp. // An fp must be within the stack and above (but not equal) sp.
bool fp_safe = (fp <= thread->stack_base()) && (fp > sp); bool fp_safe = (fp < thread->stack_base()) && (fp > sp);
// An interpreter fp must be within the stack and above (but not equal) sp. // An interpreter fp must be within the stack and above (but not equal) sp.
// Moreover, it must be at least the size of the ijava_state structure. // Moreover, it must be at least the size of the ijava_state structure.
bool fp_interp_safe = (fp <= thread->stack_base()) && (fp > sp) && bool fp_interp_safe = (fp < thread->stack_base()) && (fp > sp) &&
((fp - sp) >= ijava_state_size); ((fp - sp) >= ijava_state_size);
// We know sp/unextended_sp are safe, only fp is questionable here // We know sp/unextended_sp are safe, only fp is questionable here
@ -140,7 +132,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// sender_fp must be within the stack and above (but not // sender_fp must be within the stack and above (but not
// equal) current frame's fp. // equal) current frame's fp.
if (sender_fp > thread->stack_base() || sender_fp <= fp) { if (sender_fp >= thread->stack_base() || sender_fp <= fp) {
return false; return false;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, SAP SE. All rights reserved. * Copyright (c) 2016, 2019, SAP SE. 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.
* *
@ -59,17 +59,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
address fp = (address)_fp; address fp = (address)_fp;
address unextended_sp = (address)_unextended_sp; address unextended_sp = (address)_unextended_sp;
// Consider stack guards when trying to determine "safe" stack pointers // consider stack guards when trying to determine "safe" stack pointers
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_reserved_zone_size() : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;
// sp must be within the usable part of the stack (not in guards) // sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp < thread->stack_base()) && if (!thread->is_in_usable_stack(sp)) {
(sp >= thread->stack_base() - usable_stack_size);
if (!sp_safe) {
return false; return false;
} }
@ -81,10 +73,10 @@ bool frame::safe_for_sender(JavaThread *thread) {
} }
// An fp must be within the stack and above (but not equal) sp. // An fp must be within the stack and above (but not equal) sp.
bool fp_safe = (fp <= thread->stack_base()) && (fp > sp); bool fp_safe = (fp < thread->stack_base()) && (fp > sp);
// An interpreter fp must be within the stack and above (but not equal) sp. // An interpreter fp must be within the stack and above (but not equal) sp.
// Moreover, it must be at least the size of the z_ijava_state structure. // Moreover, it must be at least the size of the z_ijava_state structure.
bool fp_interp_safe = (fp <= thread->stack_base()) && (fp > sp) && bool fp_interp_safe = (fp < thread->stack_base()) && (fp > sp) &&
((fp - sp) >= z_ijava_state_size); ((fp - sp) >= z_ijava_state_size);
// We know sp/unextended_sp are safe, only fp is questionable here // We know sp/unextended_sp are safe, only fp is questionable here
@ -144,7 +136,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// sender_fp must be within the stack and above (but not // sender_fp must be within the stack and above (but not
// equal) current frame's fp. // equal) current frame's fp.
if (sender_fp > thread->stack_base() || sender_fp <= fp) { if (sender_fp >= thread->stack_base() || sender_fp <= fp) {
return false; return false;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2020, 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
@ -177,22 +177,21 @@ bool frame::safe_for_sender(JavaThread *thread) {
address _SP = (address) sp(); address _SP = (address) sp();
address _FP = (address) fp(); address _FP = (address) fp();
address _UNEXTENDED_SP = (address) unextended_sp(); address _UNEXTENDED_SP = (address) unextended_sp();
// sp must be within the stack
bool sp_safe = (_SP <= thread->stack_base()) &&
(_SP >= thread->stack_base() - thread->stack_size());
if (!sp_safe) { // consider stack guards when trying to determine "safe" stack pointers
// sp must be within the usable part of the stack (not in guards)
if (!thread->is_in_usable_stack(_SP)) {
return false; return false;
} }
// unextended sp must be within the stack and above or equal sp // unextended sp must be within the stack and above or equal sp
bool unextended_sp_safe = (_UNEXTENDED_SP <= thread->stack_base()) && bool unextended_sp_safe = (_UNEXTENDED_SP < thread->stack_base()) &&
(_UNEXTENDED_SP >= _SP); (_UNEXTENDED_SP >= _SP);
if (!unextended_sp_safe) return false; if (!unextended_sp_safe) return false;
// an fp must be within the stack and above (but not equal) sp // an fp must be within the stack and above (but not equal) sp
bool fp_safe = (_FP <= thread->stack_base()) && bool fp_safe = (_FP < thread->stack_base()) &&
(_FP > _SP); (_FP > _SP);
// We know sp/unextended_sp are safe only fp is questionable here // We know sp/unextended_sp are safe only fp is questionable here
@ -252,7 +251,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// an fp must be within the stack and above (but not equal) current frame's _FP // an fp must be within the stack and above (but not equal) current frame's _FP
bool sender_fp_safe = (sender_fp <= thread->stack_base()) && bool sender_fp_safe = (sender_fp < thread->stack_base()) &&
(sender_fp > _FP); (sender_fp > _FP);
if (!sender_fp_safe) { if (!sender_fp_safe) {
@ -280,7 +279,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
address jcw = (address)sender.entry_frame_call_wrapper(); address jcw = (address)sender.entry_frame_call_wrapper();
bool jcw_safe = (jcw <= thread->stack_base()) && (jcw > sender_fp); bool jcw_safe = (jcw < thread->stack_base()) && (jcw > sender_fp);
return jcw_safe; return jcw_safe;
} }
@ -672,7 +671,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
address locals = (address) *interpreter_frame_locals_addr(); address locals = (address) *interpreter_frame_locals_addr();
if (locals > thread->stack_base() || locals < (address) fp()) return false; if (locals >= thread->stack_base() || locals < (address) fp()) return false;
// We'd have to be pretty unlucky to be mislead at this point // We'd have to be pretty unlucky to be mislead at this point
return true; return true;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2020, 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
@ -57,16 +57,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
address unextended_sp = (address)_unextended_sp; address unextended_sp = (address)_unextended_sp;
// consider stack guards when trying to determine "safe" stack pointers // consider stack guards when trying to determine "safe" stack pointers
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size() : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;
// sp must be within the usable part of the stack (not in guards) // sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp < thread->stack_base()) && if (!thread->is_in_usable_stack(sp)) {
(sp >= thread->stack_base() - usable_stack_size);
if (!sp_safe) {
return false; return false;
} }
@ -553,7 +545,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
address locals = (address) *interpreter_frame_locals_addr(); address locals = (address) *interpreter_frame_locals_addr();
if (locals > thread->stack_base() || locals < (address) fp()) return false; if (locals >= thread->stack_base() || locals < (address) fp()) return false;
// We'd have to be pretty unlucky to be mislead at this point // We'd have to be pretty unlucky to be mislead at this point
return true; return true;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2020, 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
@ -719,7 +719,7 @@ bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
assert(t->osthread()->expanding_stack(), "expand should be set"); assert(t->osthread()->expanding_stack(), "expand should be set");
assert(t->stack_base() != NULL, "stack_base was not initialized"); assert(t->stack_base() != NULL, "stack_base was not initialized");
if (addr < t->stack_base() && addr >= t->stack_reserved_zone_base()) { if (t->is_in_usable_stack(addr)) {
sigset_t mask_all, old_sigset; sigset_t mask_all, old_sigset;
sigfillset(&mask_all); sigfillset(&mask_all);
pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset); pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2020, 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
@ -2542,7 +2542,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
// //
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
address addr = (address) exceptionRecord->ExceptionInformation[1]; address addr = (address) exceptionRecord->ExceptionInformation[1];
if (addr > thread->stack_reserved_zone_base() && addr < thread->stack_base()) { if (thread->is_in_usable_stack(addr)) {
addr = (address)((uintptr_t)addr & addr = (address)((uintptr_t)addr &
(~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); (~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
os::commit_memory((char *)addr, thread->stack_base() - addr, os::commit_memory((char *)addr, thread->stack_base() - addr,

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2020, 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
@ -336,8 +336,7 @@ extern "C" int JVM_handle_linux_signal(int sig, siginfo_t* info,
return 1; return 1;
} }
// check if fault address is within thread stack // check if fault address is within thread stack
if (addr < thread->stack_base() && if (thread->on_local_stack(addr)) {
addr >= thread->stack_base() - thread->stack_size()) {
// stack overflow // stack overflow
if (thread->in_stack_yellow_reserved_zone(addr)) { if (thread->in_stack_yellow_reserved_zone(addr)) {
thread->disable_stack_yellow_reserved_zone(); thread->disable_stack_yellow_reserved_zone();

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019 SAP SE. All rights reserved. * Copyright (c) 2016, 2019 SAP SE. 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.
* *
@ -63,7 +63,7 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
if (ret_frame.is_interpreted_frame()) { if (ret_frame.is_interpreted_frame()) {
frame::z_ijava_state* istate = ret_frame.ijava_state_unchecked(); frame::z_ijava_state* istate = ret_frame.ijava_state_unchecked();
if (stack_base() >= (address)istate && (address)istate > stack_end()) { if (on_local_stack((address)istate)) {
return false; return false;
} }
const Method *m = (const Method*)(istate->method); const Method *m = (const Method*)(istate->method);

View file

@ -387,7 +387,7 @@ void Thread::call_run() {
log_debug(os, thread)("Thread " UINTX_FORMAT " stack dimensions: " log_debug(os, thread)("Thread " UINTX_FORMAT " stack dimensions: "
PTR_FORMAT "-" PTR_FORMAT " (" SIZE_FORMAT "k).", PTR_FORMAT "-" PTR_FORMAT " (" SIZE_FORMAT "k).",
os::current_thread_id(), p2i(stack_base() - stack_size()), os::current_thread_id(), p2i(stack_end()),
p2i(stack_base()), stack_size()/1024); p2i(stack_base()), stack_size()/1024);
// Perform <ChildClass> initialization actions // Perform <ChildClass> initialization actions
@ -1018,24 +1018,13 @@ void Thread::check_for_valid_safepoint_state() {
} }
#endif // ASSERT #endif // ASSERT
// Check for adr in the live portion of our stack.
bool Thread::is_in_stack(address adr) const { bool Thread::is_in_stack(address adr) const {
assert(Thread::current() == this, "is_in_stack can only be called from current thread"); assert(Thread::current() == this, "is_in_stack can only be called from current thread");
address end = os::current_stack_pointer(); address end = os::current_stack_pointer();
// Allow non Java threads to call this without stack_base return (stack_base() > adr && adr >= end);
if (_stack_base == NULL) return true;
if (stack_base() > adr && adr >= end) return true;
return false;
} }
bool Thread::is_in_usable_stack(address adr) const {
size_t stack_guard_size = os::uses_stack_guard_pages() ? JavaThread::stack_guard_zone_size() : 0;
size_t usable_stack_size = _stack_size - stack_guard_size;
return ((adr < stack_base()) && (adr >= stack_base() - usable_stack_size));
}
// We had to move these methods here, because vm threads get into ObjectSynchronizer::enter // We had to move these methods here, because vm threads get into ObjectSynchronizer::enter
// However, there is a note in JavaThread::is_lock_owned() about the VM threads not being // However, there is a note in JavaThread::is_lock_owned() about the VM threads not being
// used for compilation in the future. If that change is made, the need for these methods // used for compilation in the future. If that change is made, the need for these methods
@ -1830,6 +1819,14 @@ bool JavaThread::reguard_stack(void) {
} }
// Check for adr in the usable portion of this thread's stack.
bool JavaThread::is_in_usable_stack(address adr) const {
size_t stack_guard_size = os::uses_stack_guard_pages() ? JavaThread::stack_guard_zone_size() : 0;
size_t usable_stack_size = _stack_size - stack_guard_size;
return ((stack_base() > adr) && (adr >= (stack_base() - usable_stack_size)));
}
void JavaThread::block_if_vm_exited() { void JavaThread::block_if_vm_exited() {
if (_terminated == _vm_exited) { if (_terminated == _vm_exited) {
// _vm_exited is set at safepoint, and Threads_lock is never released // _vm_exited is set at safepoint, and Threads_lock is never released

View file

@ -687,12 +687,15 @@ class Thread: public ThreadShadow {
// Used by fast lock support // Used by fast lock support
virtual bool is_lock_owned(address adr) const; virtual bool is_lock_owned(address adr) const;
// Check if address is in the stack of the thread (not just for locks). // Check if address is in the live stack of this thread (not just for locks).
// Warning: the method can only be used on the running thread // Warning: can only be called by the current thread on itself.
bool is_in_stack(address adr) const; bool is_in_stack(address adr) const;
// Check if address is in the usable part of the stack (excludes protected
// guard pages) // Check if address in the stack mapped to this thread. Used mainly in
bool is_in_usable_stack(address adr) const; // error reporting (so has to include guard zone) and frame printing.
bool on_local_stack(address adr) const {
return (_stack_base > adr && adr >= stack_end());
}
// Sets this thread as starting thread. Returns failure if thread // Sets this thread as starting thread. Returns failure if thread
// creation fails due to lack of memory, too many threads etc. // creation fails due to lack of memory, too many threads etc.
@ -728,11 +731,6 @@ protected:
void record_stack_base_and_size(); void record_stack_base_and_size();
void register_thread_stack_with_NMT() NOT_NMT_RETURN; void register_thread_stack_with_NMT() NOT_NMT_RETURN;
bool on_local_stack(address adr) const {
// QQQ this has knowledge of direction, ought to be a stack method
return (_stack_base > adr && adr >= stack_end());
}
int lgrp_id() const { return _lgrp_id; } int lgrp_id() const { return _lgrp_id; }
void set_lgrp_id(int value) { _lgrp_id = value; } void set_lgrp_id(int value) { _lgrp_id = value; }
@ -1732,6 +1730,11 @@ class JavaThread: public Thread {
stack_end() + MAX2(JavaThread::stack_guard_zone_size(), JavaThread::stack_shadow_zone_size()); stack_end() + MAX2(JavaThread::stack_guard_zone_size(), JavaThread::stack_shadow_zone_size());
} }
// Check if address is in the usable part of the stack (excludes protected
// guard pages). Can be applied to any thread and is an approximation for
// using is_in_stack when the query has to happen from another thread.
bool is_in_usable_stack(address adr) const;
// Misc. accessors/mutators // Misc. accessors/mutators
void set_do_not_unlock(void) { _do_not_unlock_if_synchronized = true; } void set_do_not_unlock(void) { _do_not_unlock_if_synchronized = true; }
void clr_do_not_unlock(void) { _do_not_unlock_if_synchronized = false; } void clr_do_not_unlock(void) { _do_not_unlock_if_synchronized = false; }