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