changeset 31038:2fd2fdc6a70a

8059340: ConstantPool::_resolved_references is missing in heap dump Reviewed-by: sspitsyn, stefank, twisti
author vlivanov
date Thu, 21 May 2015 18:22:33 +0300
parents 01a5c5fa5681
children 16aee060cf6b
files hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp hotspot/src/cpu/x86/vm/interp_masm_x86.cpp hotspot/src/cpu/x86/vm/interp_masm_x86.hpp hotspot/src/share/vm/ci/ciStreams.cpp hotspot/src/share/vm/classfile/classLoaderData.cpp hotspot/src/share/vm/classfile/classLoaderData.hpp hotspot/src/share/vm/classfile/javaClasses.cpp hotspot/src/share/vm/classfile/javaClasses.hpp hotspot/src/share/vm/oops/constantPool.cpp hotspot/src/share/vm/oops/constantPool.hpp hotspot/src/share/vm/oops/instanceKlass.cpp hotspot/src/share/vm/oops/instanceKlass.hpp hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp hotspot/src/share/vm/runtime/vmStructs.cpp
diffstat 17 files changed, 101 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Thu May 21 18:22:33 2015 +0300
@@ -229,16 +229,21 @@
   Register tmp = index;  // reuse
   lslw(tmp, tmp, LogBytesPerHeapOop);
 
-  get_constant_pool(result);
   // load pointer for resolved_references[] objArray
-  ldr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
-  // JNIHandles::resolve(obj);
-  ldr(result, Address(result, 0));
+  get_resolved_references(result);
   // Add in the index
   add(result, result, tmp);
   load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
 }
 
+void InterpreterMacroAssembler::get_resolved_references(Register reg) {
+  get_constant_pool(reg);
+  ldr(reg, Address(reg, ConstantPool::pool_holder_offset_in_bytes()));
+  ldr(reg, Address(reg, Klass::java_mirror_offset()));
+  assert(java_lang_Class::resolved_references_offset_in_bytes() > 0, "");
+  load_heap_oop(reg, Address(reg, java_lang_Class::resolved_references_offset_in_bytes()));
+}
+
 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a
 // subtype of super_klass.
 //
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp	Thu May 21 18:22:33 2015 +0300
@@ -121,6 +121,8 @@
     ldr(tags, Address(cpool, ConstantPool::tags_offset_in_bytes()));
   }
 
+  void get_resolved_references(Register reg);
+
   void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset);
   void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, size_t index_size = sizeof(u2));
   void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu May 21 18:22:33 2015 +0300
@@ -798,11 +798,8 @@
   // word index to byte offset. Since this is a java object, it can be compressed
   Register tmp = index;  // reuse
   sll(index, LogBytesPerHeapOop, tmp);
-  get_constant_pool(result);
   // load pointer for resolved_references[] objArray
-  ld_ptr(result, ConstantPool::resolved_references_offset_in_bytes(), result);
-  // JNIHandles::resolve(result)
-  ld_ptr(result, 0, result);
+  get_resolved_references(result);
   // Add in the index
   add(result, tmp, result);
   load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result);
@@ -973,6 +970,13 @@
   ld_ptr(Rcpool, ConstantPool::tags_offset_in_bytes(), Rtags);
 }
 
+void InterpreterMacroAssembler::get_resolved_references(Register Rdst) {
+  get_constant_pool(Rdst);
+  ld_ptr(Rdst, ConstantPool::pool_holder_offset_in_bytes(), Rdst);
+  ld_ptr(Rdst, Klass::java_mirror_offset(), Rdst);
+  assert(java_lang_Class::resolved_references_offset_in_bytes() > 0, "");
+  load_heap_oop(Rdst, java_lang_Class::resolved_references_offset_in_bytes(), Rdst);
+}
 
 // unlock if synchronized method
 //
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Thu May 21 18:22:33 2015 +0300
@@ -212,6 +212,7 @@
   void get_constant_pool(Register Rdst);
   void get_constant_pool_cache(Register Rdst);
   void get_cpool_and_tags(Register Rcpool, Register Rtags);
+  void get_resolved_references(Register Rdst);
   void is_a(Label& L);
 
   // Load compiled (i2c) or interpreter entry and call from interpreted
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Thu May 21 18:22:33 2015 +0300
@@ -482,6 +482,14 @@
   andl(bytecode, ConstantPoolCacheEntry::bytecode_1_mask);
 }
 
+void InterpreterMacroAssembler::get_resolved_references(Register reg) {
+  get_constant_pool(reg);
+  movptr(reg, Address(reg, ConstantPool::pool_holder_offset_in_bytes()));
+  movptr(reg, Address(reg, Klass::java_mirror_offset()));
+  assert(java_lang_Class::resolved_references_offset_in_bytes() > 0, "");
+  load_heap_oop(reg, Address(reg, java_lang_Class::resolved_references_offset_in_bytes()));
+}
+
 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
                                                                Register tmp,
                                                                int bcp_offset,
@@ -499,20 +507,16 @@
   addptr(cache, tmp);  // construct pointer to cache entry
 }
 
-// Load object from cpool->resolved_references(index)
-void InterpreterMacroAssembler::load_resolved_reference_at_index(
-                                           Register result, Register index) {
+// Load object from cpool->pool_holder->mirror->resolved_references(index)
+void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result, Register index) {
   assert_different_registers(result, index);
   // convert from field index to resolved_references() index and from
   // word index to byte offset. Since this is a java object, it can be compressed
   Register tmp = index;  // reuse
   shll(tmp, LogBytesPerHeapOop);
 
-  get_constant_pool(result);
   // load pointer for resolved_references[] objArray
-  movptr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
-  // JNIHandles::resolve(obj);
-  movptr(result, Address(result, 0));
+  get_resolved_references(result);
   // Add in the index
   addptr(result, tmp);
   load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.hpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.hpp	Thu May 21 18:22:33 2015 +0300
@@ -109,6 +109,8 @@
     movptr(tags, Address(cpool, ConstantPool::tags_offset_in_bytes()));
   }
 
+  void get_resolved_references(Register reg);
+
   void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset);
   void get_cache_and_index_at_bcp(Register cache,
                                   Register index,
--- a/hotspot/src/share/vm/ci/ciStreams.cpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/ci/ciStreams.cpp	Thu May 21 18:22:33 2015 +0300
@@ -477,10 +477,8 @@
 // ------------------------------------------------------------------
 // ciBytecodeStream::get_resolved_references
 ciObjArray* ciBytecodeStream::get_resolved_references() {
-    VM_ENTRY_MARK;
-    // Get the constant pool.
-  ConstantPool*        cpool   = _holder->get_instanceKlass()->constants();
-
+  VM_ENTRY_MARK;
+  objArrayOop resolved_references = _holder->get_instanceKlass()->resolved_references();
   // Create a resolved references array and return it.
-  return CURRENT_ENV->get_object(cpool->resolved_references())->as_obj_array();
-  }
+  return CURRENT_ENV->get_object(resolved_references)->as_obj_array();
+}
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu May 21 18:22:33 2015 +0300
@@ -60,7 +60,6 @@
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
-#include "runtime/jniHandles.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/synchronizer.hpp"
@@ -81,7 +80,7 @@
   // The null-class-loader should always be kept alive.
   _keep_alive(is_anonymous || h_class_loader.is_null()),
   _metaspace(NULL), _unloading(false), _klasses(NULL),
-  _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
+  _claimed(0), _jmethod_ids(NULL), _deallocate_list(NULL),
   _next(NULL), _dependencies(dependencies),
   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
                             Monitor::_safepoint_check_never)) {
@@ -115,7 +114,6 @@
 
   f->do_oop(&_class_loader);
   _dependencies.oops_do(f);
-  _handles->oops_do(f);
   if (klass_closure != NULL) {
     classes_do(klass_closure);
   }
@@ -356,11 +354,6 @@
     _metaspace = NULL;
     // release the metaspace
     delete m;
-    // release the handles
-    if (_handles != NULL) {
-      JNIHandleBlock::release_block(_handles);
-      _handles = NULL;
-    }
   }
 
   // Clear all the JNI handles for methods
@@ -420,17 +413,6 @@
   return _metaspace;
 }
 
-JNIHandleBlock* ClassLoaderData::handles() const           { return _handles; }
-void ClassLoaderData::set_handles(JNIHandleBlock* handles) { _handles = handles; }
-
-jobject ClassLoaderData::add_handle(Handle h) {
-  MutexLockerEx ml(metaspace_lock(),  Mutex::_no_safepoint_check_flag);
-  if (handles() == NULL) {
-    set_handles(JNIHandleBlock::allocate_block());
-  }
-  return handles()->allocate_handle(h());
-}
-
 // Add this metadata pointer to be freed when it's safe.  This is only during
 // class unloading because Handles might point to this metadata field.
 void ClassLoaderData::add_to_deallocate_list(Metadata* m) {
@@ -499,7 +481,6 @@
       p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name());
   if (claimed()) out->print(" claimed ");
   if (is_unloading()) out->print(" unloading ");
-  out->print(" handles " INTPTR_FORMAT, p2i(handles()));
   out->cr();
   if (metaspace_or_null() != NULL) {
     out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp	Thu May 21 18:22:33 2015 +0300
@@ -51,7 +51,6 @@
 
 class ClassLoaderData;
 class JNIMethodBlock;
-class JNIHandleBlock;
 class Metadebug;
 
 // GC root for walking class loader data created
@@ -173,8 +172,6 @@
                            // Has to be an int because we cas it.
   Klass* _klasses;         // The classes defined by the class loader.
 
-  JNIHandleBlock* _handles; // Handles to constant pool arrays
-
   // These method IDs are created for the class loader and set to NULL when the
   // class loader is unloaded.  They are rarely freed, only for redefine classes
   // and if they lose a data race in InstanceKlass.
@@ -200,9 +197,6 @@
 
   void set_metaspace(Metaspace* m) { _metaspace = m; }
 
-  JNIHandleBlock* handles() const;
-  void set_handles(JNIHandleBlock* handles);
-
   // GC interface.
   void clear_claimed()          { _claimed = 0; }
   bool claimed() const          { return _claimed == 1; }
@@ -290,7 +284,6 @@
   void verify();
   const char* loader_name();
 
-  jobject add_handle(Handle h);
   void add_class(Klass* k);
   void remove_class(Klass* k);
   bool contains_klass(Klass* k);
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu May 21 18:22:33 2015 +0300
@@ -567,6 +567,12 @@
     }
   }
   create_mirror(k, Handle(NULL), Handle(NULL), CHECK);
+
+  if (UseSharedSpaces && k->oop_is_instance()) {
+    // Create resolved_references array in the fresh mirror.
+    instanceKlassHandle ik(k());
+    ik->constants()->restore_unshareable_info(CHECK);
+  }
 }
 
 void java_lang_Class::initialize_mirror_fields(KlassHandle k,
@@ -924,6 +930,17 @@
   the_class_mirror->int_field_put(classRedefinedCount_offset, value);
 }
 
+objArrayOop java_lang_Class::resolved_references(oop java_class) {
+  assert(java_lang_Class::is_instance(java_class), "");
+  assert(resolvedReferences_offset > 0, "must be set");
+  return objArrayOop(java_class->obj_field(resolvedReferences_offset));
+}
+
+void java_lang_Class::set_resolved_references(oop java_class, objArrayOop a) {
+  assert(java_lang_Class::is_instance(java_class), "");
+  assert(resolvedReferences_offset > 0, "must be set");
+  java_class->obj_field_put(resolvedReferences_offset, a);
+}
 
 // Note: JDK1.1 and before had a privateInfo_offset field which was used for the
 //       platform thread structure, and a eetop offset which was used for thread
@@ -3181,6 +3198,7 @@
   }
 }
 
+int java_lang_Class::resolvedReferences_offset;
 int java_lang_Class::_klass_offset;
 int java_lang_Class::_array_klass_offset;
 int java_lang_Class::_oop_size_offset;
@@ -3336,6 +3354,9 @@
   const int x = heapOopSize;
   const int header = instanceOopDesc::base_offset_in_bytes();
 
+  // Class
+  java_lang_Class::resolvedReferences_offset = java_lang_Class::hc_resolvedReferences_offset * x + header;
+
   // Throwable Class
   java_lang_Throwable::backtrace_offset  = java_lang_Throwable::hc_backtrace_offset  * x + header;
   java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header;
@@ -3534,9 +3555,7 @@
 
   // java.lang.Class
 
-  // Fake fields
-  // CHECK_OFFSET("java/lang/Class", java_lang_Class, klass); // %%% this needs to be checked
-  // CHECK_OFFSET("java/lang/Class", java_lang_Class, array_klass); // %%% this needs to be checked
+  CHECK_OFFSET("java/lang/Class", java_lang_Class, resolvedReferences, "[Ljava/lang/Object;");
 
   // java.lang.Throwable
 
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Thu May 21 18:22:33 2015 +0300
@@ -226,6 +226,10 @@
 class java_lang_Class : AllStatic {
   friend class VMStructs;
 
+  enum {
+    hc_resolvedReferences_offset = 12
+  };
+
  private:
   // The fake offsets are added by the class loader when java.lang.Class is loaded
 
@@ -243,6 +247,7 @@
 
   static bool offsets_computed;
   static int classRedefinedCount_offset;
+  static int resolvedReferences_offset;
 
   static GrowableArray<Klass*>* _fixup_mirror_list;
 
@@ -301,6 +306,10 @@
   static int static_oop_field_count(oop java_class);
   static void set_static_oop_field_count(oop java_class, int size);
 
+  static objArrayOop     resolved_references(oop java_class);
+  static void        set_resolved_references(oop java_class, objArrayOop a);
+  static int             resolved_references_offset_in_bytes() { return resolvedReferences_offset; }
+
   static GrowableArray<Klass*>* fixup_mirror_list() {
     return _fixup_mirror_list;
   }
--- a/hotspot/src/share/vm/oops/constantPool.cpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/oops/constantPool.cpp	Thu May 21 18:22:33 2015 +0300
@@ -67,7 +67,6 @@
   set_tags(NULL);
   set_cache(NULL);
   set_reference_map(NULL);
-  set_resolved_references(NULL);
   set_operands(NULL);
   set_pool_holder(NULL);
   set_flags(0);
@@ -104,10 +103,6 @@
   unreference_symbols();
 }
 
-objArrayOop ConstantPool::resolved_references() const {
-  return (objArrayOop)JNIHandles::resolve(_resolved_references);
-}
-
 // Create resolved_references array and mapping array for original cp indexes
 // The ldc bytecode was rewritten to have the resolved reference array index so need a way
 // to map it back for resolving and some unlikely miscellaneous uses.
@@ -136,30 +131,31 @@
 
     // Create Java array for holding resolved strings, methodHandles,
     // methodTypes, invokedynamic and invokehandle appendix objects, etc.
-    objArrayOop stom = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);
-    Handle refs_handle (THREAD, (oop)stom);  // must handleize.
-    set_resolved_references(loader_data->add_handle(refs_handle));
+    objArrayOop obj_arr = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);
+    pool_holder()->set_resolved_references(obj_arr);
   }
 }
 
+objArrayOop ConstantPool::resolved_references() const {
+  return pool_holder()->resolved_references();
+}
+
 // CDS support. Create a new resolved_references array.
 void ConstantPool::restore_unshareable_info(TRAPS) {
+  // restore the C++ vtable from the shared archive
+  restore_vtable();
+
+  if (pool_holder()->java_mirror() == NULL)  return;
 
   // Only create the new resolved references array if it hasn't been attempted before
-  if (resolved_references() != NULL) return;
-
-  // restore the C++ vtable from the shared archive
-  restore_vtable();
+  if (pool_holder()->resolved_references() != NULL) return;
 
   if (SystemDictionary::Object_klass_loaded()) {
     // Recreate the object array and add to ClassLoaderData.
     int map_length = resolved_reference_length();
     if (map_length > 0) {
-      objArrayOop stom = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);
-      Handle refs_handle (THREAD, (oop)stom);  // must handleize.
-
-      ClassLoaderData* loader_data = pool_holder()->class_loader_data();
-      set_resolved_references(loader_data->add_handle(refs_handle));
+      objArrayOop resolved_references = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);
+      pool_holder()->set_resolved_references(resolved_references);
     }
   }
 }
@@ -168,9 +164,8 @@
   // Resolved references are not in the shared archive.
   // Save the length for restoration.  It is not necessarily the same length
   // as reference_map.length() if invokedynamic is saved.
-  set_resolved_reference_length(
-    resolved_references() != NULL ? resolved_references()->length() : 0);
-  set_resolved_references(NULL);
+  objArrayOop resolved_references = pool_holder()->resolved_references();
+  set_resolved_reference_length(resolved_references != NULL ? resolved_references->length() : 0);
 }
 
 int ConstantPool::cp_to_object_index(int cp_index) {
@@ -1871,7 +1866,6 @@
     st->print_cr(" - holder: " INTPTR_FORMAT, pool_holder());
   }
   st->print_cr(" - cache: " INTPTR_FORMAT, cache());
-  st->print_cr(" - resolved_references: " INTPTR_FORMAT, (void *)resolved_references());
   st->print_cr(" - reference_map: " INTPTR_FORMAT, reference_map());
 
   for (int index = 1; index < length(); index++) {      // Index 0 is unused
--- a/hotspot/src/share/vm/oops/constantPool.hpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/oops/constantPool.hpp	Thu May 21 18:22:33 2015 +0300
@@ -84,7 +84,6 @@
 
   // Array of resolved objects from the constant pool and map from resolved
   // object index to original constant pool index
-  jobject              _resolved_references;
   Array<u2>*           _reference_map;
 
   enum {
@@ -191,6 +190,7 @@
 
   // resolved strings, methodHandles and callsite objects from the constant pool
   objArrayOop resolved_references()  const;
+
   // mapping resolved object array indexes to cp indexes and back.
   int object_to_cp_index(int index)         { return _reference_map->at(index); }
   int cp_to_object_index(int index);
@@ -222,7 +222,6 @@
   static int tags_offset_in_bytes()         { return offset_of(ConstantPool, _tags); }
   static int cache_offset_in_bytes()        { return offset_of(ConstantPool, _cache); }
   static int pool_holder_offset_in_bytes()  { return offset_of(ConstantPool, _pool_holder); }
-  static int resolved_references_offset_in_bytes() { return offset_of(ConstantPool, _resolved_references); }
 
   // Storing constants
 
@@ -771,7 +770,6 @@
 
  private:
 
-  void set_resolved_references(jobject s) { _resolved_references = s; }
   Array<u2>* reference_map() const        { return _reference_map; }
   void set_reference_map(Array<u2>* o)    { _reference_map = o; }
 
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu May 21 18:22:33 2015 +0300
@@ -2032,7 +2032,6 @@
 }
 
 void InstanceKlass::remove_unshareable_info() {
-  Klass::remove_unshareable_info();
   // Unlink the class
   if (is_linked()) {
     unlink_class();
@@ -2048,6 +2047,8 @@
 
   // do array classes also.
   array_klasses_do(remove_unshareable_in_class);
+
+  Klass::remove_unshareable_info();
 }
 
 static void restore_unshareable_in_class(Klass* k, TRAPS) {
@@ -3512,3 +3513,11 @@
 unsigned char * InstanceKlass::get_cached_class_file_bytes() {
   return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
 }
+
+objArrayOop InstanceKlass::resolved_references() const {
+  return java_lang_Class::resolved_references(java_mirror());
+}
+
+void InstanceKlass::set_resolved_references(objArrayOop obj_arr) {
+  return java_lang_Class::set_resolved_references(java_mirror(), obj_arr);
+}
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu May 21 18:22:33 2015 +0300
@@ -532,6 +532,9 @@
   ConstantPool* constants() const        { return _constants; }
   void set_constants(ConstantPool* c)    { _constants = c; }
 
+  objArrayOop     resolved_references() const;
+  void        set_resolved_references(objArrayOop obj_arr);
+
   // protection domain
   oop protection_domain() const;
 
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu May 21 18:22:33 2015 +0300
@@ -3885,7 +3885,10 @@
 
   // Attach new constant pool to the original klass. The original
   // klass still refers to the old constant pool (for now).
+  // resolved_references array should be moved as well, since it is located
+  // in klass mirror.
   scratch_class->constants()->set_pool_holder(the_class());
+  the_class->set_resolved_references(scratch_class->resolved_references());
 
 #if 0
   // In theory, with constant pool merging in place we should be able
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Fri May 15 19:23:11 2015 +0300
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu May 21 18:22:33 2015 +0300
@@ -288,7 +288,6 @@
   nonstatic_field(ConstantPool,         _pool_holder,                                  InstanceKlass*)                        \
   nonstatic_field(ConstantPool,         _operands,                                     Array<u2>*)                            \
   nonstatic_field(ConstantPool,         _length,                                       int)                                   \
-  nonstatic_field(ConstantPool,         _resolved_references,                          jobject)                               \
   nonstatic_field(ConstantPool,         _reference_map,                                Array<u2>*)                            \
   nonstatic_field(ConstantPoolCache,    _length,                                       int)                                   \
   nonstatic_field(ConstantPoolCache,    _constant_pool,                                ConstantPool*)                         \