Path: blob/master/src/hotspot/share/prims/forte.cpp
41144 views
/*1* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "code/debugInfoRec.hpp"26#include "code/pcDesc.hpp"27#include "gc/shared/collectedHeap.inline.hpp"28#include "memory/universe.hpp"29#include "oops/oop.inline.hpp"30#include "prims/forte.hpp"31#include "prims/jvmtiExport.hpp"32#include "runtime/frame.inline.hpp"33#include "runtime/javaCalls.hpp"34#include "runtime/thread.inline.hpp"35#include "runtime/vframe.inline.hpp"36#include "runtime/vframeArray.hpp"3738// call frame copied from old .h file and renamed39typedef struct {40jint lineno; // line number in the source file41jmethodID method_id; // method executed in this frame42} ASGCT_CallFrame;4344// call trace copied from old .h file and renamed45typedef struct {46JNIEnv *env_id; // Env where trace was recorded47jint num_frames; // number of frames in this trace48ASGCT_CallFrame *frames; // frames49} ASGCT_CallTrace;5051// These name match the names reported by the forte quality kit52enum {53ticks_no_Java_frame = 0,54ticks_no_class_load = -1,55ticks_GC_active = -2,56ticks_unknown_not_Java = -3,57ticks_not_walkable_not_Java = -4,58ticks_unknown_Java = -5,59ticks_not_walkable_Java = -6,60ticks_unknown_state = -7,61ticks_thread_exit = -8,62ticks_deopt = -9,63ticks_safepoint = -1064};6566#if INCLUDE_JVMTI6768//-------------------------------------------------------6970// Native interfaces for use by Forte tools.717273#if !defined(IA64)7475class vframeStreamForte : public vframeStreamCommon {76public:77// constructor that starts with sender of frame fr (top_frame)78vframeStreamForte(JavaThread *jt, frame fr, bool stop_at_java_call_stub);79void forte_next();80};818283static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, CompiledMethod* nm);84static bool is_decipherable_interpreted_frame(JavaThread* thread,85frame* fr,86Method** method_p,87int* bci_p);8889909192vframeStreamForte::vframeStreamForte(JavaThread *jt,93frame fr,94bool stop_at_java_call_stub) : vframeStreamCommon(jt, false /* process_frames */) {9596_stop_at_java_call_stub = stop_at_java_call_stub;97_frame = fr;9899// We must always have a valid frame to start filling100101bool filled_in = fill_from_frame();102103assert(filled_in, "invariant");104105}106107108// Solaris SPARC Compiler1 needs an additional check on the grandparent109// of the top_frame when the parent of the top_frame is interpreted and110// the grandparent is compiled. However, in this method we do not know111// the relationship of the current _frame relative to the top_frame so112// we implement a more broad sanity check. When the previous callee is113// interpreted and the current sender is compiled, we verify that the114// current sender is also walkable. If it is not walkable, then we mark115// the current vframeStream as at the end.116void vframeStreamForte::forte_next() {117// handle frames with inlining118if (_mode == compiled_mode &&119vframeStreamCommon::fill_in_compiled_inlined_sender()) {120return;121}122123// handle general case124125int loop_count = 0;126int loop_max = MaxJavaStackTraceDepth * 2;127128129do {130131loop_count++;132133// By the time we get here we should never see unsafe but better134// safe then segv'd135136if ((loop_max != 0 && loop_count > loop_max) || !_frame.safe_for_sender(_thread)) {137_mode = at_end_mode;138return;139}140141_frame = _frame.sender(&_reg_map);142143} while (!fill_from_frame());144}145146// Determine if 'fr' is a decipherable compiled frame. We are already147// assured that fr is for a java compiled method.148149static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, CompiledMethod* nm) {150assert(nm->is_java_method(), "invariant");151152if (thread->has_last_Java_frame() && thread->last_Java_pc() == fr->pc()) {153// We're stopped at a call into the JVM so look for a PcDesc with154// the actual pc reported by the frame.155PcDesc* pc_desc = nm->pc_desc_at(fr->pc());156157// Did we find a useful PcDesc?158if (pc_desc != NULL &&159pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null) {160return true;161}162}163164// We're at some random pc in the compiled method so search for the PcDesc165// whose pc is greater than the current PC. It's done this way166// because the extra PcDescs that are recorded for improved debug167// info record the end of the region covered by the ScopeDesc168// instead of the beginning.169PcDesc* pc_desc = nm->pc_desc_near(fr->pc() + 1);170171// Now do we have a useful PcDesc?172if (pc_desc == NULL ||173pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {174// No debug information is available for this PC.175//176// vframeStreamCommon::fill_from_frame() will decode the frame depending177// on the state of the thread.178//179// Case #1: If the thread is in Java (state == _thread_in_Java), then180// the vframeStreamCommon object will be filled as if the frame were a native181// compiled frame. Therefore, no debug information is needed.182//183// Case #2: If the thread is in any other state, then two steps will be performed:184// - if asserts are enabled, found_bad_method_frame() will be called and185// the assert in found_bad_method_frame() will be triggered;186// - if asserts are disabled, the vframeStreamCommon object will be filled187// as if it were a native compiled frame.188//189// Case (2) is similar to the way interpreter frames are processed in190// vframeStreamCommon::fill_from_interpreter_frame in case no valid BCI191// was found for an interpreted frame. If asserts are enabled, the assert192// in found_bad_method_frame() will be triggered. If asserts are disabled,193// the vframeStreamCommon object will be filled afterwards as if the194// interpreter were at the point of entering into the method.195return false;196}197198// This PcDesc is useful however we must adjust the frame's pc199// so that the vframeStream lookups will use this same pc200fr->set_pc(pc_desc->real_pc(nm));201return true;202}203204205// Determine if 'fr' is a walkable interpreted frame. Returns false206// if it is not. *method_p, and *bci_p are not set when false is207// returned. *method_p is non-NULL if frame was executing a Java208// method. *bci_p is != -1 if a valid BCI in the Java method could209// be found.210// Note: this method returns true when a valid Java method is found211// even if a valid BCI cannot be found.212213static bool is_decipherable_interpreted_frame(JavaThread* thread,214frame* fr,215Method** method_p,216int* bci_p) {217assert(fr->is_interpreted_frame(), "just checking");218219// top frame is an interpreted frame220// check if it is walkable (i.e. valid Method* and valid bci)221222// Because we may be racing a gc thread the method and/or bci223// of a valid interpreter frame may look bad causing us to224// fail the is_interpreted_frame_valid test. If the thread225// is in any of the following states we are assured that the226// frame is in fact valid and we must have hit the race.227228JavaThreadState state = thread->thread_state();229bool known_valid = (state == _thread_in_native ||230state == _thread_in_vm ||231state == _thread_blocked );232233if (known_valid || fr->is_interpreted_frame_valid(thread)) {234235// The frame code should completely validate the frame so that236// references to Method* and bci are completely safe to access237// If they aren't the frame code should be fixed not this238// code. However since gc isn't locked out the values could be239// stale. This is a race we can never completely win since we can't240// lock out gc so do one last check after retrieving their values241// from the frame for additional safety242243Method* method = fr->interpreter_frame_method();244245// We've at least found a method.246// NOTE: there is something to be said for the approach that247// if we don't find a valid bci then the method is not likely248// a valid method. Then again we may have caught an interpreter249// frame in the middle of construction and the bci field is250// not yet valid.251if (!Method::is_valid_method(method)) return false;252*method_p = method; // If the Method* found is invalid, it is253// ignored by forte_fill_call_trace_given_top().254// So set method_p only if the Method is valid.255256address bcp = fr->interpreter_frame_bcp();257int bci = method->validate_bci_from_bcp(bcp);258259// note: bci is set to -1 if not a valid bci260*bci_p = bci;261return true;262}263264return false;265}266267268// Determine if a Java frame can be found starting with the frame 'fr'.269//270// Check the return value of find_initial_Java_frame and the value of271// 'method_p' to decide on how use the results returned by this method.272//273// If 'method_p' is not NULL, an initial Java frame has been found and274// the stack can be walked starting from that initial frame. In this case,275// 'method_p' points to the Method that the initial frame belongs to and276// the initial Java frame is returned in initial_frame_p.277//278// find_initial_Java_frame() returns true if a Method has been found (i.e.,279// 'method_p' is not NULL) and the initial frame that belongs to that Method280// is decipherable.281//282// A frame is considered to be decipherable:283//284// - if the frame is a compiled frame and a PCDesc is available;285//286// - if the frame is an interpreter frame that is valid or the thread is287// state (_thread_in_native || state == _thread_in_vm || state == _thread_blocked).288//289// Note that find_initial_Java_frame() can return false even if an initial290// Java method was found (e.g., there is no PCDesc available for the method).291//292// If 'method_p' is NULL, it was not possible to find a Java frame when293// walking the stack starting from 'fr'. In this case find_initial_Java_frame294// returns false.295296static bool find_initial_Java_frame(JavaThread* thread,297frame* fr,298frame* initial_frame_p,299Method** method_p,300int* bci_p) {301302// It is possible that for a frame containing a compiled method303// we can capture the method but no bci. If we get no304// bci the frame isn't walkable but the method is usable.305// Therefore we init the returned Method* to NULL so the306// caller can make the distinction.307308*method_p = NULL;309310// On the initial call to this method the frame we get may not be311// recognizable to us. This should only happen if we are in a JRT_LEAF312// or something called by a JRT_LEAF method.313314frame candidate = *fr;315316// If the starting frame we were given has no codeBlob associated with317// it see if we can find such a frame because only frames with codeBlobs318// are possible Java frames.319320if (fr->cb() == NULL) {321322// See if we can find a useful frame323int loop_count;324int loop_max = MaxJavaStackTraceDepth * 2;325RegisterMap map(thread, false, false);326327for (loop_count = 0; loop_max == 0 || loop_count < loop_max; loop_count++) {328if (!candidate.safe_for_sender(thread)) return false;329candidate = candidate.sender(&map);330if (candidate.cb() != NULL) break;331}332if (candidate.cb() == NULL) return false;333}334335// We have a frame known to be in the codeCache336// We will hopefully be able to figure out something to do with it.337int loop_count;338int loop_max = MaxJavaStackTraceDepth * 2;339RegisterMap map(thread, false, false);340341for (loop_count = 0; loop_max == 0 || loop_count < loop_max; loop_count++) {342343if (candidate.is_entry_frame()) {344// jcw is NULL if the java call wrapper couldn't be found345JavaCallWrapper *jcw = candidate.entry_frame_call_wrapper_if_safe(thread);346// If initial frame is frame from StubGenerator and there is no347// previous anchor, there are no java frames associated with a method348if (jcw == NULL || jcw->is_first_frame()) {349return false;350}351}352353if (candidate.is_interpreted_frame()) {354if (is_decipherable_interpreted_frame(thread, &candidate, method_p, bci_p)) {355*initial_frame_p = candidate;356return true;357}358359// Hopefully we got some data360return false;361}362363if (candidate.cb()->is_compiled()) {364365CompiledMethod* nm = candidate.cb()->as_compiled_method();366*method_p = nm->method();367368// If the frame is not decipherable, then the value of -1369// for the BCI is used to signal that no BCI is available.370// Furthermore, the method returns false in this case.371//372// If a decipherable frame is available, the BCI value will373// not be used.374375*bci_p = -1;376377*initial_frame_p = candidate;378379// Native wrapper code is trivial to decode by vframeStream380381if (nm->is_native_method()) return true;382383// If the frame is not decipherable, then a PC was found384// that does not have a PCDesc from which a BCI can be obtained.385// Nevertheless, a Method was found.386387if (!is_decipherable_compiled_frame(thread, &candidate, nm)) {388return false;389}390391// is_decipherable_compiled_frame may modify candidate's pc392*initial_frame_p = candidate;393394assert(nm->pc_desc_at(candidate.pc()) != NULL, "debug information must be available if the frame is decipherable");395396return true;397}398399// Must be some stub frame that we don't care about400401if (!candidate.safe_for_sender(thread)) return false;402candidate = candidate.sender(&map);403404// If it isn't in the code cache something is wrong405// since once we find a frame in the code cache they406// all should be there.407408if (candidate.cb() == NULL) return false;409410}411412return false;413414}415416static void forte_fill_call_trace_given_top(JavaThread* thd,417ASGCT_CallTrace* trace,418int depth,419frame top_frame) {420NoHandleMark nhm;421422frame initial_Java_frame;423Method* method;424int bci = -1; // assume BCI is not available for method425// update with correct information if available426int count;427428count = 0;429assert(trace->frames != NULL, "trace->frames must be non-NULL");430431// Walk the stack starting from 'top_frame' and search for an initial Java frame.432find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci);433434// Check if a Java Method has been found.435if (method == NULL) return;436437if (!Method::is_valid_method(method)) {438trace->num_frames = ticks_GC_active; // -2439return;440}441442vframeStreamForte st(thd, initial_Java_frame, false);443444for (; !st.at_end() && count < depth; st.forte_next(), count++) {445bci = st.bci();446method = st.method();447448if (!Method::is_valid_method(method)) {449// we throw away everything we've gathered in this sample since450// none of it is safe451trace->num_frames = ticks_GC_active; // -2452return;453}454455trace->frames[count].method_id = method->find_jmethod_id_or_null();456if (!method->is_native()) {457trace->frames[count].lineno = bci;458} else {459trace->frames[count].lineno = -3;460}461}462trace->num_frames = count;463return;464}465466467// Forte Analyzer AsyncGetCallTrace() entry point. Currently supported468// on Linux X86, Solaris SPARC and Solaris X86.469//470// Async-safe version of GetCallTrace being called from a signal handler471// when a LWP gets interrupted by SIGPROF but the stack traces are filled472// with different content (see below).473//474// This function must only be called when JVM/TI475// CLASS_LOAD events have been enabled since agent startup. The enabled476// event will cause the jmethodIDs to be allocated at class load time.477// The jmethodIDs cannot be allocated in a signal handler because locks478// cannot be grabbed in a signal handler safely.479//480// void (*AsyncGetCallTrace)(ASGCT_CallTrace *trace, jint depth, void* ucontext)481//482// Called by the profiler to obtain the current method call stack trace for483// a given thread. The thread is identified by the env_id field in the484// ASGCT_CallTrace structure. The profiler agent should allocate a ASGCT_CallTrace485// structure with enough memory for the requested stack depth. The VM fills in486// the frames buffer and the num_frames field.487//488// Arguments:489//490// trace - trace data structure to be filled by the VM.491// depth - depth of the call stack trace.492// ucontext - ucontext_t of the LWP493//494// ASGCT_CallTrace:495// typedef struct {496// JNIEnv *env_id;497// jint num_frames;498// ASGCT_CallFrame *frames;499// } ASGCT_CallTrace;500//501// Fields:502// env_id - ID of thread which executed this trace.503// num_frames - number of frames in the trace.504// (< 0 indicates the frame is not walkable).505// frames - the ASGCT_CallFrames that make up this trace. Callee followed by callers.506//507// ASGCT_CallFrame:508// typedef struct {509// jint lineno;510// jmethodID method_id;511// } ASGCT_CallFrame;512//513// Fields:514// 1) For Java frame (interpreted and compiled),515// lineno - bci of the method being executed or -1 if bci is not available516// method_id - jmethodID of the method being executed517// 2) For native method518// lineno - (-3)519// method_id - jmethodID of the method being executed520521extern "C" {522JNIEXPORT523void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {524JavaThread* thread;525526if (trace->env_id == NULL ||527(thread = JavaThread::thread_from_jni_environment(trace->env_id)) == NULL ||528thread->is_exiting()) {529530// bad env_id, thread has exited or thread is exiting531trace->num_frames = ticks_thread_exit; // -8532return;533}534535if (thread->in_deopt_handler()) {536// thread is in the deoptimization handler so return no frames537trace->num_frames = ticks_deopt; // -9538return;539}540541assert(JavaThread::current() == thread,542"AsyncGetCallTrace must be called by the current interrupted thread");543544if (!JvmtiExport::should_post_class_load()) {545trace->num_frames = ticks_no_class_load; // -1546return;547}548549if (Universe::heap()->is_gc_active()) {550trace->num_frames = ticks_GC_active; // -2551return;552}553554switch (thread->thread_state()) {555case _thread_new:556case _thread_uninitialized:557case _thread_new_trans:558// We found the thread on the threads list above, but it is too559// young to be useful so return that there are no Java frames.560trace->num_frames = 0;561break;562case _thread_in_native:563case _thread_in_native_trans:564case _thread_blocked:565case _thread_blocked_trans:566case _thread_in_vm:567case _thread_in_vm_trans:568{569frame fr;570571// param isInJava == false - indicate we aren't in Java code572if (!thread->pd_get_top_frame_for_signal_handler(&fr, ucontext, false)) {573trace->num_frames = ticks_unknown_not_Java; // -3 unknown frame574} else {575if (!thread->has_last_Java_frame()) {576trace->num_frames = 0; // No Java frames577} else {578trace->num_frames = ticks_not_walkable_not_Java; // -4 non walkable frame by default579forte_fill_call_trace_given_top(thread, trace, depth, fr);580581// This assert would seem to be valid but it is not.582// It would be valid if we weren't possibly racing a gc583// thread. A gc thread can make a valid interpreted frame584// look invalid. It's a small window but it does happen.585// The assert is left here commented out as a reminder.586// assert(trace->num_frames != ticks_not_walkable_not_Java, "should always be walkable");587588}589}590}591break;592case _thread_in_Java:593case _thread_in_Java_trans:594{595frame fr;596597// param isInJava == true - indicate we are in Java code598if (!thread->pd_get_top_frame_for_signal_handler(&fr, ucontext, true)) {599trace->num_frames = ticks_unknown_Java; // -5 unknown frame600} else {601trace->num_frames = ticks_not_walkable_Java; // -6, non walkable frame by default602forte_fill_call_trace_given_top(thread, trace, depth, fr);603}604}605break;606default:607// Unknown thread state608trace->num_frames = ticks_unknown_state; // -7609break;610}611}612613614#ifndef _WINDOWS615// Support for the Forte(TM) Peformance Tools collector.616//617// The method prototype is derived from libcollector.h. For more618// information, please see the libcollect man page.619620// Method to let libcollector know about a dynamically loaded function.621// Because it is weakly bound, the calls become NOP's when the library622// isn't present.623#ifdef __APPLE__624// XXXDARWIN: Link errors occur even when __attribute__((weak_import))625// is added626#define collector_func_load(x0,x1,x2,x3,x4,x5,x6) ((void) 0)627#else628void collector_func_load(char* name,629void* null_argument_1,630void* null_argument_2,631void *vaddr,632int size,633int zero_argument,634void* null_argument_3);635#pragma weak collector_func_load636#define collector_func_load(x0,x1,x2,x3,x4,x5,x6) \637( collector_func_load ? collector_func_load(x0,x1,x2,x3,x4,x5,x6),(void)0 : (void)0 )638#endif // __APPLE__639#endif // !_WINDOWS640641} // end extern "C"642#endif // !IA64643644void Forte::register_stub(const char* name, address start, address end) {645#if !defined(_WINDOWS) && !defined(IA64)646assert(pointer_delta(end, start, sizeof(jbyte)) < INT_MAX,647"Code size exceeds maximum range");648649collector_func_load((char*)name, NULL, NULL, start,650pointer_delta(end, start, sizeof(jbyte)), 0, NULL);651#endif // !_WINDOWS && !IA64652}653654#else // INCLUDE_JVMTI655extern "C" {656JNIEXPORT657void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {658trace->num_frames = ticks_no_class_load; // -1659}660}661#endif // INCLUDE_JVMTI662663664