--- a/hotspot/src/share/vm/classfile/javaClasses.inline.hpp Wed Apr 13 17:00:54 2016 -0400
+++ b/hotspot/src/share/vm/classfile/javaClasses.inline.hpp Wed Apr 13 23:31:40 2016 +0000
@@ -222,20 +222,17 @@
return line_number;
}
-/*
- * Returns the source file name of a given InstanceKlass and version
- */
inline Symbol* Backtrace::get_source_file_name(InstanceKlass* holder, int version) {
- // Find the specific ik version that contains this source_file_name_index
- // via the previous versions list, but use the current version's
- // constant pool to look it up. The previous version's index has been
- // merged for the current constant pool.
- InstanceKlass* ik = holder->get_klass_version(version);
- // This version has been cleaned up.
- if (ik == NULL) return NULL;
- int source_file_name_index = ik->source_file_name_index();
- return (source_file_name_index == 0) ?
- (Symbol*)NULL : holder->constants()->symbol_at(source_file_name_index);
+ // RedefineClasses() currently permits redefine operations to
+ // happen in parallel using a "last one wins" philosophy. That
+ // spec laxness allows the constant pool entry associated with
+ // the source_file_name_index for any older constant pool version
+ // to be unstable so we shouldn't try to use it.
+ if (holder->constants()->version() != version) {
+ return NULL;
+ } else {
+ return holder->source_file_name();
+ }
}
#endif // SHARE_VM_CLASSFILE_JAVACLASSES_INLINE_HPP
--- a/hotspot/src/share/vm/oops/constantPool.cpp Wed Apr 13 17:00:54 2016 -0400
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Wed Apr 13 23:31:40 2016 +0000
@@ -395,7 +395,7 @@
int i = which;
if (!uncached && cache() != NULL) {
if (ConstantPool::is_invokedynamic_index(which)) {
- // Invokedynamic index is index into resolved_references
+ // Invokedynamic index is index into the constant pool cache
int pool_index = invokedynamic_cp_cache_entry_at(which)->constant_pool_index();
pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);
assert(tag_at(pool_index).is_name_and_type(), "");
@@ -965,8 +965,8 @@
case JVM_CONSTANT_MethodType:
{
- int k1 = method_type_index_at_error_ok(index1);
- int k2 = cp2->method_type_index_at_error_ok(index2);
+ int k1 = method_type_index_at(index1);
+ int k2 = cp2->method_type_index_at(index2);
bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
if (match) {
return true;
@@ -975,11 +975,11 @@
case JVM_CONSTANT_MethodHandle:
{
- int k1 = method_handle_ref_kind_at_error_ok(index1);
- int k2 = cp2->method_handle_ref_kind_at_error_ok(index2);
+ int k1 = method_handle_ref_kind_at(index1);
+ int k2 = cp2->method_handle_ref_kind_at(index2);
if (k1 == k2) {
- int i1 = method_handle_index_at_error_ok(index1);
- int i2 = cp2->method_handle_index_at_error_ok(index2);
+ int i1 = method_handle_index_at(index1);
+ int i2 = cp2->method_handle_index_at(index2);
bool match = compare_entry_to(i1, cp2, i2, CHECK_false);
if (match) {
return true;
@@ -1311,15 +1311,15 @@
case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError:
{
- jint k = from_cp->method_type_index_at_error_ok(from_i);
+ jint k = from_cp->method_type_index_at(from_i);
to_cp->method_type_index_at_put(to_i, k);
} break;
case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError:
{
- int k1 = from_cp->method_handle_ref_kind_at_error_ok(from_i);
- int k2 = from_cp->method_handle_index_at_error_ok(from_i);
+ int k1 = from_cp->method_handle_ref_kind_at(from_i);
+ int k2 = from_cp->method_handle_index_at(from_i);
to_cp->method_handle_index_at_put(to_i, k1, k2);
} break;
@@ -1755,8 +1755,8 @@
case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError: {
*bytes = JVM_CONSTANT_MethodHandle;
- int kind = method_handle_ref_kind_at_error_ok(idx);
- idx1 = method_handle_index_at_error_ok(idx);
+ int kind = method_handle_ref_kind_at(idx);
+ idx1 = method_handle_index_at(idx);
*(bytes+1) = (unsigned char) kind;
Bytes::put_Java_u2((address) (bytes+2), idx1);
DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1));
@@ -1765,7 +1765,7 @@
case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError: {
*bytes = JVM_CONSTANT_MethodType;
- idx1 = method_type_index_at_error_ok(idx);
+ idx1 = method_type_index_at(idx);
Bytes::put_Java_u2((address) (bytes+1), idx1);
DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
break;
@@ -1953,12 +1953,12 @@
break;
case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodHandleInError :
- 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));
+ st->print("ref_kind=%d", method_handle_ref_kind_at(index));
+ st->print(" ref_index=%d", method_handle_index_at(index));
break;
case JVM_CONSTANT_MethodType :
case JVM_CONSTANT_MethodTypeInError :
- st->print("signature_index=%d", method_type_index_at_error_ok(index));
+ st->print("signature_index=%d", method_type_index_at(index));
break;
case JVM_CONSTANT_InvokeDynamic :
{
--- a/hotspot/src/share/vm/oops/constantPool.hpp Wed Apr 13 17:00:54 2016 -0400
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Wed Apr 13 23:31:40 2016 +0000
@@ -460,41 +460,21 @@
return *int_at_addr(which);
}
- private:
- int method_handle_ref_kind_at(int which, bool error_ok) {
+ int method_handle_ref_kind_at(int which) {
assert(tag_at(which).is_method_handle() ||
- (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
+ 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) {
+ int method_handle_index_at(int which) {
assert(tag_at(which).is_method_handle() ||
- (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
+ 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) {
+ int method_type_index_at(int which) {
assert(tag_at(which).is_method_type() ||
- (error_ok && tag_at(which).is_method_type_in_error()), "Corrupted constant pool");
+ 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) {
- 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) {
- 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) {
- 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) {
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Apr 13 17:00:54 2016 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Apr 13 23:31:40 2016 +0000
@@ -1443,8 +1443,9 @@
return JVMTI_ERROR_INTERNAL;
}
- // Update the version number of the constant pool
+ // Update the version number of the constant pools (may keep scratch_cp)
merge_cp->increment_and_save_version(old_cp->version());
+ scratch_cp->increment_and_save_version(old_cp->version());
ResourceMark rm(THREAD);
_index_map_count = 0;
@@ -3911,6 +3912,11 @@
method->set_constants(scratch_class->constants());
}
+ // NOTE: this doesn't work because you can redefine the same class in two
+ // threads, each getting their own constant pool data appended to the
+ // original constant pool. In order for the new methods to work when they
+ // become old methods, they need to keep their updated copy of the constant pool.
+
{
// walk all previous versions of the klass
InstanceKlass *ik = (InstanceKlass *)the_class();