Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/prims/forte.cpp
32285 views
/*1* Copyright (c) 2003, 2013, 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_interface/collectedHeap.inline.hpp"28#include "memory/space.hpp"29#include "memory/universe.inline.hpp"30#include "oops/oop.inline.hpp"31#include "oops/oop.inline2.hpp"32#include "prims/forte.hpp"33#include "runtime/javaCalls.hpp"34#include "runtime/thread.inline.hpp"35#include "runtime/vframe.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) && !defined(PPC64)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, nmethod* 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) {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_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 nmethod.148149static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* 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 nmethod 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()) 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.255256intptr_t bcx = fr->interpreter_frame_bcx();257258int bci = method->validate_bci_from_bcx(bcx);259260// note: bci is set to -1 if not a valid bci261*bci_p = bci;262return true;263}264265return false;266}267268269// Determine if a Java frame can be found starting with the frame 'fr'.270//271// Check the return value of find_initial_Java_frame and the value of272// 'method_p' to decide on how use the results returned by this method.273//274// If 'method_p' is not NULL, an initial Java frame has been found and275// the stack can be walked starting from that initial frame. In this case,276// 'method_p' points to the Method that the initial frame belongs to and277// the initial Java frame is returned in initial_frame_p.278//279// find_initial_Java_frame() returns true if a Method has been found (i.e.,280// 'method_p' is not NULL) and the initial frame that belongs to that Method281// is decipherable.282//283// A frame is considered to be decipherable:284//285// - if the frame is a compiled frame and a PCDesc is available;286//287// - if the frame is an interpreter frame that is valid or the thread is288// state (_thread_in_native || state == _thread_in_vm || state == _thread_blocked).289//290// Note that find_initial_Java_frame() can return false even if an initial291// Java method was found (e.g., there is no PCDesc available for the method).292//293// If 'method_p' is NULL, it was not possible to find a Java frame when294// walking the stack starting from 'fr'. In this case find_initial_Java_frame295// returns false.296297static bool find_initial_Java_frame(JavaThread* thread,298frame* fr,299frame* initial_frame_p,300Method** method_p,301int* bci_p) {302303// It is possible that for a frame containing an nmethod304// we can capture the method but no bci. If we get no305// bci the frame isn't walkable but the method is usable.306// Therefore we init the returned Method* to NULL so the307// caller can make the distinction.308309*method_p = NULL;310311// On the initial call to this method the frame we get may not be312// recognizable to us. This should only happen if we are in a JRT_LEAF313// or something called by a JRT_LEAF method.314315frame candidate = *fr;316317// If the starting frame we were given has no codeBlob associated with318// it see if we can find such a frame because only frames with codeBlobs319// are possible Java frames.320321if (fr->cb() == NULL) {322323// See if we can find a useful frame324int loop_count;325int loop_max = MaxJavaStackTraceDepth * 2;326RegisterMap map(thread, false);327328for (loop_count = 0; loop_count < loop_max; loop_count++) {329if (!candidate.safe_for_sender(thread)) return false;330candidate = candidate.sender(&map);331if (candidate.cb() != NULL) break;332}333if (candidate.cb() == NULL) return false;334}335336// We have a frame known to be in the codeCache337// We will hopefully be able to figure out something to do with it.338int loop_count;339int loop_max = MaxJavaStackTraceDepth * 2;340RegisterMap map(thread, false);341342for (loop_count = 0; loop_count < loop_max; loop_count++) {343344if (candidate.is_entry_frame()) {345// jcw is NULL if the java call wrapper couldn't be found346JavaCallWrapper *jcw = candidate.entry_frame_call_wrapper_if_safe(thread);347// If initial frame is frame from StubGenerator and there is no348// previous anchor, there are no java frames associated with a method349if (jcw == NULL || jcw->is_first_frame()) {350return false;351}352}353354if (candidate.is_interpreted_frame()) {355if (is_decipherable_interpreted_frame(thread, &candidate, method_p, bci_p)) {356*initial_frame_p = candidate;357return true;358}359360// Hopefully we got some data361return false;362}363364if (candidate.cb()->is_nmethod()) {365366nmethod* nm = (nmethod*) candidate.cb();367*method_p = nm->method();368369// If the frame is not decipherable, then the value of -1370// for the BCI is used to signal that no BCI is available.371// Furthermore, the method returns false in this case.372//373// If a decipherable frame is available, the BCI value will374// not be used.375376*bci_p = -1;377378*initial_frame_p = candidate;379380// Native wrapper code is trivial to decode by vframeStream381382if (nm->is_native_method()) return true;383384// If the frame is not decipherable, then a PC was found385// that does not have a PCDesc from which a BCI can be obtained.386// Nevertheless, a Method was found.387388if (!is_decipherable_compiled_frame(thread, &candidate, nm)) {389return false;390}391392// is_decipherable_compiled_frame may modify candidate's pc393*initial_frame_p = candidate;394395assert(nm->pc_desc_at(candidate.pc()) != NULL, "debug information must be available if the frame is decipherable");396397return true;398}399400// Must be some stub frame that we don't care about401402if (!candidate.safe_for_sender(thread)) return false;403candidate = candidate.sender(&map);404405// If it isn't in the code cache something is wrong406// since once we find a frame in the code cache they407// all should be there.408409if (candidate.cb() == NULL) return false;410411}412413return false;414415}416417static void forte_fill_call_trace_given_top(JavaThread* thd,418ASGCT_CallTrace* trace,419int depth,420frame top_frame) {421NoHandleMark nhm;422423frame initial_Java_frame;424Method* method;425int bci = -1; // assume BCI is not available for method426// update with correct information if available427int count;428429count = 0;430assert(trace->frames != NULL, "trace->frames must be non-NULL");431432// Walk the stack starting from 'top_frame' and search for an initial Java frame.433find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci);434435// Check if a Java Method has been found.436if (method == NULL) return;437438if (!method->is_valid_method()) {439trace->num_frames = ticks_GC_active; // -2440return;441}442443vframeStreamForte st(thd, initial_Java_frame, false);444445for (; !st.at_end() && count < depth; st.forte_next(), count++) {446bci = st.bci();447method = st.method();448449if (!method->is_valid_method()) {450// we throw away everything we've gathered in this sample since451// none of it is safe452trace->num_frames = ticks_GC_active; // -2453return;454}455456trace->frames[count].method_id = method->find_jmethod_id_or_null();457if (!method->is_native()) {458trace->frames[count].lineno = bci;459} else {460trace->frames[count].lineno = -3;461}462}463trace->num_frames = count;464return;465}466467468// Forte Analyzer AsyncGetCallTrace() entry point. Currently supported469// on Linux X86, Solaris SPARC and Solaris X86.470//471// Async-safe version of GetCallTrace being called from a signal handler472// when a LWP gets interrupted by SIGPROF but the stack traces are filled473// with different content (see below).474//475// This function must only be called when JVM/TI476// CLASS_LOAD events have been enabled since agent startup. The enabled477// event will cause the jmethodIDs to be allocated at class load time.478// The jmethodIDs cannot be allocated in a signal handler because locks479// cannot be grabbed in a signal handler safely.480//481// void (*AsyncGetCallTrace)(ASGCT_CallTrace *trace, jint depth, void* ucontext)482//483// Called by the profiler to obtain the current method call stack trace for484// a given thread. The thread is identified by the env_id field in the485// ASGCT_CallTrace structure. The profiler agent should allocate a ASGCT_CallTrace486// structure with enough memory for the requested stack depth. The VM fills in487// the frames buffer and the num_frames field.488//489// Arguments:490//491// trace - trace data structure to be filled by the VM.492// depth - depth of the call stack trace.493// ucontext - ucontext_t of the LWP494//495// ASGCT_CallTrace:496// typedef struct {497// JNIEnv *env_id;498// jint num_frames;499// ASGCT_CallFrame *frames;500// } ASGCT_CallTrace;501//502// Fields:503// env_id - ID of thread which executed this trace.504// num_frames - number of frames in the trace.505// (< 0 indicates the frame is not walkable).506// frames - the ASGCT_CallFrames that make up this trace. Callee followed by callers.507//508// ASGCT_CallFrame:509// typedef struct {510// jint lineno;511// jmethodID method_id;512// } ASGCT_CallFrame;513//514// Fields:515// 1) For Java frame (interpreted and compiled),516// lineno - bci of the method being executed or -1 if bci is not available517// method_id - jmethodID of the method being executed518// 2) For native method519// lineno - (-3)520// method_id - jmethodID of the method being executed521522extern "C" {523JNIEXPORT524void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {525JavaThread* thread;526527if (trace->env_id == NULL ||528(thread = JavaThread::thread_from_jni_environment(trace->env_id)) == NULL ||529thread->is_exiting()) {530531// bad env_id, thread has exited or thread is exiting532trace->num_frames = ticks_thread_exit; // -8533return;534}535536if (thread->in_deopt_handler()) {537// thread is in the deoptimization handler so return no frames538trace->num_frames = ticks_deopt; // -9539return;540}541542assert(JavaThread::current() == thread,543"AsyncGetCallTrace must be called by the current interrupted thread");544545if (!JvmtiExport::should_post_class_load()) {546trace->num_frames = ticks_no_class_load; // -1547return;548}549550if (Universe::heap()->is_gc_active()) {551trace->num_frames = ticks_GC_active; // -2552return;553}554555switch (thread->thread_state()) {556case _thread_new:557case _thread_uninitialized:558case _thread_new_trans:559// We found the thread on the threads list above, but it is too560// young to be useful so return that there are no Java frames.561trace->num_frames = 0;562break;563case _thread_in_native:564case _thread_in_native_trans:565case _thread_blocked:566case _thread_blocked_trans:567case _thread_in_vm:568case _thread_in_vm_trans:569{570frame fr;571572// param isInJava == false - indicate we aren't in Java code573if (!thread->pd_get_top_frame_for_signal_handler(&fr, ucontext, false)) {574trace->num_frames = ticks_unknown_not_Java; // -3 unknown frame575} else {576if (!thread->has_last_Java_frame()) {577trace->num_frames = 0; // No Java frames578} else {579trace->num_frames = ticks_not_walkable_not_Java; // -4 non walkable frame by default580forte_fill_call_trace_given_top(thread, trace, depth, fr);581582// This assert would seem to be valid but it is not.583// It would be valid if we weren't possibly racing a gc584// thread. A gc thread can make a valid interpreted frame585// look invalid. It's a small window but it does happen.586// The assert is left here commented out as a reminder.587// assert(trace->num_frames != ticks_not_walkable_not_Java, "should always be walkable");588589}590}591}592break;593case _thread_in_Java:594case _thread_in_Java_trans:595{596frame fr;597598// param isInJava == true - indicate we are in Java code599if (!thread->pd_get_top_frame_for_signal_handler(&fr, ucontext, true)) {600trace->num_frames = ticks_unknown_Java; // -5 unknown frame601} else {602trace->num_frames = ticks_not_walkable_Java; // -6, non walkable frame by default603forte_fill_call_trace_given_top(thread, trace, depth, fr);604}605}606break;607default:608// Unknown thread state609trace->num_frames = ticks_unknown_state; // -7610break;611}612}613614615#ifndef _WINDOWS616// Support for the Forte(TM) Peformance Tools collector.617//618// The method prototype is derived from libcollector.h. For more619// information, please see the libcollect man page.620621// Method to let libcollector know about a dynamically loaded function.622// Because it is weakly bound, the calls become NOP's when the library623// isn't present.624#ifdef __APPLE__625// XXXDARWIN: Link errors occur even when __attribute__((weak_import))626// is added627#define collector_func_load(x0,x1,x2,x3,x4,x5,x6) ((void) 0)628#else629void collector_func_load(char* name,630void* null_argument_1,631void* null_argument_2,632void *vaddr,633int size,634int zero_argument,635void* null_argument_3);636#pragma weak collector_func_load637#define collector_func_load(x0,x1,x2,x3,x4,x5,x6) \638( collector_func_load ? collector_func_load(x0,x1,x2,x3,x4,x5,x6),(void)0 : (void)0 )639#endif // __APPLE__640#endif // !_WINDOWS641642} // end extern "C"643#endif // !IA64 && !PPC64644645void Forte::register_stub(const char* name, address start, address end) {646#if !defined(_WINDOWS) && !defined(IA64) && !defined(PPC64)647assert(pointer_delta(end, start, sizeof(jbyte)) < INT_MAX,648"Code size exceeds maximum range");649650collector_func_load((char*)name, NULL, NULL, start,651pointer_delta(end, start, sizeof(jbyte)), 0, NULL);652#endif // !_WINDOWS && !IA64 && !PPC64653}654655#else // INCLUDE_JVMTI656extern "C" {657JNIEXPORT658void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {659trace->num_frames = ticks_no_class_load; // -1660}661}662#endif // INCLUDE_JVMTI663664665