This commit is contained in:
Coleen Phillimore 2016-04-13 23:31:40 +00:00
commit 50a5ba9849
4 changed files with 40 additions and 57 deletions

View file

@ -222,20 +222,17 @@ inline int Backtrace::get_line_number(const methodHandle& method, int bci) {
return line_number; 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) { inline Symbol* Backtrace::get_source_file_name(InstanceKlass* holder, int version) {
// Find the specific ik version that contains this source_file_name_index // RedefineClasses() currently permits redefine operations to
// via the previous versions list, but use the current version's // happen in parallel using a "last one wins" philosophy. That
// constant pool to look it up. The previous version's index has been // spec laxness allows the constant pool entry associated with
// merged for the current constant pool. // the source_file_name_index for any older constant pool version
InstanceKlass* ik = holder->get_klass_version(version); // to be unstable so we shouldn't try to use it.
// This version has been cleaned up. if (holder->constants()->version() != version) {
if (ik == NULL) return NULL; return NULL;
int source_file_name_index = ik->source_file_name_index(); } else {
return (source_file_name_index == 0) ? return holder->source_file_name();
(Symbol*)NULL : holder->constants()->symbol_at(source_file_name_index); }
} }
#endif // SHARE_VM_CLASSFILE_JAVACLASSES_INLINE_HPP #endif // SHARE_VM_CLASSFILE_JAVACLASSES_INLINE_HPP

View file

@ -395,7 +395,7 @@ int ConstantPool::impl_name_and_type_ref_index_at(int which, bool uncached) {
int i = which; int i = which;
if (!uncached && cache() != NULL) { if (!uncached && cache() != NULL) {
if (ConstantPool::is_invokedynamic_index(which)) { 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(); int pool_index = invokedynamic_cp_cache_entry_at(which)->constant_pool_index();
pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index); pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);
assert(tag_at(pool_index).is_name_and_type(), ""); assert(tag_at(pool_index).is_name_and_type(), "");
@ -965,8 +965,8 @@ bool ConstantPool::compare_entry_to(int index1, const constantPoolHandle& cp2,
case JVM_CONSTANT_MethodType: case JVM_CONSTANT_MethodType:
{ {
int k1 = method_type_index_at_error_ok(index1); int k1 = method_type_index_at(index1);
int k2 = cp2->method_type_index_at_error_ok(index2); int k2 = cp2->method_type_index_at(index2);
bool match = compare_entry_to(k1, cp2, k2, CHECK_false); bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
if (match) { if (match) {
return true; return true;
@ -975,11 +975,11 @@ bool ConstantPool::compare_entry_to(int index1, const constantPoolHandle& cp2,
case JVM_CONSTANT_MethodHandle: case JVM_CONSTANT_MethodHandle:
{ {
int k1 = method_handle_ref_kind_at_error_ok(index1); int k1 = method_handle_ref_kind_at(index1);
int k2 = cp2->method_handle_ref_kind_at_error_ok(index2); int k2 = cp2->method_handle_ref_kind_at(index2);
if (k1 == k2) { if (k1 == k2) {
int i1 = method_handle_index_at_error_ok(index1); int i1 = method_handle_index_at(index1);
int i2 = cp2->method_handle_index_at_error_ok(index2); int i2 = cp2->method_handle_index_at(index2);
bool match = compare_entry_to(i1, cp2, i2, CHECK_false); bool match = compare_entry_to(i1, cp2, i2, CHECK_false);
if (match) { if (match) {
return true; return true;
@ -1311,15 +1311,15 @@ void ConstantPool::copy_entry_to(const constantPoolHandle& from_cp, int from_i,
case JVM_CONSTANT_MethodType: case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError: 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); to_cp->method_type_index_at_put(to_i, k);
} break; } break;
case JVM_CONSTANT_MethodHandle: case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError: case JVM_CONSTANT_MethodHandleInError:
{ {
int k1 = from_cp->method_handle_ref_kind_at_error_ok(from_i); int k1 = from_cp->method_handle_ref_kind_at(from_i);
int k2 = from_cp->method_handle_index_at_error_ok(from_i); int k2 = from_cp->method_handle_index_at(from_i);
to_cp->method_handle_index_at_put(to_i, k1, k2); to_cp->method_handle_index_at_put(to_i, k1, k2);
} break; } break;
@ -1755,8 +1755,8 @@ int ConstantPool::copy_cpool_bytes(int cpool_size,
case JVM_CONSTANT_MethodHandle: case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError: { case JVM_CONSTANT_MethodHandleInError: {
*bytes = JVM_CONSTANT_MethodHandle; *bytes = JVM_CONSTANT_MethodHandle;
int kind = method_handle_ref_kind_at_error_ok(idx); int kind = method_handle_ref_kind_at(idx);
idx1 = method_handle_index_at_error_ok(idx); idx1 = method_handle_index_at(idx);
*(bytes+1) = (unsigned char) kind; *(bytes+1) = (unsigned char) kind;
Bytes::put_Java_u2((address) (bytes+2), idx1); Bytes::put_Java_u2((address) (bytes+2), idx1);
DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1)); DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1));
@ -1765,7 +1765,7 @@ int ConstantPool::copy_cpool_bytes(int cpool_size,
case JVM_CONSTANT_MethodType: case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError: { case JVM_CONSTANT_MethodTypeInError: {
*bytes = JVM_CONSTANT_MethodType; *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); Bytes::put_Java_u2((address) (bytes+1), idx1);
DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1)); DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
break; break;
@ -1953,12 +1953,12 @@ void ConstantPool::print_entry_on(const int index, outputStream* st) {
break; break;
case JVM_CONSTANT_MethodHandle : case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodHandleInError : case JVM_CONSTANT_MethodHandleInError :
st->print("ref_kind=%d", method_handle_ref_kind_at_error_ok(index)); st->print("ref_kind=%d", method_handle_ref_kind_at(index));
st->print(" ref_index=%d", method_handle_index_at_error_ok(index)); st->print(" ref_index=%d", method_handle_index_at(index));
break; break;
case JVM_CONSTANT_MethodType : case JVM_CONSTANT_MethodType :
case JVM_CONSTANT_MethodTypeInError : 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; break;
case JVM_CONSTANT_InvokeDynamic : case JVM_CONSTANT_InvokeDynamic :
{ {

View file

@ -460,40 +460,20 @@ class ConstantPool : public Metadata {
return *int_at_addr(which); return *int_at_addr(which);
} }
private: int method_handle_ref_kind_at(int which) {
int method_handle_ref_kind_at(int which, bool error_ok) {
assert(tag_at(which).is_method_handle() || 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 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() || 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 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) {
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) { int method_type_index_at(int which) {
return method_type_index_at(which, false); assert(tag_at(which).is_method_type() ||
} tag_at(which).is_method_type_in_error(), "Corrupted constant pool");
int method_type_index_at_error_ok(int which) { return *int_at_addr(which);
return method_type_index_at(which, true);
} }
// Derived queries: // Derived queries:

View file

@ -1443,8 +1443,9 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
return JVMTI_ERROR_INTERNAL; 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()); merge_cp->increment_and_save_version(old_cp->version());
scratch_cp->increment_and_save_version(old_cp->version());
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
_index_map_count = 0; _index_map_count = 0;
@ -3911,6 +3912,11 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
method->set_constants(scratch_class->constants()); 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 // walk all previous versions of the klass
InstanceKlass *ik = (InstanceKlass *)the_class(); InstanceKlass *ik = (InstanceKlass *)the_class();