8025088: Missing cases for JVM_CONSTANT_MethodHandleInError cause crash if debugger steps into error-tagged method handle
Summary: Need to refetch each method from InstanceKlass after all safepoints. Removed leaky PreviousVersionInfo code.
Reviewed-by: coleenp, sspitsyn
--- a/hotspot/src/share/vm/oops/constantPool.cpp Sun Sep 22 18:07:43 2013 +0200
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Mon Sep 23 08:56:19 2013 -0700
@@ -1611,9 +1611,11 @@
case JVM_CONSTANT_UnresolvedClassInError:
case JVM_CONSTANT_StringIndex:
case JVM_CONSTANT_MethodType:
+ case JVM_CONSTANT_MethodTypeInError:
return 3;
case JVM_CONSTANT_MethodHandle:
+ case JVM_CONSTANT_MethodHandleInError:
return 4; //tag, ref_kind, ref_index
case JVM_CONSTANT_Integer:
@@ -1794,8 +1796,8 @@
case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError: {
*bytes = JVM_CONSTANT_MethodHandle;
- int kind = method_handle_ref_kind_at(idx);
- idx1 = method_handle_index_at(idx);
+ int kind = method_handle_ref_kind_at_error_ok(idx);
+ idx1 = method_handle_index_at_error_ok(idx);
*(bytes+1) = (unsigned char) kind;
Bytes::put_Java_u2((address) (bytes+2), idx1);
DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1));
@@ -1804,7 +1806,7 @@
case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError: {
*bytes = JVM_CONSTANT_MethodType;
- idx1 = method_type_index_at(idx);
+ idx1 = method_type_index_at_error_ok(idx);
Bytes::put_Java_u2((address) (bytes+1), idx1);
DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
break;
@@ -1992,12 +1994,12 @@
break;
case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodHandleInError :
- st->print("ref_kind=%d", method_handle_ref_kind_at(index));
- st->print(" ref_index=%d", method_handle_index_at(index));
+ st->print("ref_kind=%d", method_handle_ref_kind_at_error_ok(index));
+ st->print(" ref_index=%d", method_handle_index_at_error_ok(index));
break;
case JVM_CONSTANT_MethodType :
case JVM_CONSTANT_MethodTypeInError :
- st->print("signature_index=%d", method_type_index_at(index));
+ st->print("signature_index=%d", method_type_index_at_error_ok(index));
break;
case JVM_CONSTANT_InvokeDynamic :
{
--- a/hotspot/src/share/vm/oops/constantPool.hpp Sun Sep 22 18:07:43 2013 +0200
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Mon Sep 23 08:56:19 2013 -0700
@@ -474,18 +474,42 @@
return *int_at_addr(which);
}
+ private:
+ int method_handle_ref_kind_at(int which, bool error_ok) {
+ assert(tag_at(which).is_method_handle() ||
+ (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
+ return extract_low_short_from_int(*int_at_addr(which)); // mask out unwanted ref_index bits
+ }
+ int method_handle_index_at(int which, bool error_ok) {
+ assert(tag_at(which).is_method_handle() ||
+ (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
+ return extract_high_short_from_int(*int_at_addr(which)); // shift out unwanted ref_kind bits
+ }
+ int method_type_index_at(int which, bool error_ok) {
+ assert(tag_at(which).is_method_type() ||
+ (error_ok && tag_at(which).is_method_type_in_error()), "Corrupted constant pool");
+ return *int_at_addr(which);
+ }
+ public:
int method_handle_ref_kind_at(int which) {
- assert(tag_at(which).is_method_handle(), "Corrupted constant pool");
- return extract_low_short_from_int(*int_at_addr(which)); // mask out unwanted ref_index bits
+ return method_handle_ref_kind_at(which, false);
+ }
+ int method_handle_ref_kind_at_error_ok(int which) {
+ return method_handle_ref_kind_at(which, true);
}
int method_handle_index_at(int which) {
- assert(tag_at(which).is_method_handle(), "Corrupted constant pool");
- return extract_high_short_from_int(*int_at_addr(which)); // shift out unwanted ref_kind bits
+ return method_handle_index_at(which, false);
+ }
+ int method_handle_index_at_error_ok(int which) {
+ return method_handle_index_at(which, true);
}
int method_type_index_at(int which) {
- assert(tag_at(which).is_method_type(), "Corrupted constant pool");
- return *int_at_addr(which);
+ return method_type_index_at(which, false);
}
+ int method_type_index_at_error_ok(int which) {
+ return method_type_index_at(which, true);
+ }
+
// Derived queries:
Symbol* method_handle_name_ref_at(int which) {
int member = method_handle_index_at(which);