8171392: Move Klass pointers outside of ConstantPool entries so ConstantPool can be read-only
authoriklam
Fri, 03 Mar 2017 23:08:35 -0800
changeset 46427 54713555867e
parent 46426 02a1fc064144
child 46428 d577822ca75c
8171392: Move Klass pointers outside of ConstantPool entries so ConstantPool can be read-only Summary: Added _resolved_klasses; moved _resolved_references to ConstantPoolCache, etc. Reviewed-by: coleenp, lfoltan, simonis, aph
hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp
hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp
hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp
hotspot/src/cpu/arm/vm/interp_masm_arm.cpp
hotspot/src/cpu/arm/vm/interp_masm_arm.hpp
hotspot/src/cpu/arm/vm/templateTable_arm.cpp
hotspot/src/cpu/ppc/vm/interp_masm_ppc.hpp
hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp
hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp
hotspot/src/cpu/s390/vm/interp_masm_s390.cpp
hotspot/src/cpu/s390/vm/interp_masm_s390.hpp
hotspot/src/cpu/s390/vm/templateTable_s390.cpp
hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp
hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
hotspot/src/cpu/x86/vm/interp_masm_x86.cpp
hotspot/src/cpu/x86/vm/interp_masm_x86.hpp
hotspot/src/cpu/x86/vm/templateTable_x86.cpp
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java
hotspot/src/share/vm/classfile/bytecodeAssembler.cpp
hotspot/src/share/vm/classfile/classFileParser.cpp
hotspot/src/share/vm/classfile/classFileParser.hpp
hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
hotspot/src/share/vm/interpreter/rewriter.cpp
hotspot/src/share/vm/memory/metaspaceShared.hpp
hotspot/src/share/vm/oops/constantPool.cpp
hotspot/src/share/vm/oops/constantPool.hpp
hotspot/src/share/vm/oops/cpCache.hpp
hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
hotspot/src/share/vm/runtime/vmStructs.cpp
hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -270,7 +270,8 @@
 
   get_constant_pool(result);
   // load pointer for resolved_references[] objArray
-  ldr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
+  ldr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
+  ldr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
   // JNIHandles::resolve(obj);
   ldr(result, Address(result, 0));
   // Add in the index
@@ -278,6 +279,15 @@
   load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
 }
 
+void InterpreterMacroAssembler::load_resolved_klass_at_offset(
+                             Register cpool, Register index, Register klass, Register temp) {
+  add(temp, cpool, index, LSL, LogBytesPerWord);
+  ldrh(temp, Address(temp, sizeof(ConstantPool))); // temp = resolved_klass_index
+  ldr(klass, Address(cpool,  ConstantPool::resolved_klasses_offset_in_bytes())); // klass = cpool->_resolved_klasses
+  add(klass, klass, temp, LSL, LogBytesPerWord);
+  ldr(klass, Address(klass, Array<Klass*>::base_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	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -123,6 +123,9 @@
   // load cpool->resolved_references(index);
   void load_resolved_reference_at_index(Register result, Register index);
 
+  // load cpool->resolved_klass_at(index);
+  void load_resolved_klass_at_offset(Register cpool, Register index, Register klass, Register temp);
+
   void pop_ptr(Register r = r0);
   void pop_i(Register r = r0);
   void pop_l(Register r = r0);
--- a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -3372,8 +3372,7 @@
   __ br(Assembler::NE, slow_case);
 
   // get InstanceKlass
-  __ lea(r4, Address(r4, r3, Address::lsl(3)));
-  __ ldr(r4, Address(r4, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_offset(r4, r3, r4, rscratch1);
 
   // make sure klass is initialized & doesn't have finalizer
   // make sure klass is fully initialized
@@ -3526,8 +3525,7 @@
   // Get superklass in r0 and subklass in r3
   __ bind(quicked);
   __ mov(r3, r0); // Save object in r3; r0 needed for subtype check
-  __ lea(r0, Address(r2, r19, Address::lsl(3)));
-  __ ldr(r0, Address(r0, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_offset(r2, r19, r0, rscratch1); // r0 = klass
 
   __ bind(resolved);
   __ load_klass(r19, r3);
@@ -3583,8 +3581,7 @@
   // Get superklass in r0 and subklass in r3
   __ bind(quicked);
   __ load_klass(r3, r0);
-  __ lea(r0, Address(r2, r19, Address::lsl(3)));
-  __ ldr(r0, Address(r0, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_offset(r2, r19, r0, rscratch1);
 
   __ bind(resolved);
 
--- a/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -298,7 +298,8 @@
 
   Register cache = result;
   // load pointer for resolved_references[] objArray
-  ldr(cache, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
+  ldr(cache, Address(result, ConstantPool::cache_offset_in_bytes()));
+  ldr(cache, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
   // JNIHandles::resolve(result)
   ldr(cache, Address(cache, 0));
   // Add in the index
@@ -308,6 +309,15 @@
   load_heap_oop(result, Address(cache, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
 }
 
+void InterpreterMacroAssembler::load_resolved_klass_at_offset(
+                                           Register Rcpool, Register Rindex, Register Rklass) {
+  add(Rtemp, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
+  ldrh(Rtemp, Address(Rtemp, sizeof(ConstantPool))); // Rtemp = resolved_klass_index
+  ldr(Rklass, Address(Rcpool,  ConstantPool::resolved_klasses_offset_in_bytes())); // Rklass = cpool->_resolved_klasses
+  add(Rklass, Rklass, AsmOperand(Rtemp, lsl, LogBytesPerWord));
+  ldr(Rklass, Address(Rklass, Array<Klass*>::base_offset_in_bytes()));
+}
+
 // Generate a subtype check: branch to not_subtype if sub_klass is
 // not a subtype of super_klass.
 // Profiling code for the subtype check failure (profile_typecheck_failed)
--- a/hotspot/src/cpu/arm/vm/interp_masm_arm.hpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/interp_masm_arm.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -141,6 +141,9 @@
   // Load object from cpool->resolved_references(*bcp+1)
   void load_resolved_reference_at_index(Register result, Register tmp);
 
+  // load cpool->resolved_klass_at(index); Rtemp is corrupted upon return
+  void load_resolved_klass_at_offset(Register Rcpool, Register Rindex, Register Rklass);
+
   void store_check_part1(Register card_table_base);                // Sets card_table_base register.
   void store_check_part2(Register obj, Register card_table_base, Register tmp);
 
--- a/hotspot/src/cpu/arm/vm/templateTable_arm.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/templateTable_arm.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -4372,10 +4372,9 @@
 #endif // AARCH64
 
   // get InstanceKlass
-  __ add(Rklass, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
-  __ ldr(Rklass, Address(Rklass, sizeof(ConstantPool)));
   __ cmp(Rtemp, JVM_CONSTANT_Class);
   __ b(slow_case, ne);
+  __ load_resolved_klass_at_offset(Rcpool, Rindex, Rklass);
 
   // make sure klass is initialized & doesn't have finalizer
   // make sure klass is fully initialized
@@ -4647,8 +4646,7 @@
 
   // Get superklass in Rsuper and subklass in Rsub
   __ bind(quicked);
-  __ add(Rtemp, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
-  __ ldr(Rsuper, Address(Rtemp, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_offset(Rcpool, Rindex, Rsuper);
 
   __ bind(resolved);
   __ load_klass(Rsub, Robj);
@@ -4721,8 +4719,7 @@
 
   // Get superklass in Rsuper and subklass in Rsub
   __ bind(quicked);
-  __ add(Rtemp, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
-  __ ldr(Rsuper, Address(Rtemp, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_offset(Rcpool, Rindex, Rsuper);
 
   __ bind(resolved);
   __ load_klass(Rsub, Robj);
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc.hpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,6 +79,9 @@
   // Load object from cpool->resolved_references(index).
   void load_resolved_reference_at_index(Register result, Register index, Label *is_null = NULL);
 
+  // load cpool->resolved_klass_at(index)
+  void load_resolved_klass_at_offset(Register Rcpool, Register Roffset, Register Rklass);
+
   void load_receiver(Register Rparam_count, Register Rrecv_dst);
 
   // helpers for expression stack
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -454,7 +454,8 @@
   Register tmp = index;  // reuse
   sldi(tmp, index, LogBytesPerHeapOop);
   // Load pointer for resolved_references[] objArray.
-  ld(result, ConstantPool::resolved_references_offset_in_bytes(), result);
+  ld(result, ConstantPool::cache_offset_in_bytes(), result);
+  ld(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
   // JNIHandles::resolve(result)
   ld(result, 0, result);
 #ifdef ASSERT
@@ -471,6 +472,25 @@
   load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result, is_null);
 }
 
+// load cpool->resolved_klass_at(index)
+void InterpreterMacroAssembler::load_resolved_klass_at_offset(Register Rcpool, Register Roffset, Register Rklass) {
+  // int value = *(Rcpool->int_at_addr(which));
+  // int resolved_klass_index = extract_low_short_from_int(value);
+  add(Roffset, Rcpool, Roffset);
+#if defined(VM_LITTLE_ENDIAN)
+  lhz(Roffset, sizeof(ConstantPool), Roffset);     // Roffset = resolved_klass_index
+#else
+  lhz(Roffset, sizeof(ConstantPool) + 2, Roffset); // Roffset = resolved_klass_index
+#endif
+
+  ld(Rklass, ConstantPool::resolved_klasses_offset_in_bytes(), Rcpool); // Rklass = Rcpool->_resolved_klasses
+
+  sldi(Roffset, Roffset, LogBytesPerWord);
+  addi(Roffset, Roffset, Array<Klass*>::base_offset_in_bytes());
+  isync(); // Order load of instance Klass wrt. tags.
+  ldx(Rklass, Rklass, Roffset);
+}
+
 // Generate a subtype check: branch to ok_is_subtype if sub_klass is
 // a subtype of super_klass. Blows registers Rsub_klass, tmp1, tmp2.
 void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, Register Rsuper_klass, Register Rtmp1,
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -3660,11 +3660,9 @@
     __ cmpdi(CCR0, Rtags, JVM_CONSTANT_Class);
     __ bne(CCR0, Lslow_case);
 
-    // Get instanceKlass (load from Rcpool + sizeof(ConstantPool) + Rindex*BytesPerWord).
+    // Get instanceKlass
     __ sldi(Roffset, Rindex, LogBytesPerWord);
-    __ addi(Rscratch, Rcpool, sizeof(ConstantPool));
-    __ isync(); // Order load of instance Klass wrt. tags.
-    __ ldx(RinstanceKlass, Roffset, Rscratch);
+    __ load_resolved_klass_at_offset(Rcpool, Roffset, RinstanceKlass);
 
     // Make sure klass is fully initialized and get instance_size.
     __ lbz(Rscratch, in_bytes(InstanceKlass::init_state_offset()), RinstanceKlass);
@@ -3875,9 +3873,7 @@
   // Extract target class from constant pool.
   __ bind(Lquicked);
   __ sldi(Roffset, Roffset, LogBytesPerWord);
-  __ addi(Rcpool, Rcpool, sizeof(ConstantPool));
-  __ isync(); // Order load of specified Klass wrt. tags.
-  __ ldx(RspecifiedKlass, Rcpool, Roffset);
+  __ load_resolved_klass_at_offset(Rcpool, Roffset, RspecifiedKlass);
 
   // Do the checkcast.
   __ bind(Lresolved);
@@ -3939,9 +3935,7 @@
   // Extract target class from constant pool.
   __ bind(Lquicked);
   __ sldi(Roffset, Roffset, LogBytesPerWord);
-  __ addi(Rcpool, Rcpool, sizeof(ConstantPool));
-  __ isync(); // Order load of specified Klass wrt. tags.
-  __ ldx(RspecifiedKlass, Rcpool, Roffset);
+  __ load_resolved_klass_at_offset(Rcpool, Roffset, RspecifiedKlass);
 
   // Do the checkcast.
   __ bind(Lresolved);
--- a/hotspot/src/cpu/s390/vm/interp_masm_s390.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/s390/vm/interp_masm_s390.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,8 @@
   Register tmp = index;  // reuse
   z_sllg(index, index, LogBytesPerHeapOop); // Offset into resolved references array.
   // Load pointer for resolved_references[] objArray.
-  z_lg(result, ConstantPool::resolved_references_offset_in_bytes(), result);
+  z_lg(result, ConstantPool::cache_offset_in_bytes(), result);
+  z_lg(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
   // JNIHandles::resolve(result)
   z_lg(result, 0, result); // Load resolved references array itself.
 #ifdef ASSERT
@@ -386,6 +387,16 @@
   load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result);
 }
 
+// load cpool->resolved_klass_at(index)
+void InterpreterMacroAssembler::load_resolved_klass_at_offset(Register cpool, Register offset, Register iklass) {
+  // int value = *(Rcpool->int_at_addr(which));
+  // int resolved_klass_index = extract_low_short_from_int(value);
+  z_llgh(offset, Address(cpool, offset, sizeof(ConstantPool) + 2)); // offset = resolved_klass_index (s390 is big-endian)
+  z_sllg(offset, offset, LogBytesPerWord);                          // Convert 'index' to 'offset'
+  z_lg(iklass, Address(cpool, ConstantPool::resolved_klasses_offset_in_bytes())); // iklass = cpool->_resolved_klasses
+  z_lg(iklass, Address(iklass, offset, Array<Klass*>::base_offset_in_bytes()));
+}
+
 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
                                                                Register tmp,
                                                                int bcp_offset,
--- a/hotspot/src/cpu/s390/vm/interp_masm_s390.hpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/s390/vm/interp_masm_s390.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -115,6 +115,8 @@
   void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
   void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
   void load_resolved_reference_at_index(Register result, Register index);
+  // load cpool->resolved_klass_at(index)
+  void load_resolved_klass_at_offset(Register cpool, Register offset, Register iklass);
 
   // Pop topmost element from stack. It just disappears. Useful if
   // consumed previously by access via stackTop().
--- a/hotspot/src/cpu/s390/vm/templateTable_s390.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/s390/vm/templateTable_s390.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -3708,7 +3708,7 @@
   __ z_sllg(offset, offset, LogBytesPerWord); // Convert to to offset.
   // Get InstanceKlass.
   Register iklass = cpool;
-  __ z_lg(iklass, Address(cpool, offset, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_offset(cpool, offset, iklass);
 
   // Make sure klass is initialized & doesn't have finalizer.
   // Make sure klass is fully initialized.
@@ -3895,7 +3895,7 @@
 
   __ z_lgr(Z_ARG4, Z_tos);  // Save receiver.
   __ z_sllg(index, index, LogBytesPerWord);  // index2bytes for addressing
-  __ mem2reg_opt(klass, Address(cpool, index, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_offset(cpool, index, klass);
 
   __ bind(resolved);
 
@@ -3969,8 +3969,7 @@
 
   __ load_klass(subklass, Z_tos);
   __ z_sllg(index, index, LogBytesPerWord);  // index2bytes for addressing
-  __ mem2reg_opt(klass,
-                 Address(cpool, index, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_offset(cpool, index, klass);
 
   __ bind(resolved);
 
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -755,7 +755,8 @@
   sll(index, LogBytesPerHeapOop, tmp);
   get_constant_pool(result);
   // load pointer for resolved_references[] objArray
-  ld_ptr(result, ConstantPool::resolved_references_offset_in_bytes(), result);
+  ld_ptr(result, ConstantPool::cache_offset_in_bytes(), result);
+  ld_ptr(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
   // JNIHandles::resolve(result)
   ld_ptr(result, 0, result);
   // Add in the index
@@ -764,6 +765,24 @@
 }
 
 
+// load cpool->resolved_klass_at(index)
+void InterpreterMacroAssembler::load_resolved_klass_at_offset(Register Rcpool,
+                                           Register Roffset, Register Rklass) {
+  // int value = *this_cp->int_at_addr(which);
+  // int resolved_klass_index = extract_low_short_from_int(value);
+  //
+  // Because SPARC is big-endian, the low_short is at (cpool->int_at_addr(which) + 2 bytes)
+  add(Roffset, Rcpool, Roffset);
+  lduh(Roffset, sizeof(ConstantPool) + 2, Roffset);  // Roffset = resolved_klass_index
+
+  Register Rresolved_klasses = Rklass;
+  ld_ptr(Rcpool, ConstantPool::resolved_klasses_offset_in_bytes(), Rresolved_klasses);
+  sll(Roffset, LogBytesPerWord, Roffset);
+  add(Roffset, Array<Klass*>::base_offset_in_bytes(), Roffset);
+  ld_ptr(Rresolved_klasses, Roffset, Rklass);
+}
+
+
 // Generate a subtype check: branch to ok_is_subtype if sub_klass is
 // a subtype of super_klass.  Blows registers Rsuper_klass, Rsub_klass, tmp1, tmp2.
 void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -196,6 +196,9 @@
   // load cpool->resolved_references(index);
   void load_resolved_reference_at_index(Register result, Register index);
 
+  // load cpool->resolved_klass_at(index)
+  void load_resolved_klass_at_offset(Register Rcpool, Register Roffset, Register Rklass);
+
   // common code
 
   void field_offset_at(int n, Register tmp, Register dest, Register base);
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -3241,9 +3241,7 @@
   __ br(Assembler::notEqual, false, Assembler::pn, slow_case);
   __ delayed()->sll(Roffset, LogBytesPerWord, Roffset);
   // get InstanceKlass
-  //__ sll(Roffset, LogBytesPerWord, Roffset);        // executed in delay slot
-  __ add(Roffset, sizeof(ConstantPool), Roffset);
-  __ ld_ptr(Rscratch, Roffset, RinstanceKlass);
+  __ load_resolved_klass_at_offset(Rscratch, Roffset, RinstanceKlass);
 
   // make sure klass is fully initialized:
   __ ldub(RinstanceKlass, in_bytes(InstanceKlass::init_state_offset()), G3_scratch);
@@ -3465,8 +3463,9 @@
 
   // Extract target class from constant pool
   __ bind(quicked);
-  __ add(Roffset, sizeof(ConstantPool), Roffset);
-  __ ld_ptr(Lscratch, Roffset, RspecifiedKlass);
+  __ load_resolved_klass_at_offset(Lscratch, Roffset, RspecifiedKlass);
+
+
   __ bind(resolved);
   __ load_klass(Otos_i, RobjKlass); // get value klass
 
@@ -3522,9 +3521,9 @@
 
   // Extract target class from constant pool
   __ bind(quicked);
-  __ add(Roffset, sizeof(ConstantPool), Roffset);
   __ get_constant_pool(Lscratch);
-  __ ld_ptr(Lscratch, Roffset, RspecifiedKlass);
+  __ load_resolved_klass_at_offset(Lscratch, Roffset, RspecifiedKlass);
+
   __ bind(resolved);
   __ load_klass(Otos_i, RobjKlass); // get value klass
 
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -509,7 +509,8 @@
 
   get_constant_pool(result);
   // load pointer for resolved_references[] objArray
-  movptr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
+  movptr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
+  movptr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
   // JNIHandles::resolve(obj);
   movptr(result, Address(result, 0));
   // Add in the index
@@ -517,6 +518,14 @@
   load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
 }
 
+// load cpool->resolved_klass_at(index)
+void InterpreterMacroAssembler::load_resolved_klass_at_index(Register cpool,
+                                           Register index, Register klass) {
+  movw(index, Address(cpool, index, Address::times_ptr, sizeof(ConstantPool)));
+  Register resolved_klasses = cpool;
+  movptr(resolved_klasses, Address(cpool, ConstantPool::resolved_klasses_offset_in_bytes()));
+  movptr(klass, Address(resolved_klasses, index, Address::times_ptr, Array<Klass*>::base_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/x86/vm/interp_masm_x86.hpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -123,6 +123,11 @@
   // load cpool->resolved_references(index);
   void load_resolved_reference_at_index(Register result, Register index);
 
+  // load cpool->resolved_klass_at(index)
+  void load_resolved_klass_at_index(Register cpool,  // the constant pool (corrupted on return)
+                                    Register index,  // the constant pool index (corrupted on return)
+                                    Register klass); // contains the Klass on return
+
   NOT_LP64(void f2ieee();)        // truncate ftos to 32bits
   NOT_LP64(void d2ieee();)        // truncate dtos to 64bits
 
--- a/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -3846,7 +3846,7 @@
   __ jcc(Assembler::notEqual, slow_case_no_pop);
 
   // get InstanceKlass
-  __ movptr(rcx, Address(rcx, rdx, Address::times_ptr, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_index(rcx, rdx, rcx);
   __ push(rcx);  // save the contexts of klass for initializing the header
 
   // make sure klass is initialized & doesn't have finalizer
@@ -4061,8 +4061,7 @@
   // Get superklass in rax and subklass in rbx
   __ bind(quicked);
   __ mov(rdx, rax); // Save object in rdx; rax needed for subtype check
-  __ movptr(rax, Address(rcx, rbx,
-                       Address::times_ptr, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_index(rcx, rbx, rax);
 
   __ bind(resolved);
   __ load_klass(rbx, rdx);
@@ -4128,8 +4127,7 @@
   // Get superklass in rax and subklass in rdx
   __ bind(quicked);
   __ load_klass(rdx, rax);
-  __ movptr(rax, Address(rcx, rbx,
-                         Address::times_ptr, sizeof(ConstantPool)));
+  __ load_resolved_klass_at_index(rcx, rbx, rax);
 
   __ bind(resolved);
 
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -84,8 +84,6 @@
     cache       = type.getAddressField("_cache");
     poolHolder  = new MetadataField(type.getAddressField("_pool_holder"), 0);
     length      = new CIntField(type.getCIntegerField("_length"), 0);
-    resolvedReferences      = type.getAddressField("_resolved_references");
-    referenceMap = type.getAddressField("_reference_map");
     headerSize  = type.getSize();
     elementSize = 0;
     // fetch constants:
@@ -105,8 +103,6 @@
   private static AddressField cache;
   private static MetadataField poolHolder;
   private static CIntField length; // number of elements in oop
-  private static AddressField  resolvedReferences;
-  private static AddressField  referenceMap;
 
   private static long headerSize;
   private static long elementSize;
@@ -124,17 +120,11 @@
   public InstanceKlass     getPoolHolder() { return (InstanceKlass)poolHolder.getValue(this); }
   public int               getLength()     { return (int)length.getValue(getAddress()); }
   public Oop               getResolvedReferences() {
-    Address handle = resolvedReferences.getValue(getAddress());
-    if (handle != null) {
-      // Load through the handle
-      OopHandle refs = handle.getOopHandleAt(0);
-      return VM.getVM().getObjectHeap().newOop(refs);
-    }
-    return null;
+    return getCache().getResolvedReferences();
   }
 
   public U2Array referenceMap() {
-    return new U2Array(referenceMap.getValue(getAddress()));
+    return getCache().referenceMap();
   }
 
   public int objectToCPIndex(int index) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,6 +51,8 @@
     elementSize    = elType.getSize();
     length         = new CIntField(type.getCIntegerField("_length"), 0);
     intSize        = VM.getVM().getObjectHeap().getIntSize();
+    resolvedReferences = type.getAddressField("_resolved_references");
+    referenceMap   = type.getAddressField("_reference_map");
   }
 
   public ConstantPoolCache(Address addr) {
@@ -65,7 +67,8 @@
   private static long elementSize;
   private static CIntField length;
   private static long intSize;
-
+  private static AddressField  resolvedReferences;
+  private static AddressField  referenceMap;
 
   public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
 
@@ -100,4 +103,18 @@
         entry.iterateFields(visitor);
       }
     }
+
+  public Oop getResolvedReferences() {
+    Address handle = resolvedReferences.getValue(getAddress());
+    if (handle != null) {
+      // Load through the handle
+      OopHandle refs = handle.getOopHandleAt(0);
+      return VM.getVM().getObjectHeap().newOop(refs);
+    }
+    return null;
+  }
+
+  public U2Array referenceMap() {
+    return new U2Array(referenceMap.getValue(getAddress()));
+  }
 };
--- a/hotspot/src/share/vm/classfile/bytecodeAssembler.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/classfile/bytecodeAssembler.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,8 +64,8 @@
         cp->symbol_at_put(idx, entry._u.utf8);
         break;
       case BytecodeCPEntry::KLASS:
-        cp->unresolved_klass_at_put(
-            idx, cp->symbol_at(entry._u.klass));
+        cp->klass_index_at_put(
+            idx, entry._u.klass);
         break;
       case BytecodeCPEntry::STRING:
         cp->unresolved_string_at_put(
@@ -85,6 +85,9 @@
         ShouldNotReachHere();
     }
   }
+
+  cp->initialize_unresolved_klasses(_orig->pool_holder()->class_loader_data(),
+                                    CHECK_NULL);
   return cp;
 }
 
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -391,6 +391,7 @@
   }
 
   int index = 1;  // declared outside of loops for portability
+  int num_klasses = 0;
 
   // first verification pass - validate cross references
   // and fixup class and string constants
@@ -459,7 +460,7 @@
         check_property(valid_symbol_at(class_index),
           "Invalid constant pool index %u in class file %s",
           class_index, CHECK);
-        cp->unresolved_klass_at_put(index, cp->symbol_at(class_index));
+        cp->unresolved_klass_at_put(index, class_index, num_klasses++);
         break;
       }
       case JVM_CONSTANT_StringIndex: {
@@ -550,8 +551,19 @@
     } // switch(tag)
   } // end of for
 
+  _first_patched_klass_resolved_index = num_klasses;
+  cp->allocate_resolved_klasses(_loader_data, num_klasses + _max_num_patched_klasses, CHECK);
+
   if (_cp_patches != NULL) {
     // need to treat this_class specially...
+
+    // Add dummy utf8 entries in the space reserved for names of patched classes. We'll use "*"
+    // for now. These will be replaced with actual names of the patched classes in patch_class().
+    Symbol* s = vmSymbols::star_name();
+    for (int n=_orig_cp_size; n<cp->length(); n++) {
+      cp->symbol_at_put(n, s);
+    }
+
     int this_class_index;
     {
       stream->guarantee_more(8, CHECK);  // flags, this_class, super_class, infs_len
@@ -701,6 +713,14 @@
   }  // end of for
 }
 
+void ClassFileParser::patch_class(ConstantPool* cp, int class_index, Klass* k, Symbol* name) {
+  int name_index = _orig_cp_size + _num_patched_klasses;
+  int resolved_klass_index = _first_patched_klass_resolved_index + _num_patched_klasses;
+
+  cp->klass_at_put(class_index, name_index, resolved_klass_index, k, name);
+  _num_patched_klasses ++;
+}
+
 void ClassFileParser::patch_constant_pool(ConstantPool* cp,
                                           int index,
                                           Handle patch,
@@ -718,13 +738,14 @@
         guarantee_property(!java_lang_Class::is_primitive(patch()),
                            "Illegal class patch at %d in class file %s",
                            index, CHECK);
-        cp->klass_at_put(index, java_lang_Class::as_Klass(patch()));
+        Klass* k = java_lang_Class::as_Klass(patch());
+        patch_class(cp, index, k, k->name());
       } else {
         guarantee_property(java_lang_String::is_instance(patch()),
                            "Illegal class patch at %d in class file %s",
                            index, CHECK);
         Symbol* const name = java_lang_String::as_symbol(patch(), CHECK);
-        cp->unresolved_klass_at_put(index, name);
+        patch_class(cp, index, NULL, name);
       }
       break;
     }
@@ -5340,8 +5361,14 @@
   ik->set_name(_class_name);
 
   if (is_anonymous()) {
-    // I am well known to myself
-    ik->constants()->klass_at_put(_this_class_index, ik); // eagerly resolve
+    // _this_class_index is a CONSTANT_Class entry that refers to this
+    // anonymous class itself. If this class needs to refer to its own methods or
+    // fields, it would use a CONSTANT_MethodRef, etc, which would reference
+    // _this_class_index. However, because this class is anonymous (it's
+    // not stored in SystemDictionary), _this_class_index cannot be resolved
+    // with ConstantPool::klass_at_impl, which does a SystemDictionary lookup.
+    // Therefore, we must eagerly resolve _this_class_index now.
+    ik->constants()->klass_at_put(_this_class_index, ik);
   }
 
   ik->set_minor_version(_minor_version);
@@ -5577,6 +5604,10 @@
   _loader_data(loader_data),
   _host_klass(host_klass),
   _cp_patches(cp_patches),
+  _num_patched_klasses(0),
+  _max_num_patched_klasses(0),
+  _orig_cp_size(0),
+  _first_patched_klass_resolved_index(0),
   _super_klass(),
   _cp(NULL),
   _fields(NULL),
@@ -5647,6 +5678,25 @@
     _need_verify = Verifier::should_verify_for(_loader_data->class_loader(),
                                                stream->need_verify());
   }
+  if (_cp_patches != NULL) {
+    int len = _cp_patches->length();
+    for (int i=0; i<len; i++) {
+      if (has_cp_patch_at(i)) {
+        Handle patch = cp_patch_at(i);
+        if (java_lang_String::is_instance(patch()) || java_lang_Class::is_instance(patch())) {
+          // We need to append the names of the patched classes to the end of the constant pool,
+          // because a patched class may have a Utf8 name that's not already included in the
+          // original constant pool. These class names are used when patch_constant_pool()
+          // calls patch_class().
+          //
+          // Note that a String in cp_patch_at(i) may be used to patch a Utf8, a String, or a Class.
+          // At this point, we don't know the tag for index i yet, because we haven't parsed the
+          // constant pool. So we can only assume the worst -- every String is used to patch a Class.
+          _max_num_patched_klasses++;
+        }
+      }
+    }
+  }
 
   // synch back verification state to stream
   stream->set_verify(_need_verify);
@@ -5776,19 +5826,25 @@
   }
 
   stream->guarantee_more(3, CHECK); // length, first cp tag
-  const u2 cp_size = stream->get_u2_fast();
+  u2 cp_size = stream->get_u2_fast();
 
   guarantee_property(
     cp_size >= 1, "Illegal constant pool size %u in class file %s",
     cp_size, CHECK);
 
+  _orig_cp_size = cp_size;
+  if (int(cp_size) + _max_num_patched_klasses > 0xffff) {
+    THROW_MSG(vmSymbols::java_lang_InternalError(), "not enough space for patched classes");
+  }
+  cp_size += _max_num_patched_klasses;
+
   _cp = ConstantPool::allocate(_loader_data,
                                cp_size,
                                CHECK);
 
   ConstantPool* const cp = _cp;
 
-  parse_constant_pool(stream, cp, cp_size, CHECK);
+  parse_constant_pool(stream, cp, _orig_cp_size, CHECK);
 
   assert(cp_size == (const u2)cp->length(), "invariant");
 
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -81,6 +81,10 @@
   mutable ClassLoaderData* _loader_data;
   const InstanceKlass* _host_klass;
   GrowableArray<Handle>* _cp_patches; // overrides for CP entries
+  int _num_patched_klasses;
+  int _max_num_patched_klasses;
+  int _orig_cp_size;
+  int _first_patched_klass_resolved_index;
 
   // Metadata created before the instance klass is created.  Must be deallocated
   // if not transferred to the InstanceKlass upon successful class loading
@@ -434,6 +438,7 @@
     return patch;
   }
 
+  void patch_class(ConstantPool* cp, int class_index, Klass* k, Symbol* name);
   void patch_constant_pool(ConstantPool* cp,
                            int index,
                            Handle patch,
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2168,7 +2168,7 @@
         ConstantPool* constants = istate->method()->constants();
         if (!constants->tag_at(index).is_unresolved_klass()) {
           // Make sure klass is initialized and doesn't have a finalizer
-          Klass* entry = constants->slot_at(index).get_klass();
+          Klass* entry = constants->resolved_klass_at(index);
           InstanceKlass* ik = InstanceKlass::cast(entry);
           if (ik->is_initialized() && ik->can_be_fastpath_allocated() ) {
             size_t obj_size = ik->size_helper();
@@ -2268,7 +2268,7 @@
             if (METHOD->constants()->tag_at(index).is_unresolved_klass()) {
               CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception);
             }
-            Klass* klassOf = (Klass*) METHOD->constants()->slot_at(index).get_klass();
+            Klass* klassOf = (Klass*) METHOD->constants()->resolved_klass_at(index);
             Klass* objKlass = STACK_OBJECT(-1)->klass(); // ebx
             //
             // Check for compatibilty. This check must not GC!!
@@ -2303,7 +2303,7 @@
             if (METHOD->constants()->tag_at(index).is_unresolved_klass()) {
               CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception);
             }
-            Klass* klassOf = (Klass*) METHOD->constants()->slot_at(index).get_klass();
+            Klass* klassOf = (Klass*) METHOD->constants()->resolved_klass_at(index);
             Klass* objKlass = STACK_OBJECT(-1)->klass();
             //
             // Check for compatibilty. This check must not GC!!
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -94,11 +94,14 @@
                                   _invokedynamic_references_map, CHECK);
 
   // initialize object cache in constant pool
+  _pool->set_cache(cache);
+  cache->set_constant_pool(_pool());
+
+  // _resolved_references is stored in pool->cache(), so need to be done after
+  // the above lines.
   _pool->initialize_resolved_references(loader_data, _resolved_references_map,
                                         _resolved_reference_limit,
                                         CHECK);
-  _pool->set_cache(cache);
-  cache->set_constant_pool(_pool());
 }
 
 
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -35,8 +35,8 @@
 #define DEFAULT_SHARED_READ_WRITE_SIZE  (NOT_LP64(6*M) LP64_ONLY(10*M))
 #define MIN_SHARED_READ_WRITE_SIZE      (NOT_LP64(6*M) LP64_ONLY(10*M))
 
-#define DEFAULT_SHARED_READ_ONLY_SIZE   (NOT_LP64(6*M) LP64_ONLY(10*M))
-#define MIN_SHARED_READ_ONLY_SIZE       (NOT_LP64(6*M) LP64_ONLY(10*M))
+#define DEFAULT_SHARED_READ_ONLY_SIZE   (NOT_LP64(8*M) LP64_ONLY(13*M))
+#define MIN_SHARED_READ_ONLY_SIZE       (NOT_LP64(8*M) LP64_ONLY(13*M))
 
 // the MIN_SHARED_MISC_DATA_SIZE and MIN_SHARED_MISC_CODE_SIZE estimates are based on
 // the sizes required for dumping the archive using the default classlist. The sizes
@@ -61,8 +61,8 @@
 
 #define LargeSharedArchiveSize          (300*M)
 #define HugeSharedArchiveSize           (800*M)
-#define ReadOnlyRegionPercentage        0.4
-#define ReadWriteRegionPercentage       0.55
+#define ReadOnlyRegionPercentage        0.52
+#define ReadWriteRegionPercentage       0.43
 #define MiscDataRegionPercentage        0.03
 #define MiscCodeRegionPercentage        0.02
 #define LargeThresholdClassCount        5000
--- a/hotspot/src/share/vm/oops/constantPool.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/oops/constantPool.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -47,18 +47,9 @@
 #include "utilities/copy.hpp"
 
 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
-  // Tags are RW but comment below applies to tags also.
   Array<u1>* tags = MetadataFactory::new_writeable_array<u1>(loader_data, length, 0, CHECK_NULL);
-
   int size = ConstantPool::size(length);
-
-  // CDS considerations:
-  // Allocate read-write but may be able to move to read-only at dumping time
-  // if all the klasses are resolved.  The only other field that is writable is
-  // the resolved_references array, which is recreated at startup time.
-  // But that could be moved to InstanceKlass (although a pain to access from
-  // assembly code).  Maybe it could be moved to the cpCache which is RW.
-  return new (loader_data, size, false, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
+  return new (loader_data, size, true, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
 }
 
 #ifdef ASSERT
@@ -80,22 +71,26 @@
 
 ConstantPool::ConstantPool(Array<u1>* tags) :
   _tags(tags),
-  _length(tags->length()),
-  _flags(0) {
+  _length(tags->length()) {
 
     assert(_tags != NULL, "invariant");
     assert(tags->length() == _length, "invariant");
     assert(tag_array_is_zero_initialized(tags), "invariant");
-    assert(0 == _flags, "invariant");
+    assert(0 == flags(), "invariant");
     assert(0 == version(), "invariant");
     assert(NULL == _pool_holder, "invariant");
 }
 
 void ConstantPool::deallocate_contents(ClassLoaderData* loader_data) {
-  MetadataFactory::free_metadata(loader_data, cache());
-  set_cache(NULL);
-  MetadataFactory::free_array<u2>(loader_data, reference_map());
-  set_reference_map(NULL);
+  if (cache() != NULL) {
+    MetadataFactory::free_array<u2>(loader_data, reference_map());
+    set_reference_map(NULL);
+    MetadataFactory::free_metadata(loader_data, cache());
+    set_cache(NULL);
+  }
+
+  MetadataFactory::free_array<Klass*>(loader_data, resolved_klasses());
+  set_resolved_klasses(NULL);
 
   MetadataFactory::free_array<jushort>(loader_data, operands());
   set_operands(NULL);
@@ -113,7 +108,7 @@
 }
 
 objArrayOop ConstantPool::resolved_references() const {
-  return (objArrayOop)JNIHandles::resolve(_resolved_references);
+  return (objArrayOop)JNIHandles::resolve(_cache->resolved_references());
 }
 
 // Create resolved_references array and mapping array for original cp indexes
@@ -150,9 +145,82 @@
   }
 }
 
+void ConstantPool::allocate_resolved_klasses(ClassLoaderData* loader_data, int num_klasses, TRAPS) {
+  // A ConstantPool can't possibly have 0xffff valid class entries,
+  // because entry #0 must be CONSTANT_Invalid, and each class entry must refer to a UTF8
+  // entry for the class's name. So at most we will have 0xfffe class entries.
+  // This allows us to use 0xffff (ConstantPool::_temp_resolved_klass_index) to indicate
+  // UnresolvedKlass entries that are temporarily created during class redefinition.
+  assert(num_klasses < CPKlassSlot::_temp_resolved_klass_index, "sanity");
+  assert(resolved_klasses() == NULL, "sanity");
+  Array<Klass*>* rk = MetadataFactory::new_writeable_array<Klass*>(loader_data, num_klasses, CHECK);
+  set_resolved_klasses(rk);
+}
+
+void ConstantPool::initialize_unresolved_klasses(ClassLoaderData* loader_data, TRAPS) {
+  int len = length();
+  int num_klasses = 0;
+  for (int i = 1; i <len; i++) {
+    switch (tag_at(i).value()) {
+    case JVM_CONSTANT_ClassIndex:
+      {
+        const int class_index = klass_index_at(i);
+        unresolved_klass_at_put(i, class_index, num_klasses++);
+      }
+      break;
+#ifndef PRODUCT
+    case JVM_CONSTANT_Class:
+    case JVM_CONSTANT_UnresolvedClass:
+    case JVM_CONSTANT_UnresolvedClassInError:
+      // All of these should have been reverted back to ClassIndex before calling
+      // this function.
+      ShouldNotReachHere();
+#endif
+    }
+  }
+  allocate_resolved_klasses(loader_data, num_klasses, THREAD);
+}
+
+// Anonymous class support:
+void ConstantPool::klass_at_put(int class_index, int name_index, int resolved_klass_index, Klass* k, Symbol* name) {
+  assert(is_within_bounds(class_index), "index out of bounds");
+  assert(is_within_bounds(name_index), "index out of bounds");
+  assert((resolved_klass_index & 0xffff0000) == 0, "must be");
+  *int_at_addr(class_index) =
+    build_int_from_shorts((jushort)resolved_klass_index, (jushort)name_index);
+
+  symbol_at_put(name_index, name);
+  name->increment_refcount();
+  Klass** adr = resolved_klasses()->adr_at(resolved_klass_index);
+  OrderAccess::release_store_ptr((Klass* volatile *)adr, k);
+
+  // The interpreter assumes when the tag is stored, the klass is resolved
+  // and the Klass* non-NULL, so we need hardware store ordering here.
+  if (k != NULL) {
+    release_tag_at_put(class_index, JVM_CONSTANT_Class);
+  } else {
+    release_tag_at_put(class_index, JVM_CONSTANT_UnresolvedClass);
+  }
+}
+
+// Anonymous class support:
+void ConstantPool::klass_at_put(int class_index, Klass* k) {
+  assert(k != NULL, "must be valid klass");
+  CPKlassSlot kslot = klass_slot_at(class_index);
+  int resolved_klass_index = kslot.resolved_klass_index();
+  Klass** adr = resolved_klasses()->adr_at(resolved_klass_index);
+  OrderAccess::release_store_ptr((Klass* volatile *)adr, k);
+
+  // The interpreter assumes when the tag is stored, the klass is resolved
+  // and the Klass* non-NULL, so we need hardware store ordering here.
+  release_tag_at_put(class_index, JVM_CONSTANT_Class);
+}
+
 // CDS support. Create a new resolved_references array.
 void ConstantPool::restore_unshareable_info(TRAPS) {
   assert(is_constantPool(), "ensure C++ vtable is restored");
+  assert(on_stack(), "should always be set for shared constant pools");
+  assert(is_shared(), "should always be set for shared constant pools");
 
   // Only create the new resolved references array if it hasn't been attempted before
   if (resolved_references() != NULL) return;
@@ -180,6 +248,12 @@
   set_resolved_reference_length(
     resolved_references() != NULL ? resolved_references()->length() : 0);
   set_resolved_references(NULL);
+
+  // Shared ConstantPools are in the RO region, so the _flags cannot be modified.
+  // The _on_stack flag is used to prevent ConstantPools from deallocation during
+  // class redefinition. Since shared ConstantPools cannot be deallocated anyway,
+  // we always set _on_stack to true to avoid having to change _flags during runtime.
+  _flags |= (_on_stack | _is_shared);
 }
 
 int ConstantPool::cp_to_object_index(int cp_index) {
@@ -229,11 +303,14 @@
   // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
   // It is not safe to rely on the tag bit's here, since we don't have a lock, and
   // the entry and tag is not updated atomicly.
-  CPSlot entry = this_cp->slot_at(which);
-  if (entry.is_resolved()) {
-    assert(entry.get_klass()->is_klass(), "must be");
-    // Already resolved - return entry.
-    return entry.get_klass();
+  CPKlassSlot kslot = this_cp->klass_slot_at(which);
+  int resolved_klass_index = kslot.resolved_klass_index();
+  int name_index = kslot.name_index();
+  assert(this_cp->tag_at(name_index).is_symbol(), "sanity");
+
+  Klass* klass = this_cp->resolved_klasses()->at(resolved_klass_index);
+  if (klass != NULL) {
+    return klass;
   }
 
   // This tag doesn't change back to unresolved class unless at a safepoint.
@@ -251,7 +328,7 @@
   }
 
   Handle mirror_handle;
-  Symbol* name = entry.get_symbol();
+  Symbol* name = this_cp->symbol_at(name_index);
   Handle loader (THREAD, this_cp->pool_holder()->class_loader());
   Handle protection_domain (THREAD, this_cp->pool_holder()->protection_domain());
   Klass* k = SystemDictionary::resolve_or_fail(name, loader, protection_domain, true, THREAD);
@@ -270,10 +347,9 @@
       // If CHECK_NULL above doesn't return the exception, that means that
       // some other thread has beaten us and has resolved the class.
       // To preserve old behavior, we return the resolved class.
-      entry = this_cp->resolved_klass_at(which);
-      assert(entry.is_resolved(), "must be resolved if exception was cleared");
-      assert(entry.get_klass()->is_klass(), "must be resolved to a klass");
-      return entry.get_klass();
+      klass = this_cp->resolved_klasses()->at(resolved_klass_index);
+      assert(klass != NULL, "must be resolved if exception was cleared");
+      return klass;
     } else {
       return NULL;  // return the pending exception
     }
@@ -287,10 +363,13 @@
   if (log_is_enabled(Debug, class, resolve)){
     trace_class_resolution(this_cp, k);
   }
-  this_cp->klass_at_put(which, k);
-  entry = this_cp->resolved_klass_at(which);
-  assert(entry.is_resolved() && entry.get_klass()->is_klass(), "must be resolved at this point");
-  return entry.get_klass();
+  Klass** adr = this_cp->resolved_klasses()->adr_at(resolved_klass_index);
+  OrderAccess::release_store_ptr((Klass* volatile *)adr, k);
+  // The interpreter assumes when the tag is stored, the klass is resolved
+  // and the Klass* stored in _resolved_klasses is non-NULL, so we need
+  // hardware store ordering here.
+  this_cp->release_tag_at_put(which, JVM_CONSTANT_Class);
+  return k;
 }
 
 
@@ -299,14 +378,17 @@
 // instanceof operations. Returns NULL if the class has not been loaded or
 // if the verification of constant pool failed
 Klass* ConstantPool::klass_at_if_loaded(const constantPoolHandle& this_cp, int which) {
-  CPSlot entry = this_cp->slot_at(which);
-  if (entry.is_resolved()) {
-    assert(entry.get_klass()->is_klass(), "must be");
-    return entry.get_klass();
+  CPKlassSlot kslot = this_cp->klass_slot_at(which);
+  int resolved_klass_index = kslot.resolved_klass_index();
+  int name_index = kslot.name_index();
+  assert(this_cp->tag_at(name_index).is_symbol(), "sanity");
+
+  Klass* k = this_cp->resolved_klasses()->at(resolved_klass_index);
+  if (k != NULL) {
+    return k;
   } else {
-    assert(entry.is_unresolved(), "must be either symbol or klass");
     Thread *thread = Thread::current();
-    Symbol* name = entry.get_symbol();
+    Symbol* name = this_cp->symbol_at(name_index);
     oop loader = this_cp->pool_holder()->class_loader();
     oop protection_domain = this_cp->pool_holder()->protection_domain();
     Handle h_prot (thread, protection_domain);
@@ -484,22 +566,8 @@
   return klass_at(klass_ref_index_at(which), THREAD);
 }
 
-
 Symbol* ConstantPool::klass_name_at(int which) const {
-  assert(tag_at(which).is_unresolved_klass() || tag_at(which).is_klass(),
-         "Corrupted constant pool");
-  // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
-  // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
-  // tag is not updated atomicly.
-  CPSlot entry = slot_at(which);
-  if (entry.is_resolved()) {
-    // Already resolved - return entry's name.
-    assert(entry.get_klass()->is_klass(), "must be");
-    return entry.get_klass()->name();
-  } else {
-    assert(entry.is_unresolved(), "must be either symbol or klass");
-    return entry.get_symbol();
-  }
+  return symbol_at(klass_slot_at(which).name_index());
 }
 
 Symbol* ConstantPool::klass_ref_at_noresolve(int which) {
@@ -850,7 +918,7 @@
 
 // Iterate over symbols and decrement ones which are Symbol*s
 // This is done during GC.
-// Only decrement the UTF8 symbols. Unresolved classes and strings point to
+// Only decrement the UTF8 symbols. Strings point to
 // these symbols but didn't increment the reference count.
 void ConstantPool::unreference_symbols() {
   for (int index = 1; index < length(); index++) { // Index 0 is unused
@@ -1231,12 +1299,6 @@
 
   int tag = from_cp->tag_at(from_i).value();
   switch (tag) {
-  case JVM_CONSTANT_Class:
-  {
-    Klass* k = from_cp->klass_at(from_i, CHECK);
-    to_cp->klass_at_put(to_i, k);
-  } break;
-
   case JVM_CONSTANT_ClassIndex:
   {
     jint ki = from_cp->klass_index_at(from_i);
@@ -1305,18 +1367,14 @@
     to_cp->string_index_at_put(to_i, si);
   } break;
 
+  case JVM_CONSTANT_Class:
   case JVM_CONSTANT_UnresolvedClass:
   case JVM_CONSTANT_UnresolvedClassInError:
   {
-    // Can be resolved after checking tag, so check the slot first.
-    CPSlot entry = from_cp->slot_at(from_i);
-    if (entry.is_resolved()) {
-      assert(entry.get_klass()->is_klass(), "must be");
-      // Already resolved
-      to_cp->klass_at_put(to_i, entry.get_klass());
-    } else {
-      to_cp->unresolved_klass_at_put(to_i, entry.get_symbol());
-    }
+    // Revert to JVM_CONSTANT_ClassIndex
+    int name_index = from_cp->klass_slot_at(from_i).name_index();
+    assert(from_cp->tag_at(name_index).is_symbol(), "sanity");
+    to_cp->klass_index_at_put(to_i, name_index);
   } break;
 
   case JVM_CONSTANT_String:
@@ -1368,7 +1426,6 @@
   }
 } // end copy_entry_to()
 
-
 // Search constant pool search_cp for an entry that matches this
 // constant pool's entry at pattern_i. Returns the index of a
 // matching entry or zero (0) if there is no matching entry.
@@ -1824,12 +1881,15 @@
   if (value) {
     // Only record if it's not already set.
     if (!on_stack()) {
+      assert(!is_shared(), "should always be set for shared constant pools");
       _flags |= _on_stack;
       MetadataOnStackMark::record(this);
     }
   } else {
     // Clearing is done single-threadedly.
-    _flags &= ~_on_stack;
+    if (!is_shared()) {
+      _flags &= ~_on_stack;
+    }
   }
 }
 
@@ -1905,6 +1965,7 @@
   st->print_cr(" - cache: " INTPTR_FORMAT, p2i(cache()));
   st->print_cr(" - resolved_references: " INTPTR_FORMAT, p2i(resolved_references()));
   st->print_cr(" - reference_map: " INTPTR_FORMAT, p2i(reference_map()));
+  st->print_cr(" - resolved_klasses: " INTPTR_FORMAT, p2i(resolved_klasses()));
 
   for (int index = 1; index < length(); index++) {      // Index 0 is unused
     ((ConstantPool*)this)->print_entry_on(index, st);
@@ -1966,14 +2027,25 @@
     case JVM_CONSTANT_Utf8 :
       symbol_at(index)->print_value_on(st);
       break;
+    case JVM_CONSTANT_ClassIndex: {
+        int name_index = *int_at_addr(index);
+        st->print("klass_index=%d ", name_index);
+        symbol_at(name_index)->print_value_on(st);
+      }
+      break;
     case JVM_CONSTANT_UnresolvedClass :               // fall-through
     case JVM_CONSTANT_UnresolvedClassInError: {
-      CPSlot entry = slot_at(index);
-      if (entry.is_resolved()) {
-        entry.get_klass()->print_value_on(st);
-      } else {
-        entry.get_symbol()->print_value_on(st);
-      }
+        CPKlassSlot kslot = klass_slot_at(index);
+        int resolved_klass_index = kslot.resolved_klass_index();
+        int name_index = kslot.name_index();
+        assert(tag_at(name_index).is_symbol(), "sanity");
+
+        Klass* klass = resolved_klasses()->at(resolved_klass_index);
+        if (klass != NULL) {
+          klass->print_value_on(st);
+        } else {
+          symbol_at(name_index)->print_value_on(st);
+        }
       }
       break;
     case JVM_CONSTANT_MethodHandle :
@@ -2044,18 +2116,13 @@
   guarantee(is_constantPool(), "object must be constant pool");
   for (int i = 0; i< length();  i++) {
     constantTag tag = tag_at(i);
-    CPSlot entry = slot_at(i);
-    if (tag.is_klass()) {
-      if (entry.is_resolved()) {
-        guarantee(entry.get_klass()->is_klass(),    "should be klass");
-      }
-    } else if (tag.is_unresolved_klass()) {
-      if (entry.is_resolved()) {
-        guarantee(entry.get_klass()->is_klass(),    "should be klass");
-      }
+    if (tag.is_klass() || tag.is_unresolved_klass()) {
+      guarantee(klass_name_at(i)->refcount() != 0, "should have nonzero reference count");
     } else if (tag.is_symbol()) {
+      CPSlot entry = slot_at(i);
       guarantee(entry.get_symbol()->refcount() != 0, "should have nonzero reference count");
     } else if (tag.is_string()) {
+      CPSlot entry = slot_at(i);
       guarantee(entry.get_symbol()->refcount() != 0, "should have nonzero reference count");
     }
   }
--- a/hotspot/src/share/vm/oops/constantPool.hpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/oops/constantPool.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -46,27 +46,47 @@
 class SymbolHashMap;
 
 class CPSlot VALUE_OBJ_CLASS_SPEC {
+ friend class ConstantPool;
   intptr_t _ptr;
+  enum TagBits  {_pseudo_bit = 1};
  public:
-  enum TagBits  { _resolved_value = 0, _symbol_bit = 1, _pseudo_bit = 2, _symbol_mask = 3 };
 
   CPSlot(intptr_t ptr): _ptr(ptr) {}
-  CPSlot(Klass* ptr): _ptr((intptr_t)ptr) {}
-  CPSlot(Symbol* ptr): _ptr((intptr_t)ptr | _symbol_bit) {}
-  CPSlot(Symbol* ptr, int tag_bits): _ptr((intptr_t)ptr | tag_bits) {}
+  CPSlot(Symbol* ptr, int tag_bits = 0): _ptr((intptr_t)ptr | tag_bits) {}
 
   intptr_t value()   { return _ptr; }
-  bool is_resolved()      { return (_ptr & _symbol_bit ) == _resolved_value; }
-  bool is_unresolved()    { return (_ptr & _symbol_bit ) != _resolved_value; }
-  bool is_pseudo_string() { return (_ptr & _symbol_mask) == _symbol_bit + _pseudo_bit; }
+  bool is_pseudo_string() { return (_ptr & _pseudo_bit) != 0; }
 
   Symbol* get_symbol() {
-    assert(is_unresolved(), "bad call");
-    return (Symbol*)(_ptr & ~_symbol_mask);
+    return (Symbol*)(_ptr & ~_pseudo_bit);
   }
-  Klass* get_klass() {
-    assert(is_resolved(), "bad call");
-    return (Klass*)_ptr;
+};
+
+// This represents a JVM_CONSTANT_Class, JVM_CONSTANT_UnresolvedClass, or
+// JVM_CONSTANT_UnresolvedClassInError slot in the constant pool.
+class CPKlassSlot VALUE_OBJ_CLASS_SPEC {
+  // cp->symbol_at(_name_index) gives the name of the class.
+  int _name_index;
+
+  // cp->_resolved_klasses->at(_resolved_klass_index) gives the Klass* for the class.
+  int _resolved_klass_index;
+public:
+  enum {
+    // This is used during constant pool merging where the resolved klass index is
+    // not yet known, and will be computed at a later stage (during a call to
+    // initialize_unresolved_klasses()).
+    _temp_resolved_klass_index = 0xffff
+  };
+  CPKlassSlot(int n, int rk) {
+    _name_index = n;
+    _resolved_klass_index = rk;
+  }
+  int name_index() const {
+    return _name_index;
+  }
+  int resolved_klass_index() const {
+    assert(_resolved_klass_index != _temp_resolved_klass_index, "constant pool merging was incomplete");
+    return _resolved_klass_index;
   }
 };
 
@@ -83,14 +103,14 @@
   InstanceKlass*       _pool_holder; // the corresponding class
   Array<u2>*           _operands;    // for variable-sized (InvokeDynamic) nodes, usually empty
 
-  // 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;
+  // Consider using an array of compressed klass pointers to
+  // save space on 64-bit platforms.
+  Array<Klass*>*       _resolved_klasses;
 
   enum {
     _has_preresolution = 1,           // Flags
-    _on_stack          = 2
+    _on_stack          = 2,
+    _is_shared         = 4
   };
 
   int                  _flags;  // old fashioned bit twiddling
@@ -119,6 +139,7 @@
 
   CPSlot slot_at(int which) const {
     assert(is_within_bounds(which), "index out of bounds");
+    assert(!tag_at(which).is_unresolved_klass() && !tag_at(which).is_unresolved_klass_in_error(), "Corrupted constant pool");
     // Uses volatile because the klass slot changes without a lock.
     volatile intptr_t adr = (intptr_t)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which));
     assert(adr != 0 || which == 0, "cp entry for klass should not be zero");
@@ -166,7 +187,10 @@
   Array<u2>* operands() const               { return _operands; }
 
   bool has_preresolution() const            { return (_flags & _has_preresolution) != 0; }
-  void set_has_preresolution()              { _flags |= _has_preresolution; }
+  void set_has_preresolution() {
+    assert(!is_shared(), "should never be called on shared ConstantPools");
+    _flags |= _has_preresolution;
+  }
 
   // Redefine classes support.  If a method refering to this constant pool
   // is on the executing stack, or as a handle in vm code, this constant pool
@@ -175,6 +199,9 @@
   bool on_stack() const                      { return (_flags &_on_stack) != 0; }
   void set_on_stack(const bool value);
 
+  // Faster than MetaspaceObj::is_shared() - used by set_on_stack()
+  bool is_shared() const                     { return (_flags & _is_shared) != 0; }
+
   // Klass holding pool
   InstanceKlass* pool_holder() const      { return _pool_holder; }
   void set_pool_holder(InstanceKlass* k)  { _pool_holder = k; }
@@ -193,9 +220,14 @@
   // 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 object_to_cp_index(int index)         { return reference_map()->at(index); }
   int cp_to_object_index(int index);
 
+  void set_resolved_klasses(Array<Klass*>* rk)  { _resolved_klasses = rk; }
+  Array<Klass*>* resolved_klasses() const       { return _resolved_klasses; }
+  void allocate_resolved_klasses(ClassLoaderData* loader_data, int num_klasses, TRAPS);
+  void initialize_unresolved_klasses(ClassLoaderData* loader_data, TRAPS);
+
   // Invokedynamic indexes.
   // They must look completely different from normal indexes.
   // The main reason is that byte swapping is sometimes done on normal indexes.
@@ -223,30 +255,27 @@
   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); }
+  static int resolved_klasses_offset_in_bytes()    { return offset_of(ConstantPool, _resolved_klasses); }
 
   // Storing constants
 
-  void klass_at_put(int which, Klass* k) {
-    assert(k != NULL, "resolved class shouldn't be null");
-    assert(is_within_bounds(which), "index out of bounds");
-    OrderAccess::release_store_ptr((Klass* volatile *)obj_at_addr_raw(which), k);
-    // The interpreter assumes when the tag is stored, the klass is resolved
-    // and the Klass* is a klass rather than a Symbol*, so we need
-    // hardware store ordering here.
-    release_tag_at_put(which, JVM_CONSTANT_Class);
-  }
-
   // For temporary use while constructing constant pool
   void klass_index_at_put(int which, int name_index) {
     tag_at_put(which, JVM_CONSTANT_ClassIndex);
     *int_at_addr(which) = name_index;
   }
 
-  // Temporary until actual use
-  void unresolved_klass_at_put(int which, Symbol* s) {
+  // Anonymous class support:
+  void klass_at_put(int class_index, int name_index, int resolved_klass_index, Klass* k, Symbol* name);
+  void klass_at_put(int class_index, Klass* k);
+
+  void unresolved_klass_at_put(int which, int name_index, int resolved_klass_index) {
     release_tag_at_put(which, JVM_CONSTANT_UnresolvedClass);
-    slot_at_put(which, s);
+
+    assert((name_index & 0xffff0000) == 0, "must be");
+    assert((resolved_klass_index & 0xffff0000) == 0, "must be");
+    *int_at_addr(which) =
+      build_int_from_shorts((jushort)resolved_klass_index, (jushort)name_index);
   }
 
   void method_handle_index_at_put(int which, int ref_kind, int ref_index) {
@@ -266,7 +295,7 @@
 
   void unresolved_string_at_put(int which, Symbol* s) {
     release_tag_at_put(which, JVM_CONSTANT_String);
-    slot_at_put(which, CPSlot(s, CPSlot::_symbol_bit));
+    slot_at_put(which, CPSlot(s));
   }
 
   void int_at_put(int which, jint i) {
@@ -348,17 +377,38 @@
     return klass_at_impl(h_this, which, false, THREAD);
   }
 
+  CPKlassSlot klass_slot_at(int which) const {
+    assert(tag_at(which).is_unresolved_klass() || tag_at(which).is_klass(),
+           "Corrupted constant pool");
+    int value = *int_at_addr(which);
+    int name_index = extract_high_short_from_int(value);
+    int resolved_klass_index = extract_low_short_from_int(value);
+    return CPKlassSlot(name_index, resolved_klass_index);
+  }
+
   Symbol* klass_name_at(int which) const;  // Returns the name, w/o resolving.
+  int klass_name_index_at(int which) const {
+    return klass_slot_at(which).name_index();
+  }
 
   Klass* resolved_klass_at(int which) const {  // Used by Compiler
     guarantee(tag_at(which).is_klass(), "Corrupted constant pool");
     // Must do an acquire here in case another thread resolved the klass
     // behind our back, lest we later load stale values thru the oop.
-    return CPSlot((Klass*)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which))).get_klass();
+    CPKlassSlot kslot = klass_slot_at(which);
+    assert(tag_at(kslot.name_index()).is_symbol(), "sanity");
+
+    Klass** adr = resolved_klasses()->adr_at(kslot.resolved_klass_index());
+    return (Klass*)OrderAccess::load_ptr_acquire(adr);
   }
 
   // RedefineClasses() API support:
   Symbol* klass_at_noresolve(int which) { return klass_name_at(which); }
+  void temp_unresolved_klass_at_put(int which, int name_index) {
+    // Used only during constant pool merging for class redefinition. The resolved klass index
+    // will be initialized later by a call to initialize_unresolved_klasses().
+    unresolved_klass_at_put(which, name_index, CPKlassSlot::_temp_resolved_klass_index);
+  }
 
   jint int_at(int which) {
     assert(tag_at(which).is_int(), "Corrupted constant pool");
@@ -428,7 +478,7 @@
   void pseudo_string_at_put(int which, int obj_index, oop x) {
     assert(tag_at(which).is_string(), "Corrupted constant pool");
     Symbol* sym = unresolved_string_at(which);
-    slot_at_put(which, CPSlot(sym, (CPSlot::_symbol_bit | CPSlot::_pseudo_bit)));
+    slot_at_put(which, CPSlot(sym, CPSlot::_pseudo_bit));
     string_at_put(which, obj_index, x);    // this works just fine
   }
 
@@ -761,9 +811,9 @@
 
  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; }
+  void set_resolved_references(jobject s) { _cache->set_resolved_references(s); }
+  Array<u2>* reference_map() const        {  return (_cache == NULL) ? NULL :  _cache->reference_map(); }
+  void set_reference_map(Array<u2>* o)    { _cache->set_reference_map(o); }
 
   // patch JSR 292 resolved references after the class is linked.
   void patch_resolved_references(GrowableArray<Handle>* cp_patches);
--- a/hotspot/src/share/vm/oops/cpCache.hpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/oops/cpCache.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -404,6 +404,13 @@
   int             _length;
   ConstantPool*   _constant_pool;          // the corresponding constant pool
 
+  // The following fields need to be modified at runtime, so they cannot be
+  // stored in the ConstantPool, which is read-only.
+  // 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;
+
   // Sizing
   debug_only(friend class ClassVerifier;)
 
@@ -433,6 +440,15 @@
   bool is_constantPoolCache() const { return true; }
 
   int length() const                             { return _length; }
+
+  jobject resolved_references()           { return _resolved_references; }
+  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; }
+
+  // Assembly code support
+  static int resolved_references_offset_in_bytes() { return offset_of(ConstantPoolCache, _resolved_references); }
+
  private:
   void set_length(int length)                    { _length = length; }
 
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -292,12 +292,22 @@
     // entries in the input constant pool. We revert the appended copy
     // back to UnresolvedClass so that either verifier will be happy
     // with the constant pool entry.
+    //
+    // this is an indirect CP entry so it needs special handling
     case JVM_CONSTANT_Class:
+    case JVM_CONSTANT_UnresolvedClass:
     {
-      // revert the copy to JVM_CONSTANT_UnresolvedClass
-      (*merge_cp_p)->unresolved_klass_at_put(*merge_cp_length_p,
-        scratch_cp->klass_name_at(scratch_i));
-
+      int name_i = scratch_cp->klass_name_index_at(scratch_i);
+      int new_name_i = find_or_append_indirect_entry(scratch_cp, name_i, merge_cp_p,
+                                                     merge_cp_length_p, THREAD);
+
+      if (new_name_i != name_i) {
+        log_trace(redefine, class, constantpool)
+          ("Class entry@%d name_index change: %d to %d",
+           *merge_cp_length_p, name_i, new_name_i);
+      }
+
+      (*merge_cp_p)->temp_unresolved_klass_at_put(*merge_cp_length_p, new_name_i);
       if (scratch_i != *merge_cp_length_p) {
         // The new entry in *merge_cp_p is at a different index than
         // the new entry in scratch_cp so we need to map the index values.
@@ -330,10 +340,6 @@
     // This was an indirect CP entry, but it has been changed into
     // Symbol*s so this entry can be directly appended.
     case JVM_CONSTANT_String:      // fall through
-
-    // These were indirect CP entries, but they have been changed into
-    // Symbol*s so these entries can be directly appended.
-    case JVM_CONSTANT_UnresolvedClass:  // fall through
     {
       ConstantPool::copy_entry_to(scratch_cp, scratch_i, *merge_cp_p, *merge_cp_length_p,
         THREAD);
@@ -504,7 +510,7 @@
       (*merge_cp_length_p)++;
     } break;
 
-    // At this stage, Class or UnresolvedClass could be here, but not
+    // At this stage, Class or UnresolvedClass could be in scratch_cp, but not
     // ClassIndex
     case JVM_CONSTANT_ClassIndex: // fall through
 
@@ -1270,8 +1276,8 @@
         // revert the copy to JVM_CONSTANT_UnresolvedClass
         // May be resolving while calling this so do the same for
         // JVM_CONSTANT_UnresolvedClass (klass_name_at() deals with transition)
-        (*merge_cp_p)->unresolved_klass_at_put(old_i,
-          old_cp->klass_name_at(old_i));
+        (*merge_cp_p)->temp_unresolved_klass_at_put(old_i,
+          old_cp->klass_name_index_at(old_i));
         break;
 
       case JVM_CONSTANT_Double:
@@ -3102,6 +3108,7 @@
 
   // attach new constant pool to klass
   scratch_class->set_constants(scratch_cp());
+  scratch_cp->initialize_unresolved_klasses(loader_data, CHECK);
 
   int i;  // for portability
 
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -238,8 +238,8 @@
   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,           _resolved_references,                          jobject)                               \
+  nonstatic_field(ConstantPoolCache,           _reference_map,                                Array<u2>*)                            \
   nonstatic_field(ConstantPoolCache,           _length,                                       int)                                   \
   nonstatic_field(ConstantPoolCache,           _constant_pool,                                ConstantPool*)                         \
   volatile_nonstatic_field(InstanceKlass,      _array_klasses,                                Klass*)                                \
--- a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java	Wed May 03 02:32:02 2017 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java	Fri Mar 03 23:08:35 2017 -0800
@@ -128,7 +128,7 @@
 
         // test with sizes which just meet the minimum required sizes
         // the following tests also attempt to use the shared archive
-        new SharedSizeTestData(Region.RO, Platform.is64bit() ? "10M":"9M", Result.VALID_ARCHIVE),
+        new SharedSizeTestData(Region.RO, Platform.is64bit() ? "14M":"9M", Result.VALID_ARCHIVE),
         new SharedSizeTestData(Region.RW, Platform.is64bit() ? "12M":"7M", Result.VALID_ARCHIVE),
         new SharedSizeTestData(Region.MD, Platform.is64bit() ? "4M":"2M", Result.VALID_ARCHIVE),
         new SharedSizeTestData(Region.MC, "120k", Result.VALID_ARCHIVE),