--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Oct 02 09:18:56 2013 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Sat Oct 05 00:58:43 2013 +0200
@@ -1376,8 +1376,15 @@
const char* klass_name = holder->external_name();
int buf_len = (int)strlen(klass_name);
- // pushing to the stack trace added one.
+ // The method id may point to an obsolete method, can't get more stack information
Method* method = holder->method_with_idnum(method_id);
+ if (method == NULL) {
+ char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64);
+ // This is what the java code prints in this case - added Redefined
+ sprintf(buf, "\tat %s.null (Redefined)", klass_name);
+ return buf;
+ }
+
char* method_name = method->name()->as_C_string();
buf_len += (int)strlen(method_name);
@@ -1773,7 +1780,8 @@
return element;
}
-oop java_lang_StackTraceElement::create(Handle mirror, int method_id, int version, int bci, TRAPS) {
+oop java_lang_StackTraceElement::create(Handle mirror, int method_id,
+ int version, int bci, TRAPS) {
// Allocate java.lang.StackTraceElement instance
Klass* k = SystemDictionary::StackTraceElement_klass();
assert(k != NULL, "must be loaded in 1.4+");
@@ -1790,8 +1798,16 @@
oop classname = StringTable::intern((char*) str, CHECK_0);
java_lang_StackTraceElement::set_declaringClass(element(), classname);
+ Method* method = holder->method_with_idnum(method_id);
+ // Method on stack may be obsolete because it was redefined so cannot be
+ // found by idnum.
+ if (method == NULL) {
+ // leave name and fileName null
+ java_lang_StackTraceElement::set_lineNumber(element(), -1);
+ return element();
+ }
+
// Fill in method name
- Method* method = holder->method_with_idnum(method_id);
oop methodname = StringTable::intern(method->name(), CHECK_0);
java_lang_StackTraceElement::set_methodName(element(), methodname);
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Oct 02 09:18:56 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Sat Oct 05 00:58:43 2013 +0200
@@ -2931,7 +2931,8 @@
old_method->set_is_obsolete();
obsolete_count++;
- // obsolete methods need a unique idnum
+ // obsolete methods need a unique idnum so they become new entries in
+ // the jmethodID cache in InstanceKlass
u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum();
if (num != ConstMethod::UNSET_IDNUM) {
old_method->set_method_idnum(num);