--- old/src/hotspot/cpu/aarch64/frame_aarch64.cpp 2020-02-11 20:30:52.461517490 -0500 +++ new/src/hotspot/cpu/aarch64/frame_aarch64.cpp 2020-02-11 20:30:51.328504941 -0500 @@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -59,16 +59,8 @@ address unextended_sp = (address)_unextended_sp; // 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) - bool sp_safe = (sp < thread->stack_base()) && - (sp >= thread->stack_base() - usable_stack_size); - - - if (!sp_safe) { + if (!thread->is_in_usable_stack(sp)) { return false; } @@ -566,7 +558,7 @@ 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 return true; --- old/src/hotspot/cpu/arm/frame_arm.cpp 2020-02-11 20:30:56.107557871 -0500 +++ new/src/hotspot/cpu/arm/frame_arm.cpp 2020-02-11 20:30:54.935544891 -0500 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -57,21 +57,14 @@ address fp = (address)_fp; address unextended_sp = (address)_unextended_sp; - 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; - + // consider stack guards when trying to determine "safe" stack pointers // sp must be within the usable part of the stack (not in guards) - bool sp_safe = (sp != NULL && - (sp <= thread->stack_base()) && - (sp >= thread->stack_base() - usable_stack_size)); - - if (!sp_safe) { + if (!thread->is_in_usable_stack(sp)) { return false; } bool unextended_sp_safe = (unextended_sp != NULL && - (unextended_sp <= thread->stack_base()) && + (unextended_sp < thread->stack_base()) && (unextended_sp >= sp)); if (!unextended_sp_safe) { return false; @@ -80,7 +73,7 @@ // We know sp/unextended_sp are safe. Only fp is questionable here. bool fp_safe = (fp != NULL && - (fp <= thread->stack_base()) && + (fp < thread->stack_base()) && fp >= sp); if (_cb != NULL ) { @@ -148,7 +141,7 @@ // is really a frame pointer. 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) { return false; @@ -178,7 +171,7 @@ // Could be the call_stub if (StubRoutines::returns_to_call_stub(sender_pc)) { 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) { return false; @@ -191,7 +184,7 @@ // Validate the JavaCallWrapper an entry frame must have 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; } @@ -501,7 +494,7 @@ 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 --- old/src/hotspot/cpu/ppc/frame_ppc.cpp 2020-02-11 20:30:59.730597998 -0500 +++ new/src/hotspot/cpu/ppc/frame_ppc.cpp 2020-02-11 20:30:58.512584508 -0500 @@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -55,17 +55,9 @@ address fp = (address)_fp; address unextended_sp = (address)_unextended_sp; - // 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; - + // consider stack guards when trying to determine "safe" stack pointers // sp must be within the usable part of the stack (not in guards) - bool sp_safe = (sp < thread->stack_base()) && - (sp >= thread->stack_base() - usable_stack_size); - - - if (!sp_safe) { + if (!thread->is_in_usable_stack(sp)) { return false; } @@ -77,10 +69,10 @@ } // 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. // 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); // We know sp/unextended_sp are safe, only fp is questionable here @@ -140,7 +132,7 @@ // sender_fp must be within the stack and above (but not // 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; } --- old/src/hotspot/cpu/s390/frame_s390.cpp 2020-02-11 20:31:03.347638058 -0500 +++ new/src/hotspot/cpu/s390/frame_s390.cpp 2020-02-11 20:31:02.168625000 -0500 @@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -59,17 +59,9 @@ address fp = (address)_fp; address unextended_sp = (address)_unextended_sp; - // 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; - + // consider stack guards when trying to determine "safe" stack pointers // sp must be within the usable part of the stack (not in guards) - bool sp_safe = (sp < thread->stack_base()) && - (sp >= thread->stack_base() - usable_stack_size); - - - if (!sp_safe) { + if (!thread->is_in_usable_stack(sp)) { return false; } @@ -81,10 +73,10 @@ } // 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. // 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); // We know sp/unextended_sp are safe, only fp is questionable here @@ -144,7 +136,7 @@ // sender_fp must be within the stack and above (but not // 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; } --- old/src/hotspot/cpu/sparc/frame_sparc.cpp 2020-02-11 20:31:06.940677852 -0500 +++ new/src/hotspot/cpu/sparc/frame_sparc.cpp 2020-02-11 20:31:05.744664606 -0500 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -177,22 +177,21 @@ address _SP = (address) sp(); address _FP = (address) fp(); 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; } // 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); if (!unextended_sp_safe) return false; // 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); // We know sp/unextended_sp are safe only fp is questionable here @@ -252,7 +251,7 @@ // 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); if (!sender_fp_safe) { @@ -280,7 +279,7 @@ 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; } @@ -672,7 +671,7 @@ 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 return true; --- old/src/hotspot/cpu/x86/frame_x86.cpp 2020-02-11 20:31:10.592718300 -0500 +++ new/src/hotspot/cpu/x86/frame_x86.cpp 2020-02-11 20:31:09.475705929 -0500 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -57,16 +57,8 @@ address unextended_sp = (address)_unextended_sp; // 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) - bool sp_safe = (sp < thread->stack_base()) && - (sp >= thread->stack_base() - usable_stack_size); - - - if (!sp_safe) { + if (!thread->is_in_usable_stack(sp)) { return false; } @@ -553,7 +545,7 @@ 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 return true; --- old/src/hotspot/os/linux/os_linux.cpp 2020-02-11 20:31:14.209758360 -0500 +++ new/src/hotspot/os/linux/os_linux.cpp 2020-02-11 20:31:13.012745103 -0500 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -719,7 +719,7 @@ assert(t->osthread()->expanding_stack(), "expand should be set"); 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; sigfillset(&mask_all); pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset); --- old/src/hotspot/os/windows/os_windows.cpp 2020-02-11 20:31:17.832798487 -0500 +++ new/src/hotspot/os/windows/os_windows.cpp 2020-02-11 20:31:16.660785506 -0500 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -2542,7 +2542,7 @@ // PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; 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 & (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); os::commit_memory((char *)addr, thread->stack_base() - addr, --- old/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp 2020-02-11 20:31:21.557839743 -0500 +++ new/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp 2020-02-11 20:31:20.341826275 -0500 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -336,8 +336,7 @@ return 1; } // check if fault address is within thread stack - if (addr < thread->stack_base() && - addr >= thread->stack_base() - thread->stack_size()) { + if (thread->on_local_stack(addr)) { // stack overflow if (thread->in_stack_yellow_reserved_zone(addr)) { thread->disable_stack_yellow_reserved_zone(); --- old/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp 2020-02-11 20:31:25.080878762 -0500 +++ new/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp 2020-02-11 20:31:23.902865715 -0500 @@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -63,7 +63,7 @@ if (ret_frame.is_interpreted_frame()) { 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; } const Method *m = (const Method*)(istate->method); --- old/src/hotspot/share/runtime/thread.cpp 2020-02-11 20:31:28.690918745 -0500 +++ new/src/hotspot/share/runtime/thread.cpp 2020-02-11 20:31:27.550906119 -0500 @@ -387,7 +387,7 @@ log_debug(os, thread)("Thread " UINTX_FORMAT " stack dimensions: " 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); // Perform initialization actions @@ -1018,24 +1018,13 @@ } #endif // ASSERT +// Check for adr in the live portion of our stack. bool Thread::is_in_stack(address adr) const { assert(Thread::current() == this, "is_in_stack can only be called from current thread"); address end = os::current_stack_pointer(); - // Allow non Java threads to call this without stack_base - 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)); + return (stack_base() > adr && adr >= end); } - // 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 // used for compilation in the future. If that change is made, the need for these methods @@ -1830,6 +1819,14 @@ } +// 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() { if (_terminated == _vm_exited) { // _vm_exited is set at safepoint, and Threads_lock is never released --- old/src/hotspot/share/runtime/thread.hpp 2020-02-11 20:31:32.214957775 -0500 +++ new/src/hotspot/share/runtime/thread.hpp 2020-02-11 20:31:31.060944993 -0500 @@ -687,12 +687,15 @@ // Used by fast lock support virtual bool is_lock_owned(address adr) const; - // Check if address is in the stack of the thread (not just for locks). - // Warning: the method can only be used on the running thread + // Check if address is in the live stack of this thread (not just for locks). + // Warning: can only be called by the current thread on itself. bool is_in_stack(address adr) const; - // Check if address is in the usable part of the stack (excludes protected - // guard pages) - bool is_in_usable_stack(address adr) const; + + // Check if address in the stack mapped to this thread. Used mainly in + // 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 // creation fails due to lack of memory, too many threads etc. @@ -728,11 +731,6 @@ void record_stack_base_and_size(); 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; } void set_lgrp_id(int value) { _lgrp_id = value; } @@ -1732,6 +1730,11 @@ 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 void set_do_not_unlock(void) { _do_not_unlock_if_synchronized = true; } void clr_do_not_unlock(void) { _do_not_unlock_if_synchronized = false; }