changeset 8493:0e1f666bf724

8081320: Backout JDK-8059340: ConstantPool::_resolved_references is missing in heap dump Reviewed-by: sspitsyn, coleenp
author vlivanov
date Fri, 29 May 2015 17:04:21 +0300
parents a7c457567b1e
children 40691aab6662
files src/cpu/aarch64/vm/interp_masm_aarch64.cpp src/cpu/aarch64/vm/interp_masm_aarch64.hpp src/cpu/sparc/vm/interp_masm_sparc.cpp src/cpu/sparc/vm/interp_masm_sparc.hpp src/cpu/x86/vm/interp_masm_x86.cpp src/cpu/x86/vm/interp_masm_x86.hpp src/share/vm/ci/ciStreams.cpp src/share/vm/classfile/classLoaderData.cpp src/share/vm/classfile/classLoaderData.hpp src/share/vm/classfile/javaClasses.cpp src/share/vm/classfile/javaClasses.hpp src/share/vm/oops/constantPool.cpp src/share/vm/oops/constantPool.hpp src/share/vm/oops/instanceKlass.cpp src/share/vm/oops/instanceKlass.hpp src/share/vm/prims/jvmtiRedefineClasses.cpp src/share/vm/runtime/vmStructs.cpp
diffstat 17 files changed, 77 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Fri May 29 17:04:21 2015 +0300
@@ -229,21 +229,16 @@
   Register tmp = index;  // reuse
   lslw(tmp, tmp, LogBytesPerHeapOop);
 
+  get_constant_pool(result);
   // load pointer for resolved_references[] objArray
-  get_resolved_references(result);
+  ldr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
+  // JNIHandles::resolve(obj);
+  ldr(result, Address(result, 0));
   // 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/src/cpu/aarch64/vm/interp_masm_aarch64.hpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/cpu/aarch64/vm/interp_masm_aarch64.hpp	Fri May 29 17:04:21 2015 +0300
@@ -121,8 +121,6 @@
     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/src/cpu/sparc/vm/interp_masm_sparc.cpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Fri May 29 17:04:21 2015 +0300
@@ -798,8 +798,11 @@
   // 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
-  get_resolved_references(result);
+  ld_ptr(result, ConstantPool::resolved_references_offset_in_bytes(), result);
+  // JNIHandles::resolve(result)
+  ld_ptr(result, 0, result);
   // Add in the index
   add(result, tmp, result);
   load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result);
@@ -970,13 +973,6 @@
   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/src/cpu/sparc/vm/interp_masm_sparc.hpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp	Fri May 29 17:04:21 2015 +0300
@@ -212,7 +212,6 @@
   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/src/cpu/x86/vm/interp_masm_x86.cpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/cpu/x86/vm/interp_masm_x86.cpp	Fri May 29 17:04:21 2015 +0300
@@ -482,14 +482,6 @@
   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,
@@ -507,16 +499,20 @@
   addptr(cache, tmp);  // construct pointer to cache entry
 }
 
-// Load object from cpool->pool_holder->mirror->resolved_references(index)
-void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result, Register index) {
+// Load object from cpool->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
-  get_resolved_references(result);
+  movptr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
+  // JNIHandles::resolve(obj);
+  movptr(result, Address(result, 0));
   // Add in the index
   addptr(result, tmp);
   load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
--- a/src/cpu/x86/vm/interp_masm_x86.hpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/cpu/x86/vm/interp_masm_x86.hpp	Fri May 29 17:04:21 2015 +0300
@@ -109,8 +109,6 @@
     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/src/share/vm/ci/ciStreams.cpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/ci/ciStreams.cpp	Fri May 29 17:04:21 2015 +0300
@@ -477,8 +477,10 @@
 // ------------------------------------------------------------------
 // ciBytecodeStream::get_resolved_references
 ciObjArray* ciBytecodeStream::get_resolved_references() {
-  VM_ENTRY_MARK;
-  objArrayOop resolved_references = _holder->get_instanceKlass()->resolved_references();
+    VM_ENTRY_MARK;
+    // Get the constant pool.
+  ConstantPool*        cpool   = _holder->get_instanceKlass()->constants();
+
   // Create a resolved references array and return it.
-  return CURRENT_ENV->get_object(resolved_references)->as_obj_array();
-}
+  return CURRENT_ENV->get_object(cpool->resolved_references())->as_obj_array();
+  }
--- a/src/share/vm/classfile/classLoaderData.cpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/classfile/classLoaderData.cpp	Fri May 29 17:04:21 2015 +0300
@@ -60,6 +60,7 @@
 #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"
@@ -80,7 +81,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), _deallocate_list(NULL),
+  _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
   _next(NULL), _dependencies(dependencies),
   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
                             Monitor::_safepoint_check_never)) {
@@ -114,6 +115,7 @@
 
   f->do_oop(&_class_loader);
   _dependencies.oops_do(f);
+  _handles->oops_do(f);
   if (klass_closure != NULL) {
     classes_do(klass_closure);
   }
@@ -354,6 +356,11 @@
     _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
@@ -413,6 +420,17 @@
   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) {
@@ -481,6 +499,7 @@
       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/src/share/vm/classfile/classLoaderData.hpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/classfile/classLoaderData.hpp	Fri May 29 17:04:21 2015 +0300
@@ -51,6 +51,7 @@
 
 class ClassLoaderData;
 class JNIMethodBlock;
+class JNIHandleBlock;
 class Metadebug;
 
 // GC root for walking class loader data created
@@ -172,6 +173,8 @@
                            // 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.
@@ -197,6 +200,9 @@
 
   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; }
@@ -284,6 +290,7 @@
   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/src/share/vm/classfile/javaClasses.cpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/classfile/javaClasses.cpp	Fri May 29 17:04:21 2015 +0300
@@ -567,12 +567,6 @@
     }
   }
   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,
@@ -930,17 +924,6 @@
   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
@@ -3198,7 +3181,6 @@
   }
 }
 
-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;
@@ -3354,9 +3336,6 @@
   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;
@@ -3555,7 +3534,9 @@
 
   // java.lang.Class
 
-  CHECK_OFFSET("java/lang/Class", java_lang_Class, resolvedReferences, "[Ljava/lang/Object;");
+  // 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
 
   // java.lang.Throwable
 
--- a/src/share/vm/classfile/javaClasses.hpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/classfile/javaClasses.hpp	Fri May 29 17:04:21 2015 +0300
@@ -226,10 +226,6 @@
 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
 
@@ -247,7 +243,6 @@
 
   static bool offsets_computed;
   static int classRedefinedCount_offset;
-  static int resolvedReferences_offset;
 
   static GrowableArray<Klass*>* _fixup_mirror_list;
 
@@ -306,10 +301,6 @@
   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/src/share/vm/oops/constantPool.cpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/oops/constantPool.cpp	Fri May 29 17:04:21 2015 +0300
@@ -67,6 +67,7 @@
   set_tags(NULL);
   set_cache(NULL);
   set_reference_map(NULL);
+  set_resolved_references(NULL);
   set_operands(NULL);
   set_pool_holder(NULL);
   set_flags(0);
@@ -103,6 +104,10 @@
   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.
@@ -131,31 +136,30 @@
 
     // Create Java array for holding resolved strings, methodHandles,
     // methodTypes, invokedynamic and invokehandle appendix objects, etc.
-    objArrayOop obj_arr = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);
-    pool_holder()->set_resolved_references(obj_arr);
+    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 ConstantPool::resolved_references() const {
-  return pool_holder()->resolved_references();
-}
-
 // CDS support. Create a new resolved_references array.
 void ConstantPool::restore_unshareable_info(TRAPS) {
+
+  // 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()->java_mirror() == NULL)  return;
-
-  // Only create the new resolved references array if it hasn't been attempted before
-  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 resolved_references = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);
-      pool_holder()->set_resolved_references(resolved_references);
+      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));
     }
   }
 }
@@ -164,8 +168,9 @@
   // 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.
-  objArrayOop resolved_references = pool_holder()->resolved_references();
-  set_resolved_reference_length(resolved_references != NULL ? resolved_references->length() : 0);
+  set_resolved_reference_length(
+    resolved_references() != NULL ? resolved_references()->length() : 0);
+  set_resolved_references(NULL);
 }
 
 int ConstantPool::cp_to_object_index(int cp_index) {
@@ -1866,6 +1871,7 @@
     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/src/share/vm/oops/constantPool.hpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/oops/constantPool.hpp	Fri May 29 17:04:21 2015 +0300
@@ -84,6 +84,7 @@
 
   // 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 {
@@ -190,7 +191,6 @@
 
   // 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,6 +222,7 @@
   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
 
@@ -770,6 +771,7 @@
 
  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/src/share/vm/oops/instanceKlass.cpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/oops/instanceKlass.cpp	Fri May 29 17:04:21 2015 +0300
@@ -2032,6 +2032,7 @@
 }
 
 void InstanceKlass::remove_unshareable_info() {
+  Klass::remove_unshareable_info();
   // Unlink the class
   if (is_linked()) {
     unlink_class();
@@ -2047,8 +2048,6 @@
 
   // do array classes also.
   array_klasses_do(remove_unshareable_in_class);
-
-  Klass::remove_unshareable_info();
 }
 
 static void restore_unshareable_in_class(Klass* k, TRAPS) {
@@ -3513,11 +3512,3 @@
 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/src/share/vm/oops/instanceKlass.hpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/oops/instanceKlass.hpp	Fri May 29 17:04:21 2015 +0300
@@ -532,9 +532,6 @@
   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/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri May 29 17:04:21 2015 +0300
@@ -3885,10 +3885,7 @@
 
   // 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/src/share/vm/runtime/vmStructs.cpp	Fri May 29 12:49:31 2015 +0200
+++ b/src/share/vm/runtime/vmStructs.cpp	Fri May 29 17:04:21 2015 +0300
@@ -288,6 +288,7 @@
   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*)                         \