Mercurial > hg > openjdk > jdk7u > hotspot
changeset 4907:33f4829de8eb
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
Summary: When constant pool is copied in merge_constant_pools the invokedynamic operands must be copied before.
Reviewed-by: coleenp, twisti
Contributed-by: serguei.spitsyn@oracle.com
author | sspitsyn |
---|---|
date | Tue, 21 Jan 2014 20:44:20 -0800 |
parents | f232cfa3fef2 |
children | 191481960846 |
files | src/share/vm/oops/constantPoolOop.cpp src/share/vm/oops/constantPoolOop.hpp src/share/vm/prims/jvmtiRedefineClasses.cpp src/share/vm/prims/jvmtiRedefineClasses.hpp |
diffstat | 4 files changed, 67 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/oops/constantPoolOop.cpp Tue Jan 21 20:43:55 2014 -0800 +++ b/src/share/vm/oops/constantPoolOop.cpp Tue Jan 21 20:44:20 2014 -0800 @@ -1078,32 +1078,9 @@ } // end compare_entry_to() -// Copy this constant pool's entries at start_i to end_i (inclusive) -// to the constant pool to_cp's entries starting at to_i. A total of -// (end_i - start_i) + 1 entries are copied. -void constantPoolOopDesc::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, - constantPoolHandle to_cp, int to_i, TRAPS) { - - int dest_i = to_i; // leave original alone for debug purposes - - for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) { - copy_entry_to(from_cp, src_i, to_cp, dest_i, CHECK); - - switch (from_cp->tag_at(src_i).value()) { - case JVM_CONSTANT_Double: - case JVM_CONSTANT_Long: - // double and long take two constant pool entries - src_i += 2; - dest_i += 2; - break; - - default: - // all others take one constant pool entry - src_i++; - dest_i++; - break; - } - } +void constantPoolOopDesc::copy_operands(constantPoolHandle from_cp, + constantPoolHandle to_cp, + TRAPS) { int from_oplen = operand_array_length(from_cp->operands()); int old_oplen = operand_array_length(to_cp->operands()); @@ -1152,8 +1129,39 @@ to_cp->set_operands(new_operands()); } } +} // end copy_operands() -} // end copy_cp_to() + +// Copy this constant pool's entries at start_i to end_i (inclusive) +// to the constant pool to_cp's entries starting at to_i. A total of +// (end_i - start_i) + 1 entries are copied. +void constantPoolOopDesc::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, + constantPoolHandle to_cp, int to_i, TRAPS) { + + + int dest_i = to_i; // leave original alone for debug purposes + + for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) { + copy_entry_to(from_cp, src_i, to_cp, dest_i, CHECK); + + switch (from_cp->tag_at(src_i).value()) { + case JVM_CONSTANT_Double: + case JVM_CONSTANT_Long: + // double and long take two constant pool entries + src_i += 2; + dest_i += 2; + break; + + default: + // all others take one constant pool entry + src_i++; + dest_i++; + break; + } + } + copy_operands(from_cp, to_cp, CHECK); + +} // end copy_cp_to_impl() // Copy this constant pool's entry at from_i to the constant pool
--- a/src/share/vm/oops/constantPoolOop.hpp Tue Jan 21 20:43:55 2014 -0800 +++ b/src/share/vm/oops/constantPoolOop.hpp Tue Jan 21 20:44:20 2014 -0800 @@ -755,6 +755,7 @@ copy_cp_to_impl(h_this, start_i, end_i, to_cp, to_i, THREAD); } static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS); + static void copy_operands(constantPoolHandle from_cp, constantPoolHandle to_cp, TRAPS); static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS); int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS); int orig_length() const { return _orig_length; }
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Tue Jan 21 20:43:55 2014 -0800 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Tue Jan 21 20:44:20 2014 -0800 @@ -1113,6 +1113,8 @@ } } // end for each old_cp entry + constantPoolOopDesc::copy_operands(old_cp, *merge_cp_p, CHECK_0); + // We don't need to sanity check that *merge_cp_length_p is within // *merge_cp_p bounds since we have the minimum on-entry check above. (*merge_cp_length_p) = old_i; @@ -1282,8 +1284,12 @@ _index_map_count = 0; _index_map_p = new intArray(scratch_cp->length(), -1); + // reference to the cp holder is needed for copy_operands() + merge_cp->set_pool_holder(scratch_class()); bool result = merge_constant_pools(old_cp, scratch_cp, &merge_cp, &merge_cp_length, THREAD); + merge_cp->set_pool_holder(NULL); + if (!result) { // The merge can fail due to memory allocation failure or due // to robustness checks. @@ -1326,7 +1332,7 @@ // Replace the new constant pool with a shrunken copy of the // merged constant pool; the previous new constant pool will // get GCed. - set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, true, + set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, THREAD); // drop local ref to the merged constant pool merge_cp()->set_is_conc_safe(true); @@ -1357,7 +1363,7 @@ // merged constant pool so now the rewritten bytecodes have // valid references; the previous new constant pool will get // GCed. - set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, true, + set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, THREAD); merge_cp()->set_is_conc_safe(true); } @@ -2343,30 +2349,30 @@ // smaller constant pool is associated with scratch_class. void VM_RedefineClasses::set_new_constant_pool( instanceKlassHandle scratch_class, constantPoolHandle scratch_cp, - int scratch_cp_length, bool shrink, TRAPS) { - assert(!shrink || scratch_cp->length() >= scratch_cp_length, "sanity check"); - - if (shrink) { - // scratch_cp is a merged constant pool and has enough space for a - // worst case merge situation. We want to associate the minimum - // sized constant pool with the klass to save space. - constantPoolHandle smaller_cp(THREAD, - oopFactory::new_constantPool(scratch_cp_length, - oopDesc::IsUnsafeConc, - THREAD)); - // preserve orig_length() value in the smaller copy - int orig_length = scratch_cp->orig_length(); - assert(orig_length != 0, "sanity check"); - smaller_cp->set_orig_length(orig_length); - scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); - scratch_cp = smaller_cp; - smaller_cp()->set_is_conc_safe(true); - } + int scratch_cp_length, TRAPS) { + assert(scratch_cp->length() >= scratch_cp_length, "sanity check"); + + // scratch_cp is a merged constant pool and has enough space for a + // worst case merge situation. We want to associate the minimum + // sized constant pool with the klass to save space. + constantPoolHandle smaller_cp(THREAD, + oopFactory::new_constantPool(scratch_cp_length, + oopDesc::IsUnsafeConc, + THREAD)); + // preserve orig_length() value in the smaller copy + int orig_length = scratch_cp->orig_length(); + assert(orig_length != 0, "sanity check"); + smaller_cp->set_orig_length(orig_length); + + // attach klass to new constant pool + // reference to the cp holder is needed for copy_operands() + smaller_cp->set_pool_holder(scratch_class()); + + scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); + scratch_cp = smaller_cp; + smaller_cp()->set_is_conc_safe(true); // attach new constant pool to klass - scratch_cp->set_pool_holder(scratch_class()); - - // attach klass to new constant pool scratch_class->set_constants(scratch_cp()); int i; // for portability
--- a/src/share/vm/prims/jvmtiRedefineClasses.hpp Tue Jan 21 20:43:55 2014 -0800 +++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp Tue Jan 21 20:44:20 2014 -0800 @@ -474,7 +474,7 @@ address& stackmap_addr_ref, address stackmap_end, u2 frame_i, u1 frame_size, TRAPS); void set_new_constant_pool(instanceKlassHandle scratch_class, - constantPoolHandle scratch_cp, int scratch_cp_length, bool shrink, TRAPS); + constantPoolHandle scratch_cp, int scratch_cp_length, TRAPS); void flush_dependent_code(instanceKlassHandle k_h, TRAPS);