aoqi@0: /* aoqi@0: * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #include "precompiled.hpp" aoqi@0: #include "runtime/frame.inline.hpp" aoqi@0: #include "runtime/thread.inline.hpp" aoqi@0: aoqi@0: // For Forte Analyzer AsyncGetCallTrace profiling support - thread is aoqi@0: // currently interrupted by SIGPROF aoqi@0: // aoqi@0: // NOTE: On Solaris, register windows are flushed in the signal handler aoqi@0: // except for possibly the top frame. aoqi@0: // aoqi@0: bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, aoqi@0: void* ucontext, bool isInJava) { aoqi@0: aoqi@0: assert(Thread::current() == this, "caller must be current thread"); aoqi@0: return pd_get_top_frame(fr_addr, ucontext, isInJava, true); aoqi@0: } aoqi@0: aoqi@0: bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) { aoqi@0: // get ucontext somehow aoqi@0: return pd_get_top_frame(fr_addr, ucontext, isInJava, false); aoqi@0: } aoqi@0: aoqi@0: bool JavaThread::pd_get_top_frame(frame* fr_addr, aoqi@0: void* ucontext, bool isInJava, bool makeWalkable) { aoqi@0: assert(this->is_Java_thread(), "must be JavaThread"); aoqi@0: aoqi@0: JavaThread* jt = (JavaThread *)this; aoqi@0: aoqi@0: if (!isInJava && makeWalkable) { aoqi@0: // make_walkable flushes register windows and grabs last_Java_pc aoqi@0: // which can not be done if the ucontext sp matches last_Java_sp aoqi@0: // stack walking utilities assume last_Java_pc set if marked flushed aoqi@0: jt->frame_anchor()->make_walkable(jt); aoqi@0: } aoqi@0: aoqi@0: // If we have a walkable last_Java_frame, then we should use it aoqi@0: // even if isInJava == true. It should be more reliable than aoqi@0: // ucontext info. aoqi@0: if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) { aoqi@0: *fr_addr = jt->pd_last_frame(); aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: ucontext_t* uc = (ucontext_t*) ucontext; aoqi@0: aoqi@0: // At this point, we don't have a walkable last_Java_frame, so aoqi@0: // we try to glean some information out of the ucontext. aoqi@0: intptr_t* ret_sp; aoqi@0: ExtendedPC addr = os::Solaris::fetch_frame_from_ucontext(this, uc, aoqi@0: &ret_sp, NULL /* ret_fp only used on Solaris X86 */); aoqi@0: if (addr.pc() == NULL || ret_sp == NULL) { aoqi@0: // ucontext wasn't useful aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: frame ret_frame(ret_sp, frame::unpatchable, addr.pc()); aoqi@0: aoqi@0: // we were running Java code when SIGPROF came in aoqi@0: if (isInJava) { aoqi@0: aoqi@0: aoqi@0: // If the frame we got is safe then it is most certainly valid aoqi@0: if (ret_frame.safe_for_sender(jt)) { aoqi@0: *fr_addr = ret_frame; aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: // If it isn't safe then we can try several things to try and get aoqi@0: // a good starting point. aoqi@0: // aoqi@0: // On sparc the frames are almost certainly walkable in the sense aoqi@0: // of sp/fp linkages. However because of recycling of windows if aoqi@0: // a piece of code does multiple save's where the initial save creates aoqi@0: // a real frame with a return pc and the succeeding save's are used to aoqi@0: // simply get free registers and have no real pc then the pc linkage on these aoqi@0: // "inner" temporary frames will be bogus. aoqi@0: // Since there is in general only a nesting level like aoqi@0: // this one deep in general we'll try and unwind such an "inner" frame aoqi@0: // here ourselves and see if it makes sense aoqi@0: aoqi@0: frame unwind_frame(ret_frame.fp(), frame::unpatchable, addr.pc()); aoqi@0: aoqi@0: if (unwind_frame.safe_for_sender(jt)) { aoqi@0: *fr_addr = unwind_frame; aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: // Well that didn't work. Most likely we're toast on this tick aoqi@0: // The previous code would try this. I think it is dubious in light aoqi@0: // of changes to safe_for_sender and the unwind trick above but aoqi@0: // if it gets us a safe frame who wants to argue. aoqi@0: aoqi@0: // If we have a last_Java_sp, then the SIGPROF signal caught us aoqi@0: // right when we were transitioning from _thread_in_Java to a new aoqi@0: // JavaThreadState. We use last_Java_sp instead of the sp from aoqi@0: // the ucontext since it should be more reliable. aoqi@0: aoqi@0: if (jt->has_last_Java_frame()) { aoqi@0: ret_sp = jt->last_Java_sp(); aoqi@0: frame ret_frame2(ret_sp, frame::unpatchable, addr.pc()); aoqi@0: if (ret_frame2.safe_for_sender(jt)) { aoqi@0: *fr_addr = ret_frame2; aoqi@0: return true; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: // This is the best we can do. We will only be able to decode the top frame aoqi@0: aoqi@0: *fr_addr = ret_frame; aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: // At this point, we know we weren't running Java code. We might aoqi@0: // have a last_Java_sp, but we don't have a walkable frame. aoqi@0: // However, we might still be able to construct something useful aoqi@0: // if the thread was running native code. aoqi@0: if (jt->has_last_Java_frame()) { aoqi@0: assert(!jt->frame_anchor()->walkable(), "case covered above"); aoqi@0: aoqi@0: frame ret_frame(jt->last_Java_sp(), frame::unpatchable, addr.pc()); aoqi@0: *fr_addr = ret_frame; aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: // nothing else to try but what we found initially aoqi@0: aoqi@0: *fr_addr = ret_frame; aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: void JavaThread::cache_global_variables() { } aoqi@0: