Merge
authorgtriantafill
Tue, 01 Aug 2017 21:29:55 +0000
changeset 46737 3dcaaf68083e
parent 46736 66f3b9317681 (current diff)
parent 46734 e77c53775f4e (diff)
child 46738 d68a77b4ccc4
Merge
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/LoaderConstraintEntry.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/PlaceholderEntry.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/PlaceholderTable.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/ProtectionDomainCacheEntry.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/ProtectionDomainEntry.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/TwoOopHashtable.java
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad	Tue Aug 01 21:29:55 2017 +0000
@@ -5343,6 +5343,17 @@
   interface(CONST_INTER);
 %}
 
+// Shift values for add/sub extension shift
+operand immIExt()
+%{
+  predicate(0 <= n->get_int() && (n->get_int() <= 4));
+  match(ConI);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 operand immI_le_4()
 %{
   predicate(n->get_int() <= 4);
@@ -12789,7 +12800,7 @@
 %{
   match(Set dst (AddL src1 (ConvI2L src2)));
   ins_cost(INSN_COST);
-  format %{ "add  $dst, $src1, sxtw $src2" %}
+  format %{ "add  $dst, $src1, $src2, sxtw" %}
 
    ins_encode %{
      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -12802,7 +12813,7 @@
 %{
   match(Set dst (SubL src1 (ConvI2L src2)));
   ins_cost(INSN_COST);
-  format %{ "sub  $dst, $src1, sxtw $src2" %}
+  format %{ "sub  $dst, $src1, $src2, sxtw" %}
 
    ins_encode %{
      __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -12816,7 +12827,7 @@
 %{
   match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
   ins_cost(INSN_COST);
-  format %{ "add  $dst, $src1, sxth $src2" %}
+  format %{ "add  $dst, $src1, $src2, sxth" %}
 
    ins_encode %{
      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -12829,7 +12840,7 @@
 %{
   match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
   ins_cost(INSN_COST);
-  format %{ "add  $dst, $src1, sxtb $src2" %}
+  format %{ "add  $dst, $src1, $src2, sxtb" %}
 
    ins_encode %{
      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -12842,7 +12853,7 @@
 %{
   match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift)));
   ins_cost(INSN_COST);
-  format %{ "add  $dst, $src1, uxtb $src2" %}
+  format %{ "add  $dst, $src1, $src2, uxtb" %}
 
    ins_encode %{
      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -12855,7 +12866,7 @@
 %{
   match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
   ins_cost(INSN_COST);
-  format %{ "add  $dst, $src1, sxth $src2" %}
+  format %{ "add  $dst, $src1, $src2, sxth" %}
 
    ins_encode %{
      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -12868,7 +12879,7 @@
 %{
   match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
   ins_cost(INSN_COST);
-  format %{ "add  $dst, $src1, sxtw $src2" %}
+  format %{ "add  $dst, $src1, $src2, sxtw" %}
 
    ins_encode %{
      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -12881,7 +12892,7 @@
 %{
   match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
   ins_cost(INSN_COST);
-  format %{ "add  $dst, $src1, sxtb $src2" %}
+  format %{ "add  $dst, $src1, $src2, sxtb" %}
 
    ins_encode %{
      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -12894,7 +12905,7 @@
 %{
   match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift)));
   ins_cost(INSN_COST);
-  format %{ "add  $dst, $src1, uxtb $src2" %}
+  format %{ "add  $dst, $src1, $src2, uxtb" %}
 
    ins_encode %{
      __ add(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -13034,6 +13045,294 @@
   ins_pipe(ialu_reg_reg);
 %}
 
+
+instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
+%{
+  match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "add  $dst, $src1, $src2, sxtb #lshift2" %}
+
+   ins_encode %{
+     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
+%{
+  match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "add  $dst, $src1, $src2, sxth #lshift2" %}
+
+   ins_encode %{
+     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
+%{
+  match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "add  $dst, $src1, $src2, sxtw #lshift2" %}
+
+   ins_encode %{
+     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
+%{
+  match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "sub  $dst, $src1, $src2, sxtb #lshift2" %}
+
+   ins_encode %{
+     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
+%{
+  match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "sub  $dst, $src1, $src2, sxth #lshift2" %}
+
+   ins_encode %{
+     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
+%{
+  match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "sub  $dst, $src1, $src2, sxtw #lshift2" %}
+
+   ins_encode %{
+     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
+%{
+  match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "addw  $dst, $src1, $src2, sxtb #lshift2" %}
+
+   ins_encode %{
+     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
+%{
+  match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "addw  $dst, $src1, $src2, sxth #lshift2" %}
+
+   ins_encode %{
+     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
+%{
+  match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "subw  $dst, $src1, $src2, sxtb #lshift2" %}
+
+   ins_encode %{
+     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
+%{
+  match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "subw  $dst, $src1, $src2, sxth #lshift2" %}
+
+   ins_encode %{
+     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+
+instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "add  $dst, $src1, $src2, sxtw #lshift" %}
+
+   ins_encode %{
+     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%};
+
+instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "sub  $dst, $src1, $src2, sxtw #lshift" %}
+
+   ins_encode %{
+     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%};
+
+
+instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "add  $dst, $src1, $src2, uxtb #lshift" %}
+
+   ins_encode %{
+     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "add  $dst, $src1, $src2, uxth #lshift" %}
+
+   ins_encode %{
+     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "add  $dst, $src1, $src2, uxtw #lshift" %}
+
+   ins_encode %{
+     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "sub  $dst, $src1, $src2, uxtb #lshift" %}
+
+   ins_encode %{
+     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "sub  $dst, $src1, $src2, uxth #lshift" %}
+
+   ins_encode %{
+     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "sub  $dst, $src1, $src2, uxtw #lshift" %}
+
+   ins_encode %{
+     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "addw  $dst, $src1, $src2, uxtb #lshift" %}
+
+   ins_encode %{
+     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "addw  $dst, $src1, $src2, uxth #lshift" %}
+
+   ins_encode %{
+     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "subw  $dst, $src1, $src2, uxtb #lshift" %}
+
+   ins_encode %{
+     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
+
+instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "subw  $dst, $src1, $src2, uxth #lshift" %}
+
+   ins_encode %{
+     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}
 // END This section of the file is automatically generated. Do not edit --------------
 
 // ============================================================================
--- a/hotspot/src/cpu/aarch64/vm/aarch64_ad.m4	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/aarch64/vm/aarch64_ad.m4	Tue Aug 01 21:29:55 2017 +0000
@@ -268,21 +268,21 @@
   ins_pipe(ialu_reg_reg_vshift);
 %}')dnl
 define(ROL_INSN, `
-instruct $3$1_rReg_Var_C$2(iRegLNoSp dst, iRegL src, iRegI shift, immI$2 c$2, rFlagsReg cr)
+instruct $3$1_rReg_Var_C$2(iReg$1NoSp dst, iReg$1 src, iRegI shift, immI$2 c$2, rFlagsReg cr)
 %{
   match(Set dst (Or$1 (LShift$1 src shift) (URShift$1 src (SubI c$2 shift))));
 
   expand %{
-    $3L_rReg(dst, src, shift, cr);
+    $3$1_rReg(dst, src, shift, cr);
   %}
 %}')dnl
 define(ROR_INSN, `
-instruct $3$1_rReg_Var_C$2(iRegLNoSp dst, iRegL src, iRegI shift, immI$2 c$2, rFlagsReg cr)
+instruct $3$1_rReg_Var_C$2(iReg$1NoSp dst, iReg$1 src, iRegI shift, immI$2 c$2, rFlagsReg cr)
 %{
   match(Set dst (Or$1 (URShift$1 src shift) (LShift$1 src (SubI c$2 shift))));
 
   expand %{
-    $3L_rReg(dst, src, shift, cr);
+    $3$1_rReg(dst, src, shift, cr);
   %}
 %}')dnl
 ROL_EXPAND(L, rol, rorv)
@@ -305,7 +305,7 @@
 %{
   match(Set dst ($3$2 src1 (ConvI2L src2)));
   ins_cost(INSN_COST);
-  format %{ "$4  $dst, $src1, $5 $src2" %}
+  format %{ "$4  $dst, $src1, $src2, $5" %}
 
    ins_encode %{
      __ $4(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -321,7 +321,7 @@
 %{
   match(Set dst ($3$1 src1 EXTEND($1, $4, src2, lshift, rshift)));
   ins_cost(INSN_COST);
-  format %{ "$5  $dst, $src1, $6 $src2" %}
+  format %{ "$5  $dst, $src1, $src2, $6" %}
 
    ins_encode %{
      __ $5(as_Register($dst$$reg), as_Register($src1$$reg),
@@ -363,5 +363,82 @@
 ADD_SUB_ZERO_EXTEND(L,255,Sub,sub,uxtb)
 ADD_SUB_ZERO_EXTEND(L,65535,Sub,sub,uxth)
 ADD_SUB_ZERO_EXTEND(L,4294967295,Sub,sub,uxtw)
+dnl
+dnl ADD_SUB_ZERO_EXTEND_SHIFT(mode, size, add node, insn, ext type)
+define(`ADD_SUB_EXTENDED_SHIFT', `
+instruct $3Ext$1_$6_shift(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, immIExt lshift2, immI_`'eval($7-$2) lshift1, immI_`'eval($7-$2) rshift1, rFlagsReg cr)
+%{
+  match(Set dst ($3$1 src1 (LShift$1 EXTEND($1, $4, src2, lshift1, rshift1) lshift2)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "$5  $dst, $src1, $src2, $6 #lshift2" %}
 
+   ins_encode %{
+     __ $5(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::$6, ($lshift2$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}')
+dnl                   $1 $2 $3   $4   $5   $6  $7
+ADD_SUB_EXTENDED_SHIFT(L,8,Add,RShift,add,sxtb,64)
+ADD_SUB_EXTENDED_SHIFT(L,16,Add,RShift,add,sxth,64)
+ADD_SUB_EXTENDED_SHIFT(L,32,Add,RShift,add,sxtw,64)
+dnl
+ADD_SUB_EXTENDED_SHIFT(L,8,Sub,RShift,sub,sxtb,64)
+ADD_SUB_EXTENDED_SHIFT(L,16,Sub,RShift,sub,sxth,64)
+ADD_SUB_EXTENDED_SHIFT(L,32,Sub,RShift,sub,sxtw,64)
+dnl
+ADD_SUB_EXTENDED_SHIFT(I,8,Add,RShift,addw,sxtb,32)
+ADD_SUB_EXTENDED_SHIFT(I,16,Add,RShift,addw,sxth,32)
+dnl
+ADD_SUB_EXTENDED_SHIFT(I,8,Sub,RShift,subw,sxtb,32)
+ADD_SUB_EXTENDED_SHIFT(I,16,Sub,RShift,subw,sxth,32)
+dnl
+dnl ADD_SUB_CONV_SHIFT(mode, add node, insn, ext type)
+define(`ADD_SUB_CONV_SHIFT', `
+instruct $2ExtI_shift(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst ($2$1 src1 (LShiftL (ConvI2L src2) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "$3  $dst, $src1, $src2, $4 #lshift" %}
+
+   ins_encode %{
+     __ $3(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::$4, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}')
+dnl
+ADD_SUB_CONV_SHIFT(L,Add,add,sxtw);
+ADD_SUB_CONV_SHIFT(L,Sub,sub,sxtw);
+dnl
+dnl ADD_SUB_ZERO_EXTEND(mode, size, add node, insn, ext type)
+define(`ADD_SUB_ZERO_EXTEND_SHIFT', `
+instruct $3Ext$1_$5_and_shift(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, imm$1_$2 mask, immIExt lshift, rFlagsReg cr)
+%{
+  match(Set dst ($3$1 src1 (LShift$1 (And$1 src2 mask) lshift)));
+  ins_cost(1.9 * INSN_COST);
+  format %{ "$4  $dst, $src1, $src2, $5 #lshift" %}
+
+   ins_encode %{
+     __ $4(as_Register($dst$$reg), as_Register($src1$$reg),
+            as_Register($src2$$reg), ext::$5, ($lshift$$constant));
+   %}
+  ins_pipe(ialu_reg_reg_shift);
+%}')
+dnl
+dnl                       $1 $2  $3  $4  $5
+ADD_SUB_ZERO_EXTEND_SHIFT(L,255,Add,add,uxtb)
+ADD_SUB_ZERO_EXTEND_SHIFT(L,65535,Add,add,uxth)
+ADD_SUB_ZERO_EXTEND_SHIFT(L,4294967295,Add,add,uxtw)
+dnl
+ADD_SUB_ZERO_EXTEND_SHIFT(L,255,Sub,sub,uxtb)
+ADD_SUB_ZERO_EXTEND_SHIFT(L,65535,Sub,sub,uxth)
+ADD_SUB_ZERO_EXTEND_SHIFT(L,4294967295,Sub,sub,uxtw)
+dnl
+ADD_SUB_ZERO_EXTEND_SHIFT(I,255,Add,addw,uxtb)
+ADD_SUB_ZERO_EXTEND_SHIFT(I,65535,Add,addw,uxth)
+dnl
+ADD_SUB_ZERO_EXTEND_SHIFT(I,255,Sub,subw,uxtb)
+ADD_SUB_ZERO_EXTEND_SHIFT(I,65535,Sub,subw,uxth)
+dnl
 // END This section of the file is automatically generated. Do not edit --------------
--- a/hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -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.
  *
@@ -369,7 +369,7 @@
   }
 
  public:
-  SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
+  SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
     : NativeSignatureIterator(method)
   {
     _from = from;
--- a/hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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.
  *
@@ -47,7 +47,7 @@
 
  public:
   // Creation
-  SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+  SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
     _masm = new MacroAssembler(buffer);
     _num_int_args = (method->is_static() ? 1 : 0);
     _num_fp_args = 0;
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -169,6 +169,7 @@
 
   template<class T>
   inline void cmpw(Register Rd, T imm)  { subsw(zr, Rd, imm); }
+  // imm is limited to 12 bits.
   inline void cmp(Register Rd, unsigned imm)  { subs(zr, Rd, imm); }
 
   inline void cmnw(Register Rd, unsigned imm) { addsw(zr, Rd, imm); }
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1207,7 +1207,7 @@
 }
 
 static void verify_oop_args(MacroAssembler* masm,
-                            methodHandle method,
+                            const methodHandle& method,
                             const BasicType* sig_bt,
                             const VMRegPair* regs) {
   Register temp_reg = r19;  // not part of any compiled calling seq
@@ -1229,7 +1229,7 @@
 }
 
 static void gen_special_dispatch(MacroAssembler* masm,
-                                 methodHandle method,
+                                 const methodHandle& method,
                                  const BasicType* sig_bt,
                                  const VMRegPair* regs) {
   verify_oop_args(masm, method, sig_bt, regs);
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -764,7 +764,7 @@
       // alignment.
       Label small;
       int low_limit = MAX2(zva_length * 2, (int)BlockZeroingLowLimit);
-      __ cmp(cnt, low_limit >> 3);
+      __ subs(rscratch1, cnt, low_limit >> 3);
       __ br(Assembler::LT, small);
       __ zero_dcache_blocks(base, cnt);
       __ bind(small);
--- a/hotspot/src/cpu/arm/vm/interpreterRT_arm.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/arm/vm/interpreterRT_arm.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -422,7 +422,7 @@
 #endif // !__ABI_HARD__
 
  public:
-  SlowSignatureHandler(methodHandle method, address from, intptr_t* to) :
+  SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to) :
     NativeSignatureIterator(method) {
     _from = from;
 
--- a/hotspot/src/cpu/arm/vm/interpreterRT_arm.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/arm/vm/interpreterRT_arm.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -56,7 +56,7 @@
 #endif
  public:
   // Creation
-  SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+  SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
     _masm = new MacroAssembler(buffer);
     _abi_offset = 0;
     _ireg = is_static() ? 2 : 1;
--- a/hotspot/src/cpu/arm/vm/sharedRuntime_arm.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/arm/vm/sharedRuntime_arm.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1024,7 +1024,7 @@
 
 
 static void verify_oop_args(MacroAssembler* masm,
-                            methodHandle method,
+                            const methodHandle& method,
                             const BasicType* sig_bt,
                             const VMRegPair* regs) {
   Register temp_reg = Rmethod;  // not part of any compiled calling seq
@@ -1045,7 +1045,7 @@
 }
 
 static void gen_special_dispatch(MacroAssembler* masm,
-                                 methodHandle method,
+                                 const methodHandle& method,
                                  const BasicType* sig_bt,
                                  const VMRegPair* regs) {
   verify_oop_args(masm, method, sig_bt, regs);
--- a/hotspot/src/cpu/ppc/vm/interpreterRT_ppc.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/ppc/vm/interpreterRT_ppc.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2014 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -45,7 +45,7 @@
 
  public:
   // Creation
-  SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+  SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
     _masm = new MacroAssembler(buffer);
     _num_used_fp_arg_regs = 0;
   }
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1610,7 +1610,7 @@
 }
 
 static void verify_oop_args(MacroAssembler* masm,
-                            methodHandle method,
+                            const methodHandle& method,
                             const BasicType* sig_bt,
                             const VMRegPair* regs) {
   Register temp_reg = R19_method;  // not part of any compiled calling seq
@@ -1632,7 +1632,7 @@
 }
 
 static void gen_special_dispatch(MacroAssembler* masm,
-                                 methodHandle method,
+                                 const methodHandle& method,
                                  const BasicType* sig_bt,
                                  const VMRegPair* regs) {
   verify_oop_args(masm, method, sig_bt, regs);
--- a/hotspot/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1139,14 +1139,7 @@
   __ load_const_optimized(Z_R1_scratch, pp);
 
   // Pop the frame before the safepoint code.
-  int retPC_offset = initial_frame_size_in_bytes() + _z_abi16(return_pc);
-  if (Displacement::is_validDisp(retPC_offset)) {
-    __ z_lg(Z_R14, retPC_offset, Z_SP);
-    __ add2reg(Z_SP, initial_frame_size_in_bytes());
-  } else {
-    __ add2reg(Z_SP, initial_frame_size_in_bytes());
-    __ restore_return_pc();
-  }
+  __ pop_frame_restore_retPC(initial_frame_size_in_bytes());
 
   if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
     __ reserved_stack_check(Z_R14);
--- a/hotspot/src/cpu/s390/vm/c1_MacroAssembler_s390.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/s390/vm/c1_MacroAssembler_s390.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -70,7 +70,7 @@
   assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
   generate_stack_overflow_check(bang_size_in_bytes);
   save_return_pc();
-  push_frame(frame_size_in_bytes); // TODO: Must we add z_abi_160?
+  push_frame(frame_size_in_bytes);
 }
 
 void C1_MacroAssembler::unverified_entry(Register receiver, Register ic_klass) {
--- a/hotspot/src/cpu/s390/vm/interpreterRT_s390.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/s390/vm/interpreterRT_s390.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2016 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -51,7 +51,7 @@
 
  public:
   // creation
-  SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+  SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
     _masm = new MacroAssembler(buffer);
     _fp_arg_nr = 0;
   }
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -2022,17 +2022,41 @@
   z_stg(fp, _z_abi(callers_sp), Z_SP);
 }
 
-// Resize_frame with SP(new) = [addr].
-void MacroAssembler::resize_frame_absolute(Register addr, Register fp, bool load_fp) {
-  assert_different_registers(addr, fp, Z_SP);
-  if (load_fp) { z_lg(fp, _z_abi(callers_sp), Z_SP); }
-
-  if (addr != Z_R0) {
-    // Minimize stalls by not using Z_SP immediately after update.
-    z_stg(fp, _z_abi(callers_sp), addr);
-    z_lgr(Z_SP, addr);
+// Resize_frame with SP(new) = [newSP] + offset.
+//   This emitter is useful if we already have calculated a pointer
+//   into the to-be-allocated stack space, e.g. with special alignment properties,
+//   but need some additional space, e.g. for spilling.
+//   newSP    is the pre-calculated pointer. It must not be modified.
+//   fp       holds, or is filled with, the frame pointer.
+//   offset   is the additional increment which is added to addr to form the new SP.
+//            Note: specify a negative value to reserve more space!
+//   load_fp == true  only indicates that fp is not pre-filled with the frame pointer.
+//                    It does not guarantee that fp contains the frame pointer at the end.
+void MacroAssembler::resize_frame_abs_with_offset(Register newSP, Register fp, int offset, bool load_fp) {
+  assert_different_registers(newSP, fp, Z_SP);
+
+  if (load_fp) {
+    z_lg(fp, _z_abi(callers_sp), Z_SP);
+  }
+
+  add2reg(Z_SP, offset, newSP);
+  z_stg(fp, _z_abi(callers_sp), Z_SP);
+}
+
+// Resize_frame with SP(new) = [newSP].
+//   load_fp == true  only indicates that fp is not pre-filled with the frame pointer.
+//                    It does not guarantee that fp contains the frame pointer at the end.
+void MacroAssembler::resize_frame_absolute(Register newSP, Register fp, bool load_fp) {
+  assert_different_registers(newSP, fp, Z_SP);
+
+  if (load_fp) {
+    z_lg(fp, _z_abi(callers_sp), Z_SP); // need to use load/store.
+  }
+
+  z_lgr(Z_SP, newSP);
+  if (newSP != Z_R0) { // make sure we generate correct code, no matter what register newSP uses.
+    z_stg(fp, _z_abi(callers_sp), newSP);
   } else {
-    z_lgr(Z_SP, addr);
     z_stg(fp, _z_abi(callers_sp), Z_SP);
   }
 }
@@ -2040,17 +2064,12 @@
 // Resize_frame with SP(new) = SP(old) + offset.
 void MacroAssembler::resize_frame(RegisterOrConstant offset, Register fp, bool load_fp) {
   assert_different_registers(fp, Z_SP);
-  if (load_fp) z_lg(fp, _z_abi(callers_sp), Z_SP);
-
-  if (Displacement::is_validDisp((int)_z_abi(callers_sp) + offset.constant_or_zero())) {
-    // Minimize stalls by first using, then updating Z_SP.
-    // Do that only if we have a small positive offset or if ExtImm are available.
-    z_stg(fp, Address(Z_SP, offset, _z_abi(callers_sp)));
-    add64(Z_SP, offset);
-  } else {
-    add64(Z_SP, offset);
-    z_stg(fp, _z_abi(callers_sp), Z_SP);
-  }
+
+  if (load_fp) {
+    z_lg(fp, _z_abi(callers_sp), Z_SP);
+  }
+  add64(Z_SP, offset);
+  z_stg(fp, _z_abi(callers_sp), Z_SP);
 }
 
 void MacroAssembler::push_frame(Register bytes, Register old_sp, bool copy_sp, bool bytes_with_inverted_sign) {
@@ -2063,32 +2082,32 @@
 #endif
   if (copy_sp) { z_lgr(old_sp, Z_SP); }
   if (bytes_with_inverted_sign) {
-    z_stg(old_sp, 0, bytes, Z_SP);
-    add2reg_with_index(Z_SP, 0, bytes, Z_SP);
+    z_agr(Z_SP, bytes);
   } else {
     z_sgr(Z_SP, bytes); // Z_sgfr sufficient, but probably not faster.
-    z_stg(old_sp, 0, Z_SP);
-  }
+  }
+  z_stg(old_sp, _z_abi(callers_sp), Z_SP);
 }
 
 unsigned int MacroAssembler::push_frame(unsigned int bytes, Register scratch) {
   long offset = Assembler::align(bytes, frame::alignment_in_bytes);
-
-  if (Displacement::is_validDisp(-offset)) {
-    // Minimize stalls by first using, then updating Z_SP.
-    // Do that only if we have ExtImm available.
-    z_stg(Z_SP, -offset, Z_SP);
-    add2reg(Z_SP, -offset);
-  } else {
-    if (scratch != Z_R0 && scratch != Z_R1) {
-      z_stg(Z_SP, -offset, Z_SP);
-      add2reg(Z_SP, -offset);
-    } else {   // scratch == Z_R0 || scratch == Z_R1
-      z_lgr(scratch, Z_SP);
-      add2reg(Z_SP, -offset);
-      z_stg(scratch, 0, Z_SP);
-    }
-  }
+  assert(offset > 0, "should push a frame with positive size, size = %ld.", offset);
+  assert(Displacement::is_validDisp(-offset), "frame size out of range, size = %ld", offset);
+
+  // We must not write outside the current stack bounds (given by Z_SP).
+  // Thus, we have to first update Z_SP and then store the previous SP as stack linkage.
+  // We rely on Z_R0 by default to be available as scratch.
+  z_lgr(scratch, Z_SP);
+  add2reg(Z_SP, -offset);
+  z_stg(scratch, _z_abi(callers_sp), Z_SP);
+#ifdef ASSERT
+  // Just make sure nobody uses the value in the default scratch register.
+  // When another register is used, the caller might rely on it containing the frame pointer.
+  if (scratch == Z_R0) {
+    z_iihf(scratch, 0xbaadbabe);
+    z_iilf(scratch, 0xdeadbeef);
+  }
+#endif
   return offset;
 }
 
@@ -2106,6 +2125,20 @@
   Assembler::z_lg(Z_SP, _z_abi(callers_sp), Z_SP);
 }
 
+// Pop current C frame and restore return PC register (Z_R14).
+void MacroAssembler::pop_frame_restore_retPC(int frame_size_in_bytes) {
+  BLOCK_COMMENT("pop_frame_restore_retPC:");
+  int retPC_offset = _z_abi16(return_pc) + frame_size_in_bytes;
+  // If possible, pop frame by add instead of load (a penny saved is a penny got :-).
+  if (Displacement::is_validDisp(retPC_offset)) {
+    z_lg(Z_R14, retPC_offset, Z_SP);
+    add2reg(Z_SP, frame_size_in_bytes);
+  } else {
+    add2reg(Z_SP, frame_size_in_bytes);
+    restore_return_pc();
+  }
+}
+
 void MacroAssembler::call_VM_leaf_base(address entry_point, bool allow_relocation) {
   if (allow_relocation) {
     call_c(entry_point);
@@ -3485,6 +3518,17 @@
 // Purpose: record the previous value if it is not null.
 // All non-tmps are preserved.
 //------------------------------------------------------
+// Note: Rpre_val needs special attention.
+//   The flag pre_val_needed indicated that the caller of this emitter function
+//   relies on Rpre_val containing the correct value, that is:
+//     either the value it contained on entry to this code segment
+//     or the value that was loaded into the register from (Robj+offset).
+//
+//   Independent from this requirement, the contents of Rpre_val must survive
+//   the push_frame() operation. push_frame() uses Z_R0_scratch by default
+//   to temporarily remember the frame pointer.
+//   If Rpre_val is assigned Z_R0_scratch by the caller, code must be emitted to
+//   save it's value.
 void MacroAssembler::g1_write_barrier_pre(Register           Robj,
                                           RegisterOrConstant offset,
                                           Register           Rpre_val,      // Ideally, this is a non-volatile register.
@@ -3498,6 +3542,16 @@
   const int buffer_offset = in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_buf());
   const int index_offset  = in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_index());
   assert_different_registers(Rtmp1, Rtmp2, Z_R0_scratch); // None of the Rtmp<i> must be Z_R0!!
+  assert_different_registers(Robj, Z_R0_scratch);         // Used for addressing. Furthermore, push_frame destroys Z_R0!!
+  assert_different_registers(Rval, Z_R0_scratch);         // push_frame destroys Z_R0!!
+
+#ifdef ASSERT
+  // make sure the register is not Z_R0. Used for addressing. Furthermore, would be destroyed by push_frame.
+  if (offset.is_register() && offset.as_register()->encoding() == 0) {
+    tty->print_cr("Roffset(g1_write_barrier_pre)  = %%r%d", offset.as_register()->encoding());
+    assert(false, "bad register for offset");
+  }
+#endif
 
   BLOCK_COMMENT("g1_write_barrier_pre {");
 
@@ -3511,7 +3565,10 @@
   }
   z_bre(filtered); // Activity indicator is zero, so there is no marking going on currently.
 
-  // Do we need to load the previous value into Rpre_val?
+  assert(Rpre_val != noreg, "must have a real register");
+
+
+  // If an object is given, we need to load the previous value into Rpre_val.
   if (Robj != noreg) {
     // Load the previous value...
     Register ixReg = offset.is_register() ? offset.register_or_noreg() : Z_R0;
@@ -3521,9 +3578,9 @@
       z_lg(Rpre_val, offset.constant_or_zero(), ixReg, Robj);
     }
   }
-  assert(Rpre_val != noreg, "must have a real register");
 
   // Is the previous value NULL?
+  // If so, we don't need to record it and we're done.
   // Note: pre_val is loaded, decompressed and stored (directly or via runtime call).
   //       Register contents is preserved across runtime call if caller requests to do so.
   z_ltgr(Rpre_val, Rpre_val);
@@ -3540,6 +3597,7 @@
   // only if index > 0. Otherwise, we need runtime to handle.
   // (The index field is typed as size_t.)
   Register Rbuffer = Rtmp1, Rindex = Rtmp2;
+  assert_different_registers(Rbuffer, Rindex, Rpre_val);
 
   z_lg(Rbuffer, buffer_offset, Z_thread);
 
@@ -3558,16 +3616,8 @@
 
   bind(callRuntime);
 
-  // Save Rpre_val (result) over runtime call.
-  // Requires Rtmp1, Rtmp2, or Rpre_val to be non-volatile.
-  Register Rpre_save = Rpre_val;
-  if (pre_val_needed && Rpre_val->is_volatile()) {
-    guarantee(!Rtmp1->is_volatile() || !Rtmp2->is_volatile(), "oops!");
-    Rpre_save = !Rtmp1->is_volatile() ? Rtmp1 : Rtmp2;
-  }
-  lgr_if_needed(Rpre_save, Rpre_val);
-
-  // Preserve inputs by spilling them into the top frame.
+  // Save some registers (inputs and result) over runtime call
+  // by spilling them into the top frame.
   if (Robj != noreg && Robj->is_volatile()) {
     z_stg(Robj, Robj->encoding()*BytesPerWord, Z_SP);
   }
@@ -3579,11 +3629,20 @@
     z_stg(Rval, Rval->encoding()*BytesPerWord, Z_SP);
   }
 
+  // Save Rpre_val (result) over runtime call.
+  Register Rpre_save = Rpre_val;
+  if ((Rpre_val == Z_R0_scratch) || (pre_val_needed && Rpre_val->is_volatile())) {
+    guarantee(!Rtmp1->is_volatile() || !Rtmp2->is_volatile(), "oops!");
+    Rpre_save = !Rtmp1->is_volatile() ? Rtmp1 : Rtmp2;
+  }
+  lgr_if_needed(Rpre_save, Rpre_val);
+
   // Push frame to protect top frame with return pc and spilled register values.
   save_return_pc();
-  push_frame_abi160(0); // Will use Z_R0 as tmp on old CPUs.
-
-  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), Rpre_val, Z_thread);
+  push_frame_abi160(0); // Will use Z_R0 as tmp.
+
+  // Rpre_val may be destroyed by push_frame().
+  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), Rpre_save, Z_thread);
 
   pop_frame();
   restore_return_pc();
@@ -3599,9 +3658,9 @@
   if (Rval != noreg && Rval->is_volatile()) {
     z_lg(Rval, Rval->encoding()*BytesPerWord, Z_SP);
   }
-
-  // Restore Rpre_val (result) after runtime call.
-  lgr_if_needed(Rpre_val, Rpre_save);
+  if (pre_val_needed && Rpre_val->is_volatile()) {
+    lgr_if_needed(Rpre_val, Rpre_save);
+  }
 
   bind(filtered);
   BLOCK_COMMENT("} g1_write_barrier_pre");
@@ -3654,7 +3713,7 @@
   // calculate address of card
   load_const_optimized(Rbase, (address)bs->byte_map_base);        // Card table base.
   z_srlg(Rcard_addr, Rstore_addr, CardTableModRefBS::card_shift); // Index into card table.
-  add2reg_with_index(Rcard_addr, 0, Rcard_addr, Rbase);           // Explicit calculation needed for cli.
+  z_algr(Rcard_addr, Rbase);                                      // Explicit calculation needed for cli.
   Rbase = noreg; // end of lifetime
 
   // Filter young.
@@ -3698,6 +3757,7 @@
 
   // TODO: do we need a frame? Introduced to be on the safe side.
   bool needs_frame = true;
+  lgr_if_needed(Rcard_addr, Rcard_addr_x); // copy back asap. push_frame will destroy Z_R0_scratch!
 
   // VM call need frame to access(write) O register.
   if (needs_frame) {
@@ -3706,7 +3766,7 @@
   }
 
   // Save the live input values.
-  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), Rcard_addr_x, Z_thread);
+  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), Rcard_addr, Z_thread);
 
   if (needs_frame) {
     pop_frame();
@@ -4062,7 +4122,12 @@
 void MacroAssembler::store_klass_gap(Register s, Register d) {
   if (UseCompressedClassPointers) {
     assert(s != d, "not enough registers");
-    z_st(s, Address(d, oopDesc::klass_gap_offset_in_bytes()));
+    // Support s = noreg.
+    if (s != noreg) {
+      z_st(s, Address(d, oopDesc::klass_gap_offset_in_bytes()));
+    } else {
+      z_mvhi(Address(d, oopDesc::klass_gap_offset_in_bytes()), 0);
+    }
   }
 }
 
@@ -6621,11 +6686,12 @@
 
   BLOCK_COMMENT("verify_oop {");
   Register tmp = Z_R0;
-  unsigned int nbytes_save = 6 *8;
+  unsigned int nbytes_save = 5*BytesPerWord;
   address entry = StubRoutines::verify_oop_subroutine_entry_address();
+
   save_return_pc();
   push_frame_abi160(nbytes_save);
-  z_stmg(Z_R0, Z_R5, 160, Z_SP);
+  z_stmg(Z_R1, Z_R5, frame::z_abi_160_size, Z_SP);
 
   z_lgr(Z_ARG2, oop);
   load_const(Z_ARG1, (address) msg);
@@ -6633,10 +6699,10 @@
   z_lg(Z_R1, 0, Z_R1);
   call_c(Z_R1);
 
-  z_lmg(Z_R0, Z_R5, 160, Z_SP);
+  z_lmg(Z_R1, Z_R5, frame::z_abi_160_size, Z_SP);
   pop_frame();
-
   restore_return_pc();
+
   BLOCK_COMMENT("} verify_oop ");
 }
 
@@ -6658,8 +6724,8 @@
   // Setup arguments.
   load_const(Z_ARG1, (void*) stop_types[type%stop_end]);
   load_const(Z_ARG2, (void*) msg);
-  get_PC(Z_R14); // Following code pushes a frame without entering a new function. Use current pc as return address.
-  save_return_pc();    // Saves return pc Z_R14.
+  get_PC(Z_R14);     // Following code pushes a frame without entering a new function. Use current pc as return address.
+  save_return_pc();  // Saves return pc Z_R14.
   push_frame_abi160(0);
   call_VM_leaf(CAST_FROM_FN_PTR(address, stop_on_request), Z_ARG1, Z_ARG2);
   // The plain disassembler does not recognize illtrap. It instead displays
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -440,9 +440,21 @@
   // Get current PC + offset. Offset given in bytes, must be even!
   address get_PC(Register result, int64_t offset);
 
+  // Accessing, and in particular modifying, a stack location is only safe if
+  // the stack pointer (Z_SP) is set such that the accessed stack location is
+  // in the reserved range.
+  //
+  // From a performance point of view, it is desirable not to change the SP
+  // first and then immediately use it to access the freshly reserved space.
+  // That opens a small gap, though. If, just after storing some value (the
+  // frame pointer) into the to-be-reserved space, an interrupt is caught,
+  // the handler might use the space beyond Z_SP for it's own purpose.
+  // If that happens, the stored value might get altered.
+
   // Resize current frame either relatively wrt to current SP or absolute.
   void resize_frame_sub(Register offset, Register fp, bool load_fp=true);
-  void resize_frame_absolute(Register addr, Register fp, bool load_fp=true);
+  void resize_frame_abs_with_offset(Register newSP, Register fp, int offset, bool load_fp);
+  void resize_frame_absolute(Register addr, Register fp, bool load_fp);
   void resize_frame(RegisterOrConstant offset, Register fp, bool load_fp=true);
 
   // Push a frame of size bytes, if copy_sp is false, old_sp must already
@@ -461,6 +473,8 @@
 
   // Pop current C frame.
   void pop_frame();
+  // Pop current C frame and restore return PC register (Z_R14).
+  void pop_frame_restore_retPC(int frame_size_in_bytes);
 
   //
   // Calls
--- a/hotspot/src/cpu/s390/vm/s390.ad	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/s390/vm/s390.ad	Tue Aug 01 21:29:55 2017 +0000
@@ -1,6 +1,6 @@
 //
 // Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
-// Copyright (c) 2016 SAP SE. All rights reserved.
+// Copyright (c) 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
@@ -910,16 +910,8 @@
   bool need_polling = do_polling() && C->is_method_compilation();
 
   // Pop frame, restore return_pc, and all stuff needed by interpreter.
-  // Pop frame by add instead of load (a penny saved is a penny got :-).
   int frame_size_in_bytes = Assembler::align((C->frame_slots() << LogBytesPerInt), frame::alignment_in_bytes);
-  int retPC_offset        = frame_size_in_bytes + _z_abi16(return_pc);
-  if (Displacement::is_validDisp(retPC_offset)) {
-    __ z_lg(Z_R14, retPC_offset, Z_SP);
-    __ add2reg(Z_SP, frame_size_in_bytes);
-  } else {
-    __ add2reg(Z_SP, frame_size_in_bytes);
-    __ restore_return_pc();
-  }
+  __ pop_frame_restore_retPC(frame_size_in_bytes);
 
   if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
     __ reserved_stack_check(Z_R14);
--- a/hotspot/src/cpu/s390/vm/sharedRuntime_s390.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/s390/vm/sharedRuntime_s390.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -312,7 +312,13 @@
   __ save_return_pc(return_pc);
 
   // Push a new frame (includes stack linkage).
-  __ push_frame(frame_size_in_bytes);
+  // use return_pc as scratch for push_frame. Z_R0_scratch (the default) and Z_R1_scratch are
+  // illegally used to pass parameters (SAPJVM extension) by RangeCheckStub::emit_code().
+  __ push_frame(frame_size_in_bytes, return_pc);
+  // We have to restore return_pc right away.
+  // Nobody else will. Furthermore, return_pc isn't necessarily the default (Z_R14).
+  // Nobody else knows which register we saved.
+  __ z_lg(return_pc, _z_abi16(return_pc) + frame_size_in_bytes, Z_SP);
 
   // Register save area in new frame starts above z_abi_160 area.
   int offset = register_save_offset;
@@ -542,7 +548,6 @@
   }
 }
 
-#if INCLUDE_CDS
 size_t SharedRuntime::trampoline_size() {
   return MacroAssembler::load_const_size() + 2;
 }
@@ -552,7 +557,6 @@
   __ load_const(Z_R1_scratch, destination);
   __ z_br(Z_R1_scratch);
 }
-#endif
 
 // ---------------------------------------------------------------------------
 void SharedRuntime::save_native_result(MacroAssembler * masm,
--- a/hotspot/src/cpu/s390/vm/stubGenerator_s390.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/s390/vm/stubGenerator_s390.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -291,7 +291,7 @@
       // Restore frame pointer.
       __ z_lg(r_entryframe_fp, _z_abi(callers_sp), Z_SP);
       // Pop frame. Done here to minimize stalls.
-      __ z_lg(Z_SP, _z_abi(callers_sp), Z_SP);
+      __ pop_frame();
 
       // Reload some volatile registers which we've spilled before the call
       // to frame manager / native entry.
@@ -563,6 +563,9 @@
   address generate_throw_exception(const char* name, address runtime_entry,
                                    bool restore_saved_exception_pc,
                                    Register arg1 = noreg, Register arg2 = noreg) {
+    assert_different_registers(arg1, Z_R0_scratch);  // would be destroyed by push_frame()
+    assert_different_registers(arg2, Z_R0_scratch);  // would be destroyed by push_frame()
+
     int insts_size = 256;
     int locs_size  = 0;
     CodeBuffer      code(name, insts_size, locs_size);
@@ -693,11 +696,13 @@
     BarrierSet* const bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
       case BarrierSet::G1SATBCTLogging:
-        // With G1, don't generate the call if we statically know that the target in uninitialized.
+        // With G1, don't generate the call if we statically know that the target is uninitialized.
         if (!dest_uninitialized) {
           // Is marking active?
           Label filtered;
-          Register Rtmp1 = Z_R0;
+          assert_different_registers(addr,  Z_R0_scratch);  // would be destroyed by push_frame()
+          assert_different_registers(count, Z_R0_scratch);  // would be destroyed by push_frame()
+          Register Rtmp1 = Z_R0_scratch;
           const int active_offset = in_bytes(JavaThread::satb_mark_queue_offset() +
                                              SATBMarkQueue::byte_offset_of_active());
           if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
@@ -708,11 +713,11 @@
           }
           __ z_bre(filtered); // Activity indicator is zero, so there is no marking going on currently.
 
-          // __ push_frame_abi160(0);
+          // __ push_frame_abi160(0);  // implicitly done in save_live_registers()
           (void) RegisterSaver::save_live_registers(_masm, RegisterSaver::arg_registers);
           __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), addr, count);
           (void) RegisterSaver::restore_live_registers(_masm, RegisterSaver::arg_registers);
-          // __ pop_frame();
+          // __ pop_frame();  // implicitly done in restore_live_registers()
 
           __ bind(filtered);
         }
@@ -739,16 +744,18 @@
       case BarrierSet::G1SATBCTLogging:
         {
           if (branchToEnd) {
-            // __ push_frame_abi160(0);
+            assert_different_registers(addr,  Z_R0_scratch);  // would be destroyed by push_frame()
+            assert_different_registers(count, Z_R0_scratch);  // would be destroyed by push_frame()
+            // __ push_frame_abi160(0);  // implicitly done in save_live_registers()
             (void) RegisterSaver::save_live_registers(_masm, RegisterSaver::arg_registers);
             __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count);
             (void) RegisterSaver::restore_live_registers(_masm, RegisterSaver::arg_registers);
-            // __ pop_frame();
+            // __ pop_frame();   // implicitly done in restore_live_registers()
           } else {
             // Tail call: call c and return to stub caller.
             address entry_point = CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post);
-            if (Z_ARG1 != addr) __ z_lgr(Z_ARG1, addr);
-            if (Z_ARG2 != count) __ z_lgr(Z_ARG2, count);
+            __ lgr_if_needed(Z_ARG1, addr);
+            __ lgr_if_needed(Z_ARG2, count);
             __ load_const(Z_R1, entry_point);
             __ z_br(Z_R1); // Branch without linking, callee will return to stub caller.
           }
@@ -1676,8 +1683,8 @@
   //   src    must designate an even/odd register pair, holding the address/length of the original message
 
   // Helper function which generates code to
-  //  - load the function code in register fCode (== Z_R0)
-  //  - load the data block length (depends on cipher function) in register srclen if requested.
+  //  - load the function code in register fCode (== Z_R0).
+  //  - load the data block length (depends on cipher function) into register srclen if requested.
   //  - is_decipher switches between cipher/decipher function codes
   //  - set_len requests (if true) loading the data block length in register srclen
   void generate_load_AES_fCode(Register keylen, Register fCode, Register srclen, bool is_decipher) {
@@ -1688,12 +1695,13 @@
       bool  identical_dataBlk_len =  (VM_Version::Cipher::_AES128_dataBlk == VM_Version::Cipher::_AES192_dataBlk)
                                   && (VM_Version::Cipher::_AES128_dataBlk == VM_Version::Cipher::_AES256_dataBlk);
       // Expanded key length is 44/52/60 * 4 bytes for AES-128/AES-192/AES-256.
-      __ z_cghi(keylen, 52);
-      __ z_lghi(fCode, VM_Version::Cipher::_AES256 + mode);
+      __ z_cghi(keylen, 52); // Check only once at the beginning. keylen and fCode may share the same register.
+
+      __ z_lghi(fCode, VM_Version::Cipher::_AES128 + mode);
       if (!identical_dataBlk_len) {
-        __ z_lghi(srclen, VM_Version::Cipher::_AES256_dataBlk);
+        __ z_lghi(srclen, VM_Version::Cipher::_AES128_dataBlk);
       }
-      __ z_brh(fCode_set);  // keyLen >  52: AES256
+      __ z_brl(fCode_set);  // keyLen <  52: AES128
 
       __ z_lghi(fCode, VM_Version::Cipher::_AES192 + mode);
       if (!identical_dataBlk_len) {
@@ -1701,11 +1709,12 @@
       }
       __ z_bre(fCode_set);  // keyLen == 52: AES192
 
-      __ z_lghi(fCode, VM_Version::Cipher::_AES128 + mode);
+      __ z_lghi(fCode, VM_Version::Cipher::_AES256 + mode);
       if (!identical_dataBlk_len) {
-        __ z_lghi(srclen, VM_Version::Cipher::_AES128_dataBlk);
+        __ z_lghi(srclen, VM_Version::Cipher::_AES256_dataBlk);
       }
-      // __ z_brl(fCode_set);  // keyLen <  52: AES128           // fallthru
+      // __ z_brh(fCode_set);  // keyLen <  52: AES128           // fallthru
+
       __ bind(fCode_set);
       if (identical_dataBlk_len) {
         __ z_lghi(srclen, VM_Version::Cipher::_AES128_dataBlk);
@@ -1715,6 +1724,54 @@
   }
 
   // Push a parameter block for the cipher/decipher instruction on the stack.
+  // Layout of the additional stack space allocated for AES_cipherBlockChaining:
+  //
+  //   |        |
+  //   +--------+ <-- SP before expansion
+  //   |        |
+  //   :        :  alignment loss, 0..(AES_parmBlk_align-8) bytes
+  //   |        |
+  //   +--------+
+  //   |        |
+  //   :        :  space for parameter block, size VM_Version::Cipher::_AES*_parmBlk_C
+  //   |        |
+  //   +--------+ <-- parmBlk, octoword-aligned, start of parameter block
+  //   |        |
+  //   :        :  additional stack space for spills etc., size AES_parmBlk_addspace, DW @ Z_SP not usable!!!
+  //   |        |
+  //   +--------+ <-- Z_SP after expansion
+
+  void generate_push_Block(int dataBlk_len, int parmBlk_len, int crypto_fCode,
+                           Register parmBlk, Register keylen, Register fCode, Register cv, Register key) {
+    const int AES_parmBlk_align    = 32;  // octoword alignment.
+    const int AES_parmBlk_addspace = 24;  // Must be sufficiently large to hold all spilled registers
+                                          // (currently 2) PLUS 1 DW for the frame pointer.
+
+    const int cv_len     = dataBlk_len;
+    const int key_len    = parmBlk_len - cv_len;
+    // This len must be known at JIT compile time. Only then are we able to recalc the SP before resize.
+    // We buy this knowledge by wasting some (up to AES_parmBlk_align) bytes of stack space.
+    const int resize_len = cv_len + key_len + AES_parmBlk_align + AES_parmBlk_addspace;
+
+    // Use parmBlk as temp reg here to hold the frame pointer.
+    __ resize_frame(-resize_len, parmBlk, true);
+
+    // calculate parmBlk address from updated (resized) SP.
+    __ add2reg(parmBlk, resize_len - (cv_len + key_len), Z_SP);
+    __ z_nill(parmBlk, (~(AES_parmBlk_align-1)) & 0xffff); // Align parameter block.
+
+    // There is room for stuff in the range [parmBlk-AES_parmBlk_addspace+8, parmBlk).
+    __ z_stg(keylen,  -8, parmBlk);                        // Spill keylen for later use.
+
+    // calculate (SP before resize) from updated SP.
+    __ add2reg(keylen, resize_len, Z_SP);                  // keylen holds prev SP for now.
+    __ z_stg(keylen, -16, parmBlk);                        // Spill prev SP for easy revert.
+
+    __ z_mvc(0,      cv_len-1,  parmBlk, 0, cv);     // Copy cv.
+    __ z_mvc(cv_len, key_len-1, parmBlk, 0, key);    // Copy key.
+    __ z_lghi(fCode, crypto_fCode);
+  }
+
   // NOTE:
   //   Before returning, the stub has to copy the chaining value from
   //   the parmBlk, where it was updated by the crypto instruction, back
@@ -1723,17 +1780,14 @@
   //   the key length across the KMC instruction. We do so by spilling it to the stack,
   //   just preceding the parmBlk (at (parmBlk - 8)).
   void generate_push_parmBlk(Register keylen, Register fCode, Register parmBlk, Register key, Register cv, bool is_decipher) {
-    const int AES_parmBlk_align    = 32;
-    const int AES_parmBlk_addspace = AES_parmBlk_align; // Must be multiple of AES_parmblk_align.
-    int       cv_len, key_len;
     int       mode = is_decipher ? VM_Version::CipherMode::decipher : VM_Version::CipherMode::cipher;
     Label     parmBlk_128, parmBlk_192, parmBlk_256, parmBlk_set;
 
     BLOCK_COMMENT("push parmBlk {");
     if (VM_Version::has_Crypto_AES()   ) { __ z_cghi(keylen, 52); }
-    if (VM_Version::has_Crypto_AES256()) { __ z_brh(parmBlk_256); }  // keyLen >  52: AES256
+    if (VM_Version::has_Crypto_AES128()) { __ z_brl(parmBlk_128); }  // keyLen <  52: AES128
     if (VM_Version::has_Crypto_AES192()) { __ z_bre(parmBlk_192); }  // keyLen == 52: AES192
-    if (VM_Version::has_Crypto_AES128()) { __ z_brl(parmBlk_128); }  // keyLen <  52: AES128
+    if (VM_Version::has_Crypto_AES256()) { __ z_brh(parmBlk_256); }  // keyLen >  52: AES256
 
     // Security net: requested AES function not available on this CPU.
     // NOTE:
@@ -1742,71 +1796,35 @@
     //   at all, we have at least AES-128.
     __ stop_static("AES key strength not supported by CPU. Use -XX:-UseAES as remedy.", 0);
 
-    if (VM_Version::has_Crypto_AES128()) {
-      __ bind(parmBlk_128);
-      cv_len  = VM_Version::Cipher::_AES128_dataBlk;
-      key_len = VM_Version::Cipher::_AES128_parmBlk_C - cv_len;
-      __ z_lay(parmBlk, -(VM_Version::Cipher::_AES128_parmBlk_C+AES_parmBlk_align)+(AES_parmBlk_align-1), Z_SP);
-      __ z_nill(parmBlk, (~(AES_parmBlk_align-1)) & 0xffff);  // align parameter block
-
-      // Resize the frame to accommodate for the aligned parameter block and other stuff.
-      // There is room for stuff in the range [parmBlk-AES_parmBlk_addspace, parmBlk).
-      __ z_stg(keylen, -8, parmBlk);                   // Spill keylen for later use.
-      __ z_stg(Z_SP,  -16, parmBlk);                   // Spill SP for easy revert.
-      __ z_aghi(parmBlk, -AES_parmBlk_addspace);       // Additional space for keylen, etc..
-      __ resize_frame_absolute(parmBlk, keylen, true); // Resize frame with parmBlk being the new SP.
-      __ z_aghi(parmBlk,  AES_parmBlk_addspace);       // Restore parameter block address.
-
-      __ z_mvc(0,      cv_len-1,  parmBlk, 0, cv);     // Copy cv.
-      __ z_mvc(cv_len, key_len-1, parmBlk, 0, key);    // Copy key.
-      __ z_lghi(fCode, VM_Version::Cipher::_AES128 + mode);
-      if (VM_Version::has_Crypto_AES192() || VM_Version::has_Crypto_AES256()) {
+    if (VM_Version::has_Crypto_AES256()) {
+      __ bind(parmBlk_256);
+      generate_push_Block(VM_Version::Cipher::_AES256_dataBlk,
+                          VM_Version::Cipher::_AES256_parmBlk_C,
+                          VM_Version::Cipher::_AES256 + mode,
+                          parmBlk, keylen, fCode, cv, key);
+      if (VM_Version::has_Crypto_AES128() || VM_Version::has_Crypto_AES192()) {
         __ z_bru(parmBlk_set);  // Fallthru otherwise.
       }
     }
 
     if (VM_Version::has_Crypto_AES192()) {
       __ bind(parmBlk_192);
-      cv_len  = VM_Version::Cipher::_AES192_dataBlk;
-      key_len = VM_Version::Cipher::_AES192_parmBlk_C - cv_len;
-      __ z_lay(parmBlk, -(VM_Version::Cipher::_AES192_parmBlk_C+AES_parmBlk_align)+(AES_parmBlk_align-1), Z_SP);
-      __ z_nill(parmBlk, (~(AES_parmBlk_align-1)) & 0xffff);  // Align parameter block.
-
-      // Resize the frame to accommodate for the aligned parameter block and other stuff.
-      // There is room for stuff in the range [parmBlk-AES_parmBlk_addspace, parmBlk).
-      __ z_stg(keylen, -8, parmBlk);                   // Spill keylen for later use.
-      __ z_stg(Z_SP,  -16, parmBlk);                   // Spill SP for easy revert.
-      __ z_aghi(parmBlk, -AES_parmBlk_addspace);       // Additional space for keylen, etc..
-      __ resize_frame_absolute(parmBlk, keylen, true); // Resize frame with parmBlk being the new SP.
-      __ z_aghi(parmBlk, AES_parmBlk_addspace);        // Restore parameter block address.
-
-      __ z_mvc(0,      cv_len-1,  parmBlk, 0, cv);     // Copy cv.
-      __ z_mvc(cv_len, key_len-1, parmBlk, 0, key);    // Copy key.
-      __ z_lghi(fCode,    VM_Version::Cipher::_AES192 + mode);
-      if (VM_Version::has_Crypto_AES256()) {
+      generate_push_Block(VM_Version::Cipher::_AES192_dataBlk,
+                          VM_Version::Cipher::_AES192_parmBlk_C,
+                          VM_Version::Cipher::_AES192 + mode,
+                          parmBlk, keylen, fCode, cv, key);
+      if (VM_Version::has_Crypto_AES128()) {
         __ z_bru(parmBlk_set);  // Fallthru otherwise.
       }
     }
 
-    if (VM_Version::has_Crypto_AES256()) {
-      __ bind(parmBlk_256);
-      cv_len  = VM_Version::Cipher::_AES256_dataBlk;
-      key_len = VM_Version::Cipher::_AES256_parmBlk_C - cv_len;
-      __ z_lay(parmBlk, -(VM_Version::Cipher::_AES256_parmBlk_C+AES_parmBlk_align)+(AES_parmBlk_align-1), Z_SP);
-      __ z_nill(parmBlk, (~(AES_parmBlk_align-1)) & 0xffff);  // Align parameter block.
-
-      // Resize the frame to accommodate for the aligned parameter block and other stuff.
-      // There is room for stuff in the range [parmBlk-AES_parmBlk_addspace, parmBlk).
-      __ z_stg(keylen, -8, parmBlk);                   // Spill keylen for later use.
-      __ z_stg(Z_SP,  -16, parmBlk);                   // Spill SP for easy revert.
-      __ z_aghi(parmBlk, -AES_parmBlk_addspace);       // Additional space for keylen, etc..
-      __ resize_frame_absolute(parmBlk, keylen, true); // Resize frame with parmBlk being the new SP.
-      __ z_aghi(parmBlk,  AES_parmBlk_addspace);       // Restore parameter block address.
-
-      __ z_mvc(0,      cv_len-1,  parmBlk, 0, cv);     // Copy cv.
-      __ z_mvc(cv_len, key_len-1, parmBlk, 0, key);    // Copy key.
-      __ z_lghi(fCode, VM_Version::Cipher::_AES256 + mode);
-      // __ z_bru(parmBlk_set);  // fallthru
+    if (VM_Version::has_Crypto_AES128()) {
+      __ bind(parmBlk_128);
+      generate_push_Block(VM_Version::Cipher::_AES128_dataBlk,
+                          VM_Version::Cipher::_AES128_parmBlk_C,
+                          VM_Version::Cipher::_AES128 + mode,
+                          parmBlk, keylen, fCode, cv, key);
+      // Fallthru
     }
 
     __ bind(parmBlk_set);
@@ -1862,41 +1880,49 @@
       }
       __ bind(parmBlk_set);
     }
-    __ z_lg(Z_SP, -16, parmBlk); // Revert resize_frame_absolute.
+    __ z_lg(Z_SP, -16, parmBlk); // Revert resize_frame_absolute. Z_SP saved by push_parmBlk.
     BLOCK_COMMENT("} pop parmBlk");
   }
 
+  // Compute AES encrypt/decrypt function.
+  void generate_AES_cipherBlock(bool is_decipher) {
+    // Incoming arguments.
+    Register       from    = Z_ARG1; // source byte array
+    Register       to      = Z_ARG2; // destination byte array
+    Register       key     = Z_ARG3; // expanded key array
+
+    const Register keylen  = Z_R0;   // Temporarily (until fCode is set) holds the expanded key array length.
+
+    // Register definitions as required by KM instruction.
+    const Register fCode   = Z_R0;   // crypto function code
+    const Register parmBlk = Z_R1;   // parameter block address (points to crypto key)
+    const Register src     = Z_ARG1; // Must be even reg (KM requirement).
+    const Register srclen  = Z_ARG2; // Must be odd reg and pair with src. Overwrites destination address.
+    const Register dst     = Z_ARG3; // Must be even reg (KM requirement). Overwrites expanded key address.
+
+    // Read key len of expanded key (in 4-byte words).
+    __ z_lgf(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
+
+    // Copy arguments to registers as required by crypto instruction.
+    __ z_lgr(parmBlk, key);          // crypto key (in T_INT array).
+    __ lgr_if_needed(src, from);     // Copy src address. Will not emit, src/from are identical.
+    __ z_lgr(dst, to);               // Copy dst address, even register required.
+
+    // Construct function code into fCode(Z_R0), data block length into srclen(Z_ARG2).
+    generate_load_AES_fCode(keylen, fCode, srclen, is_decipher);
+
+    __ km(dst, src);                 // Cipher the message.
+
+    __ z_br(Z_R14);
+  }
+
   // Compute AES encrypt function.
   address generate_AES_encryptBlock(const char* name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
-    unsigned int   start_off = __ offset();  // Remember stub start address (is rtn value).
-
-    Register       from    = Z_ARG1; // source byte array
-    Register       to      = Z_ARG2; // destination byte array
-    Register       key     = Z_ARG3; // expanded key array
-
-    const Register keylen  = Z_R0;   // Temporarily (until fCode is set) holds the expanded key array length.
-    const Register fCode   = Z_R0;   // crypto function code
-    const Register parmBlk = Z_R1;   // parameter block address (points to crypto key)
-    const Register src     = Z_ARG1; // is Z_R2
-    const Register srclen  = Z_ARG2; // Overwrites destination address.
-    const Register dst     = Z_ARG3; // Overwrites expanded key address.
-
-    // Read key len of expanded key (in 4-byte words).
-    __ z_lgf(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
-
-    // Copy arguments to registers as required by crypto instruction.
-    __ z_lgr(parmBlk, key);          // crypto key (in T_INT array).
-    // __ z_lgr(src, from);          // Copy not needed, src/from are identical.
-    __ z_lgr(dst, to);               // Copy destination address to even register.
-
-    // Construct function code in Z_R0, data block length in Z_ARG2.
-    generate_load_AES_fCode(keylen, fCode, srclen, false);
-
-    __ km(dst, src);          // Cipher the message.
-
-    __ z_br(Z_R14);
+    unsigned int start_off = __ offset();  // Remember stub start address (is rtn value).
+
+    generate_AES_cipherBlock(false);
 
     return __ addr_at(start_off);
   }
@@ -1905,33 +1931,9 @@
   address generate_AES_decryptBlock(const char* name) {
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", name);
-    unsigned int   start_off = __ offset();  // Remember stub start address (is rtn value).
-
-    Register       from    = Z_ARG1; // source byte array
-    Register       to      = Z_ARG2; // destination byte array
-    Register       key     = Z_ARG3; // expanded key array, not preset at entry!!!
-
-    const Register keylen  = Z_R0;   // Temporarily (until fCode is set) holds the expanded key array length.
-    const Register fCode   = Z_R0;   // crypto function code
-    const Register parmBlk = Z_R1;   // parameter block address (points to crypto key)
-    const Register src     = Z_ARG1; // is Z_R2
-    const Register srclen  = Z_ARG2; // Overwrites destination address.
-    const Register dst     = Z_ARG3; // Overwrites key address.
-
-    // Read key len of expanded key (in 4-byte words).
-    __ z_lgf(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
-
-    // Copy arguments to registers as required by crypto instruction.
-    __ z_lgr(parmBlk, key);     // Copy crypto key address.
-    // __ z_lgr(src, from);     // Copy not needed, src/from are identical.
-    __ z_lgr(dst, to);          // Copy destination address to even register.
-
-    // Construct function code in Z_R0, data block length in Z_ARG2.
-    generate_load_AES_fCode(keylen, fCode, srclen, true);
-
-    __ km(dst, src);          // Cipher the message.
-
-    __ z_br(Z_R14);
+    unsigned int start_off = __ offset();  // Remember stub start address (is rtn value).
+
+    generate_AES_cipherBlock(true);
 
     return __ addr_at(start_off);
   }
@@ -1949,10 +1951,7 @@
   // We align the parameter block to the next available octoword.
   //
   // Compute chained AES encrypt function.
-  address generate_cipherBlockChaining_AES_encrypt(const char* name) {
-    __ align(CodeEntryAlignment);
-    StubCodeMark mark(this, "StubRoutines", name);
-    unsigned int   start_off = __ offset();  // Remember stub start address (is rtn value).
+  void generate_AES_cipherBlockChaining(bool is_decipher) {
 
     Register       from    = Z_ARG1; // source byte array (clear text)
     Register       to      = Z_ARG2; // destination byte array (ciphered)
@@ -1972,20 +1971,29 @@
     __ z_lgf(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
 
     // Construct parm block address in parmBlk (== Z_R1), copy cv and key to parm block.
-    // Construct function code in Z_R0.
-    generate_push_parmBlk(keylen, fCode, parmBlk, key, cv, false);
+    // Construct function code in fCode (Z_R0).
+    generate_push_parmBlk(keylen, fCode, parmBlk, key, cv, is_decipher);
 
     // Prepare other registers for instruction.
-    // __ z_lgr(src, from);     // Not needed, registers are the same.
+    __ lgr_if_needed(src, from);     // Copy src address. Will not emit, src/from are identical.
     __ z_lgr(dst, to);
-    __ z_llgfr(srclen, msglen); // We pass the offsets as ints, not as longs as required.
-
-    __ kmc(dst, src);           // Cipher the message.
+    __ z_llgfr(srclen, msglen);      // We pass the offsets as ints, not as longs as required.
+
+    __ kmc(dst, src);                // Cipher the message.
 
     generate_pop_parmBlk(keylen, parmBlk, key, cv);
 
-    __ z_llgfr(Z_RET, msglen);  // We pass the offsets as ints, not as longs as required.
+    __ z_llgfr(Z_RET, msglen);       // We pass the offsets as ints, not as longs as required.
     __ z_br(Z_R14);
+  }
+
+  // Compute chained AES encrypt function.
+  address generate_cipherBlockChaining_AES_encrypt(const char* name) {
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", name);
+    unsigned int   start_off = __ offset();  // Remember stub start address (is rtn value).
+
+    generate_AES_cipherBlockChaining(false);
 
     return __ addr_at(start_off);
   }
@@ -1996,38 +2004,7 @@
     StubCodeMark mark(this, "StubRoutines", name);
     unsigned int   start_off = __ offset();  // Remember stub start address (is rtn value).
 
-    Register       from    = Z_ARG1; // source byte array (ciphered)
-    Register       to      = Z_ARG2; // destination byte array (clear text)
-    Register       key     = Z_ARG3; // expanded key array, not preset at entry!!!
-    Register       cv      = Z_ARG4; // chaining value
-    const Register msglen  = Z_ARG5; // Total length of the msg to be encrypted. Value must be returned
-                                     // in Z_RET upon completion of this stub.
-
-    const Register keylen  = Z_R0;   // Expanded key length, as read from key array. Temp only.
-    const Register fCode   = Z_R0;   // crypto function code
-    const Register parmBlk = Z_R1;   // parameter block address (points to crypto key)
-    const Register src     = Z_ARG1; // is Z_R2
-    const Register srclen  = Z_ARG2; // Overwrites destination address.
-    const Register dst     = Z_ARG3; // Overwrites key address.
-
-    // Read key len of expanded key (in 4-byte words).
-    __ z_lgf(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
-
-    // Construct parm block address in parmBlk (== Z_R1), copy cv and key to parm block.
-    // Construct function code in Z_R0.
-    generate_push_parmBlk(keylen, fCode, parmBlk, key, cv, true);
-
-    // Prepare other registers for instruction.
-    // __ z_lgr(src, from);     // Not needed, registers are the same.
-    __ z_lgr(dst, to);
-    __ z_llgfr(srclen, msglen); // We pass the offsets as ints, not as longs as required.
-
-    __ kmc(dst, src);           // Decipher the message.
-
-    generate_pop_parmBlk(keylen, parmBlk, key, cv);
-
-    __ z_llgfr(Z_RET, msglen);  // We pass the offsets as ints, not as longs as required.
-    __ z_br(Z_R14);
+    generate_AES_cipherBlockChaining(true);
 
     return __ addr_at(start_off);
   }
--- a/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -121,9 +121,8 @@
 
   // We use target_sp for storing arguments in the C frame.
   __ save_return_pc();
-
-  __ z_stmg(Z_R10,Z_R13,-32,Z_SP);
-  __ push_frame_abi160(32);
+  __ push_frame_abi160(4*BytesPerWord);                 // Reserve space to save the tmp_[1..4] registers.
+  __ z_stmg(Z_R10, Z_R13, frame::z_abi_160_size, Z_SP); // Save registers only after frame is pushed.
 
   __ z_lgr(arg_java, Z_ARG1);
 
@@ -341,9 +340,9 @@
 
   // Method exit, all arguments proocessed.
   __ bind(loop_end);
+  __ z_lmg(Z_R10, Z_R13, frame::z_abi_160_size, Z_SP); // restore registers before frame is popped.
   __ pop_frame();
   __ restore_return_pc();
-  __ z_lmg(Z_R10,Z_R13,-32,Z_SP);
   __ z_br(Z_R14);
 
   // Copy int arguments.
@@ -1232,13 +1231,9 @@
 
     // Advance local_addr to point behind locals (creates positive incr. in loop).
     __ z_lg(Z_R1_scratch, Address(Z_method, Method::const_offset()));
-    __ z_llgh(Z_R0_scratch,
-              Address(Z_R1_scratch, ConstMethod::size_of_locals_offset()));
-    if (Z_R0_scratch == Z_R0) {
-      __ z_aghi(Z_R0_scratch, -1);
-    } else {
-      __ add2reg(Z_R0_scratch, -1);
-    }
+    __ z_llgh(Z_R0_scratch, Address(Z_R1_scratch, ConstMethod::size_of_locals_offset()));
+    __ add2reg(Z_R0_scratch, -1);
+
     __ z_lgr(local_addr/*locals*/, Z_locals);
     __ z_sllg(Z_R0_scratch, Z_R0_scratch, LogBytesPerWord);
     __ z_sllg(local_count, local_count, LogBytesPerWord); // Local_count are non param locals.
--- a/hotspot/src/cpu/s390/vm/vm_version_s390.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/s390/vm/vm_version_s390.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -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
@@ -153,6 +153,10 @@
     warning("AES intrinsics are not available on this CPU");
     FLAG_SET_DEFAULT(UseAESIntrinsics, false);
   }
+  if (UseAESIntrinsics && !UseAES) {
+    warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled.");
+    FLAG_SET_DEFAULT(UseAESIntrinsics, false);
+  }
 
   // TODO: implement AES/CTR intrinsics
   if (UseAESCTRIntrinsics) {
--- a/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -176,7 +176,7 @@
 
 
  public:
-  SlowSignatureHandler(methodHandle method, address from, intptr_t* to, intptr_t *RegArgSig) : NativeSignatureIterator(method) {
+  SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to, intptr_t *RegArgSig) : NativeSignatureIterator(method) {
     _from = from;
     _to   = to;
     _RegArgSignature = RegArgSig;
--- a/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -52,7 +52,7 @@
 
  public:
   // Creation
-  SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+  SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
     _masm = new MacroAssembler(buffer);
   }
 
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1633,7 +1633,7 @@
 }
 
 static void verify_oop_args(MacroAssembler* masm,
-                            methodHandle method,
+                            const methodHandle& method,
                             const BasicType* sig_bt,
                             const VMRegPair* regs) {
   Register temp_reg = G5_method;  // not part of any compiled calling seq
@@ -1657,7 +1657,7 @@
 }
 
 static void gen_special_dispatch(MacroAssembler* masm,
-                                 methodHandle method,
+                                 const methodHandle& method,
                                  const BasicType* sig_bt,
                                  const VMRegPair* regs) {
   verify_oop_args(masm, method, sig_bt, regs);
--- a/hotspot/src/cpu/x86/vm/interpreterRT_x86.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -55,7 +55,7 @@
 
  public:
   // Creation
-  SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
+  SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
     _masm = new MacroAssembler(buffer);
 #ifdef AMD64
 #ifdef _WIN64
--- a/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -124,7 +124,7 @@
    }
 
  public:
-  SlowSignatureHandler(methodHandle method, address from, intptr_t* to) :
+  SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to) :
     NativeSignatureIterator(method) {
     _from = from;
     _to   = to + (is_static() ? 2 : 1);
--- a/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -369,7 +369,7 @@
   }
 
  public:
-  SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
+  SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
     : NativeSignatureIterator(method)
   {
     _from = from;
@@ -461,7 +461,7 @@
   }
 
  public:
-  SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
+  SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
     : NativeSignatureIterator(method)
   {
     _from = from;
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -39,7 +39,7 @@
 // Since hashCode is usually polymorphic at call sites we can't do this
 // optimization at the call site without a lot of work.
 void SharedRuntime::inline_check_hashcode_from_object_header(MacroAssembler* masm,
-                                 methodHandle method,
+                                 const methodHandle& method,
                                  Register obj_reg,
                                  Register result) {
   Label slowCase;
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1407,7 +1407,7 @@
 }
 
 static void verify_oop_args(MacroAssembler* masm,
-                            methodHandle method,
+                            const methodHandle& method,
                             const BasicType* sig_bt,
                             const VMRegPair* regs) {
   Register temp_reg = rbx;  // not part of any compiled calling seq
@@ -1429,7 +1429,7 @@
 }
 
 static void gen_special_dispatch(MacroAssembler* masm,
-                                 methodHandle method,
+                                 const methodHandle& method,
                                  const BasicType* sig_bt,
                                  const VMRegPair* regs) {
   verify_oop_args(masm, method, sig_bt, regs);
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1740,7 +1740,7 @@
 }
 
 static void gen_special_dispatch(MacroAssembler* masm,
-                                 methodHandle method,
+                                 const methodHandle& method,
                                  const BasicType* sig_bt,
                                  const VMRegPair* regs) {
   verify_oop_args(masm, method, sig_bt, regs);
--- a/hotspot/src/cpu/zero/vm/interpreterRT_zero.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/zero/vm/interpreterRT_zero.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -67,7 +67,7 @@
   ffi_cif* _cif;
 
  protected:
-  SignatureHandlerGeneratorBase(methodHandle method, ffi_cif *cif)
+  SignatureHandlerGeneratorBase(const methodHandle& method, ffi_cif *cif)
     : NativeSignatureIterator(method), _cif(cif) {
     _cif->nargs = 0;
   }
@@ -96,7 +96,7 @@
   CodeBuffer* _cb;
 
  public:
-  SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer)
+  SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer)
     : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->insts_end()),
       _cb(buffer) {
     _cb->set_insts_end((address) (cif() + 1));
@@ -115,7 +115,7 @@
   intptr_t *_dst;
 
  public:
-  SlowSignatureHandlerGenerator(methodHandle method, intptr_t* buf)
+  SlowSignatureHandlerGenerator(const methodHandle& method, intptr_t* buf)
     : SignatureHandlerGeneratorBase(method, (ffi_cif *) buf) {
     _dst = (intptr_t *) (cif() + 1);
   }
--- a/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -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.
  * Copyright 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -147,8 +147,8 @@
   Klass* clazz = recv->klass();
   Klass* klass_part = InstanceKlass::cast(clazz);
   ResourceMark rm(THREAD);
-  klassVtable* vtable = klass_part->vtable();
-  Method* vmtarget = vtable->method_at(vmindex);
+  klassVtable vtable = klass_part->vtable();
+  Method* vmtarget = vtable.method_at(vmindex);
 
   invoke_target(vmtarget, THREAD);
 
--- a/hotspot/src/jdk.hotspot.agent/doc/jsdb.html	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/doc/jsdb.html	Tue Aug 01 21:29:55 2017 +0000
@@ -1108,11 +1108,6 @@
 calls callback with Klass and initiating loader (Oop) for System dictionary
 entry.
 </dd>
-<dt>forEachPrimArrayKlass(callback)</dt>
-<dd>
-calls callback with Klass and initiating loader (Oop) for each
-primitive array Klass in the system.
-</dd>
 <dt>findInstanceKlass(name)</dt>
 <dd>
 finds the first instance klass with given name from System dictionary
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -48,6 +48,7 @@
 import sun.jvm.hotspot.code.NMethod;
 import sun.jvm.hotspot.debugger.Address;
 import sun.jvm.hotspot.debugger.OopHandle;
+import sun.jvm.hotspot.classfile.ClassLoaderDataGraph;
 import sun.jvm.hotspot.memory.SymbolTable;
 import sun.jvm.hotspot.memory.SystemDictionary;
 import sun.jvm.hotspot.memory.Universe;
@@ -853,8 +854,8 @@
                 } else {
                     String s = t.nextToken();
                     if (s.equals("-a")) {
-                        SystemDictionary sysDict = VM.getVM().getSystemDictionary();
-                        sysDict.allClassesDo(new SystemDictionary.ClassVisitor() {
+                        ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
+                        cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
                                 public void visit(Klass k) {
                                     if (k instanceof InstanceKlass) {
                                         MethodArray methods = ((InstanceKlass)k).getMethods();
@@ -887,8 +888,8 @@
                 if (t.countTokens() != 0) {
                     usage();
                 } else {
-                    SystemDictionary sysDict = VM.getVM().getSystemDictionary();
-                    sysDict.allClassesDo(new SystemDictionary.ClassVisitor() {
+                    ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
+                    cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
                             public void visit(Klass k) {
                                 if (k instanceof InstanceKlass && ((InstanceKlass)k).getConstants().getCache() != null) {
                                     MethodArray methods = ((InstanceKlass)k).getMethods();
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/classfile/ClassLoaderData.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/classfile/ClassLoaderData.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, 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
@@ -25,16 +25,16 @@
 package sun.jvm.hotspot.classfile;
 
 import java.io.PrintStream;
-import java.util.*;
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.memory.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.types.*;
 
 public class ClassLoaderData extends VMObject {
   static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
+    VM.registerVMInitializedObserver(new java.util.Observer() {
+        public void update(java.util.Observable o, Object data) {
           initialize(VM.getVM().getTypeDataBase());
         }
       });
@@ -44,19 +44,26 @@
     Type type      = db.lookupType("ClassLoaderData");
     classLoaderField = type.getOopField("_class_loader");
     nextField = type.getAddressField("_next");
-    klassesField = type.getAddressField("_klasses");
+    klassesField = new MetadataField(type.getAddressField("_klasses"), 0);
     isAnonymousField = new CIntField(type.getCIntegerField("_is_anonymous"), 0);
+    dictionaryField = type.getAddressField("_dictionary");
   }
 
   private static sun.jvm.hotspot.types.OopField classLoaderField;
   private static AddressField nextField;
-  private static AddressField klassesField;
+  private static MetadataField  klassesField;
   private static CIntField isAnonymousField;
+  private static AddressField dictionaryField;
 
   public ClassLoaderData(Address addr) {
     super(addr);
   }
 
+  public Dictionary dictionary() {
+      Address tmp = dictionaryField.getValue();
+      return (Dictionary) VMObjectFactory.newObject(Dictionary.class, tmp);
+  }
+
   public static ClassLoaderData instantiateWrapperFor(Address addr) {
     if (addr == null) {
       return null;
@@ -76,7 +83,30 @@
     return instantiateWrapperFor(nextField.getValue(getAddress()));
   }
 
-  public Klass getKlasses() {
-    return (InstanceKlass)Metadata.instantiateWrapperFor(klassesField.getValue(getAddress()));
+  public Klass getKlasses()    { return (Klass)klassesField.getValue(this);  }
+
+  /** Lookup an already loaded class. If not found null is returned. */
+  public Klass find(Symbol className) {
+    for (Klass l = getKlasses(); l != null; l = l.getNextLinkKlass()) {
+        if (className.equals(l.getName())) {
+            return l;
+        }
+    }
+    return null;
+  }
+
+  /** Iterate over all klasses - including object, primitive
+      array klasses */
+  public void classesDo(ClassLoaderDataGraph.ClassVisitor v) {
+      for (Klass l = getKlasses(); l != null; l = l.getNextLinkKlass()) {
+          v.visit(l);
+      }
+  }
+
+  /** Iterate over all klasses in the dictionary, including initiating loader. */
+  public void allEntriesDo(ClassLoaderDataGraph.ClassAndLoaderVisitor v) {
+      for (Klass l = getKlasses(); l != null; l = l.getNextLinkKlass()) {
+          dictionary().allEntriesDo(v, getClassLoader());
+      }
   }
 }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/classfile/ClassLoaderDataGraph.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/classfile/ClassLoaderDataGraph.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -27,6 +27,7 @@
 import java.io.PrintStream;
 import java.util.*;
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.classfile.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.types.*;
@@ -52,21 +53,43 @@
     return ClassLoaderData.instantiateWrapperFor(headField.getValue());
   }
 
-  public static interface KlassVisitor {
+  /** Lookup an already loaded class in any class loader. */
+  public Klass find(String className) {
+    Symbol sym = VM.getVM().getSymbolTable().probe(className);
+    if (sym == null) return null;
+    for (ClassLoaderData cld = getClassLoaderGraphHead(); cld != null; cld = cld.next()) {
+        Klass k = cld.find(sym);
+        if (k != null) {
+            return k;
+        }
+    }
+    return null;
+  }
+
+  /** Interface for iterating through all classes. */
+  public static interface ClassVisitor {
     public void visit(Klass k);
   }
 
-  /** Iterate over all anonymous class loaders and the klasses in those */
-  public void allAnonymousKlassesDo(final KlassVisitor v) {
-    for (ClassLoaderData cl = getClassLoaderGraphHead();
-         cl != null;
-         cl = cl.next()) {
-      if (cl.getIsAnonymous() == true) {
-        for (Klass k = cl.getKlasses(); k != null; k = k.getNextLinkKlass()) {
-          v.visit(k);
-        }
-      }
+  /** Interface for iterating through all classes and their class
+      loaders in dictionary */
+  public static interface ClassAndLoaderVisitor {
+    public void visit(Klass k, Oop loader);
+  }
+
+  /** Iterate over all klasses - including object, primitive
+      array klasses */
+  public void classesDo(ClassVisitor v) {
+    for (ClassLoaderData cld = getClassLoaderGraphHead(); cld != null; cld = cld.next()) {
+        cld.classesDo(v);
     }
   }
 
+  /** Iterate over all klasses - including object, primitive
+      array klasses, pass initiating loader. */
+  public void allEntriesDo(ClassAndLoaderVisitor v) {
+    for (ClassLoaderData cld = getClassLoaderGraphHead(); cld != null; cld = cld.next()) {
+        cld.allEntriesDo(v);
+    }
+  }
 }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/Dictionary.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/Dictionary.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -26,12 +26,13 @@
 
 import java.util.*;
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.classfile.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.utilities.*;
 
-public class Dictionary extends TwoOopHashtable {
+public class Dictionary extends sun.jvm.hotspot.utilities.Hashtable {
   static {
     VM.registerVMInitializedObserver(new Observer() {
         public void update(Observable o, Object data) {
@@ -55,56 +56,32 @@
     return DictionaryEntry.class;
   }
 
-  /** Iterate over all klasses in dictionary; just the classes from
-      declaring class loaders */
-  public void classesDo(SystemDictionary.ClassVisitor v) {
-    ObjectHeap heap = VM.getVM().getObjectHeap();
+  /** All classes, and their initiating class loader, passed in. */
+  public void allEntriesDo(ClassLoaderDataGraph.ClassAndLoaderVisitor v, Oop loader) {
     int tblSize = tableSize();
     for (int index = 0; index < tblSize; index++) {
       for (DictionaryEntry probe = (DictionaryEntry) bucket(index); probe != null;
-                                             probe = (DictionaryEntry) probe.next()) {
+                                              probe = (DictionaryEntry) probe.next()) {
         Klass k = probe.klass();
-        if (heap.equal(probe.loader(), ((InstanceKlass) k).getClassLoader())) {
-            v.visit(k);
-        }
+        v.visit(k, loader);
       }
     }
   }
 
-  /** All classes, and their class loaders */
-  public void classesDo(SystemDictionary.ClassAndLoaderVisitor v) {
-    int tblSize = tableSize();
-    for (int index = 0; index < tblSize; index++) {
-      for (DictionaryEntry probe = (DictionaryEntry) bucket(index); probe != null;
-                                             probe = (DictionaryEntry) probe.next()) {
-        Klass k = probe.klass();
-        v.visit(k, probe.loader());
-      }
-    }
-  }
-
-  public Klass find(int index, long hash, Symbol className, Oop classLoader, Oop protectionDomain) {
-    DictionaryEntry entry = getEntry(index, hash, className, classLoader);
-    if (entry != null && entry.isValidProtectionDomain(protectionDomain)) {
-      return entry.klass();
-    }
-    return null;
-  }
-
   // - Internals only below this point
 
-  private DictionaryEntry getEntry(int index, long hash, Symbol className, Oop classLoader) {
+  private DictionaryEntry getEntry(int index, long hash, Symbol className) {
     for (DictionaryEntry entry = (DictionaryEntry) bucket(index); entry != null;
                                     entry = (DictionaryEntry) entry.next()) {
-      if (entry.hash() == hash && entry.equals(className, classLoader)) {
+      if (entry.hash() == hash && entry.equals(className)) {
         return entry;
       }
     }
     return null;
   }
 
-  public boolean contains(Klass c, Oop classLoader) {
-    long hash = computeHash(c.getName(), classLoader);
+  public boolean contains(Klass c) {
+    long hash = computeHash(c.getName());
     int index = hashToIndex(hash);
 
     for (DictionaryEntry entry = (DictionaryEntry) bucket(index); entry != null;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -43,28 +43,6 @@
 
   private static synchronized void initialize(TypeDataBase db) {
     Type type = db.lookupType("DictionaryEntry");
-    pdSetField = type.getAddressField("_pd_set");
-    loaderDataField = type.getAddressField("_loader_data");
-  }
-
-  // Fields
-  private static AddressField pdSetField;
-  private static AddressField loaderDataField;
-
-  // Accessors
-
-  public ProtectionDomainEntry pdSet() {
-    Address tmp = pdSetField.getValue(addr);
-    return (ProtectionDomainEntry) VMObjectFactory.newObject(
-                          ProtectionDomainEntry.class, tmp);
-  }
-
-  public Oop loader() {
-    return loaderData().getClassLoader();
-  }
-
-  public ClassLoaderData loaderData() {
-    return ClassLoaderData.instantiateWrapperFor(loaderDataField.getValue(addr));
   }
 
   public Klass klass() {
@@ -75,38 +53,9 @@
     super(addr);
   }
 
-  public boolean equals(Symbol className, Oop classLoader) {
+  public boolean equals(Symbol className) {
     InstanceKlass ik = (InstanceKlass) klass();
-    Oop loader = loader();
-    if (! ik.getName().equals(className)) {
-      return false;
-    } else {
-      return (loader == null)? (classLoader == null) :
-                               (loader.equals(classLoader));
-    }
-  }
-
-  public boolean isValidProtectionDomain(Oop protectionDomain) {
-    if (protectionDomain == null) {
-      return true;
-    } else {
-      return containsProtectionDomain(protectionDomain);
-    }
-  }
-
-  public boolean containsProtectionDomain(Oop protectionDomain) {
-    InstanceKlass ik = (InstanceKlass) klass();
-    // Currently unimplemented and not used.
-    // if (protectionDomain.equals(ik.getJavaMirror().getProtectionDomain())) {
-    //   return true; // Succeeds trivially
-    // }
-    for (ProtectionDomainEntry current = pdSet(); current != null;
-                                       current = current.next()) {
-      if (protectionDomain.equals(current.protectionDomain())) {
-        return true;
-      }
-    }
-    return false;
+    return ik.getName().equals(className);
   }
 
   /* covariant return type :-(
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/LoaderConstraintEntry.java	Tue Jul 25 14:04:53 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.memory;
-
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.utilities.*;
-
-public class LoaderConstraintEntry extends sun.jvm.hotspot.utilities.HashtableEntry {
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("LoaderConstraintEntry");
-    nameField = type.getAddressField("_name");
-    numLoadersField = type.getCIntegerField("_num_loaders");
-    maxLoadersField = type.getCIntegerField("_max_loaders");
-    loadersField = type.getAddressField("_loaders");
-  }
-
-  // Fields
-  private static AddressField nameField;
-  private static CIntegerField numLoadersField;
-  private static CIntegerField maxLoadersField;
-  private static AddressField loadersField;
-
-  // Accessors
-
-  public Symbol name() {
-    return Symbol.create(nameField.getValue(addr));
-  }
-
-  public int numLoaders() {
-    return (int) numLoadersField.getValue(addr);
-  }
-
-  public int maxLoaders() {
-    return (int) maxLoadersField.getValue(addr);
-  }
-
-  public Oop initiatingLoader(int i) {
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(i >= 0 && i < numLoaders(), "invalid index");
-    }
-    Address loaders = loadersField.getValue(addr);
-    OopHandle loader = loaders.addOffsetToAsOopHandle(i * VM.getVM().getOopSize());
-    return VM.getVM().getObjectHeap().newOop(loader);
-  }
-
-  public LoaderConstraintEntry(Address addr) {
-    super(addr);
-  }
-
-  /* covariant return type :-(
-  public LoaderConstraintEntry next() {
-    return (LoaderConstraintEntry) super.next();
-  }
-  For now, let the caller cast it ..
-  */
-}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java	Tue Jul 25 14:04:53 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.memory;
-
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.utilities.*;
-
-public class LoaderConstraintTable extends TwoOopHashtable {
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("LoaderConstraintTable");
-  }
-
-  public LoaderConstraintTable(Address addr) {
-    super(addr);
-  }
-
-  // this is overriden here so that Hashtable.bucket will return
-  // object of LoaderConstraintEntry.class
-  protected Class getHashtableEntryClass() {
-    return LoaderConstraintEntry.class;
-  }
-}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/PlaceholderEntry.java	Tue Jul 25 14:04:53 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.memory;
-
-import java.util.*;
-import sun.jvm.hotspot.classfile.ClassLoaderData;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.utilities.*;
-
-public class PlaceholderEntry extends sun.jvm.hotspot.utilities.HashtableEntry {
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("PlaceholderEntry");
-    loaderDataField = type.getAddressField("_loader_data");
-  }
-
-  // Field
-  private static AddressField loaderDataField;
-
-  // Accessor
-  public Oop loader() {
-    return loaderData().getClassLoader();
-  }
-
-  public ClassLoaderData loaderData() {
-    return ClassLoaderData.instantiateWrapperFor(loaderDataField.getValue(addr));
-  }
-
-  public PlaceholderEntry(Address addr) {
-    super(addr);
-  }
-
-  public Symbol klass() {
-    return Symbol.create(literalValue());
-  }
-
-  /* covariant return type :-(
-  public PlaceholderEntry next() {
-    return (PlaceholderEntry) super.next();
-  }
-  For now, let the caller cast it ..
-  */
-}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/PlaceholderTable.java	Tue Jul 25 14:04:53 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2003, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.memory;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.utilities.*;
-
-public class PlaceholderTable extends TwoOopHashtable {
-  public PlaceholderTable(Address addr) {
-    super(addr);
-  }
-
-  // this is overriden here so that Hashtable.bucket will return
-  // object of PlacholderEntry.class
-  protected Class getHashtableEntryClass() {
-    return PlaceholderEntry.class;
-  }
-
-  /** All array classes of primitive type, and their class loaders */
-  public void primArrayClassesDo(SystemDictionary.ClassAndLoaderVisitor v) {
-    ObjectHeap heap = VM.getVM().getObjectHeap();
-    int tblSize = tableSize();
-    for (int index = 0; index < tblSize; index++) {
-      for (PlaceholderEntry probe = (PlaceholderEntry) bucket(index); probe != null;
-                                          probe = (PlaceholderEntry) probe.next()) {
-        Symbol sym = probe.klass();
-        // array of primitive arrays are stored in system dictionary as placeholders
-        FieldType ft = new FieldType(sym);
-        if (ft.isArray()) {
-          FieldType.ArrayInfo info = ft.getArrayInfo();
-          if (info.elementBasicType() != BasicType.getTObject()) {
-            Klass arrayKlass = heap.typeArrayKlassObj(info.elementBasicType());
-            arrayKlass = arrayKlass.arrayKlassOrNull(info.dimension());
-            v.visit(arrayKlass, probe.loader());
-          }
-        }
-      }
-    }
-  }
-}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/ProtectionDomainCacheEntry.java	Tue Jul 25 14:04:53 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2001, 2013, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.memory;
-
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-
-public class ProtectionDomainCacheEntry extends VMObject {
-  private static sun.jvm.hotspot.types.OopField protectionDomainField;
-
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("ProtectionDomainCacheEntry");
-    protectionDomainField = type.getOopField("_literal");
-  }
-
-  public ProtectionDomainCacheEntry(Address addr) {
-    super(addr);
-  }
-
-  public Oop protectionDomain() {
-    return VM.getVM().getObjectHeap().newOop(protectionDomainField.getValue(addr));
-  }
-}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/ProtectionDomainEntry.java	Tue Jul 25 14:04:53 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2001, 2013, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.memory;
-
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-
-public class ProtectionDomainEntry extends VMObject {
-  private static AddressField nextField;
-  private static AddressField pdCacheField;
-
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("ProtectionDomainEntry");
-
-    nextField = type.getAddressField("_next");
-    pdCacheField = type.getAddressField("_pd_cache");
-  }
-
-  public ProtectionDomainEntry(Address addr) {
-    super(addr);
-  }
-
-  public ProtectionDomainEntry next() {
-    return (ProtectionDomainEntry) VMObjectFactory.newObject(ProtectionDomainEntry.class, nextField.getValue(addr));
-  }
-
-  public Oop protectionDomain() {
-    ProtectionDomainCacheEntry pd_cache = (ProtectionDomainCacheEntry)
-      VMObjectFactory.newObject(ProtectionDomainCacheEntry.class, pdCacheField.getValue(addr));
-    return pd_cache.protectionDomain();
-  }
-}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -26,15 +26,13 @@
 
 import java.util.*;
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.classfile.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
 
 public class SystemDictionary {
-  private static AddressField dictionaryField;
   private static AddressField sharedDictionaryField;
-  private static AddressField placeholdersField;
-  private static AddressField loaderConstraintTableField;
   private static sun.jvm.hotspot.types.OopField javaSystemLoaderField;
 
   private static AddressField objectKlassField;
@@ -56,10 +54,7 @@
   private static synchronized void initialize(TypeDataBase db) {
     Type type = db.lookupType("SystemDictionary");
 
-    dictionaryField = type.getAddressField("_dictionary");
     sharedDictionaryField = type.getAddressField("_shared_dictionary");
-    placeholdersField = type.getAddressField("_placeholders");
-    loaderConstraintTableField = type.getAddressField("_loader_constraints");
     javaSystemLoaderField = type.getOopField("_java_system_loader");
 
     objectKlassField = type.getAddressField(WK_KLASS("Object_klass"));
@@ -81,26 +76,11 @@
       return (kname+"_knum");
   }
 
-  public Dictionary dictionary() {
-    Address tmp = dictionaryField.getValue();
-    return (Dictionary) VMObjectFactory.newObject(Dictionary.class, tmp);
-  }
-
   public Dictionary sharedDictionary() {
     Address tmp = sharedDictionaryField.getValue();
     return (Dictionary) VMObjectFactory.newObject(Dictionary.class, tmp);
   }
 
-  public PlaceholderTable placeholders() {
-    Address tmp = placeholdersField.getValue();
-    return (PlaceholderTable) VMObjectFactory.newObject(PlaceholderTable.class, tmp);
-  }
-
-  public LoaderConstraintTable constraints() {
-    Address tmp = placeholdersField.getValue();
-    return (LoaderConstraintTable) VMObjectFactory.newObject(LoaderConstraintTable.class, tmp);
-  }
-
   // few well known classes -- not all are added here.
   // add more if needed.
   public static InstanceKlass getThreadKlass() {
@@ -132,8 +112,8 @@
   }
 
   public InstanceKlass getAbstractOwnableSynchronizerKlass() {
-    return (InstanceKlass) find("java/util/concurrent/locks/AbstractOwnableSynchronizer",
-                                null, null);
+    ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
+    return (InstanceKlass) cldg.find("java/util/concurrent/locks/AbstractOwnableSynchronizer");
   }
 
   public static Oop javaSystemLoader() {
@@ -143,60 +123,4 @@
   private static Oop newOop(OopHandle handle) {
     return VM.getVM().getObjectHeap().newOop(handle);
   }
-
-  /** Lookup an already loaded class. If not found null is returned. */
-  public Klass find(String className, Oop classLoader, Oop protectionDomain) {
-    Symbol sym = VM.getVM().getSymbolTable().probe(className);
-    if (sym == null) return null;
-    return find(sym, classLoader, protectionDomain);
-  }
-
-  /** Lookup an already loaded class. If not found null is returned. */
-  public Klass find(Symbol className, Oop classLoader, Oop protectionDomain) {
-    Dictionary dict = dictionary();
-    long hash = dict.computeHash(className, classLoader);
-    int index = dict.hashToIndex(hash);
-    return dict.find(index, hash, className, classLoader, protectionDomain);
-  }
-
-  /** Interface for iterating through all classes in dictionary */
-  public static interface ClassVisitor {
-    public void visit(Klass k);
-  }
-
-  /** Interface for iterating through all classes and their class
-      loaders in dictionary */
-  public static interface ClassAndLoaderVisitor {
-    public void visit(Klass k, Oop loader);
-  }
-
-  /** Iterate over all klasses - including object, primitive
-      array klasses */
-  public void allClassesDo(final ClassVisitor v) {
-    ClassVisitor visitor = new ClassVisitor() {
-      public void visit(Klass k) {
-        for (Klass l = k; l != null; l = l.arrayKlassOrNull()) {
-          v.visit(l);
-        }
-      }
-    };
-    classesDo(visitor);
-    VM.getVM().getUniverse().basicTypeClassesDo(visitor);
-  }
-
-  /** Iterate over all klasses in dictionary; just the classes from
-      declaring class loaders */
-  public void classesDo(ClassVisitor v) {
-    dictionary().classesDo(v);
-  }
-
-  /** All classes, and their class loaders */
-  public void classesDo(ClassAndLoaderVisitor v) {
-    dictionary().classesDo(v);
-  }
-
-  /** All array classes of primitive type, and their class loaders */
-  public void primArrayClassesDo(ClassAndLoaderVisitor v) {
-    placeholders().primArrayClassesDo(v);
-  }
 }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/Universe.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/Universe.java	Tue Aug 01 21:29:55 2017 +0000
@@ -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
@@ -164,18 +164,6 @@
     return newOop(systemThreadGroupField.getValue());
   }
 
-  // iterate through the single dimensional primitive array klasses
-  // refer to basic_type_classes_do(void f(Klass*)) in universe.cpp
-  public void basicTypeClassesDo(SystemDictionary.ClassVisitor visitor) {
-    visitor.visit(new TypeArrayKlass(boolArrayKlassField.getValue()));
-    visitor.visit(new TypeArrayKlass(byteArrayKlassField.getValue()));
-    visitor.visit(new TypeArrayKlass(charArrayKlassField.getValue()));
-    visitor.visit(new TypeArrayKlass(intArrayKlassField.getValue()));
-    visitor.visit(new TypeArrayKlass(shortArrayKlassField.getValue()));
-    visitor.visit(new TypeArrayKlass(longArrayKlassField.getValue()));
-    visitor.visit(new TypeArrayKlass(singleArrayKlassField.getValue()));
-    visitor.visit(new TypeArrayKlass(doubleArrayKlassField.getValue()));
-  }
 
   public void print() { printOn(System.out); }
   public void printOn(PrintStream tty) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Tue Aug 01 21:29:55 2017 +0000
@@ -91,7 +91,6 @@
     fields               = type.getAddressField("_fields");
     javaFieldsCount      = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
     constants            = new MetadataField(type.getAddressField("_constants"), 0);
-    classLoaderData      = type.getAddressField("_class_loader_data");
     sourceDebugExtension = type.getAddressField("_source_debug_extension");
     innerClasses         = type.getAddressField("_inner_classes");
     sourceFileNameIndex  = new CIntField(type.getCIntegerField("_source_file_name_index"), 0);
@@ -166,7 +165,6 @@
   private static AddressField fields;
   private static CIntField javaFieldsCount;
   private static MetadataField constants;
-  private static AddressField  classLoaderData;
   private static AddressField  sourceDebugExtension;
   private static AddressField  innerClasses;
   private static CIntField sourceFileNameIndex;
@@ -328,7 +326,7 @@
       // MetaspaceObj in the CDS shared archive.
       Dictionary sharedDictionary = vm.getSystemDictionary().sharedDictionary();
       if (sharedDictionary != null) {
-        if (sharedDictionary.contains(this, null)) {
+        if (sharedDictionary.contains(this)) {
           return true;
         }
       }
@@ -448,8 +446,6 @@
     return allFieldsCount;
   }
   public ConstantPool getConstants()        { return (ConstantPool) constants.getValue(this); }
-  public ClassLoaderData getClassLoaderData() { return                ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
-  public Oop       getClassLoader()         { return                getClassLoaderData().getClassLoader(); }
   public Symbol    getSourceFileName()      { return                getConstants().getSymbolAt(sourceFileNameIndex.getValue(this)); }
   public String    getSourceDebugExtension(){ return                CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
   public long      getNonstaticFieldSize()  { return                nonstaticFieldSize.getValue(this); }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java	Tue Aug 01 21:29:55 2017 +0000
@@ -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
@@ -27,6 +27,7 @@
 import java.io.*;
 import java.util.*;
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.classfile.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
 
@@ -63,6 +64,7 @@
     nextSibling  = new MetadataField(type.getAddressField("_next_sibling"), 0);
     nextLink     = new MetadataField(type.getAddressField("_next_link"), 0);
     vtableLen    = new CIntField(type.getCIntegerField("_vtable_len"), 0);
+    classLoaderData = type.getAddressField("_class_loader_data");
 
     LH_INSTANCE_SLOW_PATH_BIT  = db.lookupIntConstant("Klass::_lh_instance_slow_path_bit").intValue();
     LH_LOG2_ELEMENT_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_log2_element_size_shift").intValue();
@@ -96,6 +98,7 @@
   private static MetadataField  nextLink;
   private static sun.jvm.hotspot.types.Field traceIDField;
   private static CIntField vtableLen;
+  private static AddressField classLoaderData;
 
   private Address getValue(AddressField field) {
     return addr.getAddressAt(field.getOffset());
@@ -110,7 +113,7 @@
   public Klass    getSuper()            { return (Klass)    superField.getValue(this);   }
   public Klass    getJavaSuper()        { return null;  }
   public int      getLayoutHelper()     { return (int)           layoutHelper.getValue(this); }
-  public Symbol   getName()             { return getSymbol(name); }
+  public Symbol   getName()             { return            getSymbol(name); }
   public long     getAccessFlags()      { return            accessFlags.getValue(this);  }
   // Convenience routine
   public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags());      }
@@ -119,6 +122,9 @@
   public Klass    getNextLinkKlass()    { return (Klass)    nextLink.getValue(this);  }
   public long     getVtableLen()        { return            vtableLen.getValue(this); }
 
+  public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
+  public Oop             getClassLoader()     { return   getClassLoaderData().getClassLoader(); }
+
   public long traceID() {
     if (traceIDField == null) return 0;
     return traceIDField.getJLong(addr);
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -28,6 +28,7 @@
 import java.util.*;
 
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.classfile.*;
 import sun.jvm.hotspot.memory.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.runtime.*;
@@ -106,8 +107,8 @@
          err.print("computing per loader stat ..");
       }
 
-      SystemDictionary dict = VM.getVM().getSystemDictionary();
-      dict.classesDo(new SystemDictionary.ClassVisitor() {
+      ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
+      cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
                         public void visit(Klass k) {
                            if (! (k instanceof InstanceKlass)) {
                               return;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, 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
@@ -29,6 +29,7 @@
 import java.util.jar.JarOutputStream;
 import java.util.jar.JarEntry;
 import java.util.jar.Manifest;
+import sun.jvm.hotspot.classfile.*;
 import sun.jvm.hotspot.memory.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.debugger.*;
@@ -100,9 +101,9 @@
                 setOutputDirectory(dirName);
             }
 
-            // walk through the system dictionary
-            SystemDictionary dict = VM.getVM().getSystemDictionary();
-            dict.classesDo(new SystemDictionary.ClassVisitor() {
+            // walk through the loaded classes
+            ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
+            cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
                     public void visit(Klass k) {
                         if (k instanceof InstanceKlass) {
                             try {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/Hashtable.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/Hashtable.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -27,6 +27,7 @@
 import java.util.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.runtime.*;
 
 public class Hashtable extends BasicHashtable {
@@ -48,6 +49,10 @@
     return HashtableEntry.class;
   }
 
+  public int computeHash(Symbol name) {
+    return (int) name.identityHash();
+  }
+
   public int hashToIndex(long fullHash) {
     return (int) (fullHash % tableSize());
   }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Tue Aug 01 21:29:55 2017 +0000
@@ -586,23 +586,9 @@
     }
 
     private void writeClassDumpRecords() throws IOException {
-        SystemDictionary sysDict = VM.getVM().getSystemDictionary();
         ClassLoaderDataGraph cldGraph = VM.getVM().getClassLoaderDataGraph();
         try {
-            sysDict.allClassesDo(new SystemDictionary.ClassVisitor() {
-                            public void visit(Klass k) {
-                                try {
-                                    writeHeapRecordPrologue();
-                                    writeClassDumpRecord(k);
-                                    writeHeapRecordEpilogue();
-                                } catch (IOException e) {
-                                    throw new RuntimeException(e);
-                                }
-                            }
-                        });
-             // Add the anonymous classes also which are not present in the
-             // System Dictionary
-             cldGraph.allAnonymousKlassesDo(new ClassLoaderDataGraph.KlassVisitor() {
+             cldGraph.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
                             public void visit(Klass k) {
                                 try {
                                     writeHeapRecordPrologue();
@@ -1088,26 +1074,9 @@
 
     private void writeClasses() throws IOException {
         // write class list (id, name) association
-        SystemDictionary sysDict = VM.getVM().getSystemDictionary();
         ClassLoaderDataGraph cldGraph = VM.getVM().getClassLoaderDataGraph();
         try {
-            sysDict.allClassesDo(new SystemDictionary.ClassVisitor() {
-                public void visit(Klass k) {
-                    try {
-                        Instance clazz = k.getJavaMirror();
-                        writeHeader(HPROF_LOAD_CLASS, 2 * (OBJ_ID_SIZE + 4));
-                        out.writeInt(serialNum);
-                        writeObjectID(clazz);
-                        KlassMap.add(serialNum - 1, k);
-                        out.writeInt(DUMMY_STACK_TRACE_ID);
-                        writeSymbolID(k.getName());
-                        serialNum++;
-                    } catch (IOException exp) {
-                        throw new RuntimeException(exp);
-                    }
-                }
-            });
-            cldGraph.allAnonymousKlassesDo(new ClassLoaderDataGraph.KlassVisitor() {
+            cldGraph.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
                 public void visit(Klass k) {
                     try {
                         Instance clazz = k.getJavaMirror();
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, 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
@@ -27,6 +27,7 @@
 import java.io.*;
 import java.util.*;
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.classfile.*;
 import sun.jvm.hotspot.gc.shared.*;
 import sun.jvm.hotspot.memory.*;
 import sun.jvm.hotspot.oops.*;
@@ -113,8 +114,8 @@
                      new RootVisitor("Weak global JNI handle root"));
 
     // Do Java-level static fields
-    SystemDictionary sysDict = VM.getVM().getSystemDictionary();
-    sysDict.allClassesDo(new SystemDictionary.ClassVisitor() {
+    ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
+    cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
 
             public void visit(Klass k) {
                 if (k instanceof InstanceKlass) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/SystemDictionaryHelper.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/SystemDictionaryHelper.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2005, 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
@@ -25,6 +25,7 @@
 package sun.jvm.hotspot.utilities;
 
 import java.util.*;
+import sun.jvm.hotspot.classfile.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.memory.*;
 import sun.jvm.hotspot.runtime.*;
@@ -52,8 +53,8 @@
       }
 
       final Vector tmp = new Vector();
-      SystemDictionary dict = VM.getVM().getSystemDictionary();
-      dict.classesDo(new SystemDictionary.ClassVisitor() {
+      ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
+      cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
                         public void visit(Klass k) {
                            if (k instanceof InstanceKlass) {
                               InstanceKlass ik = (InstanceKlass) k;
@@ -100,42 +101,15 @@
    public static InstanceKlass findInstanceKlass(String className) {
       // convert to internal name
       className = className.replace('.', '/');
-      SystemDictionary sysDict = VM.getVM().getSystemDictionary();
-
-      // check whether we have a bootstrap class of given name
-      Klass klass = sysDict.find(className, null, null);
-      if (klass != null) {
-         return (InstanceKlass) klass;
-      }
-
-      // check whether we have a system class of given name
-      klass = sysDict.find(className, sysDict.javaSystemLoader(), null);
-      if (klass != null) {
-         return (InstanceKlass) klass;
-      }
+      ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
 
-      // didn't find bootstrap or system class of given name.
-      // search through the entire dictionary..
-      InstanceKlass[] tmpKlasses = getAllInstanceKlasses();
-      // instance klass array is sorted by name. do binary search
-      int low = 0;
-      int high = tmpKlasses.length-1;
-
-      int mid = -1;
-      while (low <= high) {
-         mid = (low + high) >> 1;
-         InstanceKlass midVal = tmpKlasses[mid];
-         int cmp = midVal.getName().asString().compareTo(className);
-
-         if (cmp < 0) {
-             low = mid + 1;
-         } else if (cmp > 0) {
-             high = mid - 1;
-         } else { // match found
-             return tmpKlasses[mid];
-         }
+      // check whether we have a class of given name
+      Klass klass = cldg.find(className);
+      if (klass != null && klass instanceof InstanceKlass) {
+         return (InstanceKlass) klass;
+      } else {
+        // no match ..
+        return null;
       }
-      // no match ..
-      return null;
    }
 }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/TwoOopHashtable.java	Tue Jul 25 14:04:53 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2003, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.utilities;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-
-public class TwoOopHashtable extends Hashtable {
-  public TwoOopHashtable(Address addr) {
-    super(addr);
-  }
-
-  public long computeHash(Symbol name, Oop loader) {
-    return ((int) name.identityHash()
-        ^  (int) (loader == null ? 0 : loader.identityHash())) & 0xFFFFFFFFL;
-  }
-
-  public int indexFor(Symbol name, Oop loader) {
-    return hashToIndex(computeHash(name, loader));
-  }
-}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaHeap.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaHeap.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -27,6 +27,7 @@
 import java.util.*;
 import javax.script.ScriptException;
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.classfile.*;
 import sun.jvm.hotspot.memory.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.runtime.*;
@@ -166,11 +167,12 @@
         }
 
       final Callable finalFunc = func;
-        SystemDictionary sysDict = VM.getVM().getSystemDictionary();
+        ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
         if (withLoader) {
-            sysDict.classesDo(new SystemDictionary.ClassAndLoaderVisitor() {
-                    public void visit(Klass kls, Oop loader) {
+            cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
+                    public void visit(Klass kls) {
                         JSJavaKlass  jk = factory.newJSJavaKlass(kls);
+                        Oop loader = kls.getClassLoader();
                         if (jk == null) {
                             return;
                         }
@@ -189,7 +191,7 @@
                 });
 
         } else {
-            sysDict.classesDo(new SystemDictionary.ClassVisitor() {
+            cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
                     public void visit(Klass kls) {
                         JSJavaKlass jk = factory.newJSJavaKlass(kls);
                         if (jk == null) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -513,24 +513,18 @@
    return sa.sysDict.javaSystemLoader();
 }
 
-// iterate system dictionary for each 'Klass' 
+// iterate class loader data for each 'Klass' 
 function forEachKlass(callback) {
-   var VisitorClass = sapkg.memory.SystemDictionary.ClassVisitor;
+   var VisitorClass = sapkg.classfile.ClassLoaderDataGraph.ClassVisitor;
    var visitor = new VisitorClass() { visit: callback };
-   sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary.ClassVisitor)"](visitor);
+   sa.sysDict["classesDo(sun.jvm.hotspot.classfile.ClassLoaderDataGraph.ClassVisitor)"](visitor);
 }
 
 // iterate system dictionary for each 'Klass' and initiating loader
 function forEachKlassAndLoader(callback) {
-   var VisitorClass = sapkg.memory.SystemDictionary.ClassAndLoaderVisitor;
+   var VisitorClass = sapkg.classfile.ClassLoaderDataGraph.ClassAndLoaderVisitor;
    var visitor = new VisitorClass() { visit: callback };
-   sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary.ClassAndLoaderVisitor)"](visitor);
-}
-
-// iterate system dictionary for each primitive array klass
-function forEachPrimArrayKlass(callback) {
-   var VisitorClass = sapkg.memory.SystemDictionary.ClassAndLoaderVisitor;
-   sa.sysDict.primArrayClassesDo(new VisitorClass() { visit: callback });
+   sa.sysDict["allEntriesDo(sun.jvm.hotspot.classfile.ClassLoaderDataGraph.ClassAndLoaderVisitor)"](visitor);
 }
 
 // 'oop' to higher-level java object wrapper in which for(i in o) 
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -743,7 +743,7 @@
 
 #ifndef DEOPTIMIZE_WHEN_PATCHING
 
-static Klass* resolve_field_return_klass(methodHandle caller, int bci, TRAPS) {
+static Klass* resolve_field_return_klass(const methodHandle& caller, int bci, TRAPS) {
   Bytecode_field field_access(caller, bci);
   // This can be static or non-static field access
   Bytecodes::Code code       = field_access.code();
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -68,7 +68,7 @@
 // ciMethod::ciMethod
 //
 // Loaded method.
-ciMethod::ciMethod(methodHandle h_m, ciInstanceKlass* holder) :
+ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :
   ciMetadata(h_m()),
   _holder(holder)
 {
@@ -979,7 +979,7 @@
 //
 // Generate new MethodData* objects at compile time.
 // Return true if allocation was successful or no MDO is required.
-bool ciMethod::ensure_method_data(methodHandle h_m) {
+bool ciMethod::ensure_method_data(const methodHandle& h_m) {
   EXCEPTION_CONTEXT;
   if (is_native() || is_abstract() || h_m()->is_accessor()) {
     return true;
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -101,7 +101,7 @@
   BCEscapeAnalyzer*   _bcea;
 #endif
 
-  ciMethod(methodHandle h_m, ciInstanceKlass* holder);
+  ciMethod(const methodHandle& h_m, ciInstanceKlass* holder);
   ciMethod(ciInstanceKlass* holder, ciSymbol* name, ciSymbol* signature, ciInstanceKlass* accessor);
 
   oop loader() const                             { return _holder->loader(); }
@@ -112,7 +112,7 @@
 
   void load_code();
 
-  bool ensure_method_data(methodHandle h_m);
+  bool ensure_method_data(const methodHandle& h_m);
 
   void code_at_put(int bci, Bytecodes::Code code) {
     Bytecodes::check(code);
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1060,7 +1060,7 @@
 class MethodAnnotationCollector : public AnnotationCollector{
 public:
   MethodAnnotationCollector() : AnnotationCollector(_in_method) { }
-  void apply_to(methodHandle m);
+  void apply_to(const methodHandle& m);
 };
 
 class ClassFileParser::ClassAnnotationCollector : public AnnotationCollector{
@@ -2095,7 +2095,7 @@
   MetadataFactory::free_array<u1>(_loader_data, _field_type_annotations);
 }
 
-void MethodAnnotationCollector::apply_to(methodHandle m) {
+void MethodAnnotationCollector::apply_to(const methodHandle& m) {
   if (has_annotation(_method_CallerSensitive))
     m->set_caller_sensitive(true);
   if (has_annotation(_method_ForceInline))
@@ -3632,7 +3632,7 @@
 #ifndef PRODUCT
 static void print_field_layout(const Symbol* name,
                                Array<u2>* fields,
-                               constantPoolHandle cp,
+                               const constantPoolHandle& cp,
                                int instance_size,
                                int instance_fields_start,
                                int instance_fields_end,
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1887,7 +1887,7 @@
  *
  * TODO:  This should be a private method in a CompileTheWorld class.
  */
-static bool can_be_compiled(methodHandle m, int comp_level) {
+static bool can_be_compiled(const methodHandle& m, int comp_level) {
   assert(CompileTheWorld, "must be");
 
   // It's not valid to compile a native wrapper for MethodHandle methods
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,4 +1,4 @@
-/*
+ /*
  * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -49,6 +49,7 @@
 #include "precompiled.hpp"
 #include "classfile/classLoaderData.hpp"
 #include "classfile/classLoaderData.inline.hpp"
+#include "classfile/dictionary.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/metadataOnStackMark.hpp"
 #include "classfile/moduleEntry.hpp"
@@ -114,6 +115,12 @@
   } else {
     _unnamed_module = NULL;
   }
+
+  if (!is_anonymous) {
+    _dictionary = create_dictionary();
+  } else {
+    _dictionary = NULL;
+  }
   TRACE_INIT_ID(this);
 }
 
@@ -450,10 +457,82 @@
   }
 }
 
+// Class iterator used by the compiler.  It gets some number of classes at
+// a safepoint to decay invocation counters on the methods.
+class ClassLoaderDataGraphKlassIteratorStatic {
+  ClassLoaderData* _current_loader_data;
+  Klass*           _current_class_entry;
+ public:
+
+  ClassLoaderDataGraphKlassIteratorStatic() : _current_loader_data(NULL), _current_class_entry(NULL) {}
+
+  InstanceKlass* try_get_next_class() {
+    assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
+    int max_classes = InstanceKlass::number_of_instance_classes();
+    for (int i = 0; i < max_classes; i++) {
+
+      if (_current_class_entry != NULL) {
+        Klass* k = _current_class_entry;
+        _current_class_entry = _current_class_entry->next_link();
+
+        if (k->is_instance_klass()) {
+          InstanceKlass* ik = InstanceKlass::cast(k);
+          // Only return loaded classes
+          if (ik->is_loaded()) {
+            return ik;
+          }
+        }
+      } else {
+        // Go to next CLD
+        if (_current_loader_data != NULL) {
+          _current_loader_data = _current_loader_data->next();
+        }
+        // Start at the beginning
+        if (_current_loader_data == NULL) {
+          _current_loader_data = ClassLoaderDataGraph::_head;
+        }
+
+        _current_class_entry = _current_loader_data->klasses();
+      }
+    }
+    // should never be reached: an InstanceKlass should be returned above
+    ShouldNotReachHere();
+    return NULL;   // Object_klass not even loaded?
+  }
+
+  // If the current class for the static iterator is a class being unloaded or
+  // deallocated, adjust the current class.
+  void adjust_saved_class(ClassLoaderData* cld) {
+    if (_current_loader_data == cld) {
+      _current_loader_data = cld->next();
+      if (_current_loader_data != NULL) {
+        _current_class_entry = _current_loader_data->klasses();
+      }  // else try_get_next_class will start at the head
+    }
+  }
+
+  void adjust_saved_class(Klass* klass) {
+    if (_current_class_entry == klass) {
+      _current_class_entry = klass->next_link();
+    }
+  }
+};
+
+static ClassLoaderDataGraphKlassIteratorStatic static_klass_iterator;
+
+InstanceKlass* ClassLoaderDataGraph::try_get_next_class() {
+  return static_klass_iterator.try_get_next_class();
+}
+
+
 // Remove a klass from the _klasses list for scratch_class during redefinition
 // or parsed class in the case of an error.
 void ClassLoaderData::remove_class(Klass* scratch_class) {
   assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
+
+  // Adjust global class iterator.
+  static_klass_iterator.adjust_saved_class(scratch_class);
+
   Klass* prev = NULL;
   for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
     if (k == scratch_class) {
@@ -493,6 +572,9 @@
   // In some rare cases items added to this list will not be freed elsewhere.
   // To keep it simple, just free everything in it here.
   free_deallocate_list();
+
+  // Clean up global class iterator for compiler
+  static_klass_iterator.adjust_saved_class(this);
 }
 
 ModuleEntryTable* ClassLoaderData::modules() {
@@ -515,6 +597,45 @@
   return modules;
 }
 
+const int _boot_loader_dictionary_size    = 1009;
+const int _default_loader_dictionary_size = 107;
+const int _prime_array_size         = 8;                       // array of primes for system dictionary size
+const int _average_depth_goal       = 3;                       // goal for lookup length
+const int _primelist[_prime_array_size] = {107, 1009, 2017, 4049, 5051, 10103, 20201, 40423};
+
+// Calculate a "good" dictionary size based
+// on predicted or current loaded classes count.
+static int calculate_dictionary_size(int classcount) {
+  int newsize = _primelist[0];
+  if (classcount > 0 && !DumpSharedSpaces) {
+    int index = 0;
+    int desiredsize = classcount/_average_depth_goal;
+    for (newsize = _primelist[index]; index < _prime_array_size -1;
+         newsize = _primelist[++index]) {
+      if (desiredsize <=  newsize) {
+        break;
+      }
+    }
+  }
+  return newsize;
+}
+
+Dictionary* ClassLoaderData::create_dictionary() {
+  assert(!is_anonymous(), "anonymous class loader data do not have a dictionary");
+  int size;
+  if (_the_null_class_loader_data == NULL) {
+    size = _boot_loader_dictionary_size;
+  } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) {
+    size = 1;  // there's only one class in relection class loader and no initiated classes
+  } else if (is_system_class_loader_data()) {
+    size = calculate_dictionary_size(PredictedLoadedClassCount);
+  } else {
+    size = _default_loader_dictionary_size;
+  }
+  return new Dictionary(this, size);
+}
+
+// Unloading support
 oop ClassLoaderData::keep_alive_object() const {
   assert_locked_or_safepoint(_metaspace_lock);
   assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive");
@@ -546,6 +667,13 @@
     _modules = NULL;
   }
 
+  // Release C heap allocated hashtable for the dictionary
+  if (_dictionary != NULL) {
+    // Destroy the table itself
+    delete _dictionary;
+    _dictionary = NULL;
+  }
+
   if (_unnamed_module != NULL) {
     _unnamed_module->delete_unnamed_module();
     _unnamed_module = NULL;
@@ -974,6 +1102,46 @@
   }
 }
 
+#define FOR_ALL_DICTIONARY(X) for (ClassLoaderData* X = _head; X != NULL; X = X->next()) \
+                                if (X->dictionary() != NULL)
+
+// Walk classes in the loaded class dictionaries in various forms.
+// Only walks the classes defined in this class loader.
+void ClassLoaderDataGraph::dictionary_classes_do(void f(InstanceKlass*)) {
+  FOR_ALL_DICTIONARY(cld) {
+    cld->dictionary()->classes_do(f);
+  }
+}
+
+// Only walks the classes defined in this class loader.
+void ClassLoaderDataGraph::dictionary_classes_do(void f(InstanceKlass*, TRAPS), TRAPS) {
+  FOR_ALL_DICTIONARY(cld) {
+    cld->dictionary()->classes_do(f, CHECK);
+  }
+}
+
+// Walks all entries in the dictionary including entries initiated by this class loader.
+void ClassLoaderDataGraph::dictionary_all_entries_do(void f(InstanceKlass*, ClassLoaderData*)) {
+  FOR_ALL_DICTIONARY(cld) {
+    cld->dictionary()->all_entries_do(f);
+  }
+}
+
+void ClassLoaderDataGraph::verify_dictionary() {
+  FOR_ALL_DICTIONARY(cld) {
+    cld->dictionary()->verify();
+  }
+}
+
+void ClassLoaderDataGraph::print_dictionary(bool details) {
+  FOR_ALL_DICTIONARY(cld) {
+    tty->print("Dictionary for class loader ");
+    cld->print_value();
+    tty->cr();
+    cld->dictionary()->print(details);
+  }
+}
+
 GrowableArray<ClassLoaderData*>* ClassLoaderDataGraph::new_clds() {
   assert(_head == NULL || _saved_head != NULL, "remember_new_clds(true) not called?");
 
@@ -1074,14 +1242,19 @@
   }
 
   if (seen_dead_loader) {
-    // Walk a ModuleEntry's reads and a PackageEntry's exports lists
-    // to determine if there are modules on those lists that are now
-    // dead and should be removed.  A module's life cycle is equivalent
-    // to its defining class loader's life cycle.  Since a module is
-    // considered dead if its class loader is dead, these walks must
-    // occur after each class loader's aliveness is determined.
     data = _head;
     while (data != NULL) {
+      // Remove entries in the dictionary of live class loader that have
+      // initiated loading classes in a dead class loader.
+      if (data->dictionary() != NULL) {
+        data->dictionary()->do_unloading();
+      }
+      // Walk a ModuleEntry's reads, and a PackageEntry's exports
+      // lists to determine if there are modules on those lists that are now
+      // dead and should be removed.  A module's life cycle is equivalent
+      // to its defining class loader's life cycle.  Since a module is
+      // considered dead if its class loader is dead, these walks must
+      // occur after each class loader's aliveness is determined.
       if (data->packages() != NULL) {
         data->packages()->purge_all_package_exports();
       }
@@ -1253,6 +1426,15 @@
   }
 }
 
+void ClassLoaderData::print_on(outputStream* out) const {
+  if (class_loader() == NULL) {
+    out->print("NULL class_loader");
+  } else {
+    out->print("class loader " INTPTR_FORMAT " ", p2i(this));
+    class_loader()->print_on(out);
+  }
+}
+
 #if INCLUDE_TRACE
 
 Ticks ClassLoaderDataGraph::_class_unload_time;
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -46,9 +46,8 @@
 // used by the dynamic linker to allocate the runtime representation of all
 // the types it defines.
 //
-// ClassLoaderData are stored in the runtime representation of classes and the
-// system dictionary, are roots of garbage collection, and provides iterators
-// for root tracing and other GC operations.
+// ClassLoaderData are stored in the runtime representation of classes,
+// and provides iterators for root tracing and other GC operations.
 
 class ClassLoaderData;
 class JNIMethodBlock;
@@ -57,6 +56,8 @@
 class PackageEntry;
 class ModuleEntryTable;
 class PackageEntryTable;
+class DictionaryEntry;
+class Dictionary;
 
 // GC root for walking class loader data created
 
@@ -64,6 +65,7 @@
   friend class ClassLoaderData;
   friend class ClassLoaderDataGraphMetaspaceIterator;
   friend class ClassLoaderDataGraphKlassIteratorAtomic;
+  friend class ClassLoaderDataGraphKlassIteratorStatic;
   friend class VMStructs;
  private:
   // All CLDs (except the null CLD) can be reached by walking _head->_next->...
@@ -109,6 +111,22 @@
   static void classes_unloading_do(void f(Klass* const));
   static bool do_unloading(BoolObjectClosure* is_alive, bool clean_previous_versions);
 
+  // dictionary do
+  // Iterate over all klasses in dictionary, but
+  // just the classes from defining class loaders.
+  static void dictionary_classes_do(void f(InstanceKlass*));
+  // Added for initialize_itable_for_klass to handle exceptions.
+  static void dictionary_classes_do(void f(InstanceKlass*, TRAPS), TRAPS);
+
+  // Iterate all classes and their class loaders, including initiating class loaders.
+  static void dictionary_all_entries_do(void f(InstanceKlass*, ClassLoaderData*));
+
+  // VM_CounterDecay iteration support
+  static InstanceKlass* try_get_next_class();
+
+  static void verify_dictionary();
+  static void print_dictionary(bool details);
+
   // CMS support.
   static void remember_new_clds(bool remember) { _saved_head = (remember ? _head : NULL); }
   static GrowableArray<ClassLoaderData*>* new_clds();
@@ -193,6 +211,7 @@
 
   friend class ClassLoaderDataGraph;
   friend class ClassLoaderDataGraphKlassIteratorAtomic;
+  friend class ClassLoaderDataGraphKlassIteratorStatic;
   friend class ClassLoaderDataGraphMetaspaceIterator;
   friend class MetaDataFactory;
   friend class Method;
@@ -221,8 +240,9 @@
 
   Klass* volatile _klasses;              // The classes defined by the class loader.
   PackageEntryTable* volatile _packages; // The packages defined by the class loader.
+  ModuleEntryTable*  volatile _modules;  // The modules defined by the class loader.
   ModuleEntry* _unnamed_module;          // This class loader's unnamed module.
-  ModuleEntryTable* volatile _modules;   // The modules defined by the class loader.
+  Dictionary*  _dictionary;              // The loaded InstanceKlasses, including initiated by this class loader
 
   // 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
@@ -269,6 +289,7 @@
   // Allocate out of this class loader data
   MetaWord* allocate(size_t size);
 
+  Dictionary* create_dictionary();
  public:
 
   bool is_alive(BoolObjectClosure* is_alive_closure) const;
@@ -324,17 +345,20 @@
   void inc_keep_alive();
   void dec_keep_alive();
 
-  inline unsigned int identity_hash() const;
+  inline unsigned int identity_hash() const { return (unsigned int)(((intptr_t)this) >> 3); }
 
   // Used when tracing from klasses.
   void oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim);
 
   void classes_do(KlassClosure* klass_closure);
+  Klass* klasses() { return _klasses; }
 
   JNIMethodBlock* jmethod_ids() const              { return _jmethod_ids; }
   void set_jmethod_ids(JNIMethodBlock* new_block)  { _jmethod_ids = new_block; }
 
-  void print_value() { print_value_on(tty); }
+  void print()                                     { print_on(tty); }
+  void print_on(outputStream* out) const;
+  void print_value()                               { print_value_on(tty); }
   void print_value_on(outputStream* out) const;
   void dump(outputStream * const out) PRODUCT_RETURN;
   void verify();
@@ -352,6 +376,9 @@
   ModuleEntryTable* modules();
   bool modules_defined() { return (_modules != NULL); }
 
+  // Loaded class dictionary
+  Dictionary* dictionary() const { return _dictionary; }
+
   void add_to_deallocate_list(Metadata* m);
 
   static ClassLoaderData* class_loader_data(oop loader);
--- a/hotspot/src/share/vm/classfile/classLoaderData.inline.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/classLoaderData.inline.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -26,10 +26,6 @@
 #include "classfile/javaClasses.hpp"
 #include "oops/oop.inline.hpp"
 
-unsigned int ClassLoaderData::identity_hash() const {
-  return _class_loader == NULL ? 0 : _class_loader->identity_hash();
-}
-
 inline ClassLoaderData* ClassLoaderData::class_loader_data_or_null(oop loader) {
   if (loader == NULL) {
     return ClassLoaderData::the_null_class_loader_data();
--- a/hotspot/src/share/vm/classfile/dictionary.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -34,12 +34,10 @@
 #include "memory/iterator.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/atomic.hpp"
 #include "runtime/orderAccess.inline.hpp"
 #include "utilities/hashtable.inline.hpp"
 
-DictionaryEntry*  Dictionary::_current_class_entry = NULL;
-int               Dictionary::_current_class_index =    0;
-
 size_t Dictionary::entry_size() {
   if (DumpSharedSpaces) {
     return SystemDictionaryShared::dictionary_entry_size();
@@ -48,30 +46,33 @@
   }
 }
 
-Dictionary::Dictionary(int table_size)
-  : TwoOopHashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size()) {
-  _current_class_index = 0;
-  _current_class_entry = NULL;
-  _pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);
+Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size)
+  : _loader_data(loader_data), Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size()) {
 };
 
 
-Dictionary::Dictionary(int table_size, HashtableBucket<mtClass>* t,
+Dictionary::Dictionary(ClassLoaderData* loader_data,
+                       int table_size, HashtableBucket<mtClass>* t,
                        int number_of_entries)
-  : TwoOopHashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size(), t, number_of_entries) {
-  _current_class_index = 0;
-  _current_class_entry = NULL;
-  _pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);
+  : _loader_data(loader_data), Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size(), t, number_of_entries) {
 };
 
-ProtectionDomainCacheEntry* Dictionary::cache_get(Handle protection_domain) {
-  return _pd_cache_table->get(protection_domain);
+Dictionary::~Dictionary() {
+  DictionaryEntry* probe = NULL;
+  for (int index = 0; index < table_size(); index++) {
+    for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
+      probe = *p;
+      *p = probe->next();
+      free_entry(probe);
+    }
+  }
+  assert(number_of_entries() == 0, "should have removed all entries");
+  assert(new_entry_free_list() == NULL, "entry present on Dictionary's free list");
+  free_buckets();
 }
 
-DictionaryEntry* Dictionary::new_entry(unsigned int hash, InstanceKlass* klass,
-                                       ClassLoaderData* loader_data) {
-  DictionaryEntry* entry = (DictionaryEntry*)Hashtable<InstanceKlass*, mtClass>::new_entry(hash, klass);
-  entry->set_loader_data(loader_data);
+DictionaryEntry* Dictionary::new_entry(unsigned int hash, InstanceKlass* klass) {
+  DictionaryEntry* entry = (DictionaryEntry*)Hashtable<InstanceKlass*, mtClass>::allocate_new_entry(hash, klass);
   entry->set_pd_set(NULL);
   assert(klass->is_instance_klass(), "Must be");
   if (DumpSharedSpaces) {
@@ -88,13 +89,15 @@
     entry->set_pd_set(to_delete->next());
     delete to_delete;
   }
-  Hashtable<InstanceKlass*, mtClass>::free_entry(entry);
+  // Unlink from the Hashtable prior to freeing
+  unlink_entry(entry);
+  FREE_C_HEAP_ARRAY(char, entry);
 }
 
 
 bool DictionaryEntry::contains_protection_domain(oop protection_domain) const {
 #ifdef ASSERT
-  if (protection_domain == klass()->protection_domain()) {
+  if (protection_domain == instance_klass()->protection_domain()) {
     // Ensure this doesn't show up in the pd_set (invariant)
     bool in_pd_set = false;
     for (ProtectionDomainEntry* current = _pd_set;
@@ -112,7 +115,7 @@
   }
 #endif /* ASSERT */
 
-  if (protection_domain == klass()->protection_domain()) {
+  if (protection_domain == instance_klass()->protection_domain()) {
     // Succeeds trivially
     return true;
   }
@@ -129,7 +132,7 @@
 void DictionaryEntry::add_protection_domain(Dictionary* dict, Handle protection_domain) {
   assert_locked_or_safepoint(SystemDictionary_lock);
   if (!contains_protection_domain(protection_domain())) {
-    ProtectionDomainCacheEntry* entry = dict->cache_get(protection_domain);
+    ProtectionDomainCacheEntry* entry = SystemDictionary::cache_get(protection_domain);
     ProtectionDomainEntry* new_head =
                 new ProtectionDomainEntry(entry, _pd_set);
     // Warning: Preserve store ordering.  The SystemDictionary is read
@@ -149,86 +152,43 @@
 void Dictionary::do_unloading() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 
-  // Remove unloadable entries and classes from system dictionary
+  // The NULL class loader doesn't initiate loading classes from other class loaders
+  if (loader_data() == ClassLoaderData::the_null_class_loader_data()) {
+    return;
+  }
+
+  // Remove unloaded entries and classes from this dictionary
   DictionaryEntry* probe = NULL;
   for (int index = 0; index < table_size(); index++) {
     for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
       probe = *p;
-      Klass* e = probe->klass();
-      ClassLoaderData* loader_data = probe->loader_data();
-
-      InstanceKlass* ik = InstanceKlass::cast(e);
-
-      // Only unload classes that are not strongly reachable
-      if (!is_strongly_reachable(loader_data, e)) {
-        // Entry was not visited in phase1 (negated test from phase1)
-        assert(!loader_data->is_the_null_class_loader_data(), "unloading entry with null class loader");
-        ClassLoaderData* k_def_class_loader_data = ik->class_loader_data();
-
-        // Do we need to delete this system dictionary entry?
-        bool purge_entry = false;
+      InstanceKlass* ik = probe->instance_klass();
+      ClassLoaderData* k_def_class_loader_data = ik->class_loader_data();
 
-        // Do we need to delete this system dictionary entry?
-        if (loader_data->is_unloading()) {
-          // If the loader is not live this entry should always be
-          // removed (will never be looked up again).
-          purge_entry = true;
-        } else {
-          // The loader in this entry is alive. If the klass is dead,
-          // (determined by checking the defining class loader)
-          // the loader must be an initiating loader (rather than the
-          // defining loader). Remove this entry.
-          if (k_def_class_loader_data->is_unloading()) {
-            // If we get here, the class_loader_data must not be the defining
-            // loader, it must be an initiating one.
-            assert(k_def_class_loader_data != loader_data,
-                   "cannot have live defining loader and unreachable klass");
-            // Loader is live, but class and its defining loader are dead.
-            // Remove the entry. The class is going away.
-            purge_entry = true;
-          }
-        }
-
-        if (purge_entry) {
-          *p = probe->next();
-          if (probe == _current_class_entry) {
-            _current_class_entry = NULL;
-          }
-          free_entry(probe);
-          continue;
-        }
+      // If the klass that this loader initiated is dead,
+      // (determined by checking the defining class loader)
+      // remove this entry.
+      if (k_def_class_loader_data->is_unloading()) {
+        assert(k_def_class_loader_data != loader_data(),
+               "cannot have live defining loader and unreachable klass");
+        *p = probe->next();
+        free_entry(probe);
+        continue;
       }
       p = probe->next_addr();
     }
   }
 }
 
-void Dictionary::roots_oops_do(OopClosure* strong, OopClosure* weak) {
-  // Do strong roots marking if the closures are the same.
-  if (strong == weak || !ClassUnloading) {
-    // Only the protection domain oops contain references into the heap. Iterate
-    // over all of them.
-    _pd_cache_table->oops_do(strong);
-  } else {
-   if (weak != NULL) {
-     _pd_cache_table->oops_do(weak);
-   }
-  }
-}
-
-
 void Dictionary::remove_classes_in_error_state() {
   assert(DumpSharedSpaces, "supported only when dumping");
   DictionaryEntry* probe = NULL;
   for (int index = 0; index < table_size(); index++) {
     for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
       probe = *p;
-      InstanceKlass* ik = InstanceKlass::cast(probe->klass());
+      InstanceKlass* ik = probe->instance_klass();
       if (ik->is_in_error_state()) { // purge this entry
         *p = probe->next();
-        if (probe == _current_class_entry) {
-          _current_class_entry = NULL;
-        }
         free_entry(probe);
         ResourceMark rm;
         tty->print_cr("Preload Warning: Removed error class: %s", ik->external_name());
@@ -241,13 +201,13 @@
 }
 
 //   Just the classes from defining class loaders
-void Dictionary::classes_do(void f(Klass*)) {
+void Dictionary::classes_do(void f(InstanceKlass*)) {
   for (int index = 0; index < table_size(); index++) {
     for (DictionaryEntry* probe = bucket(index);
                           probe != NULL;
                           probe = probe->next()) {
-      Klass* k = probe->klass();
-      if (probe->loader_data() == k->class_loader_data()) {
+      InstanceKlass* k = probe->instance_klass();
+      if (loader_data() == k->class_loader_data()) {
         f(k);
       }
     }
@@ -256,78 +216,50 @@
 
 // Added for initialize_itable_for_klass to handle exceptions
 //   Just the classes from defining class loaders
-void Dictionary::classes_do(void f(Klass*, TRAPS), TRAPS) {
+void Dictionary::classes_do(void f(InstanceKlass*, TRAPS), TRAPS) {
   for (int index = 0; index < table_size(); index++) {
     for (DictionaryEntry* probe = bucket(index);
                           probe != NULL;
                           probe = probe->next()) {
-      Klass* k = probe->klass();
-      if (probe->loader_data() == k->class_loader_data()) {
+      InstanceKlass* k = probe->instance_klass();
+      if (loader_data() == k->class_loader_data()) {
         f(k, CHECK);
       }
     }
   }
 }
 
-//   All classes, and their class loaders
-// Don't iterate over placeholders
-void Dictionary::classes_do(void f(Klass*, ClassLoaderData*)) {
+// All classes, and their class loaders, including initiating class loaders
+void Dictionary::all_entries_do(void f(InstanceKlass*, ClassLoaderData*)) {
   for (int index = 0; index < table_size(); index++) {
     for (DictionaryEntry* probe = bucket(index);
                           probe != NULL;
                           probe = probe->next()) {
-      Klass* k = probe->klass();
-      f(k, probe->loader_data());
+      InstanceKlass* k = probe->instance_klass();
+      f(k, loader_data());
     }
   }
 }
 
-void Dictionary::oops_do(OopClosure* f) {
-  // Only the protection domain oops contain references into the heap. Iterate
-  // over all of them.
-  _pd_cache_table->oops_do(f);
-}
 
-void Dictionary::unlink(BoolObjectClosure* is_alive) {
-  // Only the protection domain cache table may contain references to the heap
-  // that need to be unlinked.
-  _pd_cache_table->unlink(is_alive);
-}
-
-InstanceKlass* Dictionary::try_get_next_class() {
-  while (true) {
-    if (_current_class_entry != NULL) {
-      InstanceKlass* k = _current_class_entry->klass();
-      _current_class_entry = _current_class_entry->next();
-      return k;
-    }
-    _current_class_index = (_current_class_index + 1) % table_size();
-    _current_class_entry = bucket(_current_class_index);
-  }
-  // never reached
-}
-
-// Add a loaded class to the system dictionary.
+// Add a loaded class to the dictionary.
 // Readers of the SystemDictionary aren't always locked, so _buckets
 // is volatile. The store of the next field in the constructor is
 // also cast to volatile;  we do this to ensure store order is maintained
 // by the compilers.
 
-void Dictionary::add_klass(Symbol* class_name, ClassLoaderData* loader_data,
+void Dictionary::add_klass(int index, unsigned int hash, Symbol* class_name,
                            InstanceKlass* obj) {
   assert_locked_or_safepoint(SystemDictionary_lock);
   assert(obj != NULL, "adding NULL obj");
   assert(obj->name() == class_name, "sanity check on name");
-  assert(loader_data != NULL, "Must be non-NULL");
 
-  unsigned int hash = compute_hash(class_name, loader_data);
-  int index = hash_to_index(hash);
-  DictionaryEntry* entry = new_entry(hash, obj, loader_data);
+  DictionaryEntry* entry = new_entry(hash, obj);
   add_entry(index, entry);
 }
 
 
-// This routine does not lock the system dictionary.
+// This routine does not lock the dictionary.
 //
 // Since readers don't hold a lock, we must make sure that system
 // dictionary entries are only removed at a safepoint (when only one
@@ -337,13 +269,14 @@
 // Callers should be aware that an entry could be added just after
 // _buckets[index] is read here, so the caller will not see the new entry.
 DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,
-                                       Symbol* class_name,
-                                       ClassLoaderData* loader_data) {
+                                       Symbol* class_name) {
   for (DictionaryEntry* entry = bucket(index);
                         entry != NULL;
                         entry = entry->next()) {
-    if (entry->hash() == hash && entry->equals(class_name, loader_data)) {
-      return entry;
+    if (entry->hash() == hash && entry->equals(class_name)) {
+      if (!DumpSharedSpaces || SystemDictionaryShared::is_builtin(entry)) {
+        return entry;
+      }
     }
   }
   return NULL;
@@ -351,10 +284,10 @@
 
 
 InstanceKlass* Dictionary::find(int index, unsigned int hash, Symbol* name,
-                                ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
-  DictionaryEntry* entry = get_entry(index, hash, name, loader_data);
+                                Handle protection_domain) {
+  DictionaryEntry* entry = get_entry(index, hash, name);
   if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) {
-    return entry->klass();
+    return entry->instance_klass();
   } else {
     return NULL;
   }
@@ -362,12 +295,12 @@
 
 
 InstanceKlass* Dictionary::find_class(int index, unsigned int hash,
-                                      Symbol* name, ClassLoaderData* loader_data) {
+                                      Symbol* name) {
   assert_locked_or_safepoint(SystemDictionary_lock);
-  assert (index == index_for(name, loader_data), "incorrect index?");
+  assert (index == index_for(name), "incorrect index?");
 
-  DictionaryEntry* entry = get_entry(index, hash, name, loader_data);
-  return (entry != NULL) ? entry->klass() : NULL;
+  DictionaryEntry* entry = get_entry(index, hash, name);
+  return (entry != NULL) ? entry->instance_klass() : NULL;
 }
 
 
@@ -376,19 +309,19 @@
 
 InstanceKlass* Dictionary::find_shared_class(int index, unsigned int hash,
                                              Symbol* name) {
-  assert (index == index_for(name, NULL), "incorrect index?");
+  assert (index == index_for(name), "incorrect index?");
 
-  DictionaryEntry* entry = get_entry(index, hash, name, NULL);
-  return (entry != NULL) ? entry->klass() : NULL;
+  DictionaryEntry* entry = get_entry(index, hash, name);
+  return (entry != NULL) ? entry->instance_klass() : NULL;
 }
 
 
 void Dictionary::add_protection_domain(int index, unsigned int hash,
                                        InstanceKlass* klass,
-                                       ClassLoaderData* loader_data, Handle protection_domain,
+                                       Handle protection_domain,
                                        TRAPS) {
   Symbol*  klass_name = klass->name();
-  DictionaryEntry* entry = get_entry(index, hash, klass_name, loader_data);
+  DictionaryEntry* entry = get_entry(index, hash, klass_name);
 
   assert(entry != NULL,"entry must be present, we just created it");
   assert(protection_domain() != NULL,
@@ -403,9 +336,8 @@
 
 bool Dictionary::is_valid_protection_domain(int index, unsigned int hash,
                                             Symbol* name,
-                                            ClassLoaderData* loader_data,
                                             Handle protection_domain) {
-  DictionaryEntry* entry = get_entry(index, hash, name, loader_data);
+  DictionaryEntry* entry = get_entry(index, hash, name);
   return entry->is_valid_protection_domain(protection_domain);
 }
 
@@ -432,13 +364,12 @@
     DictionaryEntry* p = master_list;
     master_list = master_list->next();
     p->set_next(NULL);
-    Symbol* class_name = p->klass()->name();
+    Symbol* class_name = p->instance_klass()->name();
     // Since the null class loader data isn't copied to the CDS archive,
     // compute the hash with NULL for loader data.
-    unsigned int hash = compute_hash(class_name, NULL);
+    unsigned int hash = compute_hash(class_name);
     int index = hash_to_index(hash);
     p->set_hash(hash);
-    p->set_loader_data(NULL);   // loader_data isn't copied to CDS
     p->set_next(bucket(index));
     set_entry(index, p);
   }
@@ -507,8 +438,9 @@
 void Dictionary::print(bool details) {
   ResourceMark rm;
 
+  assert(loader_data() != NULL, "loader data should not be null");
   if (details) {
-    tty->print_cr("Java system dictionary (table_size=%d, classes=%d)",
+    tty->print_cr("Java dictionary (table_size=%d, classes=%d)",
                    table_size(), number_of_entries());
     tty->print_cr("^ indicates that initiating loader is different from "
                   "defining loader");
@@ -518,10 +450,9 @@
     for (DictionaryEntry* probe = bucket(index);
                           probe != NULL;
                           probe = probe->next()) {
-      Klass* e = probe->klass();
-      ClassLoaderData* loader_data =  probe->loader_data();
+      Klass* e = probe->instance_klass();
       bool is_defining_class =
-         (loader_data == e->class_loader_data());
+         (loader_data() == e->class_loader_data());
       if (details) {
         tty->print("%4d: ", index);
       }
@@ -530,41 +461,36 @@
 
       if (details) {
         tty->print(", loader ");
-        if (loader_data != NULL) {
-          loader_data->print_value();
-        } else {
-          tty->print("NULL");
-        }
+        e->class_loader_data()->print_value();
       }
       tty->cr();
     }
   }
-
-  if (details) {
-    tty->cr();
-    _pd_cache_table->print();
-  }
   tty->cr();
 }
 
 void DictionaryEntry::verify() {
-  Klass* e = klass();
+  Klass* e = instance_klass();
+  guarantee(e->is_instance_klass(),
+                          "Verify of dictionary failed");
+  e->verify();
+  verify_protection_domain_set();
+}
+
+void Dictionary::verify() {
+  guarantee(number_of_entries() >= 0, "Verify of dictionary failed");
+
   ClassLoaderData* cld = loader_data();
-  guarantee(e->is_instance_klass(),
-                          "Verify of system dictionary failed");
   // class loader must be present;  a null class loader is the
   // boostrap loader
   guarantee(cld != NULL || DumpSharedSpaces ||
             cld->class_loader() == NULL ||
             cld->class_loader()->is_instance(),
             "checking type of class_loader");
-  e->verify();
-  verify_protection_domain_set();
+
+  ResourceMark rm;
+  stringStream tempst;
+  tempst.print("System Dictionary for %s", cld->loader_name());
+  verify_table<DictionaryEntry>(tempst.as_string());
 }
 
-void Dictionary::verify() {
-  guarantee(number_of_entries() >= 0, "Verify of system dictionary failed");
-  verify_table<DictionaryEntry>("System Dictionary");
-  _pd_cache_table->verify();
-}
-
--- a/hotspot/src/share/vm/classfile/dictionary.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/dictionary.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -36,21 +36,16 @@
 class BoolObjectClosure;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// The data structure for the system dictionary (and the shared system
+// The data structure for the class loader data dictionaries (and the shared system
 // dictionary).
 
-class Dictionary : public TwoOopHashtable<InstanceKlass*, mtClass> {
+class Dictionary : public Hashtable<InstanceKlass*, mtClass> {
   friend class VMStructs;
-private:
-  // current iteration index.
-  static int                    _current_class_index;
-  // pointer to the current hash table entry.
-  static DictionaryEntry*       _current_class_entry;
 
-  ProtectionDomainCacheTable*   _pd_cache_table;
+  ClassLoaderData* _loader_data;  // backpointer to owning loader
+  ClassLoaderData* loader_data() const { return _loader_data; }
 
-  DictionaryEntry* get_entry(int index, unsigned int hash,
-                             Symbol* name, ClassLoaderData* loader_data);
+  DictionaryEntry* get_entry(int index, unsigned int hash, Symbol* name);
 
 protected:
   DictionaryEntry* bucket(int i) const {
@@ -66,61 +61,48 @@
     Hashtable<InstanceKlass*, mtClass>::add_entry(index, (HashtableEntry<InstanceKlass*, mtClass>*)new_entry);
   }
 
-  static size_t entry_size();
-public:
-  Dictionary(int table_size);
-  Dictionary(int table_size, HashtableBucket<mtClass>* t, int number_of_entries);
-
-  DictionaryEntry* new_entry(unsigned int hash, InstanceKlass* klass, ClassLoaderData* loader_data);
-
   void free_entry(DictionaryEntry* entry);
 
-  void add_klass(Symbol* class_name, ClassLoaderData* loader_data, InstanceKlass* obj);
+  static size_t entry_size();
+public:
+  Dictionary(ClassLoaderData* loader_data, int table_size);
+  Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket<mtClass>* t, int number_of_entries);
+  ~Dictionary();
 
-  InstanceKlass* find_class(int index, unsigned int hash,
-                            Symbol* name, ClassLoaderData* loader_data);
+  DictionaryEntry* new_entry(unsigned int hash, InstanceKlass* klass);
+
+  void add_klass(int index, unsigned int hash, Symbol* class_name, InstanceKlass* obj);
+
+  InstanceKlass* find_class(int index, unsigned int hash, Symbol* name);
 
   InstanceKlass* find_shared_class(int index, unsigned int hash, Symbol* name);
 
-  // Compiler support
-  InstanceKlass* try_get_next_class();
-
   // GC support
   void oops_do(OopClosure* f);
   void roots_oops_do(OopClosure* strong, OopClosure* weak);
 
-  void classes_do(void f(Klass*));
-  void classes_do(void f(Klass*, TRAPS), TRAPS);
-  void classes_do(void f(Klass*, ClassLoaderData*));
+  void classes_do(void f(InstanceKlass*));
+  void classes_do(void f(InstanceKlass*, TRAPS), TRAPS);
+  void all_entries_do(void f(InstanceKlass*, ClassLoaderData*));
 
   void unlink(BoolObjectClosure* is_alive);
   void remove_classes_in_error_state();
 
-  // Classes loaded by the bootstrap loader are always strongly reachable.
-  // If we're not doing class unloading, all classes are strongly reachable.
-  static bool is_strongly_reachable(ClassLoaderData* loader_data, Klass* klass) {
-    assert (klass != NULL, "should have non-null klass");
-    return (loader_data->is_the_null_class_loader_data() || !ClassUnloading);
-  }
-
-  // Unload (that is, break root links to) all unmarked classes and loaders.
+  // Unload classes whose defining loaders are unloaded
   void do_unloading();
 
   // Protection domains
-  InstanceKlass* find(int index, unsigned int hash, Symbol* name,
-                      ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
+  InstanceKlass* find(int index, unsigned int hash, Symbol* name, Handle protection_domain);
   bool is_valid_protection_domain(int index, unsigned int hash,
-                                  Symbol* name, ClassLoaderData* loader_data,
+                                  Symbol* name,
                                   Handle protection_domain);
   void add_protection_domain(int index, unsigned int hash,
-                             InstanceKlass* klass, ClassLoaderData* loader_data,
+                             InstanceKlass* klass,
                              Handle protection_domain, TRAPS);
 
   // Sharing support
   void reorder_dictionary();
 
-  ProtectionDomainCacheEntry* cache_get(Handle protection_domain);
-
   void print(bool details = true);
 #ifdef ASSERT
   void printPerformanceInfoDetails();
@@ -128,14 +110,14 @@
   void verify();
 };
 
-// An entry in the system dictionary, this describes a class as
-// { InstanceKlass*, loader, protection_domain }.
+// An entry in the class loader data dictionaries, this describes a class as
+// { InstanceKlass*, protection_domain }.
 
 class DictionaryEntry : public HashtableEntry<InstanceKlass*, mtClass> {
   friend class VMStructs;
  private:
   // Contains the set of approved protection domains that can access
-  // this system dictionary entry.
+  // this dictionary entry.
   //
   // This protection domain set is a set of tuples:
   //
@@ -155,7 +137,6 @@
   // ClassLoader.checkPackageAccess().
   //
   ProtectionDomainEntry* _pd_set;
-  ClassLoaderData*       _loader_data;
 
  public:
   // Tells whether a protection is in the approved set.
@@ -163,7 +144,7 @@
   // Adds a protection domain to the approved set.
   void add_protection_domain(Dictionary* dict, Handle protection_domain);
 
-  InstanceKlass* klass() const { return (InstanceKlass*)literal(); }
+  InstanceKlass* instance_klass() const { return literal(); }
 
   DictionaryEntry* next() const {
     return (DictionaryEntry*)HashtableEntry<InstanceKlass*, mtClass>::next();
@@ -173,13 +154,10 @@
     return (DictionaryEntry**)HashtableEntry<InstanceKlass*, mtClass>::next_addr();
   }
 
-  ClassLoaderData* loader_data() const { return _loader_data; }
-  void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
-
   ProtectionDomainEntry* pd_set() const { return _pd_set; }
   void set_pd_set(ProtectionDomainEntry* pd_set) { _pd_set = pd_set; }
 
-  // Tells whether the initiating class' protection can access the this _klass
+  // Tells whether the initiating class' protection domain can access the klass in this entry
   bool is_valid_protection_domain(Handle protection_domain) {
     if (!ProtectionDomainVerification) return true;
     if (!SystemDictionary::has_checkPackageAccess()) return true;
@@ -197,9 +175,9 @@
     }
   }
 
-  bool equals(const Symbol* class_name, ClassLoaderData* loader_data) const {
+  bool equals(const Symbol* class_name) const {
     InstanceKlass* klass = (InstanceKlass*)literal();
-    return (klass->name() == class_name && _loader_data == loader_data);
+    return (klass->name() == class_name);
   }
 
   void print_count(outputStream *st) {
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1082,8 +1082,8 @@
   return name;
 }
 
-Klass* java_lang_Class::array_klass(oop java_class) {
-  Klass* k = ((Klass*)java_class->metadata_field(_array_klass_offset));
+Klass* java_lang_Class::array_klass_acquire(oop java_class) {
+  Klass* k = ((Klass*)java_class->metadata_field_acquire(_array_klass_offset));
   assert(k == NULL || k->is_klass() && k->is_array_klass(), "should be array klass");
   return k;
 }
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -236,7 +236,7 @@
   static BasicType primitive_type(oop java_class);
   static oop primitive_mirror(BasicType t);
   // JVM_NewArray support
-  static Klass* array_klass(oop java_class);
+  static Klass* array_klass_acquire(oop java_class);
   static void release_set_array_klass(oop java_class, Klass* klass);
   // compiler support for class operations
   static int klass_offset_in_bytes()                { return _klass_offset; }
--- a/hotspot/src/share/vm/classfile/loaderConstraints.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/loaderConstraints.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/dictionary.hpp"
 #include "classfile/classLoaderData.inline.hpp"
 #include "classfile/loaderConstraints.hpp"
 #include "logging/log.hpp"
@@ -36,8 +37,8 @@
   set_loader_data(i, ClassLoaderData::class_loader_data(p));
 }
 
-LoaderConstraintTable::LoaderConstraintTable(int nof_buckets)
-  : Hashtable<InstanceKlass*, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
+LoaderConstraintTable::LoaderConstraintTable(int table_size)
+  : Hashtable<InstanceKlass*, mtClass>(table_size, sizeof(LoaderConstraintEntry)) {};
 
 
 LoaderConstraintEntry* LoaderConstraintTable::new_entry(
@@ -315,7 +316,7 @@
   LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
   if (p != NULL && p->klass() != NULL) {
     assert(p->klass()->is_instance_klass(), "sanity");
-    if (p->klass()->is_loaded()) {
+    if (!p->klass()->is_loaded()) {
       // Only return fully loaded classes.  Classes found through the
       // constraints might still be in the process of loading.
       return NULL;
@@ -425,10 +426,9 @@
 }
 
 
-void LoaderConstraintTable::verify(Dictionary* dictionary,
-                                   PlaceholderTable* placeholders) {
+void LoaderConstraintTable::verify(PlaceholderTable* placeholders) {
   Thread *thread = Thread::current();
-  for (int cindex = 0; cindex < _loader_constraint_size; cindex++) {
+  for (int cindex = 0; cindex < table_size(); cindex++) {
     for (LoaderConstraintEntry* probe = bucket(cindex);
                                 probe != NULL;
                                 probe = probe->next()) {
@@ -437,17 +437,18 @@
         guarantee(ik->name() == probe->name(), "name should match");
         Symbol* name = ik->name();
         ClassLoaderData* loader_data = ik->class_loader_data();
-        unsigned int d_hash = dictionary->compute_hash(name, loader_data);
+        Dictionary* dictionary = loader_data->dictionary();
+        unsigned int d_hash = dictionary->compute_hash(name);
         int d_index = dictionary->hash_to_index(d_hash);
-        InstanceKlass* k = dictionary->find_class(d_index, d_hash, name, loader_data);
+        InstanceKlass* k = dictionary->find_class(d_index, d_hash, name);
         if (k != NULL) {
-          // We found the class in the system dictionary, so we should
+          // We found the class in the dictionary, so we should
           // make sure that the Klass* matches what we already have.
           guarantee(k == probe->klass(), "klass should be in dictionary");
         } else {
-          // If we don't find the class in the system dictionary, it
+          // If we don't find the class in the dictionary, it
           // has to be in the placeholders table.
-          unsigned int p_hash = placeholders->compute_hash(name, loader_data);
+          unsigned int p_hash = placeholders->compute_hash(name);
           int p_index = placeholders->hash_to_index(p_hash);
           PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash,
                                                             name, loader_data);
@@ -471,8 +472,9 @@
 void LoaderConstraintTable::print() {
   ResourceMark rm;
   assert_locked_or_safepoint(SystemDictionary_lock);
-  tty->print_cr("Java loader constraints (entries=%d)", _loader_constraint_size);
-  for (int cindex = 0; cindex < _loader_constraint_size; cindex++) {
+  tty->print_cr("Java loader constraints (entries=%d, constraints=%d)",
+                table_size(), number_of_entries());
+  for (int cindex = 0; cindex < table_size(); cindex++) {
     for (LoaderConstraintEntry* probe = bucket(cindex);
                                 probe != NULL;
                                 probe = probe->next()) {
--- a/hotspot/src/share/vm/classfile/loaderConstraints.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/loaderConstraints.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -25,28 +25,22 @@
 #ifndef SHARE_VM_CLASSFILE_LOADERCONSTRAINTS_HPP
 #define SHARE_VM_CLASSFILE_LOADERCONSTRAINTS_HPP
 
-#include "classfile/dictionary.hpp"
 #include "classfile/placeholders.hpp"
 #include "utilities/hashtable.hpp"
 
+class ClassLoaderData;
 class LoaderConstraintEntry;
 class Symbol;
 
 class LoaderConstraintTable : public Hashtable<InstanceKlass*, mtClass> {
-  friend class VMStructs;
+
 private:
-
-  enum Constants {
-    _loader_constraint_size = 107,                     // number of entries in constraint table
-    _nof_buckets            = 1009                     // number of buckets in hash table
-  };
-
   LoaderConstraintEntry** find_loader_constraint(Symbol* name,
                                                  Handle loader);
 
 public:
 
-  LoaderConstraintTable(int nof_buckets);
+  LoaderConstraintTable(int table_size);
 
   LoaderConstraintEntry* new_entry(unsigned int hash, Symbol* name,
                                    InstanceKlass* klass, int num_loaders,
@@ -84,14 +78,13 @@
 
   void purge_loader_constraints();
 
-  void verify(Dictionary* dictionary, PlaceholderTable* placeholders);
+  void verify(PlaceholderTable* placeholders);
 #ifndef PRODUCT
   void print();
 #endif
 };
 
 class LoaderConstraintEntry : public HashtableEntry<InstanceKlass*, mtClass> {
-  friend class VMStructs;
 private:
   Symbol*                _name;                   // class name
   int                    _num_loaders;
--- a/hotspot/src/share/vm/classfile/moduleEntry.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -339,12 +339,7 @@
                                          Symbol* version, Symbol* location,
                                          ClassLoaderData* loader_data) {
   assert(Module_lock->owned_by_self(), "should have the Module_lock");
-  ModuleEntry* entry = (ModuleEntry*) NEW_C_HEAP_ARRAY(char, entry_size(), mtModule);
-
-  // Initialize everything BasicHashtable would
-  entry->set_next(NULL);
-  entry->set_hash(hash);
-  entry->set_literal(name);
+  ModuleEntry* entry = (ModuleEntry*)Hashtable<Symbol*, mtModule>::allocate_new_entry(hash, name);
 
   // Initialize fields specific to a ModuleEntry
   entry->init();
--- a/hotspot/src/share/vm/classfile/packageEntry.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/packageEntry.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -198,12 +198,7 @@
 
 PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, ModuleEntry* module) {
   assert(Module_lock->owned_by_self(), "should have the Module_lock");
-  PackageEntry* entry = (PackageEntry*) NEW_C_HEAP_ARRAY(char, entry_size(), mtModule);
-
-  // Initialize everything BasicHashtable would
-  entry->set_next(NULL);
-  entry->set_hash(hash);
-  entry->set_literal(name);
+  PackageEntry* entry = (PackageEntry*)Hashtable<Symbol*, mtModule>::allocate_new_entry(hash, name);
 
   TRACE_INIT_ID(entry);
 
--- a/hotspot/src/share/vm/classfile/placeholders.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/placeholders.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -172,7 +172,7 @@
   }
 
 PlaceholderTable::PlaceholderTable(int table_size)
-    : TwoOopHashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
+    : Hashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
 }
 
 #ifndef PRODUCT
--- a/hotspot/src/share/vm/classfile/placeholders.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/placeholders.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -34,8 +34,7 @@
 // being loaded, as well as arrays of primitives.
 //
 
-class PlaceholderTable : public TwoOopHashtable<Symbol*, mtClass> {
-  friend class VMStructs;
+class PlaceholderTable : public Hashtable<Symbol*, mtClass> {
 
 public:
   PlaceholderTable(int table_size);
@@ -149,8 +148,6 @@
 // The system dictionary is the only user of this class.
 
 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
-  friend class VMStructs;
-
 
  private:
   ClassLoaderData*  _loader_data;   // initiating loader
--- a/hotspot/src/share/vm/classfile/protectionDomainCache.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/protectionDomainCache.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -88,14 +88,14 @@
     for (ProtectionDomainCacheEntry* probe = bucket(index);
                                      probe != NULL;
                                      probe = probe->next()) {
+      tty->print("%4d: ", index);
       probe->print();
     }
   }
 }
 
 void ProtectionDomainCacheEntry::print() {
-  tty->print_cr("entry " PTR_FORMAT " value " PTR_FORMAT " next " PTR_FORMAT,
-                p2i(this), p2i(literal()), p2i(next()));
+  tty->print_cr("protection_domain: " PTR_FORMAT, p2i(literal()));
 }
 #endif
 
--- a/hotspot/src/share/vm/classfile/protectionDomainCache.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/protectionDomainCache.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -33,7 +33,7 @@
 // Dictionary entry pd_set point to entries in this hashtable.   Please refer
 // to dictionary.hpp pd_set for more information about how protection domain entries
 // are used.
-// This table is walked during GC, rather than the entire system dictionary
+// This table is walked during GC, rather than the class loader data graph dictionaries.
 class ProtectionDomainCacheEntry : public HashtableEntry<oop, mtClass> {
   friend class VMStructs;
  public:
@@ -55,7 +55,7 @@
   void verify();
 };
 
-// The ProtectionDomainCacheTable contains all protection domain oops. The system
+// The ProtectionDomainCacheTable contains all protection domain oops. The
 // dictionary entries reference its entries instead of having references to oops
 // directly.
 // This is used to speed up system dictionary iteration: the oops in the
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -35,6 +35,7 @@
 #include "classfile/loaderConstraints.hpp"
 #include "classfile/packageEntry.hpp"
 #include "classfile/placeholders.hpp"
+#include "classfile/protectionDomainCache.hpp"
 #include "classfile/resolutionErrors.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -88,19 +89,14 @@
 #include "trace/tracing.hpp"
 #endif
 
-Dictionary*            SystemDictionary::_dictionary          = NULL;
 PlaceholderTable*      SystemDictionary::_placeholders        = NULL;
 Dictionary*            SystemDictionary::_shared_dictionary   = NULL;
 LoaderConstraintTable* SystemDictionary::_loader_constraints  = NULL;
 ResolutionErrorTable*  SystemDictionary::_resolution_errors   = NULL;
 SymbolPropertyTable*   SystemDictionary::_invoke_method_table = NULL;
-
+ProtectionDomainCacheTable*   SystemDictionary::_pd_cache_table = NULL;
 
 int         SystemDictionary::_number_of_modifications = 0;
-int         SystemDictionary::_sdgeneration               = 0;
-const int   SystemDictionary::_primelist[_prime_array_size] = {1009,2017,4049,5051,10103,
-              20201,40423,99991};
-
 oop         SystemDictionary::_system_loader_lock_obj     =  NULL;
 
 InstanceKlass*      SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT]
@@ -116,6 +112,10 @@
 // lazily initialized klass variables
 InstanceKlass* volatile SystemDictionary::_abstract_ownable_synchronizer_klass = NULL;
 
+// Default ProtectionDomainCacheSize value
+
+const int defaultProtectionDomainCacheSize = 1009;
+
 
 // ----------------------------------------------------------------------------
 // Java-level SystemLoader
@@ -343,32 +343,32 @@
 #endif // INCLUDE_CDS
 
   // Double-check, if child class is already loaded, just return super-class,interface
-  // Don't add a placedholder if already loaded, i.e. already in system dictionary
+  // Don't add a placedholder if already loaded, i.e. already in appropriate class loader
+  // dictionary.
   // Make sure there's a placeholder for the *child* before resolving.
   // Used as a claim that this thread is currently loading superclass/classloader
   // Used here for ClassCircularity checks and also for heap verification
-  // (every InstanceKlass in the heap needs to be in the system dictionary
-  // or have a placeholder).
-  // Must check ClassCircularity before checking if super class is already loaded
+  // (every InstanceKlass needs to be in its class loader dictionary or have a placeholder).
+  // Must check ClassCircularity before checking if super class is already loaded.
   //
   // We might not already have a placeholder if this child_name was
   // first seen via resolve_from_stream (jni_DefineClass or JVM_DefineClass);
   // the name of the class might not be known until the stream is actually
   // parsed.
   // Bugs 4643874, 4715493
-  // compute_hash can have a safepoint
 
   ClassLoaderData* loader_data = class_loader_data(class_loader);
-  unsigned int d_hash = dictionary()->compute_hash(child_name, loader_data);
-  int d_index = dictionary()->hash_to_index(d_hash);
-  unsigned int p_hash = placeholders()->compute_hash(child_name, loader_data);
+  Dictionary* dictionary = loader_data->dictionary();
+  unsigned int d_hash = dictionary->compute_hash(child_name);
+  int d_index = dictionary->hash_to_index(d_hash);
+  unsigned int p_hash = placeholders()->compute_hash(child_name);
   int p_index = placeholders()->hash_to_index(p_hash);
   // can't throw error holding a lock
   bool child_already_loaded = false;
   bool throw_circularity_error = false;
   {
     MutexLocker mu(SystemDictionary_lock, THREAD);
-    Klass* childk = find_class(d_index, d_hash, child_name, loader_data);
+    Klass* childk = find_class(d_index, d_hash, child_name, dictionary);
     Klass* quicksuperk;
     // to support // loading: if child done loading, just return superclass
     // if class_name, & class_loader don't match:
@@ -445,13 +445,18 @@
     ls.cr();
   }
 
+  // This handle and the class_loader handle passed in keeps this class from
+  // being unloaded through several GC points.
+  // The class_loader handle passed in is the initiating loader.
+  Handle mirror(THREAD, klass->java_mirror());
+
   InstanceKlass* system_loader = SystemDictionary::ClassLoader_klass();
   JavaCalls::call_special(&result,
                          class_loader,
                          system_loader,
                          vmSymbols::checkPackageAccess_name(),
                          vmSymbols::class_protectiondomain_signature(),
-                         Handle(THREAD, klass->java_mirror()),
+                         mirror,
                          protection_domain,
                          THREAD);
 
@@ -466,27 +471,16 @@
   // If no exception has been thrown, we have validated the protection domain
   // Insert the protection domain of the initiating class into the set.
   {
-    // We recalculate the entry here -- we've called out to java since
-    // the last time it was calculated.
     ClassLoaderData* loader_data = class_loader_data(class_loader);
+    Dictionary* dictionary = loader_data->dictionary();
 
     Symbol*  kn = klass->name();
-    unsigned int d_hash = dictionary()->compute_hash(kn, loader_data);
-    int d_index = dictionary()->hash_to_index(d_hash);
+    unsigned int d_hash = dictionary->compute_hash(kn);
+    int d_index = dictionary->hash_to_index(d_hash);
 
     MutexLocker mu(SystemDictionary_lock, THREAD);
-    {
-      // Note that we have an entry, and entries can be deleted only during GC,
-      // so we cannot allow GC to occur while we're holding this entry.
-
-      // We're using a NoSafepointVerifier to catch any place where we
-      // might potentially do a GC at all.
-      // Dictionary::do_unloading() asserts that classes in SD are only
-      // unloaded at a safepoint. Anonymous classes are not in SD.
-      NoSafepointVerifier nosafepoint;
-      dictionary()->add_protection_domain(d_index, d_hash, klass, loader_data,
-                                          protection_domain, THREAD);
-    }
+    dictionary->add_protection_domain(d_index, d_hash, klass,
+                                      protection_domain, THREAD);
   }
 }
 
@@ -548,9 +542,10 @@
     Handle protection_domain, Handle lockObject, TRAPS) {
 
   ClassLoaderData* loader_data = class_loader_data(class_loader);
-  unsigned int d_hash = dictionary()->compute_hash(name, loader_data);
-  int d_index = dictionary()->hash_to_index(d_hash);
-  unsigned int p_hash = placeholders()->compute_hash(name, loader_data);
+  Dictionary* dictionary = loader_data->dictionary();
+  unsigned int d_hash = dictionary->compute_hash(name);
+  int d_index = dictionary->hash_to_index(d_hash);
+  unsigned int p_hash = placeholders()->compute_hash(name);
   int p_index = placeholders()->hash_to_index(p_hash);
 
   // superk is not used, resolve_super called for circularity check only
@@ -573,7 +568,7 @@
  if (!class_loader.is_null() && is_parallelCapable(class_loader)) {
     MutexLocker mu(SystemDictionary_lock, THREAD);
     // Check if classloading completed while we were loading superclass or waiting
-    return find_class(d_index, d_hash, name, loader_data);
+    return find_class(d_index, d_hash, name, dictionary);
   }
 
   // must loop to both handle other placeholder updates
@@ -583,7 +578,7 @@
   while (super_load_in_progress) {
     MutexLocker mu(SystemDictionary_lock, THREAD);
     // Check if classloading completed while we were loading superclass or waiting
-    InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
+    InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
     if (check != NULL) {
       // Klass is already loaded, so just return it
       return check;
@@ -663,6 +658,7 @@
   // Fix for 4474172; see evaluation for more details
   class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
   ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL);
+  Dictionary* dictionary = loader_data->dictionary();
 
   // Do lookup to see if class already exist and the protection domain
   // has the right access
@@ -670,10 +666,9 @@
   // All subsequent calls use find_class, and set has_loaded_class so that
   // before we return a result we call out to java to check for valid protection domain
   // to allow returning the Klass* and add it to the pd_set if it is valid
-  unsigned int d_hash = dictionary()->compute_hash(name, loader_data);
-  int d_index = dictionary()->hash_to_index(d_hash);
-  Klass* probe = dictionary()->find(d_index, d_hash, name, loader_data,
-                                      protection_domain, THREAD);
+  unsigned int d_hash = dictionary->compute_hash(name);
+  int d_index = dictionary->hash_to_index(d_hash);
+  Klass* probe = dictionary->find(d_index, d_hash, name, protection_domain);
   if (probe != NULL) return probe;
 
 
@@ -691,7 +686,7 @@
     DoObjectLock = false;
   }
 
-  unsigned int p_hash = placeholders()->compute_hash(name, loader_data);
+  unsigned int p_hash = placeholders()->compute_hash(name);
   int p_index = placeholders()->hash_to_index(p_hash);
 
   // Class is not in SystemDictionary so we have to do loading.
@@ -710,7 +705,7 @@
 
   {
     MutexLocker mu(SystemDictionary_lock, THREAD);
-    InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
+    InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
     if (check != NULL) {
       // Klass is already loaded, so just return it
       class_has_been_loaded = true;
@@ -794,7 +789,7 @@
                 double_lock_wait(lockObject, THREAD);
               }
               // Check if classloading completed while we were waiting
-              InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
+              InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
               if (check != NULL) {
                 // Klass is already loaded, so just return it
                 k = check;
@@ -819,7 +814,7 @@
         // i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL
         // one final check if the load has already completed
         // class loaders holding the ObjectLock shouldn't find the class here
-        InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
+        InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
         if (check != NULL) {
         // Klass is already loaded, so return it after checking/adding protection domain
           k = check;
@@ -852,7 +847,7 @@
         if (k == NULL && HAS_PENDING_EXCEPTION
           && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
           MutexLocker mu(SystemDictionary_lock, THREAD);
-          InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
+          InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
           if (check != NULL) {
             // Klass is already loaded, so just use it
             k = check;
@@ -886,7 +881,7 @@
           }
         }
       }
-    } // load_instance_class loop
+    } // load_instance_class
 
     if (load_instance_added == true) {
       // clean up placeholder entries for LOAD_INSTANCE success or error
@@ -919,16 +914,8 @@
   // Check the protection domain has the right access
   {
     MutexLocker mu(SystemDictionary_lock, THREAD);
-    // Note that we have an entry, and entries can be deleted only during GC,
-    // so we cannot allow GC to occur while we're holding this entry.
-    // We're using a NoSafepointVerifier to catch any place where we
-    // might potentially do a GC at all.
-    // Dictionary::do_unloading() asserts that classes in SD are only
-    // unloaded at a safepoint. Anonymous classes are not in SD.
-    NoSafepointVerifier nosafepoint;
-    if (dictionary()->is_valid_protection_domain(d_index, d_hash, name,
-                                                 loader_data,
-                                                 protection_domain)) {
+    if (dictionary->is_valid_protection_domain(d_index, d_hash, name,
+                                               protection_domain)) {
       return k;
     }
   }
@@ -968,20 +955,11 @@
     return NULL;
   }
 
-  unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
-  int d_index = dictionary()->hash_to_index(d_hash);
-
-  {
-    // Note that we have an entry, and entries can be deleted only during GC,
-    // so we cannot allow GC to occur while we're holding this entry.
-    // We're using a NoSafepointVerifier to catch any place where we
-    // might potentially do a GC at all.
-    // Dictionary::do_unloading() asserts that classes in SD are only
-    // unloaded at a safepoint. Anonymous classes are not in SD.
-    NoSafepointVerifier nosafepoint;
-    return dictionary()->find(d_index, d_hash, class_name, loader_data,
-                              protection_domain, THREAD);
-  }
+  Dictionary* dictionary = loader_data->dictionary();
+  unsigned int d_hash = dictionary->compute_hash(class_name);
+  int d_index = dictionary->hash_to_index(d_hash);
+  return dictionary->find(d_index, d_hash, class_name,
+                          protection_domain);
 }
 
 
@@ -1035,7 +1013,6 @@
     guarantee(host_klass->class_loader() == class_loader(), "should be the same");
     guarantee(!DumpSharedSpaces, "must not create anonymous classes when dumping");
     loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader(), CHECK_NULL);
-    loader_data->record_dependency(host_klass, CHECK_NULL);
   } else {
     loader_data = ClassLoaderData::class_loader_data(class_loader());
   }
@@ -1066,7 +1043,7 @@
       // deoptimizations.
       add_to_hierarchy(k, CHECK_NULL); // No exception, but can block
 
-      // But, do not add to system dictionary.
+      // But, do not add to dictionary.
 
       // compiled code dependencies need to be validated anyway
       notice_modification();
@@ -1189,9 +1166,10 @@
 #if INCLUDE_CDS
 void SystemDictionary::set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
                                              int number_of_entries) {
-  assert(length == _nof_buckets * sizeof(HashtableBucket<mtClass>),
+  assert(length == _shared_dictionary_size * sizeof(HashtableBucket<mtClass>),
          "bad shared dictionary size.");
-  _shared_dictionary = new Dictionary(_nof_buckets, t, number_of_entries);
+  _shared_dictionary = new Dictionary(ClassLoaderData::the_null_class_loader_data(),
+                                      _shared_dictionary_size, t, number_of_entries);
 }
 
 
@@ -1200,7 +1178,7 @@
 
 InstanceKlass* SystemDictionary::find_shared_class(Symbol* class_name) {
   if (shared_dictionary() != NULL) {
-    unsigned int d_hash = shared_dictionary()->compute_hash(class_name, NULL);
+    unsigned int d_hash = shared_dictionary()->compute_hash(class_name);
     int d_index = shared_dictionary()->hash_to_index(d_hash);
 
     return shared_dictionary()->find_shared_class(d_index, d_hash, class_name);
@@ -1626,8 +1604,9 @@
   // Parallel classloaders will call find_or_define_instance_class
   // which will require a token to perform the define class
   Symbol*  name_h = k->name();
-  unsigned int d_hash = dictionary()->compute_hash(name_h, loader_data);
-  int d_index = dictionary()->hash_to_index(d_hash);
+  Dictionary* dictionary = loader_data->dictionary();
+  unsigned int d_hash = dictionary->compute_hash(name_h);
+  int d_index = dictionary->hash_to_index(d_hash);
   check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK);
 
   // Register class just loaded with class loader (placed in Vector)
@@ -1645,7 +1624,7 @@
 
   // Add the new class. We need recompile lock during update of CHA.
   {
-    unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data);
+    unsigned int p_hash = placeholders()->compute_hash(name_h);
     int p_index = placeholders()->hash_to_index(p_hash);
 
     MutexLocker mu_r(Compile_lock, THREAD);
@@ -1695,12 +1674,13 @@
 
   Symbol*  name_h = k->name(); // passed in class_name may be null
   ClassLoaderData* loader_data = class_loader_data(class_loader);
+  Dictionary* dictionary = loader_data->dictionary();
 
-  unsigned int d_hash = dictionary()->compute_hash(name_h, loader_data);
-  int d_index = dictionary()->hash_to_index(d_hash);
+  unsigned int d_hash = dictionary->compute_hash(name_h);
+  int d_index = dictionary->hash_to_index(d_hash);
 
   // Hold SD lock around find_class and placeholder creation for DEFINE_CLASS
-  unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data);
+  unsigned int p_hash = placeholders()->compute_hash(name_h);
   int p_index = placeholders()->hash_to_index(p_hash);
   PlaceholderEntry* probe;
 
@@ -1708,7 +1688,7 @@
     MutexLocker mu(SystemDictionary_lock, THREAD);
     // First check if class already defined
     if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
-      InstanceKlass* check = find_class(d_index, d_hash, name_h, loader_data);
+      InstanceKlass* check = find_class(d_index, d_hash, name_h, dictionary);
       if (check != NULL) {
         return check;
       }
@@ -1730,7 +1710,7 @@
         placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
         SystemDictionary_lock->notify_all();
 #ifdef ASSERT
-        InstanceKlass* check = find_class(d_index, d_hash, name_h, loader_data);
+        InstanceKlass* check = find_class(d_index, d_hash, name_h, dictionary);
         assert(check != NULL, "definer missed recording success");
 #endif
         return probe->instance_klass();
@@ -1769,6 +1749,7 @@
 
   return k;
 }
+
 Handle SystemDictionary::compute_loader_lock_object(Handle class_loader, TRAPS) {
   // If class_loader is NULL we synchronize on _system_loader_lock_obj
   if (class_loader.is_null()) {
@@ -1806,12 +1787,9 @@
 
 InstanceKlass* SystemDictionary::find_class(int index, unsigned int hash,
                                             Symbol* class_name,
-                                            ClassLoaderData* loader_data) {
+                                            Dictionary* dictionary) {
   assert_locked_or_safepoint(SystemDictionary_lock);
-  assert (index == dictionary()->index_for(class_name, loader_data),
-          "incorrect index?");
-
-  return dictionary()->find_class(index, hash, class_name, loader_data);
+  return dictionary->find_class(index, hash, class_name);
 }
 
 
@@ -1819,14 +1797,17 @@
 Symbol* SystemDictionary::find_placeholder(Symbol* class_name,
                                            ClassLoaderData* loader_data) {
   assert_locked_or_safepoint(SystemDictionary_lock);
-  unsigned int p_hash = placeholders()->compute_hash(class_name, loader_data);
+  unsigned int p_hash = placeholders()->compute_hash(class_name);
   int p_index = placeholders()->hash_to_index(p_hash);
   return placeholders()->find_entry(p_index, p_hash, class_name, loader_data);
 }
 
 
 // Used for assertions and verification only
+// Precalculating the hash and index is an optimization because there are many lookups
+// before adding the class.
 InstanceKlass* SystemDictionary::find_class(Symbol* class_name, ClassLoaderData* loader_data) {
+  assert_locked_or_safepoint(SystemDictionary_lock);
   #ifndef ASSERT
   guarantee(VerifyBeforeGC      ||
             VerifyDuringGC      ||
@@ -1834,18 +1815,11 @@
             VerifyDuringStartup ||
             VerifyAfterGC, "too expensive");
   #endif
-  assert_locked_or_safepoint(SystemDictionary_lock);
 
-  // First look in the loaded class array
-  unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
-  int d_index = dictionary()->hash_to_index(d_hash);
-  return find_class(d_index, d_hash, class_name, loader_data);
-}
-
-
-// Get the next class in the dictionary.
-Klass* SystemDictionary::try_get_next_class() {
-  return dictionary()->try_get_next_class();
+  Dictionary* dictionary = loader_data->dictionary();
+  unsigned int d_hash = dictionary->compute_hash(class_name);
+  int d_index = dictionary->hash_to_index(d_hash);
+  return find_class(d_index, d_hash, class_name, dictionary);
 }
 
 
@@ -1872,33 +1846,10 @@
 // ----------------------------------------------------------------------------
 // GC support
 
-// Following roots during mark-sweep is separated in two phases.
-//
-// The first phase follows preloaded classes and all other system
-// classes, since these will never get unloaded anyway.
-//
-// The second phase removes (unloads) unreachable classes from the
-// system dictionary and follows the remaining classes' contents.
-
 void SystemDictionary::always_strong_oops_do(OopClosure* blk) {
   roots_oops_do(blk, NULL);
 }
 
-// Calculate a "good" systemdictionary size based
-// on predicted or current loaded classes count
-int SystemDictionary::calculate_systemdictionary_size(int classcount) {
-  int newsize = _old_default_sdsize;
-  if ((classcount > 0)  && !DumpSharedSpaces) {
-    int desiredsize = classcount/_average_depth_goal;
-    for (newsize = _primelist[_sdgeneration]; _sdgeneration < _prime_array_size -1;
-         newsize = _primelist[++_sdgeneration]) {
-      if (desiredsize <=  newsize) {
-        break;
-      }
-    }
-  }
-  return newsize;
-}
 
 #ifdef ASSERT
 class VerifySDReachableAndLiveClosure : public OopClosure {
@@ -1907,7 +1858,7 @@
 
   template <class T> void do_oop_work(T* p) {
     oop obj = oopDesc::load_decode_heap_oop(p);
-    guarantee(_is_alive->do_object_b(obj), "Oop in system dictionary must be live");
+    guarantee(_is_alive->do_object_b(obj), "Oop in protection domain cache table must be live");
   }
 
 public:
@@ -1936,20 +1887,20 @@
 
   if (unloading_occurred) {
     GCTraceTime(Debug, gc, phases) t("Dictionary", gc_timer);
-    dictionary()->do_unloading();
     constraints()->purge_loader_constraints();
     resolution_errors()->purge_resolution_errors();
   }
 
   {
     GCTraceTime(Debug, gc, phases) t("ProtectionDomainCacheTable", gc_timer);
-    // Oops referenced by the system dictionary may get unreachable independently
+    // Oops referenced by the protection domain cache table may get unreachable independently
     // of the class loader (eg. cached protection domain oops). So we need to
-    // explicitly unlink them here instead of in Dictionary::do_unloading.
-    dictionary()->unlink(is_alive);
+    // explicitly unlink them here.
+    _pd_cache_table->unlink(is_alive);
+
 #ifdef ASSERT
     VerifySDReachableAndLiveClosure cl(is_alive);
-    dictionary()->oops_do(&cl);
+    _pd_cache_table->oops_do(&cl);
 #endif
   }
 
@@ -1966,8 +1917,16 @@
   strong->do_oop(&_system_loader_lock_obj);
   CDS_ONLY(SystemDictionaryShared::roots_oops_do(strong);)
 
-  // Adjust dictionary
-  dictionary()->roots_oops_do(strong, weak);
+  // Do strong roots marking if the closures are the same.
+  if (strong == weak || !ClassUnloading) {
+    // Only the protection domain oops contain references into the heap. Iterate
+    // over all of them.
+    _pd_cache_table->oops_do(strong);
+  } else {
+   if (weak != NULL) {
+     _pd_cache_table->oops_do(weak);
+   }
+  }
 
   // Visit extra methods
   invoke_method_table()->oops_do(strong);
@@ -1982,8 +1941,9 @@
   f->do_oop(&_system_loader_lock_obj);
   CDS_ONLY(SystemDictionaryShared::oops_do(f);)
 
-  // Adjust dictionary
-  dictionary()->oops_do(f);
+  // Only the protection domain oops contain references into the heap. Iterate
+  // over all of them.
+  _pd_cache_table->oops_do(f);
 
   // Visit extra methods
   invoke_method_table()->oops_do(f);
@@ -1991,25 +1951,6 @@
   ResolvedMethodTable::oops_do(f);
 }
 
-// Just the classes from defining class loaders
-// Don't iterate over placeholders
-void SystemDictionary::classes_do(void f(Klass*)) {
-  dictionary()->classes_do(f);
-}
-
-// Added for initialize_itable_for_klass
-//   Just the classes from defining class loaders
-// Don't iterate over placeholders
-void SystemDictionary::classes_do(void f(Klass*, TRAPS), TRAPS) {
-  dictionary()->classes_do(f, CHECK);
-}
-
-//   All classes, and their class loaders
-// Don't iterate over placeholders
-void SystemDictionary::classes_do(void f(Klass*, ClassLoaderData*)) {
-  dictionary()->classes_do(f);
-}
-
 void SystemDictionary::methods_do(void f(Method*)) {
   // Walk methods in loaded classes
   ClassLoaderDataGraph::methods_do(f);
@@ -2018,7 +1959,7 @@
 }
 
 void SystemDictionary::remove_classes_in_error_state() {
-  dictionary()->remove_classes_in_error_state();
+  ClassLoaderData::the_null_class_loader_data()->dictionary()->remove_classes_in_error_state();
 }
 
 // ----------------------------------------------------------------------------
@@ -2042,15 +1983,12 @@
 
 void SystemDictionary::initialize(TRAPS) {
   // Allocate arrays
-  assert(dictionary() == NULL,
-         "SystemDictionary should only be initialized once");
-  _sdgeneration        = 0;
-  _dictionary          = new Dictionary(calculate_systemdictionary_size(PredictedLoadedClassCount));
-  _placeholders        = new PlaceholderTable(_nof_buckets);
+  _placeholders        = new PlaceholderTable(_placeholder_table_size);
   _number_of_modifications = 0;
   _loader_constraints  = new LoaderConstraintTable(_loader_constraint_size);
   _resolution_errors   = new ResolutionErrorTable(_resolution_error_size);
   _invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
+  _pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);
 
   // Allocate private object used as system class loader lock
   _system_loader_lock_obj = oopFactory::new_intArray(0, CHECK);
@@ -2204,9 +2142,9 @@
 // Constraints on class loaders. The details of the algorithm can be
 // found in the OOPSLA'98 paper "Dynamic Class Loading in the Java
 // Virtual Machine" by Sheng Liang and Gilad Bracha.  The basic idea is
-// that the system dictionary needs to maintain a set of contraints that
+// that the dictionary needs to maintain a set of contraints that
 // must be satisfied by all classes in the dictionary.
-// if defining is true, then LinkageError if already in systemDictionary
+// if defining is true, then LinkageError if already in dictionary
 // if initiating loader, then ok if InstanceKlass matches existing entry
 
 void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
@@ -2221,12 +2159,12 @@
 
     MutexLocker mu(SystemDictionary_lock, THREAD);
 
-    InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
+    InstanceKlass* check = find_class(d_index, d_hash, name, loader_data->dictionary());
     if (check != NULL) {
       // if different InstanceKlass - duplicate class definition,
       // else - ok, class loaded by a different thread in parallel,
       // we should only have found it if it was done loading and ok to use
-      // system dictionary only holds instance classes, placeholders
+      // dictionary only holds instance classes, placeholders
       // also holds array classes
 
       assert(check->is_instance_klass(), "noninstance in systemdictionary");
@@ -2267,7 +2205,7 @@
 }
 
 
-// Update system dictionary - done after check_constraint and add_to_hierachy
+// Update class loader data dictionary - done after check_constraint and add_to_hierachy
 // have been called.
 void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
                                          int p_index, unsigned int p_hash,
@@ -2280,40 +2218,41 @@
   ClassLoaderData *loader_data = class_loader_data(class_loader);
 
   {
-  MutexLocker mu1(SystemDictionary_lock, THREAD);
+    MutexLocker mu1(SystemDictionary_lock, THREAD);
 
-  // See whether biased locking is enabled and if so set it for this
-  // klass.
-  // Note that this must be done past the last potential blocking
-  // point / safepoint. We enable biased locking lazily using a
-  // VM_Operation to iterate the SystemDictionary and installing the
-  // biasable mark word into each InstanceKlass's prototype header.
-  // To avoid race conditions where we accidentally miss enabling the
-  // optimization for one class in the process of being added to the
-  // dictionary, we must not safepoint after the test of
-  // BiasedLocking::enabled().
-  if (UseBiasedLocking && BiasedLocking::enabled()) {
-    // Set biased locking bit for all loaded classes; it will be
-    // cleared if revocation occurs too often for this type
-    // NOTE that we must only do this when the class is initally
-    // defined, not each time it is referenced from a new class loader
-    if (k->class_loader() == class_loader()) {
-      k->set_prototype_header(markOopDesc::biased_locking_prototype());
+    // See whether biased locking is enabled and if so set it for this
+    // klass.
+    // Note that this must be done past the last potential blocking
+    // point / safepoint. We enable biased locking lazily using a
+    // VM_Operation to iterate the SystemDictionary and installing the
+    // biasable mark word into each InstanceKlass's prototype header.
+    // To avoid race conditions where we accidentally miss enabling the
+    // optimization for one class in the process of being added to the
+    // dictionary, we must not safepoint after the test of
+    // BiasedLocking::enabled().
+    if (UseBiasedLocking && BiasedLocking::enabled()) {
+      // Set biased locking bit for all loaded classes; it will be
+      // cleared if revocation occurs too often for this type
+      // NOTE that we must only do this when the class is initally
+      // defined, not each time it is referenced from a new class loader
+      if (k->class_loader() == class_loader()) {
+        k->set_prototype_header(markOopDesc::biased_locking_prototype());
+      }
     }
-  }
 
-  // Make a new system dictionary entry.
-  InstanceKlass* sd_check = find_class(d_index, d_hash, name, loader_data);
-  if (sd_check == NULL) {
-    dictionary()->add_klass(name, loader_data, k);
-    notice_modification();
-  }
-#ifdef ASSERT
-  sd_check = find_class(d_index, d_hash, name, loader_data);
-  assert (sd_check != NULL, "should have entry in system dictionary");
-  // Note: there may be a placeholder entry: for circularity testing
-  // or for parallel defines
-#endif
+    // Make a new dictionary entry.
+    Dictionary* dictionary = loader_data->dictionary();
+    InstanceKlass* sd_check = find_class(d_index, d_hash, name, dictionary);
+    if (sd_check == NULL) {
+      dictionary->add_klass(d_index, d_hash, name, k);
+      notice_modification();
+    }
+  #ifdef ASSERT
+    sd_check = find_class(d_index, d_hash, name, dictionary);
+    assert (sd_check != NULL, "should have entry in dictionary");
+    // Note: there may be a placeholder entry: for circularity testing
+    // or for parallel defines
+  #endif
     SystemDictionary_lock->notify_all();
   }
 }
@@ -2383,21 +2322,21 @@
       constraint_name = fd.object_key();
     }
   }
-  unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, loader_data1);
-  int d_index1 = dictionary()->hash_to_index(d_hash1);
 
-  unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, loader_data2);
-  int d_index2 = dictionary()->hash_to_index(d_hash2);
-  {
-  MutexLocker mu_s(SystemDictionary_lock, THREAD);
+  Dictionary* dictionary1 = loader_data1->dictionary();
+  unsigned int d_hash1 = dictionary1->compute_hash(constraint_name);
+  int d_index1 = dictionary1->hash_to_index(d_hash1);
 
-  // Better never do a GC while we're holding these oops
-  NoSafepointVerifier nosafepoint;
+  Dictionary* dictionary2 = loader_data2->dictionary();
+  unsigned int d_hash2 = dictionary2->compute_hash(constraint_name);
+  int d_index2 = dictionary2->hash_to_index(d_hash2);
 
-  InstanceKlass* klass1 = find_class(d_index1, d_hash1, constraint_name, loader_data1);
-  InstanceKlass* klass2 = find_class(d_index2, d_hash2, constraint_name, loader_data2);
-  return constraints()->add_entry(constraint_name, klass1, class_loader1,
-                                  klass2, class_loader2);
+  {
+    MutexLocker mu_s(SystemDictionary_lock, THREAD);
+    InstanceKlass* klass1 = find_class(d_index1, d_hash1, constraint_name, dictionary1);
+    InstanceKlass* klass2 = find_class(d_index2, d_hash2, constraint_name, dictionary2);
+    return constraints()->add_entry(constraint_name, klass1, class_loader1,
+                                    klass2, class_loader2);
   }
 }
 
@@ -2847,64 +2786,73 @@
   return unpack_method_and_appendix(mname, caller, appendix_box, appendix_result, THREAD);
 }
 
-// Since the identity hash code for symbols changes when the symbols are
-// moved from the regular perm gen (hash in the mark word) to the shared
-// spaces (hash is the address), the classes loaded into the dictionary
-// may be in the wrong buckets.
+// Protection domain cache table handling
+
+ProtectionDomainCacheEntry* SystemDictionary::cache_get(Handle protection_domain) {
+  return _pd_cache_table->get(protection_domain);
+}
+
 
 void SystemDictionary::reorder_dictionary() {
-  dictionary()->reorder_dictionary();
+  ClassLoaderData::the_null_class_loader_data()->dictionary()->reorder_dictionary();
 }
 
 
 void SystemDictionary::copy_buckets(char** top, char* end) {
-  dictionary()->copy_buckets(top, end);
+  ClassLoaderData::the_null_class_loader_data()->dictionary()->copy_buckets(top, end);
 }
 
 
 void SystemDictionary::copy_table(char** top, char* end) {
-  dictionary()->copy_table(top, end);
+  ClassLoaderData::the_null_class_loader_data()->dictionary()->copy_table(top, end);
 }
 
-int SystemDictionary::number_of_classes() {
-  return dictionary()->number_of_entries();
-}
-
-
 // ----------------------------------------------------------------------------
 void SystemDictionary::print_shared(bool details) {
   shared_dictionary()->print(details);
 }
 
 void SystemDictionary::print(bool details) {
-  dictionary()->print(details);
+  if (shared_dictionary() != NULL) {
+    tty->print_cr("Shared Dictionary");
+    shared_dictionary()->print(details);
+  }
+
+  GCMutexLocker mu(SystemDictionary_lock);
+
+  ClassLoaderDataGraph::print_dictionary(details);
 
   // Placeholders
-  GCMutexLocker mu(SystemDictionary_lock);
   placeholders()->print();
+  tty->cr();
 
   // loader constraints - print under SD_lock
   constraints()->print();
+  tty->cr();
+
+  _pd_cache_table->print();
+  tty->cr();
 }
 
 
 void SystemDictionary::verify() {
-  guarantee(dictionary() != NULL, "Verify of system dictionary failed");
   guarantee(constraints() != NULL,
             "Verify of loader constraints failed");
-  guarantee(dictionary()->number_of_entries() >= 0 &&
-            placeholders()->number_of_entries() >= 0,
-            "Verify of system dictionary failed");
+  guarantee(placeholders()->number_of_entries() >= 0,
+            "Verify of placeholders failed");
+
+  GCMutexLocker mu(SystemDictionary_lock);
 
   // Verify dictionary
-  dictionary()->verify();
+  ClassLoaderDataGraph::verify_dictionary();
 
-  GCMutexLocker mu(SystemDictionary_lock);
   placeholders()->verify();
 
   // Verify constraint table
   guarantee(constraints() != NULL, "Verify of loader constraints failed");
-  constraints()->verify(dictionary(), placeholders());
+  constraints()->verify(placeholders());
+
+  _pd_cache_table->verify();
 }
 
 // caller needs ResourceMark
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -35,31 +35,34 @@
 #include "utilities/hashtable.hpp"
 #include "utilities/hashtable.inline.hpp"
 
-// The system dictionary stores all loaded classes and maps:
+// The dictionary in each ClassLoaderData stores all loaded classes, either
+// initiatied by its class loader or defined by its class loader:
 //
-//   [class name,class loader] -> class   i.e.  [Symbol*,oop] -> Klass*
+//   class loader -> ClassLoaderData -> [class, protection domain set]
 //
 // Classes are loaded lazily. The default VM class loader is
 // represented as NULL.
 
-// The underlying data structure is an open hash table with a fixed number
-// of buckets. During loading the loader object is locked, (for the VM loader
-// a private lock object is used). Class loading can thus be done concurrently,
-// but only by different loaders.
+// The underlying data structure is an open hash table (Dictionary) per
+// ClassLoaderData with a fixed number of buckets. During loading the
+// class loader object is locked, (for the VM loader a private lock object is used).
+// The global SystemDictionary_lock is held for all additions into the ClassLoaderData
+// dictionaries.  TODO: fix lock granularity so that class loading can
+// be done concurrently, but only by different loaders.
 //
 // During loading a placeholder (name, loader) is temporarily placed in
 // a side data structure, and is used to detect ClassCircularityErrors
 // and to perform verification during GC.  A GC can occur in the midst
 // of class loading, as we call out to Java, have to take locks, etc.
 //
-// When class loading is finished, a new entry is added to the system
-// dictionary and the place holder is removed. Note that the protection
-// domain field of the system dictionary has not yet been filled in when
-// the "real" system dictionary entry is created.
+// When class loading is finished, a new entry is added to the dictionary
+// of the class loader and the placeholder is removed. Note that the protection
+// domain field of the dictionary entry has not yet been filled in when
+// the "real" dictionary entry is created.
 //
 // Clients of this class who are interested in finding if a class has
 // been completely loaded -- not classes in the process of being loaded --
-// can read the SystemDictionary unlocked. This is safe because
+// can read the dictionary unlocked. This is safe because
 //    - entries are only deleted at safepoints
 //    - readers cannot come to a safepoint while actively examining
 //         an entry  (an entry cannot be deleted from under a reader)
@@ -78,6 +81,8 @@
 template <MEMFLAGS F> class HashtableBucket;
 class ResolutionErrorTable;
 class SymbolPropertyTable;
+class ProtectionDomainCacheTable;
+class ProtectionDomainCacheEntry;
 class GCTimer;
 
 // Certain classes are preloaded, such as java.lang.Object and java.lang.String.
@@ -281,7 +286,7 @@
                                       bool is_superclass,
                                       TRAPS);
 
-  // Parse new stream. This won't update the system dictionary or
+  // Parse new stream. This won't update the dictionary or
   // class hierarchy, simply parse the stream. Used by JVMTI RedefineClasses.
   // Also used by Unsafe_DefineAnonymousClass
   static InstanceKlass* parse_stream(Symbol* class_name,
@@ -348,14 +353,6 @@
                                                            Handle class_loader,
                                                            TRAPS);
 
-  // Iterate over all klasses in dictionary
-  // Just the classes from defining class loaders
-  static void classes_do(void f(Klass*));
-  // Added for initialize_itable_for_klass to handle exceptions
-  static void classes_do(void f(Klass*, TRAPS), TRAPS);
-  // All classes, and their class loaders, including initiating class loaders
-  static void classes_do(void f(Klass*, ClassLoaderData*));
-
   // Iterate over all methods in all klasses
   static void methods_do(void f(Method*));
 
@@ -394,11 +391,6 @@
   static void print(bool details = true);
   static void print_shared(bool details = true);
 
-  // Number of contained klasses
-  // This is both fully loaded classes and classes in the process
-  // of being loaded
-  static int number_of_classes();
-
   // Monotonically increasing counter which grows as classes are
   // loaded or modifications such as hot-swapping or setting/removing
   // of breakpoints are performed
@@ -558,28 +550,21 @@
   static Symbol* find_resolution_error(const constantPoolHandle& pool, int which,
                                        Symbol** message);
 
+
+  static ProtectionDomainCacheEntry* cache_get(Handle protection_domain);
+
  protected:
 
   enum Constants {
     _loader_constraint_size = 107,                     // number of entries in constraint table
     _resolution_error_size  = 107,                     // number of entries in resolution error table
     _invoke_method_size     = 139,                     // number of entries in invoke method table
-    _nof_buckets            = 1009,                    // number of buckets in hash table for placeholders
-    _old_default_sdsize     = 1009,                    // backward compat for system dictionary size
-    _prime_array_size       = 8,                       // array of primes for system dictionary size
-    _average_depth_goal     = 3                        // goal for lookup length
+    _shared_dictionary_size = 1009,                    // number of entries in shared dictionary
+    _placeholder_table_size = 1009                     // number of entries in hash table for placeholders
   };
 
 
-  // Static variables
-
-  // hashtable sizes for system dictionary to allow growth
-  // prime numbers for system dictionary size
-  static int                     _sdgeneration;
-  static const int               _primelist[_prime_array_size];
-
-  // Hashtable holding loaded classes.
-  static Dictionary*            _dictionary;
+  // Static tables owned by the SystemDictionary
 
   // Hashtable holding placeholders for classes being loaded.
   static PlaceholderTable*       _placeholders;
@@ -588,7 +573,7 @@
   static Dictionary*             _shared_dictionary;
 
   // Monotonically increasing counter which grows with
-  // _number_of_classes as well as hot-swapping and breakpoint setting
+  // loading classes as well as hot-swapping and breakpoint setting
   // and removal.
   static int                     _number_of_modifications;
 
@@ -604,10 +589,8 @@
   // Invoke methods (JSR 292)
   static SymbolPropertyTable*    _invoke_method_table;
 
-public:
-  // for VM_CounterDecay iteration support
-  friend class CounterDecay;
-  static Klass* try_get_next_class();
+  // ProtectionDomain cache
+  static ProtectionDomainCacheTable*   _pd_cache_table;
 
 protected:
   static void validate_protection_domain(InstanceKlass* klass,
@@ -616,7 +599,6 @@
 
   friend class VM_PopulateDumpSharedSpace;
   friend class TraversePlaceholdersClosure;
-  static Dictionary*         dictionary() { return _dictionary; }
   static Dictionary*         shared_dictionary() { return _shared_dictionary; }
   static PlaceholderTable*   placeholders() { return _placeholders; }
   static LoaderConstraintTable* constraints() { return _loader_constraints; }
@@ -666,7 +648,7 @@
 
   // Basic find on loaded classes
   static InstanceKlass* find_class(int index, unsigned int hash,
-                                   Symbol* name, ClassLoaderData* loader_data);
+                                   Symbol* name, Dictionary* dictionary);
   static InstanceKlass* find_class(Symbol* class_name, ClassLoaderData* loader_data);
 
   // Basic find on classes in the midst of being loaded
--- a/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -69,6 +69,7 @@
   }
 
   static void init_shared_dictionary_entry(Klass* k, DictionaryEntry* entry) {}
+  static bool is_builtin(DictionaryEntry* entry) { return true; }
 
   static InstanceKlass* lookup_from_stream(Symbol* class_name,
                                            Handle class_loader,
--- a/hotspot/src/share/vm/code/codeCache.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1285,7 +1285,7 @@
 
 
 // Flushes compiled methods dependent on dependee
-void CodeCache::flush_dependents_on_method(methodHandle m_h) {
+void CodeCache::flush_dependents_on_method(const methodHandle& m_h) {
   // --- Compile_lock is not held. However we are at a safepoint.
   assert_locked_or_safepoint(Compile_lock);
 
--- a/hotspot/src/share/vm/code/codeCache.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -282,7 +282,7 @@
   static void flush_evol_dependents_on(InstanceKlass* dependee);
 #endif // HOTSWAP
   // Support for fullspeed debugging
-  static void flush_dependents_on_method(methodHandle dependee);
+  static void flush_dependents_on_method(const methodHandle& dependee);
 
   // tells how many nmethods have dependencies
   static int number_of_nmethods_with_dependencies();
--- a/hotspot/src/share/vm/compiler/compilerDirectives.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/compiler/compilerDirectives.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -123,7 +123,7 @@
   return _next;
 }
 
-bool CompilerDirectives::match(methodHandle method) {
+bool CompilerDirectives::match(const methodHandle& method) {
   if (is_default_directive()) {
     return true;
   }
@@ -232,7 +232,7 @@
 // - Need to free copy after use
 // - Requires a modified bit so we don't overwrite options that is set by directives
 
-DirectiveSet* DirectiveSet::compilecommand_compatibility_init(methodHandle method) {
+DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle& method) {
   // Early bail out - checking all options is expensive - we rely on them not being used
   // Only set a flag if it has not been modified and value changes.
   // Only copy set if a flag needs to be set
@@ -307,7 +307,7 @@
   return _directive;
 }
 
-bool DirectiveSet::matches_inline(methodHandle method, int inline_action) {
+bool DirectiveSet::matches_inline(const methodHandle& method, int inline_action) {
   if (_inlinematchers != NULL) {
     if (_inlinematchers->match(method, inline_action)) {
       return true;
@@ -384,7 +384,7 @@
   }
 }
 
-bool DirectiveSet::is_intrinsic_disabled(methodHandle method) {
+bool DirectiveSet::is_intrinsic_disabled(const methodHandle& method) {
   vmIntrinsics::ID id = method->intrinsic_id();
   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 
@@ -543,7 +543,7 @@
   }
 }
 
-DirectiveSet* DirectivesStack::getMatchingDirective(methodHandle method, AbstractCompiler *comp) {
+DirectiveSet* DirectivesStack::getMatchingDirective(const methodHandle& method, AbstractCompiler *comp) {
   assert(_depth > 0, "Must never be empty");
 
   DirectiveSet* match = NULL;
--- a/hotspot/src/share/vm/compiler/compilerDirectives.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/compiler/compilerDirectives.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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,7 +84,7 @@
   static void pop_inner(); // no lock version of pop
 public:
   static void init();
-  static DirectiveSet* getMatchingDirective(methodHandle mh, AbstractCompiler* comp);
+  static DirectiveSet* getMatchingDirective(const methodHandle& mh, AbstractCompiler* comp);
   static DirectiveSet* getDefaultDirective(AbstractCompiler* comp);
   static void push(CompilerDirectives* directive);
   static void pop(int count);
@@ -109,11 +109,11 @@
   bool should_inline(ciMethod* inlinee);
   bool should_not_inline(ciMethod* inlinee);
   void print_inline(outputStream* st);
-  DirectiveSet* compilecommand_compatibility_init(methodHandle method);
+  DirectiveSet* compilecommand_compatibility_init(const methodHandle& method);
   bool is_exclusive_copy() { return _directive == NULL; }
-  bool matches_inline(methodHandle method, int inline_action);
+  bool matches_inline(const methodHandle& method, int inline_action);
   static DirectiveSet* clone(DirectiveSet const* src);
-  bool is_intrinsic_disabled(methodHandle method);
+  bool is_intrinsic_disabled(const methodHandle& method);
   static ccstrlist canonicalize_disableintrinsic(ccstrlist option_value);
   void finalize(outputStream* st);
 
@@ -170,7 +170,7 @@
   CompilerDirectives* next();
   void set_next(CompilerDirectives* next) {_next = next; }
 
-  bool match(methodHandle method);
+  bool match(const methodHandle& method);
   BasicMatcher* match() { return _match; }
   bool add_match(char* str, const char*& error_msg);
   DirectiveSet* get_for(AbstractCompiler *comp);
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -132,7 +132,7 @@
   }
 
   static TypedMethodOptionMatcher* parse_method_pattern(char*& line, const char*& error_msg);
-  TypedMethodOptionMatcher* match(methodHandle method, const char* opt, OptionType type);
+  TypedMethodOptionMatcher* match(const methodHandle& method, const char* opt, OptionType type);
 
   void init(const char* opt, OptionType type, TypedMethodOptionMatcher* next) {
     _next = next;
@@ -261,7 +261,7 @@
   return tom;
 }
 
-TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(methodHandle method, const char* opt, OptionType type) {
+TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(const methodHandle& method, const char* opt, OptionType type) {
   TypedMethodOptionMatcher* current = this;
   while (current != NULL) {
     // Fastest compare first.
@@ -289,7 +289,7 @@
   return;
 }
 
-static bool check_predicate(OracleCommand command, methodHandle method) {
+static bool check_predicate(OracleCommand command, const methodHandle& method) {
   return ((lists[command] != NULL) &&
           !method.is_null() &&
           lists[command]->match(method));
--- a/hotspot/src/share/vm/compiler/directivesParser.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/compiler/directivesParser.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -628,11 +628,20 @@
     "    match: \"foo/bar.*\"," "\n"
     "    c2: {" "\n"
     "      PrintInlining: false," "\n"
+    "    }" "\n"
+    "  }" "\n"
+    "]" "\n", true);
+
+  DirectivesParser::test(
+    "[" "\n"
+    "  {" "\n"
+    "    match: \"foo/bar.*\"," "\n"
+    "    c2: {" "\n"
     "      VectorizeDebug: 1," "\n"
     "      VectorizeDebug: -1," "\n"
     "    }" "\n"
     "  }" "\n"
-    "]" "\n", true);
+    "]" "\n", COMPILER2_PRESENT(true) NOT_COMPILER2(false));
 
   DirectivesParser::test(
     "[" "\n"
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -109,7 +109,7 @@
 //------------------------------------------------------------------------------------------------------------------------
 // Entry points
 
-AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(methodHandle m) {
+AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(const methodHandle& m) {
   // Abstract method?
   if (m->is_abstract()) return abstract;
 
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -130,11 +130,11 @@
 
 
   // Method activation
-  static MethodKind method_kind(methodHandle m);
+  static MethodKind method_kind(const methodHandle& m);
   static address    entry_for_kind(MethodKind k)                { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; }
-  static address    entry_for_method(methodHandle m)            { return entry_for_kind(method_kind(m)); }
+  static address    entry_for_method(const methodHandle& m)     { return entry_for_kind(method_kind(m)); }
 
-  static address entry_for_cds_method(methodHandle m) {
+  static address entry_for_cds_method(const methodHandle& m) {
     MethodKind k = method_kind(m);
     assert(0 <= k && k < number_of_method_entries, "illegal kind");
     return _cds_entry_table[k];
--- a/hotspot/src/share/vm/interpreter/bytecode.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/bytecode.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -212,7 +212,7 @@
 }
 
 oop Bytecode_loadconstant::resolve_constant(TRAPS) const {
-  assert(_method.not_null(), "must supply method to resolve constant");
+  assert(_method != NULL, "must supply method to resolve constant");
   int index = raw_index();
   ConstantPool* constants = _method->constants();
   if (has_cache_index()) {
--- a/hotspot/src/share/vm/interpreter/bytecode.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/bytecode.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -178,11 +178,11 @@
 
 class Bytecode_member_ref: public Bytecode {
  protected:
-  const methodHandle _method;                          // method containing the bytecode
+  const Method* _method;                          // method containing the bytecode
 
-  Bytecode_member_ref(const methodHandle& method, int bci)  : Bytecode(method(), method()->bcp_from(bci)), _method(method) {}
+  Bytecode_member_ref(const methodHandle& method, int bci)  : Bytecode(method(), method()->bcp_from(bci)), _method(method()) {}
 
-  methodHandle method() const                    { return _method; }
+  const Method* method() const                 { return _method; }
   ConstantPool* constants() const              { return _method->constants(); }
   ConstantPoolCache* cpcache() const           { return _method->constants()->cache(); }
   ConstantPoolCacheEntry* cpcache_entry() const;
@@ -312,15 +312,15 @@
 // Abstraction for ldc, ldc_w and ldc2_w
 class Bytecode_loadconstant: public Bytecode {
  private:
-  const methodHandle _method;
+  const Method* _method;
 
   int raw_index() const;
 
  public:
-  Bytecode_loadconstant(const methodHandle& method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method) { verify(); }
+  Bytecode_loadconstant(const methodHandle& method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method()) { verify(); }
 
   void verify() const {
-    assert(_method.not_null(), "must supply method");
+    assert(_method != NULL, "must supply method");
     Bytecodes::Code stdc = Bytecodes::java_code(code());
     assert(stdc == Bytecodes::_ldc ||
            stdc == Bytecodes::_ldc_w ||
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -2790,7 +2790,7 @@
     CALL_VM(continuation_bci = (intptr_t)InterpreterRuntime::exception_handler_for_exception(THREAD, except_oop()),
             handle_exception);
 
-    except_oop = THREAD->vm_result();
+    except_oop = Handle(THREAD, THREAD->vm_result());
     THREAD->set_vm_result(NULL);
     if (continuation_bci >= 0) {
       // Place exception on top of stack
@@ -2994,7 +2994,7 @@
               CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD));
             }
             assert(THREAD->has_pending_exception(), "Lost our exception!");
-            illegal_state_oop = THREAD->pending_exception();
+            illegal_state_oop = Handle(THREAD, THREAD->pending_exception());
             THREAD->clear_pending_exception();
           }
         }
@@ -3011,7 +3011,7 @@
               CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD));
             }
             assert(THREAD->has_pending_exception(), "Lost our exception!");
-            illegal_state_oop = THREAD->pending_exception();
+            illegal_state_oop = Handle(THREAD, THREAD->pending_exception());
             THREAD->clear_pending_exception();
           }
         } else {
@@ -3028,7 +3028,7 @@
           if (rcvr == NULL) {
             if (!suppress_error) {
               VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), "", note_nullCheck_trap);
-              illegal_state_oop = THREAD->pending_exception();
+              illegal_state_oop = Handle(THREAD, THREAD->pending_exception());
               THREAD->clear_pending_exception();
             }
           } else if (UseHeavyMonitors) {
@@ -3038,7 +3038,7 @@
               CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base));
             }
             if (THREAD->has_pending_exception()) {
-              if (!suppress_error) illegal_state_oop = THREAD->pending_exception();
+              if (!suppress_error) illegal_state_oop = Handle(THREAD, THREAD->pending_exception());
               THREAD->clear_pending_exception();
             }
           } else {
@@ -3059,7 +3059,7 @@
                     CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base));
                   }
                   if (THREAD->has_pending_exception()) {
-                    if (!suppress_error) illegal_state_oop = THREAD->pending_exception();
+                    if (!suppress_error) illegal_state_oop = Handle(THREAD, THREAD->pending_exception());
                     THREAD->clear_pending_exception();
                   }
                 }
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -232,7 +232,7 @@
 // Exceptions
 
 void InterpreterRuntime::note_trap_inner(JavaThread* thread, int reason,
-                                         methodHandle trap_method, int trap_bci, TRAPS) {
+                                         const methodHandle& trap_method, int trap_bci, TRAPS) {
   if (trap_method.not_null()) {
     MethodData* trap_mdo = trap_method->method_data();
     if (trap_mdo == NULL) {
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -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
@@ -66,7 +66,7 @@
   static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i)  { return method(thread)->constants()->cache()->entry_at(i); }
   static ConstantPoolCacheEntry* cache_entry(JavaThread *thread)            { return cache_entry_at(thread, Bytes::get_native_u2(bcp(thread) + 1)); }
   static void      note_trap_inner(JavaThread* thread, int reason,
-                                   methodHandle trap_method, int trap_bci, TRAPS);
+                                   const methodHandle& trap_method, int trap_bci, TRAPS);
   static void      note_trap(JavaThread *thread, int reason, TRAPS);
 #ifdef CC_INTERP
   // Profile traps in C++ interpreter.
--- a/hotspot/src/share/vm/interpreter/invocationCounter.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/invocationCounter.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -104,7 +104,7 @@
 }
 
 
-static address do_nothing(methodHandle method, TRAPS) {
+static address do_nothing(const methodHandle& method, TRAPS) {
   // dummy action for inactive invocation counters
   MethodCounters* mcs = method->method_counters();
   assert(mcs != NULL, "");
@@ -114,7 +114,7 @@
 }
 
 
-static address do_decay(methodHandle method, TRAPS) {
+static address do_decay(const methodHandle& method, TRAPS) {
   // decay invocation counters so compilation gets delayed
   MethodCounters* mcs = method->method_counters();
   assert(mcs != NULL, "");
@@ -130,7 +130,7 @@
   _action[state] = action;
 }
 
-address dummy_invocation_counter_overflow(methodHandle m, TRAPS) {
+address dummy_invocation_counter_overflow(const methodHandle& m, TRAPS) {
   ShouldNotReachHere();
   return NULL;
 }
--- a/hotspot/src/share/vm/interpreter/invocationCounter.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/invocationCounter.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, 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
@@ -62,7 +62,7 @@
   static int InterpreterBackwardBranchLimit;    // A separate threshold for on stack replacement
   static int InterpreterProfileLimit;           // Profiling threshold scaled for interpreter use
 
-  typedef address (*Action)(methodHandle method, TRAPS);
+  typedef address (*Action)(const methodHandle& method, TRAPS);
 
   enum PublicConstants {
     count_increment      = count_grain,          // use this value to increment the 32bit _counter word
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -235,7 +235,7 @@
 //------------------------------------------------------------------------------------------------------------------------
 // Implementation of LinkInfo
 
-LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, methodHandle current_method, TRAPS) {
+LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, const methodHandle& current_method, TRAPS) {
    // resolve klass
   _resolved_klass = pool->klass_ref_at(index, CHECK);
 
@@ -315,9 +315,11 @@
 
 // Look up method in klasses, including static methods
 // Then look up local default methods
-methodHandle LinkResolver::lookup_method_in_klasses(const LinkInfo& link_info,
-                                                    bool checkpolymorphism,
-                                                    bool in_imethod_resolve, TRAPS) {
+Method* LinkResolver::lookup_method_in_klasses(const LinkInfo& link_info,
+                                               bool checkpolymorphism,
+                                               bool in_imethod_resolve) {
+  NoSafepointVerifier nsv;  // Method* returned may not be reclaimed
+
   Klass* klass = link_info.resolved_klass();
   Symbol* name = link_info.name();
   Symbol* signature = link_info.signature();
@@ -327,7 +329,7 @@
 
   if (klass->is_array_klass()) {
     // Only consider klass and super klass for arrays
-    return methodHandle(THREAD, result);
+    return result;
   }
 
   InstanceKlass* ik = InstanceKlass::cast(klass);
@@ -363,7 +365,7 @@
       return NULL;
     }
   }
-  return methodHandle(THREAD, result);
+  return result;
 }
 
 // returns first instance method
@@ -418,15 +420,13 @@
   return vtable_index;
 }
 
-methodHandle LinkResolver::lookup_method_in_interfaces(const LinkInfo& cp_info, TRAPS) {
+Method* LinkResolver::lookup_method_in_interfaces(const LinkInfo& cp_info) {
   InstanceKlass *ik = InstanceKlass::cast(cp_info.resolved_klass());
 
   // Specify 'true' in order to skip default methods when searching the
   // interfaces.  Function lookup_method_in_klasses() already looked for
   // the method in the default methods table.
-  return methodHandle(THREAD,
-    ik->lookup_method_in_all_interfaces(cp_info.name(), cp_info.signature(),
-    Klass::skip_defaults));
+  return ik->lookup_method_in_all_interfaces(cp_info.name(), cp_info.signature(), Klass::skip_defaults);
 }
 
 methodHandle LinkResolver::lookup_polymorphic_method(
@@ -713,13 +713,12 @@
     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   }
 
-
   // 3. lookup method in resolved klass and its super klasses
-  methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
+  methodHandle resolved_method(THREAD, lookup_method_in_klasses(link_info, true, false));
 
   // 4. lookup method in all the interfaces implemented by the resolved klass
   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
-    resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
+    resolved_method = methodHandle(THREAD, lookup_method_in_interfaces(link_info));
 
     if (resolved_method.is_null()) {
       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
@@ -817,11 +816,11 @@
 
   // lookup method in this interface or its super, java.lang.Object
   // JDK8: also look for static methods
-  methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
+  methodHandle resolved_method(THREAD, lookup_method_in_klasses(link_info, false, true));
 
   if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
     // lookup method in all the super-interfaces
-    resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
+    resolved_method = methodHandle(THREAD, lookup_method_in_interfaces(link_info));
   }
 
   if (resolved_method.is_null()) {
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -152,7 +152,7 @@
     skip_access_check
   };
 
-  LinkInfo(const constantPoolHandle& pool, int index, methodHandle current_method, TRAPS);
+  LinkInfo(const constantPoolHandle& pool, int index, const methodHandle& current_method, TRAPS);
   LinkInfo(const constantPoolHandle& pool, int index, TRAPS);
 
   // Condensed information from other call sites within the vm.
@@ -163,7 +163,7 @@
     _name(name), _signature(signature), _current_klass(current_klass), _current_method(methodHandle()),
     _check_access(check_access == needs_access_check), _tag(tag) {}
 
-  LinkInfo(Klass* resolved_klass, Symbol* name, Symbol* signature, methodHandle current_method,
+  LinkInfo(Klass* resolved_klass, Symbol* name, Symbol* signature, const methodHandle& current_method,
            AccessCheck check_access = needs_access_check,
            constantTag tag = JVM_CONSTANT_Invalid) :
     _resolved_klass(resolved_klass),
@@ -201,10 +201,11 @@
 
  private:
 
-  static methodHandle lookup_method_in_klasses(const LinkInfo& link_info,
-                                               bool checkpolymorphism,
-                                               bool in_imethod_resolve, TRAPS);
-  static methodHandle lookup_method_in_interfaces(const LinkInfo& link_info, TRAPS);
+  static Method* lookup_method_in_klasses(const LinkInfo& link_info,
+                                          bool checkpolymorphism,
+                                          bool in_imethod_resolve);
+  static Method* lookup_method_in_interfaces(const LinkInfo& link_info);
+
   static methodHandle lookup_polymorphic_method(const LinkInfo& link_info,
                                                 Handle *appendix_result_or_null,
                                                 Handle *method_type_result, TRAPS);
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, 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
@@ -39,9 +39,9 @@
 
  protected:
   // Initialization
-  void fill(methodHandle method, int bci);
+  void fill(const methodHandle& method, int bci);
   // fills the bit mask for native calls
-  void fill_for_native(methodHandle method);
+  void fill_for_native(const methodHandle& method);
   void set_mask(CellTypeState* vars, CellTypeState* stack, int stack_top);
 
   // Deallocate bit masks and initialize fields
@@ -80,7 +80,7 @@
   virtual void fill_init_vars             (GrowableArray<intptr_t> *init_vars);
 
  public:
-  OopMapForCacheEntry(methodHandle method, int bci, OopMapCacheEntry *entry);
+  OopMapForCacheEntry(const methodHandle& method, int bci, OopMapCacheEntry *entry);
 
   // Computes stack map for (method,bci) and initialize entry
   void compute_map(TRAPS);
@@ -88,7 +88,7 @@
 };
 
 
-OopMapForCacheEntry::OopMapForCacheEntry(methodHandle method, int bci, OopMapCacheEntry* entry) : GenerateOopMap(method) {
+OopMapForCacheEntry::OopMapForCacheEntry(const methodHandle& method, int bci, OopMapCacheEntry* entry) : GenerateOopMap(method) {
   _bci       = bci;
   _entry     = entry;
   _stack_top = -1;
@@ -242,7 +242,7 @@
   void pass_double()                             { /* ignore */ }
   void pass_object()                             { set_one(offset()); }
 
-  MaskFillerForNative(methodHandle method, uintptr_t* mask, int size) : NativeSignatureIterator(method) {
+  MaskFillerForNative(const methodHandle& method, uintptr_t* mask, int size) : NativeSignatureIterator(method) {
     _mask   = mask;
     _size   = size;
     // initialize with 0
@@ -301,7 +301,7 @@
 }
 
 
-void OopMapCacheEntry::fill_for_native(methodHandle mh) {
+void OopMapCacheEntry::fill_for_native(const methodHandle& mh) {
   assert(mh->is_native(), "method must be native method");
   set_mask_size(mh->size_of_parameters() * bits_per_entry);
   allocate_bit_mask();
@@ -311,7 +311,7 @@
 }
 
 
-void OopMapCacheEntry::fill(methodHandle method, int bci) {
+void OopMapCacheEntry::fill(const methodHandle& method, int bci) {
   HandleMark hm;
   // Flush entry to deallocate an existing entry
   flush();
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -117,7 +117,7 @@
 // require that local 0 is never overwritten so it's available as an
 // argument for registration.
 
-void Rewriter::rewrite_Object_init(methodHandle method, TRAPS) {
+void Rewriter::rewrite_Object_init(const methodHandle& method, TRAPS) {
   RawBytecodeStream bcs(method);
   while (!bcs.is_last_bytecode()) {
     Bytecodes::Code opcode = bcs.raw_next();
@@ -491,17 +491,16 @@
 }
 
 // After constant pool is created, revisit methods containing jsrs.
-methodHandle Rewriter::rewrite_jsrs(methodHandle method, TRAPS) {
+methodHandle Rewriter::rewrite_jsrs(const methodHandle& method, TRAPS) {
   ResourceMark rm(THREAD);
   ResolveOopMapConflicts romc(method);
-  methodHandle original_method = method;
-  method = romc.do_potential_rewrite(CHECK_(methodHandle()));
+  methodHandle new_method = romc.do_potential_rewrite(CHECK_(methodHandle()));
   // Update monitor matching info.
   if (romc.monitor_safe()) {
-    method->set_guaranteed_monitor_matching();
+    new_method->set_guaranteed_monitor_matching();
   }
 
-  return method;
+  return new_method;
 }
 
 void Rewriter::rewrite_bytecodes(TRAPS) {
--- a/hotspot/src/share/vm/interpreter/rewriter.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/interpreter/rewriter.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -193,7 +193,7 @@
   void compute_index_maps();
   void make_constant_pool_cache(TRAPS);
   void scan_method(Method* m, bool reverse, bool* invokespecial_error);
-  void rewrite_Object_init(methodHandle m, TRAPS);
+  void rewrite_Object_init(const methodHandle& m, TRAPS);
   void rewrite_member_reference(address bcp, int offset, bool reverse);
   void maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse);
   void rewrite_invokedynamic(address bcp, int offset, bool reverse);
@@ -208,7 +208,7 @@
   // Revert bytecodes in case of an exception.
   void restore_bytecodes();
 
-  static methodHandle rewrite_jsrs(methodHandle m, TRAPS);
+  static methodHandle rewrite_jsrs(const methodHandle& m, TRAPS);
  public:
   // Driver routine:
   static void rewrite(InstanceKlass* klass, TRAPS);
--- a/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -194,7 +194,7 @@
   }
 }
 
-CompLevel JVMCIRuntime::adjust_comp_level(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread) {
+CompLevel JVMCIRuntime::adjust_comp_level(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread) {
   if (!thread->adjusting_comp_level()) {
     thread->set_adjusting_comp_level(true);
     level = adjust_comp_level_inner(method, is_osr, level, thread);
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -822,7 +822,7 @@
   }
 }
 
-CompLevel JVMCIRuntime::adjust_comp_level_inner(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread) {
+CompLevel JVMCIRuntime::adjust_comp_level_inner(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread) {
   JVMCICompiler* compiler = JVMCICompiler::instance(thread);
   if (compiler != NULL && compiler->is_bootstrapping()) {
     return level;
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -63,7 +63,7 @@
 
   static bool _shutdown_called;
 
-  static CompLevel adjust_comp_level_inner(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread);
+  static CompLevel adjust_comp_level_inner(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread);
 
  public:
   static bool is_HotSpotJVMCIRuntime_initialized() {
@@ -125,7 +125,7 @@
    * @param thread the current thread
    * @return the compilation level to use for the compilation
    */
-  static CompLevel adjust_comp_level(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread);
+  static CompLevel adjust_comp_level(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread);
 
   static BasicType kindToBasicType(Handle kind, TRAPS);
 
--- a/hotspot/src/share/vm/logging/logTag.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/logging/logTag.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -142,6 +142,7 @@
   LOG_TAG(verification) \
   LOG_TAG(verify) \
   LOG_TAG(vmoperation) \
+  LOG_TAG(vmthread) \
   LOG_TAG(vtables) \
   LOG_TAG(workgang) \
   LOG_TAG_LIST_EXT
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -3735,10 +3735,13 @@
     log.info("Metaspace (%s) allocation failed for size " SIZE_FORMAT,
              is_class_space_allocation(mdtype) ? "class" : "data", word_size);
     ResourceMark rm;
+    if (log.is_debug()) {
+      if (loader_data->metaspace_or_null() != NULL) {
+        LogStream ls(log.debug());
+        loader_data->dump(&ls);
+      }
+    }
     LogStream ls(log.info());
-    if (loader_data->metaspace_or_null() != NULL) {
-      loader_data->dump(&ls);
-    }
     MetaspaceAux::dump(&ls);
     ChunkManager::print_all_chunkmanagers(&ls);
   }
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -181,7 +181,7 @@
   static intptr_t* clone_cpp_vtables(intptr_t* p);
   static void zero_cpp_vtable_clones_for_writing();
   static void patch_cpp_vtable_pointers();
-  static bool is_valid_shared_method(const Method* m);
+  static bool is_valid_shared_method(const Method* m) NOT_CDS_RETURN_(false);
 
   static void serialize(SerializeClosure* sc, GrowableArray<MemRegion> *string_space,
                         size_t* space_size);
--- a/hotspot/src/share/vm/memory/universe.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/memory/universe.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -548,14 +548,13 @@
 }
 
 
-void initialize_itable_for_klass(Klass* k, TRAPS) {
-  InstanceKlass::cast(k)->itable().initialize_itable(false, CHECK);
+void initialize_itable_for_klass(InstanceKlass* k, TRAPS) {
+  k->itable().initialize_itable(false, CHECK);
 }
 
 
 void Universe::reinitialize_itables(TRAPS) {
-  SystemDictionary::classes_do(initialize_itable_for_klass, CHECK);
-
+  ClassLoaderDataGraph::dictionary_classes_do(initialize_itable_for_klass, CHECK);
 }
 
 
--- a/hotspot/src/share/vm/oops/cpCache.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/cpCache.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -139,7 +139,7 @@
 }
 
 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
-                                                       methodHandle method,
+                                                       const methodHandle& method,
                                                        int vtable_index,
                                                        bool sender_is_interface) {
   bool is_vtable_call = (vtable_index >= 0);  // FIXME: split this method on this boolean
@@ -241,14 +241,14 @@
   NOT_PRODUCT(verify(tty));
 }
 
-void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method,
+void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, const methodHandle& method,
                                              bool sender_is_interface) {
   int index = Method::nonvirtual_vtable_index;
   // index < 0; FIXME: inline and customize set_direct_or_vtable_call
   set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface);
 }
 
-void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
+void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, const methodHandle& method, int index) {
   // either the method is a miranda or its holder should accept the given index
   assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), "");
   // index >= 0; FIXME: inline and customize set_direct_or_vtable_call
--- a/hotspot/src/share/vm/oops/cpCache.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/cpCache.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -222,7 +222,7 @@
     int             orig_field_index,            // the original field index in the field holder
     int             field_offset,                // the field offset in words in the field holder
     TosState        field_type,                  // the (machine) field type
-    bool            is_final,                     // the field is final
+    bool            is_final,                    // the field is final
     bool            is_volatile,                 // the field is volatile
     Klass*          root_klass                   // needed by the GC to dirty the klass
   );
@@ -230,7 +230,7 @@
  private:
   void set_direct_or_vtable_call(
     Bytecodes::Code invoke_code,                 // the bytecode used for invoking the method
-    methodHandle    method,                      // the method/prototype if any (NULL, otherwise)
+    const methodHandle& method,                  // the method/prototype if any (NULL, otherwise)
     int             vtable_index,                // the vtable index if any, else negative
     bool            sender_is_interface
   );
@@ -238,13 +238,13 @@
  public:
   void set_direct_call(                          // sets entry to exact concrete method entry
     Bytecodes::Code invoke_code,                 // the bytecode used for invoking the method
-    methodHandle    method,                      // the method to call
+    const methodHandle& method,                  // the method to call
     bool            sender_is_interface
   );
 
   void set_vtable_call(                          // sets entry to vtable index
     Bytecodes::Code invoke_code,                 // the bytecode used for invoking the method
-    methodHandle    method,                      // resolved method which declares the vtable index
+    const methodHandle& method,                  // resolved method which declares the vtable index
     int             vtable_index                 // the vtable index
   );
 
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -2949,7 +2949,7 @@
     st->print(BULLET"fake entry for mirror: ");
     mirrored_klass->print_value_on_maybe_null(st);
     st->cr();
-    Klass* array_klass = java_lang_Class::array_klass(obj);
+    Klass* array_klass = java_lang_Class::array_klass_acquire(obj);
     st->print(BULLET"fake entry for array: ");
     array_klass->print_value_on_maybe_null(st);
     st->cr();
--- a/hotspot/src/share/vm/oops/klassVtable.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -287,7 +287,7 @@
 // Therefore: all package private methods need their own vtable entries for
 // them to be the root of an inheritance overriding decision
 // Package private methods may also override other vtable entries
-InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper, methodHandle target_method,
+InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper, const methodHandle& target_method,
                             int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) {
   InstanceKlass* superk = initialsuper;
   while (superk != NULL && superk->super() != NULL) {
@@ -329,7 +329,7 @@
   return superk;
 }
 
-static void log_vtables(int i, bool overrides, methodHandle target_method,
+static void log_vtables(int i, bool overrides, const methodHandle& target_method,
                         Klass* target_klass, Method* super_method,
                         Thread* thread) {
 #ifndef PRODUCT
@@ -357,7 +357,7 @@
 // OR return true if a new vtable entry is required.
 // Only called for InstanceKlass's, i.e. not for arrays
 // If that changed, could not use _klass as handle for klass
-bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle target_method,
+bool klassVtable::update_inherited_vtable(InstanceKlass* klass, const methodHandle& target_method,
                                           int super_vtable_len, int default_index,
                                           bool checkconstraints, TRAPS) {
   ResourceMark rm;
@@ -576,7 +576,7 @@
 // superclass has been loaded.
 // However, the vtable entries are filled in at link time, and therefore
 // the superclass' vtable may not yet have been filled in.
-bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
+bool klassVtable::needs_new_vtable_entry(const methodHandle& target_method,
                                          const Klass* super,
                                          Handle classloader,
                                          Symbol* classname,
@@ -1569,7 +1569,7 @@
   }
 
   static void compute() {
-    SystemDictionary::classes_do(do_class);
+    ClassLoaderDataGraph::classes_do(do_class);
     fixed  = no_klasses * oopSize;      // vtable length
     // filler size is a conservative approximation
     filler = oopSize * (no_klasses - no_instance_klasses) * (sizeof(InstanceKlass) - sizeof(ArrayKlass) - 1);
--- a/hotspot/src/share/vm/oops/klassVtable.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/klassVtable.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -128,7 +128,7 @@
   int  initialize_from_super(Klass* super);
   int  index_of(Method* m, int len) const; // same as index_of, but search only up to len
   void put_method_at(Method* m, int index);
-  static bool needs_new_vtable_entry(methodHandle m,
+  static bool needs_new_vtable_entry(const methodHandle& m,
                                      const Klass* super,
                                      Handle classloader,
                                      Symbol* classname,
@@ -136,8 +136,8 @@
                                      u2 major_version,
                                      TRAPS);
 
-  bool update_inherited_vtable(InstanceKlass* klass, methodHandle target_method, int super_vtable_len, int default_index, bool checkconstraints, TRAPS);
- InstanceKlass* find_transitive_override(InstanceKlass* initialsuper, methodHandle target_method, int vtable_index,
+  bool update_inherited_vtable(InstanceKlass* klass, const methodHandle& target_method, int super_vtable_len, int default_index, bool checkconstraints, TRAPS);
+ InstanceKlass* find_transitive_override(InstanceKlass* initialsuper, const methodHandle& target_method, int vtable_index,
                                          Handle target_loader, Symbol* target_classname, Thread* THREAD);
 
   // support for miranda methods
--- a/hotspot/src/share/vm/oops/method.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/method.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -175,7 +175,7 @@
   return buf;
 }
 
-int Method::fast_exception_handler_bci_for(methodHandle mh, Klass* ex_klass, int throw_bci, TRAPS) {
+int Method::fast_exception_handler_bci_for(const methodHandle& mh, Klass* ex_klass, int throw_bci, TRAPS) {
   // exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index)
   // access exception table
   ExceptionTable table(mh());
@@ -1078,7 +1078,7 @@
 
 }
 
-address Method::make_adapters(methodHandle mh, TRAPS) {
+address Method::make_adapters(const methodHandle& mh, TRAPS) {
   // Adapters for compiled code are made eagerly here.  They are fairly
   // small (generally < 100 bytes) and quick to make (and cached and shared)
   // so making them eagerly shouldn't be too expensive.
@@ -1147,7 +1147,7 @@
 }
 
 // Install compiled code.  Instantly it can execute.
-void Method::set_code(methodHandle mh, CompiledMethod *code) {
+void Method::set_code(const methodHandle& mh, CompiledMethod *code) {
   MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
   assert( code, "use clear_code to remove code" );
   assert( mh->check_code(), "" );
@@ -1350,7 +1350,7 @@
 }
 
 
-methodHandle Method::clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
+methodHandle Method::clone_with_new_data(const methodHandle& m, u_char* new_code, int new_code_length,
                                                 u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) {
   // Code below does not work for native methods - they should never get rewritten anyway
   assert(!m->is_native(), "cannot rewrite native methods");
@@ -1545,7 +1545,7 @@
 }
 
 // These two methods are static since a GC may move the Method
-bool Method::load_signature_classes(methodHandle m, TRAPS) {
+bool Method::load_signature_classes(const methodHandle& m, TRAPS) {
   if (!THREAD->can_call_java()) {
     // There is nothing useful this routine can do from within the Compile thread.
     // Hopefully, the signature contains only well-known classes.
@@ -1579,7 +1579,7 @@
   return sig_is_loaded;
 }
 
-bool Method::has_unloaded_classes_in_signature(methodHandle m, TRAPS) {
+bool Method::has_unloaded_classes_in_signature(const methodHandle& m, TRAPS) {
   Handle class_loader(THREAD, m->method_holder()->class_loader());
   Handle protection_domain(THREAD, m->method_holder()->protection_domain());
   ResourceMark rm(THREAD);
--- a/hotspot/src/share/vm/oops/method.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/method.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -133,7 +133,7 @@
   void set_constMethod(ConstMethod* xconst)    { _constMethod = xconst; }
 
 
-  static address make_adapters(methodHandle mh, TRAPS);
+  static address make_adapters(const methodHandle& mh, TRAPS);
   volatile address from_compiled_entry() const   { return (address)OrderAccess::load_ptr_acquire(&_from_compiled_entry); }
   volatile address from_compiled_entry_no_trampoline() const;
   volatile address from_interpreted_entry() const{ return (address)OrderAccess::load_ptr_acquire(&_from_interpreted_entry); }
@@ -324,7 +324,7 @@
   // exception handler which caused the exception to be thrown, which
   // is needed for proper retries. See, for example,
   // InterpreterRuntime::exception_handler_for_exception.
-  static int fast_exception_handler_bci_for(methodHandle mh, Klass* ex_klass, int throw_bci, TRAPS);
+  static int fast_exception_handler_bci_for(const methodHandle& mh, Klass* ex_klass, int throw_bci, TRAPS);
 
   // method data access
   MethodData* method_data() const              {
@@ -452,7 +452,7 @@
   bool check_code() const;      // Not inline to avoid circular ref
   CompiledMethod* volatile code() const                 { assert( check_code(), "" ); return (CompiledMethod *)OrderAccess::load_ptr_acquire(&_code); }
   void clear_code(bool acquire_lock = true);    // Clear out any compiled code
-  static void set_code(methodHandle mh, CompiledMethod* code);
+  static void set_code(const methodHandle& mh, CompiledMethod* code);
   void set_adapter_entry(AdapterHandlerEntry* adapter) {
     constMethod()->set_adapter_entry(adapter);
   }
@@ -776,7 +776,7 @@
   void set_is_prefixed_native()                     { _access_flags.set_is_prefixed_native(); }
 
   // Rewriting support
-  static methodHandle clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
+  static methodHandle clone_with_new_data(const methodHandle& m, u_char* new_code, int new_code_length,
                                           u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS);
 
   // jmethodID handling
@@ -954,10 +954,10 @@
   void clear_queued_for_compilation()  { _access_flags.clear_queued_for_compilation();   }
 
   // Resolve all classes in signature, return 'true' if successful
-  static bool load_signature_classes(methodHandle m, TRAPS);
+  static bool load_signature_classes(const methodHandle& m, TRAPS);
 
   // Return if true if not all classes references in signature, including return type, has been loaded
-  static bool has_unloaded_classes_in_signature(methodHandle m, TRAPS);
+  static bool has_unloaded_classes_in_signature(const methodHandle& m, TRAPS);
 
   // Printing
   void print_short_name(outputStream* st = tty); // prints as klassname::methodname; Exposed so field engineers can debug VM
--- a/hotspot/src/share/vm/oops/methodCounters.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/methodCounters.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -25,7 +25,7 @@
 #include "oops/methodCounters.hpp"
 #include "runtime/handles.inline.hpp"
 
-MethodCounters* MethodCounters::allocate(methodHandle mh, TRAPS) {
+MethodCounters* MethodCounters::allocate(const methodHandle& mh, TRAPS) {
   ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
   return new(loader_data, size(), false, MetaspaceObj::MethodCountersType, THREAD) MethodCounters(mh);
 }
--- a/hotspot/src/share/vm/oops/methodCounters.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/methodCounters.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -68,7 +68,7 @@
   u1                _highest_osr_comp_level;      // Same for OSR level
 #endif
 
-  MethodCounters(methodHandle mh) :
+  MethodCounters(const methodHandle& mh) :
 #if INCLUDE_AOT
                                     _method(mh()),
 #endif
@@ -112,7 +112,7 @@
  public:
   virtual bool is_methodCounters() const volatile { return true; }
 
-  static MethodCounters* allocate(methodHandle mh, TRAPS);
+  static MethodCounters* allocate(const methodHandle& mh, TRAPS);
 
   void deallocate_contents(ClassLoaderData* loader_data) {}
 
--- a/hotspot/src/share/vm/oops/oop.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/oop.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -204,6 +204,7 @@
   inline Metadata* metadata_field(int offset) const;
   inline void metadata_field_put(int offset, Metadata* value);
 
+  inline Metadata* metadata_field_acquire(int offset) const;
   inline void release_metadata_field_put(int offset, Metadata* value);
 
   inline jbyte byte_field(int offset) const;
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -446,6 +446,10 @@
 Metadata* oopDesc::metadata_field(int offset) const           { return *metadata_field_addr(offset);   }
 void oopDesc::metadata_field_put(int offset, Metadata* value) { *metadata_field_addr(offset) = value;  }
 
+Metadata* oopDesc::metadata_field_acquire(int offset) const   {
+  return (Metadata*)OrderAccess::load_ptr_acquire(metadata_field_addr(offset));
+}
+
 void oopDesc::release_metadata_field_put(int offset, Metadata* value) {
   OrderAccess::release_store_ptr(metadata_field_addr(offset), value);
 }
--- a/hotspot/src/share/vm/opto/superword.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/opto/superword.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -3199,7 +3199,15 @@
   if (align_to_ref_p.invar() != NULL) {
     // incorporate any extra invariant piece producing (offset +/- invar) >>> log2(elt)
     Node* log2_elt = _igvn.intcon(exact_log2(elt_size));
-    Node* aref     = new URShiftINode(align_to_ref_p.invar(), log2_elt);
+    Node* invar = align_to_ref_p.invar();
+    if (_igvn.type(invar)->isa_long()) {
+      // Computations are done % (vector width/element size) so it's
+      // safe to simply convert invar to an int and loose the upper 32
+      // bit half.
+      invar = new ConvL2INode(invar);
+      _igvn.register_new_node_with_optimizer(invar);
+    }
+    Node* aref = new URShiftINode(invar, log2_elt);
     _igvn.register_new_node_with_optimizer(aref);
     _phase->set_ctrl(aref, pre_ctrl);
     if (align_to_ref_p.negate_invar()) {
@@ -3644,12 +3652,10 @@
         n = n->in(1);
       }
     }
-    if (n->bottom_type()->isa_int()) {
-      _negate_invar = negate;
-      _invar = n;
-      NOT_PRODUCT(_tracer.offset_plus_k_10(n, _invar, _negate_invar, _offset);)
-      return true;
-    }
+    _negate_invar = negate;
+    _invar = n;
+    NOT_PRODUCT(_tracer.offset_plus_k_10(n, _invar, _negate_invar, _offset);)
+    return true;
   }
 
   NOT_PRODUCT(_tracer.offset_plus_k_11(n);)
--- a/hotspot/src/share/vm/prims/jvm.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1686,7 +1686,7 @@
   return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(fd.type_annotations(), THREAD));
 JVM_END
 
-static void bounds_check(constantPoolHandle cp, jint index, TRAPS) {
+static void bounds_check(const constantPoolHandle& cp, jint index, TRAPS) {
   if (!cp->is_within_bounds(index)) {
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds");
   }
@@ -1794,7 +1794,7 @@
 }
 JVM_END
 
-static bool select_method(methodHandle method, bool want_constructor) {
+static bool select_method(const methodHandle& method, bool want_constructor) {
   if (want_constructor) {
     return (method->is_initializer() && !method->is_static());
   } else {
@@ -1963,7 +1963,7 @@
 }
 JVM_END
 
-static jobject get_method_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) {
+static jobject get_method_at_helper(const constantPoolHandle& cp, jint index, bool force_resolution, TRAPS) {
   constantTag tag = cp->tag_at(index);
   if (!tag.is_method() && !tag.is_interface_method()) {
     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
--- a/hotspot/src/share/vm/prims/jvmti.xml	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/prims/jvmti.xml	Tue Aug 01 21:29:55 2017 +0000
@@ -404,7 +404,7 @@
     interfaces are more appropriate than <jvmti/> for many tools.
     For more information on the Java Platform Debugger Architecture,
     see the
-    <externallink id="docs/technotes/guides/jpda/architecture.html">Java
+    <externallink id="jpda/architecture.html">Java
       Platform Debugger Architecture website</externallink>.
   </intro>
 
@@ -10927,7 +10927,7 @@
 	  for a class. The segment is typically a directory or JAR file.
 	  <p/>
 	  In the live phase the <paramlink id="segment"/> may be used to specify any platform-dependent
-	  path to a <externallink id="docs/technotes/guides/jar/jar.html">
+	  path to a <externallink id="jar/jar.html">
 	  JAR file</externallink>. The agent should take care that the JAR file does not
           contain any classes or resources other than those to be defined by the bootstrap
           class loader for the purposes of instrumentation.
@@ -10975,7 +10975,7 @@
 	  for a class. The segment is typically a directory or JAR file.
 	  <p/>
 	  In the live phase the <paramlink id="segment"/> is a platform-dependent path to a
-	  <externallink id="docs/technotes/guides/jar/jar.html">JAR file</externallink> to be
+	  <externallink id="jar/jar.html">JAR file</externallink> to be
 	  searched after the system class loader unsuccessfully searches for a class. The agent should
           take care that the JAR file does not contain any classes or resources other than those to be
           defined by the system class loader for the purposes of instrumentation.
--- a/hotspot/src/share/vm/prims/jvmti.xsl	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/prims/jvmti.xsl	Tue Aug 01 21:29:55 2017 +0000
@@ -1,6 +1,6 @@
 <?xml version="1.0"?> 
 <!--
- 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
@@ -1033,10 +1033,6 @@
 <xsl:template match="externallink">
   <a>
     <xsl:attribute name="href">
-      <!-- All external links start from the same prefix -->
-      <xsl:text>http://docs.oracle.com/javase/</xsl:text>
-      <xsl:value-of select="//specification/@majorversion"/>
-      <xsl:text>/</xsl:text>
       <xsl:value-of select="@id"/>
     </xsl:attribute>
     <xsl:value-of select="."/>
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -195,7 +195,7 @@
 
   jclass to_jclass(Klass* klass) { return (klass == NULL ? NULL : (jclass)to_jobject(klass->java_mirror())); }
 
-  jmethodID to_jmethodID(methodHandle method) { return method->jmethod_id(); }
+  jmethodID to_jmethodID(const methodHandle& method) { return method->jmethod_id(); }
 
   JNIEnv* jni_env() { return _jni_env; }
 };
@@ -229,7 +229,7 @@
   jmethodID _mid;
 
 public:
-  JvmtiMethodEventMark(JavaThread *thread, methodHandle method) :
+  JvmtiMethodEventMark(JavaThread *thread, const methodHandle& method) :
     JvmtiThreadEventMark(thread),
     _mid(to_jmethodID(method)) {};
   jmethodID jni_methodID() { return _mid; }
@@ -240,7 +240,7 @@
   jlocation _loc;
 
 public:
-  JvmtiLocationEventMark(JavaThread *thread, methodHandle method, address location) :
+  JvmtiLocationEventMark(JavaThread *thread, const methodHandle& method, address location) :
     JvmtiMethodEventMark(thread, method),
     _loc(location - method->code_base()) {};
   jlocation location() { return _loc; }
@@ -251,7 +251,7 @@
   jobject _exc;
 
 public:
-  JvmtiExceptionEventMark(JavaThread *thread, methodHandle method, address location, Handle exception) :
+  JvmtiExceptionEventMark(JavaThread *thread, const methodHandle& method, address location, Handle exception) :
     JvmtiLocationEventMark(thread, method, location),
     _exc(to_jobject(exception())) {};
   jobject exception() { return _exc; }
--- a/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -70,7 +70,7 @@
 
 // The closure for GetClassLoaderClasses
 class JvmtiGetLoadedClassesClosure : public StackObj {
-  // Since the SystemDictionary::classes_do callback
+  // Since the ClassLoaderDataGraph::dictionary_all_entries_do callback
   // doesn't pass a closureData pointer,
   // we use a thread-local slot to hold a pointer to
   // a stack allocated instance of this structure.
@@ -203,7 +203,7 @@
     }
   }
 
-  static void increment_with_loader(Klass* k, ClassLoaderData* loader_data) {
+  static void increment_with_loader(InstanceKlass* k, ClassLoaderData* loader_data) {
     JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
     oop class_loader = loader_data->class_loader();
     if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
@@ -213,7 +213,7 @@
     }
   }
 
-  static void add_with_loader(Klass* k, ClassLoaderData* loader_data) {
+  static void add_with_loader(InstanceKlass* k, ClassLoaderData* loader_data) {
     JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
     if (that->available()) {
       oop class_loader = loader_data->class_loader();
@@ -285,26 +285,26 @@
 jvmtiError
 JvmtiGetLoadedClasses::getClassLoaderClasses(JvmtiEnv *env, jobject initiatingLoader,
                                              jint* classCountPtr, jclass** classesPtr) {
-  // Since SystemDictionary::classes_do only takes a function pointer
+  // Since ClassLoaderDataGraph::dictionary_all_entries_do only takes a function pointer
   // and doesn't call back with a closure data pointer,
   // we can only pass static methods.
   JvmtiGetLoadedClassesClosure closure(initiatingLoader);
   {
     // To get a consistent list of classes we need MultiArray_lock to ensure
     // array classes aren't created, and SystemDictionary_lock to ensure that
-    // classes aren't added to the system dictionary,
+    // classes aren't added to the class loader data dictionaries.
     MutexLocker ma(MultiArray_lock);
     MutexLocker sd(SystemDictionary_lock);
-    // First, count the classes in the system dictionary which have this loader recorded
+    // First, count the classes in the class loader data dictionaries which have this loader recorded
     // as an initiating loader. For basic type arrays this information is not recorded
     // so GetClassLoaderClasses will return all of the basic type arrays. This is okay
     // because the defining loader for basic type arrays is always the boot class loader
     // and these classes are "visible" to all loaders.
-    SystemDictionary::classes_do(&JvmtiGetLoadedClassesClosure::increment_with_loader);
+    ClassLoaderDataGraph::dictionary_all_entries_do(&JvmtiGetLoadedClassesClosure::increment_with_loader);
     Universe::basic_type_classes_do(&JvmtiGetLoadedClassesClosure::increment_for_basic_type_arrays);
     // Next, fill in the classes
     closure.allocate();
-    SystemDictionary::classes_do(&JvmtiGetLoadedClassesClosure::add_with_loader);
+    ClassLoaderDataGraph::dictionary_all_entries_do(&JvmtiGetLoadedClassesClosure::add_with_loader);
     Universe::basic_type_classes_do(&JvmtiGetLoadedClassesClosure::add_for_basic_type_arrays);
     // Drop the SystemDictionary_lock, so the results could be wrong from here,
     // but we still have a snapshot.
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -32,7 +32,7 @@
 
 #ifdef TIERED
 // Print an event.
-void AdvancedThresholdPolicy::print_specific(EventType type, methodHandle mh, methodHandle imh,
+void AdvancedThresholdPolicy::print_specific(EventType type, const methodHandle& mh, const methodHandle& imh,
                                              int bci, CompLevel level) {
   tty->print(" rate=");
   if (mh->prev_time() == 0) tty->print("n/a");
@@ -339,7 +339,7 @@
 }
 
 // Create MDO if necessary.
-void AdvancedThresholdPolicy::create_mdo(methodHandle mh, JavaThread* THREAD) {
+void AdvancedThresholdPolicy::create_mdo(const methodHandle& mh, JavaThread* THREAD) {
   if (mh->is_native() ||
       mh->is_abstract() ||
       mh->is_accessor() ||
@@ -546,7 +546,7 @@
   CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
 }
 
-bool AdvancedThresholdPolicy::maybe_switch_to_aot(methodHandle mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread) {
+bool AdvancedThresholdPolicy::maybe_switch_to_aot(const methodHandle& mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread) {
   if (UseAOT && !delay_compilation_during_startup()) {
     if (cur_level == CompLevel_full_profile || cur_level == CompLevel_none) {
       // If the current level is full profile or interpreter and we're switching to any other level,
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -199,16 +199,16 @@
   // determines whether we should do that.
   inline bool should_create_mdo(Method* method, CompLevel cur_level);
   // Create MDO if necessary.
-  void create_mdo(methodHandle mh, JavaThread* thread);
+  void create_mdo(const methodHandle& mh, JavaThread* thread);
   // Is method profiled enough?
   bool is_method_profiled(Method* method);
 
   double _increase_threshold_at_ratio;
 
-  bool maybe_switch_to_aot(methodHandle mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread);
+  bool maybe_switch_to_aot(const methodHandle& mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread);
 
 protected:
-  void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level);
+  void print_specific(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
 
   void set_increase_threshold_at_ratio() { _increase_threshold_at_ratio = 100 / (100 - (double)IncreaseFirstTierCompileThresholdAt); }
   void set_start_time(jlong t) { _start_time = t;    }
--- a/hotspot/src/share/vm/runtime/biasedLocking.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/biasedLocking.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -42,7 +42,7 @@
 static GrowableArray<Handle>*  _preserved_oop_stack  = NULL;
 static GrowableArray<markOop>* _preserved_mark_stack = NULL;
 
-static void enable_biased_locking(Klass* k) {
+static void enable_biased_locking(InstanceKlass* k) {
   k->set_prototype_header(markOopDesc::biased_locking_prototype());
 }
 
@@ -56,9 +56,9 @@
   bool is_cheap_allocated() const { return _is_cheap_allocated; }
 
   void doit() {
-    // Iterate the system dictionary enabling biased locking for all
-    // currently loaded classes
-    SystemDictionary::classes_do(enable_biased_locking);
+    // Iterate the class loader data dictionaries enabling biased locking for all
+    // currently loaded classes.
+    ClassLoaderDataGraph::dictionary_classes_do(enable_biased_locking);
     // Indicate that future instances should enable it as well
     _biased_locking_enabled = true;
 
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -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
@@ -96,7 +96,7 @@
 // Returns true if m must be compiled before executing it
 // This is intended to force compiles for methods (usually for
 // debugging) that would otherwise be interpreted for some reason.
-bool CompilationPolicy::must_be_compiled(methodHandle m, int comp_level) {
+bool CompilationPolicy::must_be_compiled(const methodHandle& m, int comp_level) {
   // Don't allow Xcomp to cause compiles in replay mode
   if (ReplayCompiles) return false;
 
@@ -107,7 +107,7 @@
          (UseCompiler && AlwaysCompileLoopMethods && m->has_loops() && CompileBroker::should_compile_new_jobs()); // eagerly compile loop methods
 }
 
-void CompilationPolicy::compile_if_required(methodHandle selected_method, TRAPS) {
+void CompilationPolicy::compile_if_required(const methodHandle& selected_method, TRAPS) {
   if (must_be_compiled(selected_method)) {
     // This path is unusual, mostly used by the '-Xcomp' stress test mode.
 
@@ -135,7 +135,7 @@
 }
 
 // Returns true if m is allowed to be compiled
-bool CompilationPolicy::can_be_compiled(methodHandle m, int comp_level) {
+bool CompilationPolicy::can_be_compiled(const methodHandle& m, int comp_level) {
   // allow any levels for WhiteBox
   assert(WhiteBoxAPI || comp_level == CompLevel_all || is_compile(comp_level), "illegal compilation level");
 
@@ -166,7 +166,7 @@
 }
 
 // Returns true if m is allowed to be osr compiled
-bool CompilationPolicy::can_be_osr_compiled(methodHandle m, int comp_level) {
+bool CompilationPolicy::can_be_osr_compiled(const methodHandle& m, int comp_level) {
   bool result = false;
   if (comp_level == CompLevel_all) {
     if (TieredCompilation) {
@@ -312,13 +312,13 @@
   // and hence GC's will not be going on, all Java mutators are suspended
   // at this point and hence SystemDictionary_lock is also not needed.
   assert(SafepointSynchronize::is_at_safepoint(), "can only be executed at a safepoint");
-  int nclasses = SystemDictionary::number_of_classes();
+  int nclasses = InstanceKlass::number_of_instance_classes();
   double classes_per_tick = nclasses * (CounterDecayMinIntervalLength * 1e-3 /
                                         CounterHalfLifeTime);
   for (int i = 0; i < classes_per_tick; i++) {
-    Klass* k = SystemDictionary::try_get_next_class();
-    if (k != NULL && k->is_instance_klass()) {
-      InstanceKlass::cast(k)->methods_do(do_method);
+    InstanceKlass* k = ClassLoaderDataGraph::try_get_next_class();
+    if (k != NULL) {
+      k->methods_do(do_method);
     }
   }
 }
--- a/hotspot/src/share/vm/runtime/compilationPolicy.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -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
@@ -45,7 +45,7 @@
   static bool               _in_vm_startup;
 
   // m must be compiled before executing it
-  static bool must_be_compiled(methodHandle m, int comp_level = CompLevel_all);
+  static bool must_be_compiled(const methodHandle& m, int comp_level = CompLevel_all);
 
 public:
   static  void set_in_vm_startup(bool in_vm_startup) { _in_vm_startup = in_vm_startup; }
@@ -54,12 +54,12 @@
 
   // If m must_be_compiled then request a compilation from the CompileBroker.
   // This supports the -Xcomp option.
-  static void compile_if_required(methodHandle m, TRAPS);
+  static void compile_if_required(const methodHandle& m, TRAPS);
 
   // m is allowed to be compiled
-  static bool can_be_compiled(methodHandle m, int comp_level = CompLevel_all);
+  static bool can_be_compiled(const methodHandle& m, int comp_level = CompLevel_all);
   // m is allowed to be osr compiled
-  static bool can_be_osr_compiled(methodHandle m, int comp_level = CompLevel_all);
+  static bool can_be_osr_compiled(const methodHandle& m, int comp_level = CompLevel_all);
   static bool is_compilation_enabled();
   static void set_policy(CompilationPolicy* policy) { _policy = policy; }
   static CompilationPolicy* policy()                { return _policy; }
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1408,7 +1408,7 @@
 JRT_END
 
 MethodData*
-Deoptimization::get_method_data(JavaThread* thread, methodHandle m,
+Deoptimization::get_method_data(JavaThread* thread, const methodHandle& m,
                                 bool create_if_missing) {
   Thread* THREAD = thread;
   MethodData* mdo = m()->method_data();
--- a/hotspot/src/share/vm/runtime/deoptimization.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/deoptimization.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, 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
@@ -417,7 +417,7 @@
   // returning to a deoptimized caller
   static void popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address);
 
-  static MethodData* get_method_data(JavaThread* thread, methodHandle m, bool create_if_missing);
+  static MethodData* get_method_data(JavaThread* thread, const methodHandle& m, bool create_if_missing);
  private:
   // Update the mdo's count and per-BCI reason bits, returning previous state:
   static ProfileData* query_update_method_data(MethodData* trap_mdo,
--- a/hotspot/src/share/vm/runtime/javaCalls.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/javaCalls.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -49,7 +49,7 @@
 // -----------------------------------------------------
 // Implementation of JavaCallWrapper
 
-JavaCallWrapper::JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS) {
+JavaCallWrapper::JavaCallWrapper(const methodHandle& callee_method, Handle receiver, JavaValue* result, TRAPS) {
   JavaThread* thread = (JavaThread *)THREAD;
   bool clear_pending_exception = true;
 
--- a/hotspot/src/share/vm/runtime/javaCalls.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -53,7 +53,7 @@
 
  public:
   // Construction/destruction
-   JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS);
+   JavaCallWrapper(const methodHandle& callee_method, Handle receiver, JavaValue* result, TRAPS);
   ~JavaCallWrapper();
 
   // Accessors
--- a/hotspot/src/share/vm/runtime/jniHandles.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/jniHandles.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -152,6 +152,9 @@
   // Free list computation
   void rebuild_free_list();
 
+  // No more handles in the both the current and following blocks
+  void clear() { _top = 0; }
+
  public:
   // Handle allocation
   jobject allocate_handle(oop obj);
--- a/hotspot/src/share/vm/runtime/memprofiler.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/memprofiler.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -120,7 +120,7 @@
   fprintf(_log_fp, "%6.1f,%5d,%5d," UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",",
           os::elapsedTime(),
           Threads::number_of_threads(),
-          SystemDictionary::number_of_classes(),
+          InstanceKlass::number_of_instance_classes(),
           Universe::heap()->used() / K,
           Universe::heap()->capacity() / K);
 
--- a/hotspot/src/share/vm/runtime/reflection.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/reflection.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -762,7 +762,7 @@
 }
 
 // Utility method converting a single SignatureStream element into java.lang.Class instance
-static oop get_mirror_from_signature(methodHandle method,
+static oop get_mirror_from_signature(const methodHandle& method,
                                      SignatureStream* ss,
                                      TRAPS) {
 
@@ -788,7 +788,7 @@
   return java_lang_Class::primitive_mirror(ss->type());
 }
 
-static objArrayHandle get_parameter_types(methodHandle method,
+static objArrayHandle get_parameter_types(const methodHandle& method,
                                           int parameter_count,
                                           oop* return_type,
                                           TRAPS) {
@@ -814,7 +814,7 @@
   return mirrors;
 }
 
-static objArrayHandle get_exception_types(methodHandle method, TRAPS) {
+static objArrayHandle get_exception_types(const methodHandle& method, TRAPS) {
   return method->resolved_checked_exceptions(THREAD);
 }
 
@@ -1052,7 +1052,7 @@
 
 // Method call (shared by invoke_method and invoke_constructor)
 static oop invoke(InstanceKlass* klass,
-                  methodHandle reflected_method,
+                  const methodHandle& reflected_method,
                   Handle receiver,
                   bool override,
                   objArrayHandle ptypes,
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -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
@@ -357,7 +357,7 @@
 
 #if defined(X86) && defined(COMPILER1)
   // For Object.hashCode, System.identityHashCode try to pull hashCode from object header if available.
-  static void inline_check_hashcode_from_object_header(MacroAssembler* masm, methodHandle method, Register obj_reg, Register result);
+  static void inline_check_hashcode_from_object_header(MacroAssembler* masm, const methodHandle& method, Register obj_reg, Register result);
 #endif // X86 && COMPILER1
 
  public:
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -35,7 +35,7 @@
 
 #ifdef TIERED
 
-void SimpleThresholdPolicy::print_counters(const char* prefix, methodHandle mh) {
+void SimpleThresholdPolicy::print_counters(const char* prefix, const methodHandle& mh) {
   int invocation_count = mh->invocation_count();
   int backedge_count = mh->backedge_count();
   MethodData* mdh = mh->method_data();
@@ -56,7 +56,7 @@
 }
 
 // Print an event.
-void SimpleThresholdPolicy::print_event(EventType type, methodHandle mh, methodHandle imh,
+void SimpleThresholdPolicy::print_event(EventType type, const methodHandle& mh, const methodHandle& imh,
                                         int bci, CompLevel level) {
   bool inlinee_event = mh() != imh();
 
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -57,7 +57,7 @@
   // loop_event checks if a method should be OSR compiled at a different
   // level.
   CompLevel loop_event(Method* method, CompLevel cur_level, JavaThread* thread);
-  void print_counters(const char* prefix, methodHandle mh);
+  void print_counters(const char* prefix, const methodHandle& mh);
 protected:
   int c1_count() const     { return _c1_count; }
   int c2_count() const     { return _c2_count; }
@@ -65,9 +65,9 @@
   void set_c2_count(int x) { _c2_count = x;    }
 
   enum EventType { CALL, LOOP, COMPILE, REMOVE_FROM_QUEUE, UPDATE_IN_QUEUE, REPROFILE, MAKE_NOT_ENTRANT };
-  void print_event(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level);
+  void print_event(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
   // Print policy-specific information if necessary
-  virtual void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { }
+  virtual void print_specific(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level) { }
   // Check if the method can be compiled, change level if necessary
   void compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
   // Submit a given method for compilation
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -1670,7 +1670,7 @@
 // process the same monitor lists concurrently.
 //
 // See also ParallelSPCleanupTask and
-// SafepointSynchronizer::do_cleanup_tasks() in safepoint.cpp and
+// SafepointSynchronize::do_cleanup_tasks() in safepoint.cpp and
 // Threads::parallel_java_threads_do() in thread.cpp.
 int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** listHeadp,
                                              ObjectMonitor** freeHeadp,
--- a/hotspot/src/share/vm/runtime/thread.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -3392,6 +3392,13 @@
       tc->do_thread(p);
     }
   }
+  // Thread claiming protocol requires us to claim the same interesting
+  // threads on all paths. Notably, Threads::possibly_parallel_threads_do
+  // claims all Java threads *and* the VMThread. To avoid breaking the
+  // claiming protocol, we have to claim VMThread on this path too, even
+  // if we do not apply the closure to the VMThread.
+  VMThread* vmt = VMThread::vm_thread();
+  (void)vmt->claim_oops_do(true, cp);
 }
 
 // The system initialization in the library has three phases.
@@ -4357,6 +4364,10 @@
     assert((thread_parity == _thread_claim_parity),
            "Thread " PTR_FORMAT " has incorrect parity %d != %d", p2i(p), thread_parity, _thread_claim_parity);
   }
+  VMThread* vmt = VMThread::vm_thread();
+  const int thread_parity = vmt->oops_do_parity();
+  assert((thread_parity == _thread_claim_parity),
+         "VMThread " PTR_FORMAT " has incorrect parity %d != %d", p2i(vmt), thread_parity, _thread_claim_parity);
 }
 #endif // ASSERT
 
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -31,8 +31,6 @@
 #include "classfile/compactHashtable.hpp"
 #include "classfile/dictionary.hpp"
 #include "classfile/javaClasses.hpp"
-#include "classfile/loaderConstraints.hpp"
-#include "classfile/placeholders.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "code/codeBlob.hpp"
@@ -193,10 +191,8 @@
 typedef Hashtable<Symbol*, mtSymbol>          SymbolHashtable;
 typedef HashtableEntry<Symbol*, mtClass>      SymbolHashtableEntry;
 typedef Hashtable<oop, mtSymbol>              StringHashtable;
-typedef TwoOopHashtable<InstanceKlass*, mtClass> KlassTwoOopHashtable;
 typedef Hashtable<InstanceKlass*, mtClass>       KlassHashtable;
 typedef HashtableEntry<InstanceKlass*, mtClass>  KlassHashtableEntry;
-typedef TwoOopHashtable<Symbol*, mtClass>     SymbolTwoOopHashtable;
 typedef CompactHashtable<Symbol*, char>       SymbolCompactHashTable;
 typedef RehashableHashtable<Symbol*, mtSymbol>   RehashableSymbolHashtable;
 
@@ -250,7 +246,6 @@
   nonstatic_field(InstanceKlass,               _fields,                                       Array<u2>*)                            \
   nonstatic_field(InstanceKlass,               _java_fields_count,                            u2)                                    \
   nonstatic_field(InstanceKlass,               _constants,                                    ConstantPool*)                         \
-  nonstatic_field(InstanceKlass,               _class_loader_data,                            ClassLoaderData*)                      \
   nonstatic_field(InstanceKlass,               _source_file_name_index,                       u2)                                    \
   nonstatic_field(InstanceKlass,               _source_debug_extension,                       const char*)                           \
   nonstatic_field(InstanceKlass,               _inner_classes,                                Array<jushort>*)                       \
@@ -291,6 +286,7 @@
   nonstatic_field(Klass,                       _next_sibling,                                 Klass*)                                \
   nonstatic_field(Klass,                       _next_link,                                    Klass*)                                \
   nonstatic_field(Klass,                       _vtable_len,                                   int)                                   \
+  nonstatic_field(Klass,                       _class_loader_data,                            ClassLoaderData*)                      \
   nonstatic_field(vtableEntry,                 _method,                                       Method*)                               \
   nonstatic_field(MethodData,                  _size,                                         int)                                   \
   nonstatic_field(MethodData,                  _method,                                       Method*)                               \
@@ -607,46 +603,16 @@
   /* SystemDictionary */                                                                                                             \
   /********************/                                                                                                             \
                                                                                                                                      \
-     static_field(SystemDictionary,            _dictionary,                                   Dictionary*)                           \
-     static_field(SystemDictionary,            _placeholders,                                 PlaceholderTable*)                     \
      static_field(SystemDictionary,            _shared_dictionary,                            Dictionary*)                           \
      static_field(SystemDictionary,            _system_loader_lock_obj,                       oop)                                   \
-     static_field(SystemDictionary,            _loader_constraints,                           LoaderConstraintTable*)                \
      static_field(SystemDictionary,            WK_KLASS(Object_klass),                        InstanceKlass*)                        \
      static_field(SystemDictionary,            WK_KLASS(String_klass),                        InstanceKlass*)                        \
      static_field(SystemDictionary,            WK_KLASS(Class_klass),                         InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(Cloneable_klass),                     InstanceKlass*)                        \
      static_field(SystemDictionary,            WK_KLASS(ClassLoader_klass),                   InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(Serializable_klass),                  InstanceKlass*)                        \
      static_field(SystemDictionary,            WK_KLASS(System_klass),                        InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(Throwable_klass),                     InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(ThreadDeath_klass),                   InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(Error_klass),                         InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(Exception_klass),                     InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(RuntimeException_klass),              InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(ClassNotFoundException_klass),        InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(NoClassDefFoundError_klass),          InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(LinkageError_klass),                  InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(ClassCastException_klass),            InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(ArrayStoreException_klass),           InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(VirtualMachineError_klass),           InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(OutOfMemoryError_klass),              InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(StackOverflowError_klass),            InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(ProtectionDomain_klass),              InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(AccessControlContext_klass),          InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(SecureClassLoader_klass),             InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(Reference_klass),                     InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(SoftReference_klass),                 InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(WeakReference_klass),                 InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(FinalReference_klass),                InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(PhantomReference_klass),              InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(Finalizer_klass),                     InstanceKlass*)                        \
      static_field(SystemDictionary,            WK_KLASS(Thread_klass),                        InstanceKlass*)                        \
      static_field(SystemDictionary,            WK_KLASS(ThreadGroup_klass),                   InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(Properties_klass),                    InstanceKlass*)                        \
-     static_field(SystemDictionary,            WK_KLASS(StringBuffer_klass),                  InstanceKlass*)                        \
      static_field(SystemDictionary,            WK_KLASS(MethodHandle_klass),                  InstanceKlass*)                        \
-     static_field(SystemDictionary,            _box_klasses[0],                               InstanceKlass*)                        \
      static_field(SystemDictionary,            _java_system_loader,                           oop)                                   \
                                                                                                                                      \
   /*************/                                                                                                                    \
@@ -681,42 +647,13 @@
   nonstatic_field(BasicHashtable<mtInternal>,  _entry_size,                                   int)                                   \
                                                                                                                                      \
   /*******************/                                                                                                              \
-  /* DictionaryEntry */                                                                                                              \
+  /* ClassLoaderData */                                                                                                              \
   /*******************/                                                                                                              \
-                                                                                                                                     \
-  nonstatic_field(DictionaryEntry,             _loader_data,                                  ClassLoaderData*)                      \
-  nonstatic_field(DictionaryEntry,             _pd_set,                                       ProtectionDomainEntry*)                \
-                                                                                                                                     \
-  /********************/                                                                                                             \
-                                                                                                                                     \
-  nonstatic_field(PlaceholderEntry,            _loader_data,                                  ClassLoaderData*)                      \
-                                                                                                                                     \
-  /**************************/                                                                                                       \
-  /* ProtectionDomainEntry  */                                                                                                       \
-  /**************************/                                                                                                       \
-                                                                                                                                     \
-  nonstatic_field(ProtectionDomainEntry,       _next,                                         ProtectionDomainEntry*)                \
-  nonstatic_field(ProtectionDomainEntry,       _pd_cache,                                     ProtectionDomainCacheEntry*)           \
-                                                                                                                                     \
-  /*******************************/                                                                                                  \
-  /* ProtectionDomainCacheEntry  */                                                                                                  \
-  /*******************************/                                                                                                  \
-                                                                                                                                     \
-  nonstatic_field(ProtectionDomainCacheEntry,  _literal,                                      oop)                                   \
-                                                                                                                                     \
-  /*************************/                                                                                                        \
-  /* LoaderConstraintEntry */                                                                                                        \
-  /*************************/                                                                                                        \
-                                                                                                                                     \
-  nonstatic_field(LoaderConstraintEntry,       _name,                                         Symbol*)                               \
-  nonstatic_field(LoaderConstraintEntry,       _num_loaders,                                  int)                                   \
-  nonstatic_field(LoaderConstraintEntry,       _max_loaders,                                  int)                                   \
-  nonstatic_field(LoaderConstraintEntry,       _loaders,                                      ClassLoaderData**)                     \
-                                                                                                                                     \
   nonstatic_field(ClassLoaderData,             _class_loader,                                 oop)                                   \
   nonstatic_field(ClassLoaderData,             _next,                                         ClassLoaderData*)                      \
   volatile_nonstatic_field(ClassLoaderData,    _klasses,                                      Klass*)                                \
   nonstatic_field(ClassLoaderData,             _is_anonymous,                                 bool)                                  \
+  volatile_nonstatic_field(ClassLoaderData,    _dictionary,                                   Dictionary*)                           \
                                                                                                                                      \
      static_field(ClassLoaderDataGraph,        _head,                                         ClassLoaderData*)                      \
                                                                                                                                      \
@@ -1610,20 +1547,13 @@
     declare_type(RehashableSymbolHashtable, BasicHashtable<mtSymbol>)     \
   declare_type(SymbolTable, SymbolHashtable)                              \
   declare_type(StringTable, StringHashtable)                              \
-    declare_type(LoaderConstraintTable, KlassHashtable)                   \
-    declare_type(KlassTwoOopHashtable, KlassHashtable)                    \
-    declare_type(Dictionary, KlassTwoOopHashtable)                        \
-    declare_type(PlaceholderTable, SymbolTwoOopHashtable)                 \
+    declare_type(Dictionary, KlassHashtable)                              \
   declare_toplevel_type(BasicHashtableEntry<mtInternal>)                  \
   declare_type(IntptrHashtableEntry, BasicHashtableEntry<mtInternal>)     \
     declare_type(DictionaryEntry, KlassHashtableEntry)                    \
-    declare_type(PlaceholderEntry, SymbolHashtableEntry)                  \
-    declare_type(LoaderConstraintEntry, KlassHashtableEntry)              \
   declare_toplevel_type(HashtableBucket<mtInternal>)                      \
   declare_toplevel_type(SystemDictionary)                                 \
   declare_toplevel_type(vmSymbols)                                        \
-  declare_toplevel_type(ProtectionDomainEntry)                            \
-  declare_toplevel_type(ProtectionDomainCacheEntry)                       \
                                                                           \
   declare_toplevel_type(GenericGrowableArray)                             \
   declare_toplevel_type(GrowableArray<int>)                               \
@@ -2355,12 +2285,6 @@
   declare_preprocessor_constant("PERFDATA_BIG_ENDIAN", PERFDATA_BIG_ENDIAN)       \
   declare_preprocessor_constant("PERFDATA_LITTLE_ENDIAN", PERFDATA_LITTLE_ENDIAN) \
                                                                           \
-  /***********************************/                                   \
-  /* LoaderConstraintTable constants */                                   \
-  /***********************************/                                   \
-                                                                          \
-  declare_constant(LoaderConstraintTable::_loader_constraint_size)        \
-  declare_constant(LoaderConstraintTable::_nof_buckets)                   \
                                                                           \
   /************************************************************/          \
   /* HotSpot specific JVM_ACC constants from global anon enum */          \
--- a/hotspot/src/share/vm/runtime/vmThread.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -25,6 +25,8 @@
 #include "precompiled.hpp"
 #include "compiler/compileBroker.hpp"
 #include "gc/shared/collectedHeap.hpp"
+#include "logging/log.hpp"
+#include "logging/logConfiguration.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
@@ -484,6 +486,7 @@
       // If we are at a safepoint we will evaluate all the operations that
       // follow that also require a safepoint
       if (_cur_vm_operation->evaluate_at_safepoint()) {
+        log_debug(vmthread)("Evaluating safepoint VM operation: %s", _cur_vm_operation->name());
 
         _vm_queue->set_drain_list(safepoint_ops); // ensure ops can be scanned
 
@@ -495,6 +498,7 @@
           _cur_vm_operation = safepoint_ops;
           if (_cur_vm_operation != NULL) {
             do {
+              log_debug(vmthread)("Evaluating coalesced safepoint VM operation: %s", _cur_vm_operation->name());
               // evaluate_operation deletes the op object so we have
               // to grab the next op now
               VM_Operation* next = _cur_vm_operation->next();
@@ -532,6 +536,7 @@
         SafepointSynchronize::end();
 
       } else {  // not a safepoint operation
+        log_debug(vmthread)("Evaluating non-safepoint VM operation: %s", _cur_vm_operation->name());
         if (TraceLongCompiles) {
           elapsedTimer t;
           t.start();
@@ -607,8 +612,9 @@
     // to be queued up during a safepoint synchronization.
     {
       VMOperationQueue_lock->lock_without_safepoint_check();
+      log_debug(vmthread)("Adding VM operation: %s", op->name());
       bool ok = _vm_queue->add(op);
-    op->set_timestamp(os::javaTimeMillis());
+      op->set_timestamp(os::javaTimeMillis());
       VMOperationQueue_lock->notify();
       VMOperationQueue_lock->unlock();
       // VM_Operation got skipped
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -417,10 +417,6 @@
 
 const int max_method_code_size = 64*K - 1;  // JVM spec, 2nd ed. section 4.8.1 (p.134)
 
-// Default ProtectionDomainCacheSize values
-
-const int defaultProtectionDomainCacheSize = NOT_LP64(137) LP64_ONLY(2017);
-
 //----------------------------------------------------------------------------------------------------
 // Default and minimum StringTableSize values
 
--- a/hotspot/src/share/vm/utilities/hashtable.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -84,6 +84,17 @@
   return entry;
 }
 
+// Version of hashtable entry allocation that allocates in the C heap directly.
+// The allocator in blocks is preferable but doesn't have free semantics.
+template <class T, MEMFLAGS F> HashtableEntry<T, F>* Hashtable<T, F>::allocate_new_entry(unsigned int hashValue, T obj) {
+  HashtableEntry<T, F>* entry = (HashtableEntry<T, F>*) NEW_C_HEAP_ARRAY(char, this->entry_size(), F);
+
+  entry->set_hash(hashValue);
+  entry->set_literal(obj);
+  entry->set_next(NULL);
+  return entry;
+}
+
 // Check to see if the hashtable is unbalanced.  The caller set a flag to
 // rehash at the next safepoint.  If this bucket is 60 times greater than the
 // expected average bucket length, it's an unbalanced hashtable.
@@ -357,6 +368,7 @@
 template class Hashtable<Klass*, mtClass>;
 template class Hashtable<InstanceKlass*, mtClass>;
 template class Hashtable<oop, mtClass>;
+template class Hashtable<Symbol*, mtModule>;
 #if defined(SOLARIS) || defined(CHECK_UNHANDLED_OOPS)
 template class Hashtable<oop, mtSymbol>;
 template class RehashableHashtable<oop, mtSymbol>;
--- a/hotspot/src/share/vm/utilities/hashtable.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/utilities/hashtable.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -253,18 +253,20 @@
   // Debugging
   void print()               PRODUCT_RETURN;
 
-protected:
-
-  unsigned int compute_hash(Symbol* name) {
+  unsigned int compute_hash(const Symbol* name) const {
     return (unsigned int) name->identity_hash();
   }
 
-  int index_for(Symbol* name) {
+  int index_for(const Symbol* name) const {
     return this->hash_to_index(compute_hash(name));
   }
 
+protected:
+
   // Table entry management
   HashtableEntry<T, F>* new_entry(unsigned int hashValue, T obj);
+  // Don't create and use freelist of HashtableEntry.
+  HashtableEntry<T, F>* allocate_new_entry(unsigned int hashValue, T obj);
 
   // The following method is MT-safe and may be used with caution.
   HashtableEntry<T, F>* bucket(int i) const {
@@ -324,31 +326,4 @@
 template <class T, MEMFLAGS F> juint RehashableHashtable<T, F>::seed() { return _seed; };
 template <class T, MEMFLAGS F> bool  RehashableHashtable<T, F>::use_alternate_hashcode() { return _seed != 0; };
 
-// Versions of hashtable where two handles are used to compute the index.
-
-template <class T, MEMFLAGS F> class TwoOopHashtable : public Hashtable<T, F> {
-  friend class VMStructs;
-protected:
-  TwoOopHashtable(int table_size, int entry_size)
-    : Hashtable<T, F>(table_size, entry_size) {}
-
-  TwoOopHashtable(int table_size, int entry_size, HashtableBucket<F>* t,
-                  int number_of_entries)
-    : Hashtable<T, F>(table_size, entry_size, t, number_of_entries) {}
-
-public:
-  unsigned int compute_hash(const Symbol* name, const ClassLoaderData* loader_data) const {
-    unsigned int name_hash = name->identity_hash();
-    // loader is null with CDS
-    assert(loader_data != NULL || UseSharedSpaces || DumpSharedSpaces,
-           "only allowed with shared spaces");
-    unsigned int loader_hash = loader_data == NULL ? 0 : loader_data->identity_hash();
-    return name_hash ^ loader_hash;
-  }
-
-  int index_for(Symbol* name, ClassLoaderData* loader_data) {
-    return this->hash_to_index(compute_hash(name, loader_data));
-  }
-};
-
 #endif // SHARE_VM_UTILITIES_HASHTABLE_HPP
--- a/hotspot/src/share/vm/utilities/xmlstream.cpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/utilities/xmlstream.cpp	Tue Aug 01 21:29:55 2017 +0000
@@ -380,7 +380,7 @@
 // ------------------------------------------------------------------
 // Output a method attribute, in the form " method='pkg/cls name sig'".
 // This is used only when there is no ciMethod available.
-void xmlStream::method(methodHandle method) {
+void xmlStream::method(const methodHandle& method) {
   assert_if_no_error(inside_attrs(), "printing attributes");
   if (method.is_null())  return;
   print_raw(" method='");
@@ -408,7 +408,7 @@
   }
 }
 
-void xmlStream::method_text(methodHandle method) {
+void xmlStream::method_text(const methodHandle& method) {
   ResourceMark rm;
   assert_if_no_error(inside_attrs(), "printing attributes");
   if (method.is_null())  return;
--- a/hotspot/src/share/vm/utilities/xmlstream.hpp	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/src/share/vm/utilities/xmlstream.hpp	Tue Aug 01 21:29:55 2017 +0000
@@ -137,14 +137,14 @@
 
   // commonly used XML attributes
   void          stamp();                 // stamp='1.234'
-  void          method(methodHandle m);  // method='k n s' ...
+  void          method(const methodHandle& m);  // method='k n s' ...
   void          klass(Klass* k);         // klass='name'
   void          name(const Symbol* s);   // name='name'
   void          object(const char* attr, Metadata* val);
   void          object(const char* attr, Handle val);
 
   // print the text alone (sans ''):
-  void          method_text(methodHandle m);
+  void          method_text(const methodHandle& m);
   void          klass_text(Klass* k);         // klass='name'
   void          name_text(const Symbol* s);   // name='name'
   void          object_text(Metadata* x);
--- a/hotspot/test/TEST.ROOT	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/TEST.ROOT	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 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
@@ -27,7 +27,7 @@
 # It also contains test-suite configuration information.
 
 # The list of keywords supported in this test suite
-keys=cte_test jcmd nmt regression gc stress
+keys=aot cte_test jcmd nmt regression gc stress
 
 groups=TEST.groups [closed/TEST.groups]
 
--- a/hotspot/test/compiler/aot/DeoptimizationTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/DeoptimizationTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/RecompilationTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/RecompilationTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/SharedUsageTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/SharedUsageTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeDynamic2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeDynamic2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @ignore 8132547
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeDynamic2CompiledTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeDynamic2CompiledTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @ignore 8132547
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeDynamic2InterpretedTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeDynamic2InterpretedTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @ignore 8132547
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeDynamic2NativeTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeDynamic2NativeTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @ignore 8132547
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeInterface2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeInterface2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeInterface2CompiledTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeInterface2CompiledTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeInterface2InterpretedTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeInterface2InterpretedTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeInterface2NativeTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeInterface2NativeTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeSpecial2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeSpecial2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeSpecial2CompiledTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeSpecial2CompiledTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeSpecial2InterpretedTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeSpecial2InterpretedTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeSpecial2NativeTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeSpecial2NativeTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeStatic2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeStatic2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeStatic2CompiledTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeStatic2CompiledTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeStatic2InterpretedTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeStatic2InterpretedTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeStatic2NativeTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeStatic2NativeTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeVirtual2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeVirtual2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeVirtual2CompiledTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeVirtual2CompiledTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeVirtual2InterpretedTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeVirtual2InterpretedTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromAot/AotInvokeVirtual2NativeTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromAot/AotInvokeVirtual2NativeTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromCompiled/CompiledInvokeDynamic2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromCompiled/CompiledInvokeDynamic2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.org.objectweb.asm
--- a/hotspot/test/compiler/aot/calls/fromCompiled/CompiledInvokeInterface2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromCompiled/CompiledInvokeInterface2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromCompiled/CompiledInvokeSpecial2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromCompiled/CompiledInvokeSpecial2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromCompiled/CompiledInvokeStatic2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromCompiled/CompiledInvokeStatic2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromCompiled/CompiledInvokeVirtual2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromCompiled/CompiledInvokeVirtual2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromInterpreted/InterpretedInvokeDynamic2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromInterpreted/InterpretedInvokeDynamic2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.org.objectweb.asm
--- a/hotspot/test/compiler/aot/calls/fromInterpreted/InterpretedInvokeInterface2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromInterpreted/InterpretedInvokeInterface2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromInterpreted/InterpretedInvokeSpecial2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromInterpreted/InterpretedInvokeSpecial2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromInterpreted/InterpretedInvokeStatic2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromInterpreted/InterpretedInvokeStatic2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromInterpreted/InterpretedInvokeVirtual2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromInterpreted/InterpretedInvokeVirtual2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromNative/NativeInvokeSpecial2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromNative/NativeInvokeSpecial2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromNative/NativeInvokeStatic2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromNative/NativeInvokeStatic2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/calls/fromNative/NativeInvokeVirtual2AotTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/calls/fromNative/NativeInvokeVirtual2AotTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/cli/DisabledAOTWithLibraryTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/DisabledAOTWithLibraryTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @build compiler.aot.cli.DisabledAOTWithLibraryTest
--- a/hotspot/test/compiler/aot/cli/IncorrectAOTLibraryTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/IncorrectAOTLibraryTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/MultipleAOTLibraryTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/MultipleAOTLibraryTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/NonExistingAOTLibraryTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/NonExistingAOTLibraryTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/SingleAOTLibraryTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/SingleAOTLibraryTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib / /testlibrary
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/SingleAOTOptionTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/SingleAOTOptionTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /testlibrary /
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionUnknownClassTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionUnknownClassTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library / /testlibrary/ /test/lib
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/jaotc/CompileClassTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/jaotc/CompileClassTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library / /test/lib /testlibrary
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/jaotc/CompileDirectoryTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/jaotc/CompileDirectoryTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library / /test/lib /testlibrary
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/jaotc/CompileJarTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/jaotc/CompileJarTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library / /test/lib /testlibrary
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/jaotc/CompileModuleTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/jaotc/CompileModuleTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library / /test/lib /testlibrary
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/jaotc/ListOptionNotExistingTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/jaotc/ListOptionNotExistingTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library / /test/lib /testlibrary
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/jaotc/ListOptionTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/jaotc/ListOptionTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library / /test/lib /testlibrary
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/cli/jaotc/ListOptionWrongFileTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/cli/jaotc/ListOptionWrongFileTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library / /test/lib /testlibrary
  * @modules java.base/jdk.internal.misc
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/NativeOrderOutputStreamTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/NativeOrderOutputStreamTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /**
  * @test
+ * @key aot
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules jdk.aot/jdk.tools.jaotc.utils
  * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.tools.jaotc.test.NativeOrderOutputStreamTest
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /**
  * @test
+ * @key aot
  * @modules jdk.aot/jdk.tools.jaotc
  *          jdk.aot/jdk.tools.jaotc.collect
  * @run junit/othervm jdk.tools.jaotc.test.collect.ClassSearchTest
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /**
  * @test
+ * @key aot
  * @modules jdk.aot/jdk.tools.jaotc
  *          jdk.aot/jdk.tools.jaotc.collect
  * @build jdk.tools.jaotc.test.collect.Utils
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /**
  * @test
+ * @key aot
  * @modules jdk.aot/jdk.tools.jaotc
  *          jdk.aot/jdk.tools.jaotc.collect
  *
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /**
  * @test
+ * @key aot
  * @modules jdk.aot/jdk.tools.jaotc
  *          jdk.aot/jdk.tools.jaotc.collect
  *          jdk.aot/jdk.tools.jaotc.collect.directory
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /**
  * @test
+ * @key aot
  * @modules jdk.aot/jdk.tools.jaotc
  *          jdk.aot/jdk.tools.jaotc.collect
  *          jdk.aot/jdk.tools.jaotc.collect.jar
--- a/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /**
  * @test
+ * @key aot
  * @modules jdk.aot/jdk.tools.jaotc
  *          jdk.aot/jdk.tools.jaotc.collect
  *          jdk.aot/jdk.tools.jaotc.collect.module
--- a/hotspot/test/compiler/aot/verification/ClassAndLibraryNotMatchTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/verification/ClassAndLibraryNotMatchTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/verification/vmflags/NotTrackedFlagTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/verification/vmflags/NotTrackedFlagTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/aot/verification/vmflags/TrackedFlagTest.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/compiler/aot/verification/vmflags/TrackedFlagTest.java	Tue Aug 01 21:29:55 2017 +0000
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @key aot
  * @library /test/lib /
  * @requires vm.bits == "64" & (os.arch == "amd64" | os.arch == "x86_64")
  * @modules java.base/jdk.internal.misc
--- a/hotspot/test/gc/TestFullGCALot.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/gc/TestFullGCALot.java	Tue Aug 01 21:29:55 2017 +0000
@@ -25,9 +25,9 @@
  * @test TestFullGCALot
  * @key gc
  * @bug 4187687
- * @summary Ensure no acess violation when using FullGCALot
+ * @summary Ensure no access violation when using FullGCALot
  * @requires vm.debug
- * @run main/othervm -XX:+FullGCALot -XX:FullGCALotInterval=120 TestFullGCALot
+ * @run main/othervm -XX:NewSize=10m -XX:+FullGCALot -XX:FullGCALotInterval=120 TestFullGCALot
  */
 
 public class TestFullGCALot {
--- a/hotspot/test/gc/stress/systemgc/TestSystemGC.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/gc/stress/systemgc/TestSystemGC.java	Tue Aug 01 21:29:55 2017 +0000
@@ -182,9 +182,11 @@
     }
 
     public static void main(String[] args) {
-        // First allocate the long lived objects and then run all phases twice.
+        // First allocate the long lived objects and then run all phases.
         populateLongLived();
         runAllPhases();
-        runAllPhases();
+        if (args.length > 0 && args[0].equals("long")) {
+            runAllPhases();
+        }
     }
 }
--- a/hotspot/test/runtime/NMT/CheckForProperDetailStackTrace.java	Tue Jul 25 14:04:53 2017 -0400
+++ b/hotspot/test/runtime/NMT/CheckForProperDetailStackTrace.java	Tue Aug 01 21:29:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -40,10 +40,10 @@
     /* The stack trace we look for by default. Note that :: has been replaced by .*
        to make sure it maches even if the symbol is not unmangled. */
     public static String stackTraceDefault =
+        ".*Hashtable.*allocate_new_entry.*\n" +
         ".*ModuleEntryTable.*new_entry.*\n" +
         ".*ModuleEntryTable.*locked_create_entry_or_null.*\n" +
-        ".*Modules.*define_module.*\n" +
-        ".*JVM_DefineModule.*\n";
+        ".*Modules.*define_module.*\n";
 
     /* The stack trace we look for on Solaris and Windows slowdebug builds. For some
        reason ALWAYSINLINE for AllocateHeap is ignored, so it appears in the stack strace. */