Merge
authorprr
Mon, 07 Aug 2017 09:45:38 -0700
changeset 47171 8dfd3d2dd906
parent 47170 ac621266a4b8 (current diff)
parent 46096 62c77b334012 (diff)
child 47172 ced0784a8640
Merge
jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMConfigurationException.java
jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java
jdk/test/java/lang/ClassLoader/getResource/GetResource.sh
jdk/test/tools/launcher/modules/patch/systemmodules/src1/java.base/jdk/internal/modules/SystemModules.java
--- a/.hgtags	Mon Aug 07 10:02:39 2017 +0530
+++ b/.hgtags	Mon Aug 07 09:45:38 2017 -0700
@@ -1,3 +1,5 @@
+e2b70be325bd10dae4c06f74c46d70d480854916 jdk-9+179
+5b16a1c3ccffff2a82c88bb7ea894c4ff1c9ebde jdk-9+180
 43bf6f30fcba031ecf0cc7e511efe3a8179d0f77 jdk-9+176
 d9f6bc6ba599d0487dc18b2fbdb6c34eedf6f958 jdk-9+177
 bc9df7dd63ec76f50fafeb4acc44465044662f0a jdk-9+178
@@ -438,3 +440,4 @@
 9ef5029b247b4d940080417a287440bbdbab995b jdk-10+14
 878e216039322cb3f0ecbd0944642a2b4e2593f3 jdk-10+15
 4bbea012e5676e8025ade2bcfab4d6581e6e9f4b jdk-10+16
+7db699468b4f84abbcc01647e5a964409737411a jdk-10+17
--- a/.hgtags-top-repo	Mon Aug 07 10:02:39 2017 +0530
+++ b/.hgtags-top-repo	Mon Aug 07 09:45:38 2017 -0700
@@ -437,3 +437,6 @@
 a4371edb589c60db01142e45c317adb9ccbcb083 jdk-9+177
 a6c830ee8a6798b186730475e700027cdf4598aa jdk-10+15
 2fe66ca1e2b3c361f949de9cb2894661dc0a3fa2 jdk-10+16
+ec4159ebe7050fcc5dcee8a2d150cf948ecc97db jdk-9+178
+252475ccfd84cc249f8d6faf4b7806b5e2c384ce jdk-9+179
+a133a7d1007b1456bc62824382fd8ac93b45d329 jdk-10+17
--- a/corba/.hgtags	Mon Aug 07 10:02:39 2017 +0530
+++ b/corba/.hgtags	Mon Aug 07 09:45:38 2017 -0700
@@ -437,3 +437,6 @@
 c72e9d3823f04cb3ef3166646dfea9e4c2769133 jdk-9+177
 15f59cfc6fbe9387423fb173e962265c7b5d357e jdk-10+15
 b82b62ed5debda2d98dda597506ef29cf947fbae jdk-10+16
+9c1e9712648921ae389d623042d22561fad82d75 jdk-9+178
+24390da83c5ee9e23ceafbcaff4460a01e37bb3a jdk-9+179
+50ff1fd66362f212a8db6de76089d9d0ffa4df0f jdk-10+17
--- a/hotspot/.hgtags	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/.hgtags	Mon Aug 07 09:45:38 2017 -0700
@@ -597,3 +597,6 @@
 1ca8f038fceb88c640badf9bd18905205bc63b43 jdk-9+177
 c1f3649a3a42f124b418a5a916dbad13d059b757 jdk-10+15
 2fe2a593e8ebf3a9e4dcd9ba3333a7b43126589d jdk-10+16
+9d032191f82fca5ba0aac98682f69c4ff0f1283d jdk-9+178
+d2661aa42bff322badbe6c1337fc638d2e0f5730 jdk-9+179
+73e2cb8700bfa51304bd4b02f224620859a3f600 jdk-10+17
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad	Mon Aug 07 09:45:38 2017 -0700
@@ -14394,7 +14394,7 @@
   ins_pipe(icmp_reg_reg);
 %}
 
-instruct compL_reg_immI0(rFlagsReg cr, iRegL op1, immI0 zero)
+instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero)
 %{
   match(Set cr (CmpL op1 zero));
 
@@ -14436,6 +14436,62 @@
   ins_pipe(icmp_reg_imm);
 %}
 
+instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2)
+%{
+  match(Set cr (CmpUL op1 op2));
+
+  effect(DEF cr, USE op1, USE op2);
+
+  ins_cost(INSN_COST);
+  format %{ "cmp  $op1, $op2" %}
+
+  ins_encode(aarch64_enc_cmp(op1, op2));
+
+  ins_pipe(icmp_reg_reg);
+%}
+
+instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero)
+%{
+  match(Set cr (CmpUL op1 zero));
+
+  effect(DEF cr, USE op1);
+
+  ins_cost(INSN_COST);
+  format %{ "tst  $op1" %}
+
+  ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
+
+  ins_pipe(icmp_reg_imm);
+%}
+
+instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2)
+%{
+  match(Set cr (CmpUL op1 op2));
+
+  effect(DEF cr, USE op1);
+
+  ins_cost(INSN_COST);
+  format %{ "cmp  $op1, $op2" %}
+
+  ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
+
+  ins_pipe(icmp_reg_imm);
+%}
+
+instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2)
+%{
+  match(Set cr (CmpUL op1 op2));
+
+  effect(DEF cr, USE op1);
+
+  ins_cost(INSN_COST * 2);
+  format %{ "cmp  $op1, $op2" %}
+
+  ins_encode(aarch64_enc_cmp_imm(op1, op2));
+
+  ins_pipe(icmp_reg_imm);
+%}
+
 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2)
 %{
   match(Set cr (CmpP op1 op2));
@@ -14920,7 +14976,7 @@
 %}
 
 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{
-  match(If cmp (CmpU op1 op2));
+  match(If cmp (CmpUL op1 op2));
   effect(USE labl);
 
   ins_cost(BRANCH_COST);
--- a/hotspot/src/cpu/aarch64/vm/c2_globals_aarch64.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/c2_globals_aarch64.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -49,12 +49,11 @@
 define_pd_global(intx, FLOATPRESSURE,                64);
 define_pd_global(intx, FreqInlineSize,               325);
 define_pd_global(intx, MinJumpTableSize,             10);
-define_pd_global(intx, INTPRESSURE,                  25);
+define_pd_global(intx, INTPRESSURE,                  24);
 define_pd_global(intx, InteriorEntryAlignment,       16);
 define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
 define_pd_global(intx, LoopUnrollLimit,              60);
 define_pd_global(intx, LoopPercentProfileLimit,      10);
-define_pd_global(intx, PostLoopMultiversioning,      false);
 // InitialCodeCacheSize derived from specjbb2000 run.
 define_pd_global(intx, InitialCodeCacheSize,         2496*K); // Integral multiple of CodeCacheExpansionSize
 define_pd_global(intx, CodeCacheExpansionSize,       64*K);
--- a/hotspot/src/cpu/arm/vm/arm.ad	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/arm/vm/arm.ad	Mon Aug 07 09:45:38 2017 -0700
@@ -2695,6 +2695,30 @@
   format %{ "apsr_L_LEGT" %}
   interface(REG_INTER);
 %}
+
+operand flagsRegUL_LTGE() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+
+  format %{ "apsr_UL_LTGE" %}
+  interface(REG_INTER);
+%}
+
+operand flagsRegUL_EQNE() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+
+  format %{ "apsr_UL_EQNE" %}
+  interface(REG_INTER);
+%}
+
+operand flagsRegUL_LEGT() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+
+  format %{ "apsr_UL_LEGT" %}
+  interface(REG_INTER);
+%}
 #endif
 
 // Condition Code Register, floating comparisons, unordered same as "less".
@@ -3249,6 +3273,39 @@
   %}
 %}
 
+operand cmpOpUL() %{
+  match(Bool);
+
+  format %{ "UL" %}
+  interface(COND_INTER) %{
+    equal(0x0);
+    not_equal(0x1);
+    less(0x3);
+    greater_equal(0x2);
+    less_equal(0x9);
+    greater(0x8);
+    overflow(0x0); // unsupported/unimplemented
+    no_overflow(0x0); // unsupported/unimplemented
+  %}
+%}
+
+operand cmpOpUL_commute() %{
+  match(Bool);
+
+  format %{ "UL" %}
+  interface(COND_INTER) %{
+    equal(0x0);
+    not_equal(0x1);
+    less(0x8);
+    greater_equal(0x9);
+    less_equal(0x2);
+    greater(0x3);
+    overflow(0x0); // unsupported/unimplemented
+    no_overflow(0x0); // unsupported/unimplemented
+  %}
+%}
+
+
 //----------OPERAND CLASSES----------------------------------------------------
 // Operand Classes are groups of operands that are used to simplify
 // instruction definitions by not requiring the AD writer to specify separate
@@ -10467,6 +10524,17 @@
   %}
   ins_pipe(ialu_cconly_reg_reg);
 %}
+
+instruct compUL_iReg(flagsRegU xcc, iRegL op1, iRegL op2) %{
+  match(Set xcc (CmpUL op1 op2));
+
+  size(4);
+  format %{ "CMP     $op1,$op2\t! unsigned long" %}
+  ins_encode %{
+    __ cmp($op1$$Register, $op2$$Register);
+  %}
+  ins_pipe(ialu_cconly_reg_reg);
+%}
 #else
 instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
   match(Set xcc (CmpL op1 op2));
@@ -10481,6 +10549,20 @@
   %}
   ins_pipe(ialu_cconly_reg_reg);
 %}
+
+instruct compUL_reg_reg_LTGE(flagsRegUL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
+  match(Set xcc (CmpUL op1 op2));
+  effect(DEF xcc, USE op1, USE op2, TEMP tmp);
+
+  size(8);
+  format %{ "SUBS    $tmp,$op1.low,$op2.low\t\t! unsigned long\n\t"
+            "SBCS    $tmp,$op1.hi,$op2.hi" %}
+  ins_encode %{
+    __ subs($tmp$$Register, $op1$$Register, $op2$$Register);
+    __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
+  %}
+  ins_pipe(ialu_cconly_reg_reg);
+%}
 #endif
 
 #ifdef AARCH64
@@ -10496,6 +10578,19 @@
 
   ins_pipe(ialu_cconly_reg_imm);
 %}
+
+instruct compUL_reg_con(flagsRegU xcc, iRegL op1, aimmL con) %{
+  match(Set xcc (CmpUL op1 con));
+  effect(DEF xcc, USE op1, USE con);
+
+  size(8);
+  format %{ "CMP     $op1,$con\t\t! unsigned long"  %}
+  ins_encode %{
+    __ cmp($op1$$Register, $con$$constant);
+  %}
+
+  ins_pipe(ialu_cconly_reg_imm);
+%}
 #else
 instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
   match(Set xcc (CmpL op1 op2));
@@ -10575,6 +10670,85 @@
 
   ins_pipe(ialu_cconly_reg_reg);
 %}
+
+instruct compUL_reg_reg_EQNE(flagsRegUL_EQNE xcc, iRegL op1, iRegL op2) %{
+  match(Set xcc (CmpUL op1 op2));
+  effect(DEF xcc, USE op1, USE op2);
+
+  size(8);
+  format %{ "TEQ    $op1.hi,$op2.hi\t\t! unsigned long\n\t"
+            "TEQ.eq $op1.lo,$op2.lo" %}
+  ins_encode %{
+    __ teq($op1$$Register->successor(), $op2$$Register->successor());
+    __ teq($op1$$Register, $op2$$Register, eq);
+  %}
+  ins_pipe(ialu_cconly_reg_reg);
+%}
+
+instruct compUL_reg_reg_LEGT(flagsRegUL_LEGT xcc, iRegL op1, iRegL op2, iRegL tmp) %{
+  match(Set xcc (CmpUL op1 op2));
+  effect(DEF xcc, USE op1, USE op2, TEMP tmp);
+
+  size(8);
+  format %{ "SUBS    $tmp,$op2.low,$op1.low\t\t! unsigned long\n\t"
+            "SBCS    $tmp,$op2.hi,$op1.hi" %}
+  ins_encode %{
+    __ subs($tmp$$Register, $op2$$Register, $op1$$Register);
+    __ sbcs($tmp$$Register->successor(), $op2$$Register->successor(), $op1$$Register->successor());
+  %}
+  ins_pipe(ialu_cconly_reg_reg);
+%}
+
+// TODO: try immLRot2 instead, (0, $con$$constant) becomes
+// (hi($con$$constant), lo($con$$constant)) becomes
+instruct compUL_reg_con_LTGE(flagsRegUL_LTGE xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
+  match(Set xcc (CmpUL op1 con));
+  effect(DEF xcc, USE op1, USE con, TEMP tmp);
+
+  size(8);
+  format %{ "SUBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
+            "SBCS    $tmp,$op1.hi,0" %}
+  ins_encode %{
+    __ subs($tmp$$Register, $op1$$Register, $con$$constant);
+    __ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
+  %}
+
+  ins_pipe(ialu_cconly_reg_reg);
+%}
+
+// TODO: try immLRot2 instead, (0, $con$$constant) becomes
+// (hi($con$$constant), lo($con$$constant)) becomes
+instruct compUL_reg_con_EQNE(flagsRegUL_EQNE xcc, iRegL op1, immLlowRot con) %{
+  match(Set xcc (CmpUL op1 con));
+  effect(DEF xcc, USE op1, USE con);
+
+  size(8);
+  format %{ "TEQ    $op1.hi,0\t\t! unsigned long\n\t"
+            "TEQ.eq $op1.lo,$con" %}
+  ins_encode %{
+    __ teq($op1$$Register->successor(), 0);
+    __ teq($op1$$Register, $con$$constant, eq);
+  %}
+
+  ins_pipe(ialu_cconly_reg_reg);
+%}
+
+// TODO: try immLRot2 instead, (0, $con$$constant) becomes
+// (hi($con$$constant), lo($con$$constant)) becomes
+instruct compUL_reg_con_LEGT(flagsRegUL_LEGT xcc, iRegL op1, immLlowRot con, iRegL tmp) %{
+  match(Set xcc (CmpUL op1 con));
+  effect(DEF xcc, USE op1, USE con, TEMP tmp);
+
+  size(8);
+  format %{ "RSBS    $tmp,$op1.low,$con\t\t! unsigned long\n\t"
+            "RSCS    $tmp,$op1.hi,0" %}
+  ins_encode %{
+    __ rsbs($tmp$$Register, $op1$$Register, $con$$constant);
+    __ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
+  %}
+
+  ins_pipe(ialu_cconly_reg_reg);
+%}
 #endif
 
 /* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
@@ -11126,6 +11300,48 @@
   %}
   ins_pipe(br_cc);
 %}
+
+instruct branchConUL_LTGE(cmpOpUL cmp, flagsRegUL_LTGE xcc, label labl) %{
+  match(If cmp xcc);
+  effect(USE labl);
+  predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
+
+  size(4);
+  ins_cost(BRANCH_COST);
+  format %{ "B$cmp  $xcc,$labl" %}
+  ins_encode %{
+    __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
+  %}
+  ins_pipe(br_cc);
+%}
+
+instruct branchConUL_EQNE(cmpOpUL cmp, flagsRegUL_EQNE xcc, label labl) %{
+  match(If cmp xcc);
+  effect(USE labl);
+  predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
+
+  size(4);
+  ins_cost(BRANCH_COST);
+  format %{ "B$cmp  $xcc,$labl" %}
+  ins_encode %{
+    __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
+  %}
+  ins_pipe(br_cc);
+%}
+
+instruct branchConUL_LEGT(cmpOpUL_commute cmp, flagsRegUL_LEGT xcc, label labl) %{
+  match(If cmp xcc);
+  effect(USE labl);
+  predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
+
+  size(4);
+  ins_cost(BRANCH_COST);
+  format %{ "B$cmp  $xcc,$labl" %}
+  ins_encode %{
+    __ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
+  %}
+  ins_pipe(br_cc);
+%}
 #endif
 
 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
--- a/hotspot/src/cpu/arm/vm/c2_globals_arm.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/arm/vm/c2_globals_arm.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -70,7 +70,6 @@
 define_pd_global(bool, ResizeTLAB,                   true);
 define_pd_global(intx, LoopUnrollLimit,              60); // Design center runs on 1.3.1
 define_pd_global(intx, LoopPercentProfileLimit,      10);
-define_pd_global(intx, PostLoopMultiversioning,      false);
 define_pd_global(intx, MinJumpTableSize,             16);
 
 // Peephole and CISC spilling both break the graph, and so makes the
--- a/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -55,7 +55,6 @@
 define_pd_global(bool, ResizeTLAB,                   true);
 define_pd_global(intx, LoopUnrollLimit,              60);
 define_pd_global(intx, LoopPercentProfileLimit,      10);
-define_pd_global(intx, PostLoopMultiversioning,      false);
 
 // Peephole and CISC spilling both break the graph, and so make the
 // scheduler sick.
--- a/hotspot/src/cpu/ppc/vm/ppc.ad	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad	Mon Aug 07 09:45:38 2017 -0700
@@ -11048,6 +11048,29 @@
   ins_pipe(pipe_class_compare);
 %}
 
+// Added CmpUL for LoopPredicate.
+instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
+  match(Set crx (CmpUL src1 src2));
+  format %{ "CMPLD   $crx, $src1, $src2" %}
+  size(4);
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
+    __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
+  %}
+  ins_pipe(pipe_class_compare);
+%}
+
+instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
+  match(Set crx (CmpUL src1 src2));
+  format %{ "CMPLDI  $crx, $src1, $src2" %}
+  size(4);
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_cmpli);
+    __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
+  %}
+  ins_pipe(pipe_class_compare);
+%}
+
 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{
   match(Set cr0 (CmpL (AndL src1 src2) zero));
   // r0 is killed
--- a/hotspot/src/cpu/s390/vm/c2_globals_s390.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/c2_globals_s390.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -56,7 +56,6 @@
 define_pd_global(bool, ResizeTLAB,                   true);
 define_pd_global(intx, LoopUnrollLimit,              60);
 define_pd_global(intx, LoopPercentProfileLimit,      10);
-define_pd_global(intx, PostLoopMultiversioning,      false);
 define_pd_global(intx, MinJumpTableSize,             18);
 
 // Peephole and CISC spilling both break the graph, and so makes the
--- a/hotspot/src/cpu/s390/vm/s390.ad	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/s390.ad	Mon Aug 07 09:45:38 2017 -0700
@@ -8475,6 +8475,24 @@
 %}
 
 //  LONG unsigned
+// Added CmpUL for LoopPredicate.
+instruct compUL_reg_reg(flagsReg cr, iRegL op1, iRegL op2) %{
+  match(Set cr (CmpUL op1 op2));
+  size(4);
+  format %{ "CLGR    $op1,$op2\t # long" %}
+  opcode(CLGR_ZOPC);
+  ins_encode(z_rreform(op1, op2));
+  ins_pipe(pipe_class_dummy);
+%}
+
+instruct compUL_reg_imm32(flagsReg cr, iRegL op1, uimmL32 con) %{
+  match(Set cr (CmpUL op1 con));
+  size(6);
+  format %{ "CLGFI   $op1,$con" %}
+  opcode(CLGFI_ZOPC);
+  ins_encode(z_rilform_unsigned(op1, con));
+  ins_pipe(pipe_class_dummy);
+%}
 
 //  PTR unsigned
 
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -53,7 +53,6 @@
 define_pd_global(bool, ResizeTLAB,                   true);
 define_pd_global(intx, LoopUnrollLimit,              60); // Design center runs on 1.3.1
 define_pd_global(intx, LoopPercentProfileLimit,      10);
-define_pd_global(intx, PostLoopMultiversioning,      false);
 define_pd_global(intx, MinJumpTableSize,             5);
 
 // Peephole and CISC spilling both break the graph, and so makes the
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Mon Aug 07 09:45:38 2017 -0700
@@ -3403,6 +3403,16 @@
   interface(CONST_INTER);
 %}
 
+// Unsigned Long Immediate: 12-bit (non-negative that fits in simm13)
+operand immUL12() %{
+  predicate((0 <= n->get_long()) && (n->get_long() == (int)n->get_long()) && Assembler::is_simm13((int)n->get_long()));
+  match(ConL);
+  op_cost(0);
+
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 // Integer Immediate non-negative
 operand immU31()
 %{
@@ -3936,6 +3946,15 @@
   interface(REG_INTER);
 %}
 
+// Condition Code Register, unsigned long comparisons.
+operand flagsRegUL() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+
+  format %{ "xcc_UL" %}
+  interface(REG_INTER);
+%}
+
 // Condition Code Register, floating comparisons, unordered same as "less".
 operand flagsRegF() %{
   constraint(ALLOC_IN_RC(float_flags));
@@ -8797,6 +8816,17 @@
   ins_pipe(ialu_cconly_reg_reg);
 %}
 
+instruct compUL_iReg(flagsRegUL xcc, iRegL op1, iRegL op2) %{
+  match(Set xcc (CmpUL op1 op2));
+  effect(DEF xcc, USE op1, USE op2);
+
+  size(4);
+  format %{ "CMP    $op1,$op2\t! unsigned long" %}
+  opcode(Assembler::subcc_op3, Assembler::arith_op);
+  ins_encode(form3_rs1_rs2_rd(op1, op2, R_G0));
+  ins_pipe(ialu_cconly_reg_reg);
+%}
+
 instruct compI_iReg_imm13(flagsReg icc, iRegI op1, immI13 op2) %{
   match(Set icc (CmpI op1 op2));
   effect( DEF icc, USE op1 );
@@ -8883,6 +8913,17 @@
   ins_pipe(ialu_cconly_reg_imm);
 %}
 
+instruct compUL_iReg_imm13(flagsRegUL xcc, iRegL op1, immUL12 op2) %{
+  match(Set xcc (CmpUL op1 op2));
+  effect(DEF xcc, USE op1, USE op2);
+
+  size(4);
+  format %{ "CMP    $op1,$op2\t! unsigned long" %}
+  opcode(Assembler::subcc_op3, Assembler::arith_op);
+  ins_encode(form3_rs1_simm13_rd(op1, op2, R_G0));
+  ins_pipe(ialu_cconly_reg_imm);
+%}
+
 // Compare Pointers
 instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{
   match(Set pcc (CmpP op1 op2));
@@ -9256,6 +9297,44 @@
   ins_pipe(cmp_br_reg_imm);
 %}
 
+instruct cmpUL_reg_branch(cmpOpU cmp, iRegL op1, iRegL op2, label labl, flagsRegUL xcc) %{
+  match(If cmp (CmpUL op1 op2));
+  effect(USE labl, KILL xcc);
+
+  size(12);
+  ins_cost(BRANCH_COST);
+  format %{ "CMP    $op1,$op2\t! unsigned long\n\t"
+            "BP$cmp   $labl" %}
+  ins_encode %{
+    Label* L = $labl$$label;
+    Assembler::Predict predict_taken =
+      cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
+    __ cmp($op1$$Register, $op2$$Register);
+    __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
+    __ delayed()->nop();
+  %}
+  ins_pipe(cmp_br_reg_reg);
+%}
+
+instruct cmpUL_imm_branch(cmpOpU cmp, iRegL op1, immL5 op2, label labl, flagsRegUL xcc) %{
+  match(If cmp (CmpUL op1 op2));
+  effect(USE labl, KILL xcc);
+
+  size(12);
+  ins_cost(BRANCH_COST);
+  format %{ "CMP    $op1,$op2\t! unsigned long\n\t"
+            "BP$cmp   $labl" %}
+  ins_encode %{
+    Label* L = $labl$$label;
+    Assembler::Predict predict_taken =
+      cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
+    __ cmp($op1$$Register, $op2$$constant);
+    __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
+    __ delayed()->nop();
+  %}
+  ins_pipe(cmp_br_reg_imm);
+%}
+
 instruct cmpL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{
   match(If cmp (CmpL op1 op2));
   effect(USE labl, KILL xcc);
@@ -9484,6 +9563,42 @@
   ins_pipe(cbcond_reg_imm);
 %}
 
+instruct cmpUL_reg_branch_short(cmpOpU cmp, iRegL op1, iRegL op2, label labl, flagsRegUL xcc) %{
+  match(If cmp (CmpUL op1 op2));
+  predicate(UseCBCond);
+  effect(USE labl, KILL xcc);
+
+  size(4);
+  ins_cost(BRANCH_COST);
+  format %{ "CXB$cmp  $op1,$op2,$labl\t! unsigned long" %}
+  ins_encode %{
+    Label* L = $labl$$label;
+    assert(__ use_cbcond(*L), "back to back cbcond");
+    __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$Register, *L);
+  %}
+  ins_short_branch(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
+  ins_pipe(cbcond_reg_reg);
+%}
+
+instruct cmpUL_imm_branch_short(cmpOpU cmp, iRegL op1, immL5 op2, label labl, flagsRegUL xcc) %{
+  match(If cmp (CmpUL op1 op2));
+  predicate(UseCBCond);
+  effect(USE labl, KILL xcc);
+
+  size(4);
+  ins_cost(BRANCH_COST);
+  format %{ "CXB$cmp  $op1,$op2,$labl\t! unsigned long" %}
+  ins_encode %{
+    Label* L = $labl$$label;
+    assert(__ use_cbcond(*L), "back to back cbcond");
+    __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$constant, *L);
+  %}
+  ins_short_branch(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
+  ins_pipe(cbcond_reg_imm);
+%}
+
 instruct cmpL_reg_branch_short(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{
   match(If cmp (CmpL op1 op2));
   predicate(UseCBCond);
@@ -9722,6 +9837,25 @@
   ins_pipe(br_cc);
 %}
 
+instruct branchConU_long(cmpOpU cmp, flagsRegUL xcc, label labl) %{
+  match(If cmp xcc);
+  effect(USE labl);
+
+  size(8);
+  ins_cost(BRANCH_COST);
+  format %{ "BP$cmp   $xcc,$labl" %}
+  ins_encode %{
+    Label* L = $labl$$label;
+    Assembler::Predict predict_taken =
+      cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
+
+    __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
+    __ delayed()->nop();
+  %}
+  ins_avoid_back_to_back(AVOID_BEFORE);
+  ins_pipe(br_cc);
+%}
+
 // Manifest a CmpL3 result in an integer register.  Very painful.
 // This is the test to avoid.
 instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -47,7 +47,6 @@
 define_pd_global(intx, FreqInlineSize,               325);
 define_pd_global(intx, MinJumpTableSize,             10);
 define_pd_global(intx, LoopPercentProfileLimit,      30);
-define_pd_global(intx, PostLoopMultiversioning,      true);
 #ifdef AMD64
 define_pd_global(intx, INTPRESSURE,                  13);
 define_pd_global(intx, FLOATPRESSURE,                14);
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -116,7 +116,7 @@
   product(bool, UseStoreImmI16, true,                                       \
           "Use store immediate 16-bits value instruction on x86")           \
                                                                             \
-  product(intx, UseAVX, 99,                                                 \
+  product(intx, UseAVX, 2,                                                  \
           "Highest supported AVX instructions set on x86/x64")              \
           range(0, 99)                                                      \
                                                                             \
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Mon Aug 07 09:45:38 2017 -0700
@@ -4030,6 +4030,26 @@
   interface(REG_INTER);
 %}
 
+// Condition Code Register used by unsigned long compare
+operand flagsReg_ulong_LTGE() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+  format %{ "FLAGS_U_LTGE" %}
+  interface(REG_INTER);
+%}
+operand flagsReg_ulong_EQNE() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+  format %{ "FLAGS_U_EQNE" %}
+  interface(REG_INTER);
+%}
+operand flagsReg_ulong_LEGT() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+  format %{ "FLAGS_U_LEGT" %}
+  interface(REG_INTER);
+%}
+
 // Float register operands
 operand regDPR() %{
   predicate( UseSSE < 2 );
@@ -4588,7 +4608,7 @@
   %}
 %}
 
-// Comparision Code used in long compares
+// Comparison Code used in long compares
 operand cmpOp_commute() %{
   match(Bool);
 
@@ -4605,6 +4625,23 @@
   %}
 %}
 
+// Comparison Code used in unsigned long compares
+operand cmpOpU_commute() %{
+  match(Bool);
+
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x7, "nbe");
+    greater_equal(0x6, "be");
+    less_equal(0x3, "nb");
+    greater(0x2, "b");
+    overflow(0x0, "o");
+    no_overflow(0x1, "no");
+  %}
+%}
+
 //----------OPERAND CLASSES----------------------------------------------------
 // Operand Classes are groups of operands that are used as to simplify
 // instruction definitions by not requiring the AD writer to specify separate
@@ -12639,6 +12676,44 @@
   %}
 %}
 
+//======
+// Manifest a CmpUL result in the normal flags.  Only good for LT or GE
+// compares.  Can be used for LE or GT compares by reversing arguments.
+// NOT GOOD FOR EQ/NE tests.
+instruct cmpUL_zero_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src, immL0 zero) %{
+  match(Set flags (CmpUL src zero));
+  ins_cost(100);
+  format %{ "TEST   $src.hi,$src.hi" %}
+  opcode(0x85);
+  ins_encode(OpcP, RegReg_Hi2(src, src));
+  ins_pipe(ialu_cr_reg_reg);
+%}
+
+// Manifest a CmpUL result in the normal flags.  Only good for LT or GE
+// compares.  Can be used for LE or GT compares by reversing arguments.
+// NOT GOOD FOR EQ/NE tests.
+instruct cmpUL_reg_flags_LTGE(flagsReg_ulong_LTGE flags, eRegL src1, eRegL src2, rRegI tmp) %{
+  match(Set flags (CmpUL src1 src2));
+  effect(TEMP tmp);
+  ins_cost(300);
+  format %{ "CMP    $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t"
+            "MOV    $tmp,$src1.hi\n\t"
+            "SBB    $tmp,$src2.hi\t! Compute flags for unsigned long compare" %}
+  ins_encode(long_cmp_flags2(src1, src2, tmp));
+  ins_pipe(ialu_cr_reg_reg);
+%}
+
+// Unsigned long compares reg < zero/req OR reg >= zero/req.
+// Just a wrapper for a normal branch, plus the predicate test.
+instruct cmpUL_LTGE(cmpOpU cmp, flagsReg_ulong_LTGE flags, label labl) %{
+  match(If cmp flags);
+  effect(USE labl);
+  predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
+  expand %{
+    jmpCon(cmp, flags, labl);    // JLT or JGE...
+  %}
+%}
+
 // Compare 2 longs and CMOVE longs.
 instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{
   match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
@@ -12767,6 +12842,41 @@
   %}
 %}
 
+//======
+// Manifest a CmpUL result in the normal flags.  Only good for EQ/NE compares.
+instruct cmpUL_zero_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src, immL0 zero, rRegI tmp) %{
+  match(Set flags (CmpUL src zero));
+  effect(TEMP tmp);
+  ins_cost(200);
+  format %{ "MOV    $tmp,$src.lo\n\t"
+            "OR     $tmp,$src.hi\t! Unsigned long is EQ/NE 0?" %}
+  ins_encode(long_cmp_flags0(src, tmp));
+  ins_pipe(ialu_reg_reg_long);
+%}
+
+// Manifest a CmpUL result in the normal flags.  Only good for EQ/NE compares.
+instruct cmpUL_reg_flags_EQNE(flagsReg_ulong_EQNE flags, eRegL src1, eRegL src2) %{
+  match(Set flags (CmpUL src1 src2));
+  ins_cost(200+300);
+  format %{ "CMP    $src1.lo,$src2.lo\t! Unsigned long compare; set flags for low bits\n\t"
+            "JNE,s  skip\n\t"
+            "CMP    $src1.hi,$src2.hi\n\t"
+     "skip:\t" %}
+  ins_encode(long_cmp_flags1(src1, src2));
+  ins_pipe(ialu_cr_reg_reg);
+%}
+
+// Unsigned long compare reg == zero/reg OR reg != zero/reg
+// Just a wrapper for a normal branch, plus the predicate test.
+instruct cmpUL_EQNE(cmpOpU cmp, flagsReg_ulong_EQNE flags, label labl) %{
+  match(If cmp flags);
+  effect(USE labl);
+  predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
+  expand %{
+    jmpCon(cmp, flags, labl);    // JEQ or JNE...
+  %}
+%}
+
 // Compare 2 longs and CMOVE longs.
 instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{
   match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
@@ -12900,6 +13010,46 @@
   %}
 %}
 
+//======
+// Manifest a CmpUL result in the normal flags.  Only good for LE or GT compares.
+// Same as cmpUL_reg_flags_LEGT except must negate src
+instruct cmpUL_zero_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src, immL0 zero, rRegI tmp) %{
+  match(Set flags (CmpUL src zero));
+  effect(TEMP tmp);
+  ins_cost(300);
+  format %{ "XOR    $tmp,$tmp\t# Unsigned long compare for -$src < 0, use commuted test\n\t"
+            "CMP    $tmp,$src.lo\n\t"
+            "SBB    $tmp,$src.hi\n\t" %}
+  ins_encode(long_cmp_flags3(src, tmp));
+  ins_pipe(ialu_reg_reg_long);
+%}
+
+// Manifest a CmpUL result in the normal flags.  Only good for LE or GT compares.
+// Same as cmpUL_reg_flags_LTGE except operands swapped.  Swapping operands
+// requires a commuted test to get the same result.
+instruct cmpUL_reg_flags_LEGT(flagsReg_ulong_LEGT flags, eRegL src1, eRegL src2, rRegI tmp) %{
+  match(Set flags (CmpUL src1 src2));
+  effect(TEMP tmp);
+  ins_cost(300);
+  format %{ "CMP    $src2.lo,$src1.lo\t! Unsigned long compare, swapped operands, use with commuted test\n\t"
+            "MOV    $tmp,$src2.hi\n\t"
+            "SBB    $tmp,$src1.hi\t! Compute flags for unsigned long compare" %}
+  ins_encode(long_cmp_flags2( src2, src1, tmp));
+  ins_pipe(ialu_cr_reg_reg);
+%}
+
+// Unsigned long compares reg < zero/req OR reg >= zero/req.
+// Just a wrapper for a normal branch, plus the predicate test
+instruct cmpUL_LEGT(cmpOpU_commute cmp, flagsReg_ulong_LEGT flags, label labl) %{
+  match(If cmp flags);
+  effect(USE labl);
+  predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le);
+  ins_cost(300);
+  expand %{
+    jmpCon(cmp, flags, labl);    // JGT or JLE...
+  %}
+%}
+
 // Compare 2 longs and CMOVE longs.
 instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{
   match(Set dst (CMoveL (Binary cmp flags) (Binary dst src)));
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Mon Aug 07 09:45:38 2017 -0700
@@ -11518,6 +11518,48 @@
   ins_pipe(pipe_slow);
 %}
 
+// Unsigned long compare Instructions; really, same as signed long except they
+// produce an rFlagsRegU instead of rFlagsReg.
+instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2)
+%{
+  match(Set cr (CmpUL op1 op2));
+
+  format %{ "cmpq    $op1, $op2\t# unsigned" %}
+  opcode(0x3B);  /* Opcode 3B /r */
+  ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
+  ins_pipe(ialu_cr_reg_reg);
+%}
+
+instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2)
+%{
+  match(Set cr (CmpUL op1 op2));
+
+  format %{ "cmpq    $op1, $op2\t# unsigned" %}
+  opcode(0x81, 0x07); /* Opcode 81 /7 */
+  ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2));
+  ins_pipe(ialu_cr_reg_imm);
+%}
+
+instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2)
+%{
+  match(Set cr (CmpUL op1 (LoadL op2)));
+
+  format %{ "cmpq    $op1, $op2\t# unsigned" %}
+  opcode(0x3B); /* Opcode 3B /r */
+  ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
+  ins_pipe(ialu_cr_reg_mem);
+%}
+
+instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero)
+%{
+  match(Set cr (CmpUL src zero));
+
+  format %{ "testq   $src, $src\t# unsigned" %}
+  opcode(0x85);
+  ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
+  ins_pipe(ialu_cr_reg_imm);
+%}
+
 //----------Max and Min--------------------------------------------------------
 // Min Instructions
 
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 package org.graalvm.compiler.hotspot;
 
 import java.util.Formatter;
+import java.util.Objects;
 
 /**
  * Mechanism for checking that the current Java runtime environment supports the minimum JVMCI API
@@ -37,10 +38,11 @@
 class JVMCIVersionCheck {
 
     private static final int JVMCI8_MIN_MAJOR_VERSION = 0;
-    private static final int JVMCI8_MIN_MINOR_VERSION = 23;
+    private static final int JVMCI8_MIN_MINOR_VERSION = 26;
 
-    // Will be updated once an ea build with the required JVMCI API is available.
-    private static final int JVMCI9_MIN_EA_BUILD = 143;
+    // MAX_VALUE indicates that no current EA version is compatible with Graal.
+    // Note: Keep README.md in sync with the EA version support checked here.
+    private static final int JVMCI9_MIN_EA_BUILD = 176;
 
     private static void failVersionCheck(boolean exit, String reason, Object... args) {
         Formatter errorMessage = new Formatter().format(reason, args);
@@ -77,13 +79,27 @@
                 start += "-jvmci-".length();
                 int end = vmVersion.indexOf('.', start);
                 if (end > 0) {
-                    int major = Integer.parseInt(vmVersion.substring(start, end));
+                    int major;
+                    try {
+                        major = Integer.parseInt(vmVersion.substring(start, end));
+                    } catch (NumberFormatException e) {
+                        failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
+                                        "Cannot read JVMCI major version from java.vm.version property: %s.%n", vmVersion);
+                        return;
+                    }
                     start = end + 1;
                     end = start;
                     while (end < vmVersion.length() && Character.isDigit(vmVersion.charAt(end))) {
                         end++;
                     }
-                    int minor = Integer.parseInt(vmVersion.substring(start, end));
+                    int minor;
+                    try {
+                        minor = Integer.parseInt(vmVersion.substring(start, end));
+                    } catch (NumberFormatException e) {
+                        failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
+                                        "Cannot read JVMCI minor version from java.vm.version property: %s.%n", vmVersion);
+                        return;
+                    }
                     if (major >= JVMCI8_MIN_MAJOR_VERSION && minor >= JVMCI8_MIN_MINOR_VERSION) {
                         return;
                     }
@@ -96,7 +112,7 @@
                             "Cannot read JVMCI version from java.vm.version property: %s.%n", vmVersion);
         } else {
             if (vmVersion.contains("SNAPSHOT")) {
-                // The snapshot of http://hg.openjdk.java.net/jdk9/hs tip is expected to work
+                // The snapshot of http://hg.openjdk.java.net/jdk9/dev tip is expected to work
                 return;
             }
             if (vmVersion.contains("internal")) {
@@ -104,23 +120,36 @@
                 return;
             }
             // http://openjdk.java.net/jeps/223
-            // Only support EA builds until GA is available
-            if (vmVersion.startsWith("9-ea+")) {
-                int start = "9-ea+".length();
+            if (vmVersion.startsWith("9+")) {
+                int start = "9+".length();
                 int end = start;
                 end = start;
                 while (end < vmVersion.length() && Character.isDigit(vmVersion.charAt(end))) {
                     end++;
                 }
-                int build = Integer.parseInt(vmVersion.substring(start, end));
+                int build;
+                try {
+                    build = Integer.parseInt(vmVersion.substring(start, end));
+                } catch (NumberFormatException e) {
+                    failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
+                                    "Cannot read JDK9 EA build number from java.vm.version property: %s.%n", vmVersion);
+                    return;
+                }
                 if (build >= JVMCI9_MIN_EA_BUILD) {
                     return;
                 }
-                failVersionCheck(exitOnFailure, "The VM is an insufficiently recent EA JDK9 build for Graal: %d < %d.%n", build, JVMCI9_MIN_EA_BUILD);
+                // Using Object.equals suppresses Eclipse's "Dead code" warning.
+                // Unfortunately @SuppressWarnings("unused") can only be applied at method level.
+                if (Objects.equals(JVMCI9_MIN_EA_BUILD, Integer.MAX_VALUE)) {
+                    failVersionCheck(exitOnFailure, "This version of Graal is not compatible with any JDK 9 Early Access build.%n");
+                } else {
+                    failVersionCheck(exitOnFailure, "The VM is an insufficiently recent EA JDK9 build for Graal: %d < %d.%n", build, JVMCI9_MIN_EA_BUILD);
+                }
                 return;
+            } else {
+                // Graal will be compatible with all JDK versions as of 9 GA
+                // until a JVMCI API change is made in a 9u or later release.
             }
-            failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
-                            "Cannot read JDK9 EA build number from java.vm.version property: %s.%n", vmVersion);
         }
     }
 
--- a/hotspot/src/share/vm/adlc/archDesc.cpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/share/vm/adlc/archDesc.cpp	Mon Aug 07 09:45:38 2017 -0700
@@ -1166,6 +1166,7 @@
          || strcmp(idealName,"CmpP") == 0
          || strcmp(idealName,"CmpN") == 0
          || strcmp(idealName,"CmpL") == 0
+         || strcmp(idealName,"CmpUL") == 0
          || strcmp(idealName,"CmpD") == 0
          || strcmp(idealName,"CmpF") == 0
          || strcmp(idealName,"FastLock") == 0
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -181,7 +181,7 @@
            "Map number of unrolls for main loop via "                       \
            "Superword Level Parallelism analysis")                          \
                                                                             \
-  diagnostic_pd(bool, PostLoopMultiversioning,                              \
+  experimental(bool, PostLoopMultiversioning, false,                        \
            "Multi versioned post loops to eliminate range checks")          \
                                                                             \
   notproduct(bool, TraceSuperWordLoopUnrollAnalysis, false,                 \
--- a/hotspot/src/share/vm/opto/classes.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/share/vm/opto/classes.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -81,6 +81,7 @@
 macro(CmpLTMask)
 macro(CmpP)
 macro(CmpU)
+macro(CmpUL)
 macro(CompareAndSwapB)
 macro(CompareAndSwapS)
 macro(CompareAndSwapI)
--- a/hotspot/src/share/vm/opto/loopPredicate.cpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/share/vm/opto/loopPredicate.cpp	Mon Aug 07 09:45:38 2017 -0700
@@ -29,6 +29,7 @@
 #include "opto/connode.hpp"
 #include "opto/convertnode.hpp"
 #include "opto/loopnode.hpp"
+#include "opto/matcher.hpp"
 #include "opto/mulnode.hpp"
 #include "opto/opaquenode.hpp"
 #include "opto/rootnode.hpp"
@@ -629,45 +630,138 @@
 //   max(scale*i + offset) = scale*init + offset
 BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
                                        int scale, Node* offset,
-                                       Node* init, Node* limit, Node* stride,
-                                       Node* range, bool upper) {
+                                       Node* init, Node* limit, jint stride,
+                                       Node* range, bool upper, bool &overflow) {
+  jint con_limit  = limit->is_Con()  ? limit->get_int()  : 0;
+  jint con_init   = init->is_Con()   ? init->get_int()   : 0;
+  jint con_offset = offset->is_Con() ? offset->get_int() : 0;
+
   stringStream* predString = NULL;
   if (TraceLoopPredicate) {
     predString = new stringStream();
     predString->print("rc_predicate ");
   }
 
-  Node* max_idx_expr  = init;
-  int stride_con = stride->get_int();
-  if ((stride_con > 0) == (scale > 0) == upper) {
-    // Limit is not exact.
-    // Calculate exact limit here.
-    // Note, counted loop's test is '<' or '>'.
-    limit = exact_limit(loop);
-    max_idx_expr = new SubINode(limit, stride);
+  overflow = false;
+  Node* max_idx_expr = NULL;
+  const TypeInt* idx_type = TypeInt::INT;
+  if ((stride > 0) == (scale > 0) == upper) {
+    if (TraceLoopPredicate) {
+      predString->print(limit->is_Con() ? "(%d " : "(limit ", con_limit);
+      predString->print("- %d) ", stride);
+    }
+    // Check if (limit - stride) may overflow
+    const TypeInt* limit_type = _igvn.type(limit)->isa_int();
+    jint limit_lo = limit_type->_lo;
+    jint limit_hi = limit_type->_hi;
+    if ((stride > 0 && (java_subtract(limit_lo, stride) < limit_lo)) ||
+        (stride < 0 && (java_subtract(limit_hi, stride) > limit_hi))) {
+      // No overflow possible
+      ConINode* con_stride = _igvn.intcon(stride);
+      set_ctrl(con_stride, C->root());
+      max_idx_expr = new SubINode(limit, con_stride);
+      idx_type = TypeInt::make(limit_lo - stride, limit_hi - stride, limit_type->_widen);
+    } else {
+      // May overflow
+      overflow = true;
+      limit = new ConvI2LNode(limit);
+      register_new_node(limit, ctrl);
+      ConLNode* con_stride = _igvn.longcon(stride);
+      set_ctrl(con_stride, C->root());
+      max_idx_expr = new SubLNode(limit, con_stride);
+    }
     register_new_node(max_idx_expr, ctrl);
-    if (TraceLoopPredicate) predString->print("(limit - stride) ");
   } else {
-    if (TraceLoopPredicate) predString->print("init ");
+    if (TraceLoopPredicate) {
+      predString->print(init->is_Con() ? "%d " : "init ", con_init);
+    }
+    idx_type = _igvn.type(init)->isa_int();
+    max_idx_expr = init;
   }
 
   if (scale != 1) {
     ConNode* con_scale = _igvn.intcon(scale);
     set_ctrl(con_scale, C->root());
-    max_idx_expr = new MulINode(max_idx_expr, con_scale);
+    if (TraceLoopPredicate) {
+      predString->print("* %d ", scale);
+    }
+    // Check if (scale * max_idx_expr) may overflow
+    const TypeInt* scale_type = TypeInt::make(scale);
+    MulINode* mul = new MulINode(max_idx_expr, con_scale);
+    idx_type = (TypeInt*)mul->mul_ring(idx_type, scale_type);
+    if (overflow || TypeInt::INT->higher_equal(idx_type)) {
+      // May overflow
+      mul->destruct();
+      if (!overflow) {
+        max_idx_expr = new ConvI2LNode(max_idx_expr);
+        register_new_node(max_idx_expr, ctrl);
+      }
+      overflow = true;
+      con_scale = _igvn.longcon(scale);
+      set_ctrl(con_scale, C->root());
+      max_idx_expr = new MulLNode(max_idx_expr, con_scale);
+    } else {
+      // No overflow possible
+      max_idx_expr = mul;
+    }
     register_new_node(max_idx_expr, ctrl);
-    if (TraceLoopPredicate) predString->print("* %d ", scale);
   }
 
-  if (offset && (!offset->is_Con() || offset->get_int() != 0)){
-    max_idx_expr = new AddINode(max_idx_expr, offset);
+  if (offset && (!offset->is_Con() || con_offset != 0)){
+    if (TraceLoopPredicate) {
+      predString->print(offset->is_Con() ? "+ %d " : "+ offset", con_offset);
+    }
+    // Check if (max_idx_expr + offset) may overflow
+    const TypeInt* offset_type = _igvn.type(offset)->isa_int();
+    jint lo = java_add(idx_type->_lo, offset_type->_lo);
+    jint hi = java_add(idx_type->_hi, offset_type->_hi);
+    if (overflow || (lo > hi) ||
+        ((idx_type->_lo & offset_type->_lo) < 0 && lo >= 0) ||
+        ((~(idx_type->_hi | offset_type->_hi)) < 0 && hi < 0)) {
+      // May overflow
+      if (!overflow) {
+        max_idx_expr = new ConvI2LNode(max_idx_expr);
+        register_new_node(max_idx_expr, ctrl);
+      }
+      overflow = true;
+      offset = new ConvI2LNode(offset);
+      register_new_node(offset, ctrl);
+      max_idx_expr = new AddLNode(max_idx_expr, offset);
+    } else {
+      // No overflow possible
+      max_idx_expr = new AddINode(max_idx_expr, offset);
+    }
     register_new_node(max_idx_expr, ctrl);
-    if (TraceLoopPredicate)
-      if (offset->is_Con()) predString->print("+ %d ", offset->get_int());
-      else predString->print("+ offset ");
   }
 
-  CmpUNode* cmp = new CmpUNode(max_idx_expr, range);
+  CmpNode* cmp = NULL;
+  if (overflow) {
+    // Integer expressions may overflow, do long comparison
+    range = new ConvI2LNode(range);
+    register_new_node(range, ctrl);
+    if (!Matcher::has_match_rule(Op_CmpUL)) {
+      // We don't support unsigned long comparisons. Set 'max_idx_expr'
+      // to max_julong if < 0 to make the signed comparison fail.
+      ConINode* sign_pos = _igvn.intcon(BitsPerLong - 1);
+      set_ctrl(sign_pos, C->root());
+      Node* sign_bit_mask = new RShiftLNode(max_idx_expr, sign_pos);
+      register_new_node(sign_bit_mask, ctrl);
+      // OR with sign bit to set all bits to 1 if negative (otherwise no change)
+      max_idx_expr = new OrLNode(max_idx_expr, sign_bit_mask);
+      register_new_node(max_idx_expr, ctrl);
+      // AND with 0x7ff... to unset the sign bit
+      ConLNode* remove_sign_mask = _igvn.longcon(max_jlong);
+      set_ctrl(remove_sign_mask, C->root());
+      max_idx_expr = new AndLNode(max_idx_expr, remove_sign_mask);
+      register_new_node(max_idx_expr, ctrl);
+
+      cmp = new CmpLNode(max_idx_expr, range);
+    } else {
+      cmp = new CmpULNode(max_idx_expr, range);
+    }
+  } else {
+    cmp = new CmpUNode(max_idx_expr, range);
+  }
   register_new_node(cmp, ctrl);
   BoolNode* bol = new BoolNode(cmp, BoolTest::lt);
   register_new_node(bol, ctrl);
@@ -814,28 +908,30 @@
       assert(ok, "must be index expression");
 
       Node* init    = cl->init_trip();
-      Node* limit   = cl->limit();
-      Node* stride  = cl->stride();
+      // Limit is not exact.
+      // Calculate exact limit here.
+      // Note, counted loop's test is '<' or '>'.
+      Node* limit   = exact_limit(loop);
+      int  stride   = cl->stride()->get_int();
 
       // Build if's for the upper and lower bound tests.  The
       // lower_bound test will dominate the upper bound test and all
       // cloned or created nodes will use the lower bound test as
       // their declared control.
-      ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, iff->Opcode());
-      ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, iff->Opcode());
-      assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
-      Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
 
       // Perform cloning to keep Invariance state correct since the
       // late schedule will place invariant things in the loop.
+      Node *ctrl = predicate_proj->in(0)->as_If()->in(0);
       rng = invar.clone(rng, ctrl);
       if (offset && offset != zero) {
         assert(invar.is_invariant(offset), "offset must be loop invariant");
         offset = invar.clone(offset, ctrl);
       }
+      // If predicate expressions may overflow in the integer range, longs are used.
+      bool overflow = false;
 
       // Test the lower bound
-      BoolNode*  lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false);
+      BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow);
       // Negate test if necessary
       bool negated = false;
       if (proj->_con != predicate_proj->_con) {
@@ -843,19 +939,22 @@
         register_new_node(lower_bound_bol, ctrl);
         negated = true;
       }
+      ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, overflow ? Op_If : iff->Opcode());
       IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
       _igvn.hash_delete(lower_bound_iff);
       lower_bound_iff->set_req(1, lower_bound_bol);
       if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx);
 
       // Test the upper bound
-      BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true);
+      BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow);
       negated = false;
       if (proj->_con != predicate_proj->_con) {
         upper_bound_bol = new BoolNode(upper_bound_bol->in(1), upper_bound_bol->_test.negate());
         register_new_node(upper_bound_bol, ctrl);
         negated = true;
       }
+      ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, overflow ? Op_If : iff->Opcode());
+      assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
       IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
       _igvn.hash_delete(upper_bound_iff);
       upper_bound_iff->set_req(1, upper_bound_bol);
--- a/hotspot/src/share/vm/opto/loopnode.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/share/vm/opto/loopnode.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -983,8 +983,8 @@
   // Construct a range check for a predicate if
   BoolNode* rc_predicate(IdealLoopTree *loop, Node* ctrl,
                          int scale, Node* offset,
-                         Node* init, Node* limit, Node* stride,
-                         Node* range, bool upper);
+                         Node* init, Node* limit, jint stride,
+                         Node* range, bool upper, bool &overflow);
 
   // Implementation of the loop predication to promote checks outside the loop
   bool loop_predication_impl(IdealLoopTree *loop);
--- a/hotspot/src/share/vm/opto/output.cpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/share/vm/opto/output.cpp	Mon Aug 07 09:45:38 2017 -0700
@@ -1982,6 +1982,7 @@
     if( last->is_MachIf() && last->in(1) == n &&
         ( op == Op_CmpI ||
           op == Op_CmpU ||
+          op == Op_CmpUL ||
           op == Op_CmpP ||
           op == Op_CmpF ||
           op == Op_CmpD ||
--- a/hotspot/src/share/vm/opto/subnode.cpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/share/vm/opto/subnode.cpp	Mon Aug 07 09:45:38 2017 -0700
@@ -738,6 +738,60 @@
   return TypeInt::CC;           // else use worst case results
 }
 
+
+// Simplify a CmpUL (compare 2 unsigned longs) node, based on local information.
+// If both inputs are constants, compare them.
+const Type* CmpULNode::sub(const Type* t1, const Type* t2) const {
+  assert(!t1->isa_ptr(), "obsolete usage of CmpUL");
+
+  // comparing two unsigned longs
+  const TypeLong* r0 = t1->is_long();   // Handy access
+  const TypeLong* r1 = t2->is_long();
+
+  // Current installed version
+  // Compare ranges for non-overlap
+  julong lo0 = r0->_lo;
+  julong hi0 = r0->_hi;
+  julong lo1 = r1->_lo;
+  julong hi1 = r1->_hi;
+
+  // If either one has both negative and positive values,
+  // it therefore contains both 0 and -1, and since [0..-1] is the
+  // full unsigned range, the type must act as an unsigned bottom.
+  bool bot0 = ((jlong)(lo0 ^ hi0) < 0);
+  bool bot1 = ((jlong)(lo1 ^ hi1) < 0);
+
+  if (bot0 || bot1) {
+    // All unsigned values are LE -1 and GE 0.
+    if (lo0 == 0 && hi0 == 0) {
+      return TypeInt::CC_LE;            //   0 <= bot
+    } else if ((jlong)lo0 == -1 && (jlong)hi0 == -1) {
+      return TypeInt::CC_GE;            // -1 >= bot
+    } else if (lo1 == 0 && hi1 == 0) {
+      return TypeInt::CC_GE;            // bot >= 0
+    } else if ((jlong)lo1 == -1 && (jlong)hi1 == -1) {
+      return TypeInt::CC_LE;            // bot <= -1
+    }
+  } else {
+    // We can use ranges of the form [lo..hi] if signs are the same.
+    assert(lo0 <= hi0 && lo1 <= hi1, "unsigned ranges are valid");
+    // results are reversed, '-' > '+' for unsigned compare
+    if (hi0 < lo1) {
+      return TypeInt::CC_LT;            // smaller
+    } else if (lo0 > hi1) {
+      return TypeInt::CC_GT;            // greater
+    } else if (hi0 == lo1 && lo0 == hi1) {
+      return TypeInt::CC_EQ;            // Equal results
+    } else if (lo0 >= hi1) {
+      return TypeInt::CC_GE;
+    } else if (hi0 <= lo1) {
+      return TypeInt::CC_LE;
+    }
+  }
+
+  return TypeInt::CC;                   // else use worst case results
+}
+
 //=============================================================================
 //------------------------------sub--------------------------------------------
 // Simplify an CmpP (compare 2 pointers) node, based on local information.
--- a/hotspot/src/share/vm/opto/subnode.hpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/share/vm/opto/subnode.hpp	Mon Aug 07 09:45:38 2017 -0700
@@ -198,6 +198,15 @@
   virtual const Type *sub( const Type *, const Type * ) const;
 };
 
+//------------------------------CmpULNode---------------------------------------
+// Compare 2 unsigned long values, returning condition codes (-1, 0 or 1).
+class CmpULNode : public CmpNode {
+public:
+  CmpULNode(Node* in1, Node* in2) : CmpNode(in1, in2) { }
+  virtual int Opcode() const;
+  virtual const Type* sub(const Type*, const Type*) const;
+};
+
 //------------------------------CmpL3Node--------------------------------------
 // Compare 2 long values, returning integer value (-1, 0 or 1).
 class CmpL3Node : public CmpLNode {
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Mon Aug 07 09:45:38 2017 -0700
@@ -2013,6 +2013,7 @@
   declare_c2_type(CmpPNode, CmpNode)                                      \
   declare_c2_type(CmpNNode, CmpNode)                                      \
   declare_c2_type(CmpLNode, CmpNode)                                      \
+  declare_c2_type(CmpULNode, CmpNode)                                     \
   declare_c2_type(CmpL3Node, CmpLNode)                                    \
   declare_c2_type(CmpFNode, CmpNode)                                      \
   declare_c2_type(CmpF3Node, CmpFNode)                                    \
--- a/hotspot/test/compiler/rangechecks/TestRangeCheckEliminationDisabled.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/hotspot/test/compiler/rangechecks/TestRangeCheckEliminationDisabled.java	Mon Aug 07 09:45:38 2017 -0700
@@ -26,7 +26,7 @@
  * @bug 8154763
  * @summary Tests PostLoopMultiversioning with RangeCheckElimination disabled.
  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
- *                   -XX:+PostLoopMultiversioning -XX:-RangeCheckElimination
+ *                   -XX:+UnlockExperimentalVMOptions -XX:+PostLoopMultiversioning -XX:-RangeCheckElimination
  *                   compiler.rangechecks.TestRangeCheckEliminationDisabled
  */
 
--- a/jaxp/.hgtags	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxp/.hgtags	Mon Aug 07 09:45:38 2017 -0700
@@ -437,3 +437,6 @@
 332ad9f92632f56f337b8c40edef9a95a42b26bc jdk-9+177
 02a876781a3a6193140591d92db7b95ca743eac2 jdk-10+15
 d109d55cf642bf2b438624e81f94c18c168f9178 jdk-10+16
+0983b2dbe17ba4fed3af34e0512ca77a9845fe8a jdk-9+178
+87243a3131f79e8b3903eaca6b629abc48f08ace jdk-9+179
+97d6f14334cfd766f57c296a5a707c8a709aeff0 jdk-10+17
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMConfigurationException.java	Mon Aug 07 10:02:39 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.sun.org.apache.xml.internal.dtm;
-
-import javax.xml.transform.SourceLocator;
-
-/**
- * Indicates a serious configuration error.
- */
-public class DTMConfigurationException extends DTMException {
-    static final long serialVersionUID = -4607874078818418046L;
-
-    /**
-     * Create a new <code>DTMConfigurationException</code> with no
-     * detail message.
-     */
-    public DTMConfigurationException() {
-        super("Configuration Error");
-    }
-
-    /**
-     * Create a new <code>DTMConfigurationException</code> with
-     * the <code>String </code> specified as an error message.
-     *
-     * @param msg The error message for the exception.
-     */
-    public DTMConfigurationException(String msg) {
-        super(msg);
-    }
-
-    /**
-     * Create a new <code>DTMConfigurationException</code> with a
-     * given <code>Exception</code> base cause of the error.
-     *
-     * @param e The exception to be encapsulated in a
-     * DTMConfigurationException.
-     */
-    public DTMConfigurationException(Throwable e) {
-        super(e);
-    }
-
-    /**
-     * Create a new <code>DTMConfigurationException</code> with the
-     * given <code>Exception</code> base cause and detail message.
-     *
-     * @param msg The detail message.
-     * @param e The exception to be wrapped in a DTMConfigurationException
-     */
-    public DTMConfigurationException(String msg, Throwable e) {
-        super(msg, e);
-    }
-
-    /**
-     * Create a new DTMConfigurationException from a message and a Locator.
-     *
-     * <p>This constructor is especially useful when an application is
-     * creating its own exception from within a DocumentHandler
-     * callback.</p>
-     *
-     * @param message The error or warning message.
-     * @param locator The locator object for the error or warning.
-     */
-    public DTMConfigurationException(String message,
-                                             SourceLocator locator) {
-        super(message, locator);
-    }
-
-    /**
-     * Wrap an existing exception in a DTMConfigurationException.
-     *
-     * @param message The error or warning message, or null to
-     *                use the message from the embedded exception.
-     * @param locator The locator object for the error or warning.
-     * @param e Any exception.
-     */
-    public DTMConfigurationException(String message,
-                                             SourceLocator locator,
-                                             Throwable e) {
-        super(message, locator, e);
-    }
-}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMException.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMException.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -21,124 +20,20 @@
 
 package com.sun.org.apache.xml.internal.dtm;
 
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import javax.xml.transform.SourceLocator;
-
-import com.sun.org.apache.xml.internal.res.XMLErrorResources;
-import com.sun.org.apache.xml.internal.res.XMLMessages;
-
-
 /**
- * This class specifies an exceptional condition that occured
+ * This class specifies an exceptional condition that occurred
  * in the DTM module.
  */
 public class DTMException extends RuntimeException {
     static final long serialVersionUID = -775576419181334734L;
 
-    /** Field locator specifies where the error occured.
-     *  @serial */
-    SourceLocator locator;
-
-    /**
-     * Method getLocator retrieves an instance of a SourceLocator
-     * object that specifies where an error occured.
-     *
-     * @return A SourceLocator object, or null if none was specified.
-     */
-    public SourceLocator getLocator() {
-        return locator;
-    }
-
-    /**
-     * Method setLocator sets an instance of a SourceLocator
-     * object that specifies where an error occured.
-     *
-     * @param location A SourceLocator object, or null to clear the location.
-     */
-    public void setLocator(SourceLocator location) {
-        locator = location;
-    }
-
-    /** Field containedException specifies a wrapped exception.  May be null.
-     *  @serial */
-    Throwable containedException;
-
-    /**
-     * This method retrieves an exception that this exception wraps.
-     *
-     * @return An Throwable object, or null.
-     * @see #getCause
-     */
-    public Throwable getException() {
-        return containedException;
-    }
-
-    /**
-     * Returns the cause of this throwable or <code>null</code> if the
-     * cause is nonexistent or unknown.  (The cause is the throwable that
-     * caused this throwable to get thrown.)
-     */
-    public Throwable getCause() {
-
-        return ((containedException == this)
-                ? null
-                : containedException);
-    }
-
-    /**
-     * Initializes the <i>cause</i> of this throwable to the specified value.
-     * (The cause is the throwable that caused this throwable to get thrown.)
-     *
-     * <p>This method can be called at most once.  It is generally called from
-     * within the constructor, or immediately after creating the
-     * throwable.  If this throwable was created
-     * with {@link #DTMException(Throwable)} or
-     * {@link #DTMException(String,Throwable)}, this method cannot be called
-     * even once.
-     *
-     * @param  cause the cause (which is saved for later retrieval by the
-     *         {@link #getCause()} method).  (A <tt>null</tt> value is
-     *         permitted, and indicates that the cause is nonexistent or
-     *         unknown.)
-     * @return  a reference to this <code>Throwable</code> instance.
-     * @throws IllegalArgumentException if <code>cause</code> is this
-     *         throwable.  (A throwable cannot
-     *         be its own cause.)
-     * @throws IllegalStateException if this throwable was
-     *         created with {@link #DTMException(Throwable)} or
-     *         {@link #DTMException(String,Throwable)}, or this method has already
-     *         been called on this throwable.
-     */
-    public synchronized Throwable initCause(Throwable cause) {
-
-        if ((this.containedException == null) && (cause != null)) {
-            throw new IllegalStateException(XMLMessages.createXMLMessage(XMLErrorResources.ER_CANNOT_OVERWRITE_CAUSE, null)); //"Can't overwrite cause");
-        }
-
-        if (cause == this) {
-            throw new IllegalArgumentException(
-                XMLMessages.createXMLMessage(XMLErrorResources.ER_SELF_CAUSATION_NOT_PERMITTED, null)); //"Self-causation not permitted");
-        }
-
-        this.containedException = cause;
-
-        return this;
-    }
-
     /**
      * Create a new DTMException.
      *
      * @param message The error or warning message.
      */
     public DTMException(String message) {
-
         super(message);
-
-        this.containedException = null;
-        this.locator            = null;
     }
 
     /**
@@ -147,11 +42,7 @@
      * @param e The exception to be wrapped.
      */
     public DTMException(Throwable e) {
-
-        super(e.getMessage());
-
-        this.containedException = e;
-        this.locator            = null;
+        super(e);
     }
 
     /**
@@ -165,162 +56,6 @@
      * @param e Any exception
      */
     public DTMException(String message, Throwable e) {
-
-        super(((message == null) || (message.length() == 0))
-              ? e.getMessage()
-              : message);
-
-        this.containedException = e;
-        this.locator            = null;
-    }
-
-    /**
-     * Create a new DTMException from a message and a Locator.
-     *
-     * <p>This constructor is especially useful when an application is
-     * creating its own exception from within a DocumentHandler
-     * callback.</p>
-     *
-     * @param message The error or warning message.
-     * @param locator The locator object for the error or warning.
-     */
-    public DTMException(String message, SourceLocator locator) {
-
-        super(message);
-
-        this.containedException = null;
-        this.locator            = locator;
-    }
-
-    /**
-     * Wrap an existing exception in a DTMException.
-     *
-     * @param message The error or warning message, or null to
-     *                use the message from the embedded exception.
-     * @param locator The locator object for the error or warning.
-     * @param e Any exception
-     */
-    public DTMException(String message, SourceLocator locator,
-                                Throwable e) {
-
-        super(message);
-
-        this.containedException = e;
-        this.locator            = locator;
-    }
-
-    /**
-     * Get the error message with location information
-     * appended.
-     */
-    public String getMessageAndLocation() {
-
-        StringBuffer sbuffer = new StringBuffer();
-        String       message = super.getMessage();
-
-        if (null != message) {
-            sbuffer.append(message);
-        }
-
-        if (null != locator) {
-            String systemID = locator.getSystemId();
-            int    line     = locator.getLineNumber();
-            int    column   = locator.getColumnNumber();
-
-            if (null != systemID) {
-                sbuffer.append("; SystemID: ");
-                sbuffer.append(systemID);
-            }
-
-            if (0 != line) {
-                sbuffer.append("; Line#: ");
-                sbuffer.append(line);
-            }
-
-            if (0 != column) {
-                sbuffer.append("; Column#: ");
-                sbuffer.append(column);
-            }
-        }
-
-        return sbuffer.toString();
+        super(message, e);
     }
-
-    /**
-     * Get the location information as a string.
-     *
-     * @return A string with location info, or null
-     * if there is no location information.
-     */
-    public String getLocationAsString() {
-
-        if (null != locator) {
-            StringBuffer sbuffer  = new StringBuffer();
-            String       systemID = locator.getSystemId();
-            int          line     = locator.getLineNumber();
-            int          column   = locator.getColumnNumber();
-
-            if (null != systemID) {
-                sbuffer.append("; SystemID: ");
-                sbuffer.append(systemID);
-            }
-
-            if (0 != line) {
-                sbuffer.append("; Line#: ");
-                sbuffer.append(line);
-            }
-
-            if (0 != column) {
-                sbuffer.append("; Column#: ");
-                sbuffer.append(column);
-            }
-
-            return sbuffer.toString();
-        } else {
-            return null;
-        }
     }
-
-    /**
-     * Print the the trace of methods from where the error
-     * originated.  This will trace all nested exception
-     * objects, as well as this object.
-     */
-    public void printStackTrace() {
-        printStackTrace(new java.io.PrintWriter(System.err, true));
-    }
-
-    /**
-     * Print the the trace of methods from where the error
-     * originated.  This will trace all nested exception
-     * objects, as well as this object.
-     * @param s The stream where the dump will be sent to.
-     */
-    public void printStackTrace(java.io.PrintStream s) {
-        printStackTrace(new java.io.PrintWriter(s));
-    }
-
-    /**
-     * Print the the trace of methods from where the error
-     * originated.  This will trace all nested exception
-     * objects, as well as this object.
-     * @param s The writer where the dump will be sent to.
-     */
-    public void printStackTrace(java.io.PrintWriter s) {
-
-        if (s == null) {
-            s = new java.io.PrintWriter(System.err, true);
-        }
-
-        try {
-            String locInfo = getLocationAsString();
-
-            if (null != locInfo) {
-                s.println(locInfo);
-            }
-
-            super.printStackTrace(s);
-        } catch (Throwable e) {}
-
-    }
-}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMManager.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/DTMManager.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -21,12 +20,8 @@
 
 package com.sun.org.apache.xml.internal.dtm;
 
-import com.sun.org.apache.xml.internal.res.XMLErrorResources;
-import com.sun.org.apache.xml.internal.res.XMLMessages;
 import com.sun.org.apache.xml.internal.utils.PrefixResolver;
 import com.sun.org.apache.xml.internal.utils.XMLStringFactory;
-import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
-import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
 
 /**
  * A DTMManager instance can be used to create DTM and
@@ -99,11 +94,11 @@
    *
    * @return new DTMManager instance, never null.
    *
-   * @throws DTMConfigurationException
+   * @throws DTMException
    * if the implementation is not available or cannot be instantiated.
    */
   public static DTMManager newInstance(XMLStringFactory xsf)
-           throws DTMConfigurationException
+           throws DTMException
   {
       final DTMManager factoryImpl = new com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault();
       factoryImpl.setXMLStringFactory(xsf);
@@ -315,20 +310,6 @@
 
   // -------------------- private methods --------------------
 
-   /**
-   * Temp debug code - this will be removed after we test everything
-   */
-  private static boolean debug;
-
-  static
-  {
-    try
-    {
-      debug = SecuritySupport.getSystemProperty("dtm.debug") != null;
-    }
-    catch (SecurityException ex){}
-  }
-
   /** This value, set at compile time, controls how many bits of the
    * DTM node identifier numbers are used to identify a node within a
    * document, and thus sets the maximum number of nodes per
@@ -394,47 +375,4 @@
   {
     return IDENT_NODE_DEFAULT;
   }
-
-    //
-    // Classes
-    //
-
-    /**
-     * A configuration error.
-     * Originally in ObjectFactory. This is the only portion used in this package
-     */
-    static class ConfigurationError
-        extends Error {
-                static final long serialVersionUID = 5122054096615067992L;
-        //
-        // Data
-        //
-
-        /** Exception. */
-        private Exception exception;
-
-        //
-        // Constructors
-        //
-
-        /**
-         * Construct a new instance with the specified detail string and
-         * exception.
-         */
-        ConfigurationError(String msg, Exception x) {
-            super(msg);
-            this.exception = x;
-        } // <init>(String,Exception)
-
-        //
-        // Public methods
-        //
-
-        /** Returns the exception associated to this error. */
-        Exception getException() {
-            return exception;
-        } // getException():Exception
-
-    } // class ConfigurationError
-
 }
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java	Mon Aug 07 09:45:38 2017 -0700
@@ -34,7 +34,7 @@
  * The CatalogFeatures holds a collection of features and properties.
  *
  *
- * <table class="plain">
+ * <table class="plain" id="CatalogFeatures">
  * <caption>Catalog Features</caption>
  * <thead>
  * <tr>
@@ -55,7 +55,7 @@
  * <tbody>
  *
  * <tr>
- * <th scope="row" style="font-weight:normal">FILES</th>
+ * <th scope="row" style="font-weight:normal" id="FILES">FILES</th>
  * <td>A semicolon-delimited list of URIs to locate the catalog files.
  * The URIs must be absolute and have a URL protocol handler for the URI scheme.
  * </td>
@@ -71,7 +71,7 @@
  * </tr>
  *
  * <tr>
- * <th rowspan="2" scope="row" style="font-weight:normal">PREFER</th>
+ * <th rowspan="2" scope="row" style="font-weight:normal" id="PREFER">PREFER</th>
  * <td rowspan="2">Indicates the preference between the public and system
  * identifiers. The default value is public [3].</td>
  * <td rowspan="2">javax.xml.catalog.prefer</td>
@@ -91,7 +91,7 @@
  * </tr>
  *
  * <tr>
- * <th rowspan="2" scope="row" style="font-weight:normal">DEFER</th>
+ * <th rowspan="2" scope="row" style="font-weight:normal" id="DEFER">DEFER</th>
  * <td rowspan="2">Indicates that the alternative catalogs including those
  * specified in delegate entries or nextCatalog are not read until they are
  * needed. The default value is true.</td>
@@ -111,7 +111,7 @@
  * </tr>
  *
  * <tr>
- * <th rowspan="3" scope="row" style="font-weight:normal">RESOLVE</th>
+ * <th rowspan="3" scope="row" style="font-weight:normal" id="RESOLVE">RESOLVE</th>
  * <td rowspan="3">Determines the action if there is no matching entry found after
  * all of the specified catalogs are exhausted. The default is strict.</td>
  * <td rowspan="3">javax.xml.catalog.resolve [4]</td>
--- a/jaxp/src/java.xml/share/classes/javax/xml/datatype/DatatypeFactory.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxp/src/java.xml/share/classes/javax/xml/datatype/DatatypeFactory.java	Mon Aug 07 09:45:38 2017 -0700
@@ -34,7 +34,7 @@
 
 /**
  * Factory that creates new {@code javax.xml.datatype} {@code Object}s that map XML to/from Java {@code Object}s.
- * <p>
+ * <p id="DatatypeFactory.newInstance">
  * A new instance of the {@code DatatypeFactory} is created through the {@link #newInstance()} method
  * that uses the following implementation resolution mechanisms to determine an implementation:
  * <ol>
--- a/jaxp/src/java.xml/share/classes/javax/xml/datatype/package-info.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxp/src/java.xml/share/classes/javax/xml/datatype/package-info.java	Mon Aug 07 09:45:38 2017 -0700
@@ -149,23 +149,13 @@
  *     <li>xs:unsignedShort</li>
  * </ul>
  *
- * <hr>
- *
- * <ul>
- *     <li>Author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a></li>
- *     <li>See <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">
+ * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">
  *             W3C XML Schema 1.0 Part 2, Section 3.2.7-14</a>
- *     </li>
- *     <li>See <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
+ * @see <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
  *             XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>
- *     </li>
- *     <li>See <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">
+ * @see <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">
  *             XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>
- *     </li>
- *     <li>Since 1.5</li>
- * </ul>
- *
- * <hr>
  * @since 1.5
  */
 
--- a/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerConfigurationException.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerConfigurationException.java	Mon Aug 07 09:45:38 2017 -0700
@@ -32,6 +32,8 @@
  */
 public class TransformerConfigurationException extends TransformerException {
 
+    private static final long serialVersionUID = 1285547467942875745L;
+
     /**
      * Create a new <code>TransformerConfigurationException</code> with no
      * detail message.
--- a/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerException.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerException.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2006, 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,36 +27,47 @@
 
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.Objects;
 
 /**
- * This class specifies an exceptional condition that occured
+ * This class specifies an exceptional condition that occurred
  * during the transformation process.
  *
  * @since 1.4
  */
 public class TransformerException extends Exception {
 
-    /** Field locator specifies where the error occured */
+    private static final long serialVersionUID = 975798773772956428L;
+
+    /** Field locator specifies where the error occurred */
     SourceLocator locator;
 
     /**
      * Method getLocator retrieves an instance of a SourceLocator
-     * object that specifies where an error occured.
+     * object that specifies where an error occurred.
      *
      * @return A SourceLocator object, or null if none was specified.
      */
     public SourceLocator getLocator() {
-        return locator;
+        return this.locator;
     }
 
     /**
      * Method setLocator sets an instance of a SourceLocator
-     * object that specifies where an error occured.
+     * object that specifies where an error occurred.
      *
      * @param location A SourceLocator object, or null to clear the location.
      */
     public void setLocator(SourceLocator location) {
-        locator = location;
+        this.locator = location;
     }
 
     /** Field containedException specifies a wrapped exception.  May be null. */
@@ -76,7 +87,9 @@
      * Returns the cause of this throwable or <code>null</code> if the
      * cause is nonexistent or unknown.  (The cause is the throwable that
      * caused this throwable to get thrown.)
+     * @return the cause, or null if unknown
      */
+    @Override
     public Throwable getCause() {
 
         return ((containedException == this)
@@ -108,6 +121,7 @@
      *         {@link #TransformerException(String,Throwable)}, or this method has already
      *         been called on this throwable.
      */
+    @Override
     public synchronized Throwable initCause(Throwable cause) {
 
         // TransformerException doesn't set its cause (probably
@@ -136,11 +150,7 @@
      * @param message The error or warning message.
      */
     public TransformerException(String message) {
-
-        super(message);
-
-        this.containedException = null;
-        this.locator            = null;
+        this(message, null, null);
     }
 
     /**
@@ -149,11 +159,7 @@
      * @param e The exception to be wrapped.
      */
     public TransformerException(Throwable e) {
-
-        super(e.toString());
-
-        this.containedException = e;
-        this.locator            = null;
+        this(null, null, e);
     }
 
     /**
@@ -167,13 +173,7 @@
      * @param e Any exception
      */
     public TransformerException(String message, Throwable e) {
-
-        super(((message == null) || (message.length() == 0))
-              ? e.toString()
-              : message);
-
-        this.containedException = e;
-        this.locator            = null;
+        this(message, null, e);
     }
 
     /**
@@ -187,11 +187,7 @@
      * @param locator The locator object for the error or warning.
      */
     public TransformerException(String message, SourceLocator locator) {
-
-        super(message);
-
-        this.containedException = null;
-        this.locator            = locator;
+        this(message, locator, null);
     }
 
     /**
@@ -204,8 +200,9 @@
      */
     public TransformerException(String message, SourceLocator locator,
                                 Throwable e) {
-
-        super(message);
+        super(((message == null) || (message.length() == 0))
+              ? ((e == null) ? "" : e.toString())
+              : message);
 
         this.containedException = e;
         this.locator            = locator;
@@ -219,34 +216,9 @@
      *         location information appended.
      */
     public String getMessageAndLocation() {
-
-        StringBuffer sbuffer = new StringBuffer();
-        String       message = super.getMessage();
-
-        if (null != message) {
-            sbuffer.append(message);
-        }
-
-        if (null != locator) {
-            String systemID = locator.getSystemId();
-            int    line     = locator.getLineNumber();
-            int    column   = locator.getColumnNumber();
-
-            if (null != systemID) {
-                sbuffer.append("; SystemID: ");
-                sbuffer.append(systemID);
-            }
-
-            if (0 != line) {
-                sbuffer.append("; Line#: ");
-                sbuffer.append(line);
-            }
-
-            if (0 != column) {
-                sbuffer.append("; Column#: ");
-                sbuffer.append(column);
-            }
-        }
+        StringBuilder sbuffer = new StringBuilder();
+        sbuffer.append(Objects.toString(super.getMessage(), ""));
+        sbuffer.append(Objects.toString(getLocationAsString(), ""));
 
         return sbuffer.toString();
     }
@@ -258,9 +230,29 @@
      * if there is no location information.
      */
     public String getLocationAsString() {
+        if (locator == null) {
+            return null;
+        }
 
-        if (null != locator) {
-            StringBuffer sbuffer  = new StringBuffer();
+        if (System.getSecurityManager() == null) {
+            return getLocationString();
+        } else {
+            return AccessController.doPrivileged((PrivilegedAction<String>) () ->
+                getLocationString(),
+                new AccessControlContext(new ProtectionDomain[] {getNonPrivDomain()}));
+        }
+    }
+
+    /**
+     * Constructs the location string.
+     * @return the location string
+     */
+    private String getLocationString() {
+        if (locator == null) {
+            return null;
+        }
+
+        StringBuilder sbuffer  = new StringBuilder();
             String       systemID = locator.getSystemId();
             int          line     = locator.getLineNumber();
             int          column   = locator.getColumnNumber();
@@ -281,9 +273,6 @@
             }
 
             return sbuffer.toString();
-        } else {
-            return null;
-        }
     }
 
     /**
@@ -291,6 +280,7 @@
      * originated.  This will trace all nested exception
      * objects, as well as this object.
      */
+    @Override
     public void printStackTrace() {
         printStackTrace(new java.io.PrintWriter(System.err, true));
     }
@@ -301,6 +291,7 @@
      * objects, as well as this object.
      * @param s The stream where the dump will be sent to.
      */
+    @Override
     public void printStackTrace(java.io.PrintStream s) {
         printStackTrace(new java.io.PrintWriter(s));
     }
@@ -311,6 +302,7 @@
      * objects, as well as this object.
      * @param s The writer where the dump will be sent to.
      */
+    @Override
     public void printStackTrace(java.io.PrintWriter s) {
 
         if (s == null) {
@@ -358,11 +350,8 @@
                     } else {
                         exception = null;
                     }
-                } catch (InvocationTargetException ite) {
-                    exception = null;
-                } catch (IllegalAccessException iae) {
-                    exception = null;
-                } catch (NoSuchMethodException nsme) {
+                } catch (InvocationTargetException | IllegalAccessException
+                        | NoSuchMethodException e) {
                     exception = null;
                 }
             }
@@ -371,4 +360,14 @@
             s.flush();
         }
     }
+
+    /**
+     * Creates a ProtectionDomain that has no permission.
+     * @return a ProtectionDomain
+     */
+    private ProtectionDomain getNonPrivDomain() {
+        CodeSource nullSource = new CodeSource(null, (CodeSigner[]) null);
+        PermissionCollection noPermission = new Permissions();
+        return new ProtectionDomain(nullSource, noPermission);
 }
+}
--- a/jaxws/.hgtags	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxws/.hgtags	Mon Aug 07 09:45:38 2017 -0700
@@ -440,3 +440,6 @@
 b44a721aee3d3b2537754e559fe9ecccadea548b jdk-9+177
 6d17fd0a5133a0dd916c77a9a24ae7f0ca402876 jdk-10+15
 bc8289ce1ed3ed5fff62152ed46da3be0b60b7c3 jdk-10+16
+d0190aaf1816081d9b2e0577b65b793804896d1e jdk-9+178
+56ac1831ac5924b5092a53a85d6fc68749501fb8 jdk-9+179
+4c07d366c2e177edba7aa54c4b015e4dbf12bc83 jdk-10+17
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java	Mon Aug 07 09:45:38 2017 -0700
@@ -84,6 +84,14 @@
     private final static String LEXICAL_HANDLER_PROPERTY =
         "http://xml.org/sax/properties/lexical-handler";
 
+    private static final String DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
+
+    private static final String EXTERNAL_GE = "http://xml.org/sax/features/external-general-entities";
+
+    private static final String EXTERNAL_PE = "http://xml.org/sax/features/external-parameter-entities";
+
+    private static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
+
     private static final Logger LOGGER = Logger.getLogger(XmlUtil.class.getName());
 
     private static final String DISABLE_XML_SECURITY = "com.sun.xml.internal.ws.disableXmlSecurity";
@@ -327,10 +335,24 @@
 
     public static DocumentBuilderFactory newDocumentBuilderFactory(boolean disableSecurity) {
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING;
         try {
-            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, !xmlSecurityDisabled(disableSecurity));
+            boolean securityOn = !xmlSecurityDisabled(disableSecurity);
+            factory.setFeature(featureToSet, securityOn);
+            factory.setNamespaceAware(true);
+            if (securityOn) {
+                factory.setExpandEntityReferences(false);
+                featureToSet = DISALLOW_DOCTYPE_DECL;
+                factory.setFeature(featureToSet, true);
+                featureToSet = EXTERNAL_GE;
+                factory.setFeature(featureToSet, false);
+                featureToSet = EXTERNAL_PE;
+                factory.setFeature(featureToSet, false);
+                featureToSet = LOAD_EXTERNAL_DTD;
+                factory.setFeature(featureToSet, false);
+            }
         } catch (ParserConfigurationException e) {
-            LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[] { factory.getClass().getName() } );
+            LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[] {factory.getClass().getName()} );
         }
         return factory;
     }
@@ -347,10 +369,23 @@
 
     public static SAXParserFactory newSAXParserFactory(boolean disableSecurity) {
         SAXParserFactory factory = SAXParserFactory.newInstance();
+        String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING;
         try {
-            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, !xmlSecurityDisabled(disableSecurity));
+            boolean securityOn = !xmlSecurityDisabled(disableSecurity);
+            factory.setFeature(featureToSet, securityOn);
+            factory.setNamespaceAware(true);
+            if (securityOn) {
+                featureToSet = DISALLOW_DOCTYPE_DECL;
+                factory.setFeature(featureToSet, true);
+                featureToSet = EXTERNAL_GE;
+                factory.setFeature(featureToSet, false);
+                featureToSet = EXTERNAL_PE;
+                factory.setFeature(featureToSet, false);
+                featureToSet = LOAD_EXTERNAL_DTD;
+                factory.setFeature(featureToSet, false);
+            }
         } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) {
-            LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[]{factory.getClass().getName()});
+            LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[]{factory.getClass().getName()});
         }
         return factory;
     }
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java	Mon Aug 07 09:45:38 2017 -0700
@@ -112,29 +112,13 @@
         this.entityResolver = entityResolver;
         this.errorReceiver = errReceiver;
         this.logic = logic;
-        try {
-            // secure xml processing can be switched off if input requires it
-            boolean secureProcessingEnabled = options == null || !options.disableXmlSecurity;
-            DocumentBuilderFactory dbf = XmlUtil.newDocumentBuilderFactory(!secureProcessingEnabled);
-            dbf.setNamespaceAware(true);
-            this.documentBuilder = dbf.newDocumentBuilder();
-
-            this.parserFactory = XmlUtil.newSAXParserFactory(secureProcessingEnabled);
-            this.parserFactory.setNamespaceAware(true);
+        // secure xml processing can be switched off if input requires it
+        boolean disableXmlSecurity = options == null ? false : options.disableXmlSecurity;
 
-            if(secureProcessingEnabled){
-                dbf.setExpandEntityReferences(false);
-                try {
-                parserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
-                parserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
-                parserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
-              } catch (SAXNotRecognizedException e){
-                throw new ParserConfigurationException(e.getMessage());
-              } catch (SAXNotSupportedException e) {
-                throw new ParserConfigurationException(e.getMessage());
-              }
-            }
-
+        DocumentBuilderFactory dbf = XmlUtil.newDocumentBuilderFactory(disableXmlSecurity);
+        this.parserFactory = XmlUtil.newSAXParserFactory(disableXmlSecurity);
+        try {
+            this.documentBuilder = dbf.newDocumentBuilder();
         } catch (ParserConfigurationException e) {
             throw new AssertionError(e);
         }
--- a/jdk/.hgtags	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/.hgtags	Mon Aug 07 09:45:38 2017 -0700
@@ -439,3 +439,5 @@
 3281b964ab104002623d744e8b77a12269b70acd jdk-10+16
 443025bee731eb2225371b92c1c74b519b7baf33 jdk-9+178
 06df1ce4b9b887d05ce6a13f4def3547e434dd1a jdk-9+179
+d93f2fd542b7d7855c2cd49ae15ebcc3d441a83b jdk-10+17
+c4b709bad6c5d29294124de5e74e1e2ac84fcf1f jdk-10+18
--- a/jdk/src/java.base/share/classes/java/io/FilterOutputStream.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/io/FilterOutputStream.java	Mon Aug 07 09:45:38 2017 -0700
@@ -50,7 +50,12 @@
     /**
      * Whether the stream is closed; implicitly initialized to false.
      */
-    private boolean closed;
+    private volatile boolean closed;
+
+    /**
+     * Object used to prevent a race on the 'closed' instance variable.
+     */
+    private final Object closeLock = new Object();
 
     /**
      * Creates an output stream filter built on top of the specified
@@ -165,7 +170,12 @@
         if (closed) {
             return;
         }
-        closed = true;
+        synchronized (closeLock) {
+            if (closed) {
+                return;
+            }
+            closed = true;
+        }
 
         Throwable flushException = null;
         try {
--- a/jdk/src/java.base/share/classes/java/lang/Class.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java	Mon Aug 07 09:45:38 2017 -0700
@@ -364,9 +364,9 @@
             // Reflective call to get caller class is only needed if a security manager
             // is present.  Avoid the overhead of making this call otherwise.
             caller = Reflection.getCallerClass();
-            if (VM.isSystemDomainLoader(loader)) {
+            if (loader == null) {
                 ClassLoader ccl = ClassLoader.getClassLoader(caller);
-                if (!VM.isSystemDomainLoader(ccl)) {
+                if (ccl != null) {
                     sm.checkPermission(
                         SecurityConstants.GET_CLASSLOADER_PERMISSION);
                 }
@@ -432,18 +432,21 @@
         Objects.requireNonNull(module);
         Objects.requireNonNull(name);
 
-        Class<?> caller = Reflection.getCallerClass();
-        if (caller != null && caller.getModule() != module) {
-            // if caller is null, Class.forName is the last java frame on the stack.
-            // java.base has all permissions
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
+        ClassLoader cl;
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            Class<?> caller = Reflection.getCallerClass();
+            if (caller != null && caller.getModule() != module) {
+                // if caller is null, Class.forName is the last java frame on the stack.
+                // java.base has all permissions
                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
             }
+            PrivilegedAction<ClassLoader> pa = module::getClassLoader;
+            cl = AccessController.doPrivileged(pa);
+        } else {
+            cl = module.getClassLoader();
         }
 
-        PrivilegedAction<ClassLoader> pa = module::getClassLoader;
-        ClassLoader cl = AccessController.doPrivileged(pa);
         if (cl != null) {
             return cl.loadClass(module, name);
         } else {
--- a/jdk/src/java.base/share/classes/java/lang/Module.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/Module.java	Mon Aug 07 09:45:38 2017 -0700
@@ -246,7 +246,6 @@
         return null;
     }
 
-
     // --
 
     // special Module to mean "all unnamed modules"
@@ -257,17 +256,38 @@
     private static final Module EVERYONE_MODULE = new Module(null);
     private static final Set<Module> EVERYONE_SET = Set.of(EVERYONE_MODULE);
 
+    /**
+     * The holder of data structures to support readability, exports, and
+     * service use added at runtime with the reflective APIs.
+     */
+    private static class ReflectionData {
+        /**
+         * A module (1st key) reads another module (2nd key)
+         */
+        static final WeakPairMap<Module, Module, Boolean> reads =
+            new WeakPairMap<>();
+
+        /**
+         * A module (1st key) exports or opens a package to another module
+         * (2nd key). The map value is a map of package name to a boolean
+         * that indicates if the package is opened.
+         */
+        static final WeakPairMap<Module, Module, Map<String, Boolean>> exports =
+            new WeakPairMap<>();
+
+        /**
+         * A module (1st key) uses a service (2nd key)
+         */
+        static final WeakPairMap<Module, Class<?>, Boolean> uses =
+            new WeakPairMap<>();
+    }
+
 
     // -- readability --
 
     // the modules that this module reads
     private volatile Set<Module> reads;
 
-    // additional module (2nd key) that some module (1st key) reflectively reads
-    private static final WeakPairMap<Module, Module, Boolean> reflectivelyReads
-        = new WeakPairMap<>();
-
-
     /**
      * Indicates if this module reads the given module. This method returns
      * {@code true} if invoked to test if this module reads itself. It also
@@ -300,13 +320,13 @@
         }
 
         // check if this module reads the other module reflectively
-        if (reflectivelyReads.containsKeyPair(this, other))
+        if (ReflectionData.reads.containsKeyPair(this, other))
             return true;
 
         // if other is an unnamed module then check if this module reads
         // all unnamed modules
         if (!other.isNamed()
-            && reflectivelyReads.containsKeyPair(this, ALL_UNNAMED_MODULE))
+            && ReflectionData.reads.containsKeyPair(this, ALL_UNNAMED_MODULE))
             return true;
 
         return false;
@@ -393,7 +413,7 @@
             }
 
             // add reflective read
-            reflectivelyReads.putIfAbsent(this, other, Boolean.TRUE);
+            ReflectionData.reads.putIfAbsent(this, other, Boolean.TRUE);
         }
     }
 
@@ -408,13 +428,6 @@
     // if the value contains EVERYONE_MODULE then the package is exported to all
     private volatile Map<String, Set<Module>> exportedPackages;
 
-    // additional exports or opens added at run-time
-    // this module (1st key), other module (2nd key)
-    // (package name, open?) (value)
-    private static final WeakPairMap<Module, Module, Map<String, Boolean>>
-        reflectivelyExports = new WeakPairMap<>();
-
-
     /**
      * Returns {@code true} if this module exports the given package to at
      * least the given module.
@@ -600,7 +613,7 @@
      */
     private boolean isReflectivelyExportedOrOpen(String pn, Module other, boolean open) {
         // exported or open to all modules
-        Map<String, Boolean> exports = reflectivelyExports.get(this, EVERYONE_MODULE);
+        Map<String, Boolean> exports = ReflectionData.exports.get(this, EVERYONE_MODULE);
         if (exports != null) {
             Boolean b = exports.get(pn);
             if (b != null) {
@@ -612,7 +625,7 @@
         if (other != EVERYONE_MODULE) {
 
             // exported or open to other
-            exports = reflectivelyExports.get(this, other);
+            exports = ReflectionData.exports.get(this, other);
             if (exports != null) {
                 Boolean b = exports.get(pn);
                 if (b != null) {
@@ -623,7 +636,7 @@
 
             // other is an unnamed module && exported or open to all unnamed
             if (!other.isNamed()) {
-                exports = reflectivelyExports.get(this, ALL_UNNAMED_MODULE);
+                exports = ReflectionData.exports.get(this, ALL_UNNAMED_MODULE);
                 if (exports != null) {
                     Boolean b = exports.get(pn);
                     if (b != null) {
@@ -886,8 +899,8 @@
             }
         }
 
-        // add package name to reflectivelyExports if absent
-        Map<String, Boolean> map = reflectivelyExports
+        // add package name to exports if absent
+        Map<String, Boolean> map = ReflectionData.exports
             .computeIfAbsent(this, other,
                              (m1, m2) -> new ConcurrentHashMap<>());
         if (open) {
@@ -932,10 +945,6 @@
 
     // -- services --
 
-    // additional service type (2nd key) that some module (1st key) uses
-    private static final WeakPairMap<Module, Class<?>, Boolean> reflectivelyUses
-        = new WeakPairMap<>();
-
     /**
      * If the caller's module is this module then update this module to add a
      * service dependence on the given service type. This method is intended
@@ -980,7 +989,7 @@
      */
     void implAddUses(Class<?> service) {
         if (!canUse(service)) {
-            reflectivelyUses.putIfAbsent(this, service, Boolean.TRUE);
+            ReflectionData.uses.putIfAbsent(this, service, Boolean.TRUE);
         }
     }
 
@@ -1011,7 +1020,7 @@
             return true;
 
         // uses added via addUses
-        return reflectivelyUses.containsKeyPair(this, service);
+        return ReflectionData.uses.containsKeyPair(this, service);
     }
 
 
@@ -1060,8 +1069,11 @@
                                              Function<String, ClassLoader> clf,
                                              ModuleLayer layer)
     {
-        Map<String, Module> nameToModule = new HashMap<>();
-        Map<String, ClassLoader> moduleToLoader = new HashMap<>();
+        boolean isBootLayer = (ModuleLayer.boot() == null);
+
+        int cap = (int)(cf.modules().size() / 0.75f + 1.0f);
+        Map<String, Module> nameToModule = new HashMap<>(cap);
+        Map<String, ClassLoader> nameToLoader = new HashMap<>(cap);
 
         Set<ClassLoader> loaders = new HashSet<>();
         boolean hasPlatformModules = false;
@@ -1070,7 +1082,7 @@
         for (ResolvedModule resolvedModule : cf.modules()) {
             String name = resolvedModule.name();
             ClassLoader loader = clf.apply(name);
-            moduleToLoader.put(name, loader);
+            nameToLoader.put(name, loader);
             if (loader == null || loader == ClassLoaders.platformClassLoader()) {
                 if (!(clf instanceof ModuleLoaderMap.Mapper)) {
                     throw new IllegalArgumentException("loader can't be 'null'"
@@ -1087,20 +1099,19 @@
             ModuleReference mref = resolvedModule.reference();
             ModuleDescriptor descriptor = mref.descriptor();
             String name = descriptor.name();
-            URI uri = mref.location().orElse(null);
-            ClassLoader loader = moduleToLoader.get(resolvedModule.name());
+            ClassLoader loader = nameToLoader.get(name);
             Module m;
             if (loader == null && name.equals("java.base")) {
                 // java.base is already defined to the VM
                 m = Object.class.getModule();
             } else {
+                URI uri = mref.location().orElse(null);
                 m = new Module(layer, loader, descriptor, uri);
             }
             nameToModule.put(name, m);
-            moduleToLoader.put(name, loader);
         }
 
-        // setup readability and exports
+        // setup readability and exports/opens
         for (ResolvedModule resolvedModule : cf.modules()) {
             ModuleReference mref = resolvedModule.reference();
             ModuleDescriptor descriptor = mref.descriptor();
@@ -1146,7 +1157,18 @@
             }
 
             // exports and opens
-            initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
+            if (descriptor.isOpen() || descriptor.isAutomatic()) {
+                // The VM doesn't special case open or automatic modules yet
+                // so need to export all packages
+                for (String source : descriptor.packages()) {
+                    addExportsToAll0(m, source);
+                }
+            } else if (isBootLayer && descriptor.opens().isEmpty()) {
+                // no open packages, no qualified exports to modules in parent layers
+                initExports(m, nameToModule);
+            } else {
+                initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
+            }
         }
 
         // if there are modules defined to the boot or platform class loaders
@@ -1161,7 +1183,7 @@
                 if (!descriptor.provides().isEmpty()) {
                     String name = descriptor.name();
                     Module m = nameToModule.get(name);
-                    ClassLoader loader = moduleToLoader.get(name);
+                    ClassLoader loader = nameToLoader.get(name);
                     if (loader == null) {
                         bootCatalog.register(m);
                     } else if (loader == pcl) {
@@ -1179,7 +1201,6 @@
         return nameToModule;
     }
 
-
     /**
      * Find the runtime Module corresponding to the given ResolvedModule
      * in the given parent layer (or its parents).
@@ -1201,25 +1222,55 @@
                 .orElse(null);
     }
 
+    /**
+     * Initialize/setup a module's exports.
+     *
+     * @param m the module
+     * @param nameToModule map of module name to Module (for qualified exports)
+     */
+    private static void initExports(Module m, Map<String, Module> nameToModule) {
+        Map<String, Set<Module>> exportedPackages = new HashMap<>();
+
+        for (Exports exports : m.getDescriptor().exports()) {
+            String source = exports.source();
+            if (exports.isQualified()) {
+                // qualified exports
+                Set<Module> targets = new HashSet<>();
+                for (String target : exports.targets()) {
+                    Module m2 = nameToModule.get(target);
+                    if (m2 != null) {
+                        addExports0(m, source, m2);
+                        targets.add(m2);
+                    }
+                }
+                if (!targets.isEmpty()) {
+                    exportedPackages.put(source, targets);
+                }
+            } else {
+                // unqualified exports
+                addExportsToAll0(m, source);
+                exportedPackages.put(source, EVERYONE_SET);
+            }
+        }
+
+        if (!exportedPackages.isEmpty())
+            m.exportedPackages = exportedPackages;
+    }
 
     /**
-     * Initialize the maps of exported and open packages for module m.
+     * Initialize/setup a module's exports.
+     *
+     * @param m the module
+     * @param nameToSource map of module name to Module for modules that m reads
+     * @param nameToModule map of module name to Module for modules in the layer
+     *                     under construction
+     * @param parents the parent layers
      */
     private static void initExportsAndOpens(Module m,
                                             Map<String, Module> nameToSource,
                                             Map<String, Module> nameToModule,
                                             List<ModuleLayer> parents) {
-        // The VM doesn't special case open or automatic modules so need to
-        // export all packages
         ModuleDescriptor descriptor = m.getDescriptor();
-        if (descriptor.isOpen() || descriptor.isAutomatic()) {
-            assert descriptor.opens().isEmpty();
-            for (String source : descriptor.packages()) {
-                addExportsToAll0(m, source);
-            }
-            return;
-        }
-
         Map<String, Set<Module>> openPackages = new HashMap<>();
         Map<String, Set<Module>> exportedPackages = new HashMap<>();
 
@@ -1272,7 +1323,6 @@
                 if (!targets.isEmpty()) {
                     exportedPackages.put(source, targets);
                 }
-
             } else {
                 // unqualified exports
                 addExportsToAll0(m, source);
--- a/jdk/src/java.base/share/classes/java/lang/System.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/System.java	Mon Aug 07 09:45:38 2017 -0700
@@ -313,6 +313,10 @@
      * @see java.lang.RuntimePermission
      */
     public static void setSecurityManager(final SecurityManager s) {
+        if (security == null) {
+            // ensure image reader is initialized
+            Object.class.getResource("java/lang/ANY");
+        }
         if (s != null) {
             try {
                 s.checkPackageAccess("java.lang");
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Mon Aug 07 09:45:38 2017 -0700
@@ -2476,7 +2476,7 @@
                 return false;
             }
             ClassLoader loader = defc.getClassLoader();
-            if (!jdk.internal.misc.VM.isSystemDomainLoader(loader)) {
+            if (loader != null) {
                 ClassLoader sysl = ClassLoader.getSystemClassLoader();
                 boolean found = false;
                 while (sysl != null) {
--- a/jdk/src/java.base/share/classes/java/lang/module/Configuration.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/Configuration.java	Mon Aug 07 09:45:38 2017 -0700
@@ -31,6 +31,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Deque;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -41,6 +42,9 @@
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import jdk.internal.module.ModuleReferenceImpl;
+import jdk.internal.module.ModuleTarget;
+
 /**
  * A configuration that is the result of <a href="package-summary.html#resolution">
  * resolution</a> or resolution with <a href="#service-binding">service binding</a>.
@@ -121,11 +125,8 @@
         this.targetPlatform = null;
     }
 
-    private Configuration(List<Configuration> parents,
-                          Resolver resolver,
-                          boolean check)
-    {
-        Map<ResolvedModule, Set<ResolvedModule>> g = resolver.finish(this, check);
+    private Configuration(List<Configuration> parents, Resolver resolver) {
+        Map<ResolvedModule, Set<ResolvedModule>> g = resolver.finish(this);
 
         @SuppressWarnings(value = {"rawtypes", "unchecked"})
         Entry<String, ResolvedModule>[] nameEntries
@@ -147,6 +148,62 @@
     }
 
     /**
+     * Creates the Configuration for the boot layer from a pre-generated
+     * readability graph.
+     *
+     * @apiNote This method is coded for startup performance.
+     */
+    Configuration(ModuleFinder finder, Map<String, Set<String>> map) {
+        int moduleCount = map.size();
+
+        // create map of name -> ResolvedModule
+        @SuppressWarnings(value = {"rawtypes", "unchecked"})
+        Entry<String, ResolvedModule>[] nameEntries
+            = (Entry<String, ResolvedModule>[])new Entry[moduleCount];
+        ResolvedModule[] moduleArray = new ResolvedModule[moduleCount];
+        String targetPlatform = null;
+        int i = 0;
+        for (String name : map.keySet()) {
+            ModuleReference mref = finder.find(name).orElse(null);
+            assert mref != null;
+
+            if (targetPlatform == null && mref instanceof ModuleReferenceImpl) {
+                ModuleTarget target = ((ModuleReferenceImpl)mref).moduleTarget();
+                if (target != null) {
+                    targetPlatform = target.targetPlatform();
+                }
+            }
+
+            ResolvedModule resolvedModule = new ResolvedModule(this, mref);
+            moduleArray[i] = resolvedModule;
+            nameEntries[i] = Map.entry(name, resolvedModule);
+            i++;
+        }
+        Map<String, ResolvedModule> nameToModule = Map.ofEntries(nameEntries);
+
+        // create entries for readability graph
+        @SuppressWarnings(value = {"rawtypes", "unchecked"})
+        Entry<ResolvedModule, Set<ResolvedModule>>[] moduleEntries
+            = (Entry<ResolvedModule, Set<ResolvedModule>>[])new Entry[moduleCount];
+        i = 0;
+        for (ResolvedModule resolvedModule : moduleArray) {
+            Set<String> names = map.get(resolvedModule.name());
+            ResolvedModule[] readsArray = new ResolvedModule[names.size()];
+            int j = 0;
+            for (String name : names) {
+                readsArray[j++] = nameToModule.get(name);
+            }
+            moduleEntries[i++] = Map.entry(resolvedModule, Set.of(readsArray));
+        }
+
+        this.parents = List.of(empty());
+        this.graph = Map.ofEntries(moduleEntries);
+        this.modules = Set.of(moduleArray);
+        this.nameToModule = nameToModule;
+        this.targetPlatform = targetPlatform;
+    }
+
+    /**
      * Resolves a collection of root modules, with this configuration as its
      * parent, to create a new configuration. This method works exactly as
      * specified by the static {@link
@@ -233,24 +290,20 @@
 
     /**
      * Resolves a collection of root modules, with service binding, and with
-     * the empty configuration as its parent. The consistency checks
-     * are optionally run.
+     * the empty configuration as its parent.
      *
      * This method is used to create the configuration for the boot layer.
      */
     static Configuration resolveAndBind(ModuleFinder finder,
                                         Collection<String> roots,
-                                        boolean check,
                                         PrintStream traceOutput)
     {
         List<Configuration> parents = List.of(empty());
         Resolver resolver = new Resolver(finder, parents, ModuleFinder.of(), traceOutput);
         resolver.resolve(roots).bind();
-
-        return new Configuration(parents, resolver, check);
+        return new Configuration(parents, resolver);
     }
 
-
     /**
      * Resolves a collection of root modules to create a configuration.
      *
@@ -356,7 +409,7 @@
         Resolver resolver = new Resolver(before, parentList, after, null);
         resolver.resolve(roots);
 
-        return new Configuration(parentList, resolver, true);
+        return new Configuration(parentList, resolver);
     }
 
     /**
@@ -427,7 +480,7 @@
         Resolver resolver = new Resolver(before, parentList, after, null);
         resolver.resolve(roots).bind();
 
-        return new Configuration(parentList, resolver, true);
+        return new Configuration(parentList, resolver);
     }
 
 
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Mon Aug 07 09:45:38 2017 -0700
@@ -2728,10 +2728,15 @@
                 @Override
                 public Configuration resolveAndBind(ModuleFinder finder,
                                                     Collection<String> roots,
-                                                    boolean check,
                                                     PrintStream traceOutput)
                 {
-                    return Configuration.resolveAndBind(finder, roots, check, traceOutput);
+                    return Configuration.resolveAndBind(finder, roots, traceOutput);
+                }
+
+                @Override
+                public Configuration newConfiguration(ModuleFinder finder,
+                                                      Map<String, Set<String>> graph) {
+                    return new Configuration(finder, graph);
                 }
             });
     }
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java	Mon Aug 07 09:45:38 2017 -0700
@@ -25,9 +25,7 @@
 
 package java.lang.module;
 
-import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.security.AccessController;
 import java.security.Permission;
 import java.security.PrivilegedAction;
@@ -40,10 +38,8 @@
 import java.util.Optional;
 import java.util.Set;
 
-import jdk.internal.module.ModuleBootstrap;
-import jdk.internal.module.ModulePatcher;
 import jdk.internal.module.ModulePath;
-import jdk.internal.module.SystemModuleFinder;
+import jdk.internal.module.SystemModuleFinders;
 
 /**
  * A finder of modules. A {@code ModuleFinder} is used to find modules during
@@ -157,53 +153,14 @@
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkPermission(new RuntimePermission("accessSystemModules"));
-            PrivilegedAction<ModuleFinder> pa = ModuleFinder::privilegedOfSystem;
+            PrivilegedAction<ModuleFinder> pa = SystemModuleFinders::ofSystem;
             return AccessController.doPrivileged(pa);
         } else {
-            return privilegedOfSystem();
-        }
-    }
-
-    /**
-     * Returns a module finder that locates the system modules. This method
-     * assumes it has permissions to access the runtime image.
-     */
-    private static ModuleFinder privilegedOfSystem() {
-        String home = System.getProperty("java.home");
-        Path modules = Paths.get(home, "lib", "modules");
-        if (Files.isRegularFile(modules)) {
-            return SystemModuleFinder.getInstance();
-        } else {
-            Path dir = Paths.get(home, "modules");
-            if (Files.isDirectory(dir)) {
-                return privilegedOf(ModuleBootstrap.patcher(), dir);
-            } else {
-                throw new InternalError("Unable to detect the run-time image");
-            }
+            return SystemModuleFinders.ofSystem();
         }
     }
 
     /**
-     * Returns a module finder that locates the system modules in an exploded
-     * image. The image may be patched.
-     */
-    private static ModuleFinder privilegedOf(ModulePatcher patcher, Path dir) {
-        ModuleFinder finder = ModulePath.of(patcher, dir);
-        return new ModuleFinder() {
-            @Override
-            public Optional<ModuleReference> find(String name) {
-                PrivilegedAction<Optional<ModuleReference>> pa = () -> finder.find(name);
-                return AccessController.doPrivileged(pa);
-            }
-            @Override
-            public Set<ModuleReference> findAll() {
-                PrivilegedAction<Set<ModuleReference>> pa = finder::findAll;
-                return AccessController.doPrivileged(pa);
-            }
-        };
-    }
-
-    /**
      * Returns a module finder that locates modules on the file system by
      * searching a sequence of directories and/or packaged modules.
      *
--- a/jdk/src/java.base/share/classes/java/lang/module/Resolver.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/Resolver.java	Mon Aug 07 09:45:38 2017 -0700
@@ -353,25 +353,13 @@
 
     /**
      * Execute post-resolution checks and returns the module graph of resolved
-     * modules as {@code Map}. The resolved modules will be in the given
-     * configuration.
-     *
-     * @param check {@true} to execute the post resolution checks
+     * modules as a map.
      */
-    Map<ResolvedModule, Set<ResolvedModule>> finish(Configuration cf,
-                                                    boolean check)
-    {
-        if (check) {
-            detectCycles();
-            checkHashes();
-        }
-
+    Map<ResolvedModule, Set<ResolvedModule>> finish(Configuration cf) {
+        detectCycles();
+        checkHashes();
         Map<ResolvedModule, Set<ResolvedModule>> graph = makeGraph(cf);
-
-        if (check) {
-            checkExportSuppliers(graph);
-        }
-
+        checkExportSuppliers(graph);
         return graph;
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java	Mon Aug 07 09:45:38 2017 -0700
@@ -453,7 +453,7 @@
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             ClassLoader ccl = caller.getClassLoader();
-            if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
+            if (loader == null && ccl != null) {
                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
             }
             ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
--- a/jdk/src/java.base/share/classes/java/net/URL.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/net/URL.java	Mon Aug 07 09:45:38 2017 -0700
@@ -409,7 +409,7 @@
             }
         }
 
-        protocol = protocol.toLowerCase(Locale.ROOT);
+        protocol = toLowerCase(protocol);
         this.protocol = protocol;
         if (host != null) {
 
@@ -585,7 +585,7 @@
             for (i = start ; !aRef && (i < limit) &&
                      ((c = spec.charAt(i)) != '/') ; i++) {
                 if (c == ':') {
-                    String s = spec.substring(start, i).toLowerCase(Locale.ROOT);
+                    String s = toLowerCase(spec.substring(start, i));
                     if (isValidProtocol(s)) {
                         newProtocol = s;
                         start = i + 1;
@@ -1318,6 +1318,17 @@
         }
     }
 
+    /**
+     * Returns the protocol in lower case. Special cases known protocols
+     * to avoid loading locale classes during startup.
+     */
+    static String toLowerCase(String protocol) {
+        if (protocol.equals("jrt") || protocol.equals("file") || protocol.equals("jar")) {
+            return protocol;
+        } else {
+            return protocol.toLowerCase(Locale.ROOT);
+        }
+    }
 
     /**
      * Non-overrideable protocols: "jrt" and "file"
--- a/jdk/src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java	Mon Aug 07 09:45:38 2017 -0700
@@ -70,7 +70,7 @@
     extends Selector
 {
 
-    private AtomicBoolean selectorOpen = new AtomicBoolean(true);
+    private final AtomicBoolean selectorOpen = new AtomicBoolean(true);
 
     // The provider that created this selector
     private final SelectorProvider provider;
--- a/jdk/src/java.base/share/classes/java/security/MessageDigest.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/security/MessageDigest.java	Mon Aug 07 09:45:38 2017 -0700
@@ -57,7 +57,7 @@
  * and catching the CloneNotSupportedException:
  *
  * <pre>{@code
- * MessageDigest md = MessageDigest.getInstance("SHA");
+ * MessageDigest md = MessageDigest.getInstance("SHA-256");
  *
  * try {
  *     md.update(toChapter1);
@@ -496,7 +496,7 @@
     /**
      * Returns a string that identifies the algorithm, independent of
      * implementation details. The name should be a standard
-     * Java Security name (such as "SHA", "MD5", and so on).
+     * Java Security name (such as "SHA-256").
      * See the MessageDigest section in the <a href=
      * "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">
      * Java Security Standard Algorithm Names Specification</a>
--- a/jdk/src/java.base/share/classes/java/security/Signature.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/security/Signature.java	Mon Aug 07 09:45:38 2017 -0700
@@ -51,11 +51,10 @@
  * authentication and integrity assurance of digital data.
  *
  * <p> The signature algorithm can be, among others, the NIST standard
- * DSA, using DSA and SHA-1. The DSA algorithm using the
- * SHA-1 message digest algorithm can be specified as {@code SHA1withDSA}.
- * In the case of RSA, there are multiple choices for the message digest
- * algorithm, so the signing algorithm could be specified as, for example,
- * {@code MD2withRSA}, {@code MD5withRSA}, or {@code SHA1withRSA}.
+ * DSA, using DSA and SHA-256. The DSA algorithm using the
+ * SHA-256 message digest algorithm can be specified as {@code SHA256withDSA}.
+ * In the case of RSA the signing algorithm could be specified as, for example,
+ * {@code SHA256withRSA}.
  * The algorithm name must be specified, as there is no default.
  *
  * <p> A Signature object can be used to generate and verify digital
--- a/jdk/src/java.base/share/classes/java/security/SignedObject.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/security/SignedObject.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, 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
@@ -81,13 +81,12 @@
  * verification in an attempt to bypass a security check.
  *
  * <p> The signature algorithm can be, among others, the NIST standard
- * DSA, using DSA and SHA-1.  The algorithm is specified using the
+ * DSA, using DSA and SHA-256.  The algorithm is specified using the
  * same convention as that for signatures. The DSA algorithm using the
- * SHA-1 message digest algorithm can be specified, for example, as
- * "SHA/DSA" or "SHA-1/DSA" (they are equivalent).  In the case of
- * RSA, there are multiple choices for the message digest algorithm,
- * so the signing algorithm could be specified as, for example,
- * "MD2/RSA", "MD5/RSA" or "SHA-1/RSA".  The algorithm name must be
+ * SHA-256 message digest algorithm can be specified, for example, as
+ * "SHA256withDSA".  In the case of
+ * RSA the signing algorithm could be specified as, for example,
+ * "SHA256withRSA".  The algorithm name must be
  * specified, as there is no default.
  *
  * <p> The name of the Cryptography Package Provider is designated
--- a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/regex/Pattern.java	Mon Aug 07 09:45:38 2017 -0700
@@ -667,11 +667,11 @@
  * <tr><td>{@code \p{Alpha}}</td>
  *     <td>An alphabetic character:{@code \p{IsAlphabetic}}</td></tr>
  * <tr><td>{@code \p{Digit}}</td>
- *     <td>A decimal digit character:{@code p{IsDigit}}</td></tr>
+ *     <td>A decimal digit character:{@code \p{IsDigit}}</td></tr>
  * <tr><td>{@code \p{Alnum}}</td>
  *     <td>An alphanumeric character:{@code [\p{IsAlphabetic}\p{IsDigit}]}</td></tr>
  * <tr><td>{@code \p{Punct}}</td>
- *     <td>A punctuation character:{@code p{IsPunctuation}}</td></tr>
+ *     <td>A punctuation character:{@code \p{IsPunctuation}}</td></tr>
  * <tr><td>{@code \p{Graph}}</td>
  *     <td>A visible character: {@code [^\p{IsWhite_Space}\p{gc=Cc}\p{gc=Cs}\p{gc=Cn}]}</td></tr>
  * <tr><td>{@code \p{Print}}</td>
--- a/jdk/src/java.base/share/classes/javax/crypto/Cipher.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/javax/crypto/Cipher.java	Mon Aug 07 09:45:38 2017 -0700
@@ -59,7 +59,7 @@
  * <p>A <i>transformation</i> is a string that describes the operation (or
  * set of operations) to be performed on the given input, to produce some
  * output. A transformation always includes the name of a cryptographic
- * algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and
+ * algorithm (e.g., <i>AES</i>), and may be followed by a feedback mode and
  * padding scheme.
  *
  * <p> A transformation is of the form:
@@ -75,17 +75,19 @@
  * For example, the following is a valid transformation:
  *
  * <pre>
- *     Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
+ *     Cipher c = Cipher.getInstance("<i>AES/CBC/PKCS5Padding</i>");
  * </pre>
  *
  * Using modes such as {@code CFB} and {@code OFB}, block
  * ciphers can encrypt data in units smaller than the cipher's actual
  * block size.  When requesting such a mode, you may optionally specify
  * the number of bits to be processed at a time by appending this number
- * to the mode name as shown in the "{@code DES/CFB8/NoPadding}" and
- * "{@code DES/OFB32/PKCS5Padding}" transformations. If no such
- * number is specified, a provider-specific default is used. (For
- * example, the SunJCE provider uses a default of 64 bits for DES.)
+ * to the mode name as shown in the "{@code AES/CFB8/NoPadding}" and
+ * "{@code AES/OFB32/PKCS5Padding}" transformations. If no such
+ * number is specified, a provider-specific default is used.
+ * (See the
+ * {@extLink security_guide_jdk_providers JDK Providers Documentation}
+ * for the JDK Providers default values.)
  * Thus, block ciphers can be turned into byte-oriented stream ciphers by
  * using an 8 bit mode such as CFB8 or OFB8.
  * <p>
@@ -308,7 +310,7 @@
         /*
          * array containing the components of a Cipher transformation:
          *
-         * index 0: algorithm component (e.g., DES)
+         * index 0: algorithm component (e.g., AES)
          * index 1: feedback component (e.g., CFB)
          * index 2: padding component (e.g., PKCS5Padding)
          */
@@ -354,8 +356,8 @@
         // transform string to lookup in the provider
         final String transform;
         // the mode/padding suffix in upper case. for example, if the algorithm
-        // to lookup is "DES/CBC/PKCS5Padding" suffix is "/CBC/PKCS5PADDING"
-        // if loopup is "DES", suffix is the empty string
+        // to lookup is "AES/CBC/PKCS5Padding" suffix is "/CBC/PKCS5PADDING"
+        // if lookup is "AES", suffix is the empty string
         // needed because aliases prevent straight transform.equals()
         final String suffix;
         // value to pass to setMode() or null if no such call required
@@ -440,11 +442,11 @@
         }
 
         if ((mode == null) && (pad == null)) {
-            // DES
+            // AES
             Transform tr = new Transform(alg, "", null, null);
             return Collections.singletonList(tr);
         } else { // if ((mode != null) && (pad != null)) {
-            // DES/CBC/PKCS5Padding
+            // AES/CBC/PKCS5Padding
             List<Transform> list = new ArrayList<>(4);
             list.add(new Transform(alg, "/" + mode + "/" + pad, null, null));
             list.add(new Transform(alg, "/" + mode, null, pad));
@@ -488,7 +490,7 @@
      * {@link Security#getProviders() Security.getProviders()}.
      *
      * @param transformation the name of the transformation, e.g.,
-     * <i>DES/CBC/PKCS5Padding</i>.
+     * <i>AES/CBC/PKCS5Padding</i>.
      * See the Cipher section in the <a href=
      *   "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
      * Java Security Standard Algorithm Names Specification</a>
@@ -566,7 +568,7 @@
      * the {@link Security#getProviders() Security.getProviders()} method.
      *
      * @param transformation the name of the transformation,
-     * e.g., <i>DES/CBC/PKCS5Padding</i>.
+     * e.g., <i>AES/CBC/PKCS5Padding</i>.
      * See the Cipher section in the <a href=
      *   "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
      * Java Security Standard Algorithm Names Specification</a>
@@ -626,7 +628,7 @@
      * does not have to be registered in the provider list.
      *
      * @param transformation the name of the transformation,
-     * e.g., <i>DES/CBC/PKCS5Padding</i>.
+     * e.g., <i>AES/CBC/PKCS5Padding</i>.
      * See the Cipher section in the <a href=
      *   "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
      * Java Security Standard Algorithm Names Specification</a>
--- a/jdk/src/java.base/share/classes/javax/crypto/CipherSpi.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/javax/crypto/CipherSpi.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, 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
@@ -59,7 +59,7 @@
  * <p>A <i>transformation</i> is a string that describes the operation (or
  * set of operations) to be performed on the given input, to produce some
  * output. A transformation always includes the name of a cryptographic
- * algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and
+ * algorithm (e.g., <i>AES</i>), and may be followed by a feedback mode and
  * padding scheme.
  *
  * <p> A transformation is of the form:
@@ -75,7 +75,7 @@
  * For example, the following is a valid transformation:
  *
  * <pre>
- *     Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
+ *     Cipher c = Cipher.getInstance("<i>AES/CBC/PKCS5Padding</i>");
  * </pre>
  *
  * <p>A provider may supply a separate class for each combination
@@ -125,32 +125,32 @@
  * </ul>
  *
  * <p>For example, a provider may supply a subclass of <code>CipherSpi</code>
- * that implements <i>DES/ECB/PKCS5Padding</i>, one that implements
- * <i>DES/CBC/PKCS5Padding</i>, one that implements
- * <i>DES/CFB/PKCS5Padding</i>, and yet another one that implements
- * <i>DES/OFB/PKCS5Padding</i>. That provider would have the following
+ * that implements <i>AES/ECB/PKCS5Padding</i>, one that implements
+ * <i>AES/CBC/PKCS5Padding</i>, one that implements
+ * <i>AES/CFB/PKCS5Padding</i>, and yet another one that implements
+ * <i>AES/OFB/PKCS5Padding</i>. That provider would have the following
  * <code>Cipher</code> properties in its master class:
  *
  * <ul>
  *
  * <li>
  * <pre>
- *     <code>Cipher.</code><i>DES/ECB/PKCS5Padding</i>
+ *     <code>Cipher.</code><i>AES/ECB/PKCS5Padding</i>
  * </pre>
  *
  * <li>
  * <pre>
- *     <code>Cipher.</code><i>DES/CBC/PKCS5Padding</i>
+ *     <code>Cipher.</code><i>AES/CBC/PKCS5Padding</i>
  * </pre>
  *
  * <li>
  * <pre>
- *     <code>Cipher.</code><i>DES/CFB/PKCS5Padding</i>
+ *     <code>Cipher.</code><i>AES/CFB/PKCS5Padding</i>
  * </pre>
  *
  * <li>
  * <pre>
- *     <code>Cipher.</code><i>DES/OFB/PKCS5Padding</i>
+ *     <code>Cipher.</code><i>AES/OFB/PKCS5Padding</i>
  * </pre>
  *
  * </ul>
@@ -158,7 +158,7 @@
  * <p>Another provider may implement a class for each of the above modes
  * (i.e., one class for <i>ECB</i>, one for <i>CBC</i>, one for <i>CFB</i>,
  * and one for <i>OFB</i>), one class for <i>PKCS5Padding</i>,
- * and a generic <i>DES</i> class that subclasses from <code>CipherSpi</code>.
+ * and a generic <i>AES</i> class that subclasses from <code>CipherSpi</code>.
  * That provider would have the following
  * <code>Cipher</code> properties in its master class:
  *
@@ -166,7 +166,7 @@
  *
  * <li>
  * <pre>
- *     <code>Cipher.</code><i>DES</i>
+ *     <code>Cipher.</code><i>AES</i>
  * </pre>
  *
  * </ul>
--- a/jdk/src/java.base/share/classes/javax/crypto/Mac.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/javax/crypto/Mac.java	Mon Aug 07 09:45:38 2017 -0700
@@ -50,7 +50,7 @@
  *
  * <p> A MAC mechanism that is based on cryptographic hash functions is
  * referred to as HMAC. HMAC can be used with any cryptographic hash function,
- * e.g., MD5 or SHA-1, in combination with a secret shared key. HMAC is
+ * e.g., SHA256 or SHA384, in combination with a secret shared key. HMAC is
  * specified in RFC 2104.
  *
  * <p> Every implementation of the Java platform is required to support
--- a/jdk/src/java.base/share/classes/javax/crypto/SealedObject.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/javax/crypto/SealedObject.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, 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
@@ -40,7 +40,7 @@
  * <p> Given any Serializable object, one can create a SealedObject
  * that encapsulates the original object, in serialized
  * format (i.e., a "deep copy"), and seals (encrypts) its serialized contents,
- * using a cryptographic algorithm such as DES, to protect its
+ * using a cryptographic algorithm such as AES, to protect its
  * confidentiality.  The encrypted content can later be decrypted (with
  * the corresponding algorithm using the correct decryption key) and
  * de-serialized, yielding the original object.
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java	Mon Aug 07 09:45:38 2017 -0700
@@ -55,13 +55,13 @@
 import java.util.NoSuchElementException;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 import java.util.stream.Stream;
 
 import jdk.internal.misc.VM;
 import jdk.internal.module.ModulePatcher.PatchedModuleReader;
-import jdk.internal.module.SystemModules;
 import jdk.internal.module.Resources;
 
 
@@ -139,7 +139,7 @@
 
     // maps package name to loaded module for modules in the boot layer
     private static final Map<String, LoadedModule> packageToModule
-        = new ConcurrentHashMap<>(SystemModules.PACKAGES_IN_BOOT_LAYER);
+        = new ConcurrentHashMap<>(1024);
 
     // maps a module name to a module reference
     private final Map<String, ModuleReference> nameToModule;
@@ -946,9 +946,16 @@
         URL url = cs.getLocation();
         if (url == null)
             return perms;
-        Permission p = null;
+
+        // avoid opening connection when URL is to resource in run-time image
+        if (url.getProtocol().equals("jrt")) {
+            perms.add(new RuntimePermission("accessSystemModules"));
+            return perms;
+        }
+
+        // open connection to determine the permission needed
         try {
-            p = url.openConnection().getPermission();
+            Permission p = url.openConnection().getPermission();
             if (p != null) {
                 // for directories then need recursive access
                 if (p instanceof FilePermission) {
@@ -969,23 +976,26 @@
     // -- miscellaneous supporting methods
 
     /**
-     * Returns the ModuleReader for the given module.
+     * Returns the ModuleReader for the given module, creating it if needed
      */
     private ModuleReader moduleReaderFor(ModuleReference mref) {
-        return moduleToReader.computeIfAbsent(mref, BuiltinClassLoader::createModuleReader);
-    }
-
-    /**
-     * Creates a ModuleReader for the given module.
-     */
-    private static ModuleReader createModuleReader(ModuleReference mref) {
-        try {
-            return mref.open();
-        } catch (IOException e) {
-            // Return a null module reader to avoid a future class load
-            // attempting to open the module again.
-            return new NullModuleReader();
+        ModuleReader reader = moduleToReader.get(mref);
+        if (reader == null) {
+            // avoid method reference during startup
+            Function<ModuleReference, ModuleReader> create = new Function<>() {
+                public ModuleReader apply(ModuleReference moduleReference) {
+                    try {
+                        return mref.open();
+                    } catch (IOException e) {
+                        // Return a null module reader to avoid a future class
+                        // load attempting to open the module again.
+                        return new NullModuleReader();
+                    }
+                }
+            };
+            reader = moduleToReader.computeIfAbsent(mref, create);
         }
+        return reader;
     }
 
     /**
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java	Mon Aug 07 09:45:38 2017 -0700
@@ -25,7 +25,6 @@
 
 package jdk.internal.loader;
 
-import java.io.File;
 import java.io.IOException;
 import java.net.URL;
 import java.nio.file.InvalidPathException;
@@ -38,7 +37,6 @@
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.VM;
 
-
 /**
  * Creates and provides access to the built-in platform and application class
  * loaders. It also creates the class loader that is used to locate resources
@@ -61,23 +59,30 @@
      */
     static {
 
-        // -Xbootclasspth/a or -javaagent Boot-Class-Path
+        // -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute
         URLClassPath bcp = null;
         String s = VM.getSavedProperty("jdk.boot.class.path.append");
         if (s != null && s.length() > 0)
-            bcp = toURLClassPath(s);
+            bcp = new URLClassPath(s, true);
 
         // we have a class path if -cp is specified or -m is not specified.
         // If neither is specified then default to -cp <working directory>
         // If -cp is not specified and -m is specified, the value of
         // java.class.path is an empty string, then no class path.
-        URLClassPath ucp = new URLClassPath(new URL[0]);
         String mainMid = System.getProperty("jdk.module.main");
         String cp = System.getProperty("java.class.path");
-        if (cp == null)
-            cp = "";
-        if (mainMid == null || cp.length() > 0)
-            addClassPathToUCP(cp, ucp);
+        if (mainMid == null) {
+            // no main module specified so class path required
+            if (cp == null) {
+                cp = "";
+            }
+        } else {
+            // main module specified, ignore empty class path
+            if (cp != null && cp.length() == 0) {
+                cp = null;
+            }
+        }
+        URLClassPath ucp = new URLClassPath(cp, false);
 
         // create the class loaders
         BOOT_LOADER = new BootClassLoader(bcp);
@@ -198,7 +203,7 @@
          * @see java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch
          */
         void appendToClassPathForInstrumentation(String path) {
-            addClassPathToUCP(path, ucp);
+            ucp.addFile(path);
         }
 
         /**
@@ -220,40 +225,11 @@
     }
 
     /**
-     * Returns a {@code URLClassPath} of file URLs to each of the elements in
-     * the given class path.
-     */
-    private static URLClassPath toURLClassPath(String cp) {
-        URLClassPath ucp = new URLClassPath(new URL[0]);
-        addClassPathToUCP(cp, ucp);
-        return ucp;
-    }
-
-    /**
-     * Converts the elements in the given class path to file URLs and adds
-     * them to the given URLClassPath.
-     */
-    private static void addClassPathToUCP(String cp, URLClassPath ucp) {
-        int off = 0;
-        int next;
-        while ((next = cp.indexOf(File.pathSeparator, off)) != -1) {
-            URL url = toFileURL(cp.substring(off, next));
-            if (url != null)
-                ucp.addURL(url);
-            off = next + 1;
-        }
-
-        // remaining
-        URL url = toFileURL(cp.substring(off));
-        if (url != null)
-            ucp.addURL(url);
-    }
-
-    /**
      * Attempts to convert the given string to a file URL.
      *
      * @apiNote This is called by the VM
      */
+    @Deprecated
     private static URL toFileURL(String s) {
         try {
             // Use an intermediate File object to construct a URI/URL without
@@ -265,5 +241,4 @@
             return null;
         }
     }
-
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Mon Aug 07 09:45:38 2017 -0700
@@ -46,6 +46,7 @@
 import java.security.PrivilegedExceptionAction;
 import java.security.cert.Certificate;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -66,7 +67,6 @@
 import java.util.zip.ZipFile;
 
 import jdk.internal.misc.JavaNetURLAccess;
-import jdk.internal.misc.JavaNetURLClassLoaderAccess;
 import jdk.internal.misc.JavaUtilZipFileAccess;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.util.jar.InvalidJarIndexError;
@@ -100,19 +100,19 @@
     }
 
     /* The original search path of URLs. */
-    private ArrayList<URL> path = new ArrayList<>();
+    private final List<URL> path;
 
     /* The stack of unopened URLs */
-    Stack<URL> urls = new Stack<>();
+    private final Stack<URL> urls = new Stack<>();
 
     /* The resulting search path of Loaders */
-    ArrayList<Loader> loaders = new ArrayList<>();
+    private final ArrayList<Loader> loaders = new ArrayList<>();
 
     /* Map of each URL opened to its corresponding Loader */
-    HashMap<String, Loader> lmap = new HashMap<>();
+    private final HashMap<String, Loader> lmap = new HashMap<>();
 
     /* The jar protocol handler to use when creating new URLs */
-    private URLStreamHandler jarHandler;
+    private final URLStreamHandler jarHandler;
 
     /* Whether this URLClassLoader has been closed yet */
     private boolean closed = false;
@@ -137,12 +137,16 @@
     public URLClassPath(URL[] urls,
                         URLStreamHandlerFactory factory,
                         AccessControlContext acc) {
-        for (int i = 0; i < urls.length; i++) {
-            path.add(urls[i]);
+        List<URL> path = new ArrayList<>(urls.length);
+        for (URL url : urls) {
+            path.add(url);
         }
+        this.path = path;
         push(urls);
         if (factory != null) {
             jarHandler = factory.createURLStreamHandler("jar");
+        } else {
+            jarHandler = null;
         }
         if (DISABLE_ACC_CHECKING)
             this.acc = null;
@@ -150,16 +154,50 @@
             this.acc = acc;
     }
 
-    /**
-     * Constructs a URLClassPath with no additional security restrictions.
-     * Used by code that implements the class path.
-     */
-    public URLClassPath(URL[] urls) {
-        this(urls, null, null);
+    public URLClassPath(URL[] urls, AccessControlContext acc) {
+        this(urls, null, acc);
     }
 
-    public URLClassPath(URL[] urls, AccessControlContext acc) {
-        this(urls, null, acc);
+    /**
+     * Constructs a URLClassPath from a class path string.
+     *
+     * @param cp the class path string
+     * @param skipEmptyElements indicates if empty elements are ignored or
+     *        treated as the current working directory
+     *
+     * @apiNote Used to create the application class path.
+     */
+    URLClassPath(String cp, boolean skipEmptyElements) {
+        List<URL> path = new ArrayList<>();
+        if (cp != null) {
+            // map each element of class path to a file URL
+            int off = 0;
+            int next;
+            while ((next = cp.indexOf(File.pathSeparator, off)) != -1) {
+                String element = cp.substring(off, next);
+                if (element.length() > 0 || !skipEmptyElements) {
+                    URL url = toFileURL(element);
+                    if (url != null) path.add(url);
+                }
+                off = next + 1;
+            }
+
+            // remaining element
+            String element = cp.substring(off);
+            if (element.length() > 0 || !skipEmptyElements) {
+                URL url = toFileURL(element);
+                if (url != null) path.add(url);
+            }
+
+            // push the URLs
+            for (int i = path.size() - 1; i >= 0; --i) {
+                urls.push(path.get(i));
+            }
+        }
+
+        this.path = path;
+        this.jarHandler = null;
+        this.acc = null;
     }
 
     public synchronized List<IOException> closeLoaders() {
@@ -198,6 +236,28 @@
     }
 
     /**
+     * Appends the specified file path as a file URL to the search path.
+     */
+    public void addFile(String s) {
+        URL url = toFileURL(s);
+        if (url != null) {
+            addURL(url);
+        }
+    }
+
+    /**
+     * Returns a file URL for the given file path.
+     */
+    private static URL toFileURL(String s) {
+        try {
+            File f = new File(s).getCanonicalFile();
+            return ParseUtil.fileToEncodedURL(f);
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
      * Returns the original search path of URLs.
      */
     public URL[] getURLs() {
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java	Mon Aug 07 09:45:38 2017 -0700
@@ -25,6 +25,8 @@
 
 package jdk.internal.logger;
 
+import jdk.internal.misc.VM;
+
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
 import java.util.HashMap;
@@ -140,15 +142,9 @@
         return AccessController.doPrivileged(new PrivilegedAction<>() {
             @Override
             public Boolean run() {
-                final ClassLoader moduleCL = m.getClassLoader();
-                if (moduleCL == null) return true;
-                ClassLoader cl = ClassLoader.getPlatformClassLoader();
-                while (cl != null && moduleCL != cl) {
-                    cl = cl.getParent();
-                }
                 // returns true if moduleCL is the platform class loader
                 // or one of its ancestors.
-                return moduleCL == cl;
+                return VM.isSystemDomainLoader(m.getClassLoader());
             }
         });
     }
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java	Mon Aug 07 09:45:38 2017 -0700
@@ -34,16 +34,10 @@
 import java.lang.module.ModuleDescriptor.Provides;
 import java.lang.module.ModuleDescriptor.Version;
 import java.lang.module.ModuleFinder;
-import java.lang.module.ModuleReader;
-import java.lang.module.ModuleReference;
-import java.net.URI;
-import java.nio.file.Path;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
-import java.util.function.Supplier;
-
-import jdk.internal.module.ModuleHashes;
 
 /**
  * Provides access to non-public methods in java.lang.module.
@@ -131,12 +125,16 @@
 
     /**
      * Resolves a collection of root modules, with service binding
-     * and the empty configuration as the parent. The post resolution
-     * checks are optionally run.
+     * and the empty configuration as the parent.
      */
     Configuration resolveAndBind(ModuleFinder finder,
                                  Collection<String> roots,
-                                 boolean check,
                                  PrintStream traceOutput);
 
+    /**
+     * Creates a configuration from a pre-generated readability graph.
+     */
+    Configuration newConfiguration(ModuleFinder finder,
+                                   Map<String, Set<String>> graph);
+
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java	Mon Aug 07 09:45:38 2017 -0700
@@ -124,11 +124,11 @@
     }
 
     /**
-     * Returns true if the given class loader is in the system domain
-     * in which all permissions are granted.
+     * Returns true if the given class loader is the bootstrap class loader
+     * or the platform class loader.
      */
     public static boolean isSystemDomainLoader(ClassLoader loader) {
-        return loader == null;
+        return loader == null || loader == ClassLoader.getPlatformClassLoader();
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/DefaultRoots.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.internal.module;
+
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Defines methods to compute the default set of root modules for the unnamed
+ * module.
+ */
+
+public final class DefaultRoots {
+    private static final String JAVA_SE = "java.se";
+
+    private DefaultRoots() { }
+
+    /**
+     * Returns the default set of root modules for the unnamed module computed from
+     * the system modules observable with the given module finder.
+     */
+    static Set<String> compute(ModuleFinder systemModuleFinder, ModuleFinder finder) {
+        Set<String> roots = new HashSet<>();
+
+        boolean hasJava = false;
+        if (systemModuleFinder.find(JAVA_SE).isPresent()) {
+            if (finder == systemModuleFinder || finder.find(JAVA_SE).isPresent()) {
+                // java.se is a system module
+                hasJava = true;
+                roots.add(JAVA_SE);
+            }
+        }
+
+        for (ModuleReference mref : systemModuleFinder.findAll()) {
+            String mn = mref.descriptor().name();
+            if (hasJava && mn.startsWith("java.")) {
+                // not a root
+                continue;
+            }
+
+            if (ModuleResolution.doNotResolveByDefault(mref)) {
+                // not a root
+                continue;
+            }
+
+            if ((finder == systemModuleFinder || finder.find(mn).isPresent())) {
+                // add as root if exports at least one package to all modules
+                ModuleDescriptor descriptor = mref.descriptor();
+                for (ModuleDescriptor.Exports e : descriptor.exports()) {
+                    if (!e.isQualified()) {
+                        roots.add(mn);
+                        break;
+                    }
+                }
+            }
+        }
+
+        return roots;
+    }
+
+    /**
+     * Returns the default set of root modules for the unnamed module from the
+     * modules observable with the given module finder.
+     */
+    public static Set<String> compute(ModuleFinder finder) {
+        return compute(finder, finder);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ExplodedSystemModules.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.internal.module;
+
+import java.lang.module.ModuleDescriptor;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A dummy SystemModules for use with exploded builds or testing.
+ */
+
+class ExplodedSystemModules implements SystemModules {
+    @Override
+    public boolean hasSplitPackages() {
+        return true;  // not known
+    }
+
+    @Override
+    public boolean hasIncubatorModules() {
+        return true;  // not known
+    }
+
+    @Override
+    public ModuleDescriptor[] moduleDescriptors() {
+        throw new InternalError();
+    }
+
+    @Override
+    public ModuleTarget[] moduleTargets() {
+        throw new InternalError();
+    }
+
+    @Override
+    public ModuleHashes[] moduleHashes() {
+        throw new InternalError();
+    }
+
+    @Override
+    public ModuleResolution[] moduleResolutions() {
+        throw new InternalError();
+    }
+
+    @Override
+    public Map<String, Set<String>> moduleReads() {
+        throw new InternalError();
+    }
+
+    @Override
+    public  Map<String, Set<String>> concealedPackagesToOpen() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public  Map<String, Set<String>> exportedPackagesToOpen() {
+        return Collections.emptyMap();
+    }
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Mon Aug 07 09:45:38 2017 -0700
@@ -40,16 +40,20 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 
 import jdk.internal.loader.BootLoader;
 import jdk.internal.loader.BuiltinClassLoader;
 import jdk.internal.misc.JavaLangAccess;
+import jdk.internal.misc.JavaLangModuleAccess;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.perf.PerfCounter;
 
@@ -70,8 +74,6 @@
 
     private static final String JAVA_BASE = "java.base";
 
-    private static final String JAVA_SE = "java.se";
-
     // the token for "all default modules"
     private static final String ALL_DEFAULT = "ALL-DEFAULT";
 
@@ -84,13 +86,13 @@
     // the token for "all modules on the module path"
     private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
 
+    // access to java.lang/module
+    private static final JavaLangModuleAccess JLMA
+        = SharedSecrets.getJavaLangModuleAccess();
+
     // The ModulePatcher for the initial configuration
     private static final ModulePatcher patcher = initModulePatcher();
 
-    // ModuleFinders for the initial configuration
-    private static ModuleFinder unlimitedFinder;
-    private static ModuleFinder limitedFinder;
-
     /**
      * Returns the ModulePatcher for the initial configuration.
      */
@@ -98,21 +100,38 @@
         return patcher;
     }
 
+    // ModuleFinders for the initial configuration
+    private static volatile ModuleFinder unlimitedFinder;
+    private static volatile ModuleFinder limitedFinder;
+
     /**
-     * Returns the ModuleFinder for the initial configuration before observability
-     * is limited by the --limit-modules command line option.
+     * Returns the ModuleFinder for the initial configuration before
+     * observability is limited by the --limit-modules command line option.
+     *
+     * @apiNote Used to support locating modules {@code java.instrument} and
+     * {@code jdk.management.agent} modules when they are loaded dynamically.
      */
     public static ModuleFinder unlimitedFinder() {
-        assert unlimitedFinder != null;
-        return unlimitedFinder;
+        ModuleFinder finder = unlimitedFinder;
+        if (finder == null) {
+            return ModuleFinder.ofSystem();
+        } else {
+            return finder;
+        }
     }
 
     /**
      * Returns the ModuleFinder for the initial configuration.
+     *
+     * @apiNote Used to support "{@code java --list-modules}".
      */
     public static ModuleFinder limitedFinder() {
-        assert limitedFinder != null;
-        return limitedFinder;
+        ModuleFinder finder = limitedFinder;
+        if (finder == null) {
+            return unlimitedFinder();
+        } else {
+            return finder;
+        }
     }
 
     /**
@@ -120,13 +139,60 @@
      *
      * @see java.lang.System#initPhase2()
      */
-    public static ModuleLayer boot() {
+    public static ModuleLayer boot() throws Exception {
+
+        // Step 0: Command line options
+
+        long t0 = System.nanoTime();
+
+        ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
+        ModuleFinder appModulePath = finderFor("jdk.module.path");
+        boolean isPatched = patcher.hasPatches();
 
-        // Step 1: Locate system modules (may be patched)
+        String mainModule = System.getProperty("jdk.module.main");
+        Set<String> addModules = addModules();
+        Set<String> limitModules = limitModules();
+
+        PrintStream traceOutput = null;
+        String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
+        if (trace != null && Boolean.parseBoolean(trace))
+            traceOutput = System.out;
+
+
+        // Step 1: The observable system modules, either all system modules
+        // or the system modules pre-generated for the initial module (the
+        // initial module may be the unnamed module). If the system modules
+        // are pre-generated for the initial module then resolution can be
+        // skipped.
 
         long t1 = System.nanoTime();
-        ModuleFinder systemModules = ModuleFinder.ofSystem();
-        PerfCounters.systemModulesTime.addElapsedTimeFrom(t1);
+
+        SystemModules systemModules = null;
+        ModuleFinder systemModuleFinder;
+
+        boolean haveModulePath = (appModulePath != null || upgradeModulePath != null);
+        boolean needResolution = true;
+
+        if (!haveModulePath && addModules.isEmpty() && limitModules.isEmpty()) {
+            systemModules = SystemModuleFinders.systemModules(mainModule);
+            if (systemModules != null && !isPatched && (traceOutput == null)) {
+                needResolution = false;
+            }
+        }
+        if (systemModules == null) {
+            // all system modules are observable
+            systemModules = SystemModuleFinders.allSystemModules();
+        }
+        if (systemModules != null) {
+            // images build
+            systemModuleFinder = SystemModuleFinders.of(systemModules);
+        } else {
+            // exploded build or testing
+            systemModules = new ExplodedSystemModules();
+            systemModuleFinder = SystemModuleFinders.ofSystem();
+        }
+
+        Counters.add("jdk.module.boot.1.systemModulesTime", t1);
 
 
         // Step 2: Define and load java.base. This patches all classes loaded
@@ -136,7 +202,7 @@
 
         long t2 = System.nanoTime();
 
-        ModuleReference base = systemModules.find(JAVA_BASE).orElse(null);
+        ModuleReference base = systemModuleFinder.find(JAVA_BASE).orElse(null);
         if (base == null)
             throw new InternalError(JAVA_BASE + " not found");
         URI baseUri = base.location().orElse(null);
@@ -145,171 +211,138 @@
         BootLoader.loadModule(base);
         Modules.defineModule(null, base.descriptor(), baseUri);
 
-        PerfCounters.defineBaseTime.addElapsedTimeFrom(t2);
+        Counters.add("jdk.module.boot.2.defineBaseTime", t2);
 
 
         // Step 2a: If --validate-modules is specified then the VM needs to
         // start with only java.base, all other options are ignored.
 
-        String propValue = getAndRemoveProperty("jdk.module.minimumBoot");
-        if (propValue != null) {
+        if (getAndRemoveProperty("jdk.module.minimumBoot") != null) {
             return createMinimalBootLayer();
         }
 
 
-        // Step 3: Construct the module path and the set of root modules to
-        // resolve. If --limit-modules is specified then it limits the set
-        // modules that are observable.
+        // Step 3: If resolution is needed then create the module finder and
+        // the set of root modules to resolve.
 
         long t3 = System.nanoTime();
 
-        // --upgrade-module-path option specified to launcher
-        ModuleFinder upgradeModulePath
-            = createModulePathFinder("jdk.module.upgrade.path");
-        if (upgradeModulePath != null)
-            systemModules = ModuleFinder.compose(upgradeModulePath, systemModules);
+        ModuleFinder savedModuleFinder = null;
+        ModuleFinder finder;
+        Set<String> roots;
+        if (needResolution) {
 
-        // --module-path option specified to the launcher
-        ModuleFinder appModulePath = createModulePathFinder("jdk.module.path");
+            // upgraded modules override the modules in the run-time image
+            if (upgradeModulePath != null)
+                systemModuleFinder = ModuleFinder.compose(upgradeModulePath,
+                                                          systemModuleFinder);
 
-        // The module finder: [--upgrade-module-path] system [--module-path]
-        ModuleFinder finder = systemModules;
-        if (appModulePath != null)
-            finder = ModuleFinder.compose(finder, appModulePath);
+            // The module finder: [--upgrade-module-path] system [--module-path]
+            if (appModulePath != null) {
+                finder = ModuleFinder.compose(systemModuleFinder, appModulePath);
+            } else {
+                finder = systemModuleFinder;
+            }
 
-        // The root modules to resolve
-        Set<String> roots = new HashSet<>();
-
-        // launcher -m option to specify the main/initial module
-        String mainModule = System.getProperty("jdk.module.main");
-        if (mainModule != null)
-            roots.add(mainModule);
+            // The root modules to resolve
+            roots = new HashSet<>();
 
-        // additional module(s) specified by --add-modules
-        boolean addAllDefaultModules = false;
-        boolean addAllSystemModules = false;
-        boolean addAllApplicationModules = false;
-        for (String mod: getExtraAddModules()) {
-            switch (mod) {
-                case ALL_DEFAULT:
-                    addAllDefaultModules = true;
-                    break;
-                case ALL_SYSTEM:
-                    addAllSystemModules = true;
-                    break;
-                case ALL_MODULE_PATH:
-                    addAllApplicationModules = true;
-                    break;
-                default :
-                    roots.add(mod);
-            }
-        }
+            // launcher -m option to specify the main/initial module
+            if (mainModule != null)
+                roots.add(mainModule);
 
-        // --limit-modules
-        unlimitedFinder = finder;
-        propValue = getAndRemoveProperty("jdk.module.limitmods");
-        if (propValue != null) {
-            Set<String> mods = new HashSet<>();
-            for (String mod: propValue.split(",")) {
-                mods.add(mod);
-            }
-            finder = limitFinder(finder, mods, roots);
-        }
-        limitedFinder = finder;
-
-        // If there is no initial module specified then assume that the initial
-        // module is the unnamed module of the application class loader. This
-        // is implemented by resolving "java.se" and all (non-java.*) modules
-        // that export an API. If "java.se" is not observable then all java.*
-        // modules are resolved. Modules that have the DO_NOT_RESOLVE_BY_DEFAULT
-        // bit set in their ModuleResolution attribute flags are excluded from
-        // the default set of roots.
-        if (mainModule == null || addAllDefaultModules) {
-            boolean hasJava = false;
-            if (systemModules.find(JAVA_SE).isPresent()) {
-                // java.se is a system module
-                if (finder == systemModules || finder.find(JAVA_SE).isPresent()) {
-                    // java.se is observable
-                    hasJava = true;
-                    roots.add(JAVA_SE);
+            // additional module(s) specified by --add-modules
+            boolean addAllDefaultModules = false;
+            boolean addAllSystemModules = false;
+            boolean addAllApplicationModules = false;
+            for (String mod : addModules) {
+                switch (mod) {
+                    case ALL_DEFAULT:
+                        addAllDefaultModules = true;
+                        break;
+                    case ALL_SYSTEM:
+                        addAllSystemModules = true;
+                        break;
+                    case ALL_MODULE_PATH:
+                        addAllApplicationModules = true;
+                        break;
+                    default:
+                        roots.add(mod);
                 }
             }
 
-            for (ModuleReference mref : systemModules.findAll()) {
-                String mn = mref.descriptor().name();
-                if (hasJava && mn.startsWith("java."))
-                    continue;
+            // --limit-modules
+            savedModuleFinder = finder;
+            if (!limitModules.isEmpty()) {
+                finder = limitFinder(finder, limitModules, roots);
+            }
 
-                if (ModuleResolution.doNotResolveByDefault(mref))
-                    continue;
+            // If there is no initial module specified then assume that the initial
+            // module is the unnamed module of the application class loader. This
+            // is implemented by resolving "java.se" and all (non-java.*) modules
+            // that export an API. If "java.se" is not observable then all java.*
+            // modules are resolved. Modules that have the DO_NOT_RESOLVE_BY_DEFAULT
+            // bit set in their ModuleResolution attribute flags are excluded from
+            // the default set of roots.
+            if (mainModule == null || addAllDefaultModules) {
+                roots.addAll(DefaultRoots.compute(systemModuleFinder, finder));
+            }
 
-                // add as root if observable and exports at least one package
-                if ((finder == systemModules || finder.find(mn).isPresent())) {
-                    ModuleDescriptor descriptor = mref.descriptor();
-                    for (ModuleDescriptor.Exports e : descriptor.exports()) {
-                        if (!e.isQualified()) {
-                            roots.add(mn);
-                            break;
-                        }
-                    }
-                }
+            // If `--add-modules ALL-SYSTEM` is specified then all observable system
+            // modules will be resolved.
+            if (addAllSystemModules) {
+                ModuleFinder f = finder;  // observable modules
+                systemModuleFinder.findAll()
+                    .stream()
+                    .map(ModuleReference::descriptor)
+                    .map(ModuleDescriptor::name)
+                    .filter(mn -> f.find(mn).isPresent())  // observable
+                    .forEach(mn -> roots.add(mn));
             }
+
+            // If `--add-modules ALL-MODULE-PATH` is specified then all observable
+            // modules on the application module path will be resolved.
+            if (appModulePath != null && addAllApplicationModules) {
+                ModuleFinder f = finder;  // observable modules
+                appModulePath.findAll()
+                    .stream()
+                    .map(ModuleReference::descriptor)
+                    .map(ModuleDescriptor::name)
+                    .filter(mn -> f.find(mn).isPresent())  // observable
+                    .forEach(mn -> roots.add(mn));
+            }
+        } else {
+            // no resolution case
+            finder = systemModuleFinder;
+            roots = null;
         }
 
-        // If `--add-modules ALL-SYSTEM` is specified then all observable system
-        // modules will be resolved.
-        if (addAllSystemModules) {
-            ModuleFinder f = finder;  // observable modules
-            systemModules.findAll()
-                .stream()
-                .map(ModuleReference::descriptor)
-                .map(ModuleDescriptor::name)
-                .filter(mn -> f.find(mn).isPresent())  // observable
-                .forEach(mn -> roots.add(mn));
-        }
-
-        // If `--add-modules ALL-MODULE-PATH` is specified then all observable
-        // modules on the application module path will be resolved.
-        if (appModulePath != null && addAllApplicationModules) {
-            ModuleFinder f = finder;  // observable modules
-            appModulePath.findAll()
-                .stream()
-                .map(ModuleReference::descriptor)
-                .map(ModuleDescriptor::name)
-                .filter(mn -> f.find(mn).isPresent())  // observable
-                .forEach(mn -> roots.add(mn));
-        }
-
-        PerfCounters.optionsAndRootsTime.addElapsedTimeFrom(t3);
-
+        Counters.add("jdk.module.boot.3.optionsAndRootsTime", t3);
 
         // Step 4: Resolve the root modules, with service binding, to create
-        // the configuration for the boot layer.
+        // the configuration for the boot layer. If resolution is not needed
+        // then create the configuration for the boot layer from the
+        // readability graph created at link time.
 
         long t4 = System.nanoTime();
 
-        // determine if post resolution checks are needed
-        boolean needPostResolutionChecks = true;
-        if (baseUri.getScheme().equals("jrt")   // toLowerCase not needed here
-                && (upgradeModulePath == null)
-                && (appModulePath == null)
-                && (patcher.isEmpty())) {
-            needPostResolutionChecks = false;
+        Configuration cf;
+        if (needResolution) {
+            cf = JLMA.resolveAndBind(finder, roots, traceOutput);
+        } else {
+            Map<String, Set<String>> map = systemModules.moduleReads();
+            cf = JLMA.newConfiguration(systemModuleFinder, map);
         }
 
-        PrintStream traceOutput = null;
-        propValue = getAndRemoveProperty("jdk.module.showModuleResolution");
-        if (propValue != null && Boolean.parseBoolean(propValue))
-            traceOutput = System.out;
+        // check that modules specified to --patch-module are resolved
+        if (isPatched) {
+            patcher.patchedModules()
+                    .stream()
+                    .filter(mn -> !cf.findModule(mn).isPresent())
+                    .forEach(mn -> warnUnknownModule(PATCH_MODULE, mn));
+        }
 
-        // run the resolver to create the configuration
-        Configuration cf = SharedSecrets.getJavaLangModuleAccess()
-                .resolveAndBind(finder,
-                                roots,
-                                needPostResolutionChecks,
-                                traceOutput);
-
-        PerfCounters.resolveTime.addElapsedTimeFrom(t4);
+        Counters.add("jdk.module.boot.4.resolveTime", t4);
 
 
         // Step 5: Map the modules in the configuration to class loaders.
@@ -326,7 +359,7 @@
 
         // check that all modules to be mapped to the boot loader will be
         // loaded from the runtime image
-        if (needPostResolutionChecks) {
+        if (haveModulePath) {
             for (ResolvedModule resolvedModule : cf.modules()) {
                 ModuleReference mref = resolvedModule.reference();
                 String name = mref.descriptor().name();
@@ -335,51 +368,54 @@
                     if (upgradeModulePath != null
                             && upgradeModulePath.find(name).isPresent())
                         fail(name + ": cannot be loaded from upgrade module path");
-                    if (!systemModules.find(name).isPresent())
+                    if (!systemModuleFinder.find(name).isPresent())
                         fail(name + ": cannot be loaded from application module path");
                 }
             }
-
-            // check if module specified in --patch-module is present
-            for (String mn: patcher.patchedModules()) {
-                if (!cf.findModule(mn).isPresent()) {
-                    warnUnknownModule(PATCH_MODULE, mn);
-                }
-            }
         }
 
         // check for split packages in the modules mapped to the built-in loaders
-        if (SystemModules.hasSplitPackages() || needPostResolutionChecks) {
+        if (systemModules.hasSplitPackages() || isPatched || haveModulePath) {
             checkSplitPackages(cf, clf);
         }
 
         // load/register the modules with the built-in class loaders
         loadModules(cf, clf);
 
-        PerfCounters.loadModulesTime.addElapsedTimeFrom(t5);
+        Counters.add("jdk.module.boot.5.loadModulesTime", t5);
 
 
         // Step 6: Define all modules to the VM
 
         long t6 = System.nanoTime();
         ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
-        PerfCounters.layerCreateTime.addElapsedTimeFrom(t6);
+        Counters.add("jdk.module.boot.6.layerCreateTime", t6);
 
 
         // Step 7: Miscellaneous
 
         // check incubating status
-        checkIncubatingStatus(cf);
+        if (systemModules.hasIncubatorModules() || haveModulePath) {
+            checkIncubatingStatus(cf);
+        }
 
-        // --add-reads, --add-exports/--add-opens, and -illegal-access
+        // --add-reads, --add-exports/--add-opens, and --illegal-access
         long t7 = System.nanoTime();
         addExtraReads(bootLayer);
         boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
-        addIllegalAccess(bootLayer, upgradeModulePath, extraExportsOrOpens);
-        PerfCounters.adjustModulesTime.addElapsedTimeFrom(t7);
+        addIllegalAccess(upgradeModulePath, systemModules, bootLayer, extraExportsOrOpens);
+        Counters.add("jdk.module.boot.7.adjustModulesTime", t7);
+
+        // save module finders for later use
+        if (savedModuleFinder != null) {
+            unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
+            if (savedModuleFinder != finder)
+                limitedFinder = new SafeModuleFinder(finder);
+        }
 
         // total time to initialize
-        PerfCounters.bootstrapTime.addElapsedTimeFrom(t1);
+        Counters.add("jdk.module.boot.totalTime", t0);
+        Counters.publish();
 
         return bootLayer;
     }
@@ -391,7 +427,6 @@
         Configuration cf = SharedSecrets.getJavaLangModuleAccess()
             .resolveAndBind(ModuleFinder.ofSystem(),
                             Set.of(JAVA_BASE),
-                            false,
                             null);
 
         Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
@@ -439,7 +474,6 @@
                     }
                 }
             }
-
         }
     }
 
@@ -489,7 +523,7 @@
      * Creates a finder from the module path that is the value of the given
      * system property and optionally patched by --patch-module
      */
-    private static ModuleFinder createModulePathFinder(String prop) {
+    private static ModuleFinder finderFor(String prop) {
         String s = System.getProperty(prop);
         if (s == null) {
             return null;
@@ -510,35 +544,48 @@
      */
     private static ModulePatcher initModulePatcher() {
         Map<String, List<String>> map = decode("jdk.module.patch.",
-                File.pathSeparator,
-                false);
+                                               File.pathSeparator,
+                                               false);
         return new ModulePatcher(map);
     }
 
     /**
-     * Returns the set of module names specified via --add-modules options
-     * on the command line
+     * Returns the set of module names specified by --add-module options.
      */
-    private static Set<String> getExtraAddModules() {
+    private static Set<String> addModules() {
         String prefix = "jdk.module.addmods.";
         int index = 0;
-
         // the system property is removed after decoding
         String value = getAndRemoveProperty(prefix + index);
         if (value == null) {
             return Collections.emptySet();
+        } else {
+            Set<String> modules = new HashSet<>();
+            while (value != null) {
+                for (String s : value.split(",")) {
+                    if (s.length() > 0) modules.add(s);
+                }
+                index++;
+                value = getAndRemoveProperty(prefix + index);
+            }
+            return modules;
         }
+    }
 
-        Set<String> modules = new HashSet<>();
-        while (value != null) {
-            for (String s : value.split(",")) {
-                if (s.length() > 0) modules.add(s);
+    /**
+     * Returns the set of module names specified by --limit-modules.
+     */
+    private static Set<String> limitModules() {
+        String value = getAndRemoveProperty("jdk.module.limitmods");
+        if (value == null) {
+            return Collections.emptySet();
+        } else {
+            Set<String> names = new HashSet<>();
+            for (String name : value.split(",")) {
+                if (name.length() > 0) names.add(name);
             }
-            index++;
-            value = getAndRemoveProperty(prefix + index);
+            return names;
         }
-
-        return modules;
     }
 
     /**
@@ -676,8 +723,9 @@
      * Process the --illegal-access option (and its default) to open packages
      * of system modules in the boot layer to code in unnamed modules.
      */
-    private static void addIllegalAccess(ModuleLayer bootLayer,
-                                         ModuleFinder upgradeModulePath,
+    private static void addIllegalAccess(ModuleFinder upgradeModulePath,
+                                         SystemModules systemModules,
+                                         ModuleLayer bootLayer,
                                          boolean extraExportsOrOpens) {
         String value = getAndRemoveProperty("jdk.module.illegalAccess");
         IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
@@ -702,10 +750,10 @@
         IllegalAccessLogger.Builder builder
             = new IllegalAccessLogger.Builder(mode, System.err);
 
-        Map<String, Set<String>> map1 = SystemModules.concealedPackagesToOpen();
-        Map<String, Set<String>> map2 = SystemModules.exportedPackagesToOpen();
+        Map<String, Set<String>> map1 = systemModules.concealedPackagesToOpen();
+        Map<String, Set<String>> map2 = systemModules.exportedPackagesToOpen();
         if (map1.isEmpty() && map2.isEmpty()) {
-            // need to generate maps when on exploded build
+            // need to generate (exploded build)
             IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
             map1 = maps.concealedPackagesToOpen();
             map2 = maps.exportedPackagesToOpen();
@@ -906,6 +954,10 @@
         }
     }
 
+    /**
+     * Returns an iterator that yields all elements of the first iterator
+     * followed by all the elements of the second iterator.
+     */
     static <T> Iterator<T> concat(Iterator<T> iterator1, Iterator<T> iterator2) {
         return new Iterator<T>() {
             @Override
@@ -921,23 +973,76 @@
         };
     }
 
-    static class PerfCounters {
+    /**
+     * Wraps a (potentially not thread safe) ModuleFinder created during startup
+     * for use after startup.
+     */
+    static class SafeModuleFinder implements ModuleFinder {
+        private final Set<ModuleReference> mrefs;
+        private volatile Map<String, ModuleReference> nameToModule;
+
+        SafeModuleFinder(ModuleFinder finder) {
+            this.mrefs = Collections.unmodifiableSet(finder.findAll());
+        }
+        @Override
+        public Optional<ModuleReference> find(String name) {
+            Objects.requireNonNull(name);
+            Map<String, ModuleReference> nameToModule = this.nameToModule;
+            if (nameToModule == null) {
+                this.nameToModule = nameToModule = mrefs.stream()
+                        .collect(Collectors.toMap(m -> m.descriptor().name(),
+                                                  Function.identity()));
+            }
+            return Optional.ofNullable(nameToModule.get(name));
+        }
+        @Override
+        public Set<ModuleReference> findAll() {
+            return mrefs;
+        }
+    }
 
-        static PerfCounter systemModulesTime
-            = PerfCounter.newPerfCounter("jdk.module.bootstrap.systemModulesTime");
-        static PerfCounter defineBaseTime
-            = PerfCounter.newPerfCounter("jdk.module.bootstrap.defineBaseTime");
-        static PerfCounter optionsAndRootsTime
-            = PerfCounter.newPerfCounter("jdk.module.bootstrap.optionsAndRootsTime");
-        static PerfCounter resolveTime
-            = PerfCounter.newPerfCounter("jdk.module.bootstrap.resolveTime");
-        static PerfCounter layerCreateTime
-            = PerfCounter.newPerfCounter("jdk.module.bootstrap.layerCreateTime");
-        static PerfCounter loadModulesTime
-            = PerfCounter.newPerfCounter("jdk.module.bootstrap.loadModulesTime");
-        static PerfCounter adjustModulesTime
-            = PerfCounter.newPerfCounter("jdk.module.bootstrap.adjustModulesTime");
-        static PerfCounter bootstrapTime
-            = PerfCounter.newPerfCounter("jdk.module.bootstrap.totalTime");
+    /**
+     * Counters for startup performance analysis.
+     */
+    static class Counters {
+        private static final boolean PUBLISH_COUNTERS;
+        private static final boolean PRINT_COUNTERS;
+        private static Map<String, Long> counters;
+        static {
+            String s = System.getProperty("jdk.module.boot.usePerfData");
+            if (s == null) {
+                PUBLISH_COUNTERS = false;
+                PRINT_COUNTERS = false;
+            } else {
+                PUBLISH_COUNTERS = true;
+                PRINT_COUNTERS = s.equals("debug");
+                counters = new LinkedHashMap<>();  // preserve insert order
+            }
+        }
+
+        /**
+         * Add a counter
+         */
+        static void add(String name, long start) {
+            if (PUBLISH_COUNTERS || PRINT_COUNTERS) {
+                counters.put(name, (System.nanoTime() - start));
+            }
+        }
+
+        /**
+         * Publish the counters to the instrumentation buffer or stdout.
+         */
+        static void publish() {
+            if (PUBLISH_COUNTERS || PRINT_COUNTERS) {
+                for (Map.Entry<String, Long> e : counters.entrySet()) {
+                    String name = e.getKey();
+                    long value = e.getValue();
+                    if (PUBLISH_COUNTERS)
+                        PerfCounter.newPerfCounter(name).set(value);
+                    if (PRINT_COUNTERS)
+                        System.out.println(name + " = " + value);
+                }
+            }
+        }
     }
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java	Mon Aug 07 09:45:38 2017 -0700
@@ -200,10 +200,10 @@
     }
 
     /**
-     * Returns true is this module patcher has no patches.
+     * Returns true is this module patcher has patches.
      */
-    public boolean isEmpty() {
-        return map.isEmpty();
+    public boolean hasPatches() {
+        return !map.isEmpty();
     }
 
     /*
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java	Mon Aug 07 09:45:38 2017 -0700
@@ -68,14 +68,14 @@
     /**
      * Constructs a new instance of this class.
      */
-    ModuleReferenceImpl(ModuleDescriptor descriptor,
-                        URI location,
-                        Supplier<ModuleReader> readerSupplier,
-                        ModulePatcher patcher,
-                        ModuleTarget target,
-                        ModuleHashes recordedHashes,
-                        ModuleHashes.HashSupplier hasher,
-                        ModuleResolution moduleResolution)
+    public ModuleReferenceImpl(ModuleDescriptor descriptor,
+                               URI location,
+                               Supplier<ModuleReader> readerSupplier,
+                               ModulePatcher patcher,
+                               ModuleTarget target,
+                               ModuleHashes recordedHashes,
+                               ModuleHashes.HashSupplier hasher,
+                               ModuleResolution moduleResolution)
     {
         super(descriptor, Objects.requireNonNull(location));
         this.location = location;
--- a/jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java	Mon Aug 07 10:02:39 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,469 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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 jdk.internal.module;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UncheckedIOException;
-import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleFinder;
-import java.lang.module.ModuleReader;
-import java.lang.module.ModuleReference;
-import java.net.URI;
-import java.net.URLConnection;
-import java.nio.ByteBuffer;
-import java.util.ArrayDeque;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
-import jdk.internal.jimage.ImageLocation;
-import jdk.internal.jimage.ImageReader;
-import jdk.internal.jimage.ImageReaderFactory;
-import jdk.internal.misc.JavaNetUriAccess;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.module.ModuleHashes.HashSupplier;
-import jdk.internal.perf.PerfCounter;
-
-/**
- * A {@code ModuleFinder} that finds modules that are linked into the
- * run-time image.
- *
- * The modules linked into the run-time image are assumed to have the
- * Packages attribute.
- */
-
-public class SystemModuleFinder implements ModuleFinder {
-
-    private static final JavaNetUriAccess JNUA = SharedSecrets.getJavaNetUriAccess();
-
-    private static final PerfCounter initTime
-        = PerfCounter.newPerfCounter("jdk.module.finder.jimage.initTime");
-    private static final PerfCounter moduleCount
-        = PerfCounter.newPerfCounter("jdk.module.finder.jimage.modules");
-    private static final PerfCounter packageCount
-        = PerfCounter.newPerfCounter("jdk.module.finder.jimage.packages");
-    private static final PerfCounter exportsCount
-        = PerfCounter.newPerfCounter("jdk.module.finder.jimage.exports");
-
-    // singleton finder to find modules in the run-time images
-    private static final SystemModuleFinder INSTANCE;
-
-    public static SystemModuleFinder getInstance() {
-        return INSTANCE;
-    }
-
-    /**
-     * For now, the module references are created eagerly on the assumption
-     * that service binding will require all modules to be located.
-     */
-    static {
-        long t0 = System.nanoTime();
-
-        INSTANCE = new SystemModuleFinder();
-
-        initTime.addElapsedTimeFrom(t0);
-    }
-
-    /**
-     * Holder class for the ImageReader
-     */
-    private static class SystemImage {
-        static final ImageReader READER;
-        static {
-            long t0 = System.nanoTime();
-            READER = ImageReaderFactory.getImageReader();
-            initTime.addElapsedTimeFrom(t0);
-        }
-
-        static ImageReader reader() {
-            return READER;
-        }
-    }
-
-    private static boolean isFastPathSupported() {
-       return SystemModules.MODULE_NAMES.length > 0;
-    }
-
-    private static String[] moduleNames() {
-        if (isFastPathSupported())
-            // module names recorded at link time
-            return SystemModules.MODULE_NAMES;
-
-        // this happens when java.base is patched with java.base
-        // from an exploded image
-        return SystemImage.reader().getModuleNames();
-    }
-
-    // the set of modules in the run-time image
-    private final Set<ModuleReference> modules;
-
-    // maps module name to module reference
-    private final Map<String, ModuleReference> nameToModule;
-
-    // module name to hashes
-    private final Map<String, byte[]> hashes;
-
-    private SystemModuleFinder() {
-        String[] names = moduleNames();
-        int n = names.length;
-        moduleCount.add(n);
-
-        // fastpath is enabled by default.
-        // It can be disabled for troubleshooting purpose.
-        boolean disabled =
-            System.getProperty("jdk.system.module.finder.disabledFastPath") != null;
-
-        ModuleDescriptor[] descriptors;
-        ModuleTarget[] targets;
-        ModuleHashes[] recordedHashes;
-        ModuleResolution[] moduleResolutions;
-
-        // fast loading of ModuleDescriptor of system modules
-        if (isFastPathSupported() && !disabled) {
-            descriptors = SystemModules.descriptors();
-            targets = SystemModules.targets();
-            recordedHashes = SystemModules.hashes();
-            moduleResolutions = SystemModules.moduleResolutions();
-        } else {
-            // if fast loading of ModuleDescriptors is disabled
-            // fallback to read module-info.class
-            descriptors = new ModuleDescriptor[n];
-            targets = new ModuleTarget[n];
-            recordedHashes = new ModuleHashes[n];
-            moduleResolutions = new ModuleResolution[n];
-            ImageReader imageReader = SystemImage.reader();
-            for (int i = 0; i < names.length; i++) {
-                String mn = names[i];
-                ImageLocation loc = imageReader.findLocation(mn, "module-info.class");
-                ModuleInfo.Attributes attrs =
-                    ModuleInfo.read(imageReader.getResourceBuffer(loc), null);
-                descriptors[i] = attrs.descriptor();
-                targets[i] = attrs.target();
-                recordedHashes[i] = attrs.recordedHashes();
-                moduleResolutions[i] = attrs.moduleResolution();
-            }
-        }
-
-        Map<String, byte[]> hashes = null;
-        boolean secondSeen = false;
-        // record the hashes to build HashSupplier
-        for (ModuleHashes mh : recordedHashes) {
-            if (mh != null) {
-                // if only one module contain ModuleHashes, use it
-                if (hashes == null) {
-                    hashes = mh.hashes();
-                } else {
-                    if (!secondSeen) {
-                        hashes = new HashMap<>(hashes);
-                        secondSeen = true;
-                    }
-                    hashes.putAll(mh.hashes());
-                }
-            }
-        }
-        this.hashes = (hashes == null) ? Map.of() : hashes;
-
-        ModuleReference[] mods = new ModuleReference[n];
-
-        @SuppressWarnings(value = {"rawtypes", "unchecked"})
-        Entry<String, ModuleReference>[] map
-            = (Entry<String, ModuleReference>[])new Entry[n];
-
-        for (int i = 0; i < n; i++) {
-            ModuleDescriptor md = descriptors[i];
-
-            // create the ModuleReference
-            ModuleReference mref = toModuleReference(md,
-                                                     targets[i],
-                                                     recordedHashes[i],
-                                                     hashSupplier(names[i]),
-                                                     moduleResolutions[i]);
-            mods[i] = mref;
-            map[i] = Map.entry(names[i], mref);
-
-            // counters
-            packageCount.add(md.packages().size());
-            exportsCount.add(md.exports().size());
-        }
-
-        modules = Set.of(mods);
-        nameToModule = Map.ofEntries(map);
-    }
-
-    @Override
-    public Optional<ModuleReference> find(String name) {
-        Objects.requireNonNull(name);
-        return Optional.ofNullable(nameToModule.get(name));
-    }
-
-    @Override
-    public Set<ModuleReference> findAll() {
-        return modules;
-    }
-
-    private ModuleReference toModuleReference(ModuleDescriptor md,
-                                              ModuleTarget target,
-                                              ModuleHashes recordedHashes,
-                                              HashSupplier hasher,
-                                              ModuleResolution mres) {
-        String mn = md.name();
-        URI uri = JNUA.create("jrt", "/".concat(mn));
-
-        Supplier<ModuleReader> readerSupplier = new Supplier<>() {
-            @Override
-            public ModuleReader get() {
-                return new ImageModuleReader(mn, uri);
-            }
-        };
-
-        ModuleReference mref = new ModuleReferenceImpl(md,
-                                                       uri,
-                                                       readerSupplier,
-                                                       null,
-                                                       target,
-                                                       recordedHashes,
-                                                       hasher,
-                                                       mres);
-
-        // may need a reference to a patched module if --patch-module specified
-        mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
-
-        return mref;
-    }
-
-    private HashSupplier hashSupplier(String name) {
-        if (!hashes.containsKey(name))
-            return null;
-
-        return new HashSupplier() {
-            @Override
-            public byte[] generate(String algorithm) {
-                return hashes.get(name);
-            }
-        };
-    }
-
-    /**
-     * A ModuleReader for reading resources from a module linked into the
-     * run-time image.
-     */
-    static class ImageModuleReader implements ModuleReader {
-        private final String module;
-        private volatile boolean closed;
-
-        /**
-         * If there is a security manager set then check permission to
-         * connect to the run-time image.
-         */
-        private static void checkPermissionToConnect(URI uri) {
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                try {
-                    URLConnection uc = uri.toURL().openConnection();
-                    sm.checkPermission(uc.getPermission());
-                } catch (IOException ioe) {
-                    throw new UncheckedIOException(ioe);
-                }
-            }
-        }
-
-        ImageModuleReader(String module, URI uri) {
-            checkPermissionToConnect(uri);
-            this.module = module;
-        }
-
-        /**
-         * Returns the ImageLocation for the given resource, {@code null}
-         * if not found.
-         */
-        private ImageLocation findImageLocation(String name) throws IOException {
-            Objects.requireNonNull(name);
-            if (closed)
-                throw new IOException("ModuleReader is closed");
-            ImageReader imageReader = SystemImage.reader();
-            if (imageReader != null) {
-                return imageReader.findLocation(module, name);
-            } else {
-                // not an images build
-                return null;
-            }
-        }
-
-        @Override
-        public Optional<URI> find(String name) throws IOException {
-            ImageLocation location = findImageLocation(name);
-            if (location != null) {
-                URI u = URI.create("jrt:/" + module + "/" + name);
-                return Optional.of(u);
-            } else {
-                return Optional.empty();
-            }
-        }
-
-        @Override
-        public Optional<InputStream> open(String name) throws IOException {
-            return read(name).map(this::toInputStream);
-        }
-
-        private InputStream toInputStream(ByteBuffer bb) { // ## -> ByteBuffer?
-            try {
-                int rem = bb.remaining();
-                byte[] bytes = new byte[rem];
-                bb.get(bytes);
-                return new ByteArrayInputStream(bytes);
-            } finally {
-                release(bb);
-            }
-        }
-
-        @Override
-        public Optional<ByteBuffer> read(String name) throws IOException {
-            ImageLocation location = findImageLocation(name);
-            if (location != null) {
-                return Optional.of(SystemImage.reader().getResourceBuffer(location));
-            } else {
-                return Optional.empty();
-            }
-        }
-
-        @Override
-        public void release(ByteBuffer bb) {
-            Objects.requireNonNull(bb);
-            ImageReader.releaseByteBuffer(bb);
-        }
-
-        @Override
-        public Stream<String> list() throws IOException {
-            if (closed)
-                throw new IOException("ModuleReader is closed");
-
-            Spliterator<String> s = new ModuleContentSpliterator(module);
-            return StreamSupport.stream(s, false);
-        }
-
-        @Override
-        public void close() {
-            // nothing else to do
-            closed = true;
-        }
-    }
-
-    /**
-     * A Spliterator for traversing the resources of a module linked into the
-     * run-time image.
-     */
-    static class ModuleContentSpliterator implements Spliterator<String> {
-        final String moduleRoot;
-        final Deque<ImageReader.Node> stack;
-        Iterator<ImageReader.Node> iterator;
-
-        ModuleContentSpliterator(String module) throws IOException {
-            moduleRoot = "/modules/" + module;
-            stack = new ArrayDeque<>();
-
-            // push the root node to the stack to get started
-            ImageReader.Node dir = SystemImage.reader().findNode(moduleRoot);
-            if (dir == null || !dir.isDirectory())
-                throw new IOException(moduleRoot + " not a directory");
-            stack.push(dir);
-            iterator = Collections.emptyIterator();
-        }
-
-        /**
-         * Returns the name of the next non-directory node or {@code null} if
-         * there are no remaining nodes to visit.
-         */
-        private String next() throws IOException {
-            for (;;) {
-                while (iterator.hasNext()) {
-                    ImageReader.Node node = iterator.next();
-                    String name = node.getName();
-                    if (node.isDirectory()) {
-                        // build node
-                        ImageReader.Node dir = SystemImage.reader().findNode(name);
-                        assert dir.isDirectory();
-                        stack.push(dir);
-                    } else {
-                        // strip /modules/$MODULE/ prefix
-                        return name.substring(moduleRoot.length() + 1);
-                    }
-                }
-
-                if (stack.isEmpty()) {
-                    return null;
-                } else {
-                    ImageReader.Node dir = stack.poll();
-                    assert dir.isDirectory();
-                    iterator = dir.getChildren().iterator();
-                }
-            }
-        }
-
-        @Override
-        public boolean tryAdvance(Consumer<? super String> action) {
-            String next;
-            try {
-                next = next();
-            } catch (IOException ioe) {
-                throw new UncheckedIOException(ioe);
-            }
-            if (next != null) {
-                action.accept(next);
-                return true;
-            } else {
-                return false;
-            }
-        }
-
-        @Override
-        public Spliterator<String> trySplit() {
-            return null;
-        }
-
-        @Override
-        public int characteristics() {
-            return Spliterator.DISTINCT + Spliterator.NONNULL + Spliterator.IMMUTABLE;
-        }
-
-        @Override
-        public long estimateSize() {
-            return Long.MAX_VALUE;
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinders.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,576 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.internal.module;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReader;
+import java.lang.module.ModuleReference;
+import java.lang.reflect.Constructor;
+import java.net.URI;
+import java.net.URLConnection;
+import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayDeque;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import jdk.internal.jimage.ImageLocation;
+import jdk.internal.jimage.ImageReader;
+import jdk.internal.jimage.ImageReaderFactory;
+import jdk.internal.misc.JavaNetUriAccess;
+import jdk.internal.misc.SharedSecrets;
+import jdk.internal.module.ModuleHashes.HashSupplier;
+
+/**
+ * The factory for SystemModules objects and for creating ModuleFinder objects
+ * that find modules in the runtime image.
+ *
+ * This class supports initializing the module system when the runtime is an
+ * images build, an exploded build, or an images build with java.base patched
+ * by an exploded java.base. It also supports a testing mode that re-parses
+ * the module-info.class resources in the run-time image.
+ */
+
+public final class SystemModuleFinders {
+    private static final JavaNetUriAccess JNUA = SharedSecrets.getJavaNetUriAccess();
+
+    private static final boolean USE_FAST_PATH;
+    static {
+        String value = System.getProperty("jdk.system.module.finder.disableFastPath");
+        if (value == null) {
+            USE_FAST_PATH = true;
+        } else {
+            USE_FAST_PATH = (value.length() > 0) && !Boolean.parseBoolean(value);
+        }
+    }
+
+    // cached ModuleFinder returned from ofSystem
+    private static volatile ModuleFinder cachedSystemModuleFinder;
+
+    private SystemModuleFinders() { }
+
+    /**
+     * Returns the SystemModules object to reconstitute all modules. Returns
+     * null if this is an exploded build or java.base is patched by an exploded
+     * build.
+     */
+    static SystemModules allSystemModules() {
+        if (USE_FAST_PATH) {
+            return SystemModulesMap.allSystemModules();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns a SystemModules object to reconstitute the modules for the
+     * given initial module. If the initial module is null then return the
+     * SystemModules object to reconstitute the default modules.
+     *
+     * Return null if there is no SystemModules class for the initial module,
+     * this is an exploded build, or java.base is patched by an exploded build.
+     */
+    static SystemModules systemModules(String initialModule) {
+        if (USE_FAST_PATH) {
+            if (initialModule == null) {
+                return SystemModulesMap.defaultSystemModules();
+            }
+
+            String[] initialModules = SystemModulesMap.moduleNames();
+            for (int i = 0; i < initialModules.length; i++) {
+                String moduleName = initialModules[i];
+                if (initialModule.equals(moduleName)) {
+                    String cn = SystemModulesMap.classNames()[i];
+                    try {
+                        // one-arg Class.forName as java.base may not be defined
+                        Constructor<?> ctor = Class.forName(cn).getConstructor();
+                        return (SystemModules) ctor.newInstance();
+                    } catch (Exception e) {
+                        throw new InternalError(e);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a ModuleFinder that is backed by the given SystemModules object.
+     *
+     * @apiNote The returned ModuleFinder is thread safe.
+     */
+    static ModuleFinder of(SystemModules systemModules) {
+        ModuleDescriptor[] descriptors = systemModules.moduleDescriptors();
+        ModuleTarget[] targets = systemModules.moduleTargets();
+        ModuleHashes[] recordedHashes = systemModules.moduleHashes();
+        ModuleResolution[] moduleResolutions = systemModules.moduleResolutions();
+
+        int moduleCount = descriptors.length;
+        ModuleReference[] mrefs = new ModuleReference[moduleCount];
+        @SuppressWarnings(value = {"rawtypes", "unchecked"})
+        Map.Entry<String, ModuleReference>[] map
+            = (Map.Entry<String, ModuleReference>[])new Map.Entry[moduleCount];
+
+        Map<String, byte[]> nameToHash = generateNameToHash(recordedHashes);
+
+        for (int i = 0; i < moduleCount; i++) {
+            String name = descriptors[i].name();
+            HashSupplier hashSupplier = hashSupplier(nameToHash, name);
+            ModuleReference mref = toModuleReference(descriptors[i],
+                                                     targets[i],
+                                                     recordedHashes[i],
+                                                     hashSupplier,
+                                                     moduleResolutions[i]);
+            mrefs[i] = mref;
+            map[i] = Map.entry(name, mref);
+        }
+
+        return new SystemModuleFinder(mrefs, map);
+    }
+
+    /**
+     * Returns the ModuleFinder to find all system modules. Supports both
+     * images and exploded builds.
+     *
+     * @apiNote Used by ModuleFinder.ofSystem()
+     */
+    public static ModuleFinder ofSystem() {
+        ModuleFinder finder = cachedSystemModuleFinder;
+        if (finder != null) {
+            return finder;
+        }
+
+        // probe to see if this is an images build
+        String home = System.getProperty("java.home");
+        Path modules = Paths.get(home, "lib", "modules");
+        if (Files.isRegularFile(modules)) {
+            if (USE_FAST_PATH) {
+                SystemModules systemModules = allSystemModules();
+                if (systemModules != null) {
+                    finder = of(systemModules);
+                }
+            }
+
+            // fall back to parsing the module-info.class files in image
+            if (finder == null) {
+                finder = ofModuleInfos();
+            }
+
+            cachedSystemModuleFinder = finder;
+            return finder;
+
+        }
+
+        // exploded build (do not cache module finder)
+        Path dir = Paths.get(home, "modules");
+        if (!Files.isDirectory(dir))
+            throw new InternalError("Unable to detect the run-time image");
+        ModuleFinder f = ModulePath.of(ModuleBootstrap.patcher(), dir);
+        return new ModuleFinder() {
+            @Override
+            public Optional<ModuleReference> find(String name) {
+                PrivilegedAction<Optional<ModuleReference>> pa = () -> f.find(name);
+                return AccessController.doPrivileged(pa);
+            }
+            @Override
+            public Set<ModuleReference> findAll() {
+                PrivilegedAction<Set<ModuleReference>> pa = f::findAll;
+                return AccessController.doPrivileged(pa);
+            }
+        };
+    }
+
+    /**
+     * Parses the module-info.class of all module in the runtime image and
+     * returns a ModuleFinder to find the modules.
+     *
+     * @apiNote The returned ModuleFinder is thread safe.
+     */
+    private static ModuleFinder ofModuleInfos() {
+        // parse the module-info.class in every module
+        Map<String, ModuleInfo.Attributes> nameToAttributes = new HashMap<>();
+        Map<String, byte[]> nameToHash = new HashMap<>();
+        ImageReader reader = SystemImage.reader();
+        for (String mn : reader.getModuleNames()) {
+            ImageLocation loc = reader.findLocation(mn, "module-info.class");
+            ModuleInfo.Attributes attrs
+                = ModuleInfo.read(reader.getResourceBuffer(loc), null);
+
+            nameToAttributes.put(mn, attrs);
+            ModuleHashes hashes = attrs.recordedHashes();
+            if (hashes != null) {
+                for (String name : hashes.names()) {
+                    nameToHash.computeIfAbsent(name, k -> hashes.hashFor(name));
+                }
+            }
+        }
+
+        // create a ModuleReference for each module
+        Set<ModuleReference> mrefs = new HashSet<>();
+        Map<String, ModuleReference> nameToModule = new HashMap<>();
+        for (Map.Entry<String, ModuleInfo.Attributes> e : nameToAttributes.entrySet()) {
+            String mn = e.getKey();
+            ModuleInfo.Attributes attrs = e.getValue();
+            HashSupplier hashSupplier = hashSupplier(nameToHash, mn);
+            ModuleReference mref = toModuleReference(attrs.descriptor(),
+                                                     attrs.target(),
+                                                     attrs.recordedHashes(),
+                                                     hashSupplier,
+                                                     attrs.moduleResolution());
+            mrefs.add(mref);
+            nameToModule.put(mn, mref);
+        }
+
+        return new SystemModuleFinder(mrefs, nameToModule);
+    }
+
+    /**
+     * A ModuleFinder that finds module in an array or set of modules.
+     */
+    private static class SystemModuleFinder implements ModuleFinder {
+        final Set<ModuleReference> mrefs;
+        final Map<String, ModuleReference> nameToModule;
+
+        SystemModuleFinder(ModuleReference[] array,
+                           Map.Entry<String, ModuleReference>[] map) {
+            this.mrefs = Set.of(array);
+            this.nameToModule = Map.ofEntries(map);
+        }
+
+        SystemModuleFinder(Set<ModuleReference> mrefs,
+                           Map<String, ModuleReference> nameToModule) {
+            this.mrefs = Collections.unmodifiableSet(mrefs);
+            this.nameToModule = Collections.unmodifiableMap(nameToModule);
+        }
+
+        @Override
+        public Optional<ModuleReference> find(String name) {
+            Objects.requireNonNull(name);
+            return Optional.ofNullable(nameToModule.get(name));
+        }
+
+        @Override
+        public Set<ModuleReference> findAll() {
+            return mrefs;
+        }
+    }
+
+    /**
+     * Creates a ModuleReference to the system module.
+     */
+    static ModuleReference toModuleReference(ModuleDescriptor descriptor,
+                                             ModuleTarget target,
+                                             ModuleHashes recordedHashes,
+                                             HashSupplier hasher,
+                                             ModuleResolution mres) {
+        String mn = descriptor.name();
+        URI uri = JNUA.create("jrt", "/".concat(mn));
+
+        Supplier<ModuleReader> readerSupplier = new Supplier<>() {
+            @Override
+            public ModuleReader get() {
+                return new SystemModuleReader(mn, uri);
+            }
+        };
+
+        ModuleReference mref = new ModuleReferenceImpl(descriptor,
+                                                       uri,
+                                                       readerSupplier,
+                                                       null,
+                                                       target,
+                                                       recordedHashes,
+                                                       hasher,
+                                                       mres);
+
+        // may need a reference to a patched module if --patch-module specified
+        mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
+
+        return mref;
+    }
+
+    /**
+     * Generates a map of module name to hash value.
+     */
+    static Map<String, byte[]> generateNameToHash(ModuleHashes[] recordedHashes) {
+        Map<String, byte[]> nameToHash = null;
+
+        boolean secondSeen = false;
+        // record the hashes to build HashSupplier
+        for (ModuleHashes mh : recordedHashes) {
+            if (mh != null) {
+                // if only one module contain ModuleHashes, use it
+                if (nameToHash == null) {
+                    nameToHash = mh.hashes();
+                } else {
+                    if (!secondSeen) {
+                        nameToHash = new HashMap<>(nameToHash);
+                        secondSeen = true;
+                    }
+                    nameToHash.putAll(mh.hashes());
+                }
+            }
+        }
+        return (nameToHash != null) ? nameToHash : Collections.emptyMap();
+    }
+
+    /**
+     * Returns a HashSupplier that returns the hash of the given module.
+     */
+    static HashSupplier hashSupplier(Map<String, byte[]> nameToHash, String name) {
+        byte[] hash = nameToHash.get(name);
+        if (hash != null) {
+            // avoid lambda here
+            return new HashSupplier() {
+                @Override
+                public byte[] generate(String algorithm) {
+                    return hash;
+                }
+            };
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Holder class for the ImageReader
+     *
+     * @apiNote This class must be loaded before a security manager is set.
+     */
+    private static class SystemImage {
+        static final ImageReader READER = ImageReaderFactory.getImageReader();
+        static ImageReader reader() {
+            return READER;
+        }
+    }
+
+    /**
+     * A ModuleReader for reading resources from a module linked into the
+     * run-time image.
+     */
+    private static class SystemModuleReader implements ModuleReader {
+        private final String module;
+        private volatile boolean closed;
+
+        /**
+         * If there is a security manager set then check permission to
+         * connect to the run-time image.
+         */
+        private static void checkPermissionToConnect(URI uri) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                try {
+                    URLConnection uc = uri.toURL().openConnection();
+                    sm.checkPermission(uc.getPermission());
+                } catch (IOException ioe) {
+                    throw new UncheckedIOException(ioe);
+                }
+            }
+        }
+
+        SystemModuleReader(String module, URI uri) {
+            checkPermissionToConnect(uri);
+            this.module = module;
+        }
+
+        /**
+         * Returns the ImageLocation for the given resource, {@code null}
+         * if not found.
+         */
+        private ImageLocation findImageLocation(String name) throws IOException {
+            Objects.requireNonNull(name);
+            if (closed)
+                throw new IOException("ModuleReader is closed");
+            ImageReader imageReader = SystemImage.reader();
+            if (imageReader != null) {
+                return imageReader.findLocation(module, name);
+            } else {
+                // not an images build
+                return null;
+            }
+        }
+
+        @Override
+        public Optional<URI> find(String name) throws IOException {
+            ImageLocation location = findImageLocation(name);
+            if (location != null) {
+                URI u = URI.create("jrt:/" + module + "/" + name);
+                return Optional.of(u);
+            } else {
+                return Optional.empty();
+            }
+        }
+
+        @Override
+        public Optional<InputStream> open(String name) throws IOException {
+            return read(name).map(this::toInputStream);
+        }
+
+        private InputStream toInputStream(ByteBuffer bb) { // ## -> ByteBuffer?
+            try {
+                int rem = bb.remaining();
+                byte[] bytes = new byte[rem];
+                bb.get(bytes);
+                return new ByteArrayInputStream(bytes);
+            } finally {
+                release(bb);
+            }
+        }
+
+        @Override
+        public Optional<ByteBuffer> read(String name) throws IOException {
+            ImageLocation location = findImageLocation(name);
+            if (location != null) {
+                return Optional.of(SystemImage.reader().getResourceBuffer(location));
+            } else {
+                return Optional.empty();
+            }
+        }
+
+        @Override
+        public void release(ByteBuffer bb) {
+            Objects.requireNonNull(bb);
+            ImageReader.releaseByteBuffer(bb);
+        }
+
+        @Override
+        public Stream<String> list() throws IOException {
+            if (closed)
+                throw new IOException("ModuleReader is closed");
+
+            Spliterator<String> s = new ModuleContentSpliterator(module);
+            return StreamSupport.stream(s, false);
+        }
+
+        @Override
+        public void close() {
+            // nothing else to do
+            closed = true;
+        }
+    }
+
+    /**
+     * A Spliterator for traversing the resources of a module linked into the
+     * run-time image.
+     */
+    private static class ModuleContentSpliterator implements Spliterator<String> {
+        final String moduleRoot;
+        final Deque<ImageReader.Node> stack;
+        Iterator<ImageReader.Node> iterator;
+
+        ModuleContentSpliterator(String module) throws IOException {
+            moduleRoot = "/modules/" + module;
+            stack = new ArrayDeque<>();
+
+            // push the root node to the stack to get started
+            ImageReader.Node dir = SystemImage.reader().findNode(moduleRoot);
+            if (dir == null || !dir.isDirectory())
+                throw new IOException(moduleRoot + " not a directory");
+            stack.push(dir);
+            iterator = Collections.emptyIterator();
+        }
+
+        /**
+         * Returns the name of the next non-directory node or {@code null} if
+         * there are no remaining nodes to visit.
+         */
+        private String next() throws IOException {
+            for (;;) {
+                while (iterator.hasNext()) {
+                    ImageReader.Node node = iterator.next();
+                    String name = node.getName();
+                    if (node.isDirectory()) {
+                        // build node
+                        ImageReader.Node dir = SystemImage.reader().findNode(name);
+                        assert dir.isDirectory();
+                        stack.push(dir);
+                    } else {
+                        // strip /modules/$MODULE/ prefix
+                        return name.substring(moduleRoot.length() + 1);
+                    }
+                }
+
+                if (stack.isEmpty()) {
+                    return null;
+                } else {
+                    ImageReader.Node dir = stack.poll();
+                    assert dir.isDirectory();
+                    iterator = dir.getChildren().iterator();
+                }
+            }
+        }
+
+        @Override
+        public boolean tryAdvance(Consumer<? super String> action) {
+            String next;
+            try {
+                next = next();
+            } catch (IOException ioe) {
+                throw new UncheckedIOException(ioe);
+            }
+            if (next != null) {
+                action.accept(next);
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public Spliterator<String> trySplit() {
+            return null;
+        }
+
+        @Override
+        public int characteristics() {
+            return Spliterator.DISTINCT + Spliterator.NONNULL + Spliterator.IMMUTABLE;
+        }
+
+        @Override
+        public long estimateSize() {
+            return Long.MAX_VALUE;
+        }
+    }
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/module/SystemModules.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/SystemModules.java	Mon Aug 07 09:45:38 2017 -0700
@@ -26,94 +26,73 @@
 package jdk.internal.module;
 
 import java.lang.module.ModuleDescriptor;
-import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 
 /**
- * SystemModules class will be generated at link time to create
- * ModuleDescriptor for the system modules directly to improve
- * the module descriptor reconstitution time.
+ * A SystemModules object reconstitutes module descriptors and other modules
+ * attributes in an efficient way to avoid parsing module-info.class files at
+ * startup. Implementations of this class are generated by the "system modules"
+ * jlink plugin.
  *
- * This will skip parsing of module-info.class file and validating
- * names such as module name, package name, service and provider type names.
- * It also avoids taking a defensive copy of any collection.
- *
+ * @see SystemModuleFinders
  * @see jdk.tools.jlink.internal.plugins.SystemModulesPlugin
  */
-public final class SystemModules {
-    /**
-     * Name of the system modules.
-     *
-     * This array provides a way for SystemModuleFinder to fallback
-     * and read module-info.class from the run-time image instead of
-     * the fastpath.
-     */
-    public static final String[] MODULE_NAMES = new String[0];
+
+interface SystemModules {
 
     /**
-     * Number of packages in the boot layer from the installed modules.
-     *
-     * Don't make it final to avoid inlining during compile time as
-     * the value will be changed at jlink time.
+     * Returns false if the module reconstituted by this SystemModules object
+     * have no overlapping packages. Returns true if there are overlapping
+     * packages or unknown.
      */
-    public static int PACKAGES_IN_BOOT_LAYER = 1024;
+    boolean hasSplitPackages();
+
+    /**
+     * Return false if the modules reconstituted by this SystemModules object
+     * do not include any incubator modules. Returns true if there are
+     * incubating modules or unknown.
+     */
+    boolean hasIncubatorModules();
 
     /**
-     * Return true if there are no split packages in the run-time image.
+     * Returns the non-empty array of ModuleDescriptor objects.
      */
-    public static boolean hasSplitPackages() {
-        return true;
-    }
+    ModuleDescriptor[] moduleDescriptors();
 
     /**
-     * Returns a non-empty array of ModuleDescriptor objects in the run-time image.
-     *
-     * When running an exploded image it returns an empty array.
+     * Returns the array of ModuleTarget objects. The array elements correspond
+     * to the array of ModuleDescriptor objects.
      */
-    public static ModuleDescriptor[] descriptors() {
-        throw new InternalError("expected to be overridden at link time");
-    }
+    ModuleTarget[] moduleTargets();
 
     /**
-     * Returns a non-empty array of ModuleTarget objects in the run-time image.
-     *
-     * When running an exploded image it returns an empty array.
+     * Returns the array of ModuleHashes objects. The array elements correspond
+     * to the array of ModuleDescriptor objects.
      */
-    public static ModuleTarget[] targets() {
-        throw new InternalError("expected to be overridden at link time");
-    }
+    ModuleHashes[] moduleHashes();
 
     /**
-     * Returns a non-empty array of ModuleHashes recorded in each module
-     * in the run-time image.
-     *
-     * When running an exploded image it returns an empty array.
+     * Returns the array of ModuleResolution objects. The array elements correspond
+     * to the array of ModuleDescriptor objects.
      */
-    public static ModuleHashes[] hashes() {
-        throw new InternalError("expected to be overridden at link time");
-    }
+    ModuleResolution[] moduleResolutions();
 
     /**
-     * Returns a non-empty array of ModuleResolutions in the run-time image.
+     * Returns the map representing readability graph for the modules reconstituted
+     * by this SystemModules object.
      */
-    public static ModuleResolution[] moduleResolutions() {
-        throw new InternalError("expected to be overridden at link time");
-    }
+    Map<String, Set<String>> moduleReads();
 
     /**
      * Returns the map of module concealed packages to open. The map key is the
      * module name, the value is the set of concealed packages to open.
      */
-    public static Map<String, Set<String>> concealedPackagesToOpen() {
-        return Collections.emptyMap();
-    }
+    Map<String, Set<String>> concealedPackagesToOpen();
 
     /**
      * Returns the map of module exported packages to open. The map key is the
      * module name, the value is the set of exported packages to open.
      */
-    public static Map<String, Set<String>> exportedPackagesToOpen() {
-        return Collections.emptyMap();
-    }
+    Map<String, Set<String>> exportedPackagesToOpen();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/SystemModulesMap.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.internal.module;
+
+/**
+ * This class is generated/overridden at link time to return the names of the
+ * SystemModules classes generated at link time.
+ *
+ * @see SystemModuleFinders
+ * @see jdk.tools.jlink.internal.plugins.SystemModulesPlugin
+ */
+
+class SystemModulesMap {
+
+    /**
+     * Returns the SystemModules object to reconstitute all modules or null
+     * if this is an exploded build.
+     */
+    static SystemModules allSystemModules() {
+        return null;
+    }
+
+    /**
+     * Returns the SystemModules object to reconstitute default modules or null
+     * if this is an exploded build.
+     */
+    static SystemModules defaultSystemModules() {
+        return null;
+    }
+
+    /**
+     * Returns the array of initial module names identified at link time.
+     */
+    static String[] moduleNames() {
+        return new String[0];
+    }
+
+    /**
+     * Returns the array of of SystemModules class names. The elements
+     * correspond to the elements in the array returned by moduleNames().
+     */
+    static String[] classNames() {
+        return new String[0];
+    }
+}
\ No newline at end of file
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java	Mon Aug 07 09:45:38 2017 -0700
@@ -316,8 +316,7 @@
      */
     public static boolean isCallerSensitive(Method m) {
         final ClassLoader loader = m.getDeclaringClass().getClassLoader();
-        if (VM.isSystemDomainLoader(loader) ||
-                loader == ClassLoaders.platformClassLoader()) {
+        if (VM.isSystemDomainLoader(loader)) {
             return m.isAnnotationPresent(CallerSensitive.class);
         }
         return false;
--- a/jdk/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, 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
@@ -26,10 +26,18 @@
 package sun.nio.ch;
 
 import java.io.IOException;
-import java.nio.channels.*;
-import java.nio.channels.spi.*;
 import java.net.SocketException;
-import java.util.*;
+import java.nio.channels.ClosedSelectorException;
+import java.nio.channels.IllegalSelectorException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.AbstractSelector;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
 
 
 /**
@@ -54,23 +62,18 @@
         super(sp);
         keys = new HashSet<>();
         selectedKeys = new HashSet<>();
-        if (Util.atBugLevel("1.4")) {
-            publicKeys = keys;
-            publicSelectedKeys = selectedKeys;
-        } else {
-            publicKeys = Collections.unmodifiableSet(keys);
-            publicSelectedKeys = Util.ungrowableSet(selectedKeys);
-        }
+        publicKeys = Collections.unmodifiableSet(keys);
+        publicSelectedKeys = Util.ungrowableSet(selectedKeys);
     }
 
     public Set<SelectionKey> keys() {
-        if (!isOpen() && !Util.atBugLevel("1.4"))
+        if (!isOpen())
             throw new ClosedSelectorException();
         return publicKeys;
     }
 
     public Set<SelectionKey> selectedKeys() {
-        if (!isOpen() && !Util.atBugLevel("1.4"))
+        if (!isOpen())
             throw new ClosedSelectorException();
         return publicSelectedKeys;
     }
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Mon Aug 07 09:45:38 2017 -0700
@@ -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
@@ -25,13 +25,16 @@
 
 package sun.nio.ch;
 
-import java.lang.reflect.*;
 import java.io.FileDescriptor;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.*;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
 import jdk.internal.misc.Unsafe;
 import sun.security.action.GetPropertyAction;
 
@@ -456,21 +459,4 @@
         }
         return dbb;
     }
-
-
-    // -- Bug compatibility --
-
-    private static volatile String bugLevel;
-
-    static boolean atBugLevel(String bl) {              // package-private
-        if (bugLevel == null) {
-            if (!jdk.internal.misc.VM.isBooted())
-                return false;
-            String value = GetPropertyAction
-                    .privilegedGetProperty("sun.nio.ch.bugLevel");
-            bugLevel = (value != null) ? value : "";
-        }
-        return bugLevel.equals(bl);
-    }
-
 }
--- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java	Mon Aug 07 09:45:38 2017 -0700
@@ -79,6 +79,9 @@
     public static final Debug debug = Debug.getInstance("ssl");
 
     // enum HandshakeType:
+    //
+    // Please update the isUnsupported() method accordingly if the handshake
+    // types get updated in the future.
     static final byte   ht_hello_request          = 0;      // RFC 5246
     static final byte   ht_client_hello           = 1;      // RFC 5246
     static final byte   ht_server_hello           = 2;      // RFC 5246
@@ -130,6 +133,24 @@
         return b;
     }
 
+    static boolean isUnsupported(byte handshakeType) {
+        return (handshakeType != ht_hello_request) &&
+               (handshakeType != ht_client_hello) &&
+               (handshakeType != ht_server_hello) &&
+               (handshakeType != ht_hello_verify_request) &&
+               (handshakeType != ht_new_session_ticket) &&
+               (handshakeType != ht_certificate) &&
+               (handshakeType != ht_server_key_exchange) &&
+               (handshakeType != ht_certificate_request) &&
+               (handshakeType != ht_server_hello_done) &&
+               (handshakeType != ht_certificate_verify) &&
+               (handshakeType != ht_client_key_exchange) &&
+               (handshakeType != ht_finished) &&
+               (handshakeType != ht_certificate_url) &&
+               (handshakeType != ht_certificate_status) &&
+               (handshakeType != ht_supplemental_data);
+    }
+
     private static byte[] genPad(int b, int count) {
         byte[] padding = new byte[count];
         Arrays.fill(padding, (byte)b);
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1034,6 +1034,12 @@
             input.mark(4);
 
             messageType = (byte)input.getInt8();
+            if (HandshakeMessage.isUnsupported(messageType)) {
+                throw new SSLProtocolException(
+                    "Received unsupported or unknown handshake message: " +
+                    messageType);
+            }
+
             messageLen = input.getInt24();
 
             if (input.available() < messageLen) {
--- a/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnection.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnection.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2008, 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
@@ -73,8 +73,8 @@
  * must not be null; the behavior is unspecified if it is.</p>
  *
  * <p>Class loading aspects are detailed in the
- * <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
- * JMX Specification, version 1.4</a> PDF document.</p>
+ * <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
+ * JMX Specification, version 1.4</a></p>
  *
  * <p>Most methods in this interface parallel methods in the {@link
  * MBeanServerConnection} interface.  Where an aspect of the behavior
--- a/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/package.html	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/package.html	Mon Aug 07 09:45:38 2017 -0700
@@ -2,7 +2,7 @@
 <head>
     <title>RMI connector</title>
 <!--
-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
@@ -316,19 +316,8 @@
     <p>If an RMI connector client or server receives from its peer an
       instance of a class that it does not know, and if dynamic code
       downloading is active for the RMI connection, then the class can
-      be downloaded from a codebase specified by the peer.  The
-      article <a
-    href="{@docRoot}/../technotes/guides/rmi/codebase.html"><em>Dynamic
-    code downloading using Java RMI</em></a> explains this in more
-    detail.</p>
-
-
-    @see <a href="{@docRoot}/../technotes/guides/rmi/index.html">
-	Java&trade; Remote Method
-	Invocation (RMI)</a>
-
-    @see <a href="{@docRoot}/../technotes/guides/jndi/index.html">
-	Java Naming and Directory Interface&trade; (JNDI)</a>
+      be downloaded from a codebase specified by the peer.
+      {@extLink rmi_guide Java RMI Guide} explains this in more detail.</p>
 
     @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045,
     section 6.8, "Base64 Content-Transfer-Encoding"</a>
--- a/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java	Mon Aug 07 09:45:38 2017 -0700
@@ -588,8 +588,8 @@
                                Class<T> mxbeanInterface)
             throws java.io.IOException {
 
-        // Only allow MXBean interfaces from rt.jar loaded by the
-        // bootstrap class loader
+        // Only allow MXBean interfaces from the platform modules loaded by the
+        // bootstrap or platform class loader
         final Class<?> cls = mxbeanInterface;
         ClassLoader loader =
             AccessController.doPrivileged(
--- a/jdk/src/java.management/share/classes/javax/management/loading/package.html	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.management/share/classes/javax/management/loading/package.html	Mon Aug 07 09:45:38 2017 -0700
@@ -2,7 +2,7 @@
 <head>
 <title>javax.management.loading package</title>
 <!--
-Copyright (c) 1999, 2011, 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
@@ -67,11 +67,8 @@
 	<code>PrivateClassLoader</code>.</p>
 
     <p id="spec">
-    @see <a href="{@docRoot}/../technotes/guides/jmx/">
-      Java Platform documentation on JMX technology</a>,
-    in particular the 
-    <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
-      JMX Specification, version 1.4(pdf).</a>
+    @see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
+      JMX Specification, version 1.4</a>
 
       @since 1.5
 </BODY>
--- a/jdk/src/java.management/share/classes/javax/management/modelmbean/package.html	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.management/share/classes/javax/management/modelmbean/package.html	Mon Aug 07 09:45:38 2017 -0700
@@ -2,7 +2,7 @@
 <head>
 <title>javax.management.modelmbean package</title>
 <!--
-Copyright (c) 2000, 2011, 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
@@ -114,9 +114,8 @@
 
     <ul>
 	  <li>See the <i>JMX 1.4 Specification</i>
-	     PDF document available from the 
-	     <a href="{@docRoot}/../technotes/guides/jmx/">
-	     Java Platform documentation on JMX technology</a>
+	     <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
+             JMX Specification, version 1.4</a>
     </ul>
 
     @since 1.5
--- a/jdk/src/java.management/share/classes/javax/management/monitor/package.html	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.management/share/classes/javax/management/monitor/package.html	Mon Aug 07 09:45:38 2017 -0700
@@ -2,7 +2,7 @@
 <head>
 <title>javax.management.monitor package</title>
 <!--
-Copyright (c) 1999, 2013, 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
@@ -184,11 +184,8 @@
 	</li>
       </ul>
     <p id="spec">
-    @see <a href="{@docRoot}/../technotes/guides/jmx/">
-      Java Platform documentation on JMX technology</a>,
-    in particular the 
-    <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
-      JMX Specification, version 1.4(pdf).</a>
+    @see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
+      JMX Specification, version 1.4</a>
       @since 1.5
 
 </BODY>
--- a/jdk/src/java.management/share/classes/javax/management/openmbean/package.html	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.management/share/classes/javax/management/openmbean/package.html	Mon Aug 07 09:45:38 2017 -0700
@@ -2,7 +2,7 @@
 <head>
 <title>javax.management.openmbean package</title>
 <!--
-Copyright (c) 2001, 2011, 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
@@ -142,10 +142,7 @@
 	then {@code minValue} must not be greater than {@code maxValue}.
     </ul>
 
-    @see <a href="{@docRoot}/../technotes/guides/jmx/">
-      Java Platform documentation on JMX technology</a>,
-    in particular the 
-    <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
+    @see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
       JMX Specification, version 1.4</a>
 
     @since 1.5
--- a/jdk/src/java.management/share/classes/javax/management/package.html	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.management/share/classes/javax/management/package.html	Mon Aug 07 09:45:38 2017 -0700
@@ -2,7 +2,7 @@
     <head>
         <title>javax.management package</title>
         <!--
-Copyright (c) 1999, 2013, 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
@@ -389,11 +389,8 @@
         </ul>
 
         <p id="spec">
-        @see <a href="{@docRoot}/../technotes/guides/jmx/index.html">
-        Java Platform documentation on JMX technology</a>
-        in particular the
-        <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
-        JMX Specification, version 1.4(pdf).</a>
+        @see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
+        JMX Specification, version 1.4</a>
 
         @since 1.5
 
--- a/jdk/src/java.management/share/classes/javax/management/relation/package.html	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.management/share/classes/javax/management/relation/package.html	Mon Aug 07 09:45:38 2017 -0700
@@ -2,7 +2,7 @@
 <head>
 <title>javax.management.relation package</title>
 <!--
-Copyright (c) 2000, 2011, 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
@@ -136,10 +136,7 @@
 // Set of ObjectName containing moduleB
 </pre>
 
-    @see <a href="{@docRoot}/../technotes/guides/jmx/">
-      Java Platform documentation on JMX technology</a>,
-    in particular the 
-    <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
+    @see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
       JMX Specification, version 1.4</a>
 
       @since 1.5
--- a/jdk/src/java.management/share/classes/javax/management/remote/package.html	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.management/share/classes/javax/management/remote/package.html	Mon Aug 07 09:45:38 2017 -0700
@@ -2,7 +2,7 @@
 <head>
     <title>JMX&trade; Remote API.</title>
 <!--
-Copyright (c) 2002, 2014, 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
@@ -32,8 +32,8 @@
 	This package defines the essential interfaces for making a JMX
 	MBean server manageable remotely. The specification of this 
         functionality is completed by Part III of the 
-       <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
-	JMX Specification, version 1.4</a> PDF document.</p>
+       <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
+	JMX Specification, version 1.4</a></p>
 
       <p>The JMX specification defines the notion of <b>connectors</b>.
 	A connector is attached to a JMX API MBean server and makes it
@@ -194,10 +194,7 @@
 	connector server.</p>
 
 
-    @see <a href="{@docRoot}/../technotes/guides/jmx/">
-      Java Platform documentation on JMX technology</a>,
-    in particular the 
-    <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
+    @see <a href="https://jcp.org/aboutJava/communityprocess/mrel/jsr160/index2.html">
       JMX Specification, version 1.4</a>
     
     @since 1.5
--- a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardException.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardException.java	Mon Aug 07 09:45:38 2017 -0700
@@ -48,7 +48,7 @@
 
     /**
      * Constructs a new CardException with the specified cause and a detail message
-     * of <code>(cause==null ? null : cause.toString())</code>.
+     * of {@code (cause==null ? null : cause.toString())}.
      *
      * @param cause the cause of this exception or null
      */
--- a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardNotPresentException.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardNotPresentException.java	Mon Aug 07 09:45:38 2017 -0700
@@ -48,7 +48,7 @@
 
     /**
      * Constructs a new CardNotPresentException with the specified cause and a detail message
-     * of <code>(cause==null ? null : cause.toString())</code>.
+     * of {@code (cause==null ? null : cause.toString())}.
      *
      * @param cause the cause of this exception or null
      */
--- a/jdk/src/jdk.attach/share/classes/com/sun/tools/attach/AttachPermission.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.attach/share/classes/com/sun/tools/attach/AttachPermission.java	Mon Aug 07 09:45:38 2017 -0700
@@ -42,14 +42,16 @@
  *
  * <table class="striped"><caption style="display:none">Table shows permission
  * target name, what the permission allows, and associated risks</caption>
+ * <thead>
  * <tr>
- * <th>Permission Target Name</th>
- * <th>What the Permission Allows</th>
- * <th>Risks of Allowing this Permission</th>
+ * <th scope="col">Permission Target Name</th>
+ * <th scope="col">What the Permission Allows</th>
+ * <th scope="col">Risks of Allowing this Permission</th>
  * </tr>
- *
+ * </thead>
+ * <tbody>
  * <tr>
- *   <td>attachVirtualMachine</td>
+ *   <th scope="row">attachVirtualMachine</th>
  *   <td>Ability to attach to another Java virtual machine and load agents
  *       into that VM.
  *   </td>
@@ -59,14 +61,14 @@
  * </tr>
  *
  * <tr>
- *   <td>createAttachProvider</td>
+ *   <th scope="row">createAttachProvider</th>
  *   <td>Ability to create an <code>AttachProvider</code> instance.
  *   </td>
  *   <td>This allows an attacker to create an AttachProvider which can
  *       potentially be used to attach to other Java virtual machines.
  *   </td>
  * </tr>
-
+ * </tbody>
  *
  * </table>
 
--- a/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpServer.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpServer.java	Mon Aug 07 09:45:38 2017 -0700
@@ -59,21 +59,29 @@
  * Paths are matched literally, which means that the strings are compared
  * case sensitively, and with no conversion to or from any encoded forms.
  * For example. Given a HttpServer with the following HttpContexts configured.
- * <table><caption style="display:none">description</caption>
- * <tr><td><i>Context</i></td><td><i>Context path</i></td></tr>
- * <tr><td>ctx1</td><td>"/"</td></tr>
- * <tr><td>ctx2</td><td>"/apps/"</td></tr>
- * <tr><td>ctx3</td><td>"/apps/foo/"</td></tr>
+ * <table class="striped"><caption style="display:none">description</caption>
+ * <thead>
+ * <tr><th scope="col"><i>Context</i></th><th scope="col"><i>Context path</i></th></tr>
+ * </thead>
+ * <tbody>
+ * <tr><th scope="row">ctx1</th><td>"/"</td></tr>
+ * <tr><th scope="row">ctx2</th><td>"/apps/"</td></tr>
+ * <tr><th scope="row">ctx3</th><td>"/apps/foo/"</td></tr>
+ * </tbody>
  * </table>
  * <p>
  * the following table shows some request URIs and which, if any context they would
  * match with.
- * <table><caption style="display:none">description</caption>
- * <tr><td><i>Request URI</i></td><td><i>Matches context</i></td></tr>
- * <tr><td>"http://foo.com/apps/foo/bar"</td><td>ctx3</td></tr>
- * <tr><td>"http://foo.com/apps/Foo/bar"</td><td>no match, wrong case</td></tr>
- * <tr><td>"http://foo.com/apps/app1"</td><td>ctx2</td></tr>
- * <tr><td>"http://foo.com/foo"</td><td>ctx1</td></tr>
+ * <table class="striped"><caption style="display:none">description</caption>
+ * <thead>
+ * <tr><th scope="col"><i>Request URI</i></th><th scope="col"><i>Matches context</i></th></tr>
+ * </thead>
+ * <tbody>
+ * <tr><th scope="row">"http://foo.com/apps/foo/bar"</th><td>ctx3</td></tr>
+ * <tr><th scope="row">"http://foo.com/apps/Foo/bar"</th><td>no match, wrong case</td></tr>
+ * <tr><th scope="row">"http://foo.com/apps/app1"</th><td>ctx2</td></tr>
+ * <tr><th scope="row">"http://foo.com/foo"</th><td>ctx1</td></tr>
+ * </tbody>
  * </table>
  * <p>
  * <b>Note about socket backlogs</b><p>
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpResponse.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpResponse.java	Mon Aug 07 09:45:38 2017 -0700
@@ -618,7 +618,7 @@
          * on one of the given {@code CompletableFuture<Void}s which themselves complete
          * after all individual responses associated with the multi response
          * have completed, or after all push promises have been received.
-         * <p>
+         *
          * @implNote Implementations might follow the pattern shown below
          * <pre>
          * {@code
@@ -633,7 +633,6 @@
          *      }
          * }
          * </pre>
-         * <p>
          *
          * @param onComplete a CompletableFuture which completes after all
          * responses have been received relating to this multi request.
--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/SocketTransportService.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/SocketTransportService.java	Mon Aug 07 09:45:38 2017 -0700
@@ -275,6 +275,12 @@
             sa = new InetSocketAddress(localaddress, port);
         }
         ServerSocket ss = new ServerSocket();
+        if (port == 0) {
+            // Only need SO_REUSEADDR if we're using a fixed port. If we
+            // start seeing EADDRINUSE due to collisions in free ports
+            // then we should retry the bind() a few times.
+            ss.setReuseAddress(false);
+        }
         ss.bind(sa);
         return new SocketListenKey(ss);
     }
--- a/jdk/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, 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
@@ -119,8 +119,26 @@
     return (char *)dbgsysTlsGet(tlsIndex);
 }
 
+/* Set options common to client and server sides */
 static jdwpTransportError
-setOptions(int fd)
+setOptionsCommon(int fd)
+{
+    jvalue dontcare;
+    int err;
+
+    dontcare.i = 0;  /* keep compiler happy */
+
+    err = dbgsysSetSocketOption(fd, TCP_NODELAY, JNI_TRUE, dontcare);
+    if (err < 0) {
+        RETURN_IO_ERROR("setsockopt TCPNODELAY failed");
+    }
+
+    return JDWPTRANSPORT_ERROR_NONE;
+}
+
+/* Set the SO_REUSEADDR option */
+static jdwpTransportError
+setReuseAddrOption(int fd)
 {
     jvalue dontcare;
     int err;
@@ -132,11 +150,6 @@
         RETURN_IO_ERROR("setsockopt SO_REUSEADDR failed");
     }
 
-    err = dbgsysSetSocketOption(fd, TCP_NODELAY, JNI_TRUE, dontcare);
-    if (err < 0) {
-        RETURN_IO_ERROR("setsockopt TCPNODELAY failed");
-    }
-
     return JDWPTRANSPORT_ERROR_NONE;
 }
 
@@ -350,10 +363,21 @@
         RETURN_IO_ERROR("socket creation failed");
     }
 
-    err = setOptions(serverSocketFD);
+    err = setOptionsCommon(serverSocketFD);
     if (err) {
         return err;
     }
+    if (sa.sin_port != 0) {
+        /*
+         * Only need SO_REUSEADDR if we're using a fixed port. If we
+         * start seeing EADDRINUSE due to collisions in free ports
+         * then we should retry the dbgsysBind() a few times.
+         */
+        err = setReuseAddrOption(serverSocketFD);
+        if (err) {
+            return err;
+        }
+    }
 
     err = dbgsysBind(serverSocketFD, (struct sockaddr *)&sa, sizeof(sa));
     if (err < 0) {
@@ -510,12 +534,18 @@
         RETURN_IO_ERROR("unable to create socket");
     }
 
-    err = setOptions(socketFD);
+    err = setOptionsCommon(socketFD);
     if (err) {
         return err;
     }
 
     /*
+     * We don't call setReuseAddrOption() for the non-server socket
+     * case. If we start seeing EADDRINUSE due to collisions in free
+     * ports then we should retry the dbgsysConnect() a few times.
+     */
+
+    /*
      * To do a timed connect we make the socket non-blocking
      * and poll with a timeout;
      */
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java	Mon Aug 07 09:45:38 2017 -0700
@@ -28,6 +28,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.module.Configuration;
 import java.lang.module.ModuleDescriptor;
 import java.lang.module.ModuleDescriptor.Exports;
 import java.lang.module.ModuleDescriptor.Opens;
@@ -37,12 +38,15 @@
 import java.lang.module.ModuleFinder;
 import java.lang.module.ModuleReader;
 import java.lang.module.ModuleReference;
+import java.lang.module.ResolvedModule;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -50,18 +54,20 @@
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.function.IntSupplier;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 import jdk.internal.module.Checks;
 import jdk.internal.module.ClassFileAttributes;
 import jdk.internal.module.ClassFileConstants;
+import jdk.internal.module.DefaultRoots;
 import jdk.internal.module.IllegalAccessMaps;
 import jdk.internal.module.ModuleHashes;
 import jdk.internal.module.ModuleInfo.Attributes;
 import jdk.internal.module.ModuleInfoExtender;
+import jdk.internal.module.ModuleReferenceImpl;
 import jdk.internal.module.ModuleResolution;
 import jdk.internal.module.ModuleTarget;
-import jdk.internal.module.SystemModules;
 import jdk.internal.org.objectweb.asm.Attribute;
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassVisitor;
@@ -72,33 +78,42 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
 import jdk.tools.jlink.internal.ModuleSorter;
+import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.plugin.PluginException;
 import jdk.tools.jlink.plugin.ResourcePool;
-import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.plugin.ResourcePoolBuilder;
 import jdk.tools.jlink.plugin.ResourcePoolEntry;
 
 /**
- * Jlink plugin to reconstitute module descriptors for system modules.
- * It will extend module-info.class with ModulePackages attribute,
- * if not present. It also determines the number of packages of
- * the boot layer at link time.
+ * Jlink plugin to reconstitute module descriptors and other attributes for system
+ * modules. The plugin generates implementations of SystemModules to avoid parsing
+ * module-info.class files at startup. It also generates SystemModulesMap to return
+ * the SystemModules implementation for a specific initial module.
  *
- * This plugin will override jdk.internal.module.SystemModules class
+ * As a side effect, the plugin adds the ModulePackages class file attribute to the
+ * module-info.class files that don't have the attribute.
  *
- * @see jdk.internal.module.SystemModuleFinder
- * @see SystemModules
+ * @see jdk.internal.module.SystemModuleFinders
+ * @see jdk.internal.module.SystemModules
  */
+
 public final class SystemModulesPlugin implements Plugin {
     private static final String NAME = "system-modules";
     private static final String DESCRIPTION =
-        PluginsResourceBundle.getDescription(NAME);
+            PluginsResourceBundle.getDescription(NAME);
+    private static final String SYSTEM_MODULES_MAP_CLASS =
+            "jdk/internal/module/SystemModulesMap";
+    private static final String SYSTEM_MODULES_CLASS_PREFIX =
+            "jdk/internal/module/SystemModules$";
+    private static final String ALL_SYSTEM_MODULES_CLASS =
+            SYSTEM_MODULES_CLASS_PREFIX + "all";
+    private static final String DEFAULT_SYSTEM_MODULES_CLASS =
+            SYSTEM_MODULES_CLASS_PREFIX + "default";
 
     private boolean enabled;
-    private boolean retainModuleTarget;
+
     public SystemModulesPlugin() {
         this.enabled = true;
-        this.retainModuleTarget = false;
     }
 
     @Override
@@ -131,11 +146,7 @@
     public void configure(Map<String, String> config) {
         String arg = config.get(NAME);
         if (arg != null) {
-            if (arg.equals("retainModuleTarget")) {
-                retainModuleTarget = true;
-            } else {
-                throw new IllegalArgumentException(NAME + ": " + arg);
-            }
+            throw new IllegalArgumentException(NAME + ": " + arg);
         }
     }
 
@@ -145,25 +156,56 @@
             throw new PluginException(NAME + " was set");
         }
 
-        SystemModulesClassGenerator generator =
-            new SystemModulesClassGenerator(retainModuleTarget);
+        // validate, transform (if needed), and add the module-info.class files
+        List<ModuleInfo> moduleInfos = transformModuleInfos(in, out);
+
+        // generate and add the SystemModuleMap and SystemModules classes
+        Set<String> generated = genSystemModulesClasses(moduleInfos, out);
+
+        // pass through all other resources
+        in.entries()
+            .filter(data -> !data.path().endsWith("/module-info.class")
+                    && !generated.contains(data.path()))
+            .forEach(data -> out.add(data));
 
-        // generate the byte code to create ModuleDescriptors
-        // such that the modules linked in the image would skip parsing
-        // of module-info.class and also skip name check
+        return out.build();
+    }
+
+    /**
+     * Validates and transforms the module-info.class files in the modules, adding
+     * the ModulePackages class file attribute if needed.
+     *
+     * @return the list of ModuleInfo objects, the first element is java.base
+     */
+    List<ModuleInfo> transformModuleInfos(ResourcePool in, ResourcePoolBuilder out) {
+        List<ModuleInfo> moduleInfos = new ArrayList<>();
 
         // Sort modules in the topological order so that java.base is always first.
         new ModuleSorter(in.moduleView()).sorted().forEach(module -> {
             ResourcePoolEntry data = module.findEntry("module-info.class").orElseThrow(
-                // automatic module not supported yet
+                // automatic modules not supported
                 () ->  new PluginException("module-info.class not found for " +
-                    module.name() + " module")
+                        module.name() + " module")
             );
 
             assert module.name().equals(data.moduleName());
+
             try {
-                // validate the module and add to system modules
-                data = generator.buildModuleInfo(data, module.packages());
+                byte[] content = data.contentBytes();
+                Set<String> packages = module.packages();
+                ModuleInfo moduleInfo = new ModuleInfo(content, packages);
+
+                // link-time validation
+                moduleInfo.validateNames();
+
+                // check if any exported or open package is not present
+                moduleInfo.validatePackages();
+
+                // module-info.class may be overridden to add ModulePackages
+                if (moduleInfo.shouldRewrite()) {
+                    data = data.copyWithContent(moduleInfo.getBytes());
+                }
+                moduleInfos.add(moduleInfo);
 
                 // add resource pool entry
                 out.add(data);
@@ -172,37 +214,134 @@
             }
         });
 
-        // Generate the new class
-        ClassWriter cwriter = generator.getClassWriter();
-        in.entries().forEach(data -> {
-            if (data.path().endsWith("module-info.class"))
-                return;
-            if (generator.isOverriddenClass(data.path())) {
-                byte[] bytes = cwriter.toByteArray();
-                ResourcePoolEntry ndata = data.copyWithContent(bytes);
-                out.add(ndata);
-            } else {
-                out.add(data);
+        return moduleInfos;
+    }
+
+    /**
+     * Generates the SystemModules classes (at least one) and the SystemModulesMap
+     * class to map initial modules to a SystemModules class.
+     *
+     * @return the resource names of the resources added to the pool
+     */
+    private Set<String> genSystemModulesClasses(List<ModuleInfo> moduleInfos,
+                                                ResourcePoolBuilder out) {
+        int moduleCount = moduleInfos.size();
+        ModuleFinder finder = finderOf(moduleInfos);
+        assert finder.findAll().size() == moduleCount;
+
+        // map of initial module name to SystemModules class name
+        Map<String, String> map = new LinkedHashMap<>();
+
+        // the names of resources written to the pool
+        Set<String> generated = new HashSet<>();
+
+        // generate the SystemModules implementation to reconstitute all modules
+        Set<String> allModuleNames = moduleInfos.stream()
+                .map(ModuleInfo::moduleName)
+                .collect(Collectors.toSet());
+        String rn = genSystemModulesClass(moduleInfos,
+                                          resolve(finder, allModuleNames),
+                                          ALL_SYSTEM_MODULES_CLASS,
+                                          out);
+        generated.add(rn);
+
+        // generate, if needed, a SystemModules class to reconstitute the modules
+        // needed for the case that the initial module is the unnamed module.
+        String defaultSystemModulesClassName;
+        Configuration cf = resolve(finder, DefaultRoots.compute(finder));
+        if (cf.modules().size() == moduleCount) {
+            // all modules are resolved so no need to generate a class
+            defaultSystemModulesClassName = ALL_SYSTEM_MODULES_CLASS;
+        } else {
+            defaultSystemModulesClassName = DEFAULT_SYSTEM_MODULES_CLASS;
+            rn = genSystemModulesClass(sublist(moduleInfos, cf),
+                                       cf,
+                                       defaultSystemModulesClassName,
+                                       out);
+            generated.add(rn);
+        }
+
+        // Generate a SystemModules class for each module with a main class
+        int suffix = 0;
+        for (ModuleInfo mi : moduleInfos) {
+            if (mi.descriptor().mainClass().isPresent()) {
+                String moduleName = mi.moduleName();
+                cf = resolve(finder, Set.of(moduleName));
+                if (cf.modules().size() == moduleCount) {
+                    // resolves all modules so no need to generate a class
+                    map.put(moduleName, ALL_SYSTEM_MODULES_CLASS);
+                } else {
+                    String cn = SYSTEM_MODULES_CLASS_PREFIX + (suffix++);
+                    rn = genSystemModulesClass(sublist(moduleInfos, cf), cf, cn, out);
+                    map.put(moduleName, cn);
+                    generated.add(rn);
+                }
             }
-        });
+        }
+
+        // generate SystemModulesMap
+        rn = genSystemModulesMapClass(ALL_SYSTEM_MODULES_CLASS,
+                                      defaultSystemModulesClassName,
+                                      map,
+                                      out);
+        generated.add(rn);
+
+        // return the resource names of the generated classes
+        return generated;
+    }
+
+    /**
+     * Resolves a collection of root modules, with service binding, to create
+     * configuration.
+     */
+    private Configuration resolve(ModuleFinder finder, Set<String> roots) {
+        return Configuration.empty().resolveAndBind(finder, ModuleFinder.of(), roots);
+    }
 
-        return out.build();
+    /**
+     * Returns the list of ModuleInfo objects that correspond to the modules in
+     * the given configuration.
+     */
+    private List<ModuleInfo> sublist(List<ModuleInfo> moduleInfos, Configuration cf) {
+        Set<String> names = cf.modules()
+                .stream()
+                .map(ResolvedModule::name)
+                .collect(Collectors.toSet());
+        return moduleInfos.stream()
+                .filter(mi -> names.contains(mi.moduleName()))
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Generate a SystemModules implementation class and add it as a resource.
+     *
+     * @return the name of the class resource added to the pool
+     */
+    private String genSystemModulesClass(List<ModuleInfo> moduleInfos,
+                                         Configuration cf,
+                                         String className,
+                                         ResourcePoolBuilder out) {
+        SystemModulesClassGenerator generator
+            = new SystemModulesClassGenerator(className, moduleInfos);
+        byte[] bytes = generator.getClassWriter(cf).toByteArray();
+        String rn = "/java.base/" + className + ".class";
+        ResourcePoolEntry e = ResourcePoolEntry.create(rn, bytes);
+        out.add(e);
+        return rn;
     }
 
     static class ModuleInfo {
-        private final ByteArrayInputStream bain;
+        private final ByteArrayInputStream bais;
         private final Attributes attrs;
         private final Set<String> packages;
-        private final boolean dropModuleTarget;
         private final boolean addModulePackages;
         private ModuleDescriptor descriptor;  // may be different that the original one
 
-        ModuleInfo(byte[] bytes, Set<String> packages, boolean dropModuleTarget)
-            throws IOException
-        {
-            this.bain = new ByteArrayInputStream(bytes);
+        ModuleInfo(byte[] bytes, Set<String> packages) throws IOException {
+            this.bais = new ByteArrayInputStream(bytes);
             this.packages = packages;
-            this.attrs = jdk.internal.module.ModuleInfo.read(bain, null);
+            this.attrs = jdk.internal.module.ModuleInfo.read(bais, null);
+
             // If ModulePackages attribute is present, the packages from this
             // module descriptor returns the packages in that attribute.
             // If it's not present, ModuleDescriptor::packages only contains
@@ -215,14 +354,6 @@
             // add ModulePackages attribute if this module contains some packages
             // and ModulePackages is not present
             this.addModulePackages = packages.size() > 0 && !hasModulePackages();
-
-            // drop target attribute only if any OS property is present
-            ModuleTarget target = attrs.target();
-            if (dropModuleTarget && target != null) {
-                this.dropModuleTarget = (target.targetPlatform() != null);
-            } else {
-                this.dropModuleTarget = false;
-            }
         }
 
         String moduleName() {
@@ -233,7 +364,6 @@
             return descriptor;
         }
 
-
         Set<String> packages() {
             return packages;
         }
@@ -283,7 +413,6 @@
             }
         }
 
-
         /**
          * Validates if exported and open packages are present
          */
@@ -328,17 +457,15 @@
         }
 
         /**
-         * Returns true if module-info.class should be written
-         * 1. add ModulePackages attribute if not present; or
-         * 2. drop ModuleTarget attribute except java.base
+         * Returns true if module-info.class should be rewritten to add the
+         * ModulePackages attribute.
          */
         boolean shouldRewrite() {
-            return addModulePackages || dropModuleTarget;
+            return addModulePackages;
         }
 
         /**
-         * Returns the bytes for the module-info.class with ModulePackages
-         * attribute added and/or with ModuleTarget attribute dropped.
+         * Returns the bytes for the (possibly updated) module-info.class.
          */
         byte[] getBytes() throws IOException {
             try (InputStream in = getInputStream()) {
@@ -347,13 +474,10 @@
                     if (addModulePackages) {
                         rewriter.addModulePackages(packages);
                     }
-                    if (dropModuleTarget) {
-                        rewriter.dropModuleTarget();
-                    }
                     // rewritten module descriptor
                     byte[] bytes = rewriter.getBytes();
-                    try (ByteArrayInputStream bain = new ByteArrayInputStream(bytes)) {
-                        this.descriptor = ModuleDescriptor.read(bain);
+                    try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
+                        this.descriptor = ModuleDescriptor.read(bais);
                     }
                     return bytes;
                 } else {
@@ -366,8 +490,8 @@
          * Returns the input stream of the module-info.class
          */
         InputStream getInputStream() {
-            bain.reset();
-            return bain;
+            bais.reset();
+            return bais;
         }
 
         class ModuleInfoRewriter extends ByteArrayOutputStream {
@@ -383,10 +507,6 @@
                 }
             }
 
-            void dropModuleTarget() {
-                extender.targetPlatform("");
-            }
-
             byte[] getBytes() throws IOException {
                 extender.write(this);
                 return buf;
@@ -395,12 +515,10 @@
     }
 
     /**
-     * ClassWriter of a new jdk.internal.module.SystemModules class
-     * to reconstitute ModuleDescriptor of the system modules.
+     * Generates a SystemModules class to reconstitute the ModuleDescriptor
+     * and other attributes of system modules.
      */
     static class SystemModulesClassGenerator {
-        private static final String CLASSNAME =
-            "jdk/internal/module/SystemModules";
         private static final String MODULE_DESCRIPTOR_BUILDER =
             "jdk/internal/module/Builder";
         private static final String MODULE_DESCRIPTOR_ARRAY_SIGNATURE =
@@ -422,10 +540,6 @@
         private static final String MODULE_RESOLUTIONS_ARRAY_SIGNATURE  =
             "[Ljdk/internal/module/ModuleResolution;";
 
-        // static variables in SystemModules class
-        private static final String MODULE_NAMES = "MODULE_NAMES";
-        private static final String PACKAGE_COUNT = "PACKAGES_IN_BOOT_LAYER";
-
         private static final int MAX_LOCAL_VARS = 256;
 
         private final int BUILDER_VAR    = 0;
@@ -434,14 +548,14 @@
         private final int MH_VAR         = 1;  // variable for ModuleHashes
         private int nextLocalVar         = 2;  // index to next local variable
 
-        private final ClassWriter cw;
-        private boolean dropModuleTarget;
-
         // Method visitor for generating the SystemModules::modules() method
         private MethodVisitor mv;
 
+        // name of class to generate
+        private final String className;
+
         // list of all ModuleDescriptorBuilders, invoked in turn when building.
-        private final List<ModuleInfo> moduleInfos = new ArrayList<>();
+        private final List<ModuleInfo> moduleInfos;
 
         // A builder to create one single Set instance for a given set of
         // names or modifiers to reduce the footprint
@@ -449,10 +563,11 @@
         private final DedupSetBuilder dedupSetBuilder
             = new DedupSetBuilder(this::getNextLocalVar);
 
-        public SystemModulesClassGenerator(boolean retainModuleTarget) {
-            this.cw = new ClassWriter(ClassWriter.COMPUTE_MAXS +
-                                      ClassWriter.COMPUTE_FRAMES);
-            this.dropModuleTarget = !retainModuleTarget;
+        public SystemModulesClassGenerator(String className,
+                                           List<ModuleInfo> moduleInfos) {
+            this.className = className;
+            this.moduleInfos = moduleInfos;
+            moduleInfos.forEach(mi -> dedups(mi.descriptor()));
         }
 
         private int getNextLocalVar() {
@@ -460,105 +575,10 @@
         }
 
         /*
-         * static initializer initializing the static fields
-         *
-         * static Map<String, ModuleDescriptor> map = new HashMap<>();
-         */
-        private void clinit(int numModules, int numPackages,
-                            boolean hasSplitPackages) {
-            cw.visit(Opcodes.V1_8, ACC_PUBLIC+ACC_FINAL+ACC_SUPER, CLASSNAME,
-                     null, "java/lang/Object", null);
-
-            // public static String[] MODULE_NAMES = new String[] {....};
-            cw.visitField(ACC_PUBLIC+ACC_FINAL+ACC_STATIC, MODULE_NAMES,
-                    "[Ljava/lang/String;", null, null)
-                    .visitEnd();
-
-            // public static int PACKAGES_IN_BOOT_LAYER;
-            cw.visitField(ACC_PUBLIC+ACC_FINAL+ACC_STATIC, PACKAGE_COUNT,
-                    "I", null, numPackages)
-                    .visitEnd();
-
-            MethodVisitor clinit =
-                cw.visitMethod(ACC_STATIC, "<clinit>", "()V",
-                               null, null);
-            clinit.visitCode();
-
-            // create the MODULE_NAMES array
-            pushInt(clinit, numModules);
-            clinit.visitTypeInsn(ANEWARRAY, "java/lang/String");
-
-            int index = 0;
-            for (ModuleInfo minfo : moduleInfos) {
-                clinit.visitInsn(DUP);                  // arrayref
-                pushInt(clinit, index++);
-                clinit.visitLdcInsn(minfo.moduleName()); // value
-                clinit.visitInsn(AASTORE);
-            }
-
-            clinit.visitFieldInsn(PUTSTATIC, CLASSNAME, MODULE_NAMES,
-                    "[Ljava/lang/String;");
-
-            clinit.visitInsn(RETURN);
-            clinit.visitMaxs(0, 0);
-            clinit.visitEnd();
-
-            // public static boolean hasSplitPackages();
-            MethodVisitor split =
-                cw.visitMethod(ACC_PUBLIC+ACC_STATIC, "hasSplitPackages",
-                               "()Z", null, null);
-            split.visitCode();
-            split.visitInsn(hasSplitPackages ? ICONST_1 : ICONST_0);
-            split.visitInsn(IRETURN);
-            split.visitMaxs(0, 0);
-            split.visitEnd();
-
-        }
-
-        /*
          * Adds the given ModuleDescriptor to the system module list.
          * It performs link-time validation and prepares mapping from various
          * Sets to SetBuilders to emit an optimized number of sets during build.
          */
-        public ResourcePoolEntry buildModuleInfo(ResourcePoolEntry entry,
-                                                 Set<String> packages)
-            throws IOException
-        {
-            if (moduleInfos.isEmpty() && !entry.moduleName().equals("java.base")) {
-                throw new InternalError("java.base must be the first module to process");
-            }
-
-            ModuleInfo moduleInfo;
-            if (entry.moduleName().equals("java.base")) {
-                moduleInfo = new ModuleInfo(entry.contentBytes(), packages, false);
-                ModuleDescriptor md = moduleInfo.descriptor;
-                // drop ModuleTarget attribute if java.base has all OS properties
-                ModuleTarget target = moduleInfo.target();
-                if (dropModuleTarget && target.targetPlatform() != null) {
-                    dropModuleTarget = true;
-                } else {
-                    dropModuleTarget = false;
-                }
-            } else {
-                moduleInfo = new ModuleInfo(entry.contentBytes(), packages, dropModuleTarget);
-            }
-
-            // link-time validation
-            moduleInfo.validateNames();
-            // check if any exported or open package is not present
-            moduleInfo.validatePackages();
-
-            // module-info.class may be overridden for optimization
-            // 1. update ModuleTarget attribute to drop targetPlartform
-            // 2. add/update ModulePackages attribute
-            if (moduleInfo.shouldRewrite()) {
-                entry = entry.copyWithContent(moduleInfo.getBytes());
-            }
-            moduleInfos.add(moduleInfo);
-            dedups(moduleInfo.descriptor());
-            return entry;
-        }
-
         private void dedups(ModuleDescriptor md) {
             // exports
             for (Exports e : md.exports()) {
@@ -581,47 +601,123 @@
             dedupSetBuilder.stringSet(md.uses());
         }
 
-        /*
-         * Generate bytecode for SystemModules
+        /**
+         * Generate SystemModules class
          */
-        public ClassWriter getClassWriter() {
-            int numModules = moduleInfos.size();
-            Set<String> allPackages = new HashSet<>();
-            int packageCount = 0;
-            for (ModuleInfo minfo : moduleInfos) {
-                allPackages.addAll(minfo.packages);
-                packageCount += minfo.packages.size();
-            }
+        public ClassWriter getClassWriter(Configuration cf) {
+            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+                                             + ClassWriter.COMPUTE_FRAMES);
+            cw.visit(Opcodes.V1_8,
+                     ACC_FINAL+ACC_SUPER,
+                     className,
+                     null,
+                     "java/lang/Object",
+                     new String[] { "jdk/internal/module/SystemModules" });
 
-            int numPackages = allPackages.size();
-            boolean hasSplitPackages = (numPackages < packageCount);
-            clinit(numModules, numPackages, hasSplitPackages);
+            // generate <init>
+            genConstructor(cw);
+
+            // generate hasSplitPackages
+            genHasSplitPackages(cw);
 
-            // generate SystemModules::descriptors
-            genDescriptorsMethod();
+            // generate hasIncubatorModules
+            genIncubatorModules(cw);
 
-            // generate SystemModules::targets
-            genTargetsMethod();
+            // generate moduleDescriptors
+            genModuleDescriptorsMethod(cw);
+
+            // generate moduleTargets
+            genModuleTargetsMethod(cw);
 
-            // generate SystemModules::hashes
-            genHashesMethod();
+            // generate moduleHashes
+            genModuleHashesMethod(cw);
+
+            // generate moduleResolutions
+            genModuleResolutionsMethod(cw);
 
-            // generate SystemModules::moduleResolutions
-            genModuleResolutionsMethod();
+            // generate moduleReads
+            genModuleReads(cw, cf);
 
-            // generate SystemModules::concealedPackagesToOpen and
-            // SystemModules::exportedPackagesToOpen
-            genXXXPackagesToOpenMethods();
+            // generate concealedPackagesToOpen and exportedPackagesToOpen
+            genXXXPackagesToOpenMethods(cw);
 
             return cw;
         }
 
         /**
-         * Generate bytecode for SystemModules::descriptors method
+         * Generate byteccode for no-arg constructor
+         */
+        private void genConstructor(ClassWriter cw) {
+            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitMethodInsn(INVOKESPECIAL,
+                               "java/lang/Object",
+                               "<init>",
+                               "()V",
+                               false);
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        }
+
+        /**
+         * Generate bytecode for hasSplitPackages method
          */
-        private void genDescriptorsMethod() {
-            this.mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
-                                     "descriptors",
+        private void genHasSplitPackages(ClassWriter cw) {
+            boolean distinct = moduleInfos.stream()
+                    .map(ModuleInfo::packages)
+                    .flatMap(Set::stream)
+                    .allMatch(new HashSet<>()::add);
+            boolean hasSplitPackages = !distinct;
+
+            mv = cw.visitMethod(ACC_PUBLIC,
+                                "hasSplitPackages",
+                                "()Z",
+                                "()Z",
+                                null);
+            mv.visitCode();
+            if (hasSplitPackages) {
+                mv.visitInsn(ICONST_1);
+            } else {
+                mv.visitInsn(ICONST_0);
+            }
+            mv.visitInsn(IRETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        }
+
+        /**
+         * Generate bytecode for hasIncubatorModules method
+         */
+        private void genIncubatorModules(ClassWriter cw) {
+            boolean hasIncubatorModules = moduleInfos.stream()
+                    .map(ModuleInfo::moduleResolution)
+                    .filter(mres -> (mres != null && mres.hasIncubatingWarning()))
+                    .findFirst()
+                    .isPresent();
+
+            mv = cw.visitMethod(ACC_PUBLIC,
+                                "hasIncubatorModules",
+                                "()Z",
+                                "()Z",
+                                null);
+            mv.visitCode();
+            if (hasIncubatorModules) {
+                mv.visitInsn(ICONST_1);
+            } else {
+                mv.visitInsn(ICONST_0);
+            }
+            mv.visitInsn(IRETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        }
+
+        /**
+         * Generate bytecode for moduleDescriptors method
+         */
+        private void genModuleDescriptorsMethod(ClassWriter cw) {
+            this.mv = cw.visitMethod(ACC_PUBLIC,
+                                     "moduleDescriptors",
                                      "()" + MODULE_DESCRIPTOR_ARRAY_SIGNATURE,
                                      "()" + MODULE_DESCRIPTOR_ARRAY_SIGNATURE,
                                      null);
@@ -643,11 +739,11 @@
         }
 
         /**
-         * Generate bytecode for SystemModules::targets method
+         * Generate bytecode for moduleTargets method
          */
-        private void genTargetsMethod() {
-            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC+ACC_STATIC,
-                                              "targets",
+        private void genModuleTargetsMethod(ClassWriter cw) {
+            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC,
+                                              "moduleTargets",
                                               "()" + MODULE_TARGET_ARRAY_SIGNATURE,
                                               "()" + MODULE_TARGET_ARRAY_SIGNATURE,
                                               null);
@@ -656,18 +752,34 @@
             mv.visitTypeInsn(ANEWARRAY, MODULE_TARGET_CLASSNAME);
             mv.visitVarInsn(ASTORE, MT_VAR);
 
-            for (int index=0; index < moduleInfos.size(); index++) {
+
+            // if java.base has a ModuleTarget attribute then generate the array
+            // with one element, all other elements will be null.
+
+            ModuleInfo base = moduleInfos.get(0);
+            if (!base.moduleName().equals("java.base"))
+                throw new InternalError("java.base should be first module in list");
+            ModuleTarget target = base.target();
+
+            int count;
+            if (target != null && target.targetPlatform() != null) {
+                count = 1;
+            } else {
+                count = moduleInfos.size();
+            }
+
+            for (int index = 0; index < count; index++) {
                 ModuleInfo minfo = moduleInfos.get(index);
-                if (minfo.target() != null && !minfo.dropModuleTarget) {
+                if (minfo.target() != null) {
                     mv.visitVarInsn(ALOAD, MT_VAR);
                     pushInt(mv, index);
 
-                    // new ModuleTarget(String, String)
+                    // new ModuleTarget(String)
                     mv.visitTypeInsn(NEW, MODULE_TARGET_CLASSNAME);
                     mv.visitInsn(DUP);
                     mv.visitLdcInsn(minfo.target().targetPlatform());
                     mv.visitMethodInsn(INVOKESPECIAL, MODULE_TARGET_CLASSNAME,
-                        "<init>", "(Ljava/lang/String;)V", false);
+                                       "<init>", "(Ljava/lang/String;)V", false);
 
                     mv.visitInsn(AASTORE);
                 }
@@ -680,12 +792,12 @@
         }
 
         /**
-         * Generate bytecode for SystemModules::hashes method
+         * Generate bytecode for moduleHashes method
          */
-        private void genHashesMethod() {
+        private void genModuleHashesMethod(ClassWriter cw) {
             MethodVisitor hmv =
-                cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
-                               "hashes",
+                cw.visitMethod(ACC_PUBLIC,
+                               "moduleHashes",
                                "()" + MODULE_HASHES_ARRAY_SIGNATURE,
                                "()" + MODULE_HASHES_ARRAY_SIGNATURE,
                                null);
@@ -710,11 +822,11 @@
         }
 
         /**
-         * Generate bytecode for SystemModules::methodResoultions method
+         * Generate bytecode for moduleResolutions method
          */
-        private void genModuleResolutionsMethod() {
+        private void genModuleResolutionsMethod(ClassWriter cw) {
             MethodVisitor mresmv =
-                cw.visitMethod(ACC_PUBLIC+ACC_STATIC,
+                cw.visitMethod(ACC_PUBLIC,
                                "moduleResolutions",
                                "()" + MODULE_RESOLUTIONS_ARRAY_SIGNATURE,
                                "()" + MODULE_RESOLUTIONS_ARRAY_SIGNATURE,
@@ -746,75 +858,88 @@
         }
 
         /**
-         * Generate SystemModules::concealedPackagesToOpen and
-         * SystemModules::exportedPackagesToOpen methods.
+         * Generate bytecode for moduleReads method
          */
-        private void genXXXPackagesToOpenMethods() {
-            List<ModuleDescriptor> descriptors = moduleInfos.stream()
-                    .map(ModuleInfo::descriptor)
-                    .collect(Collectors.toList());
-            ModuleFinder finder = finderOf(descriptors);
-            IllegalAccessMaps maps = IllegalAccessMaps.generate(finder);
-            generate("concealedPackagesToOpen", maps.concealedPackagesToOpen());
-            generate("exportedPackagesToOpen", maps.exportedPackagesToOpen());
+        private void genModuleReads(ClassWriter cw, Configuration cf) {
+            // module name -> names of modules that it reads
+            Map<String, Set<String>> map = cf.modules().stream()
+                    .collect(Collectors.toMap(
+                            ResolvedModule::name,
+                            m -> m.reads().stream()
+                                    .map(ResolvedModule::name)
+                                    .collect(Collectors.toSet())));
+            generate(cw, "moduleReads", map, true);
         }
 
         /**
-         * Generate SystemModules:XXXPackagesToOpen
+         * Generate concealedPackagesToOpen and exportedPackagesToOpen methods.
          */
-        private void generate(String methodName, Map<String, Set<String>> map) {
-            // Map<String, Set<String>> XXXPackagesToOpen()
-            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC+ACC_STATIC,
+        private void genXXXPackagesToOpenMethods(ClassWriter cw) {
+            ModuleFinder finder = finderOf(moduleInfos);
+            IllegalAccessMaps maps = IllegalAccessMaps.generate(finder);
+            generate(cw, "concealedPackagesToOpen", maps.concealedPackagesToOpen(), false);
+            generate(cw, "exportedPackagesToOpen", maps.exportedPackagesToOpen(), false);
+        }
+
+        /**
+         * Generate method to return {@code Map<String, Set<String>>}.
+         *
+         * If {@code dedup} is true then the values are de-duplicated.
+         */
+        private void generate(ClassWriter cw,
+                              String methodName,
+                              Map<String, Set<String>> map,
+                              boolean dedup) {
+            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC,
                                               methodName,
                                               "()Ljava/util/Map;",
                                               "()Ljava/util/Map;",
                                               null);
             mv.visitCode();
 
-            // new Map$Entry[moduleCount]
+            // map of Set -> local
+            Map<Set<String>, Integer> locals;
+
+            // generate code to create the sets that are duplicated
+            if (dedup) {
+                Collection<Set<String>> values = map.values();
+                Set<Set<String>> duplicateSets = values.stream()
+                        .distinct()
+                        .filter(s -> Collections.frequency(values, s) > 1)
+                        .collect(Collectors.toSet());
+                locals = new HashMap<>();
+                int index = 1;
+                for (Set<String> s : duplicateSets) {
+                    genImmutableSet(mv, s);
+                    mv.visitVarInsn(ASTORE, index);
+                    locals.put(s, index);
+                    if (++index >= MAX_LOCAL_VARS) {
+                        break;
+                    }
+                }
+            } else {
+                locals = Map.of();
+            }
+
+            // new Map$Entry[size]
             pushInt(mv, map.size());
             mv.visitTypeInsn(ANEWARRAY, "java/util/Map$Entry");
 
             int index = 0;
             for (Map.Entry<String, Set<String>> e : map.entrySet()) {
-                String moduleName = e.getKey();
-                Set<String> packages = e.getValue();
-                int packageCount = packages.size();
+                String name = e.getKey();
+                Set<String> s = e.getValue();
 
                 mv.visitInsn(DUP);
                 pushInt(mv, index);
-                mv.visitLdcInsn(moduleName);
+                mv.visitLdcInsn(name);
 
-                // use Set.of(Object[]) when there are more than 2 packages
-                // use Set.of(Object) or Set.of(Object, Object) when fewer packages
-                if (packageCount > 2) {
-                    pushInt(mv, packageCount);
-                    mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
-                    int i = 0;
-                    for (String pn : packages) {
-                        mv.visitInsn(DUP);
-                        pushInt(mv, i);
-                        mv.visitLdcInsn(pn);
-                        mv.visitInsn(AASTORE);
-                        i++;
-                    }
-                    mv.visitMethodInsn(INVOKESTATIC,
-                                       "java/util/Set",
-                                       "of",
-                                       "([Ljava/lang/Object;)Ljava/util/Set;",
-                                       true);
+                // if de-duplicated then load the local, otherwise generate code
+                Integer varIndex = locals.get(s);
+                if (varIndex == null) {
+                    genImmutableSet(mv, s);
                 } else {
-                    StringBuilder sb = new StringBuilder("(");
-                    for (String pn : packages) {
-                        mv.visitLdcInsn(pn);
-                        sb.append("Ljava/lang/Object;");
-                    }
-                    sb.append(")Ljava/util/Set;");
-                    mv.visitMethodInsn(INVOKESTATIC,
-                                       "java/util/Set",
-                                       "of",
-                                       sb.toString(),
-                                       true);
+                    mv.visitVarInsn(ALOAD, varIndex);
                 }
 
                 String desc = "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/Map$Entry;";
@@ -835,19 +960,42 @@
             mv.visitEnd();
         }
 
-        public boolean isOverriddenClass(String path) {
-            return path.equals("/java.base/" + CLASSNAME + ".class");
-        }
+        /**
+         * Generate code to generate an immutable set.
+         */
+        private void genImmutableSet(MethodVisitor mv, Set<String> set) {
+            int size = set.size();
 
-        void pushInt(MethodVisitor mv, int num) {
-            if (num <= 5) {
-                mv.visitInsn(ICONST_0 + num);
-            } else if (num < Byte.MAX_VALUE) {
-                mv.visitIntInsn(BIPUSH, num);
-            } else if (num < Short.MAX_VALUE) {
-                mv.visitIntInsn(SIPUSH, num);
+            // use Set.of(Object[]) when there are more than 2 elements
+            // use Set.of(Object) or Set.of(Object, Object) when fewer
+            if (size > 2) {
+                pushInt(mv, size);
+                mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
+                int i = 0;
+                for (String element : set) {
+                    mv.visitInsn(DUP);
+                    pushInt(mv, i);
+                    mv.visitLdcInsn(element);
+                    mv.visitInsn(AASTORE);
+                    i++;
+                }
+                mv.visitMethodInsn(INVOKESTATIC,
+                        "java/util/Set",
+                        "of",
+                        "([Ljava/lang/Object;)Ljava/util/Set;",
+                        true);
             } else {
-                throw new IllegalArgumentException("exceed limit: " + num);
+                StringBuilder sb = new StringBuilder("(");
+                for (String element : set) {
+                    mv.visitLdcInsn(element);
+                    sb.append("Ljava/lang/Object;");
+                }
+                sb.append(")Ljava/util/Set;");
+                mv.visitMethodInsn(INVOKESTATIC,
+                        "java/util/Set",
+                        "of",
+                        sb.toString(),
+                        true);
             }
         }
 
@@ -1564,18 +1712,159 @@
         }
     }
 
-    static ModuleFinder finderOf(Iterable<ModuleDescriptor> descriptors) {
+    /**
+     * Generate SystemModulesMap and add it as a resource.
+     *
+     * @return the name of the class resource added to the pool
+     */
+    private String genSystemModulesMapClass(String allSystemModulesClassName,
+                                            String defaultSystemModulesClassName,
+                                            Map<String, String> map,
+                                            ResourcePoolBuilder out) {
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+                                         + ClassWriter.COMPUTE_FRAMES);
+        cw.visit(Opcodes.V1_8,
+                 ACC_FINAL+ACC_SUPER,
+                 SYSTEM_MODULES_MAP_CLASS,
+                 null,
+                 "java/lang/Object",
+                 null);
+
+        // <init>
+        MethodVisitor mv = cw.visitMethod(0, "<init>", "()V", null, null);
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitMethodInsn(INVOKESPECIAL,
+                           "java/lang/Object",
+                           "<init>",
+                           "()V",
+                           false);
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        // allSystemModules()
+        mv = cw.visitMethod(ACC_STATIC,
+                            "allSystemModules",
+                            "()Ljdk/internal/module/SystemModules;",
+                            "()Ljdk/internal/module/SystemModules;",
+                            null);
+        mv.visitCode();
+        mv.visitTypeInsn(NEW, allSystemModulesClassName);
+        mv.visitInsn(DUP);
+        mv.visitMethodInsn(INVOKESPECIAL,
+                           allSystemModulesClassName,
+                           "<init>",
+                           "()V",
+                           false);
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        // defaultSystemModules()
+        mv = cw.visitMethod(ACC_STATIC,
+                            "defaultSystemModules",
+                            "()Ljdk/internal/module/SystemModules;",
+                            "()Ljdk/internal/module/SystemModules;",
+                            null);
+        mv.visitCode();
+        mv.visitTypeInsn(NEW, defaultSystemModulesClassName);
+        mv.visitInsn(DUP);
+        mv.visitMethodInsn(INVOKESPECIAL,
+                           defaultSystemModulesClassName,
+                           "<init>",
+                           "()V",
+                           false);
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        // moduleNames()
+        mv = cw.visitMethod(ACC_STATIC,
+                            "moduleNames",
+                            "()[Ljava/lang/String;",
+                            "()[Ljava/lang/String;",
+                            null);
+        mv.visitCode();
+        pushInt(mv, map.size());
+        mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
+
+        int index = 0;
+        for (String moduleName : map.keySet()) {
+            mv.visitInsn(DUP);                  // arrayref
+            pushInt(mv, index);
+            mv.visitLdcInsn(moduleName);
+            mv.visitInsn(AASTORE);
+            index++;
+        }
+
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        // classNames()
+        mv = cw.visitMethod(ACC_STATIC,
+                            "classNames",
+                            "()[Ljava/lang/String;",
+                            "()[Ljava/lang/String;",
+                            null);
+        mv.visitCode();
+        pushInt(mv, map.size());
+        mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
+
+        index = 0;
+        for (String className : map.values()) {
+            mv.visitInsn(DUP);                  // arrayref
+            pushInt(mv, index);
+            mv.visitLdcInsn(className.replace('/', '.'));
+            mv.visitInsn(AASTORE);
+            index++;
+        }
+
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        // write the class file to the pool as a resource
+        String rn = "/java.base/" + SYSTEM_MODULES_MAP_CLASS + ".class";
+        ResourcePoolEntry e = ResourcePoolEntry.create(rn, cw.toByteArray());
+        out.add(e);
+
+        return rn;
+    }
+
+    /**
+     * Pushes an int constant
+     */
+    private static void pushInt(MethodVisitor mv, int value) {
+        if (value <= 5) {
+            mv.visitInsn(ICONST_0 + value);
+        } else if (value < Byte.MAX_VALUE) {
+            mv.visitIntInsn(BIPUSH, value);
+        } else if (value < Short.MAX_VALUE) {
+            mv.visitIntInsn(SIPUSH, value);
+        } else {
+            throw new IllegalArgumentException("exceed limit: " + value);
+        }
+    }
+
+    /**
+     * Returns a module finder that finds all modules in the given list
+     */
+    private static ModuleFinder finderOf(Collection<ModuleInfo> moduleInfos) {
+        Supplier<ModuleReader> readerSupplier = () -> null;
         Map<String, ModuleReference> namesToReference = new HashMap<>();
-        for (ModuleDescriptor descriptor : descriptors) {
-            String name = descriptor.name();
-            URI uri = URI.create("module:/" + name);
-            ModuleReference mref = new ModuleReference(descriptor, uri) {
-                @Override
-                public ModuleReader open() {
-                    throw new UnsupportedOperationException();
-                }
-            };
-            namesToReference.putIfAbsent(name, mref);
+        for (ModuleInfo mi : moduleInfos) {
+            String name = mi.moduleName();
+            ModuleReference mref
+                = new ModuleReferenceImpl(mi.descriptor(),
+                                          URI.create("jrt:/" + name),
+                                          readerSupplier,
+                                          null,
+                                          mi.target(),
+                                          null,
+                                          null,
+                                          mi.moduleResolution());
+            namesToReference.put(name, mref);
         }
 
         return new ModuleFinder() {
--- a/jdk/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java	Mon Aug 07 09:45:38 2017 -0700
@@ -107,35 +107,38 @@
  * diagnostic command are described in the table below:
  *
  * <table class="striped"><caption style="display:none">description</caption>
+ *   <thead>
  *   <tr>
- *     <th>Name</th><th>Type</th><th>Description</th>
+ *     <th scope="col">Name</th><th scope="col">Type</th><th scope="col">Description</th>
  *   </tr>
+ *   </thead>
+ *   <tbody>
  *   <tr>
- *     <td>dcmd.name</td><td>String</td>
+ *     <th scope="row">dcmd.name</th><td>String</td>
  *     <td>The original diagnostic command name (not the operation name)</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.description</td><td>String</td>
+ *     <th scope="row">dcmd.description</th><td>String</td>
  *     <td>The diagnostic command description</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.help</td><td>String</td>
+ *     <th scope="row">dcmd.help</th><td>String</td>
  *     <td>The full help message for this diagnostic command (same output as
  *          the one produced by the 'help' command)</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.vmImpact</td><td>String</td>
+ *     <th scope="row">dcmd.vmImpact</th><td>String</td>
  *     <td>The impact of the diagnostic command,
  *      this value is the same as the one printed in the 'impact'
  *      section of the help message of the diagnostic command, and it
  *      is different from the getImpact() of the MBeanOperationInfo</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.enabled</td><td>boolean</td>
+ *     <th scope="row">dcmd.enabled</th><td>boolean</td>
  *     <td>True if the diagnostic command is enabled, false otherwise</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.permissionClass</td><td>String</td>
+ *     <th scope="row">dcmd.permissionClass</th><td>String</td>
  *     <td>Some diagnostic command might require a specific permission to be
  *          executed, in addition to the MBeanPermission to invoke their
  *          associated MBean operation. This field returns the fully qualified
@@ -143,22 +146,23 @@
  *   </td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.permissionName</td><td>String</td>
+ *     <th scope="row">dcmd.permissionName</th><td>String</td>
  *     <td>The fist argument of the permission required to execute this
  *          diagnostic command or null if no permission is required</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.permissionAction</td><td>String</td>
+ *     <th scope="row">dcmd.permissionAction</th><td>String</td>
  *     <td>The second argument of the permission required to execute this
  *          diagnostic command or null if the permission constructor has only
  *          one argument (like the ManagementPermission) or if no permission
  *          is required</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.arguments</td><td>Descriptor</td>
+ *     <th scope="row">dcmd.arguments</th><td>Descriptor</td>
  *     <td>A Descriptor instance containing the descriptions of options and
  *          arguments supported by the diagnostic command (see below)</td>
  *   </tr>
+ *   </tbody>
  * </table>
  *
  * <p>The description of parameters (options or arguments) of a diagnostic
@@ -168,37 +172,41 @@
  * instance are described in the table below:
  *
  * <table class="striped"><caption style="display:none">description</caption>
+ *   <thead>
  *   <tr>
- *     <th>Name</th><th>Type</th><th>Description</th>
+ *     <th scope="col">Name</th><th scope="col">Type</th><th scope="col">Description</th>
  *   </tr>
+ *   </thead>
+ *   <tbody>
  *   <tr>
- *     <td>dcmd.arg.name</td><td>String</td>
+ *     <th scope="row">dcmd.arg.name</th><td>String</td>
  *     <td>The name of the parameter</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.arg.type</td><td>String</td>
+ *     <th scope="row">dcmd.arg.type</th><td>String</td>
  *     <td>The type of the parameter. The returned String is the name of a type
  *          recognized by the diagnostic command parser. These types are not
  *          Java types and are implementation dependent.
  *          </td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.arg.description</td><td>String</td>
+ *     <th scope="row">dcmd.arg.description</th><td>String</td>
  *     <td>The parameter description</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.arg.isMandatory</td><td>boolean</td>
+ *     <th scope="row">dcmd.arg.isMandatory</th><td>boolean</td>
  *     <td>True if the parameter is mandatory, false otherwise</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.arg.isOption</td><td>boolean</td>
+ *     <th scope="row">dcmd.arg.isOption</th><td>boolean</td>
  *     <td>True if the parameter is an option, false if it is an argument</td>
  *   </tr>
  *   <tr>
- *     <td>dcmd.arg.isMultiple</td><td>boolean</td>
+ *     <th scope="row">dcmd.arg.isMultiple</th><td>boolean</td>
  *     <td>True if the parameter can be specified several times, false
  *          otherwise</td>
  *   </tr>
+ *   </tbody>
  * </table>
  *
  * <p>When the set of diagnostic commands currently supported by the Java
--- a/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java	Mon Aug 07 09:45:38 2017 -0700
@@ -182,26 +182,30 @@
      * the following attributes:
      * <blockquote>
      * <table class="striped"><caption style="display:none">description</caption>
+     * <thead>
      * <tr>
-     *   <th style="text-align:left">Attribute Name</th>
-     *   <th style="text-align:left">Type</th>
+     *   <th scope="col" style="text-align:left">Attribute Name</th>
+     *   <th scope="col" style="text-align:left">Type</th>
      * </tr>
+     * </thead>
+     * <tbody>
      * <tr>
-     *   <td>gcName</td>
+     *   <th scope="row">gcName</th>
      *   <td>{@code java.lang.String}</td>
      * </tr>
      * <tr>
-     *   <td>gcAction</td>
+     *   <th scope="row">gcAction</th>
      *   <td>{@code java.lang.String}</td>
      * </tr>
      * <tr>
-     *   <td>gcCause</td>
+     *   <th scope="row">gcCause</th>
      *   <td>{@code java.lang.String}</td>
      * </tr>
      * <tr>
-     *   <td>gcInfo</td>
+     *   <th scope="row">gcInfo</th>
      *   <td>{@code javax.management.openmbean.CompositeData}</td>
      * </tr>
+     * </tbody>
      * </table>
      * </blockquote>
      *
--- a/jdk/src/jdk.management/share/classes/com/sun/management/GcInfo.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/GcInfo.java	Mon Aug 07 09:45:38 2017 -0700
@@ -184,30 +184,34 @@
      *
      * <blockquote>
      * <table class="striped"><caption style="display:none">description</caption>
+     * <thead>
      * <tr>
-     *   <th style="text-align:left">Attribute Name</th>
-     *   <th style="text-align:left">Type</th>
+     *   <th scope="col" style="text-align:left">Attribute Name</th>
+     *   <th scope="col" style="text-align:left">Type</th>
      * </tr>
+     * </thead>
+     * <tbody>
      * <tr>
-     *   <td>index</td>
+     *   <th scope="row">index</th>
      *   <td>{@code java.lang.Long}</td>
      * </tr>
      * <tr>
-     *   <td>startTime</td>
+     *   <th scope="row">startTime</th>
      *   <td>{@code java.lang.Long}</td>
      * </tr>
      * <tr>
-     *   <td>endTime</td>
+     *   <th scope="row">endTime</th>
      *   <td>{@code java.lang.Long}</td>
      * </tr>
      * <tr>
-     *   <td>memoryUsageBeforeGc</td>
+     *   <th scope="row">memoryUsageBeforeGc</th>
      *   <td>{@code javax.management.openmbean.TabularData}</td>
      * </tr>
      * <tr>
-     *   <td>memoryUsageAfterGc</td>
+     *   <th scope="row">memoryUsageAfterGc</th>
      *   <td>{@code javax.management.openmbean.TabularData}</td>
      * </tr>
+     * </tbody>
      * </table>
      * </blockquote>
      *
--- a/jdk/src/jdk.management/share/classes/com/sun/management/VMOption.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/VMOption.java	Mon Aug 07 09:45:38 2017 -0700
@@ -191,26 +191,30 @@
      *
      * <blockquote>
      * <table class="striped"><caption style="display:none">description</caption>
+     * <thead>
      * <tr>
-     *   <th style="text-align:left">Attribute Name</th>
-     *   <th style="text-align:left">Type</th>
+     *   <th scope="col" style="text-align:left">Attribute Name</th>
+     *   <th scope="col" style="text-align:left">Type</th>
      * </tr>
+     * </thead>
+     * <tbody>
      * <tr>
-     *   <td>name</td>
+     *   <th scope="row">name</th>
      *   <td>{@code java.lang.String}</td>
      * </tr>
      * <tr>
-     *   <td>value</td>
+     *   <th scope="row">value</th>
      *   <td>{@code java.lang.String}</td>
      * </tr>
      * <tr>
-     *   <td>origin</td>
+     *   <th scope="row">origin</th>
      *   <td>{@code java.lang.String}</td>
      * </tr>
      * <tr>
-     *   <td>writeable</td>
+     *   <th scope="row">writeable</th>
      *   <td>{@code java.lang.Boolean}</td>
      * </tr>
+     * </tbody>
      * </table>
      * </blockquote>
      *
--- a/jdk/src/jdk.net/share/classes/jdk/net/NetworkPermission.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/src/jdk.net/share/classes/jdk/net/NetworkPermission.java	Mon Aug 07 09:45:38 2017 -0700
@@ -36,25 +36,30 @@
  *
  * <table class="striped"><caption style="display:none">permission target name,
  *  what the target allows,and associated risks</caption>
+ * <thead>
  * <tr>
- *   <th>Permission Target Name</th>
- *   <th>What the Permission Allows</th>
- *   <th>Risks of Allowing this Permission</th>
+ *   <th scope="col">Permission Target Name</th>
+ *   <th scope="col">What the Permission Allows</th>
+ *   <th scope="col">Risks of Allowing this Permission</th>
  * </tr>
+ * </thead>
+ * <tbody>
  * <tr>
- *   <td>setOption.SO_FLOW_SLA</td>
+ *   <th scope="row">setOption.SO_FLOW_SLA</th>
  *   <td>set the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA} option
  *       on any socket that supports it</td>
  *   <td>allows caller to set a higher priority or bandwidth allocation
  *       to sockets it creates, than they might otherwise be allowed.</td>
  * </tr>
  * <tr>
- *   <td>getOption.SO_FLOW_SLA</td>
+ *   <th scope="row">getOption.SO_FLOW_SLA</th>
  *   <td>retrieve the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA}
  *       setting from any socket that supports the option</td>
  *   <td>allows caller access to SLA information that it might not
  *       otherwise have</td>
- * </tr></table>
+ * </tr>
+ * </tbody>
+ * </table>
  *
  * @see jdk.net.ExtendedSocketOptions
  *
--- a/jdk/test/java/lang/ClassLoader/getResource/GetResource.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/lang/ClassLoader/getResource/GetResource.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -21,11 +21,45 @@
  * questions.
  */
 
+/*
+ * @test
+ * @bug 6760902
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.ProcessTools
+ * @run testng GetResource
+ * @summary Empty path on bootclasspath is not default to current working
+ *          directory for both class lookup and resource lookup whereas
+ *          empty path on classpath is default to current working directory.
+ */
+
+import java.io.File;
+import java.io.IOException;
 import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.JDKToolFinder;
+import static jdk.testlibrary.ProcessTools.*;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
 
 public class GetResource {
+    private static final Path CWD = Paths.get(System.getProperty("user.dir"));
+    private static final String DIR_A = "a";
+    private static final String DIR_B = "b";
+
     private static final String RESOURCE_NAME = "test.properties";
-    public static void main(String[] args) {
+    private static final String GETRESOURCE_CLASS = "GetResource.class";
+
+    public static void main(String... args) {
         String expect = args[0] + "/" + RESOURCE_NAME;
         URL url = GetResource.class.getResource(RESOURCE_NAME);
         System.out.println("getResource found: " + url);
@@ -39,4 +73,98 @@
             throw new RuntimeException(url + " != expected resource " + expect);
         }
     }
+
+    @BeforeTest
+    public void setup() throws IOException {
+        // setup two directories "a" and "b"
+        // each directory contains both test.properties and this test class
+        Path testSrc = Paths.get(System.getProperty("test.src"));
+        Path testClasses = Paths.get(System.getProperty("test.classes"));
+
+        Files.createDirectories(Paths.get(DIR_A));
+        Files.createDirectories(Paths.get(DIR_B));
+
+        Files.copy(testSrc.resolve(RESOURCE_NAME),
+                   Paths.get(DIR_A, RESOURCE_NAME));
+        Files.copy(testSrc.resolve(RESOURCE_NAME),
+                   Paths.get(DIR_B, RESOURCE_NAME));
+
+        Files.copy(testClasses.resolve(GETRESOURCE_CLASS),
+                   Paths.get(DIR_A, GETRESOURCE_CLASS));
+        Files.copy(testClasses.resolve(GETRESOURCE_CLASS),
+                   Paths.get(DIR_B, GETRESOURCE_CLASS));
+    }
+
+    private String concat(String... dirs) {
+        return Stream.of(dirs).collect(Collectors.joining(File.pathSeparator));
+    }
+
+    @DataProvider
+    public Object[][] options() {
+        return new Object[][] {
+            new Object[] { List.of("-Xbootclasspath/a:a"), "a"},
+            new Object[] { List.of("-Xbootclasspath/a:b"), "b"},
+            new Object[] { List.of("-Xbootclasspath/a:" + concat("a", "b")), "a"},
+            new Object[] { List.of("-Xbootclasspath/a:" + concat("b", "a")), "b"},
+
+            new Object[] { List.of("-cp", "a"), "a"},
+            new Object[] { List.of("-cp", "b"), "b"},
+            new Object[] { List.of("-cp", concat("a", "b")), "a"},
+            new Object[] { List.of("-cp", concat("b", "a")), "b"},
+        };
+    }
+
+    @Test(dataProvider = "options")
+    public void test(List<String> options, String expected) throws Throwable {
+        runTest(CWD, options, expected);
+    }
+
+    @DataProvider
+    public Object[][] dirA() {
+        String dirB = ".." + File.separator + "b";
+        return new Object[][] {
+            new Object[] { List.of("-Xbootclasspath/a:."), "a"},
+
+            new Object[] { List.of("-Xbootclasspath/a:" + dirB), "b"},
+            // empty path in first element
+            new Object[] { List.of("-Xbootclasspath/a:" + File.pathSeparator + dirB), "b"},
+
+            new Object[] { List.of("-cp", File.pathSeparator), "a"},
+            new Object[] { List.of("-cp", dirB), "b"},
+            new Object[] { List.of("-cp", File.pathSeparator + dirB), "a"},
+        };
+    }
+
+    @Test(dataProvider = "dirA")
+    public void testCurrentDirA(List<String> options, String expected) throws Throwable {
+        // current working directory is "a"
+        runTest(CWD.resolve(DIR_A), options, expected);
+    }
+
+    private void runTest(Path dir, List<String> options, String expected)
+        throws Throwable
+    {
+        String javapath = JDKToolFinder.getJDKTool("java");
+
+        List<String> cmdLine = new ArrayList<>();
+        cmdLine.add(javapath);
+        options.forEach(cmdLine::add);
+
+        cmdLine.add("GetResource");
+        cmdLine.add(expected);
+
+        System.out.println("Command line: " + cmdLine);
+        ProcessBuilder pb =
+            new ProcessBuilder(cmdLine.stream().toArray(String[]::new));
+
+        // change working directory
+        pb.directory(dir.toFile());
+
+        // remove CLASSPATH environment variable
+        Map<String,String> env = pb.environment();
+        String value = env.remove("CLASSPATH");
+
+        executeCommand(pb).shouldHaveExitValue(0);
+    }
+
 }
--- a/jdk/test/java/lang/ClassLoader/getResource/GetResource.sh	Mon Aug 07 10:02:39 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-#
-# Copyright (c) 2014, 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.
-#
-
-# @test
-# @bug 6760902
-# @summary Empty path on bootclasspath is not default to current working
-#          directory for both class lookup and resource lookup whereas
-#          empty path on classpath is default to current working directory.
-#
-# @run shell GetResource.sh
-
-if [ -z "$TESTJAVA" ]; then
-  if [ $# -lt 1 ]; then exit 1; fi
-  TESTJAVA="$1"; shift
-  COMPILEJAVA="${TESTJAVA}"
-  TESTSRC="`pwd`"
-  TESTCLASSES="`pwd`"
-fi
-
-# set platform-specific variables
-OS=`uname -s`
-case "$OS" in
-  Windows*)
-    PS=";"
-    ;;
-  CYGWIN* )
-    PS=";"
-    TESTCLASSES=`/usr/bin/cygpath -a -s -m ${TESTCLASSES}`
-    ;;
-  * )
-    PS=":"
-    ;;
-esac
-
-echo TESTSRC=${TESTSRC}
-echo TESTCLASSES=${TESTCLASSES}
-echo TESTJAVA=${TESTJAVA}
-echo ""
-
-${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-        -d ${TESTCLASSES} \
-        ${TESTSRC}/GetResource.java  || exit 10
-
-setup() {
-    dest=${TESTCLASSES}/$1
-    rm -rf $dest
-    mkdir $dest
-    cp ${TESTSRC}/test.properties $dest
-    cp ${TESTCLASSES}/GetResource.class $dest
-}
-
-
-count=0
-runTest() {
-    expected=$1;
-    vmoption=$2; shift; shift
-    count=`expr $count+1`
-    echo "Test $count : $vmoption $@"
-    ${TESTJAVA}/bin/java ${TESTVMOPTS} "$vmoption" $@ \
-        GetResource $expected     || exit $count
-}
-
-# run test
-setup "a"
-setup "b"
-
-cd ${TESTCLASSES}
-DIR=`pwd`
-
-#    Expected    -classpath
-runTest "a"      -cp a
-runTest "a"      -cp "a${PS}b"
-runTest "b"      -cp b
-runTest "b"      -cp "b${PS}a"
-
-cd ${DIR}/a
-
-# no -classpath
-runTest "a"      -cp "${PS}"                            
-runTest "b"      -cp "../b"                   
-
-# Test empty path in classpath default to current working directory
-runTest "a"      -cp "${PS}../b"
-
--- a/jdk/test/java/net/httpclient/security/0.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/0.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/1.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/1.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/10.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/10.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -22,6 +22,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/11.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/11.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -24,6 +24,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/12.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/12.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -24,6 +24,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/14.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/14.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/15.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/15.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -26,6 +26,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/2.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/2.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/3.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/3.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/4.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/4.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -24,6 +24,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/5.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/5.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/6.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/6.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/7.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/7.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/8.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/8.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/9.policy	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/9.policy	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 grant codeBase "jrt:/jdk.incubator.httpclient" {
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.net.util";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www";
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
 
--- a/jdk/test/java/net/httpclient/security/Driver.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/Driver.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -34,7 +34,7 @@
  * @compile ../ProxyServer.java
  * @build Security
  *
- * @run driver/timeout=60 Driver
+ * @run driver/timeout=90 Driver
  */
 
 /**
--- a/jdk/test/java/nio/channels/Selector/KeySets.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/nio/channels/Selector/KeySets.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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,34 +26,25 @@
  * @summary Check various properties of key and selected-key sets
  *
  * @run main KeySets
- * @run main/othervm -Dsun.nio.ch.bugLevel=1.4 KeySets
  */
 
 import java.io.*;
 import java.nio.channels.*;
 import java.util.*;
 
-
 public class KeySets {
 
-    static boolean compat;
-
     static abstract class Catch {
         abstract void go() throws Exception;
         Catch(Class xc) throws Exception {
             try {
                 go();
             } catch (Exception x) {
-                if (compat)
-                    throw new Exception("Exception thrown", x);
                 if (xc.isInstance(x))
                     return;
                 throw new Exception("Wrong exception", x);
             }
-            if (compat)
-                return;
-            throw new Exception("Not thrown as expected: "
-                                + xc.getName());
+            throw new Exception("Not thrown as expected: " + xc.getName());
         }
     }
 
@@ -74,7 +65,6 @@
                 void go() throws Exception {
                     sel.selectedKeys();
                 }};
-
     }
 
     static void testNoAddition(final Set s) throws Exception {
@@ -174,14 +164,10 @@
         sel.selectedKeys().clear();
         if (!sel.selectedKeys().isEmpty())
             throw new Exception("clear failed");
-
     }
 
     public static void main(String[] args) throws Exception {
-        String bl = System.getProperty("sun.nio.ch.bugLevel");
-        compat = (bl != null) && bl.equals("1.4");
         testClose();
         testMutability();
     }
-
 }
--- a/jdk/test/java/rmi/testlibrary/TestSocketFactory.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/rmi/testlibrary/TestSocketFactory.java	Mon Aug 07 09:45:38 2017 -0700
@@ -512,9 +512,8 @@
             } else {
                 if (matchIndex > 0) {
                     // mismatch, write out any that matched already
-                    if (matchIndex > 0) // Only non-trivial matches
-                        DEBUG( "Partial match %s matched %d bytes at offset: %d (0x%04x), expected: x%02x, actual: x%02x%n",
-                                name, matchIndex, bytesOut, bytesOut,  matchBytes[matchIndex], b);
+                    DEBUG("Partial match %s matched %d bytes at offset: %d (0x%04x), expected: x%02x, actual: x%02x%n",
+                            name, matchIndex, bytesOut, bytesOut, matchBytes[matchIndex], b);
                     out.write(matchBytes, 0, matchIndex);
                     log.write(matchBytes, 0, matchIndex);
                     bytesOut += matchIndex;
@@ -530,6 +529,19 @@
             }
         }
 
+        public void flush() throws IOException {
+            if (matchIndex > 0) {
+                // write out any that matched already to avoid consumer hang.
+                // Match/replace across a flush is not supported.
+                DEBUG( "Flush partial match %s matched %d bytes at offset: %d (0x%04x)%n",
+                        name, matchIndex, bytesOut, bytesOut);
+                out.write(matchBytes, 0, matchIndex);
+                log.write(matchBytes, 0, matchIndex);
+                bytesOut += matchIndex;
+                matchIndex = 0;
+            }
+        }
+
         @Override
         public String toString() {
             return String.format("%s: Out: (%d)", name, bytesOut);
--- a/jdk/test/java/util/ResourceBundle/modules/layer/run.sh	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/java/util/ResourceBundle/modules/layer/run.sh	Mon Aug 07 09:45:38 2017 -0700
@@ -22,7 +22,7 @@
 #
 
 # @test
-# @bug 8180375
+# @bug 8180375 8185251
 # @summary Tests resource bundles are correctly loaded from
 #   modules through "<packageName>.spi.<simpleName>Provider" types.
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ResourceBundle/modules/layer/src/m1/p/resources/MyResource_en.properties	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 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
+# 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.
+#
+
+# Purposely empty resource bundle
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/SSLEngine/IllegalHandshakeMessage.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+//
+// This test case relies on updated static security property, no way to re-use
+// security property in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8180643
+ * @summary Illegal handshake message
+ *
+ * @run main/othervm IllegalHandshakeMessage
+ */
+
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.security.*;
+import java.nio.*;
+
+public class IllegalHandshakeMessage {
+
+    public static void main(String args[]) throws Exception {
+        SSLContext context = SSLContext.getDefault();
+
+        SSLEngine cliEngine = context.createSSLEngine();
+        cliEngine.setUseClientMode(true);
+        SSLEngine srvEngine = context.createSSLEngine();
+        srvEngine.setUseClientMode(false);
+
+        SSLSession session = cliEngine.getSession();
+        int netBufferMax = session.getPacketBufferSize();
+        int appBufferMax = session.getApplicationBufferSize();
+
+        ByteBuffer cliToSrv = ByteBuffer.allocateDirect(netBufferMax);
+        ByteBuffer srvToCli = ByteBuffer.allocateDirect(netBufferMax);
+        ByteBuffer srvIBuff = ByteBuffer.allocateDirect(appBufferMax + 50);
+        ByteBuffer cliOBuff = ByteBuffer.wrap("I'm client".getBytes());
+        ByteBuffer srvOBuff = ByteBuffer.wrap("I'm server".getBytes());
+
+
+        System.out.println("client hello (handshake type(0xAB))");
+        SSLEngineResult cliRes = cliEngine.wrap(cliOBuff, cliToSrv);
+        System.out.println("Client wrap result: " + cliRes);
+        cliToSrv.flip();
+        if (cliToSrv.limit() > 7) {
+            cliToSrv.put(5, (byte)0xAB);    // use illegal handshake type
+            cliToSrv.put(7, (byte)0x80);    // use illegal message length
+        } else {
+            // unlikely
+            throw new Exception("No handshage message generated.");
+        }
+
+        try {
+            SSLEngineResult srvRes = srvEngine.unwrap(cliToSrv, srvIBuff);
+            System.out.println("Server unwrap result: " + srvRes);
+            runDelegatedTasks(srvRes, srvEngine);
+
+            srvRes = srvEngine.wrap(srvOBuff, srvToCli);
+            System.out.println("Server wrap result: " + srvRes);
+
+            throw new Exception(
+                "Unsupported handshake message is not handled properly.");
+        } catch (SSLException e) {
+            // get the expected exception
+            System.out.println("Expected exception: " + e);
+        }
+    }
+
+    private static void runDelegatedTasks(SSLEngineResult result,
+            SSLEngine engine) throws Exception {
+
+        if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+            Runnable runnable;
+            while ((runnable = engine.getDelegatedTask()) != null) {
+                System.out.println("\trunning delegated task...");
+                runnable.run();
+            }
+            HandshakeStatus hsStatus = engine.getHandshakeStatus();
+            if (hsStatus == HandshakeStatus.NEED_TASK) {
+                throw new Exception(
+                    "handshake shouldn't need additional tasks");
+            }
+            System.out.println("\tnew HandshakeStatus: " + hsStatus);
+        }
+    }
+}
+
--- a/jdk/test/tools/jlink/plugins/SystemModuleDescriptors/SystemModulesTest.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/tools/jlink/plugins/SystemModuleDescriptors/SystemModulesTest.java	Mon Aug 07 09:45:38 2017 -0700
@@ -111,16 +111,10 @@
 
     private void checkAttributes(ModuleReference modRef) {
         try {
-            if (modRef.descriptor().name().equals("java.base")) {
-                ModuleTargetHelper.ModuleTarget mt = ModuleTargetHelper.read(modRef);
-                String[] values = mt.targetPlatform().split("-");
-                assertTrue(checkOSName(values[0]));
-                assertTrue(checkOSArch(values[1]));
-            } else {
-                // target platform attribute is dropped by jlink plugin for other modules
-                ModuleTargetHelper.ModuleTarget mt = ModuleTargetHelper.read(modRef);
-                assertTrue(mt == null || mt.targetPlatform() == null);
-            }
+            ModuleTargetHelper.ModuleTarget mt = ModuleTargetHelper.read(modRef);
+            String[] values = mt.targetPlatform().split("-");
+            assertTrue(checkOSName(values[0]));
+            assertTrue(checkOSArch(values[1]));
         } catch (IOException exp) {
             throw new UncheckedIOException(exp);
         }
--- a/jdk/test/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java	Mon Aug 07 09:45:38 2017 -0700
@@ -284,7 +284,6 @@
         Set<String> modules = Set.of("m1", "m4");
         assertTrue(JLINK_TOOL.run(System.out, System.out,
             "--output", dir.toString(),
-            "--system-modules", "retainModuleTarget",
             "--exclude-resources", "m4/p4/dummy/*",
             "--add-modules", modules.stream().collect(Collectors.joining(",")),
             "--module-path", mp) == 0);
--- a/jdk/test/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java	Mon Aug 07 09:45:38 2017 -0700
@@ -32,7 +32,7 @@
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 import jdk.internal.module.ClassFileAttributes;
@@ -67,8 +67,7 @@
     }
 
     private static boolean hasModuleTarget(String modName) throws IOException {
-        FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
-                                                  Collections.emptyMap());
+        FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), Map.of());
         Path path = fs.getPath("/", "modules", modName, "module-info.class");
         try (InputStream in = Files.newInputStream(path)) {
             return hasModuleTarget(in);
@@ -86,8 +85,8 @@
             expectModuleTarget = true;
         }
 
-        // java.base is packaged with osName/osArch/osVersion
-        if (! hasModuleTarget("java.base")) {
+        // java.base is packaged with ModuleTarget
+        if (!hasModuleTarget("java.base")) {
             throw new RuntimeException("ModuleTarget absent for java.base");
         }
 
@@ -109,8 +108,7 @@
         }
 
         // verify ModuleDescriptor from module-info.class read from jimage
-        FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
-            Collections.emptyMap());
+        FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), Map.of());
         Path path = fs.getPath("/", "modules", mn, "module-info.class");
         checkModuleDescriptor(ModuleDescriptor.read(Files.newInputStream(path)), packages);
     }
@@ -121,16 +119,9 @@
             throw new RuntimeException(md.mainClass().toString());
         }
 
-        if (expectModuleTarget) {
-            // ModuleTarget attribute is retained
-            if (! hasModuleTarget(md.name())) {
-                throw new RuntimeException("ModuleTarget missing for " + md.name());
-            }
-        } else {
-            // by default ModuleTarget attribute is dropped
-            if (hasModuleTarget(md.name())) {
-                throw new RuntimeException("ModuleTarget present for " + md.name());
-            }
+        // ModuleTarget attribute should be present
+        if (!hasModuleTarget(md.name())) {
+            throw new RuntimeException("ModuleTarget missing for " + md.name());
         }
 
         Set<String> pkgs = md.packages();
--- a/jdk/test/tools/launcher/modules/illegalaccess/IllegalAccessTest.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/jdk/test/tools/launcher/modules/illegalaccess/IllegalAccessTest.java	Mon Aug 07 09:45:38 2017 -0700
@@ -23,6 +23,7 @@
 
 /**
  * @test
+ * @requires vm.compMode != "Xcomp"
  * @modules java.base/jdk.internal.misc
  *          java.base/sun.security.x509
  *          java.activation
--- a/jdk/test/tools/launcher/modules/patch/systemmodules/src1/java.base/jdk/internal/modules/SystemModules.java	Mon Aug 07 10:02:39 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2016, 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 jdk.internal.module;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-/*
- * Test --patch-module java.base=jdk/modules/java.base to override
- * java.base with an exploded image
- */
-public final class SystemModules {
-    public static final String[] MODULE_NAMES = new String[0];
-
-    public static int PACKAGES_IN_BOOT_LAYER = 1024;
-
-    public static boolean hasSplitPackages() {
-        return true;
-    }
-
-    public static Map<String, Set<String>> concealedPackagesToOpen() {
-        return Collections.emptyMap();
-    }
-
-    public static Map<String, Set<String>> exportedPackagesToOpen() {
-        return Collections.emptyMap();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/patch/systemmodules/src1/java.base/jdk/internal/modules/SystemModulesMap.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,47 @@
+/*
+ * 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
+ * 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 jdk.internal.module;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/*
+ * Test --patch-module java.base=jdk/modules/java.base to override
+ * java.base with an exploded image
+ */
+class SystemModulesMap {
+    static SystemModules allSystemModules() {
+        return null;
+    }
+    static SystemModules defaultSystemModules() {
+        return null;
+    }
+    static String[] moduleNames() {
+        return new String[0];
+    }
+    static String[] classNames() {
+        return new String[0];
+    }
+}
--- a/langtools/.hgtags	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/.hgtags	Mon Aug 07 09:45:38 2017 -0700
@@ -437,3 +437,6 @@
 2f01728210c1405ef459e69d9c7247b5df6abb78 jdk-9+177
 2b9273266ea629ca686239c416a7ff8a592d822a jdk-10+15
 4070d214e88729006184a4abbe8f494fcec6afb6 jdk-10+16
+849e366ef175012e6dedc3ca151da416716e0ea9 jdk-9+178
+b653b1b2ea883593596bc18e9af73a9b369eeb0a jdk-9+179
+41028d8c0a71c6beaf1886ca095e703fbb1513ec jdk-10+17
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/javadoc/Doclet.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/javadoc/Doclet.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, 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
@@ -30,7 +30,7 @@
  * showing the entry-point methods.  A starting class must
  * import com.sun.javadoc.* and implement the
  * {@code start(RootDoc)} method, as described in the
- * <a href="package-summary.html#package_description">package
+ * <a href="package-summary.html#package.description">package
  * description</a>.  If the doclet takes command line options,
  * it must also implement {@code optionLength} and
  * {@code validOptions}.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/Doclet.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/Doclet.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -33,7 +33,7 @@
 
 /**
  * The user doclet must implement this interface, as described in the
- * <a href="package-summary.html#package_description">package description</a>.
+ * <a href="package-summary.html#package.description">package description</a>.
  * Each implementation of a Doclet must provide a public no-argument constructor
  * to be used by tools to instantiate the doclet. The tool infrastructure will
  * interact with classes implementing this interface as follows:
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Mon Aug 07 09:45:38 2017 -0700
@@ -40,10 +40,12 @@
 
 import jdk.javadoc.doclet.Doclet;
 import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlVersion;
 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
 import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.DocletException;
 import jdk.javadoc.internal.doclets.toolkit.Messages;
 import jdk.javadoc.internal.doclets.toolkit.Resources;
 import jdk.javadoc.internal.doclets.toolkit.WriterFactory;
@@ -162,6 +164,11 @@
     public boolean createtree = true;
 
     /**
+     * The META charset tag used for cross-platform viewing.
+     */
+    public String charset = null;
+
+    /**
      * True if command line option "-nodeprecated" is used. Default value is
      * false.
      */
@@ -797,4 +804,23 @@
         oset.addAll(super.getSupportedOptions());
         return oset;
     }
+
+    @Override
+    protected boolean finishOptionSettings0() throws DocletException {
+        if (docencoding == null) {
+            if (charset == null) {
+                docencoding = charset = (encoding == null) ? HtmlConstants.HTML_DEFAULT_CHARSET : encoding;
+            } else {
+                docencoding = charset;
+            }
+        } else {
+            if (charset == null) {
+                charset = docencoding;
+            } else if (!charset.equals(docencoding)) {
+                reporter.print(ERROR, getText("doclet.Option_conflict", "-charset", "-docencoding"));
+                return false;
+            }
+        }
+        return super.finishOptionSettings0();
+    }
 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Mon Aug 07 09:45:38 2017 -0700
@@ -446,9 +446,7 @@
         Content head = new HtmlTree(HtmlTag.HEAD);
         head.addContent(getGeneratedBy(!configuration.notimestamp));
         head.addContent(getTitle());
-        Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
-                (configuration.charset.length() > 0) ?
-                        configuration.charset : HtmlConstants.HTML_DEFAULT_CHARSET);
+        Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, configuration.charset);
         head.addContent(meta);
         if (!configuration.notimestamp) {
             SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java	Mon Aug 07 09:45:38 2017 -0700
@@ -78,9 +78,7 @@
 
         Content windowTitle = HtmlTree.TITLE(new StringContent(title));
         head.addContent(windowTitle);
-        Content metaContentType = HtmlTree.META("Content", CONTENT_TYPE,
-                (configuration.charset.length() > 0) ?
-                        configuration.charset : HtmlConstants.HTML_DEFAULT_CHARSET);
+        Content metaContentType = HtmlTree.META("Content", CONTENT_TYPE, configuration.charset);
         head.addContent(metaContentType);
 
         String topFilePath = configuration.topFile.getPath();
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1007,8 +1007,7 @@
                 ? getHyperLink(SectionName.PACKAGES, contents.navPackages)
                 : contents.navPackages);
         addNavGap(liNav);
-        liNav.addContent((display(uses) || (moduleMode == ModuleMode.API && display(usesTrees))
-                || display(provides) || (moduleMode == ModuleMode.API && display(providesTrees)))
+        liNav.addContent((displayServices(uses, usesTrees) || displayServices(provides.keySet(), providesTrees))
                 ? getHyperLink(SectionName.SERVICES, contents.navServices)
                 : contents.navServices);
         ulNav.addContent(liNav);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java	Mon Aug 07 09:45:38 2017 -0700
@@ -247,6 +247,7 @@
     public void addPackageDescription(Content packageContentTree) {
         if (!utils.getBody(packageElement).isEmpty()) {
             Content tree = configuration.allowTag(HtmlTag.SECTION) ? sectionTree : packageContentTree;
+            tree.addContent(getMarkerAnchor(SectionName.PACKAGE_DESCRIPTION));
             addDeprecationInfo(tree);
             addInlineComment(packageElement, tree);
         }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Mon Aug 07 09:45:38 2017 -0700
@@ -328,9 +328,7 @@
         head.addContent(getGeneratedBy(!configuration.notimestamp));
         Content windowTitle = HtmlTree.TITLE(new StringContent(title));
         head.addContent(windowTitle);
-        Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
-                (configuration.charset.length() > 0) ?
-                        configuration.charset : HtmlConstants.HTML_DEFAULT_CHARSET);
+        Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, configuration.charset);
         head.addContent(meta);
         head.addContent(getStyleSheetProperties(configuration));
         head.addContent(getFramesJavaScript());
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java	Mon Aug 07 09:45:38 2017 -0700
@@ -55,6 +55,7 @@
 import jdk.javadoc.internal.doclets.toolkit.util.SimpleDocletException;
 import jdk.javadoc.internal.doclets.toolkit.util.TypeElementCatalog;
 import jdk.javadoc.internal.doclets.toolkit.util.Utils;
+import jdk.javadoc.internal.doclets.toolkit.util.Utils.Pair;
 import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap;
 import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.GetterSetter;
 import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.Kind;
@@ -66,11 +67,11 @@
  * BaseConfiguration, to configure and add their own options. This class contains
  * all user options which are supported by the 1.1 doclet and the standard
  * doclet.
- *
- *  <p><b>This is NOT part of any supported API.
- *  If you write code that depends on this, you do so at your own risk.
- *  This code and its internal interfaces are subject to change or
- *  deletion without notice.</b>
+ * <p>
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
  *
  * @author Robert Field.
  * @author Atul Dambalkar.
@@ -142,11 +143,6 @@
     public boolean backwardCompatibility = true;
 
     /**
-     * The META charset tag used for cross-platform viewing.
-     */
-    public String charset = "";
-
-    /**
      * True if user wants to add member names as meta keywords.
      * Set to false because meta keywords are ignored in general
      * by most Internet search engines.
@@ -240,7 +236,6 @@
 
     /**
      * Sourcepath from where to read the source files. Default is classpath.
-     *
      */
     public String sourcepath = "";
 
@@ -266,7 +261,7 @@
      * True if user wants to suppress time stamp in output.
      * Default is false.
      */
-    public boolean notimestamp= false;
+    public boolean notimestamp = false;
 
     /**
      * The package grouping instance.
@@ -278,7 +273,7 @@
      */
     public final Extern extern = new Extern(this);
 
-    public  Reporter reporter;
+    public Reporter reporter;
 
     public Locale locale;
 
@@ -287,21 +282,21 @@
      */
     public boolean quiet = false;
 
-    private String urlForLink;
-
-    private String pkglistUrlForLink;
+    // A list containing urls
+    private final List<String> linkList = new ArrayList<>();
 
-    private String urlForLinkOffline;
+     // A list of pairs containing urls and package list
+    private final List<Pair<String, String>> linkOfflineList = new ArrayList<>();
 
-    private String pkglistUrlForLinkOffline;
 
     public boolean dumpOnError = false;
 
-    private List<GroupContainer> groups;
+    private List<Pair<String, String>> groupPairs;
 
     private final Map<TypeElement, EnumMap<Kind, Reference<VisibleMemberMap>>> typeElementMemberCache;
 
     public abstract Messages getMessages();
+
     public abstract Resources getResources();
 
     /**
@@ -342,15 +337,17 @@
      */
     public SortedMap<ModuleElement, Set<PackageElement>> modulePackages;
 
-   /**
-    * The list of known modules, that should be documented.
-    */
+    /**
+     * The list of known modules, that should be documented.
+     */
     public SortedSet<ModuleElement> modules;
 
     protected static final String sharedResourceBundleName =
             "jdk.javadoc.internal.doclets.toolkit.resources.doclets";
+
     /**
      * Constructs the configurations needed by the doclet.
+     *
      * @param doclet the doclet that created this configuration
      */
     public BaseConfiguration(Doclet doclet) {
@@ -359,7 +356,7 @@
         excludedQualifiers = new HashSet<>();
         setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH);
         metakeywords = new MetaKeywords(this);
-        groups = new ArrayList<>(0);
+        groupPairs = new ArrayList<>(0);
         typeElementMemberCache = new HashMap<>();
     }
 
@@ -400,31 +397,37 @@
     }
 
     private Set<ModuleElement> specifiedModuleElements;
+
     public Set<ModuleElement> getSpecifiedModuleElements() {
         return specifiedModuleElements;
     }
 
     private Set<PackageElement> specifiedPackageElements;
+
     public Set<PackageElement> getSpecifiedPackageElements() {
         return specifiedPackageElements;
     }
 
     private Set<TypeElement> specifiedTypeElements;
+
     public Set<TypeElement> getSpecifiedTypeElements() {
         return specifiedTypeElements;
     }
 
     private Set<ModuleElement> includedModuleElements;
+
     public Set<ModuleElement> getIncludedModuleElements() {
         return includedModuleElements;
     }
 
     private Set<PackageElement> includedPackageElements;
+
     public Set<PackageElement> getIncludedPackageElements() {
         return includedPackageElements;
     }
 
     private Set<TypeElement> includedTypeElements;
+
     public Set<TypeElement> getIncludedTypeElements() {
         return includedTypeElements;
     }
@@ -435,7 +438,7 @@
         modules.addAll(getSpecifiedModuleElements());
 
         modulePackages = new TreeMap<>(utils.makeModuleComparator());
-        for (PackageElement p: packages) {
+        for (PackageElement p : packages) {
             ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
             if (mdle != null && !mdle.isUnnamed()) {
                 Set<PackageElement> s = modulePackages
@@ -444,7 +447,7 @@
             }
         }
 
-        for (PackageElement p: getIncludedPackageElements()) {
+        for (PackageElement p : getIncludedPackageElements()) {
             ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
             if (mdle != null && !mdle.isUnnamed()) {
                 Set<PackageElement> s = modulePackages
@@ -474,207 +477,205 @@
     public Set<Doclet.Option> getSupportedOptions() {
         Resources resources = getResources();
         Doclet.Option[] options = {
-            new Option(resources, "-author") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    showauthor = true;
-                    return true;
-                }
-            },
-            new Option(resources, "-d", 1) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    destDirName = addTrailingFileSep(args.get(0));
-                    return true;
-                }
-            },
-            new Option(resources, "-docencoding", 1) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    docencoding = args.get(0);
-                    return true;
-                }
-            },
-            new Option(resources, "-docfilessubdirs") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    copydocfilesubdirs = true;
-                    return true;
-                }
-            },
-            new Hidden(resources, "-encoding", 1) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    encoding = args.get(0);
-                    return true;
-                }
-            },
-            new Option(resources, "-excludedocfilessubdir", 1) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    addToSet(excludedDocFileDirs, args.get(0));
-                    return true;
-                }
-            },
-            new Option(resources, "-group", 2) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    groups.add(new GroupContainer(args.get(0), args.get(1)));
-                    return true;
-                }
-            },
-            new Option(resources, "--javafx -javafx") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    javafx = true;
-                    return true;
-                }
-            },
-            new Option(resources, "-keywords") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    keywords = true;
-                    return true;
-                }
-            },
-            new Option(resources, "-link", 1) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    urlForLink = args.get(0);
-                    pkglistUrlForLink = urlForLink;
-                    return true;
-                }
-            },
-            new Option(resources, "-linksource") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    linksource = true;
-                    return true;
-                }
-            },
-            new Option(resources, "-linkoffline", 2) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    urlForLinkOffline = args.get(0);
-                    pkglistUrlForLinkOffline = args.get(1);
-                    return true;
-                }
-            },
-            new Option(resources, "-nocomment") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    nocomment = true;
-                    return true;
-                }
-            },
-            new Option(resources, "-nodeprecated") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    nodeprecated = true;
-                    return true;
+                new Option(resources, "-author") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        showauthor = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "-d", 1) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        destDirName = addTrailingFileSep(args.get(0));
+                        return true;
+                    }
+                },
+                new Option(resources, "-docencoding", 1) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        docencoding = args.get(0);
+                        return true;
+                    }
+                },
+                new Option(resources, "-docfilessubdirs") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        copydocfilesubdirs = true;
+                        return true;
+                    }
+                },
+                new Hidden(resources, "-encoding", 1) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        encoding = args.get(0);
+                        return true;
+                    }
+                },
+                new Option(resources, "-excludedocfilessubdir", 1) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        addToSet(excludedDocFileDirs, args.get(0));
+                        return true;
+                    }
+                },
+                new Option(resources, "-group", 2) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        groupPairs.add(new Pair<>(args.get(0), args.get(1)));
+                        return true;
+                    }
+                },
+                new Option(resources, "--javafx -javafx") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        javafx = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "-keywords") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        keywords = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "-link", 1) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        linkList.add(args.get(0));
+                        return true;
+                    }
+                },
+                new Option(resources, "-linksource") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        linksource = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "-linkoffline", 2) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        linkOfflineList.add(new Pair<String, String>(args.get(0), args.get(1)));
+                        return true;
+                    }
+                },
+                new Option(resources, "-nocomment") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        nocomment = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "-nodeprecated") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        nodeprecated = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "-nosince") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        nosince = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "-notimestamp") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        notimestamp = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "-noqualifier", 1) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        addToSet(excludedQualifiers, args.get(0));
+                        return true;
+                    }
+                },
+                new Hidden(resources, "-quiet") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        quiet = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "-serialwarn") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        serialwarn = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "-sourcetab", 1) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        linksource = true;
+                        try {
+                            setTabWidth(Integer.parseInt(args.get(0)));
+                        } catch (NumberFormatException e) {
+                            //Set to -1 so that warning will be printed
+                            //to indicate what is valid argument.
+                            sourcetab = -1;
+                        }
+                        if (sourcetab <= 0) {
+                            getMessages().warning("doclet.sourcetab_warning");
+                            setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH);
+                        }
+                        return true;
+                    }
+                },
+                new Option(resources, "-tag", 1) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        ArrayList<String> list = new ArrayList<>();
+                        list.add(opt);
+                        list.add(args.get(0));
+                        customTagStrs.add(list);
+                        return true;
+                    }
+                },
+                new Option(resources, "-taglet", 1) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        ArrayList<String> list = new ArrayList<>();
+                        list.add(opt);
+                        list.add(args.get(0));
+                        customTagStrs.add(list);
+                        return true;
+                    }
+                },
+                new Option(resources, "-tagletpath", 1) {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        tagletpath = args.get(0);
+                        return true;
+                    }
+                },
+                new Option(resources, "-version") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        showversion = true;
+                        return true;
+                    }
+                },
+                new Hidden(resources, "--dump-on-error") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        dumpOnError = true;
+                        return true;
+                    }
+                },
+                new Option(resources, "--allow-script-in-comments") {
+                    @Override
+                    public boolean process(String opt, List<String> args) {
+                        allowScriptInComments = true;
+                        return true;
+                    }
                 }
-            },
-            new Option(resources, "-nosince") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    nosince = true;
-                    return true;
-                }
-            },
-            new Option(resources, "-notimestamp") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    notimestamp = true;
-                    return true;
-                }
-            },
-            new Option(resources, "-noqualifier", 1) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    addToSet(excludedQualifiers, args.get(0));
-                    return true;
-                }
-            },
-            new Hidden(resources, "-quiet") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    quiet = true;
-                    return true;
-                }
-            },
-            new Option(resources, "-serialwarn") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    serialwarn = true;
-                    return true;
-                }
-            },
-            new Option(resources, "-sourcetab", 1) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    linksource = true;
-                    try {
-                        setTabWidth(Integer.parseInt(args.get(0)));
-                    } catch (NumberFormatException e) {
-                             //Set to -1 so that warning will be printed
-                        //to indicate what is valid argument.
-                        sourcetab = -1;
-                    }
-                    if (sourcetab <= 0) {
-                        getMessages().warning("doclet.sourcetab_warning");
-                        setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH);
-                    }
-                    return true;
-                }
-            },
-            new Option(resources, "-tag", 1) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    ArrayList<String> list = new ArrayList<>();
-                    list.add(opt);
-                    list.add(args.get(0));
-                    customTagStrs.add(list);
-                    return true;
-                }
-            },
-             new Option(resources, "-taglet", 1) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    ArrayList<String> list = new ArrayList<>();
-                    list.add(opt);
-                    list.add(args.get(0));
-                    customTagStrs.add(list);
-                    return true;
-                }
-            },
-            new Option(resources, "-tagletpath", 1) {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    tagletpath = args.get(0);
-                    return true;
-                }
-            },
-            new Option(resources, "-version") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    showversion = true;
-                    return true;
-                }
-            },
-            new Hidden(resources, "--dump-on-error") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    dumpOnError = true;
-                    return true;
-                }
-            },
-            new Option(resources, "--allow-script-in-comments") {
-                @Override
-                public boolean process(String opt, List<String> args) {
-                    allowScriptInComments = true;
-                    return true;
-                }
-            }
         };
         Set<Doclet.Option> set = new TreeSet<>();
         set.addAll(Arrays.asList(options));
@@ -687,24 +688,24 @@
      * when this is called all the option have been set, this method,
      * initializes certain components before anything else is started.
      */
-    private void finishOptionSettings0() throws DocletException {
+    protected boolean finishOptionSettings0() throws DocletException {
         initDestDirectory();
-        if (urlForLink != null && pkglistUrlForLink != null)
-            extern.link(urlForLink, pkglistUrlForLink, reporter, false);
-        if (urlForLinkOffline != null && pkglistUrlForLinkOffline != null)
-            extern.link(urlForLinkOffline, pkglistUrlForLinkOffline, reporter, true);
-        if (docencoding == null) {
-            docencoding = encoding;
+        for (String link : linkList) {
+            extern.link(link, reporter);
+        }
+        for (Pair<String, String> linkOfflinePair : linkOfflineList) {
+            extern.link(linkOfflinePair.first, linkOfflinePair.second, reporter);
         }
         typeElementCatalog = new TypeElementCatalog(includedTypeElements, this);
         initTagletManager(customTagStrs);
-        groups.stream().forEach((grp) -> {
+        groupPairs.stream().forEach((grp) -> {
             if (showModules) {
-                group.checkModuleGroups(grp.value1, grp.value2);
+                group.checkModuleGroups(grp.first, grp.second);
             } else {
-                group.checkPackageGroups(grp.value1, grp.value2);
+                group.checkPackageGroups(grp.first, grp.second);
             }
         });
+        return true;
     }
 
     /**
@@ -716,8 +717,7 @@
     public boolean setOptions() throws DocletException {
         initPackages();
         initModules();
-        finishOptionSettings0();
-        if (!finishOptionSettings())
+        if (!finishOptionSettings0() || !finishOptionSettings())
             return false;
 
         return true;
@@ -748,12 +748,12 @@
      * be in the following format:  "[tag name]:[location str]:[heading]".
      *
      * @param customTagStrs the set two dimensional arrays of strings.  These arrays contain
-     * either -tag or -taglet arguments.
+     *                      either -tag or -taglet arguments.
      */
     private void initTagletManager(Set<List<String>> customTagStrs) {
         tagletManager = tagletManager == null ?
-            new TagletManager(nosince, showversion, showauthor, javafx, this) :
-            tagletManager;
+                new TagletManager(nosince, showversion, showauthor, javafx, this) :
+                tagletManager;
         for (List<String> args : customTagStrs) {
             if (args.get(0).equals("-taglet")) {
                 tagletManager.addCustomTag(args.get(1), getFileManager(), tagletpath);
@@ -793,12 +793,11 @@
      * @param maxTokens the maximum number of tokens returned.  If the
      *                  max is reached, the remaining part of s is appended
      *                  to the end of the last token.
-     *
      * @return an array of tokens.
      */
     private List<String> tokenize(String s, char separator, int maxTokens) {
         List<String> tokens = new ArrayList<>();
-        StringBuilder  token = new StringBuilder ();
+        StringBuilder token = new StringBuilder();
         boolean prevIsEscapeChar = false;
         for (int i = 0; i < s.length(); i += Character.charCount(i)) {
             int currentChar = s.codePointAt(i);
@@ -806,7 +805,7 @@
                 // Case 1:  escaped character
                 token.appendCodePoint(currentChar);
                 prevIsEscapeChar = false;
-            } else if (currentChar == separator && tokens.size() < maxTokens-1) {
+            } else if (currentChar == separator && tokens.size() < maxTokens - 1) {
                 // Case 2:  separator
                 tokens.add(token.toString());
                 token = new StringBuilder();
@@ -824,10 +823,10 @@
         return tokens;
     }
 
-    private void addToSet(Set<String> s, String str){
+    private void addToSet(Set<String> s, String str) {
         StringTokenizer st = new StringTokenizer(str, ":");
         String current;
-        while(st.hasMoreTokens()){
+        while (st.hasMoreTokens()) {
             current = st.nextToken();
             s.add(current);
         }
@@ -847,7 +846,7 @@
         int indexDblfs;
         while ((indexDblfs = path.indexOf(dblfs, 1)) >= 0) {
             path = path.substring(0, indexDblfs) +
-                path.substring(indexDblfs + fs.length());
+                    path.substring(indexDblfs + fs.length());
         }
         if (!path.endsWith(fs))
             path += fs;
@@ -855,7 +854,6 @@
     }
 
     /**
-     *
      * This checks for the validity of the options used by the user.
      * As of this writing, this checks only docencoding.
      *
@@ -883,7 +881,7 @@
      * @param reporter    used to report errors.
      */
     private boolean checkOutputFileEncoding(String docencoding) {
-        OutputStream ost= new ByteArrayOutputStream();
+        OutputStream ost = new ByteArrayOutputStream();
         OutputStreamWriter osw = null;
         try {
             osw = new OutputStreamWriter(ost, docencoding);
@@ -908,7 +906,7 @@
      * @param docfilesubdir the doc-files subdirectory to check.
      * @return true if the directory is excluded.
      */
-    public boolean shouldExcludeDocFileDir(String docfilesubdir){
+    public boolean shouldExcludeDocFileDir(String docfilesubdir) {
         return excludedDocFileDirs.contains(docfilesubdir);
     }
 
@@ -918,10 +916,10 @@
      * @param qualifier the qualifier to check.
      * @return true if the qualifier should be excluded
      */
-    public boolean shouldExcludeQualifier(String qualifier){
+    public boolean shouldExcludeQualifier(String qualifier) {
         if (excludedQualifiers.contains("all") ||
-            excludedQualifiers.contains(qualifier) ||
-            excludedQualifiers.contains(qualifier + ".*")) {
+                excludedQualifiers.contains(qualifier) ||
+                excludedQualifiers.contains(qualifier + ".*")) {
             return true;
         } else {
             int index = -1;
@@ -956,7 +954,7 @@
      * @param key the key for the desired string
      * @return the string for the given key
      * @throws MissingResourceException if the key is not found in either
-     *  bundle.
+     *                                  bundle.
      */
     public abstract String getText(String key);
 
@@ -965,11 +963,11 @@
      * {@link Resources resources}.
      * Equivalent to <code>getResources.getText(key, args);</code>.
      *
-     * @param key the key for the desired string
+     * @param key  the key for the desired string
      * @param args values to be substituted into the resulting string
      * @return the string for the given key
      * @throws MissingResourceException if the key is not found in either
-     *  bundle.
+     *                                  bundle.
      */
     public abstract String getText(String key, String... args);
 
@@ -997,8 +995,8 @@
      * {@link Resources resources} as a {@code Content} object.
      *
      * @param key the key for the desired string
-     * @param o1 resource argument
-     * @param o2 resource argument
+     * @param o1  resource argument
+     * @param o2  resource argument
      * @return a content tree for the text
      */
     public abstract Content getContent(String key, Object o1, Object o2);
@@ -1045,8 +1043,8 @@
      */
     public InputStream getBuilderXML() throws DocFileIOException {
         return builderXMLPath == null ?
-            BaseConfiguration.class.getResourceAsStream(DEFAULT_BUILDER_XML) :
-            DocFile.createFileForInput(this, builderXMLPath).openInputStream();
+                BaseConfiguration.class.getResourceAsStream(DEFAULT_BUILDER_XML) :
+                DocFile.createFileForInput(this, builderXMLPath).openInputStream();
     }
 
     /**
@@ -1203,18 +1201,6 @@
     }
 
     /*
-     * Stores a pair of Strings.
-     */
-    protected static class GroupContainer {
-        final String value1;
-        final String value2;
-        public GroupContainer(String value1, String value2) {
-            this.value1 = value1;
-            this.value2 = value2;
-        }
-    }
-
-    /*
      * Splits the elements in a collection to its individual
      * collection.
      */
@@ -1267,6 +1253,7 @@
     /**
      * Returns whether or not to allow JavaScript in comments.
      * Default is off; can be set true from a command line option.
+     *
      * @return the allowScriptInComments
      */
     public boolean isAllowScriptInComments() {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java	Mon Aug 07 09:45:38 2017 -0700
@@ -170,6 +170,36 @@
     }
 
     /**
+     * Build the extern package list from given URL or the directory path,
+     * as specified with the "-link" flag.
+     * Flag error if the "-link" or "-linkoffline" option is already used.
+     *
+     * @param url        URL or Directory path.
+     * @param reporter   The <code>DocErrorReporter</code> used to report errors.
+     * @return true if successful, false otherwise
+     * @throws DocFileIOException if there is a problem reading a package list file
+     */
+    public boolean link(String url, Reporter reporter) throws DocFileIOException {
+        return link(url, url, reporter, false);
+    }
+
+    /**
+     * Build the extern package list from given URL or the directory path,
+     * as specified with the "-linkoffline" flag.
+     * Flag error if the "-link" or "-linkoffline" option is already used.
+     *
+     * @param url        URL or Directory path.
+     * @param pkglisturl This can be another URL for "package-list" or ordinary
+     *                   file.
+     * @param reporter   The <code>DocErrorReporter</code> used to report errors.
+     * @return true if successful, false otherwise
+     * @throws DocFileIOException if there is a problem reading a package list file
+     */
+    public boolean link(String url, String pkglisturl, Reporter reporter) throws DocFileIOException {
+        return link(url, pkglisturl, reporter, true);
+    }
+
+    /*
      * Build the extern package list from given URL or the directory path.
      * Flag error if the "-link" or "-linkoffline" option is already used.
      *
@@ -181,7 +211,7 @@
      * @return true if successful, false otherwise
      * @throws DocFileIOException if there is a problem reading a package list file
      */
-    public boolean link(String url, String pkglisturl, Reporter reporter, boolean linkoffline)
+    private boolean link(String url, String pkglisturl, Reporter reporter, boolean linkoffline)
                 throws DocFileIOException {
         this.linkoffline = linkoffline;
         try {
@@ -245,8 +275,7 @@
             readPackageList(link.openStream(), urlpath, false);
         } catch (URISyntaxException | MalformedURLException exc) {
             throw new Fault(configuration.getText("doclet.MalformedURL", pkglisturlpath.toString()), exc);
-        }
-        catch (IOException exc) {
+        } catch (IOException exc) {
             throw new Fault(configuration.getText("doclet.URL_error", pkglisturlpath.toString()), exc);
         }
     }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/StandardDocFileFactory.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/StandardDocFileFactory.java	Mon Aug 07 09:45:38 2017 -0700
@@ -202,11 +202,7 @@
 
             try {
                 OutputStream out = getFileObjectForOutput(path).openOutputStream();
-                if (configuration.docencoding == null) {
-                    return new BufferedWriter(new OutputStreamWriter(out));
-                } else {
-                    return new BufferedWriter(new OutputStreamWriter(out, configuration.docencoding));
-                }
+                return new BufferedWriter(new OutputStreamWriter(out, configuration.docencoding));
             } catch (IOException e) {
                 throw new DocFileIOException(this, DocFileIOException.Mode.WRITE, e);
             }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Mon Aug 07 09:45:38 2017 -0700
@@ -679,10 +679,11 @@
         }
     }
 
-   /**
+    /**
      * Get the signature. It is the parameter list, type is qualified.
      * For instance, for a method {@code mymethod(String x, int y)},
      * it will return {@code(java.lang.String,int)}.
+     *
      * @param e
      * @return String
      */
@@ -1674,19 +1675,24 @@
         }
     }
 
+    private Comparator<Element> moduleComparator = null;
     /**
      * Comparator for ModuleElements, simply compares the fully qualified names
      * @return a Comparator
      */
     public Comparator<Element> makeModuleComparator() {
-        return new Utils.ElementComparator<Element>() {
-            @Override
-            public int compare(Element mod1, Element mod2) {
-                return compareFullyQualifiedNames(mod1, mod2);
-            }
-        };
+        if (moduleComparator == null) {
+            moduleComparator = new Utils.ElementComparator() {
+                @Override
+                public int compare(Element mod1, Element mod2) {
+                    return compareFullyQualifiedNames(mod1, mod2);
+                }
+            };
+        }
+        return moduleComparator;
     }
 
+    private Comparator<Element> allClassesComparator = null;
     /**
      * Returns a Comparator for all classes, compares the simple names of
      * TypeElement, if equal then the fully qualified names.
@@ -1694,42 +1700,53 @@
      * @return Comparator
      */
     public Comparator<Element> makeAllClassesComparator() {
-        return new Utils.ElementComparator<Element>() {
-            @Override
-            public int compare(Element e1, Element e2) {
-                int result =  compareNames(e1, e2);
-                if (result == 0)
-                    result =  compareFullyQualifiedNames(e1, e2);
-
-                return result;
-            }
-        };
+        if (allClassesComparator == null) {
+            allClassesComparator = new Utils.ElementComparator() {
+                @Override
+                public int compare(Element e1, Element e2) {
+                    int result = compareNames(e1, e2);
+                    if (result == 0)
+                        result = compareFullyQualifiedNames(e1, e2);
+
+                    return result;
+                }
+            };
+        }
+        return allClassesComparator;
     }
 
+    private Comparator<Element> packageComparator = null;
     /**
      * Returns a Comparator for packages, by comparing the fully qualified names.
      *
      * @return a Comparator
      */
     public Comparator<Element> makePackageComparator() {
-        return new Utils.ElementComparator<Element>() {
-            @Override
-            public int compare(Element pkg1, Element pkg2) {
-                return compareFullyQualifiedNames(pkg1, pkg2);
-            }
-        };
+        if (packageComparator == null) {
+            packageComparator = new Utils.ElementComparator() {
+                @Override
+                public int compare(Element pkg1, Element pkg2) {
+                    return compareFullyQualifiedNames(pkg1, pkg2);
+                }
+            };
+        }
+        return packageComparator;
     }
 
+    private Comparator<SerialFieldTree> serialFieldTreeComparator = null;
     /**
      * Returns a Comparator for SerialFieldTree.
      * @return a Comparator
      */
     public Comparator<SerialFieldTree> makeSerialFieldTreeComparator() {
-        return (SerialFieldTree o1, SerialFieldTree o2) -> {
-            String s1 = o1.getName().toString();
-            String s2 = o2.getName().toString();
-            return s1.compareTo(s2);
-        };
+        if (serialFieldTreeComparator == null) {
+            serialFieldTreeComparator = (SerialFieldTree o1, SerialFieldTree o2) -> {
+                String s1 = o1.getName().toString();
+                String s2 = o2.getName().toString();
+                return s1.compareTo(s2);
+            };
+        }
+        return serialFieldTreeComparator;
     }
 
     /**
@@ -1740,6 +1757,7 @@
         return makeClassUseComparator();
     }
 
+    private Comparator<Element> overrideUseComparator = null;
     /**
      * Returns a Comparator for overrides and implements,
      * used primarily on methods, compares the name first,
@@ -1748,33 +1766,38 @@
      * @return a Comparator
      */
     public Comparator<Element> makeOverrideUseComparator() {
-        return new Utils.ElementComparator<Element>() {
-            @Override
-            public int compare(Element o1, Element o2) {
-                int result = compareStrings(getSimpleName(o1), getSimpleName(o2));
-                if (result != 0) {
-                    return result;
-                }
-                if (!isTypeElement(o1) && !isTypeElement(o2) && !isPackage(o1) && !isPackage(o2)) {
-                    TypeElement t1 = getEnclosingTypeElement(o1);
-                    TypeElement t2 = getEnclosingTypeElement(o2);
-                    result = compareStrings(getSimpleName(t1), getSimpleName(t2));
+        if (overrideUseComparator == null) {
+            overrideUseComparator = new Utils.ElementComparator() {
+                @Override
+                public int compare(Element o1, Element o2) {
+                    int result = compareStrings(getSimpleName(o1), getSimpleName(o2));
+                    if (result != 0) {
+                        return result;
+                    }
+                    if (!isTypeElement(o1) && !isTypeElement(o2) && !isPackage(o1) && !isPackage(o2)) {
+                        TypeElement t1 = getEnclosingTypeElement(o1);
+                        TypeElement t2 = getEnclosingTypeElement(o2);
+                        result = compareStrings(getSimpleName(t1), getSimpleName(t2));
+                        if (result != 0)
+                            return result;
+                    }
+                    result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2));
                     if (result != 0)
                         return result;
+                    return compareElementTypeKinds(o1, o2);
                 }
-                result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2));
-                if (result != 0)
-                    return result;
-                return compareElementTypeKinds(o1, o2);
-            }
-        };
+            };
+        }
+        return overrideUseComparator;
     }
 
+    private Comparator<Element> indexUseComparator = null;
     /**
-     * Returns a Comparator for index file presentations, and are sorted as follows.
-     *  If comparing modules and packages then simply compare the qualified names, if comparing a module
-     *  or a package with a type/member then compare the FullyQualifiedName of the module or a package
-     *  with the SimpleName of the entity, otherwise
+     *  Returns a Comparator for index file presentations, and are sorted as follows.
+     *  If comparing modules and/or packages then simply compare the qualified names,
+     *  if comparing a module or a package with a type/member then compare the
+     *  FullyQualifiedName of the module or a package with the SimpleName of the entity,
+     *  otherwise:
      *  1. compare the ElementKind ex: Module, Package, Interface etc.
      *  2a. if equal and if the type is of ExecutableElement(Constructor, Methods),
      *      a case insensitive comparison of parameter the type signatures
@@ -1783,73 +1806,76 @@
      * @return a comparator for index file use
      */
     public Comparator<Element> makeIndexUseComparator() {
-        return new Utils.ElementComparator<Element>() {
-            /**
-             * Compare two given elements, if comparing two modules or two packages, return the
-             * comparison of FullyQualifiedName, if comparing a module or a package with a
-             * type/member then compare the FullyQualifiedName of the module or the package
-             * with the SimpleName of the entity, then sort on the kinds, then on
-             * the parameters only if the type is an ExecutableElement,
-             * the parameters are compared and finally the qualified names.
-             *
-             * @param e1 - an element.
-             * @param e2 - an element.
-             * @return a negative integer, zero, or a positive integer as the first
-             *         argument is less than, equal to, or greater than the second.
-             */
-            @Override
-            public int compare(Element e1, Element e2) {
-                int result = 0;
-                if ((isModule(e1) || isPackage(e1)) && (isModule(e2) || isPackage(e2))) {
-                    result = compareFullyQualifiedNames(e1, e2);
+        if (indexUseComparator == null) {
+            indexUseComparator = new Utils.ElementComparator() {
+                /**
+                 * Compares two elements.
+                 *
+                 * @param e1 - an element.
+                 * @param e2 - an element.
+                 * @return a negative integer, zero, or a positive integer as the first
+                 * argument is less than, equal to, or greater than the second.
+                 */
+                @Override
+                public int compare(Element e1, Element e2) {
+                    int result;
+                    // first, compare names as appropriate
+                    if ((isModule(e1) || isPackage(e1)) && (isModule(e2) || isPackage(e2))) {
+                        result = compareFullyQualifiedNames(e1, e2);
+                    } else if (isModule(e1) || isPackage(e1)) {
+                        result = compareStrings(getFullyQualifiedName(e1), getSimpleName(e2));
+                    } else if (isModule(e2) || isPackage(e2)) {
+                        result = compareStrings(getSimpleName(e1), getFullyQualifiedName(e2));
+                    } else {
+                        result = compareNames(e1, e2);
+                    }
                     if (result != 0) {
                         return result;
                     }
-                    return compareElementTypeKinds(e1, e2);
-                }
-                if (isModule(e1) || isPackage(e1)) {
-                    result = compareStrings(getFullyQualifiedName(e1), getSimpleName(e2));
-                } else if (isModule(e2) || isPackage(e2)) {
-                    result = compareStrings(getSimpleName(e1), getFullyQualifiedName(e2));
-                } else {
-                    result = compareNames(e1, e2);
-                }
-                if (result != 0) {
-                    return result;
-                }
-                result = compareElementTypeKinds(e1, e2);
-                if (result != 0) {
-                    return result;
-                }
-                if (hasParameters(e1)) {
-                    List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
-                    List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
-                    result = compareParameters(false, parameters1, parameters2);
+                    // if names are the same, compare element kinds
+                    result = compareElementTypeKinds(e1, e2);
                     if (result != 0) {
                         return result;
                     }
-                    result = compareParameters(true, parameters1, parameters2);
-                    if (result != 0) {
-                        return result;
+                    // if element kinds are the same, and are methods,
+                    // compare the method parameters
+                    if (hasParameters(e1)) {
+                        List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
+                        List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
+                        result = compareParameters(false, parameters1, parameters2);
+                        if (result != 0) {
+                            return result;
+                        }
+                        result = compareParameters(true, parameters1, parameters2);
+                        if (result != 0) {
+                            return result;
+                        }
                     }
+                    // else fall back on fully qualified names
+                    return compareFullyQualifiedNames(e1, e2);
                 }
-                return compareFullyQualifiedNames(e1, e2);
-            }
-        };
+            };
+        }
+        return indexUseComparator;
     }
 
+    private Comparator<TypeMirror> typeMirrorClassUseComparator = null;
     /**
      * Compares the FullyQualifiedNames of two TypeMirrors
      * @return
      */
     public Comparator<TypeMirror> makeTypeMirrorClassUseComparator() {
-        return (TypeMirror type1, TypeMirror type2) -> {
-            String s1 = getQualifiedTypeName(type1);
-            String s2 = getQualifiedTypeName(type2);
-            return compareStrings(s1, s2);
-        };
+        if (typeMirrorClassUseComparator == null) {
+            typeMirrorClassUseComparator = (TypeMirror type1, TypeMirror type2) -> {
+                String s1 = getQualifiedTypeName(type1);
+                String s2 = getQualifiedTypeName(type2);
+                return compareStrings(s1, s2);
+            };
+        }
+        return typeMirrorClassUseComparator;
     }
 
+    private Comparator<TypeMirror> typeMirrorIndexUseComparator = null;
     /**
      * Compares the SimpleNames of TypeMirrors if equal then the
      * FullyQualifiedNames of TypeMirrors.
@@ -1857,12 +1883,15 @@
      * @return
      */
     public Comparator<TypeMirror> makeTypeMirrorIndexUseComparator() {
-        return (TypeMirror t1, TypeMirror t2) -> {
-            int result = compareStrings(getTypeName(t1, false), getTypeName(t2, false));
-            if (result != 0)
-                return result;
-            return compareStrings(getQualifiedTypeName(t1), getQualifiedTypeName(t2));
-        };
+        if (typeMirrorIndexUseComparator == null) {
+            typeMirrorIndexUseComparator = (TypeMirror t1, TypeMirror t2) -> {
+                int result = compareStrings(getTypeName(t1, false), getTypeName(t2, false));
+                if (result != 0)
+                    return result;
+                return compareStrings(getQualifiedTypeName(t1), getQualifiedTypeName(t2));
+            };
+        }
+        return typeMirrorIndexUseComparator;
     }
 
     /**
@@ -1936,6 +1965,7 @@
         }.visit(e);
     }
 
+    private Comparator<Element> classUseComparator = null;
     /**
      * Comparator for ClassUse presentations, and sorts as follows:
      * 1. member names
@@ -1945,51 +1975,52 @@
      * @return a comparator to sort classes and members for class use
      */
     public Comparator<Element> makeClassUseComparator() {
-        return new Utils.ElementComparator<Element>() {
-            /**
-             * Compare two Elements, first sort on simple name, and if
-             * applicable on the fully qualified name, and finally if applicable
-             * on the parameter types.
-             * @param e1 - an element.
-             * @param e2 - an element.
-             * @return a negative integer, zero, or a positive integer as the first
-             *         argument is less than, equal to, or greater than the second.
-             */
-            @Override
-            public int compare(Element e1, Element e2) {
-                int result = compareNames(e1, e2);
-                if (result != 0) {
-                    return result;
-                }
-                result = compareFullyQualifiedNames(e1, e2);
-                if (result != 0) {
-                    return result;
-                }
-                if (hasParameters(e1) && hasParameters(e2)) {
-                    @SuppressWarnings("unchecked")
-                    List<VariableElement> parameters1 = (List<VariableElement>) ((ExecutableElement)e1).getParameters();
-                    @SuppressWarnings("unchecked")
-                    List<VariableElement> parameters2 = (List<VariableElement>) ((ExecutableElement)e2).getParameters();
-                    result =  compareParameters(false, parameters1, parameters2);
+        if (classUseComparator == null) {
+            classUseComparator = new Utils.ElementComparator() {
+                /**
+                 * Compares two Elements.
+                 *
+                 * @param e1 - an element.
+                 * @param e2 - an element.
+                 * @return a negative integer, zero, or a positive integer as the first
+                 * argument is less than, equal to, or greater than the second.
+                 */
+                @Override
+                public int compare(Element e1, Element e2) {
+                    int result = compareNames(e1, e2);
+                    if (result != 0) {
+                        return result;
+                    }
+                    result = compareFullyQualifiedNames(e1, e2);
                     if (result != 0) {
                         return result;
                     }
-                    result =  compareParameters(true, parameters1, parameters2);
+                    if (hasParameters(e1) && hasParameters(e2)) {
+                        @SuppressWarnings("unchecked")
+                        List<VariableElement> parameters1 = (List<VariableElement>)((ExecutableElement)e1).getParameters();
+                        @SuppressWarnings("unchecked")
+                        List<VariableElement> parameters2 = (List<VariableElement>)((ExecutableElement)e2).getParameters();
+                        result = compareParameters(false, parameters1, parameters2);
+                        if (result != 0) {
+                            return result;
+                        }
+                        result = compareParameters(true, parameters1, parameters2);
+                    }
+                    if (result != 0) {
+                        return result;
+                    }
+                    return compareElementTypeKinds(e1, e2);
                 }
-                if (result != 0) {
-                    return result;
-                }
-                return compareElementTypeKinds(e1, e2);
-            }
-        };
+            };
+        }
+        return classUseComparator;
     }
 
     /**
      * A general purpose comparator to sort Element entities, basically provides the building blocks
      * for creating specific comparators for an use-case.
-     * @param <T> an Element
      */
-    private abstract class ElementComparator<T extends Element> implements Comparator<Element> {
+    private abstract class ElementComparator implements Comparator<Element> {
         /**
          * compares two parameter arrays by first comparing the length of the arrays, and
          * then each Type of the parameter in the array.
@@ -2097,8 +2128,6 @@
         /**
          * The fully qualified names of the entities, used solely by the comparator.
          *
-         * @param p1 the first Element.
-         * @param p2 the first Element.
          * @return a negative integer, zero, or a positive integer as the first argument is less
          * than, equal to, or greater than the second.
          */
@@ -3299,4 +3328,19 @@
             return out;
         }
     }
+
+    /**
+     * A simple pair container.
+     * @param <K> first a value
+     * @param <L> second another value
+     */
+    public static class Pair<K, L> {
+        public final K first;
+        public final L second;
+
+        public Pair(K first, L second) {
+            this.first = first;
+            this.second = second;
+        }
+    }
 }
--- a/langtools/test/TEST.groups	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/test/TEST.groups	Mon Aug 07 09:45:38 2017 -0700
@@ -27,11 +27,13 @@
     jdk \
     lib \
     tools \
+    -jdk/jshell/ExternalEditorTest.java \
     -jdk/jshell/ToolReloadTest.java \
     -jdk/jshell/ToolLocaleMessageTest.java
 
 # (Almost) no langtools tests are tier 2.
 tier2 = \
+    jdk/jshell/ExternalEditorTest.java \
     jdk/jshell/ToolReloadTest.java \
     jdk/jshell/ToolLocaleMessageTest.java
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testCharsetDocencodingOptions/TestCharsetDocencodingOptions.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug      8183582
+ * @summary  Rationalize doclet -docencoding and -charset options.
+ * @library  ../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build    JavadocTester
+ * @run main TestCharsetDocencodingOptions
+ */
+
+public class TestCharsetDocencodingOptions extends JavadocTester {
+
+    public static void main(String... args) throws Exception {
+        TestCharsetDocencodingOptions tester = new TestCharsetDocencodingOptions();
+        tester.runTests();
+    }
+
+    @Test
+    void testWithNoOptions() {
+        javadoc("-d", "out",
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutputFileEncoding("utf-8");
+    }
+
+    @Test
+    void testWithDocencoding() {
+        javadoc("-d", "out-1",
+                "-docencoding", "ISO-8859-1",
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutputFileEncoding("ISO-8859-1");
+    }
+
+    @Test
+    void testWithCharset() {
+        javadoc("-d", "out-2",
+                "-charset", "ISO-8859-1",
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutputFileEncoding("ISO-8859-1");
+    }
+
+    @Test
+    void testDocencodingWithCharsetSimilar() {
+        javadoc("-d", "out-3",
+                "-docencoding", "ISO-8859-1",
+                "-charset", "ISO-8859-1",
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutputFileEncoding("ISO-8859-1");
+    }
+
+    @Test
+    void testDocencodingWithCharsetDifferent() {
+        javadoc("-d", "out-4",
+                "-charset", "UTF-8",
+                "-docencoding", "ISO-8859-1",
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.ERROR);
+
+        checkOutput(Output.OUT, true,
+                "javadoc: error - Option -charset conflicts with -docencoding");
+    }
+
+    @Test
+    void testWithEncoding() {
+        javadoc("-d", "out-5",
+                "-sourcepath", testSrc,
+                "-encoding", "ISO-8859-1",
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutputFileEncoding("ISO-8859-1");
+    }
+
+
+    void checkOutputFileEncoding(String charset) {
+        checkOutput("index.html", true,
+                "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + charset + "\">");
+        checkOutput("pkg/Foo.html", true,
+                "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + charset + "\">");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testCharsetDocencodingOptions/pkg/Foo.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 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
+ * 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 pkg;
+
+public class Foo {}
--- a/langtools/test/jdk/javadoc/doclet/testHtmlTag/TestHtmlTag.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testHtmlTag/TestHtmlTag.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -106,7 +106,9 @@
         checkExit(Exit.OK);
 
         checkOutput("pkg3/package-summary.html", true,
-                "<div class=\"contentContainer\">\n"
+                "<div class=\"contentContainer\"><a name=\"package.description\">\n"
+                + "<!--   -->\n"
+                + "</a>\n"
                 + "<div class=\"block\"><p>This is the first line."
                 + " Note the newlines before the &lt;p&gt; is relevant.</div>");
 
--- a/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java	Mon Aug 07 09:45:38 2017 -0700
@@ -161,7 +161,9 @@
                 + "<!-- ========= START OF TOP NAVBAR ======= -->",
                 "<main role=\"main\">\n"
                 + "<div class=\"header\">",
-                "<section role=\"region\">\n"
+                "<section role=\"region\"><a id=\"package.description\">\n"
+                + "<!--   -->\n"
+                + "</a>\n"
                 + "<div class=\"block\">Test package.</div>",
                 "<footer role=\"contentinfo\">\n"
                 + "<nav role=\"navigation\">\n"
@@ -1107,7 +1109,9 @@
                 "<a name=\"navbar.top.firstrow\">\n"
                 + "<!--   -->\n"
                 + "</a>",
-                "<div class=\"contentContainer\">\n"
+                "<div class=\"contentContainer\"><a name=\"package.description\">\n"
+                + "<!--   -->\n"
+                + "</a>\n"
                 + "<div class=\"block\">Test package.</div>",
                 "<table class=\"typeSummary\" summary=\"Interface Summary table, listing interfaces, and an explanation\">",
                 "<table class=\"typeSummary\" summary=\"Class Summary table, listing classes, and an explanation\">",
--- a/langtools/test/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java	Mon Aug 07 09:45:38 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 4720957 5020118 8026567 8038976
+ * @bug 4720957 5020118 8026567 8038976 8184969
  * @summary Test to make sure that -link and -linkoffline link to
  * right files, and URLs with and without trailing slash are accepted.
  * @author jamieh
@@ -135,6 +135,46 @@
         // this is the text that is given when there is a problem with a URL
         checkOutput(Output.OUT, false,
                 "warning - Error fetching URL");
+
+        // check multiple link options
+        javadoc("-d", "out5",
+                "-sourcepath", testSrc,
+                "-link", "../" + "out1",
+                "-link", "../" + "out2",
+                "pkg3");
+        checkExit(Exit.OK);
+        checkOutput("pkg3/A.html", true,
+                "<pre>public class <span class=\"typeNameLabel\">A</span>\n"
+                + "extends java.lang.Object</pre>\n"
+                + "<div class=\"block\">Test links.\n"
+                + " <br>\n"
+                + " <a href=\"../../out2/pkg2/C2.html?is-external=true\" "
+                + "title=\"class or interface in pkg2\"><code>link to pkg2.C2</code></a>\n"
+                + " <br>\n"
+                + " <a href=\"../../out1/mylib/lang/StringBuilderChild.html?is-external=true\" "
+                + "title=\"class or interface in mylib.lang\">"
+                + "<code>link to mylib.lang.StringBuilderChild</code></a>.</div>\n"
+        );
+
+        // check multiple linkoffline options
+        javadoc("-d", "out6",
+                "-sourcepath", testSrc,
+                "-linkoffline", "../copy/out1", "out1",
+                "-linkoffline", "../copy/out2", "out2",
+                "pkg3");
+        checkExit(Exit.OK);
+        checkOutput("pkg3/A.html", true,
+                "<pre>public class <span class=\"typeNameLabel\">A</span>\n"
+                        + "extends java.lang.Object</pre>\n"
+                        + "<div class=\"block\">Test links.\n"
+                        + " <br>\n"
+                        + " <a href=\"../../copy/out2/pkg2/C2.html?is-external=true\" "
+                        + "title=\"class or interface in pkg2\"><code>link to pkg2.C2</code></a>\n"
+                        + " <br>\n"
+                        + " <a href=\"../../copy/out1/mylib/lang/StringBuilderChild.html?is-external=true\" "
+                        + "title=\"class or interface in mylib.lang\">"
+                        + "<code>link to mylib.lang.StringBuilderChild</code></a>.</div>\n"
+        );
     }
 
     /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testLinkOption/pkg3/A.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 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
+ * 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 pkg3;
+
+/**
+ * Test links.
+ * <br>
+ * {@link pkg2.C2 link to pkg2.C2}
+ * <br>
+ * {@link mylib.lang.StringBuilderChild link to mylib.lang.StringBuilderChild}.
+ */
+
+public class A {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testModules/TestModuleServicesLink.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8185151
+ * @summary test that navigation summary links are not linked when there are no dependencies
+ * @modules jdk.javadoc/jdk.javadoc.internal.api
+ *          jdk.javadoc/jdk.javadoc.internal.tool
+ * @library ../lib /tools/lib
+ * @build toolbox.ToolBox toolbox.ModuleBuilder JavadocTester
+ * @run main TestModuleServicesLink
+ */
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import toolbox.*;
+
+public class TestModuleServicesLink extends JavadocTester {
+
+    public final ToolBox tb;
+    public static void main(String... args) throws Exception {
+        TestModuleServicesLink  tester = new TestModuleServicesLink ();
+        tester.runTests(m -> new Object[] { Paths.get(m.getName()) });
+    }
+
+    public TestModuleServicesLink () {
+        tb = new ToolBox();
+    }
+
+    @Test
+    public void checkNavbarWithServices1(Path base) throws Exception {
+        ModuleBuilder mb = new ModuleBuilder(tb, "m")
+                .comment("module m.\n@uses p1.A")
+                .uses("p1.A")
+                .uses("p1.B")
+                .exports("p1")
+                .classes("package p1; public class A {}")
+                .classes("package p1; public class B {}");
+        mb.write(base);
+
+        javadoc("-d", base.toString() + "/out",
+                "-quiet",
+                "--module-source-path", base.toString(),
+                "--module", "m");
+        checkExit(Exit.OK);
+
+        checkOutput("m-summary.html", true,
+                "<a href=\"#module.description\">Description</a>&nbsp;|"
+                + "&nbsp;Modules&nbsp;|"
+                + "&nbsp;<a href=\"#packages.summary\">Packages</a>&nbsp;|"
+                + "&nbsp;<a href=\"#services.summary\">Services</a>");
+
+    }
+
+    @Test
+    public void checkNavbarWithServices2(Path base) throws Exception {
+        ModuleBuilder mb = new ModuleBuilder(tb, "m")
+                        .comment("module m.\n@provides p1.A")
+                        .provides("p1.A", "p1.B")
+                        .exports("p1")
+                        .classes("package p1; public interface A {}")
+                        .classes("package p1; public class B implements A {}");
+        mb.write(base);
+
+        javadoc("-d", base.toString() + "/out",
+                "-quiet",
+                "--module-source-path", base.toString(),
+                "--module", "m");
+        checkExit(Exit.OK);
+
+        checkOutput("m-summary.html", true,
+                "<a href=\"#module.description\">Description</a>&nbsp;|"
+                + "&nbsp;Modules&nbsp;|"
+                + "&nbsp;<a href=\"#packages.summary\">Packages</a>&nbsp;|"
+                + "&nbsp;<a href=\"#services.summary\">Services</a>");
+
+    }
+
+    @Test
+    public void checkNavbarWithoutServices(Path base) throws Exception {
+        ModuleBuilder mb = new ModuleBuilder(tb, "m")
+                .exports("p1")
+                .classes("package p1; public class A {}")
+                .classes("package p1; public class B {}");
+        mb.write(base);
+
+        javadoc("-d", base.toString() + "/out",
+                "-quiet",
+                "--module-source-path", base.toString(),
+                "--module", "m");
+        checkExit(Exit.OK);
+
+        checkOutput("m-summary.html", true,
+                "Description&nbsp;|&nbsp;Modules&nbsp;|"
+                + "&nbsp;<a href=\"#packages.summary\">Packages</a>&nbsp;|"
+                + "&nbsp;Services");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testPackageDescription/TestPackageDescription.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug      8185194
+ * @summary  Test anchor for package description in package summary page
+  * @library  ../lib/
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build    JavadocTester TestPackageDescription
+ * @run main TestPackageDescription
+ */
+
+public class TestPackageDescription extends JavadocTester {
+
+    public static void main(String... args) throws Exception {
+        TestPackageDescription tester = new TestPackageDescription();
+        tester.runTests();
+    }
+
+    @Test
+    void test1() {
+        javadoc("-d", "out",
+                "-sourcepath", testSrc,
+                "pkg",
+                "-html5");
+        checkExit(Exit.OK);
+
+        checkOutput("pkg/package-summary.html", true,
+                "<a id=\"package.description\">\n"
+                + "<!--   -->\n"
+                + "</a>\n"
+                + "<div class=\"block\">package description</div>\n");
+    }
+
+    @Test
+    void test2() {
+        javadoc("-d", "out-2",
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutput("pkg/package-summary.html", true,
+                "<a name=\"package.description\">\n"
+                + "<!--   -->\n"
+                + "</a>\n"
+                + "<div class=\"block\">package description</div>\n");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testPackageDescription/pkg/A.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 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
+ * 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 pkg;
+
+public class A {
+
+   public A() {
+   }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testPackageDescription/pkg/package-info.java	Mon Aug 07 09:45:38 2017 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 description
+ *
+ */
+package pkg;
--- a/langtools/test/jdk/jshell/ExternalEditorTest.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/langtools/test/jdk/jshell/ExternalEditorTest.java	Mon Aug 07 09:45:38 2017 -0700
@@ -28,6 +28,7 @@
  * @modules jdk.jshell/jdk.internal.jshell.tool
  * @build ReplToolTesting CustomEditor EditorTestBase
  * @run testng ExternalEditorTest
+ * @key intermittent
  */
 
 import java.io.BufferedWriter;
--- a/nashorn/.hgtags	Mon Aug 07 10:02:39 2017 +0530
+++ b/nashorn/.hgtags	Mon Aug 07 09:45:38 2017 -0700
@@ -428,3 +428,6 @@
 aa7404e062b95f679018f25eaaf933dcf0cf3f2b jdk-9+177
 f8a0c4895b2abe64a8c55af6117ffda192e34d30 jdk-10+15
 f456f59dad3f6b74bcc3c668a56d51f5955cfb28 jdk-10+16
+7497ad85759ff010f44344b553223d1647fb6eba jdk-9+178
+3adfb547e3e49e304ffc82d8c6489cb830b74d62 jdk-9+179
+6ac0ca441ccb9ccc49c5007248dc1f3af8076a71 jdk-10+17
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java	Mon Aug 07 09:45:38 2017 -0700
@@ -90,9 +90,9 @@
 @ScriptClass("Global")
 public final class Global extends Scope {
     // This special value is used to flag a lazily initialized global property.
-    // This also serves as placeholder value used in place of a location property
-    // (__FILE__, __DIR__, __LINE__)
     private static final Object LAZY_SENTINEL = new Object();
+    // This serves as placeholder value used in place of a location property (__FILE__, __DIR__, __LINE__)
+    private static final Object LOCATION_PLACEHOLDER = new Object();
 
     private static final String PACKAGE_PREFIX = "jdk.nashorn.internal.objects.";
 
@@ -916,7 +916,7 @@
     public volatile Object org;
 
     /**
-     * Getter for the Nashorn extension: Java access - global.javaImporter.
+     * Getter for the Nashorn extension: Java access - global.JavaImporter.
      *
      * @param self self reference
      * @return the value of the JavaImporter property
@@ -931,7 +931,7 @@
     }
 
     /**
-     * Setter for the Nashorn extension: Java access - global.javaImporter.
+     * Setter for the Nashorn extension: Java access - global.JavaImporter.
      *
      * @param self self reference
      * @param value value of the JavaImporter property
@@ -975,15 +975,15 @@
 
     /** Nashorn extension: current script's file name */
     @Property(name = "__FILE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
-    public static final Object __FILE__ = LAZY_SENTINEL;
+    public static final Object __FILE__ = LOCATION_PLACEHOLDER;
 
     /** Nashorn extension: current script's directory */
     @Property(name = "__DIR__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
-    public static final Object __DIR__ = LAZY_SENTINEL;
+    public static final Object __DIR__ = LOCATION_PLACEHOLDER;
 
     /** Nashorn extension: current source line number being executed */
     @Property(name = "__LINE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
-    public static final Object __LINE__ = LAZY_SENTINEL;
+    public static final Object __LINE__ = LOCATION_PLACEHOLDER;
 
     private volatile NativeDate DEFAULT_DATE;
 
@@ -2093,6 +2093,9 @@
     }
 
     private synchronized ScriptFunction getBuiltinJavaImporter() {
+        if (getContext().getEnv()._no_java) {
+            throw new IllegalStateException();
+        }
         if (this.builtinJavaImporter == null) {
             this.builtinJavaImporter = initConstructor("JavaImporter", ScriptFunction.class);
         }
@@ -2100,6 +2103,9 @@
     }
 
     private synchronized ScriptObject getBuiltinJavaApi() {
+        if (getContext().getEnv()._no_java) {
+            throw new IllegalStateException();
+        }
         if (this.builtinJavaApi == null) {
             this.builtinJavaApi = initConstructor("Java", ScriptObject.class);
             this.builtInJavaExtend = (ScriptFunction)builtinJavaApi.get("extend");
@@ -2325,7 +2331,7 @@
      * @return true if the value is a placeholder, false otherwise.
      */
     public static boolean isLocationPropertyPlaceholder(final Object placeholder) {
-        return placeholder == LAZY_SENTINEL;
+        return placeholder == LOCATION_PLACEHOLDER;
     }
 
     /**
@@ -2628,6 +2634,17 @@
             this.javaApi = LAZY_SENTINEL;
             this.javaImporter = LAZY_SENTINEL;
             initJavaAccess();
+        } else {
+            // delete nasgen-created global properties related to java access
+            this.delete("Java", false);
+            this.delete("JavaImporter", false);
+            this.delete("Packages", false);
+            this.delete("com", false);
+            this.delete("edu", false);
+            this.delete("java", false);
+            this.delete("javafx", false);
+            this.delete("javax", false);
+            this.delete("org", false);
         }
 
         if (! env._no_typed_arrays) {
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/test/ClassFilterTest.java	Mon Aug 07 10:02:39 2017 +0530
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/test/ClassFilterTest.java	Mon Aug 07 09:45:38 2017 -0700
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.internal.runtime.test;
 
+import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
 import java.io.File;
 import javax.script.ScriptEngine;
@@ -77,6 +78,65 @@
         } catch (final ScriptException e) {
             //emtpy
         }
+        try {
+            engine.eval("Java");
+            fail("TypeError should have been thrown");
+        } catch (final ScriptException e) {
+            //emtpy
+        }
+        try {
+            engine.eval("JavaImporter");
+            fail("TypeError should have been thrown");
+        } catch (final ScriptException e) {
+            //emtpy
+        }
+        try {
+            engine.eval("Packages");
+            fail("TypeError should have been thrown");
+        } catch (final ScriptException e) {
+            //emtpy
+        }
+        try {
+            engine.eval("com");
+            fail("TypeError should have been thrown");
+        } catch (final ScriptException e) {
+            //emtpy
+        }
+        try {
+            engine.eval("edu");
+            fail("TypeError should have been thrown");
+        } catch (final ScriptException e) {
+            //emtpy
+        }
+        try {
+            engine.eval("java");
+            fail("TypeError should have been thrown");
+        } catch (final ScriptException e) {
+            //emtpy
+        }
+        try {
+            engine.eval("javafx");
+            fail("TypeError should have been thrown");
+        } catch (final ScriptException e) {
+            //emtpy
+        }
+        try {
+            engine.eval("javax");
+            fail("TypeError should have been thrown");
+        } catch (final ScriptException e) {
+            //emtpy
+        }
+        try {
+            engine.eval("org");
+            fail("TypeError should have been thrown");
+        } catch (final ScriptException e) {
+            //emtpy
+        }
+        try {
+            assertEquals(engine.eval("Java = this[\"__LINE__\"]; Java === this[\"__LINE__\"]"), Boolean.TRUE);
+        } catch (final ScriptException e) {
+            fail("Unexpected exception", e);
+        }
     }
 
     @Test