< prev index next > src/hotspot/share/prims/jvmtiRedefineClasses.cpp
Print this page
#include "cds/metaspaceShared.hpp"
#include "classfile/classFileStream.hpp"
#include "classfile/classLoaderDataGraph.hpp"
#include "classfile/classLoadInfo.hpp"
#include "classfile/javaClasses.inline.hpp"
+ #include "classfile/klassFactory.hpp"
#include "classfile/metadataOnStackMark.hpp"
+ #include "classfile/stackMapTable.hpp"
#include "classfile/symbolTable.hpp"
- #include "classfile/klassFactory.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "compiler/compileBroker.hpp"
case JVM_CONSTANT_Invalid: // fall through
// At this stage, String could be here, but not StringIndex
case JVM_CONSTANT_StringIndex: // fall through
- // At this stage JVM_CONSTANT_UnresolvedClassInError should not be
- // here
+ // At this stage JVM_CONSTANT_UnresolvedClassInError should not be here
case JVM_CONSTANT_UnresolvedClassInError: // fall through
default:
{
// leave a breadcrumb
if (!rewrite_cp_refs_in_permitted_subclasses_attribute(scratch_class)) {
// propagate failure back to caller
return false;
}
+ // rewrite constant pool references in the LoadableDescriptors attribute:
+ if (!rewrite_cp_refs_in_loadable_descriptors_attribute(scratch_class)) {
+ // propagate failure back to caller
+ return false;
+ }
+
// rewrite constant pool references in the methods:
if (!rewrite_cp_refs_in_methods(scratch_class)) {
// propagate failure back to caller
return false;
}
permitted_subclasses->at_put(i, find_new_index(cp_index));
}
return true;
}
+ // Rewrite constant pool references in the LoadableDescriptors attribute.
+ bool VM_RedefineClasses::rewrite_cp_refs_in_loadable_descriptors_attribute(
+ InstanceKlass* scratch_class) {
+
+ Array<u2>* loadable_descriptors = scratch_class->loadable_descriptors();
+ assert(loadable_descriptors != nullptr, "unexpected null loadable_descriptors");
+ for (int i = 0; i < loadable_descriptors->length(); i++) {
+ u2 cp_index = loadable_descriptors->at(i);
+ loadable_descriptors->at_put(i, find_new_index(cp_index));
+ }
+ return true;
+ }
+
// Rewrite constant pool references in the methods.
bool VM_RedefineClasses::rewrite_cp_refs_in_methods(InstanceKlass* scratch_class) {
Array<Method*>* methods = scratch_class->methods();
assert(stackmap_p + 1 <= stackmap_end, "no room for frame_type");
u1 frame_type = *stackmap_p;
stackmap_p++;
+ if (frame_type == 246) { // EARLY_LARVAL
+ // rewrite_cp_refs in unset fields and fall through.
+ rewrite_cp_refs_in_early_larval_stackmaps(stackmap_p, stackmap_end, calc_number_of_entries, frame_type);
+ // The larval frames point to the next frame, so advance to the next frame and fall through.
+ frame_type = *stackmap_p;
+ stackmap_p++;
+ }
+
// same_frame {
// u1 frame_type = SAME; /* 0-63 */
// }
if (frame_type <= 63) {
// nothing more to do for same_frame
rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end,
calc_number_of_entries, frame_type);
}
// reserved for future use
- else if (frame_type >= 128 && frame_type <= 246) {
+ else if (frame_type >= 128 && frame_type <= 245) {
// nothing more to do for reserved frame_types
}
// same_locals_1_stack_item_frame_extended {
// u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED; /* 247 */
break;
} // end switch (tag)
} // end rewrite_cp_refs_in_verification_type_info()
+ void VM_RedefineClasses::rewrite_cp_refs_in_early_larval_stackmaps(
+ address& stackmap_p_ref, address stackmap_end, u2 frame_i,
+ u1 frame_type) {
+
+ u2 num_early_larval_stackmaps = Bytes::get_Java_u2(stackmap_p_ref);
+ stackmap_p_ref += 2;
+
+ for (u2 i = 0; i < num_early_larval_stackmaps; i++) {
+
+ u2 name_and_ref_index = Bytes::get_Java_u2(stackmap_p_ref);
+ u2 new_cp_index = find_new_index(name_and_ref_index);
+ if (new_cp_index != 0) {
+ log_debug(redefine, class, stackmap)("mapped old name_and_ref_index=%d", name_and_ref_index);
+ Bytes::put_Java_u2(stackmap_p_ref, new_cp_index);
+ name_and_ref_index = new_cp_index;
+ }
+ log_debug(redefine, class, stackmap)
+ ("frame_i=%u, frame_type=%u, name_and_ref_index=%d", frame_i, frame_type, name_and_ref_index);
+
+ stackmap_p_ref += 2;
+ }
+ } // rewrite_cp_refs_in_early_larval_stackmaps
+
// Change the constant pool associated with klass scratch_class to scratch_cp.
// scratch_cp_length elements are copied from scratch_cp to a smaller constant pool
// and the smaller constant pool is associated with scratch_class.
void VM_RedefineClasses::set_new_constant_pool(
ClassLoaderData* loader_data,
< prev index next >