< prev index next >

src/hotspot/share/prims/jvmtiRedefineClasses.cpp

Print this page
@@ -26,13 +26,14 @@
  #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"

@@ -609,12 +610,11 @@
      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

@@ -1934,10 +1934,16 @@
    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;
    }

@@ -2082,10 +2088,23 @@
      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();
  

@@ -3269,10 +3288,18 @@
  
      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

@@ -3286,11 +3313,11 @@
        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 */

@@ -3474,10 +3501,33 @@
      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 >