forte.cpp revision 0
0N/A/*
0N/A * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0N/A * CA 95054 USA or visit www.sun.com if you need additional information or
0N/A * have any questions.
0N/A *
0N/A */
0N/A
0N/A# include "incls/_precompiled.incl"
0N/A# include "incls/_forte.cpp.incl"
0N/A
0N/A
0N/A//-------------------------------------------------------
0N/A
0N/A// Native interfaces for use by Forte tools.
0N/A
0N/A
0N/A#ifndef IA64
0N/A
0N/Aclass vframeStreamForte : public vframeStreamCommon {
0N/A public:
0N/A // constructor that starts with sender of frame fr (top_frame)
0N/A vframeStreamForte(JavaThread *jt, frame fr, bool stop_at_java_call_stub);
0N/A void forte_next();
0N/A};
0N/A
0N/A
0N/Astatic void forte_is_walkable_compiled_frame(frame* fr, RegisterMap* map,
0N/A bool* is_compiled_p, bool* is_walkable_p);
0N/Astatic bool forte_is_walkable_interpreted_frame(frame* fr,
0N/A methodOop* method_p, int* bci_p);
0N/A
0N/A
0N/A// A Forte specific version of frame:safe_for_sender().
0N/Astatic bool forte_safe_for_sender(frame* fr, JavaThread *thread) {
0N/A bool ret_value = false; // be pessimistic
0N/A
0N/A#ifdef COMPILER2
0N/A#if defined(IA32) || defined(AMD64)
0N/A {
0N/A // This check is the same as the standard safe_for_sender()
0N/A // on IA32 or AMD64 except that NULL FP values are tolerated
0N/A // for C2.
0N/A address sp = (address)fr->sp();
0N/A address fp = (address)fr->fp();
0N/A ret_value = sp != NULL && sp <= thread->stack_base() &&
0N/A sp >= thread->stack_base() - thread->stack_size() &&
0N/A (fp == NULL || (fp <= thread->stack_base() &&
0N/A fp >= thread->stack_base() - thread->stack_size()));
0N/A
0N/A // We used to use standard safe_for_sender() when we are supposed
0N/A // to be executing Java code. However, that prevents us from
0N/A // walking some intrinsic stacks so now we have to be more refined.
0N/A // If we passed the above check and we have a NULL frame pointer
0N/A // and we are supposed to be executing Java code, then we have a
0N/A // couple of more checks to make.
0N/A if (ret_value && fp == NULL && (thread->thread_state() == _thread_in_Java
0N/A || thread->thread_state() == _thread_in_Java_trans)) {
0N/A
0N/A if (fr->is_interpreted_frame()) {
0N/A // interpreted frames don't really have a NULL frame pointer
0N/A return false;
0N/A } else if (CodeCache::find_blob(fr->pc()) == NULL) {
0N/A // the NULL frame pointer should be associated with generated code
0N/A return false;
0N/A }
0N/A }
0N/A }
0N/A
0N/A#else // !(IA32 || AMD64)
0N/A ret_value = fr->safe_for_sender(thread);
0N/A#endif // IA32 || AMD64
0N/A
0N/A#else // !COMPILER2
0N/A ret_value = fr->safe_for_sender(thread);
0N/A#endif // COMPILER2
0N/A
0N/A if (!ret_value) {
0N/A return ret_value; // not safe, nothing more to do
0N/A }
0N/A
0N/A address sp1;
0N/A
0N/A#ifdef SPARC
0N/A // On Solaris SPARC, when a compiler frame has an interpreted callee
0N/A // the _interpreter_sp_adjustment field contains the adjustment to
0N/A // this frame's SP made by that interpreted callee.
0N/A // For AsyncGetCallTrace(), we need to verify that the resulting SP
0N/A // is valid for the specified thread's stack.
0N/A sp1 = (address)fr->sp();
0N/A address sp2 = (address)fr->unextended_sp();
0N/A
0N/A // If the second SP is NULL, then the _interpreter_sp_adjustment
0N/A // field simply adjusts this frame's SP to NULL and the frame is
0N/A // not safe. This strange value can be set in the frame constructor
0N/A // when our peek into the interpreted callee's adjusted value for
0N/A // this frame's SP finds a NULL. This can happen when SIGPROF
0N/A // catches us while we are creating the interpreter frame.
0N/A //
0N/A if (sp2 == NULL ||
0N/A
0N/A // If the two SPs are different, then _interpreter_sp_adjustment
0N/A // is non-zero and we need to validate the second SP. We invert
0N/A // the range check from frame::safe_for_sender() and bail out
0N/A // if the second SP is not safe.
0N/A (sp1 != sp2 && !(sp2 <= thread->stack_base()
0N/A && sp2 >= (thread->stack_base() - thread->stack_size())))) {
0N/A return false;
0N/A }
0N/A#endif // SPARC
0N/A
0N/A if (fr->is_entry_frame()) {
0N/A // This frame thinks it is an entry frame; we need to validate
0N/A // the JavaCallWrapper pointer.
0N/A // Note: frame::entry_frame_is_first() assumes that the
0N/A // JavaCallWrapper has a non-NULL _anchor field. We don't
0N/A // check that here (yet) since we've never seen a failure
0N/A // due to a NULL _anchor field.
0N/A // Update: Originally this check was done only for SPARC. However,
0N/A // this failure has now been seen on C2 C86. I have no reason to
0N/A // believe that this is not a general issue so I'm enabling the
0N/A // check for all compilers on all supported platforms.
0N/A#ifdef COMPILER2
0N/A#if defined(IA32) || defined(AMD64)
0N/A if (fr->fp() == NULL) {
0N/A // C2 X86 allows NULL frame pointers, but if we have one then
0N/A // we cannot call entry_frame_call_wrapper().
0N/A return false;
0N/A }
0N/A#endif // IA32 || AMD64
0N/A#endif // COMPILER2
0N/A
0N/A sp1 = (address)fr->entry_frame_call_wrapper();
0N/A // We invert the range check from frame::safe_for_sender() and
0N/A // bail out if the JavaCallWrapper * is not safe.
0N/A if (!(sp1 <= thread->stack_base()
0N/A && sp1 >= (thread->stack_base() - thread->stack_size()))) {
0N/A return false;
0N/A }
0N/A }
0N/A
0N/A return ret_value;
0N/A}
0N/A
0N/A
0N/A// Unknown compiled frames have caused assertion failures on Solaris
0N/A// X86. This code also detects unknown compiled frames on Solaris
0N/A// SPARC, but no assertion failures have been observed. However, I'm
0N/A// paranoid so I'm enabling this code whenever we have a compiler.
0N/A//
0N/A// Returns true if the specified frame is an unknown compiled frame
0N/A// and false otherwise.
0N/Astatic bool is_unknown_compiled_frame(frame* fr, JavaThread *thread) {
0N/A bool ret_value = false; // be optimistic
0N/A
0N/A // This failure mode only occurs when the thread is in state
0N/A // _thread_in_Java so we are okay for this check for any other
0N/A // thread state.
0N/A //
0N/A // Note: _thread_in_Java does not always mean that the thread
0N/A // is executing Java code. AsyncGetCallTrace() has caught
0N/A // threads executing in JRT_LEAF() routines when the state
0N/A // will also be _thread_in_Java.
0N/A if (thread->thread_state() != _thread_in_Java) {
0N/A return ret_value;
0N/A }
0N/A
0N/A // This failure mode only occurs with compiled frames so we are
0N/A // okay for this check for both entry and interpreted frames.
0N/A if (fr->is_entry_frame() || fr->is_interpreted_frame()) {
0N/A return ret_value;
0N/A }
0N/A
0N/A // This failure mode only occurs when the compiled frame's PC
0N/A // is in the code cache so we are okay for this check if the
0N/A // PC is not in the code cache.
0N/A CodeBlob* cb = CodeCache::find_blob(fr->pc());
0N/A if (cb == NULL) {
0N/A return ret_value;
0N/A }
0N/A
0N/A // We have compiled code in the code cache so it is time for
0N/A // the final check: let's see if any frame type is set
0N/A ret_value = !(
0N/A // is_entry_frame() is checked above
0N/A // testers that are a subset of is_entry_frame():
0N/A // is_first_frame()
0N/A fr->is_java_frame()
0N/A // testers that are a subset of is_java_frame():
0N/A // is_interpreted_frame()
0N/A // is_compiled_frame()
0N/A || fr->is_native_frame()
0N/A || fr->is_runtime_frame()
0N/A || fr->is_safepoint_blob_frame()
0N/A );
0N/A
0N/A // If there is no frame type set, then we have an unknown compiled
0N/A // frame and sender() should not be called on it.
0N/A
0N/A return ret_value;
0N/A}
0N/A
0N/A#define DebugNonSafepoints_IS_CLEARED \
0N/A (!FLAG_IS_DEFAULT(DebugNonSafepoints) && !DebugNonSafepoints)
0N/A
0N/A// if -XX:-DebugNonSafepoints, then top-frame will be skipped
0N/AvframeStreamForte::vframeStreamForte(JavaThread *jt, frame fr,
0N/A bool stop_at_java_call_stub) : vframeStreamCommon(jt) {
0N/A _stop_at_java_call_stub = stop_at_java_call_stub;
0N/A
0N/A if (!DebugNonSafepoints_IS_CLEARED) {
0N/A // decode the top frame fully
0N/A // (usual case, if JVMTI is enabled)
0N/A _frame = fr;
0N/A } else {
0N/A // skip top frame, as it may not be at safepoint
0N/A // For AsyncGetCallTrace(), we extracted as much info from the top
0N/A // frame as we could in forte_is_walkable_frame(). We also verified
0N/A // forte_safe_for_sender() so this sender() call is safe.
0N/A _frame = fr.sender(&_reg_map);
0N/A }
0N/A
0N/A if (jt->thread_state() == _thread_in_Java && !fr.is_first_frame()) {
0N/A bool sender_check = false; // assume sender is not safe
0N/A
0N/A if (forte_safe_for_sender(&_frame, jt)) {
0N/A // If the initial sender frame is safe, then continue on with other
0N/A // checks. The unsafe sender frame has been seen on Solaris X86
0N/A // with both Compiler1 and Compiler2. It has not been seen on
0N/A // Solaris SPARC, but seems like a good sanity check to have
0N/A // anyway.
0N/A
0N/A // SIGPROF caught us in Java code and the current frame is not the
0N/A // first frame so we should sanity check the sender frame. It is
0N/A // possible for SIGPROF to catch us in the middle of making a call.
0N/A // When that happens the current frame is actually a combination of
0N/A // the real sender and some of the new call's info. We can't find
0N/A // the real sender with such a current frame and things can get
0N/A // confused.
0N/A //
0N/A // This sanity check has caught problems with the sender frame on
0N/A // Solaris SPARC. So far Solaris X86 has not had a failure here.
0N/A sender_check = _frame.is_entry_frame()
0N/A // testers that are a subset of is_entry_frame():
0N/A // is_first_frame()
0N/A || _frame.is_java_frame()
0N/A // testers that are a subset of is_java_frame():
0N/A // is_interpreted_frame()
0N/A // is_compiled_frame()
0N/A || _frame.is_native_frame()
0N/A || _frame.is_runtime_frame()
0N/A || _frame.is_safepoint_blob_frame()
0N/A ;
0N/A
0N/A // We need an additional sanity check on an initial interpreted
0N/A // sender frame. This interpreted frame needs to be both walkable
0N/A // and have a valid BCI. This is yet another variant of SIGPROF
0N/A // catching us in the middle of making a call.
0N/A if (sender_check && _frame.is_interpreted_frame()) {
0N/A methodOop method = NULL;
0N/A int bci = -1;
0N/A
0N/A if (!forte_is_walkable_interpreted_frame(&_frame, &method, &bci)
0N/A || bci == -1) {
0N/A sender_check = false;
0N/A }
0N/A }
0N/A
0N/A // We need an additional sanity check on an initial compiled
0N/A // sender frame. This compiled frame also needs to be walkable.
0N/A // This is yet another variant of SIGPROF catching us in the
0N/A // middle of making a call.
0N/A if (sender_check && !_frame.is_interpreted_frame()) {
0N/A bool is_compiled, is_walkable;
0N/A
0N/A forte_is_walkable_compiled_frame(&_frame, &_reg_map,
0N/A &is_compiled, &is_walkable);
0N/A if (is_compiled && !is_walkable) {
0N/A sender_check = false;
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (!sender_check) {
0N/A // nothing else to try if we can't recognize the sender
0N/A _mode = at_end_mode;
0N/A return;
0N/A }
0N/A }
0N/A
0N/A int loop_count = 0;
0N/A int loop_max = MaxJavaStackTraceDepth * 2;
0N/A
0N/A while (!fill_from_frame()) {
0N/A _frame = _frame.sender(&_reg_map);
0N/A
0N/A#ifdef COMPILER2
0N/A#if defined(IA32) || defined(AMD64)
0N/A // Stress testing on C2 X86 has shown a periodic problem with
0N/A // the sender() call below. The initial _frame that we have on
0N/A // entry to the loop has already passed forte_safe_for_sender()
0N/A // so we only check frames after it.
0N/A if (!forte_safe_for_sender(&_frame, _thread)) {
0N/A _mode = at_end_mode;
0N/A return;
0N/A }
0N/A#endif // IA32 || AMD64
0N/A#endif // COMPILER2
0N/A
0N/A if (++loop_count >= loop_max) {
0N/A // We have looped more than twice the number of possible
0N/A // Java frames. This indicates that we are trying to walk
0N/A // a stack that is in the middle of being constructed and
0N/A // it is self referential.
0N/A _mode = at_end_mode;
0N/A return;
0N/A }
0N/A }
0N/A}
0N/A
0N/A
0N/A// Solaris SPARC Compiler1 needs an additional check on the grandparent
0N/A// of the top_frame when the parent of the top_frame is interpreted and
0N/A// the grandparent is compiled. However, in this method we do not know
0N/A// the relationship of the current _frame relative to the top_frame so
0N/A// we implement a more broad sanity check. When the previous callee is
0N/A// interpreted and the current sender is compiled, we verify that the
0N/A// current sender is also walkable. If it is not walkable, then we mark
0N/A// the current vframeStream as at the end.
0N/Avoid vframeStreamForte::forte_next() {
0N/A // handle frames with inlining
0N/A if (_mode == compiled_mode &&
0N/A vframeStreamCommon::fill_in_compiled_inlined_sender()) {
0N/A return;
0N/A }
0N/A
0N/A // handle general case
0N/A
0N/A int loop_count = 0;
0N/A int loop_max = MaxJavaStackTraceDepth * 2;
0N/A
0N/A
0N/A do {
0N/A
0N/A#if defined(COMPILER1) && defined(SPARC)
0N/A bool prevIsInterpreted = _frame.is_interpreted_frame();
0N/A#endif // COMPILER1 && SPARC
0N/A
0N/A _frame = _frame.sender(&_reg_map);
0N/A
0N/A if (!forte_safe_for_sender(&_frame, _thread)) {
0N/A _mode = at_end_mode;
0N/A return;
0N/A }
0N/A
0N/A#if defined(COMPILER1) && defined(SPARC)
0N/A if (prevIsInterpreted) {
0N/A // previous callee was interpreted and may require a special check
0N/A if (_frame.is_compiled_frame() && _frame.cb()->is_compiled_by_c1()) {
0N/A // compiled sender called interpreted callee so need one more check
0N/A bool is_compiled, is_walkable;
0N/A
0N/A // sanity check the compiled sender frame
0N/A forte_is_walkable_compiled_frame(&_frame, &_reg_map,
0N/A &is_compiled, &is_walkable);
0N/A assert(is_compiled, "sanity check");
0N/A if (!is_walkable) {
0N/A // compiled sender frame is not walkable so bail out
0N/A _mode = at_end_mode;
0N/A return;
0N/A }
0N/A }
0N/A }
0N/A#endif // COMPILER1 && SPARC
0N/A
0N/A if (++loop_count >= loop_max) {
0N/A // We have looped more than twice the number of possible
0N/A // Java frames. This indicates that we are trying to walk
0N/A // a stack that is in the middle of being constructed and
0N/A // it is self referential.
0N/A _mode = at_end_mode;
0N/A return;
0N/A }
0N/A } while (!fill_from_frame());
0N/A}
0N/A
0N/A// Determine if 'fr' is a walkable, compiled frame.
0N/A// *is_compiled_p is set to true if the frame is compiled and if it
0N/A// is, then *is_walkable_p is set to true if it is also walkable.
0N/Astatic void forte_is_walkable_compiled_frame(frame* fr, RegisterMap* map,
0N/A bool* is_compiled_p, bool* is_walkable_p) {
0N/A
0N/A *is_compiled_p = false;
0N/A *is_walkable_p = false;
0N/A
0N/A CodeBlob* cb = CodeCache::find_blob(fr->pc());
0N/A if (cb != NULL &&
0N/A cb->is_nmethod() &&
0N/A ((nmethod*)cb)->is_java_method()) {
0N/A // frame is compiled and executing a Java method
0N/A *is_compiled_p = true;
0N/A
0N/A // Increment PC because the PcDesc we want is associated with
0N/A // the *end* of the instruction, and pc_desc_near searches
0N/A // forward to the first matching PC after the probe PC.
0N/A PcDesc* pc_desc = NULL;
0N/A if (!DebugNonSafepoints_IS_CLEARED) {
0N/A // usual case: look for any safepoint near the sampled PC
0N/A address probe_pc = fr->pc() + 1;
0N/A pc_desc = ((nmethod*) cb)->pc_desc_near(probe_pc);
0N/A } else {
0N/A // reduced functionality: only recognize PCs immediately after calls
0N/A pc_desc = ((nmethod*) cb)->pc_desc_at(fr->pc());
0N/A }
0N/A if (pc_desc != NULL && (pc_desc->scope_decode_offset()
0N/A == DebugInformationRecorder::serialized_null)) {
0N/A pc_desc = NULL;
0N/A }
0N/A if (pc_desc != NULL) {
0N/A // it has a PcDesc so the frame is also walkable
0N/A *is_walkable_p = true;
0N/A if (!DebugNonSafepoints_IS_CLEARED) {
0N/A // Normalize the PC to the one associated exactly with
0N/A // this PcDesc, so that subsequent stack-walking queries
0N/A // need not be approximate:
0N/A fr->set_pc(pc_desc->real_pc((nmethod*) cb));
0N/A }
0N/A }
0N/A // Implied else: this compiled frame has no PcDesc, i.e., contains
0N/A // a frameless stub such as C1 method exit, so it is not walkable.
0N/A }
0N/A // Implied else: this isn't a compiled frame so it isn't a
0N/A // walkable, compiled frame.
0N/A}
0N/A
0N/A// Determine if 'fr' is a walkable interpreted frame. Returns false
0N/A// if it is not. *method_p, and *bci_p are not set when false is
0N/A// returned. *method_p is non-NULL if frame was executing a Java
0N/A// method. *bci_p is != -1 if a valid BCI in the Java method could
0N/A// be found.
0N/A// Note: this method returns true when a valid Java method is found
0N/A// even if a valid BCI cannot be found.
0N/A
0N/Astatic bool forte_is_walkable_interpreted_frame(frame* fr,
0N/A methodOop* method_p, int* bci_p) {
0N/A assert(fr->is_interpreted_frame(), "just checking");
0N/A
0N/A // top frame is an interpreted frame
0N/A // check if it is walkable (i.e. valid methodOop and valid bci)
0N/A if (fr->is_interpreted_frame_valid()) {
0N/A if (fr->fp() != NULL) {
0N/A // access address in order not to trigger asserts that
0N/A // are built in interpreter_frame_method function
0N/A methodOop method = *fr->interpreter_frame_method_addr();
0N/A if (Universe::heap()->is_valid_method(method)) {
0N/A intptr_t bcx = fr->interpreter_frame_bcx();
0N/A int bci = method->validate_bci_from_bcx(bcx);
0N/A // note: bci is set to -1 if not a valid bci
0N/A *method_p = method;
0N/A *bci_p = bci;
0N/A return true;
0N/A }
0N/A }
0N/A }
0N/A return false;
0N/A}
0N/A
0N/A
0N/A// Determine if 'fr' can be used to find a walkable frame. Returns
0N/A// false if a walkable frame cannot be found. *walkframe_p, *method_p,
0N/A// and *bci_p are not set when false is returned. Returns true if a
0N/A// walkable frame is returned via *walkframe_p. *method_p is non-NULL
0N/A// if the returned frame was executing a Java method. *bci_p is != -1
0N/A// if a valid BCI in the Java method could be found.
0N/A//
0N/A// *walkframe_p will be used by vframeStreamForte as the initial
0N/A// frame for walking the stack. Currently the initial frame is
0N/A// skipped by vframeStreamForte because we inherited the logic from
0N/A// the vframeStream class. This needs to be revisited in the future.
0N/Astatic bool forte_is_walkable_frame(JavaThread* thread, frame* fr,
0N/A frame* walkframe_p, methodOop* method_p, int* bci_p) {
0N/A
0N/A if (!forte_safe_for_sender(fr, thread)
0N/A || is_unknown_compiled_frame(fr, thread)
0N/A ) {
0N/A // If the initial frame is not safe, then bail out. So far this
0N/A // has only been seen on Solaris X86 with Compiler2, but it seems
0N/A // like a great initial sanity check.
0N/A return false;
0N/A }
0N/A
0N/A if (fr->is_first_frame()) {
0N/A // If initial frame is frame from StubGenerator and there is no
0N/A // previous anchor, there are no java frames yet
0N/A return false;
0N/A }
0N/A
0N/A if (fr->is_interpreted_frame()) {
0N/A if (forte_is_walkable_interpreted_frame(fr, method_p, bci_p)) {
0N/A *walkframe_p = *fr;
0N/A return true;
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A // At this point we have something other than a first frame or an
0N/A // interpreted frame.
0N/A
0N/A methodOop method = NULL;
0N/A frame candidate = *fr;
0N/A
0N/A // If we loop more than twice the number of possible Java
0N/A // frames, then this indicates that we are trying to walk
0N/A // a stack that is in the middle of being constructed and
0N/A // it is self referential. So far this problem has only
0N/A // been seen on Solaris X86 Compiler2, but it seems like
0N/A // a good robustness fix for all platforms.
0N/A
0N/A int loop_count;
0N/A int loop_max = MaxJavaStackTraceDepth * 2;
0N/A
0N/A for (loop_count = 0; loop_count < loop_max; loop_count++) {
0N/A // determine if the candidate frame is executing a Java method
0N/A if (CodeCache::contains(candidate.pc())) {
0N/A // candidate is a compiled frame or stub routine
0N/A CodeBlob* cb = CodeCache::find_blob(candidate.pc());
0N/A
0N/A if (cb->is_nmethod()) {
0N/A method = ((nmethod *)cb)->method();
0N/A }
0N/A } // end if CodeCache has our PC
0N/A
0N/A RegisterMap map(thread, false);
0N/A
0N/A // we have a Java frame that seems reasonable
0N/A if (method != NULL && candidate.is_java_frame()
0N/A && candidate.sp() != NULL && candidate.pc() != NULL) {
0N/A // we need to sanity check the candidate further
0N/A bool is_compiled, is_walkable;
0N/A
0N/A forte_is_walkable_compiled_frame(&candidate, &map, &is_compiled,
0N/A &is_walkable);
0N/A if (is_compiled) {
0N/A // At this point, we know we have a compiled Java frame with
0N/A // method information that we want to return. We don't check
0N/A // the is_walkable flag here because that flag pertains to
0N/A // vframeStreamForte work that is done after we are done here.
0N/A break;
0N/A }
0N/A }
0N/A
0N/A // At this point, the candidate doesn't work so try the sender.
0N/A
0N/A // For AsyncGetCallTrace() we cannot assume there is a sender
0N/A // for the initial frame. The initial forte_safe_for_sender() call
0N/A // and check for is_first_frame() is done on entry to this method.
0N/A candidate = candidate.sender(&map);
0N/A if (!forte_safe_for_sender(&candidate, thread)) {
0N/A
0N/A#ifdef COMPILER2
0N/A#if defined(IA32) || defined(AMD64)
0N/A // C2 on X86 can use the ebp register as a general purpose register
0N/A // which can cause the candidate to fail theforte_safe_for_sender()
0N/A // above. We try one more time using a NULL frame pointer (fp).
0N/A
0N/A candidate = frame(candidate.sp(), NULL, candidate.pc());
0N/A if (!forte_safe_for_sender(&candidate, thread)) {
0N/A#endif // IA32 || AMD64
0N/A#endif // COMPILER2
0N/A
0N/A return false;
0N/A
0N/A#ifdef COMPILER2
0N/A#if defined(IA32) || defined(AMD64)
0N/A } // end forte_safe_for_sender retry with NULL fp
0N/A#endif // IA32 || AMD64
0N/A#endif // COMPILER2
0N/A
0N/A } // end first forte_safe_for_sender check
0N/A
0N/A if (candidate.is_first_frame()
0N/A || is_unknown_compiled_frame(&candidate, thread)) {
0N/A return false;
0N/A }
0N/A } // end for loop_count
0N/A
0N/A if (method == NULL) {
0N/A // If we didn't get any method info from the candidate, then
0N/A // we have nothing to return so bail out.
0N/A return false;
0N/A }
0N/A
0N/A *walkframe_p = candidate;
0N/A *method_p = method;
0N/A *bci_p = -1;
0N/A return true;
0N/A}
0N/A
0N/A
0N/A// call frame copied from old .h file and renamed
0N/Atypedef struct {
0N/A jint lineno; // line number in the source file
0N/A jmethodID method_id; // method executed in this frame
0N/A} ASGCT_CallFrame;
0N/A
0N/A// call trace copied from old .h file and renamed
0N/Atypedef struct {
0N/A JNIEnv *env_id; // Env where trace was recorded
0N/A jint num_frames; // number of frames in this trace
0N/A ASGCT_CallFrame *frames; // frames
0N/A} ASGCT_CallTrace;
0N/A
0N/Astatic void forte_fill_call_trace_given_top(JavaThread* thd,
0N/A ASGCT_CallTrace* trace, int depth, frame top_frame) {
0N/A NoHandleMark nhm;
0N/A
0N/A frame walkframe;
0N/A methodOop method;
0N/A int bci;
0N/A int count;
0N/A
0N/A count = 0;
0N/A assert(trace->frames != NULL, "trace->frames must be non-NULL");
0N/A
0N/A if (!forte_is_walkable_frame(thd, &top_frame, &walkframe, &method, &bci)) {
0N/A // return if no walkable frame is found
0N/A return;
0N/A }
0N/A
0N/A CollectedHeap* ch = Universe::heap();
0N/A
0N/A if (method != NULL) {
0N/A // The method is not stored GC safe so see if GC became active
0N/A // after we entered AsyncGetCallTrace() and before we try to
0N/A // use the methodOop.
0N/A // Yes, there is still a window after this check and before
0N/A // we use methodOop below, but we can't lock out GC so that
0N/A // has to be an acceptable risk.
0N/A if (!ch->is_valid_method(method)) {
0N/A trace->num_frames = -2;
0N/A return;
0N/A }
0N/A
0N/A if (DebugNonSafepoints_IS_CLEARED) {
0N/A // Take whatever method the top-frame decoder managed to scrape up.
0N/A // We look further at the top frame only if non-safepoint
0N/A // debugging information is available.
0N/A count++;
0N/A trace->num_frames = count;
0N/A trace->frames[0].method_id = method->find_jmethod_id_or_null();
0N/A if (!method->is_native()) {
0N/A trace->frames[0].lineno = bci;
0N/A } else {
0N/A trace->frames[0].lineno = -3;
0N/A }
0N/A }
0N/A }
0N/A
0N/A // check has_last_Java_frame() after looking at the top frame
0N/A // which may be an interpreted Java frame.
0N/A if (!thd->has_last_Java_frame() && method == NULL) {
0N/A trace->num_frames = 0;
0N/A return;
0N/A }
0N/A
0N/A vframeStreamForte st(thd, walkframe, false);
0N/A for (; !st.at_end() && count < depth; st.forte_next(), count++) {
0N/A bci = st.bci();
0N/A method = st.method();
0N/A
0N/A // The method is not stored GC safe so see if GC became active
0N/A // after we entered AsyncGetCallTrace() and before we try to
0N/A // use the methodOop.
0N/A // Yes, there is still a window after this check and before
0N/A // we use methodOop below, but we can't lock out GC so that
0N/A // has to be an acceptable risk.
0N/A if (!ch->is_valid_method(method)) {
0N/A // we throw away everything we've gathered in this sample since
0N/A // none of it is safe
0N/A trace->num_frames = -2;
0N/A return;
0N/A }
0N/A
0N/A trace->frames[count].method_id = method->find_jmethod_id_or_null();
0N/A if (!method->is_native()) {
0N/A trace->frames[count].lineno = bci;
0N/A } else {
0N/A trace->frames[count].lineno = -3;
0N/A }
0N/A }
0N/A trace->num_frames = count;
0N/A return;
0N/A}
0N/A
0N/A
0N/A// Forte Analyzer AsyncGetCallTrace() entry point. Currently supported
0N/A// on Linux X86, Solaris SPARC and Solaris X86.
0N/A//
0N/A// Async-safe version of GetCallTrace being called from a signal handler
0N/A// when a LWP gets interrupted by SIGPROF but the stack traces are filled
0N/A// with different content (see below).
0N/A//
0N/A// This function must only be called when JVM/TI
0N/A// CLASS_LOAD events have been enabled since agent startup. The enabled
0N/A// event will cause the jmethodIDs to be allocated at class load time.
0N/A// The jmethodIDs cannot be allocated in a signal handler because locks
0N/A// cannot be grabbed in a signal handler safely.
0N/A//
0N/A// void (*AsyncGetCallTrace)(ASGCT_CallTrace *trace, jint depth, void* ucontext)
0N/A//
0N/A// Called by the profiler to obtain the current method call stack trace for
0N/A// a given thread. The thread is identified by the env_id field in the
0N/A// ASGCT_CallTrace structure. The profiler agent should allocate a ASGCT_CallTrace
0N/A// structure with enough memory for the requested stack depth. The VM fills in
0N/A// the frames buffer and the num_frames field.
0N/A//
0N/A// Arguments:
0N/A//
0N/A// trace - trace data structure to be filled by the VM.
0N/A// depth - depth of the call stack trace.
0N/A// ucontext - ucontext_t of the LWP
0N/A//
0N/A// ASGCT_CallTrace:
0N/A// typedef struct {
0N/A// JNIEnv *env_id;
0N/A// jint num_frames;
0N/A// ASGCT_CallFrame *frames;
0N/A// } ASGCT_CallTrace;
0N/A//
0N/A// Fields:
0N/A// env_id - ID of thread which executed this trace.
0N/A// num_frames - number of frames in the trace.
0N/A// (< 0 indicates the frame is not walkable).
0N/A// frames - the ASGCT_CallFrames that make up this trace. Callee followed by callers.
0N/A//
0N/A// ASGCT_CallFrame:
0N/A// typedef struct {
0N/A// jint lineno;
0N/A// jmethodID method_id;
0N/A// } ASGCT_CallFrame;
0N/A//
0N/A// Fields:
0N/A// 1) For Java frame (interpreted and compiled),
0N/A// lineno - bci of the method being executed or -1 if bci is not available
0N/A// method_id - jmethodID of the method being executed
0N/A// 2) For native method
0N/A// lineno - (-3)
0N/A// method_id - jmethodID of the method being executed
0N/A
0N/Aextern "C" {
0N/Avoid AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {
0N/A if (SafepointSynchronize::is_synchronizing()) {
0N/A // The safepoint mechanism is trying to synchronize all the threads.
0N/A // Since this can involve thread suspension, it is not safe for us
0N/A // to be here. We can reduce the deadlock risk window by quickly
0N/A // returning to the SIGPROF handler. However, it is still possible
0N/A // for VMThread to catch us here or in the SIGPROF handler. If we
0N/A // are suspended while holding a resource and another thread blocks
0N/A // on that resource in the SIGPROF handler, then we will have a
0N/A // three-thread deadlock (VMThread, this thread, the other thread).
0N/A trace->num_frames = -10;
0N/A return;
0N/A }
0N/A
0N/A JavaThread* thread;
0N/A
0N/A if (trace->env_id == NULL ||
0N/A (thread = JavaThread::thread_from_jni_environment(trace->env_id)) == NULL ||
0N/A thread->is_exiting()) {
0N/A
0N/A // bad env_id, thread has exited or thread is exiting
0N/A trace->num_frames = -8;
0N/A return;
0N/A }
0N/A
0N/A if (thread->in_deopt_handler()) {
0N/A // thread is in the deoptimization handler so return no frames
0N/A trace->num_frames = -9;
0N/A return;
0N/A }
0N/A
0N/A assert(JavaThread::current() == thread,
0N/A "AsyncGetCallTrace must be called by the current interrupted thread");
0N/A
0N/A if (!JvmtiExport::should_post_class_load()) {
0N/A trace->num_frames = -1;
0N/A return;
0N/A }
0N/A
0N/A if (Universe::heap()->is_gc_active()) {
0N/A trace->num_frames = -2;
0N/A return;
0N/A }
0N/A
0N/A switch (thread->thread_state()) {
0N/A case _thread_new:
0N/A case _thread_uninitialized:
0N/A case _thread_new_trans:
0N/A // We found the thread on the threads list above, but it is too
0N/A // young to be useful so return that there are no Java frames.
0N/A trace->num_frames = 0;
0N/A break;
0N/A case _thread_in_native:
0N/A case _thread_in_native_trans:
0N/A case _thread_blocked:
0N/A case _thread_blocked_trans:
0N/A case _thread_in_vm:
0N/A case _thread_in_vm_trans:
0N/A {
0N/A frame fr;
0N/A
0N/A // param isInJava == false - indicate we aren't in Java code
0N/A if (!thread->pd_get_top_frame_for_signal_handler(&fr, ucontext, false)) {
0N/A if (!thread->has_last_Java_frame()) {
0N/A trace->num_frames = 0; // no Java frames
0N/A } else {
0N/A trace->num_frames = -3; // unknown frame
0N/A }
0N/A } else {
0N/A trace->num_frames = -4; // non walkable frame by default
0N/A forte_fill_call_trace_given_top(thread, trace, depth, fr);
0N/A }
0N/A }
0N/A break;
0N/A case _thread_in_Java:
0N/A case _thread_in_Java_trans:
0N/A {
0N/A frame fr;
0N/A
0N/A // param isInJava == true - indicate we are in Java code
0N/A if (!thread->pd_get_top_frame_for_signal_handler(&fr, ucontext, true)) {
0N/A trace->num_frames = -5; // unknown frame
0N/A } else {
0N/A trace->num_frames = -6; // non walkable frame by default
0N/A forte_fill_call_trace_given_top(thread, trace, depth, fr);
0N/A }
0N/A }
0N/A break;
0N/A default:
0N/A // Unknown thread state
0N/A trace->num_frames = -7;
0N/A break;
0N/A }
0N/A}
0N/A
0N/A
0N/A#ifndef _WINDOWS
0N/A// Support for the Forte(TM) Peformance Tools collector.
0N/A//
0N/A// The method prototype is derived from libcollector.h. For more
0N/A// information, please see the libcollect man page.
0N/A
0N/A// Method to let libcollector know about a dynamically loaded function.
0N/A// Because it is weakly bound, the calls become NOP's when the library
0N/A// isn't present.
0N/Avoid collector_func_load(char* name,
0N/A void* null_argument_1,
0N/A void* null_argument_2,
0N/A void *vaddr,
0N/A int size,
0N/A int zero_argument,
0N/A void* null_argument_3);
0N/A#pragma weak collector_func_load
0N/A#define collector_func_load(x0,x1,x2,x3,x4,x5,x6) \
0N/A ( collector_func_load ? collector_func_load(x0,x1,x2,x3,x4,x5,x6),0 : 0 )
0N/A#endif // !_WINDOWS
0N/A
0N/A} // end extern "C"
0N/A#endif // !IA64
0N/A
0N/Avoid Forte::register_stub(const char* name, address start, address end) {
0N/A#if !defined(_WINDOWS) && !defined(IA64)
0N/A assert(pointer_delta(end, start, sizeof(jbyte)) < INT_MAX,
0N/A "Code size exceeds maximum range")
0N/A
0N/A collector_func_load((char*)name, NULL, NULL, start,
0N/A pointer_delta(end, start, sizeof(jbyte)), 0, NULL);
0N/A#endif // !_WINDOWS && !IA64
0N/A}