8153123: Streamline StackWalker code

Reviewed-by: coleenp, dfuchs, mchung, redestad
This commit is contained in:
Brent Christian 2016-04-08 12:26:29 -07:00
parent 87d68625af
commit 2d2abce433
9 changed files with 91 additions and 262 deletions

View File

@ -41,7 +41,6 @@
JVM_DumpAllStacks;
JVM_DumpThreads;
JVM_FillInStackTrace;
JVM_FillStackFrames;
JVM_FindClassFromCaller;
JVM_FindClassFromClass;
JVM_FindClassFromBootLoader;
@ -157,13 +156,13 @@
JVM_SetClassSigners;
JVM_SetNativeThreadName;
JVM_SetPrimitiveArrayElement;
JVM_SetMethodInfo;
JVM_SetThreadPriority;
JVM_Sleep;
JVM_StartThread;
JVM_StopThread;
JVM_SuspendThread;
JVM_SupportsCX8;
JVM_ToStackTraceElement;
JVM_TotalMemory;
JVM_UnloadLibrary;
JVM_Yield;

View File

@ -58,7 +58,6 @@ JVM_DoPrivileged
JVM_DumpAllStacks
JVM_DumpThreads
JVM_FillInStackTrace
JVM_FillStackFrames
JVM_FindClassFromCaller
JVM_FindClassFromClass
JVM_FindLibraryEntry
@ -169,7 +168,6 @@ JVM_ReleaseUTF
JVM_ResumeThread
JVM_SetArrayElement
JVM_SetClassSigners
JVM_SetMethodInfo
JVM_SetNativeThreadName
JVM_SetPrimitiveArrayElement
JVM_SetThreadPriority
@ -178,6 +176,7 @@ JVM_StartThread
JVM_StopThread
JVM_SupportsCX8
JVM_SuspendThread
JVM_ToStackTraceElement
JVM_TotalMemory
JVM_UnloadLibrary
JVM_Yield

View File

@ -2187,43 +2187,19 @@ void java_lang_StackTraceElement::fill_in(Handle element,
}
Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) {
if (MemberNameInStackFrame) {
Handle mname(THREAD, stackFrame->obj_field(_memberName_offset));
Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mname());
// we should expand MemberName::name when Throwable uses StackTrace
// MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL);
return method;
} else {
short mid = stackFrame->short_field(_mid_offset);
short version = stackFrame->short_field(_version_offset);
return holder->method_with_orig_idnum(mid, version);
}
}
Symbol* java_lang_StackFrameInfo::get_file_name(Handle stackFrame, InstanceKlass* holder) {
if (MemberNameInStackFrame) {
return holder->source_file_name();
} else {
short version = stackFrame->short_field(_version_offset);
return Backtrace::get_source_file_name(holder, version);
}
Handle mname(THREAD, stackFrame->obj_field(_memberName_offset));
Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mname());
// we should expand MemberName::name when Throwable uses StackTrace
// MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL);
return method;
}
void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci) {
// set Method* or mid/cpref
if (MemberNameInStackFrame) {
oop mname = stackFrame->obj_field(_memberName_offset);
InstanceKlass* ik = method->method_holder();
CallInfo info(method(), ik);
MethodHandles::init_method_MemberName(mname, info);
} else {
int mid = method->orig_method_idnum();
int cpref = method->name_index();
assert((jushort)mid == mid, "mid should be short");
assert((jushort)cpref == cpref, "cpref should be short");
java_lang_StackFrameInfo::set_mid(stackFrame(), (short)mid);
java_lang_StackFrameInfo::set_cpref(stackFrame(), (short)cpref);
}
oop mname = stackFrame->obj_field(_memberName_offset);
InstanceKlass* ik = method->method_holder();
CallInfo info(method(), ik);
MethodHandles::init_method_MemberName(mname, info);
// set bci
java_lang_StackFrameInfo::set_bci(stackFrame(), bci);
// method may be redefined; store the version
@ -2232,52 +2208,23 @@ void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const metho
java_lang_StackFrameInfo::set_version(stackFrame(), (short)version);
}
void java_lang_StackFrameInfo::fill_methodInfo(Handle stackFrame, TRAPS) {
void java_lang_StackFrameInfo::to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS) {
ResourceMark rm(THREAD);
oop k = stackFrame->obj_field(_declaringClass_offset);
InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k));
Handle k (THREAD, stackFrame->obj_field(_declaringClass_offset));
InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k()));
Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK);
int bci = stackFrame->int_field(_bci_offset);
// The method can be NULL if the requested class version is gone
Symbol* sym = (method != NULL) ? method->name() : NULL;
if (MemberNameInStackFrame) {
assert(sym != NULL, "MemberName must have method name");
} else {
// The method can be NULL if the requested class version is gone
if (sym == NULL) {
short cpref = stackFrame->short_field(_cpref_offset);
sym = holder->constants()->symbol_at(cpref);
}
}
// set method name
oop methodname = StringTable::intern(sym, CHECK);
java_lang_StackFrameInfo::set_methodName(stackFrame(), methodname);
// set file name and line number
Symbol* source = get_file_name(stackFrame, holder);
if (source != NULL) {
oop filename = StringTable::intern(source, CHECK);
java_lang_StackFrameInfo::set_fileName(stackFrame(), filename);
}
// if the method has been redefined, the bci is no longer applicable
short version = stackFrame->short_field(_version_offset);
if (version_matches(method, version)) {
int line_number = Backtrace::get_line_number(method, bci);
java_lang_StackFrameInfo::set_lineNumber(stackFrame(), line_number);
}
short bci = stackFrame->short_field(_bci_offset);
int cpref = method->name_index();
java_lang_StackTraceElement::fill_in(stack_trace_element, holder, method, version, bci, cpref, CHECK);
}
void java_lang_StackFrameInfo::compute_offsets() {
Klass* k = SystemDictionary::StackFrameInfo_klass();
compute_offset(_declaringClass_offset, k, vmSymbols::declaringClass_name(), vmSymbols::class_signature());
compute_offset(_memberName_offset, k, vmSymbols::memberName_name(), vmSymbols::object_signature());
compute_offset(_bci_offset, k, vmSymbols::bci_name(), vmSymbols::int_signature());
compute_offset(_methodName_offset, k, vmSymbols::methodName_name(), vmSymbols::string_signature());
compute_offset(_fileName_offset, k, vmSymbols::fileName_name(), vmSymbols::string_signature());
compute_offset(_lineNumber_offset, k, vmSymbols::lineNumber_name(), vmSymbols::int_signature());
compute_offset(_bci_offset, k, vmSymbols::bci_name(), vmSymbols::short_signature());
STACKFRAMEINFO_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
}
@ -3690,12 +3637,7 @@ int java_lang_StackTraceElement::moduleVersion_offset;
int java_lang_StackFrameInfo::_declaringClass_offset;
int java_lang_StackFrameInfo::_memberName_offset;
int java_lang_StackFrameInfo::_bci_offset;
int java_lang_StackFrameInfo::_methodName_offset;
int java_lang_StackFrameInfo::_fileName_offset;
int java_lang_StackFrameInfo::_lineNumber_offset;
int java_lang_StackFrameInfo::_mid_offset;
int java_lang_StackFrameInfo::_version_offset;
int java_lang_StackFrameInfo::_cpref_offset;
int java_lang_LiveStackFrameInfo::_monitors_offset;
int java_lang_LiveStackFrameInfo::_locals_offset;
int java_lang_LiveStackFrameInfo::_operands_offset;
@ -3741,34 +3683,14 @@ void java_lang_StackFrameInfo::set_declaringClass(oop element, oop value) {
element->obj_field_put(_declaringClass_offset, value);
}
void java_lang_StackFrameInfo::set_mid(oop element, short value) {
element->short_field_put(_mid_offset, value);
}
void java_lang_StackFrameInfo::set_version(oop element, short value) {
element->short_field_put(_version_offset, value);
}
void java_lang_StackFrameInfo::set_cpref(oop element, short value) {
element->short_field_put(_cpref_offset, value);
}
void java_lang_StackFrameInfo::set_bci(oop element, int value) {
element->int_field_put(_bci_offset, value);
}
void java_lang_StackFrameInfo::set_fileName(oop element, oop value) {
element->obj_field_put(_fileName_offset, value);
}
void java_lang_StackFrameInfo::set_methodName(oop element, oop value) {
element->obj_field_put(_methodName_offset, value);
}
void java_lang_StackFrameInfo::set_lineNumber(oop element, int value) {
element->int_field_put(_lineNumber_offset, value);
}
void java_lang_LiveStackFrameInfo::set_monitors(oop element, oop value) {
element->obj_field_put(_monitors_offset, value);
}

View File

@ -1364,25 +1364,16 @@ class Backtrace: AllStatic {
// Interface to java.lang.StackFrameInfo objects
#define STACKFRAMEINFO_INJECTED_FIELDS(macro) \
macro(java_lang_StackFrameInfo, mid, short_signature, false) \
macro(java_lang_StackFrameInfo, version, short_signature, false) \
macro(java_lang_StackFrameInfo, cpref, short_signature, false)
macro(java_lang_StackFrameInfo, version, short_signature, false)
class java_lang_StackFrameInfo: AllStatic {
private:
static int _declaringClass_offset;
static int _memberName_offset;
static int _bci_offset;
static int _methodName_offset;
static int _fileName_offset;
static int _lineNumber_offset;
static int _mid_offset;
static int _version_offset;
static int _cpref_offset;
static Method* get_method(Handle stackFrame, InstanceKlass* holder, TRAPS);
static Symbol* get_file_name(Handle stackFrame, InstanceKlass* holder);
public:
// Setters
@ -1390,19 +1381,12 @@ public:
static void set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci);
static void set_bci(oop info, int value);
// set method info in an instance of StackFrameInfo
static void fill_methodInfo(Handle info, TRAPS);
static void set_methodName(oop info, oop value);
static void set_fileName(oop info, oop value);
static void set_lineNumber(oop info, int value);
// these injected fields are only used if -XX:-MemberNameInStackFrame set
static void set_mid(oop info, short value);
static void set_version(oop info, short value);
static void set_cpref(oop info, short value);
static void compute_offsets();
static void to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS);
// Debugging
friend class JavaClasses;
};

View File

@ -534,7 +534,6 @@ JVM_END
JVM_ENTRY(jobject, JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
jint skip_frames, jint frame_count, jint start_index,
jobjectArray classes,
jobjectArray frames))
JVMWrapper("JVM_CallStackWalk");
JavaThread* jt = (JavaThread*) THREAD;
@ -543,78 +542,51 @@ JVM_ENTRY(jobject, JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mod
}
Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));
objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(classes));
objArrayHandle classes_array_h(THREAD, ca);
// frames array is null when only getting caller reference
objArrayOop fa = objArrayOop(JNIHandles::resolve(frames));
// frames array is a Class<?>[] array when only getting caller reference,
// and a StackFrameInfo[] array (or derivative) otherwise. It should never
// be null.
objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
objArrayHandle frames_array_h(THREAD, fa);
int limit = start_index + frame_count;
if (classes_array_h->length() < limit) {
if (frames_array_h->length() < limit) {
THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "not enough space in buffers", NULL);
}
Handle result = StackWalk::walk(stackStream_h, mode, skip_frames, frame_count,
start_index, classes_array_h,
frames_array_h, CHECK_NULL);
start_index, frames_array_h, CHECK_NULL);
return JNIHandles::make_local(env, result());
JVM_END
JVM_ENTRY(jint, JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
jint frame_count, jint start_index,
jobjectArray classes,
jobjectArray frames))
JVMWrapper("JVM_MoreStackWalk");
JavaThread* jt = (JavaThread*) THREAD;
objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(classes));
objArrayHandle classes_array_h(THREAD, ca);
// frames array is null when only getting caller reference
objArrayOop fa = objArrayOop(JNIHandles::resolve(frames));
// frames array is a Class<?>[] array when only getting caller reference,
// and a StackFrameInfo[] array (or derivative) otherwise. It should never
// be null.
objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
objArrayHandle frames_array_h(THREAD, fa);
int limit = start_index+frame_count;
if (classes_array_h->length() < limit) {
if (frames_array_h->length() < limit) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "not enough space in buffers");
}
Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));
return StackWalk::moreFrames(stackStream_h, mode, anchor, frame_count,
start_index, classes_array_h,
frames_array_h, THREAD);
start_index, frames_array_h, THREAD);
JVM_END
JVM_ENTRY(void, JVM_FillStackFrames(JNIEnv *env, jclass stackStream,
jint start_index,
jobjectArray frames,
jint from_index, jint to_index))
JVMWrapper("JVM_FillStackFrames");
if (TraceStackWalk) {
tty->print("JVM_FillStackFrames() start_index=%d from_index=%d to_index=%d\n",
start_index, from_index, to_index);
}
JavaThread* jt = (JavaThread*) THREAD;
objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
objArrayHandle frames_array_h(THREAD, fa);
if (frames_array_h->length() < to_index) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array length not matched");
}
for (int i = from_index; i < to_index; i++) {
Handle stackFrame(THREAD, frames_array_h->obj_at(i));
java_lang_StackFrameInfo::fill_methodInfo(stackFrame, CHECK);
}
JVM_END
JVM_ENTRY(void, JVM_SetMethodInfo(JNIEnv *env, jobject frame))
JVMWrapper("JVM_SetMethodInfo");
Handle stackFrame(THREAD, JNIHandles::resolve(frame));
java_lang_StackFrameInfo::fill_methodInfo(stackFrame, THREAD);
JVM_ENTRY(void, JVM_ToStackTraceElement(JNIEnv *env, jobject frame, jobject stack))
JVMWrapper("JVM_ToStackTraceElement");
Handle stack_frame_info(THREAD, JNIHandles::resolve_non_null(frame));
Handle stack_trace_element(THREAD, JNIHandles::resolve_non_null(stack));
java_lang_StackFrameInfo::to_stack_trace_element(stack_frame_info, stack_trace_element, THREAD);
JVM_END
// java.lang.Object ///////////////////////////////////////////////

View File

@ -209,7 +209,6 @@ JVM_GetStackTraceElements(JNIEnv *env, jobject throwable, jobjectArray elements)
*/
enum {
JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x2,
JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE = 0x10,
JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20,
JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100
};
@ -217,23 +216,15 @@ enum {
JNIEXPORT jobject JNICALL
JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
jint skip_frames, jint frame_count, jint start_index,
jobjectArray classes,
jobjectArray frames);
JNIEXPORT jint JNICALL
JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
jint frame_count, jint start_index,
jobjectArray classes,
jobjectArray frames);
JNIEXPORT void JNICALL
JVM_FillStackFrames(JNIEnv* env, jclass cls,
jint start_index,
jobjectArray frames,
jint from_index, jint toIndex);
JNIEXPORT void JNICALL
JVM_SetMethodInfo(JNIEnv* env, jobject frame);
JVM_ToStackTraceElement(JNIEnv* env, jobject frame, jobject stackElement);
/*
* java.lang.Thread

View File

@ -37,22 +37,22 @@
#include "utilities/globalDefinitions.hpp"
// setup and cleanup actions
void StackWalkAnchor::setup_magic_on_entry(objArrayHandle classes_array) {
classes_array->obj_at_put(magic_pos, _thread->threadObj());
void StackWalkAnchor::setup_magic_on_entry(objArrayHandle frames_array) {
frames_array->obj_at_put(magic_pos, _thread->threadObj());
_anchor = address_value();
assert(check_magic(classes_array), "invalid magic");
assert(check_magic(frames_array), "invalid magic");
}
bool StackWalkAnchor::check_magic(objArrayHandle classes_array) {
oop m1 = classes_array->obj_at(magic_pos);
bool StackWalkAnchor::check_magic(objArrayHandle frames_array) {
oop m1 = frames_array->obj_at(magic_pos);
jlong m2 = _anchor;
if (m1 == _thread->threadObj() && m2 == address_value()) return true;
return false;
}
bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle classes_array) {
bool ok = check_magic(classes_array);
classes_array->obj_at_put(magic_pos, NULL);
bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle frames_array) {
bool ok = check_magic(frames_array);
frames_array->obj_at_put(magic_pos, NULL);
_anchor = 0L;
return ok;
}
@ -62,18 +62,18 @@ bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle classes_array) {
// Parameters:
// thread Current Java thread.
// magic Magic value used for each stack walking
// classes_array User-supplied buffers. The 0th element is reserved
// frames_array User-supplied buffers. The 0th element is reserved
// to this StackWalkAnchor to use
//
StackWalkAnchor* StackWalkAnchor::from_current(JavaThread* thread, jlong magic,
objArrayHandle classes_array)
objArrayHandle frames_array)
{
assert(thread != NULL && thread->is_Java_thread(), "");
oop m1 = classes_array->obj_at(magic_pos);
oop m1 = frames_array->obj_at(magic_pos);
if (m1 != thread->threadObj()) return NULL;
if (magic == 0L) return NULL;
StackWalkAnchor* anchor = (StackWalkAnchor*) (intptr_t) magic;
if (!anchor->is_valid_in(thread, classes_array)) return NULL;
if (!anchor->is_valid_in(thread, frames_array)) return NULL;
return anchor;
}
@ -88,24 +88,24 @@ StackWalkAnchor* StackWalkAnchor::from_current(JavaThread* thread, jlong magic,
// vfst vFrameStream.
// max_nframes Maximum number of frames to be filled.
// 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.
// 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, vframeStream& vfst,
int max_nframes, int start_index,
objArrayHandle classes_array,
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, classes_array->length());
max_nframes, start_index, frames_array->length());
}
assert(max_nframes > 0, "invalid max_nframes");
assert(start_index + max_nframes <= classes_array->length(), "oob");
assert(start_index + max_nframes <= frames_array->length(), "oob");
int frames_decoded = 0;
for (; !vfst.at_end(); vfst.next()) {
@ -129,14 +129,18 @@ int StackWalk::fill_in_frames(jlong mode, vframeStream& vfst,
tty->print_cr(" bci=%d", bci);
}
classes_array->obj_at_put(index, method->method_holder()->java_mirror());
// 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, vfst.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;
}
@ -279,15 +283,15 @@ void StackWalk::fill_live_stackframe(Handle stackFrame, const methodHandle& meth
// skip_frames Number of frames to be skipped.
// frame_count Number of frames to be traversed.
// 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.
// frames array is a Class<?>[] array when only getting caller
// reference, and a StackFrameInfo[] array (or derivative)
// otherwise. It should never be null.
//
// Returns Object returned from AbstractStackWalker::doStackWalk call.
//
oop StackWalk::walk(Handle stackStream, jlong mode,
int skip_frames, int frame_count, int start_index,
objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS) {
JavaThread* jt = (JavaThread*)THREAD;
@ -296,10 +300,8 @@ oop StackWalk::walk(Handle stackStream, jlong mode,
mode, skip_frames, frame_count);
}
if (need_method_info(mode)) {
if (frames_array.is_null()) {
THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
}
if (frames_array.is_null()) {
THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
}
Klass* stackWalker_klass = SystemDictionary::StackWalker_klass();
@ -313,48 +315,17 @@ oop StackWalk::walk(Handle stackStream, jlong mode,
vframeStream& vfst = anchor.vframe_stream();
{
// Skip all methods from AbstractStackWalker and StackWalk (enclosing method)
if (!fill_in_stacktrace(mode)) {
while (!vfst.at_end()) {
InstanceKlass* ik = vfst.method()->method_holder();
if (ik != stackWalker_klass &&
ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass) {
break;
}
if (TraceStackWalk) {
tty->print(" skip "); vfst.method()->print_short_name(); tty->print("\n");
}
vfst.next();
while (!vfst.at_end()) {
InstanceKlass* ik = vfst.method()->method_holder();
if (ik != stackWalker_klass &&
ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass) {
break;
}
}
// For exceptions, skip Throwable::fillInStackTrace and <init> methods
// of the exception class and superclasses
if (fill_in_stacktrace(mode)) {
bool skip_to_fillInStackTrace = false;
bool skip_throwableInit_check = false;
while (!vfst.at_end() && !skip_throwableInit_check) {
InstanceKlass* ik = vfst.method()->method_holder();
Method* method = vfst.method();
if (!skip_to_fillInStackTrace) {
if (ik == SystemDictionary::Throwable_klass() &&
method->name() == vmSymbols::fillInStackTrace_name()) {
// this frame will be skipped
skip_to_fillInStackTrace = true;
}
} else if (!(ik->is_subclass_of(SystemDictionary::Throwable_klass()) &&
method->name() == vmSymbols::object_initializer_name())) {
// there are none or we've seen them all - either way stop checking
skip_throwableInit_check = true;
break;
}
if (TraceStackWalk) {
tty->print("stack walk: skip "); vfst.method()->print_short_name(); tty->print("\n");
}
vfst.next();
if (TraceStackWalk) {
tty->print(" skip "); vfst.method()->print_short_name(); tty->print("\n");
}
vfst.next();
}
// stack frame has been traversed individually and resume stack walk
@ -372,7 +343,7 @@ oop StackWalk::walk(Handle stackStream, jlong mode,
int end_index = start_index;
int numFrames = 0;
if (!vfst.at_end()) {
numFrames = fill_in_frames(mode, vfst, frame_count, start_index, classes_array,
numFrames = fill_in_frames(mode, vfst, frame_count, start_index,
frames_array, end_index, CHECK_NULL);
if (numFrames < 1) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "stack walk: decode failed", NULL);
@ -392,12 +363,12 @@ oop StackWalk::walk(Handle stackStream, jlong mode,
args.push_int(end_index);
// Link the thread and vframe stream into the callee-visible object
anchor.setup_magic_on_entry(classes_array);
anchor.setup_magic_on_entry(frames_array);
JavaCalls::call(&result, m_doStackWalk, &args, THREAD);
// Do this before anything else happens, to disable any lingering stream objects
bool ok = anchor.cleanup_magic_on_exit(classes_array);
bool ok = anchor.cleanup_magic_on_exit(frames_array);
// Throw pending exception if we must
(void) (CHECK_NULL);
@ -419,31 +390,28 @@ oop StackWalk::walk(Handle stackStream, jlong 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);
StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, frames_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()) {
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_anchor " PTR_FORMAT " start %d frames %d",
frame_count, p2i(existing_anchor), start_index, classes_array->length());
frame_count, p2i(existing_anchor), start_index, frames_array->length());
}
int end_index = start_index;
if (frame_count <= 0) {
@ -451,14 +419,14 @@ jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic,
}
int count = frame_count + start_index;
assert (classes_array->length() >= count, "not enough space in buffers");
assert (frames_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,
int n = fill_in_frames(mode, vfst, frame_count, start_index,
frames_array, end_index, CHECK_0);
if (n < 1) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);

View File

@ -45,12 +45,12 @@ public:
vframeStream& vframe_stream() { return _vfst; }
JavaThread* thread() { return _thread; }
void setup_magic_on_entry(objArrayHandle classes_array);
bool check_magic(objArrayHandle classes_array);
bool cleanup_magic_on_exit(objArrayHandle classes_array);
void setup_magic_on_entry(objArrayHandle frames_array);
bool check_magic(objArrayHandle frames_array);
bool cleanup_magic_on_exit(objArrayHandle frames_array);
bool is_valid_in(Thread* thread, objArrayHandle classes_array) {
return (_thread == thread && check_magic(classes_array));
bool is_valid_in(Thread* thread, objArrayHandle frames_array) {
return (_thread == thread && check_magic(frames_array));
}
jlong address_value() {
@ -64,7 +64,6 @@ class StackWalk : public AllStatic {
private:
static int fill_in_frames(jlong mode, vframeStream& vfst,
int max_nframes, int start_index,
objArrayHandle classes_array,
objArrayHandle frames_array,
int& end_index, TRAPS);
@ -82,20 +81,18 @@ private:
static inline bool live_frame_info(int mode) {
return (mode & JVM_STACKWALK_FILL_LIVE_STACK_FRAMES) != 0;
}
static inline bool fill_in_stacktrace(int mode) {
return (mode & JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE) != 0;
}
public:
static inline bool use_frames_array(int mode) {
return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
}
static oop walk(Handle stackStream, jlong mode,
int skip_frames, int frame_count, int start_index,
objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS);
static jint moreFrames(Handle stackStream, jlong mode, jlong magic,
int frame_count, int start_index,
objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS);
};

View File

@ -2958,9 +2958,6 @@ public:
develop(bool, TraceStackWalk, false, \
"Trace stack walking") \
\
product(bool, MemberNameInStackFrame, true, \
"Use MemberName in StackFrame") \
\
/* notice: the max range value here is max_jint, not max_intx */ \
/* because of overflow issue */ \
NOT_EMBEDDED(diagnostic(intx, GuaranteedSafepointInterval, 1000, \