示例#1
0
// Unpacks one or more frames into user-supplied buffers.
// Updates the end index, and returns the number of unpacked frames.
// Always start with the existing vfst.method and bci.
// Do not call vfst.next to advance over the last returned value.
// In other words, do not leave any stale data in the vfst.
//
// Parameters:
//   mode             Restrict which frames to be decoded.
//   BaseFrameStream  stream of frames
//   max_nframes      Maximum number of frames to be filled.
//   start_index      Start index to the user-supplied buffers.
//   frames_array     Buffer to store Class or StackFrame in, starting at start_index.
//                    frames array is a Class<?>[] array when only getting caller
//                    reference, and a StackFrameInfo[] array (or derivative)
//                    otherwise. It should never be null.
//   end_index        End index to the user-supplied buffers with unpacked frames.
//
// Returns the number of frames whose information was transferred into the buffers.
//
int StackWalk::fill_in_frames(jlong mode, BaseFrameStream& stream,
                              int max_nframes, int start_index,
                              objArrayHandle  frames_array,
                              int& end_index, TRAPS) {
    log_debug(stackwalk)("fill_in_frames limit=%d start=%d frames length=%d",
                         max_nframes, start_index, frames_array->length());
    assert(max_nframes > 0, "invalid max_nframes");
    assert(start_index + max_nframes <= frames_array->length(), "oob");

    int frames_decoded = 0;
    for (; !stream.at_end(); stream.next()) {
        Method* method = stream.method();

        if (method == NULL) continue;

        // skip hidden frames for default StackWalker option (i.e. SHOW_HIDDEN_FRAMES
        // not set) and when StackWalker::getCallerClass is called
        if (!ShowHiddenFrames && (skip_hidden_frames(mode) || get_caller_class(mode))) {
            if (method->is_hidden()) {
                if (log_is_enabled(Debug, stackwalk)) {
                    ResourceMark rm(THREAD);
                    outputStream* st = Log(stackwalk)::debug_stream();
                    st->print("  hidden method: ");
                    method->print_short_name(st);
                    st->cr();
                }
                continue;
            }
        }

        int index = end_index++;
        if (log_is_enabled(Debug, stackwalk)) {
            ResourceMark rm(THREAD);
            outputStream* st = Log(stackwalk)::debug_stream();
            st->print("  %d: frame method: ", index);
            method->print_short_name(st);
            st->print_cr(" bci=%d", stream.bci());
        }

        if (!need_method_info(mode) && get_caller_class(mode) &&
                index == start_index && method->caller_sensitive()) {
            ResourceMark rm(THREAD);
            THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(),
                        err_msg("StackWalker::getCallerClass called from @CallerSensitive %s method",
                                method->name_and_sig_as_C_string()));
        }
        // fill in StackFrameInfo and initialize MemberName
        stream.fill_frame(index, frames_array, method, CHECK_0);
        if (++frames_decoded >= max_nframes)  break;
    }
    return frames_decoded;
}
示例#2
0
// Unpacks one or more frames into user-supplied buffers.
// Updates the end index, and returns the number of unpacked frames.
// Always start with the existing vfst.method and bci.
// Do not call vfst.next to advance over the last returned value.
// In other words, do not leave any stale data in the vfst.
//
// Parameters:
//   mode             Restrict which frames to be decoded.
//   JavaFrameStream  stream of javaVFrames
//   max_nframes      Maximum number of frames to be filled.
//   start_index      Start index to the user-supplied buffers.
//   frames_array     Buffer to store Class or StackFrame in, starting at start_index.
//                    frames array is a Class<?>[] array when only getting caller
//                    reference, and a StackFrameInfo[] array (or derivative)
//                    otherwise. It should never be null.
//   end_index        End index to the user-supplied buffers with unpacked frames.
//
// Returns the number of frames whose information was transferred into the buffers.
//
int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream,
                              int max_nframes, int start_index,
                              objArrayHandle  frames_array,
                              int& end_index, TRAPS) {
  if (TraceStackWalk) {
    tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d",
                  max_nframes, start_index, frames_array->length());
  }
  assert(max_nframes > 0, "invalid max_nframes");
  assert(start_index + max_nframes <= frames_array->length(), "oob");

  int frames_decoded = 0;
  for (; !stream.at_end(); stream.next()) {
    Method* method = stream.method();
    int bci = stream.bci();

    if (method == NULL) continue;
    if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) {
      if (method->is_hidden()) {
        if (TraceStackWalk) {
          tty->print("  hidden method: "); method->print_short_name();
          tty->print("\n");
        }
        continue;
      }
    }

    int index = end_index++;
    if (TraceStackWalk) {
      tty->print("  %d: frame method: ", index); method->print_short_name();
      tty->print_cr(" bci=%d", bci);
    }

    // fill in StackFrameInfo and initialize MemberName
    if (live_frame_info(mode)) {
      assert (use_frames_array(mode), "Bad mode for get live frame");
      Handle stackFrame(frames_array->obj_at(index));
      fill_live_stackframe(stackFrame, method, bci, stream.java_frame(), CHECK_0);
    } else if (need_method_info(mode)) {
      assert (use_frames_array(mode), "Bad mode for get stack frame");
      Handle stackFrame(frames_array->obj_at(index));
      fill_stackframe(stackFrame, method, bci);
    } else {
      assert (use_frames_array(mode) == false, "Bad mode for get caller class");
      frames_array->obj_at_put(index, method->method_holder()->java_mirror());
    }
    if (++frames_decoded >= max_nframes)  break;
  }
  return frames_decoded;
}
示例#3
0
void Rewriter::relocate_and_link(instanceKlassHandle this_oop,
                                 objArrayHandle methods, TRAPS) {
  int len = methods->length();
  for (int i = len-1; i >= 0; i--) {
    methodHandle m(THREAD, (methodOop)methods->obj_at(i));

    if (m->has_jsrs()) {
      m = rewrite_jsrs(m, CHECK);
      // Method might have gotten rewritten.
      methods->obj_at_put(i, m());
    }

    // Set up method entry points for compiler and interpreter    .
    m->link_method(m, CHECK);

    // This is for JVMTI and unrelated to relocator but the last thing we do
#ifdef ASSERT
    if (StressMethodComparator) {
      static int nmc = 0;
      for (int j = i; j >= 0 && j >= i-4; j--) {
        if ((++nmc % 1000) == 0)  tty->print_cr("Have run MethodComparator %d times...", nmc);
        bool z = MethodComparator::methods_EMCP(m(),
                   (methodOop)methods->obj_at(j));
        if (j == i && !z) {
          tty->print("MethodComparator FAIL: "); m->print(); m->print_codes();
          assert(z, "method must compare equal to itself");
        }
      }
    }
#endif //ASSERT
  }
}
示例#4
0
// Walk the next batch of stack frames
//
// Parameters:
//   stackStream    StackStream object
//   mode           Stack walking mode.
//   magic          Must be valid value to continue the stack walk
//   frame_count    Number of frames to be decoded.
//   start_index    Start index to the user-supplied buffers.
//   classes_array  Buffer to store classes in, starting at start_index.
//   frames_array   Buffer to store StackFrame in, starting at start_index.
//                  NULL if not used.
//
// Returns the end index of frame filled in the buffer.
//
jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic,
                           int frame_count, int start_index,
                           objArrayHandle classes_array,
                           objArrayHandle frames_array,
                           TRAPS)
{
  JavaThread* jt = (JavaThread*)THREAD;
  StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, classes_array);
  if (existing_anchor == NULL) {
    THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
  }

  if ((need_method_info(mode) || live_frame_info(mode)) && frames_array.is_null()) {
    THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L);
  }

  if (TraceStackWalk) {
    tty->print_cr("StackWalk::moreFrames frame_count %d existing_anchor " PTR_FORMAT " start %d frames %d",
                  frame_count, p2i(existing_anchor), start_index, classes_array->length());
  }
  int end_index = start_index;
  if (frame_count <= 0) {
    return end_index;        // No operation.
  }

  int count = frame_count + start_index;
  assert (classes_array->length() >= count, "not enough space in buffers");

  StackWalkAnchor& anchor = (*existing_anchor);
  vframeStream& vfst = anchor.vframe_stream();
  if (!vfst.at_end()) {
    vfst.next();  // this was the last frame decoded in the previous batch
    if (!vfst.at_end()) {
      int n = fill_in_frames(mode, vfst, frame_count, start_index, classes_array,
                             frames_array, end_index, CHECK_0);
      if (n < 1) {
        THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
      }
      return end_index;
    }
  }
  return end_index;
}
示例#5
0
// Walk the next batch of stack frames
//
// Parameters:
//   stackStream    StackStream object
//   mode           Stack walking mode.
//   magic          Must be valid value to continue the stack walk
//   frame_count    Number of frames to be decoded.
//   start_index    Start index to the user-supplied buffers.
//   frames_array   Buffer to store StackFrame in, starting at start_index.
//
// Returns the end index of frame filled in the buffer.
//
jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic,
                           int frame_count, int start_index,
                           objArrayHandle frames_array,
                           TRAPS)
{
  JavaThread* jt = (JavaThread*)THREAD;
  JavaFrameStream* existing_stream = JavaFrameStream::from_current(jt, magic, frames_array);
  if (existing_stream == NULL) {
    THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
  }

  if (frames_array.is_null()) {
    THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L);
  }

  if (TraceStackWalk) {
    tty->print_cr("StackWalk::moreFrames frame_count %d existing_stream " PTR_FORMAT " start %d frames %d",
                  frame_count, p2i(existing_stream), start_index, frames_array->length());
  }
  int end_index = start_index;
  if (frame_count <= 0) {
    return end_index;        // No operation.
  }

  int count = frame_count + start_index;
  assert (frames_array->length() >= count, "not enough space in buffers");

  JavaFrameStream& stream = (*existing_stream);
  if (!stream.at_end()) {
    stream.next(); // advance past the last frame decoded in previous batch
    if (!stream.at_end()) {
      int n = fill_in_frames(mode, stream, frame_count, start_index,
                             frames_array, end_index, CHECK_0);
      if (n < 1) {
        THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
      }
      return end_index;
    }
  }
  return end_index;
}