| 1 | /* |
| 2 | * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. |
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | * |
| 5 | * This code is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License version 2 only, as |
| 7 | * published by the Free Software Foundation. |
| 8 | * |
| 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 12 | * version 2 for more details (a copy is included in the LICENSE file that |
| 13 | * accompanied this code). |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License version |
| 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
| 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 18 | * |
| 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| 20 | * or visit www.oracle.com if you need additional information or have any |
| 21 | * questions. |
| 22 | * |
| 23 | */ |
| 24 | |
| 25 | #include "precompiled.hpp" |
| 26 | #include "code/debugInfoRec.hpp" |
| 27 | #include "code/pcDesc.hpp" |
| 28 | #include "gc/shared/collectedHeap.inline.hpp" |
| 29 | #include "memory/universe.hpp" |
| 30 | #include "oops/oop.inline.hpp" |
| 31 | #include "prims/forte.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" |
| 37 | |
| 38 | // call frame copied from old .h file and renamed |
| 39 | typedef struct { |
| 40 | jint lineno; // line number in the source file |
| 41 | jmethodID method_id; // method executed in this frame |
| 42 | } ASGCT_CallFrame; |
| 43 | |
| 44 | // call trace copied from old .h file and renamed |
| 45 | typedef struct { |
| 46 | JNIEnv *env_id; // Env where trace was recorded |
| 47 | jint num_frames; // number of frames in this trace |
| 48 | ASGCT_CallFrame *frames; // frames |
| 49 | } ASGCT_CallTrace; |
| 50 | |
| 51 | // These name match the names reported by the forte quality kit |
| 52 | enum { |
| 53 | ticks_no_Java_frame = 0, |
| 54 | ticks_no_class_load = -1, |
| 55 | ticks_GC_active = -2, |
| 56 | ticks_unknown_not_Java = -3, |
| 57 | ticks_not_walkable_not_Java = -4, |
| 58 | ticks_unknown_Java = -5, |
| 59 | ticks_not_walkable_Java = -6, |
| 60 | ticks_unknown_state = -7, |
| 61 | ticks_thread_exit = -8, |
| 62 | ticks_deopt = -9, |
| 63 | ticks_safepoint = -10 |
| 64 | }; |
| 65 | |
| 66 | #if INCLUDE_JVMTI |
| 67 | |
| 68 | //------------------------------------------------------- |
| 69 | |
| 70 | // Native interfaces for use by Forte tools. |
| 71 | |
| 72 | |
| 73 | #if !defined(IA64) |
| 74 | |
| 75 | class vframeStreamForte : public vframeStreamCommon { |
| 76 | public: |
| 77 | // constructor that starts with sender of frame fr (top_frame) |
| 78 | vframeStreamForte(JavaThread *jt, frame fr, bool stop_at_java_call_stub); |
| 79 | void forte_next(); |
| 80 | }; |
| 81 | |
| 82 | |
| 83 | static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, CompiledMethod* nm); |
| 84 | static bool is_decipherable_interpreted_frame(JavaThread* thread, |
| 85 | frame* fr, |
| 86 | Method** method_p, |
| 87 | int* bci_p); |
| 88 | |
| 89 | |
| 90 | |
| 91 | |
| 92 | vframeStreamForte::vframeStreamForte(JavaThread *jt, |
| 93 | frame fr, |
| 94 | bool stop_at_java_call_stub) : vframeStreamCommon(jt) { |
| 95 | |
| 96 | _stop_at_java_call_stub = stop_at_java_call_stub; |
| 97 | _frame = fr; |
| 98 | |
| 99 | // We must always have a valid frame to start filling |
| 100 | |
| 101 | bool filled_in = fill_from_frame(); |
| 102 | |
| 103 | assert(filled_in, "invariant" ); |
| 104 | |
| 105 | } |
| 106 | |
| 107 | |
| 108 | // Solaris SPARC Compiler1 needs an additional check on the grandparent |
| 109 | // of the top_frame when the parent of the top_frame is interpreted and |
| 110 | // the grandparent is compiled. However, in this method we do not know |
| 111 | // the relationship of the current _frame relative to the top_frame so |
| 112 | // we implement a more broad sanity check. When the previous callee is |
| 113 | // interpreted and the current sender is compiled, we verify that the |
| 114 | // current sender is also walkable. If it is not walkable, then we mark |
| 115 | // the current vframeStream as at the end. |
| 116 | void vframeStreamForte::forte_next() { |
| 117 | // handle frames with inlining |
| 118 | if (_mode == compiled_mode && |
| 119 | vframeStreamCommon::fill_in_compiled_inlined_sender()) { |
| 120 | return; |
| 121 | } |
| 122 | |
| 123 | // handle general case |
| 124 | |
| 125 | int loop_count = 0; |
| 126 | int loop_max = MaxJavaStackTraceDepth * 2; |
| 127 | |
| 128 | |
| 129 | do { |
| 130 | |
| 131 | loop_count++; |
| 132 | |
| 133 | // By the time we get here we should never see unsafe but better |
| 134 | // safe then segv'd |
| 135 | |
| 136 | if ((loop_max != 0 && loop_count > loop_max) || !_frame.safe_for_sender(_thread)) { |
| 137 | _mode = at_end_mode; |
| 138 | return; |
| 139 | } |
| 140 | |
| 141 | _frame = _frame.sender(&_reg_map); |
| 142 | |
| 143 | } while (!fill_from_frame()); |
| 144 | } |
| 145 | |
| 146 | // Determine if 'fr' is a decipherable compiled frame. We are already |
| 147 | // assured that fr is for a java compiled method. |
| 148 | |
| 149 | static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, CompiledMethod* nm) { |
| 150 | assert(nm->is_java_method(), "invariant" ); |
| 151 | |
| 152 | if (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 with |
| 154 | // the actual pc reported by the frame. |
| 155 | PcDesc* pc_desc = nm->pc_desc_at(fr->pc()); |
| 156 | |
| 157 | // Did we find a useful PcDesc? |
| 158 | if (pc_desc != NULL && |
| 159 | pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null) { |
| 160 | return true; |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | // We're at some random pc in the compiled method so search for the PcDesc |
| 165 | // whose pc is greater than the current PC. It's done this way |
| 166 | // because the extra PcDescs that are recorded for improved debug |
| 167 | // info record the end of the region covered by the ScopeDesc |
| 168 | // instead of the beginning. |
| 169 | PcDesc* pc_desc = nm->pc_desc_near(fr->pc() + 1); |
| 170 | |
| 171 | // Now do we have a useful PcDesc? |
| 172 | if (pc_desc == NULL || |
| 173 | pc_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 depending |
| 177 | // on the state of the thread. |
| 178 | // |
| 179 | // Case #1: If the thread is in Java (state == _thread_in_Java), then |
| 180 | // the vframeStreamCommon object will be filled as if the frame were a native |
| 181 | // 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 and |
| 185 | // the assert in found_bad_method_frame() will be triggered; |
| 186 | // - if asserts are disabled, the vframeStreamCommon object will be filled |
| 187 | // as if it were a native compiled frame. |
| 188 | // |
| 189 | // Case (2) is similar to the way interpreter frames are processed in |
| 190 | // vframeStreamCommon::fill_from_interpreter_frame in case no valid BCI |
| 191 | // was found for an interpreted frame. If asserts are enabled, the assert |
| 192 | // in found_bad_method_frame() will be triggered. If asserts are disabled, |
| 193 | // the vframeStreamCommon object will be filled afterwards as if the |
| 194 | // interpreter were at the point of entering into the method. |
| 195 | return false; |
| 196 | } |
| 197 | |
| 198 | // This PcDesc is useful however we must adjust the frame's pc |
| 199 | // so that the vframeStream lookups will use this same pc |
| 200 | fr->set_pc(pc_desc->real_pc(nm)); |
| 201 | return true; |
| 202 | } |
| 203 | |
| 204 | |
| 205 | // Determine if 'fr' is a walkable interpreted frame. Returns false |
| 206 | // if it is not. *method_p, and *bci_p are not set when false is |
| 207 | // returned. *method_p is non-NULL if frame was executing a Java |
| 208 | // method. *bci_p is != -1 if a valid BCI in the Java method could |
| 209 | // be found. |
| 210 | // Note: this method returns true when a valid Java method is found |
| 211 | // even if a valid BCI cannot be found. |
| 212 | |
| 213 | static bool is_decipherable_interpreted_frame(JavaThread* thread, |
| 214 | frame* fr, |
| 215 | Method** method_p, |
| 216 | int* bci_p) { |
| 217 | assert(fr->is_interpreted_frame(), "just checking" ); |
| 218 | |
| 219 | // top frame is an interpreted frame |
| 220 | // check if it is walkable (i.e. valid Method* and valid bci) |
| 221 | |
| 222 | // Because we may be racing a gc thread the method and/or bci |
| 223 | // of a valid interpreter frame may look bad causing us to |
| 224 | // fail the is_interpreted_frame_valid test. If the thread |
| 225 | // is in any of the following states we are assured that the |
| 226 | // frame is in fact valid and we must have hit the race. |
| 227 | |
| 228 | JavaThreadState state = thread->thread_state(); |
| 229 | bool known_valid = (state == _thread_in_native || |
| 230 | state == _thread_in_vm || |
| 231 | state == _thread_blocked ); |
| 232 | |
| 233 | if (known_valid || fr->is_interpreted_frame_valid(thread)) { |
| 234 | |
| 235 | // The frame code should completely validate the frame so that |
| 236 | // references to Method* and bci are completely safe to access |
| 237 | // If they aren't the frame code should be fixed not this |
| 238 | // code. However since gc isn't locked out the values could be |
| 239 | // stale. This is a race we can never completely win since we can't |
| 240 | // lock out gc so do one last check after retrieving their values |
| 241 | // from the frame for additional safety |
| 242 | |
| 243 | Method* method = fr->interpreter_frame_method(); |
| 244 | |
| 245 | // We've at least found a method. |
| 246 | // NOTE: there is something to be said for the approach that |
| 247 | // if we don't find a valid bci then the method is not likely |
| 248 | // a valid method. Then again we may have caught an interpreter |
| 249 | // frame in the middle of construction and the bci field is |
| 250 | // not yet valid. |
| 251 | if (!Method::is_valid_method(method)) return false; |
| 252 | *method_p = method; // If the Method* found is invalid, it is |
| 253 | // ignored by forte_fill_call_trace_given_top(). |
| 254 | // So set method_p only if the Method is valid. |
| 255 | |
| 256 | address bcp = fr->interpreter_frame_bcp(); |
| 257 | int bci = method->validate_bci_from_bcp(bcp); |
| 258 | |
| 259 | // note: bci is set to -1 if not a valid bci |
| 260 | *bci_p = bci; |
| 261 | return true; |
| 262 | } |
| 263 | |
| 264 | return false; |
| 265 | } |
| 266 | |
| 267 | |
| 268 | // 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 of |
| 271 | // '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 and |
| 274 | // 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 and |
| 276 | // 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 Method |
| 280 | // 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 is |
| 287 | // 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 initial |
| 290 | // 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 when |
| 293 | // walking the stack starting from 'fr'. In this case find_initial_Java_frame |
| 294 | // returns false. |
| 295 | |
| 296 | static bool find_initial_Java_frame(JavaThread* thread, |
| 297 | frame* fr, |
| 298 | frame* initial_frame_p, |
| 299 | Method** method_p, |
| 300 | int* bci_p) { |
| 301 | |
| 302 | // It is possible that for a frame containing a compiled method |
| 303 | // we can capture the method but no bci. If we get no |
| 304 | // bci the frame isn't walkable but the method is usable. |
| 305 | // Therefore we init the returned Method* to NULL so the |
| 306 | // caller can make the distinction. |
| 307 | |
| 308 | *method_p = NULL; |
| 309 | |
| 310 | // On the initial call to this method the frame we get may not be |
| 311 | // recognizable to us. This should only happen if we are in a JRT_LEAF |
| 312 | // or something called by a JRT_LEAF method. |
| 313 | |
| 314 | frame candidate = *fr; |
| 315 | |
| 316 | // If the starting frame we were given has no codeBlob associated with |
| 317 | // it see if we can find such a frame because only frames with codeBlobs |
| 318 | // are possible Java frames. |
| 319 | |
| 320 | if (fr->cb() == NULL) { |
| 321 | |
| 322 | // See if we can find a useful frame |
| 323 | int loop_count; |
| 324 | int loop_max = MaxJavaStackTraceDepth * 2; |
| 325 | RegisterMap map(thread, false); |
| 326 | |
| 327 | for (loop_count = 0; loop_max == 0 || loop_count < loop_max; loop_count++) { |
| 328 | if (!candidate.safe_for_sender(thread)) return false; |
| 329 | candidate = candidate.sender(&map); |
| 330 | if (candidate.cb() != NULL) break; |
| 331 | } |
| 332 | if (candidate.cb() == NULL) return false; |
| 333 | } |
| 334 | |
| 335 | // We have a frame known to be in the codeCache |
| 336 | // We will hopefully be able to figure out something to do with it. |
| 337 | int loop_count; |
| 338 | int loop_max = MaxJavaStackTraceDepth * 2; |
| 339 | RegisterMap map(thread, false); |
| 340 | |
| 341 | for (loop_count = 0; loop_max == 0 || loop_count < loop_max; loop_count++) { |
| 342 | |
| 343 | if (candidate.is_entry_frame()) { |
| 344 | // jcw is NULL if the java call wrapper couldn't be found |
| 345 | JavaCallWrapper *jcw = candidate.entry_frame_call_wrapper_if_safe(thread); |
| 346 | // If initial frame is frame from StubGenerator and there is no |
| 347 | // previous anchor, there are no java frames associated with a method |
| 348 | if (jcw == NULL || jcw->is_first_frame()) { |
| 349 | return false; |
| 350 | } |
| 351 | } |
| 352 | |
| 353 | if (candidate.is_interpreted_frame()) { |
| 354 | if (is_decipherable_interpreted_frame(thread, &candidate, method_p, bci_p)) { |
| 355 | *initial_frame_p = candidate; |
| 356 | return true; |
| 357 | } |
| 358 | |
| 359 | // Hopefully we got some data |
| 360 | return false; |
| 361 | } |
| 362 | |
| 363 | if (candidate.cb()->is_compiled()) { |
| 364 | |
| 365 | CompiledMethod* nm = candidate.cb()->as_compiled_method(); |
| 366 | *method_p = nm->method(); |
| 367 | |
| 368 | // If the frame is not decipherable, then the value of -1 |
| 369 | // 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 will |
| 373 | // not be used. |
| 374 | |
| 375 | *bci_p = -1; |
| 376 | |
| 377 | *initial_frame_p = candidate; |
| 378 | |
| 379 | // Native wrapper code is trivial to decode by vframeStream |
| 380 | |
| 381 | if (nm->is_native_method()) return true; |
| 382 | |
| 383 | // If the frame is not decipherable, then a PC was found |
| 384 | // that does not have a PCDesc from which a BCI can be obtained. |
| 385 | // Nevertheless, a Method was found. |
| 386 | |
| 387 | if (!is_decipherable_compiled_frame(thread, &candidate, nm)) { |
| 388 | return false; |
| 389 | } |
| 390 | |
| 391 | // is_decipherable_compiled_frame may modify candidate's pc |
| 392 | *initial_frame_p = candidate; |
| 393 | |
| 394 | assert(nm->pc_desc_at(candidate.pc()) != NULL, "debug information must be available if the frame is decipherable" ); |
| 395 | |
| 396 | return true; |
| 397 | } |
| 398 | |
| 399 | // Must be some stub frame that we don't care about |
| 400 | |
| 401 | if (!candidate.safe_for_sender(thread)) return false; |
| 402 | candidate = candidate.sender(&map); |
| 403 | |
| 404 | // If it isn't in the code cache something is wrong |
| 405 | // since once we find a frame in the code cache they |
| 406 | // all should be there. |
| 407 | |
| 408 | if (candidate.cb() == NULL) return false; |
| 409 | |
| 410 | } |
| 411 | |
| 412 | return false; |
| 413 | |
| 414 | } |
| 415 | |
| 416 | static void forte_fill_call_trace_given_top(JavaThread* thd, |
| 417 | ASGCT_CallTrace* trace, |
| 418 | int depth, |
| 419 | frame top_frame) { |
| 420 | NoHandleMark nhm; |
| 421 | |
| 422 | frame initial_Java_frame; |
| 423 | Method* method; |
| 424 | int bci = -1; // assume BCI is not available for method |
| 425 | // update with correct information if available |
| 426 | int count; |
| 427 | |
| 428 | count = 0; |
| 429 | assert(trace->frames != NULL, "trace->frames must be non-NULL" ); |
| 430 | |
| 431 | // Walk the stack starting from 'top_frame' and search for an initial Java frame. |
| 432 | find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci); |
| 433 | |
| 434 | // Check if a Java Method has been found. |
| 435 | if (method == NULL) return; |
| 436 | |
| 437 | if (!Method::is_valid_method(method)) { |
| 438 | trace->num_frames = ticks_GC_active; // -2 |
| 439 | return; |
| 440 | } |
| 441 | |
| 442 | vframeStreamForte st(thd, initial_Java_frame, false); |
| 443 | |
| 444 | for (; !st.at_end() && count < depth; st.forte_next(), count++) { |
| 445 | bci = st.bci(); |
| 446 | method = st.method(); |
| 447 | |
| 448 | if (!Method::is_valid_method(method)) { |
| 449 | // we throw away everything we've gathered in this sample since |
| 450 | // none of it is safe |
| 451 | trace->num_frames = ticks_GC_active; // -2 |
| 452 | return; |
| 453 | } |
| 454 | |
| 455 | trace->frames[count].method_id = method->find_jmethod_id_or_null(); |
| 456 | if (!method->is_native()) { |
| 457 | trace->frames[count].lineno = bci; |
| 458 | } else { |
| 459 | trace->frames[count].lineno = -3; |
| 460 | } |
| 461 | } |
| 462 | trace->num_frames = count; |
| 463 | return; |
| 464 | } |
| 465 | |
| 466 | |
| 467 | // Forte Analyzer AsyncGetCallTrace() entry point. Currently supported |
| 468 | // on Linux X86, Solaris SPARC and Solaris X86. |
| 469 | // |
| 470 | // Async-safe version of GetCallTrace being called from a signal handler |
| 471 | // when a LWP gets interrupted by SIGPROF but the stack traces are filled |
| 472 | // with different content (see below). |
| 473 | // |
| 474 | // This function must only be called when JVM/TI |
| 475 | // CLASS_LOAD events have been enabled since agent startup. The enabled |
| 476 | // event will cause the jmethodIDs to be allocated at class load time. |
| 477 | // The jmethodIDs cannot be allocated in a signal handler because locks |
| 478 | // 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 for |
| 483 | // a given thread. The thread is identified by the env_id field in the |
| 484 | // ASGCT_CallTrace structure. The profiler agent should allocate a ASGCT_CallTrace |
| 485 | // structure with enough memory for the requested stack depth. The VM fills in |
| 486 | // 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 LWP |
| 493 | // |
| 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 available |
| 516 | // method_id - jmethodID of the method being executed |
| 517 | // 2) For native method |
| 518 | // lineno - (-3) |
| 519 | // method_id - jmethodID of the method being executed |
| 520 | |
| 521 | extern "C" { |
| 522 | JNIEXPORT |
| 523 | void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) { |
| 524 | JavaThread* thread; |
| 525 | |
| 526 | if (trace->env_id == NULL || |
| 527 | (thread = JavaThread::thread_from_jni_environment(trace->env_id)) == NULL || |
| 528 | thread->is_exiting()) { |
| 529 | |
| 530 | // bad env_id, thread has exited or thread is exiting |
| 531 | trace->num_frames = ticks_thread_exit; // -8 |
| 532 | return; |
| 533 | } |
| 534 | |
| 535 | if (thread->in_deopt_handler()) { |
| 536 | // thread is in the deoptimization handler so return no frames |
| 537 | trace->num_frames = ticks_deopt; // -9 |
| 538 | return; |
| 539 | } |
| 540 | |
| 541 | assert(JavaThread::current() == thread, |
| 542 | "AsyncGetCallTrace must be called by the current interrupted thread" ); |
| 543 | |
| 544 | if (!JvmtiExport::should_post_class_load()) { |
| 545 | trace->num_frames = ticks_no_class_load; // -1 |
| 546 | return; |
| 547 | } |
| 548 | |
| 549 | if (Universe::heap()->is_gc_active()) { |
| 550 | trace->num_frames = ticks_GC_active; // -2 |
| 551 | return; |
| 552 | } |
| 553 | |
| 554 | switch (thread->thread_state()) { |
| 555 | case _thread_new: |
| 556 | case _thread_uninitialized: |
| 557 | case _thread_new_trans: |
| 558 | // We found the thread on the threads list above, but it is too |
| 559 | // young to be useful so return that there are no Java frames. |
| 560 | trace->num_frames = 0; |
| 561 | break; |
| 562 | case _thread_in_native: |
| 563 | case _thread_in_native_trans: |
| 564 | case _thread_blocked: |
| 565 | case _thread_blocked_trans: |
| 566 | case _thread_in_vm: |
| 567 | case _thread_in_vm_trans: |
| 568 | { |
| 569 | frame fr; |
| 570 | |
| 571 | // param isInJava == false - indicate we aren't in Java code |
| 572 | if (!thread->pd_get_top_frame_for_signal_handler(&fr, ucontext, false)) { |
| 573 | trace->num_frames = ticks_unknown_not_Java; // -3 unknown frame |
| 574 | } else { |
| 575 | if (!thread->has_last_Java_frame()) { |
| 576 | trace->num_frames = 0; // No Java frames |
| 577 | } else { |
| 578 | trace->num_frames = ticks_not_walkable_not_Java; // -4 non walkable frame by default |
| 579 | forte_fill_call_trace_given_top(thread, trace, depth, fr); |
| 580 | |
| 581 | // This assert would seem to be valid but it is not. |
| 582 | // It would be valid if we weren't possibly racing a gc |
| 583 | // thread. A gc thread can make a valid interpreted frame |
| 584 | // 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"); |
| 587 | |
| 588 | } |
| 589 | } |
| 590 | } |
| 591 | break; |
| 592 | case _thread_in_Java: |
| 593 | case _thread_in_Java_trans: |
| 594 | { |
| 595 | frame fr; |
| 596 | |
| 597 | // param isInJava == true - indicate we are in Java code |
| 598 | if (!thread->pd_get_top_frame_for_signal_handler(&fr, ucontext, true)) { |
| 599 | trace->num_frames = ticks_unknown_Java; // -5 unknown frame |
| 600 | } else { |
| 601 | trace->num_frames = ticks_not_walkable_Java; // -6, non walkable frame by default |
| 602 | forte_fill_call_trace_given_top(thread, trace, depth, fr); |
| 603 | } |
| 604 | } |
| 605 | break; |
| 606 | default: |
| 607 | // Unknown thread state |
| 608 | trace->num_frames = ticks_unknown_state; // -7 |
| 609 | break; |
| 610 | } |
| 611 | } |
| 612 | |
| 613 | |
| 614 | #ifndef _WINDOWS |
| 615 | // Support for the Forte(TM) Peformance Tools collector. |
| 616 | // |
| 617 | // The method prototype is derived from libcollector.h. For more |
| 618 | // information, please see the libcollect man page. |
| 619 | |
| 620 | // Method to let libcollector know about a dynamically loaded function. |
| 621 | // Because it is weakly bound, the calls become NOP's when the library |
| 622 | // isn't present. |
| 623 | #ifdef __APPLE__ |
| 624 | // XXXDARWIN: Link errors occur even when __attribute__((weak_import)) |
| 625 | // is added |
| 626 | #define collector_func_load(x0,x1,x2,x3,x4,x5,x6) ((void) 0) |
| 627 | #else |
| 628 | void collector_func_load(char* name, |
| 629 | void* null_argument_1, |
| 630 | void* null_argument_2, |
| 631 | void *vaddr, |
| 632 | int size, |
| 633 | int zero_argument, |
| 634 | void* null_argument_3); |
| 635 | #pragma weak collector_func_load |
| 636 | #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 // !_WINDOWS |
| 640 | |
| 641 | } // end extern "C" |
| 642 | #endif // !IA64 |
| 643 | |
| 644 | void Forte::register_stub(const char* name, address start, address end) { |
| 645 | #if !defined(_WINDOWS) && !defined(IA64) |
| 646 | assert(pointer_delta(end, start, sizeof(jbyte)) < INT_MAX, |
| 647 | "Code size exceeds maximum range" ); |
| 648 | |
| 649 | collector_func_load((char*)name, NULL, NULL, start, |
| 650 | pointer_delta(end, start, sizeof(jbyte)), 0, NULL); |
| 651 | #endif // !_WINDOWS && !IA64 |
| 652 | } |
| 653 | |
| 654 | #else // INCLUDE_JVMTI |
| 655 | extern "C" { |
| 656 | JNIEXPORT |
| 657 | void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) { |
| 658 | trace->num_frames = ticks_no_class_load; // -1 |
| 659 | } |
| 660 | } |
| 661 | #endif // INCLUDE_JVMTI |
| 662 | |