forte.cpp 30.9 KB
Newer Older
D
duke 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895
/*
 * 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
}