hotspot/src/share/vm/prims/forte.cpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 670 ddf3e9583f2f
child 5233 6fd5e41e3f54
permissions -rw-r--r--
6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
670
ddf3e9583f2f 6719955: Update copyright year
xdono
parents: 354
diff changeset
     2
 * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_forte.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    28
// These name match the names reported by the forte quality kit
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    29
enum {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    30
  ticks_no_Java_frame         =  0,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    31
  ticks_no_class_load         = -1,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    32
  ticks_GC_active             = -2,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    33
  ticks_unknown_not_Java      = -3,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    34
  ticks_not_walkable_not_Java = -4,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    35
  ticks_unknown_Java          = -5,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    36
  ticks_not_walkable_Java     = -6,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    37
  ticks_unknown_state         = -7,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    38
  ticks_thread_exit           = -8,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    39
  ticks_deopt                 = -9,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    40
  ticks_safepoint             = -10
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    41
};
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
//-------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
// Native interfaces for use by Forte tools.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
#ifndef IA64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
class vframeStreamForte : public vframeStreamCommon {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  // constructor that starts with sender of frame fr (top_frame)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
  vframeStreamForte(JavaThread *jt, frame fr, bool stop_at_java_call_stub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  void forte_next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    58
static void is_decipherable_compiled_frame(frame* fr, RegisterMap* map,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  bool* is_compiled_p, bool* is_walkable_p);
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    60
static bool is_decipherable_interpreted_frame(JavaThread* thread,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    61
                                                frame* fr,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    62
                                                methodOop* method_p,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    63
                                                int* bci_p);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    68
vframeStreamForte::vframeStreamForte(JavaThread *jt,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    69
                                     frame fr,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    70
                                     bool stop_at_java_call_stub) : vframeStreamCommon(jt) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  _stop_at_java_call_stub = stop_at_java_call_stub;
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    73
  _frame = fr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    75
  // We must always have a valid frame to start filling
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    77
  bool filled_in = fill_from_frame();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
    79
  assert(filled_in, "invariant");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
// Solaris SPARC Compiler1 needs an additional check on the grandparent
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
// of the top_frame when the parent of the top_frame is interpreted and
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
// the grandparent is compiled. However, in this method we do not know
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
// the relationship of the current _frame relative to the top_frame so
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
// we implement a more broad sanity check. When the previous callee is
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
// interpreted and the current sender is compiled, we verify that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
// current sender is also walkable. If it is not walkable, then we mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
// the current vframeStream as at the end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
void vframeStreamForte::forte_next() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  // handle frames with inlining
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  if (_mode == compiled_mode &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
      vframeStreamCommon::fill_in_compiled_inlined_sender()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  // handle general case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
  int loop_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  int loop_max = MaxJavaStackTraceDepth * 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   107
    loop_count++;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   109
    // By the time we get here we should never see unsafe but better
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   110
    // safe then segv'd
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   112
    if (loop_count > loop_max || !_frame.safe_for_sender(_thread)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
      _mode = at_end_mode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   117
    _frame = _frame.sender(&_reg_map);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  } while (!fill_from_frame());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   122
// Determine if 'fr' is a decipherable compiled frame. We are already
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   123
// assured that fr is for a java nmethod.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   124
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   125
static bool is_decipherable_compiled_frame(frame* fr) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   127
  assert(fr->cb() != NULL && fr->cb()->is_nmethod(), "invariant");
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   128
  nmethod* nm = (nmethod*) fr->cb();
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   129
  assert(nm->is_java_method(), "invariant");
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   130
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   131
  // First try and find an exact PcDesc
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   133
  PcDesc* pc_desc = nm->pc_desc_at(fr->pc());
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   134
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   135
  // Did we find a useful PcDesc?
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   136
  if (pc_desc != NULL &&
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   137
      pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   139
    address probe_pc = fr->pc() + 1;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   140
    pc_desc = nm->pc_desc_near(probe_pc);
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   141
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   142
    // Now do we have a useful PcDesc?
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   143
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   144
    if (pc_desc != NULL &&
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   145
        pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   146
      // No debug information available for this pc
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   147
      // vframeStream would explode if we try and walk the frames.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   148
      return false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    }
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   150
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   151
    // This PcDesc is useful however we must adjust the frame's pc
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   152
    // so that the vframeStream lookups will use this same pc
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   153
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   154
    fr->set_pc(pc_desc->real_pc(nm));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  }
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   156
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   157
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
// Determine if 'fr' is a walkable interpreted frame. Returns false
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
// if it is not. *method_p, and *bci_p are not set when false is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
// returned. *method_p is non-NULL if frame was executing a Java
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
// method. *bci_p is != -1 if a valid BCI in the Java method could
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
// be found.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
// Note: this method returns true when a valid Java method is found
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
// even if a valid BCI cannot be found.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   168
static bool is_decipherable_interpreted_frame(JavaThread* thread,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   169
                                                frame* fr,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   170
                                                methodOop* method_p,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   171
                                                int* bci_p) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  assert(fr->is_interpreted_frame(), "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  // top frame is an interpreted frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  // check if it is walkable (i.e. valid methodOop and valid bci)
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   176
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   177
  // Because we may be racing a gc thread the method and/or bci
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   178
  // of a valid interpreter frame may look bad causing us to
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   179
  // fail the is_interpreted_frame_valid test. If the thread
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   180
  // is in any of the following states we are assured that the
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   181
  // frame is in fact valid and we must have hit the race.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   182
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   183
  JavaThreadState state = thread->thread_state();
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   184
  bool known_valid = (state == _thread_in_native ||
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   185
                      state == _thread_in_vm ||
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   186
                      state == _thread_blocked );
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   187
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   188
  if (known_valid || fr->is_interpreted_frame_valid(thread)) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   189
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   190
    // The frame code should completely validate the frame so that
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   191
    // references to methodOop and bci are completely safe to access
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   192
    // If they aren't the frame code should be fixed not this
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   193
    // code. However since gc isn't locked out the values could be
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   194
    // stale. This is a race we can never completely win since we can't
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   195
    // lock out gc so do one last check after retrieving their values
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   196
    // from the frame for additional safety
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   197
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   198
    methodOop method = fr->interpreter_frame_method();
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   199
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   200
    // We've at least found a method.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   201
    // NOTE: there is something to be said for the approach that
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   202
    // if we don't find a valid bci then the method is not likely
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   203
    // a valid method. Then again we may have caught an interpreter
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   204
    // frame in the middle of construction and the bci field is
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   205
    // not yet valid.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   206
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   207
    *method_p = method;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   208
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   209
    // See if gc may have invalidated method since we validated frame
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   210
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   211
    if (!Universe::heap()->is_valid_method(method)) return false;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   212
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   213
    intptr_t bcx = fr->interpreter_frame_bcx();
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   214
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   215
    int      bci = method->validate_bci_from_bcx(bcx);
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   216
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   217
    // note: bci is set to -1 if not a valid bci
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   218
    *bci_p = bci;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   219
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  }
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   221
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   226
// Determine if 'fr' can be used to find an initial Java frame.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   227
// Return false if it can not find a fully decipherable Java frame
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   228
// (in other words a frame that isn't safe to use in a vframe stream).
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   229
// Obviously if it can't even find a Java frame false will also be returned.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   230
//
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   231
// If we find a Java frame decipherable or not then by definition we have
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   232
// identified a method and that will be returned to the caller via method_p.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   233
// If we can determine a bci that is returned also. (Hmm is it possible
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   234
// to return a method and bci and still return false? )
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   235
//
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   236
// The initial Java frame we find (if any) is return via initial_frame_p.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
//
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   238
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   239
static bool find_initial_Java_frame(JavaThread* thread,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   240
                                    frame* fr,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   241
                                    frame* initial_frame_p,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   242
                                    methodOop* method_p,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   243
                                    int* bci_p) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   244
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   245
  // It is possible that for a frame containing an nmethod
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   246
  // we can capture the method but no bci. If we get no
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   247
  // bci the frame isn't walkable but the method is usable.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   248
  // Therefore we init the returned methodOop to NULL so the
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   249
  // caller can make the distinction.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   250
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   251
  *method_p = NULL;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   252
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   253
  // On the initial call to this method the frame we get may not be
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   254
  // recognizable to us. This should only happen if we are in a JRT_LEAF
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   255
  // or something called by a JRT_LEAF method.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   256
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   258
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   259
  frame candidate = *fr;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   260
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   261
  // If the starting frame we were given has no codeBlob associated with
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   262
  // it see if we can find such a frame because only frames with codeBlobs
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   263
  // are possible Java frames.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   264
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   265
  if (fr->cb() == NULL) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   266
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   267
    // See if we can find a useful frame
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   268
    int loop_count;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   269
    int loop_max = MaxJavaStackTraceDepth * 2;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   270
    RegisterMap map(thread, false);
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   271
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   272
    for (loop_count = 0; loop_count < loop_max; loop_count++) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   273
      if (!candidate.safe_for_sender(thread)) return false;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   274
      candidate = candidate.sender(&map);
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   275
      if (candidate.cb() != NULL) break;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   276
    }
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   277
    if (candidate.cb() == NULL) return false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   280
  // We have a frame known to be in the codeCache
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   281
  // We will hopefully be able to figure out something to do with it.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  int loop_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  int loop_max = MaxJavaStackTraceDepth * 2;
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   284
  RegisterMap map(thread, false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  for (loop_count = 0; loop_count < loop_max; loop_count++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   288
    if (candidate.is_first_frame()) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   289
      // If initial frame is frame from StubGenerator and there is no
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   290
      // previous anchor, there are no java frames associated with a method
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   291
      return false;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   292
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   294
    if (candidate.is_interpreted_frame()) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   295
      if (is_decipherable_interpreted_frame(thread, &candidate, method_p, bci_p)) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   296
        *initial_frame_p = candidate;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   297
        return true;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   298
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   300
      // Hopefully we got some data
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   301
      return false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   304
    if (candidate.cb()->is_nmethod()) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   305
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   306
      nmethod* nm = (nmethod*) candidate.cb();
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   307
      *method_p = nm->method();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   309
      // If the frame isn't fully decipherable then the default
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   310
      // value for the bci is a signal that we don't have a bci.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   311
      // If we have a decipherable frame this bci value will
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   312
      // not be used.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   313
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   314
      *bci_p = -1;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   316
      *initial_frame_p = candidate;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   317
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   318
      // Native wrapper code is trivial to decode by vframeStream
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   319
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   320
      if (nm->is_native_method()) return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   322
      // If it isn't decipherable then we have found a pc that doesn't
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   323
      // have a PCDesc that can get us a bci however we did find
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   324
      // a method
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   326
      if (!is_decipherable_compiled_frame(&candidate)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
        return false;
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   328
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   330
      // is_decipherable_compiled_frame may modify candidate's pc
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   331
      *initial_frame_p = candidate;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   333
      return true;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   334
    }
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   335
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   336
    // Must be some stub frame that we don't care about
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   338
    if (!candidate.safe_for_sender(thread)) return false;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   339
    candidate = candidate.sender(&map);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   341
    // If it isn't in the code cache something is wrong
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   342
    // since once we find a frame in the code cache they
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   343
    // all should be there.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   344
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   345
    if (candidate.cb() == NULL) return false;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   346
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   349
  return false;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   350
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
// call frame copied from old .h file and renamed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
typedef struct {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
    jint lineno;                      // line number in the source file
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
    jmethodID method_id;              // method executed in this frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
} ASGCT_CallFrame;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
// call trace copied from old .h file and renamed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
typedef struct {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
    JNIEnv *env_id;                   // Env where trace was recorded
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
    jint num_frames;                  // number of frames in this trace
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
    ASGCT_CallFrame *frames;          // frames
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
} ASGCT_CallTrace;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
static void forte_fill_call_trace_given_top(JavaThread* thd,
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   368
                                            ASGCT_CallTrace* trace,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   369
                                            int depth,
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   370
                                            frame top_frame) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  NoHandleMark nhm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   373
  frame initial_Java_frame;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  methodOop method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  int bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  int count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
  count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
  assert(trace->frames != NULL, "trace->frames must be non-NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   381
  bool fully_decipherable = find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci);
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   382
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   383
  // The frame might not be walkable but still recovered a method
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   384
  // (e.g. an nmethod with no scope info for the pc
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   385
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   386
  if (method == NULL) return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  CollectedHeap* ch = Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   390
  // The method is not stored GC safe so see if GC became active
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   391
  // after we entered AsyncGetCallTrace() and before we try to
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   392
  // use the methodOop.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   393
  // Yes, there is still a window after this check and before
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   394
  // we use methodOop below, but we can't lock out GC so that
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   395
  // has to be an acceptable risk.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   396
  if (!ch->is_valid_method(method)) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   397
    trace->num_frames = ticks_GC_active; // -2
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   401
  // We got a Java frame however it isn't fully decipherable
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   402
  // so it won't necessarily be safe to use it for the
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   403
  // initial frame in the vframe stream.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   404
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   405
  if (!fully_decipherable) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   406
    // Take whatever method the top-frame decoder managed to scrape up.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   407
    // We look further at the top frame only if non-safepoint
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   408
    // debugging information is available.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   409
    count++;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   410
    trace->num_frames = count;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   411
    trace->frames[0].method_id = method->find_jmethod_id_or_null();
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   412
    if (!method->is_native()) {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   413
      trace->frames[0].lineno = bci;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   414
    } else {
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   415
      trace->frames[0].lineno = -3;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   416
    }
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   417
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   418
    if (!initial_Java_frame.safe_for_sender(thd)) return;
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   419
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   420
    RegisterMap map(thd, false);
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   421
    initial_Java_frame = initial_Java_frame.sender(&map);
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   422
  }
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   423
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   424
  vframeStreamForte st(thd, initial_Java_frame, false);
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   425
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  for (; !st.at_end() && count < depth; st.forte_next(), count++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    bci = st.bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
    method = st.method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
    // The method is not stored GC safe so see if GC became active
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
    // after we entered AsyncGetCallTrace() and before we try to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
    // use the methodOop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
    // Yes, there is still a window after this check and before
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
    // we use methodOop below, but we can't lock out GC so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
    // has to be an acceptable risk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
    if (!ch->is_valid_method(method)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
      // we throw away everything we've gathered in this sample since
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
      // none of it is safe
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   439
      trace->num_frames = ticks_GC_active; // -2
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
    trace->frames[count].method_id = method->find_jmethod_id_or_null();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
    if (!method->is_native()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
      trace->frames[count].lineno = bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
      trace->frames[count].lineno = -3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  trace->num_frames = count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
// Forte Analyzer AsyncGetCallTrace() entry point. Currently supported
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
// on Linux X86, Solaris SPARC and Solaris X86.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
// Async-safe version of GetCallTrace being called from a signal handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
// when a LWP gets interrupted by SIGPROF but the stack traces are filled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
// with different content (see below).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
// This function must only be called when JVM/TI
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
// CLASS_LOAD events have been enabled since agent startup. The enabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
// event will cause the jmethodIDs to be allocated at class load time.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
// The jmethodIDs cannot be allocated in a signal handler because locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
// cannot be grabbed in a signal handler safely.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
// void (*AsyncGetCallTrace)(ASGCT_CallTrace *trace, jint depth, void* ucontext)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
// Called by the profiler to obtain the current method call stack trace for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
// a given thread. The thread is identified by the env_id field in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
// ASGCT_CallTrace structure. The profiler agent should allocate a ASGCT_CallTrace
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
// structure with enough memory for the requested stack depth. The VM fills in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
// the frames buffer and the num_frames field.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
// Arguments:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
//   trace    - trace data structure to be filled by the VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
//   depth    - depth of the call stack trace.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
//   ucontext - ucontext_t of the LWP
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
// ASGCT_CallTrace:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
//   typedef struct {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
//       JNIEnv *env_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
//       jint num_frames;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
//       ASGCT_CallFrame *frames;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
//   } ASGCT_CallTrace;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
// Fields:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
//   env_id     - ID of thread which executed this trace.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
//   num_frames - number of frames in the trace.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
//                (< 0 indicates the frame is not walkable).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
//   frames     - the ASGCT_CallFrames that make up this trace. Callee followed by callers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
//  ASGCT_CallFrame:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
//    typedef struct {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
//        jint lineno;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
//        jmethodID method_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
//    } ASGCT_CallFrame;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
//  Fields:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
//    1) For Java frame (interpreted and compiled),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
//       lineno    - bci of the method being executed or -1 if bci is not available
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
//       method_id - jmethodID of the method being executed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
//    2) For native method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
//       lineno    - (-3)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
//       method_id - jmethodID of the method being executed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   511
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   512
// This is if'd out because we no longer use thread suspension.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   513
// However if someone wanted to backport this to a 5.0 jvm then this
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   514
// code would be important.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   515
#if 0
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  if (SafepointSynchronize::is_synchronizing()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
    // The safepoint mechanism is trying to synchronize all the threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
    // Since this can involve thread suspension, it is not safe for us
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
    // to be here. We can reduce the deadlock risk window by quickly
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
    // returning to the SIGPROF handler. However, it is still possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
    // for VMThread to catch us here or in the SIGPROF handler. If we
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
    // are suspended while holding a resource and another thread blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
    // on that resource in the SIGPROF handler, then we will have a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
    // three-thread deadlock (VMThread, this thread, the other thread).
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   525
    trace->num_frames = ticks_safepoint; // -10
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  }
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   528
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  JavaThread* thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  if (trace->env_id == NULL ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
    (thread = JavaThread::thread_from_jni_environment(trace->env_id)) == NULL ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    thread->is_exiting()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    // bad env_id, thread has exited or thread is exiting
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   537
    trace->num_frames = ticks_thread_exit; // -8
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  if (thread->in_deopt_handler()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
    // thread is in the deoptimization handler so return no frames
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   543
    trace->num_frames = ticks_deopt; // -9
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  assert(JavaThread::current() == thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
         "AsyncGetCallTrace must be called by the current interrupted thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  if (!JvmtiExport::should_post_class_load()) {
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   551
    trace->num_frames = ticks_no_class_load; // -1
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  if (Universe::heap()->is_gc_active()) {
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   556
    trace->num_frames = ticks_GC_active; // -2
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  switch (thread->thread_state()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  case _thread_new:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  case _thread_uninitialized:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  case _thread_new_trans:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
    // We found the thread on the threads list above, but it is too
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
    // young to be useful so return that there are no Java frames.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
    trace->num_frames = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  case _thread_in_native:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
  case _thread_in_native_trans:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
  case _thread_blocked:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
  case _thread_blocked_trans:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  case _thread_in_vm:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  case _thread_in_vm_trans:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
      frame fr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
      // param isInJava == false - indicate we aren't in Java code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
      if (!thread->pd_get_top_frame_for_signal_handler(&fr, ucontext, false)) {
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   579
        trace->num_frames = ticks_unknown_not_Java;  // -3 unknown frame
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   580
      } else {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
        if (!thread->has_last_Java_frame()) {
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   582
          trace->num_frames = 0; // No Java frames
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
        } else {
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   584
          trace->num_frames = ticks_not_walkable_not_Java;    // -4 non walkable frame by default
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   585
          forte_fill_call_trace_given_top(thread, trace, depth, fr);
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   586
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   587
          // This assert would seem to be valid but it is not.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   588
          // It would be valid if we weren't possibly racing a gc
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   589
          // thread. A gc thread can make a valid interpreted frame
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   590
          // look invalid. It's a small window but it does happen.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   591
          // The assert is left here commented out as a reminder.
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   592
          // assert(trace->num_frames != ticks_not_walkable_not_Java, "should always be walkable");
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   593
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
  case _thread_in_Java:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
  case _thread_in_Java_trans:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
      frame fr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
      // param isInJava == true - indicate we are in Java code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
      if (!thread->pd_get_top_frame_for_signal_handler(&fr, ucontext, true)) {
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   605
        trace->num_frames = ticks_unknown_Java;  // -5 unknown frame
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
      } else {
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   607
        trace->num_frames = ticks_not_walkable_Java;  // -6, non walkable frame by default
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
        forte_fill_call_trace_given_top(thread, trace, depth, fr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
    // Unknown thread state
354
3b42d6fdcb82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 1
diff changeset
   614
    trace->num_frames = ticks_unknown_state; // -7
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
#ifndef _WINDOWS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
// Support for the Forte(TM) Peformance Tools collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
// The method prototype is derived from libcollector.h. For more
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
// information, please see the libcollect man page.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
// Method to let libcollector know about a dynamically loaded function.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
// Because it is weakly bound, the calls become NOP's when the library
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
// isn't present.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
void    collector_func_load(char* name,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
                            void* null_argument_1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
                            void* null_argument_2,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
                            void *vaddr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
                            int size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
                            int zero_argument,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
                            void* null_argument_3);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
#pragma weak collector_func_load
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
#define collector_func_load(x0,x1,x2,x3,x4,x5,x6) \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
        ( collector_func_load ? collector_func_load(x0,x1,x2,x3,x4,x5,x6),0 : 0 )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
#endif // !_WINDOWS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
} // end extern "C"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
#endif // !IA64
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
void Forte::register_stub(const char* name, address start, address end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
#if !defined(_WINDOWS) && !defined(IA64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
  assert(pointer_delta(end, start, sizeof(jbyte)) < INT_MAX,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
    "Code size exceeds maximum range")
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
  collector_func_load((char*)name, NULL, NULL, start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
    pointer_delta(end, start, sizeof(jbyte)), 0, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
#endif // !_WINDOWS && !IA64
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
}