< prev index next >

src/hotspot/cpu/ppc/frame_ppc.cpp

Print this page
rev 51053 : JFR profiling for PPC64
* * *
PPC64: jfr profiling

*** 47,64 **** } #endif // ASSERT bool frame::safe_for_sender(JavaThread *thread) { bool safe = false; ! address cursp = (address)sp(); ! address curfp = (address)fp(); ! if ((cursp != NULL && curfp != NULL && ! (cursp <= thread->stack_base() && cursp >= thread->stack_base() - thread->stack_size())) && ! (curfp <= thread->stack_base() && curfp >= thread->stack_base() - thread->stack_size())) { ! safe = true; } ! return safe; } bool frame::is_interpreted_frame() const { return Interpreter::contains(pc()); } --- 47,196 ---- } #endif // ASSERT bool frame::safe_for_sender(JavaThread *thread) { bool safe = false; ! address sp = (address)_sp; ! 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_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) { ! return false; ! } ! ! // unextended sp must be within the stack and above or equal sp ! 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()) && (fp > sp) && ((fp - sp) >= (ijava_state_size + top_ijava_frame_abi_size)); ! ! // We know sp/unextended_sp are safe only fp is questionable here ! ! // If the current frame is known to the code cache then we can attempt to ! // to construct the sender and do some validation of it. This goes a long way ! // toward eliminating issues when we get in frame construction code ! ! if (_cb != NULL ) { ! // First check if frame is complete and tester is reliable ! // Unfortunately we can only check frame complete for runtime stubs and nmethod ! // other generic buffer blobs are more problematic so we just assume they are ! // ok. adapter blobs never have a frame complete and are never ok. ! if (!_cb->is_frame_complete_at(_pc)) { ! if (_cb->is_compiled() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) { ! return false; ! } ! } ! ! // Could just be some random pointer within the codeBlob ! if (!_cb->code_contains(_pc)) { ! return false; ! } ! ! // Entry frame checks ! if (is_entry_frame()) { ! // an entry frame must have a valid fp. ! return fp_safe && is_entry_frame_valid(thread); ! } ! ! if (is_interpreted_frame() && !fp_safe) { ! return false; ! } ! ! abi_minframe* sender_abi = (abi_minframe*) fp; ! intptr_t* sender_sp = (intptr_t*) fp; ! address sender_pc = (address) sender_abi->lr;; ! ! // We must always be able to find a recognizable pc ! CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc); ! if (sender_pc == NULL || sender_blob == NULL) { ! return false; ! } ! ! // Could be a zombie method ! if (sender_blob->is_zombie() || sender_blob->is_unloaded()) { ! return false; ! } ! ! // It should be safe to construct the sender though it might not be valid ! ! frame sender(sender_sp, sender_pc); ! ! // Do we have a valid fp? ! address sender_fp = (address) sender.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()) && (sender_fp > fp); ! ! if (!sender_fp_safe) { ! return false; ! } ! ! // If the potential sender is the interpreter then we can do some more checking ! if (Interpreter::contains(sender_pc)) { ! return sender.is_interpreted_frame_valid(thread); ! } ! ! // Could just be some random pointer within the codeBlob ! if (!sender.cb()->code_contains(sender_pc)) { ! return false; ! } ! ! // We should never be able to see an adapter if the current frame is something from code cache ! if (sender_blob->is_adapter_blob()) { ! return false; ! } ! ! if (sender.is_entry_frame()) { ! // Validate the JavaCallWrapper an entry frame must have ! ! address jcw = (address)sender.entry_frame_call_wrapper(); ! ! bool jcw_safe = (jcw <= thread->stack_base()) && (jcw > sender_fp); ! return jcw_safe; } ! ! // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size ! // because you must allocate window space ! if (sender_blob->frame_size() <= 0) { ! return false; ! } ! ! // Could put some more validation for the potential non-interpreted sender ! // frame we'd create by calling sender if I could think of any. Wait for next crash in forte... ! ! // One idea is seeing if the sender_pc we have is one that we'd expect to call to current cb ! ! // We've validated the potential sender that would be created ! ! return true; ! ! } ! ! // Must be native-compiled frame. Since sender will try and use fp to find ! // linkages it must be safe ! ! if (!fp_safe) return false; ! ! // could try and do some more potential verification of native frame if we could think of some... ! ! return true; } bool frame::is_interpreted_frame() const { return Interpreter::contains(pc()); }
< prev index next >