Merge jdk9-b75
authorduke
Wed, 05 Jul 2017 20:43:22 +0200
changeset 31842 f55df5cfe11c
parent 31841 740e7c7adac0 (diff)
parent 31761 f4b5bcf49fa3 (current diff)
child 31843 23d7c6628f22
child 31844 6b802329fd04
child 31845 efa29955bdd0
child 31847 573eadb22d9b
child 31868 52b21e0e85f9
child 31871 9151b16cd46c
child 31872 eb13a70c73a5
child 31911 99a420709fce
child 31921 275be672e934
child 31923 a54b8f617077
child 31924 243ebe5fe525
child 31928 4484fb4ac301
child 31929 1e2ee502d1be
child 31933 759a2264cea4
child 31935 a1cf2a432c04
child 31936 02f1cfc234a0
child 31949 ddd0594084a7
Merge
--- a/.hgtags-top-repo	Wed Jul 05 20:42:40 2017 +0200
+++ b/.hgtags-top-repo	Wed Jul 05 20:43:22 2017 +0200
@@ -316,3 +316,4 @@
 c706ef5ea5da00078dc5e4334660315f7d99c15b jdk9-b71
 8582c35016fb6211b373810b6b172feccf9c483b jdk9-b72
 4c2cbaae528bce970dabbb5676005d379357f4b6 jdk9-b73
+57f3134853ecdd4a3ee2d4d26f22ba981d653d79 jdk9-b74
--- a/corba/.hgtags	Wed Jul 05 20:42:40 2017 +0200
+++ b/corba/.hgtags	Wed Jul 05 20:43:22 2017 +0200
@@ -316,3 +316,4 @@
 cd39ed501fb0504554a7f58ac6cf3dd2b64afec0 jdk9-b71
 f9f3706bd24c42c07cb260fe05730a749b8e52f4 jdk9-b72
 29096b78d93b01a2f8882509cd40755e3d6b8cd9 jdk9-b73
+622fe934e351e89107edf3c667d6b57f543f58f1 jdk9-b74
--- a/hotspot/.hgignore	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/.hgignore	Wed Jul 05 20:43:22 2017 +0200
@@ -10,3 +10,4 @@
 .igv.log
 ^.hgtip
 .DS_Store
+\.class$
--- a/hotspot/.hgtags	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/.hgtags	Wed Jul 05 20:43:22 2017 +0200
@@ -476,3 +476,4 @@
 07c6b035d68b0c41b1dcd442157b50b41a2551e9 jdk9-b71
 c1b2825ef47e75cb34dd18450d1c4280b7c5853c jdk9-b72
 e37d432868be0aa7cb5e0f3d7caff1e825d8ead3 jdk9-b73
+fff6b54e9770ac4c12c2fb4cab5aa7672affa4bd jdk9-b74
--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -34,7 +34,6 @@
 
 define_pd_global(bool, ConvertSleepToYield,      true);
 define_pd_global(bool, ShareVtableStubs,         true);
-define_pd_global(bool, CountInterpCalls,         true);
 define_pd_global(bool, NeedsDeoptSuspend,        false); // only register window machines need this
 
 define_pd_global(bool, ImplicitNullChecks,       true);  // Generate code for implicit null checks
@@ -61,8 +60,6 @@
 
 define_pd_global(intx, StackShadowPages, 4 DEBUG_ONLY(+5));
 
-define_pd_global(intx, PreInflateSpin,           10);
-
 define_pd_global(bool, RewriteBytecodes,     true);
 define_pd_global(bool, RewriteFrequentPairs, true);
 
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -869,7 +869,7 @@
 // native method than the typical interpreter frame setup.
 address InterpreterGenerator::generate_native_entry(bool synchronized) {
   // determine code generation flags
-  bool inc_counter  = UseCompiler || CountCompiledCalls;
+  bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 
   // r1: Method*
   // rscratch1: sender sp
@@ -1307,7 +1307,7 @@
 //
 address InterpreterGenerator::generate_normal_entry(bool synchronized) {
   // determine code generation flags
-  bool inc_counter  = UseCompiler || CountCompiledCalls;
+  bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 
   // rscratch1: sender sp
   address entry_point = __ pc();
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. 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
@@ -225,7 +225,7 @@
   return (BasicObjectLock *) get_ijava_state();
 }
 
-// SAPJVM ASc 2012-11-21. Return register stack slot addr at which currently interpreted method is found
+// Return register stack slot addr at which currently interpreted method is found.
 inline Method** frame::interpreter_frame_method_addr() const {
   return (Method**) &(get_ijava_state()->method);
 }
--- a/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -47,8 +47,6 @@
 define_pd_global(intx, InlineFrequencyCount,  100);
 define_pd_global(intx, InlineSmallCode,       1500);
 
-define_pd_global(intx, PreInflateSpin,        10);
-
 // Flags for template interpreter.
 define_pd_global(bool, RewriteBytecodes,      true);
 define_pd_global(bool, RewriteFrequentPairs,  true);
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -3433,6 +3433,376 @@
   bind(Ldone_false);
 }
 
+// dest_lo += src1 + src2
+// dest_hi += carry1 + carry2
+void MacroAssembler::add2_with_carry(Register dest_hi,
+                                     Register dest_lo,
+                                     Register src1, Register src2) {
+  li(R0, 0);
+  addc(dest_lo, dest_lo, src1);
+  adde(dest_hi, dest_hi, R0);
+  addc(dest_lo, dest_lo, src2);
+  adde(dest_hi, dest_hi, R0);
+}
+
+// Multiply 64 bit by 64 bit first loop.
+void MacroAssembler::multiply_64_x_64_loop(Register x, Register xstart,
+                                           Register x_xstart,
+                                           Register y, Register y_idx,
+                                           Register z,
+                                           Register carry,
+                                           Register product_high, Register product,
+                                           Register idx, Register kdx,
+                                           Register tmp) {
+  //  jlong carry, x[], y[], z[];
+  //  for (int idx=ystart, kdx=ystart+1+xstart; idx >= 0; idx--, kdx--) {
+  //    huge_128 product = y[idx] * x[xstart] + carry;
+  //    z[kdx] = (jlong)product;
+  //    carry  = (jlong)(product >>> 64);
+  //  }
+  //  z[xstart] = carry;
+
+  Label L_first_loop, L_first_loop_exit;
+  Label L_one_x, L_one_y, L_multiply;
+
+  addic_(xstart, xstart, -1);
+  blt(CCR0, L_one_x);   // Special case: length of x is 1.
+
+  // Load next two integers of x.
+  sldi(tmp, xstart, LogBytesPerInt);
+  ldx(x_xstart, x, tmp);
+#ifdef VM_LITTLE_ENDIAN
+  rldicl(x_xstart, x_xstart, 32, 0);
+#endif
+
+  align(32, 16);
+  bind(L_first_loop);
+
+  cmpdi(CCR0, idx, 1);
+  blt(CCR0, L_first_loop_exit);
+  addi(idx, idx, -2);
+  beq(CCR0, L_one_y);
+
+  // Load next two integers of y.
+  sldi(tmp, idx, LogBytesPerInt);
+  ldx(y_idx, y, tmp);
+#ifdef VM_LITTLE_ENDIAN
+  rldicl(y_idx, y_idx, 32, 0);
+#endif
+
+
+  bind(L_multiply);
+  multiply64(product_high, product, x_xstart, y_idx);
+
+  li(tmp, 0);
+  addc(product, product, carry);         // Add carry to result.
+  adde(product_high, product_high, tmp); // Add carry of the last addition.
+  addi(kdx, kdx, -2);
+
+  // Store result.
+#ifdef VM_LITTLE_ENDIAN
+  rldicl(product, product, 32, 0);
+#endif
+  sldi(tmp, kdx, LogBytesPerInt);
+  stdx(product, z, tmp);
+  mr_if_needed(carry, product_high);
+  b(L_first_loop);
+
+
+  bind(L_one_y); // Load one 32 bit portion of y as (0,value).
+
+  lwz(y_idx, 0, y);
+  b(L_multiply);
+
+
+  bind( L_one_x ); // Load one 32 bit portion of x as (0,value).
+
+  lwz(x_xstart, 0, x);
+  b(L_first_loop);
+
+  bind(L_first_loop_exit);
+}
+
+// Multiply 64 bit by 64 bit and add 128 bit.
+void MacroAssembler::multiply_add_128_x_128(Register x_xstart, Register y,
+                                            Register z, Register yz_idx,
+                                            Register idx, Register carry,
+                                            Register product_high, Register product,
+                                            Register tmp, int offset) {
+
+  //  huge_128 product = (y[idx] * x_xstart) + z[kdx] + carry;
+  //  z[kdx] = (jlong)product;
+
+  sldi(tmp, idx, LogBytesPerInt);
+  if ( offset ) {
+    addi(tmp, tmp, offset);
+  }
+  ldx(yz_idx, y, tmp);
+#ifdef VM_LITTLE_ENDIAN
+  rldicl(yz_idx, yz_idx, 32, 0);
+#endif
+
+  multiply64(product_high, product, x_xstart, yz_idx);
+  ldx(yz_idx, z, tmp);
+#ifdef VM_LITTLE_ENDIAN
+  rldicl(yz_idx, yz_idx, 32, 0);
+#endif
+
+  add2_with_carry(product_high, product, carry, yz_idx);
+
+  sldi(tmp, idx, LogBytesPerInt);
+  if ( offset ) {
+    addi(tmp, tmp, offset);
+  }
+#ifdef VM_LITTLE_ENDIAN
+  rldicl(product, product, 32, 0);
+#endif
+  stdx(product, z, tmp);
+}
+
+// Multiply 128 bit by 128 bit. Unrolled inner loop.
+void MacroAssembler::multiply_128_x_128_loop(Register x_xstart,
+                                             Register y, Register z,
+                                             Register yz_idx, Register idx, Register carry,
+                                             Register product_high, Register product,
+                                             Register carry2, Register tmp) {
+
+  //  jlong carry, x[], y[], z[];
+  //  int kdx = ystart+1;
+  //  for (int idx=ystart-2; idx >= 0; idx -= 2) { // Third loop
+  //    huge_128 product = (y[idx+1] * x_xstart) + z[kdx+idx+1] + carry;
+  //    z[kdx+idx+1] = (jlong)product;
+  //    jlong carry2 = (jlong)(product >>> 64);
+  //    product = (y[idx] * x_xstart) + z[kdx+idx] + carry2;
+  //    z[kdx+idx] = (jlong)product;
+  //    carry = (jlong)(product >>> 64);
+  //  }
+  //  idx += 2;
+  //  if (idx > 0) {
+  //    product = (y[idx] * x_xstart) + z[kdx+idx] + carry;
+  //    z[kdx+idx] = (jlong)product;
+  //    carry = (jlong)(product >>> 64);
+  //  }
+
+  Label L_third_loop, L_third_loop_exit, L_post_third_loop_done;
+  const Register jdx = R0;
+
+  // Scale the index.
+  srdi_(jdx, idx, 2);
+  beq(CCR0, L_third_loop_exit);
+  mtctr(jdx);
+
+  align(32, 16);
+  bind(L_third_loop);
+
+  addi(idx, idx, -4);
+
+  multiply_add_128_x_128(x_xstart, y, z, yz_idx, idx, carry, product_high, product, tmp, 8);
+  mr_if_needed(carry2, product_high);
+
+  multiply_add_128_x_128(x_xstart, y, z, yz_idx, idx, carry2, product_high, product, tmp, 0);
+  mr_if_needed(carry, product_high);
+  bdnz(L_third_loop);
+
+  bind(L_third_loop_exit);  // Handle any left-over operand parts.
+
+  andi_(idx, idx, 0x3);
+  beq(CCR0, L_post_third_loop_done);
+
+  Label L_check_1;
+
+  addic_(idx, idx, -2);
+  blt(CCR0, L_check_1);
+
+  multiply_add_128_x_128(x_xstart, y, z, yz_idx, idx, carry, product_high, product, tmp, 0);
+  mr_if_needed(carry, product_high);
+
+  bind(L_check_1);
+
+  addi(idx, idx, 0x2);
+  andi_(idx, idx, 0x1) ;
+  addic_(idx, idx, -1);
+  blt(CCR0, L_post_third_loop_done);
+
+  sldi(tmp, idx, LogBytesPerInt);
+  lwzx(yz_idx, y, tmp);
+  multiply64(product_high, product, x_xstart, yz_idx);
+  lwzx(yz_idx, z, tmp);
+
+  add2_with_carry(product_high, product, yz_idx, carry);
+
+  sldi(tmp, idx, LogBytesPerInt);
+  stwx(product, z, tmp);
+  srdi(product, product, 32);
+
+  sldi(product_high, product_high, 32);
+  orr(product, product, product_high);
+  mr_if_needed(carry, product);
+
+  bind(L_post_third_loop_done);
+}   // multiply_128_x_128_loop
+
+void MacroAssembler::multiply_to_len(Register x, Register xlen,
+                                     Register y, Register ylen,
+                                     Register z, Register zlen,
+                                     Register tmp1, Register tmp2,
+                                     Register tmp3, Register tmp4,
+                                     Register tmp5, Register tmp6,
+                                     Register tmp7, Register tmp8,
+                                     Register tmp9, Register tmp10,
+                                     Register tmp11, Register tmp12,
+                                     Register tmp13) {
+
+  ShortBranchVerifier sbv(this);
+
+  assert_different_registers(x, xlen, y, ylen, z, zlen,
+                             tmp1, tmp2, tmp3, tmp4, tmp5, tmp6);
+  assert_different_registers(x, xlen, y, ylen, z, zlen,
+                             tmp1, tmp2, tmp3, tmp4, tmp5, tmp7);
+  assert_different_registers(x, xlen, y, ylen, z, zlen,
+                             tmp1, tmp2, tmp3, tmp4, tmp5, tmp8);
+
+  const Register idx = tmp1;
+  const Register kdx = tmp2;
+  const Register xstart = tmp3;
+
+  const Register y_idx = tmp4;
+  const Register carry = tmp5;
+  const Register product = tmp6;
+  const Register product_high = tmp7;
+  const Register x_xstart = tmp8;
+  const Register tmp = tmp9;
+
+  // First Loop.
+  //
+  //  final static long LONG_MASK = 0xffffffffL;
+  //  int xstart = xlen - 1;
+  //  int ystart = ylen - 1;
+  //  long carry = 0;
+  //  for (int idx=ystart, kdx=ystart+1+xstart; idx >= 0; idx-, kdx--) {
+  //    long product = (y[idx] & LONG_MASK) * (x[xstart] & LONG_MASK) + carry;
+  //    z[kdx] = (int)product;
+  //    carry = product >>> 32;
+  //  }
+  //  z[xstart] = (int)carry;
+
+  mr_if_needed(idx, ylen);        // idx = ylen
+  mr_if_needed(kdx, zlen);        // kdx = xlen + ylen
+  li(carry, 0);                   // carry = 0
+
+  Label L_done;
+
+  addic_(xstart, xlen, -1);
+  blt(CCR0, L_done);
+
+  multiply_64_x_64_loop(x, xstart, x_xstart, y, y_idx, z,
+                        carry, product_high, product, idx, kdx, tmp);
+
+  Label L_second_loop;
+
+  cmpdi(CCR0, kdx, 0);
+  beq(CCR0, L_second_loop);
+
+  Label L_carry;
+
+  addic_(kdx, kdx, -1);
+  beq(CCR0, L_carry);
+
+  // Store lower 32 bits of carry.
+  sldi(tmp, kdx, LogBytesPerInt);
+  stwx(carry, z, tmp);
+  srdi(carry, carry, 32);
+  addi(kdx, kdx, -1);
+
+
+  bind(L_carry);
+
+  // Store upper 32 bits of carry.
+  sldi(tmp, kdx, LogBytesPerInt);
+  stwx(carry, z, tmp);
+
+  // Second and third (nested) loops.
+  //
+  //  for (int i = xstart-1; i >= 0; i--) { // Second loop
+  //    carry = 0;
+  //    for (int jdx=ystart, k=ystart+1+i; jdx >= 0; jdx--, k--) { // Third loop
+  //      long product = (y[jdx] & LONG_MASK) * (x[i] & LONG_MASK) +
+  //                     (z[k] & LONG_MASK) + carry;
+  //      z[k] = (int)product;
+  //      carry = product >>> 32;
+  //    }
+  //    z[i] = (int)carry;
+  //  }
+  //
+  //  i = xlen, j = tmp1, k = tmp2, carry = tmp5, x[i] = rdx
+
+  bind(L_second_loop);
+
+  li(carry, 0);                   // carry = 0;
+
+  addic_(xstart, xstart, -1);     // i = xstart-1;
+  blt(CCR0, L_done);
+
+  Register zsave = tmp10;
+
+  mr(zsave, z);
+
+
+  Label L_last_x;
+
+  sldi(tmp, xstart, LogBytesPerInt);
+  add(z, z, tmp);                 // z = z + k - j
+  addi(z, z, 4);
+  addic_(xstart, xstart, -1);     // i = xstart-1;
+  blt(CCR0, L_last_x);
+
+  sldi(tmp, xstart, LogBytesPerInt);
+  ldx(x_xstart, x, tmp);
+#ifdef VM_LITTLE_ENDIAN
+  rldicl(x_xstart, x_xstart, 32, 0);
+#endif
+
+
+  Label L_third_loop_prologue;
+
+  bind(L_third_loop_prologue);
+
+  Register xsave = tmp11;
+  Register xlensave = tmp12;
+  Register ylensave = tmp13;
+
+  mr(xsave, x);
+  mr(xlensave, xstart);
+  mr(ylensave, ylen);
+
+
+  multiply_128_x_128_loop(x_xstart, y, z, y_idx, ylen,
+                          carry, product_high, product, x, tmp);
+
+  mr(z, zsave);
+  mr(x, xsave);
+  mr(xlen, xlensave);   // This is the decrement of the loop counter!
+  mr(ylen, ylensave);
+
+  addi(tmp3, xlen, 1);
+  sldi(tmp, tmp3, LogBytesPerInt);
+  stwx(carry, z, tmp);
+  addic_(tmp3, tmp3, -1);
+  blt(CCR0, L_done);
+
+  srdi(carry, carry, 32);
+  sldi(tmp, tmp3, LogBytesPerInt);
+  stwx(carry, z, tmp);
+  b(L_second_loop);
+
+  // Next infrequent code is moved outside loops.
+  bind(L_last_x);
+
+  lwz(x_xstart, 0, x);
+  b(L_third_loop_prologue);
+
+  bind(L_done);
+}   // multiply_to_len
 
 void MacroAssembler::asm_assert(bool check_equal, const char *msg, int id) {
 #ifdef ASSERT
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -677,6 +677,31 @@
   void char_arrays_equalsImm(Register str1_reg, Register str2_reg, int cntval, Register result_reg,
                              Register tmp1_reg, Register tmp2_reg);
 
+  // Emitters for BigInteger.multiplyToLen intrinsic.
+  inline void multiply64(Register dest_hi, Register dest_lo,
+                         Register x, Register y);
+  void add2_with_carry(Register dest_hi, Register dest_lo,
+                       Register src1, Register src2);
+  void multiply_64_x_64_loop(Register x, Register xstart, Register x_xstart,
+                             Register y, Register y_idx, Register z,
+                             Register carry, Register product_high, Register product,
+                             Register idx, Register kdx, Register tmp);
+  void multiply_add_128_x_128(Register x_xstart, Register y, Register z,
+                              Register yz_idx, Register idx, Register carry,
+                              Register product_high, Register product, Register tmp,
+                              int offset);
+  void multiply_128_x_128_loop(Register x_xstart,
+                               Register y, Register z,
+                               Register yz_idx, Register idx, Register carry,
+                               Register product_high, Register product,
+                               Register carry2, Register tmp);
+  void multiply_to_len(Register x, Register xlen,
+                       Register y, Register ylen,
+                       Register z, Register zlen,
+                       Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5,
+                       Register tmp6, Register tmp7, Register tmp8, Register tmp9, Register tmp10,
+                       Register tmp11, Register tmp12, Register tmp13);
+
   //
   // Debugging
   //
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.inline.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.inline.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -423,6 +423,13 @@
   twi(traptoEqual | traptoGreaterThanUnsigned, a/*reg a*/, si16);
 }
 
+// unsigned integer multiplication 64*64 -> 128 bits
+inline void MacroAssembler::multiply64(Register dest_hi, Register dest_lo,
+                                       Register x, Register y) {
+  mulld(dest_lo, x, y);
+  mulhdu(dest_hi, x, y);
+}
+
 #if defined(ABI_ELFv2)
 inline address MacroAssembler::function_entry() { return pc(); }
 #else
--- a/hotspot/src/cpu/ppc/vm/ppc.ad	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad	Wed Jul 05 20:43:22 2017 +0200
@@ -10930,7 +10930,7 @@
 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{
   match(Set crx (FastLock oop box));
   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
-  predicate(/*(!UseNewFastLockPPC64 || UseBiasedLocking) &&*/ !Compile::current()->use_rtm());
+  predicate(!Compile::current()->use_rtm());
 
   format %{ "FASTLOCK  $oop, $box, $tmp1, $tmp2, $tmp3" %}
   ins_encode %{
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -2053,6 +2053,79 @@
     __ blr();
   }
 
+  // Stub for BigInteger::multiplyToLen()
+  //
+  //  Arguments:
+  //
+  //  Input:
+  //    R3 - x address
+  //    R4 - x length
+  //    R5 - y address
+  //    R6 - y length
+  //    R7 - z address
+  //    R8 - z length
+  //
+  address generate_multiplyToLen() {
+
+    StubCodeMark mark(this, "StubRoutines", "multiplyToLen");
+
+    address start = __ function_entry();
+
+    const Register x     = R3;
+    const Register xlen  = R4;
+    const Register y     = R5;
+    const Register ylen  = R6;
+    const Register z     = R7;
+    const Register zlen  = R8;
+
+    const Register tmp1  = R2; // TOC not used.
+    const Register tmp2  = R9;
+    const Register tmp3  = R10;
+    const Register tmp4  = R11;
+    const Register tmp5  = R12;
+
+    // non-volatile regs
+    const Register tmp6  = R31;
+    const Register tmp7  = R30;
+    const Register tmp8  = R29;
+    const Register tmp9  = R28;
+    const Register tmp10 = R27;
+    const Register tmp11 = R26;
+    const Register tmp12 = R25;
+    const Register tmp13 = R24;
+
+    BLOCK_COMMENT("Entry:");
+
+    // Save non-volatile regs (frameless).
+    int current_offs = 8;
+    __ std(R24, -current_offs, R1_SP); current_offs += 8;
+    __ std(R25, -current_offs, R1_SP); current_offs += 8;
+    __ std(R26, -current_offs, R1_SP); current_offs += 8;
+    __ std(R27, -current_offs, R1_SP); current_offs += 8;
+    __ std(R28, -current_offs, R1_SP); current_offs += 8;
+    __ std(R29, -current_offs, R1_SP); current_offs += 8;
+    __ std(R30, -current_offs, R1_SP); current_offs += 8;
+    __ std(R31, -current_offs, R1_SP);
+
+    __ multiply_to_len(x, xlen, y, ylen, z, zlen, tmp1, tmp2, tmp3, tmp4, tmp5,
+                       tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13);
+
+    // Restore non-volatile regs.
+    current_offs = 8;
+    __ ld(R24, -current_offs, R1_SP); current_offs += 8;
+    __ ld(R25, -current_offs, R1_SP); current_offs += 8;
+    __ ld(R26, -current_offs, R1_SP); current_offs += 8;
+    __ ld(R27, -current_offs, R1_SP); current_offs += 8;
+    __ ld(R28, -current_offs, R1_SP); current_offs += 8;
+    __ ld(R29, -current_offs, R1_SP); current_offs += 8;
+    __ ld(R30, -current_offs, R1_SP); current_offs += 8;
+    __ ld(R31, -current_offs, R1_SP);
+
+    __ blr();  // Return to caller.
+
+    return start;
+  }
+
   // Initialization
   void generate_initial() {
     // Generates all stubs and initializes the entry points
@@ -2102,6 +2175,12 @@
     generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
                                                        &StubRoutines::_safefetchN_fault_pc,
                                                        &StubRoutines::_safefetchN_continuation_pc);
+
+#ifdef COMPILER2
+    if (UseMultiplyToLenIntrinsic) {
+      StubRoutines::_multiplyToLen = generate_multiplyToLen();
+    }
+#endif
   }
 
  public:
--- a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -668,7 +668,7 @@
 
   address entry = __ pc();
 
-  const bool inc_counter = UseCompiler || CountCompiledCalls;
+  const bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 
   // -----------------------------------------------------------------------------
   // Allocate a new frame that represents the native callee (i2n frame).
@@ -1118,7 +1118,7 @@
 // Generic interpreted method entry to (asm) interpreter.
 //
 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
-  bool inc_counter = UseCompiler || CountCompiledCalls;
+  bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
   address entry = __ pc();
   // Generate the code to allocate the interpreter stack frame.
   Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
--- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -198,6 +198,10 @@
     FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
   }
 
+  if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
+    UseMultiplyToLenIntrinsic = true;
+  }
+
   // Adjust RTM (Restricted Transactional Memory) flags.
   if (!has_tcheck() && UseRTMLocking) {
     // Can't continue because UseRTMLocking affects UseBiasedLocking flag
@@ -228,7 +232,6 @@
       warning("RTMAbortRatio must be in the range 0 to 100, resetting it to 50");
       FLAG_SET_DEFAULT(RTMAbortRatio, 50);
     }
-    FLAG_SET_ERGO(bool, UseNewFastLockPPC64, false); // Does not implement TM.
     guarantee(RTMSpinLoopCount > 0, "unsupported");
 #else
     // Only C2 does RTM locking optimization.
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -39,7 +39,6 @@
 define_pd_global(bool, DontYieldALot,               true);  // yield no more than 100 times per second
 define_pd_global(bool, ConvertSleepToYield,         false); // do not convert sleep(0) to yield. Helps GUI
 define_pd_global(bool, ShareVtableStubs,            false); // improves performance markedly for mtrt and compress
-define_pd_global(bool, CountInterpCalls,            false); // not implemented in the interpreter
 define_pd_global(bool, NeedsDeoptSuspend,           true); // register window machines need this
 
 define_pd_global(bool, ImplicitNullChecks,          true);  // Generate code for implicit null checks
@@ -67,8 +66,6 @@
 define_pd_global(intx, StackYellowPages, 2);
 define_pd_global(intx, StackRedPages, 1);
 
-define_pd_global(intx, PreInflateSpin,       40);  // Determined by running design center
-
 define_pd_global(bool, RewriteBytecodes,     true);
 define_pd_global(bool, RewriteFrequentPairs, true);
 
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -801,7 +801,7 @@
   // the following temporary registers are used during frame creation
   const Register Gtmp1 = G3_scratch ;
   const Register Gtmp2 = G1_scratch;
-  bool inc_counter  = UseCompiler || CountCompiledCalls;
+  bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 
   // make sure registers are different!
   assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2);
@@ -1225,7 +1225,7 @@
 address InterpreterGenerator::generate_normal_entry(bool synchronized) {
   address entry = __ pc();
 
-  bool inc_counter  = UseCompiler || CountCompiledCalls;
+  bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 
   // the following temporary registers are used during frame creation
   const Register Gtmp1 = G3_scratch ;
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -308,7 +308,7 @@
     }
   } else if (UseGHASHIntrinsics) {
     if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics))
-      warning("GHASH intrinsics require VIS3 insructions support. Intriniscs will be disabled");
+      warning("GHASH intrinsics require VIS3 instruction support. Intrinsics will be disabled");
     FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
   }
 
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -33,7 +33,6 @@
 
 define_pd_global(bool, ConvertSleepToYield,      true);
 define_pd_global(bool, ShareVtableStubs,         true);
-define_pd_global(bool, CountInterpCalls,         true);
 define_pd_global(bool, NeedsDeoptSuspend,        false); // only register window machines need this
 
 define_pd_global(bool, ImplicitNullChecks,       true);  // Generate code for implicit null checks
@@ -66,8 +65,6 @@
 define_pd_global(intx, StackShadowPages, 4 DEBUG_ONLY(+5));
 #endif // AMD64
 
-define_pd_global(intx, PreInflateSpin,           10);
-
 define_pd_global(bool, RewriteBytecodes,     true);
 define_pd_global(bool, RewriteFrequentPairs, true);
 
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1781,6 +1781,7 @@
        cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
     } else
     if ((EmitSync & 128) == 0) {                      // avoid ST-before-CAS
+       // register juggle because we need tmpReg for cmpxchgptr below
        movptr(scrReg, boxReg);
        movptr(boxReg, tmpReg);                   // consider: LEA box, [tmp-2]
 
@@ -1814,7 +1815,10 @@
        }
        cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
        movptr(Address(scrReg, 0), 3);          // box->_displaced_header = 3
+       // If we weren't able to swing _owner from NULL to the BasicLock
+       // then take the slow path.
        jccb  (Assembler::notZero, DONE_LABEL);
+       // update _owner from BasicLock to thread
        get_thread (scrReg);                    // beware: clobbers ICCs
        movptr(Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), scrReg);
        xorptr(boxReg, boxReg);                 // set icc.ZFlag = 1 to indicate success
@@ -2083,6 +2087,9 @@
        xorptr(boxReg, boxReg);                  // box is really EAX
        if (os::is_MP()) { lock(); }
        cmpxchgptr(rsp, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
+       // There's no successor so we tried to regrab the lock with the
+       // placeholder value. If that didn't work, then another thread
+       // grabbed the lock so we're done (and exit was a success).
        jccb  (Assembler::notEqual, LSuccess);
        // Since we're low on registers we installed rsp as a placeholding in _owner.
        // Now install Self over rsp.  This is safe as we're transitioning from
@@ -2190,6 +2197,9 @@
       movptr(boxReg, (int32_t)NULL_WORD);
       if (os::is_MP()) { lock(); }
       cmpxchgptr(r15_thread, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
+      // There's no successor so we tried to regrab the lock.
+      // If that didn't work, then another thread grabbed the
+      // lock so we're done (and exit was a success).
       jccb  (Assembler::notEqual, LSuccess);
       // Intentional fall-through into slow-path
 
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -2456,7 +2456,8 @@
   // allocate space for the code
   ResourceMark rm;
   // setup code generation tools
-  CodeBuffer   buffer("deopt_blob", 1024, 1024);
+  // note: the buffer code size must account for StackShadowPages=50
+  CodeBuffer   buffer("deopt_blob", 1536, 1024);
   MacroAssembler* masm = new MacroAssembler(&buffer);
   int frame_size_in_words;
   OopMap* map = NULL;
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -2780,6 +2780,7 @@
     const XMMRegister xmm_temp7 = xmm7;
 
     __ enter();
+    handleSOERegisters(true);  // Save registers
 
     __ movptr(state, state_param);
     __ movptr(subkeyH, subkeyH_param);
@@ -2883,6 +2884,7 @@
     __ pshufb(xmm_temp6, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr()));
     __ movdqu(Address(state, 0), xmm_temp6);   // store the result
 
+    handleSOERegisters(false);  // restore registers
     __ leave();
     __ ret(0);
     return start;
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -849,7 +849,7 @@
 
 address InterpreterGenerator::generate_native_entry(bool synchronized) {
   // determine code generation flags
-  bool inc_counter  = UseCompiler || CountCompiledCalls;
+  bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 
   // rbx,: Method*
   // rsi: sender sp
@@ -1265,7 +1265,7 @@
 //
 address InterpreterGenerator::generate_normal_entry(bool synchronized) {
   // determine code generation flags
-  bool inc_counter  = UseCompiler || CountCompiledCalls;
+  bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 
   // rbx,: Method*
   // rsi: sender sp
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -809,7 +809,7 @@
 // native method than the typical interpreter frame setup.
 address InterpreterGenerator::generate_native_entry(bool synchronized) {
   // determine code generation flags
-  bool inc_counter  = UseCompiler || CountCompiledCalls;
+  bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 
   // rbx: Method*
   // r13: sender sp
@@ -1256,7 +1256,7 @@
 //
 address InterpreterGenerator::generate_normal_entry(bool synchronized) {
   // determine code generation flags
-  bool inc_counter  = UseCompiler || CountCompiledCalls;
+  bool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;
 
   // ebx: Method*
   // r13: sender sp
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -34,7 +34,6 @@
 
 define_pd_global(bool,  ConvertSleepToYield,  true);
 define_pd_global(bool,  ShareVtableStubs,     true);
-define_pd_global(bool,  CountInterpCalls,     true);
 define_pd_global(bool,  NeedsDeoptSuspend,    false);
 
 define_pd_global(bool,  ImplicitNullChecks,   true);
@@ -45,7 +44,6 @@
 define_pd_global(intx,  OptoLoopAlignment,    16);
 define_pd_global(intx,  InlineFrequencyCount, 100);
 define_pd_global(intx,  InlineSmallCode,      1000 );
-define_pd_global(intx,  PreInflateSpin,       10);
 
 define_pd_global(intx,  StackYellowPages,     2);
 define_pd_global(intx,  StackRedPages,        1);
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -3740,15 +3740,6 @@
          "stack size not a multiple of page size");
 
   initialize_performance_counter();
-
-  // Win95/Win98 scheduler bug work-around. The Win95/98 scheduler is
-  // known to deadlock the system, if the VM issues to thread operations with
-  // a too high frequency, e.g., such as changing the priorities.
-  // The 6000 seems to work well - no deadlocks has been notices on the test
-  // programs that we have seen experience this problem.
-  if (!os::win32::is_nt()) {
-    StarvationMonitorInterval = 6000;
-  }
 }
 
 
--- a/hotspot/src/share/tools/LogCompilation/Makefile	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/Makefile	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@
 
 logc.jar: filelist manifest.mf
 	@mkdir -p $(OUTPUT_DIR)
-	$(JAVAC) -source 1.5 -deprecation -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) @filelist
+	$(JAVAC) -deprecation -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) @filelist
 	$(JAR) cvfm logc.jar manifest.mf -C $(OUTPUT_DIR) com
 
 .PHONY: filelist
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/BasicLogEvent.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/BasicLogEvent.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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,14 +27,29 @@
 import java.io.PrintStream;
 
 /**
- *
- * @author never
+ * Provide basic data structures and behaviour for {@link LogEvent}s.
  */
 public abstract class BasicLogEvent implements LogEvent {
 
+    /**
+     * The event's ID. This is a number; we represent it as a string for
+     * convenience.
+     */
     protected final String id;
+
+    /**
+     * The event's start time.
+     */
     protected final double start;
+
+    /**
+     * The event's end time.
+     */
     protected double end;
+
+    /**
+     * The compilation during which this event was signalled.
+     */
     protected Compilation compilation;
 
     BasicLogEvent(double start, String id) {
@@ -43,33 +58,37 @@
         this.id = id;
     }
 
-    public double getStart() {
+    public final double getStart() {
         return start;
     }
 
-    public double getEnd() {
+    public final double getEnd() {
         return end;
     }
 
-    public void setEnd(double end) {
+    public final void setEnd(double end) {
         this.end = end;
     }
 
-    public double getElapsedTime() {
+    public final double getElapsedTime() {
         return ((int) ((getEnd() - getStart()) * 1000)) / 1000.0;
     }
 
-    public String getId() {
+    public final String getId() {
         return id;
     }
 
-    public Compilation getCompilation() {
+    public final Compilation getCompilation() {
         return compilation;
     }
 
+    /**
+     * Set the compilation for this event. This is not a {@code final} method
+     * as it is overridden in {@link UncommonTrapEvent}.
+     */
     public void setCompilation(Compilation compilation) {
         this.compilation = compilation;
     }
 
-    abstract public void print(PrintStream stream);
+    abstract public void print(PrintStream stream, boolean printID);
 }
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,41 +29,119 @@
 import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * Representation of a compilation scope in a compilation log. This class is a
+ * hybrid: its instances can represent original scopes of methods being
+ * compiled, but are also used to represent call sites in given methods.
+ */
 public class CallSite {
 
+    /**
+     * The index of the call in the caller. This will be 0 if this instance
+     * represents a compilation root.
+     */
     private int bci;
+
+    /**
+     * The method that is called at this call site. This will be {@code null}
+     * if this instance represents a compilation root.
+     */
     private Method method;
+
+    /**
+     * The invocation count for this call site.
+     */
     private int count;
+
+    /**
+     * The receiver type of the call represented by this instance, if known.
+     */
     private String receiver;
+
+    /**
+     * In case the {@linkplain receiver receiver type} of the call represented
+     * by this instance is known, this is how often the type was encountered.
+     */
     private int receiver_count;
+
+    /**
+     * The reason for a success or failure of an inlining operation at this
+     * call site.
+     */
     private String reason;
+
+    /**
+     * A list of all calls in this compilation scope.
+     */
     private List<CallSite> calls;
+
+    /**
+     * Number of nodes in the graph at the end of parsing this compilation
+     * scope.
+     */
     private int endNodes;
+
+    /**
+     * Number of live nodes in the graph at the end of parsing this compilation
+     * scope.
+     */
     private int endLiveNodes;
+
+    /**
+     * Time in seconds since VM startup at which parsing this compilation scope
+     * ended.
+     */
     private double timeStamp;
+
+    /**
+     * The inline ID in case the call represented by this instance is inlined,
+     * 0 otherwise.
+     */
     private long inlineId;
 
-    CallSite() {
-    }
+    /**
+     * List of uncommon traps in this compilation scope.
+     */
+    private List<UncommonTrap> traps;
 
+    /**
+     * Default constructor: used to create an instance that represents the top
+     * scope of a compilation.
+     */
+    CallSite() {}
+
+    /**
+     * Constructor to create an instance that represents an actual method call.
+     */
     CallSite(int bci, Method m) {
         this.bci = bci;
         this.method = m;
     }
 
+    /**
+     * Add a call site to the compilation scope represented by this instance.
+     */
     void add(CallSite site) {
         if (getCalls() == null) {
-            setCalls(new ArrayList<CallSite>());
+            calls = new ArrayList<>();
         }
         getCalls().add(site);
     }
 
+    /**
+     * Return the last of the {@linkplain #getCalls() call sites} in this
+     * compilation scope.
+     */
     CallSite last() {
-        return last(-1);
+        return getCalls().get(getCalls().size() - 1);
     }
 
-    CallSite last(int fromEnd) {
-        return getCalls().get(getCalls().size() + fromEnd);
+    /**
+     * Return the last-but-one of the {@linkplain #getCalls() call sites} in
+     * this compilation scope.
+     */
+    CallSite lastButOne() {
+        return getCalls().get(getCalls().size() - 2);
     }
 
     public String toString() {
@@ -84,7 +162,7 @@
     }
 
     public void print(PrintStream stream) {
-        print(stream, 0);
+        print(stream, 0, true, false);
     }
 
     void emit(PrintStream stream, int indent) {
@@ -92,21 +170,14 @@
             stream.print(' ');
         }
     }
-    private static boolean compat = true;
 
-    public void print(PrintStream stream, int indent) {
+    public void print(PrintStream stream, int indent, boolean printInlining, boolean printUncommonTraps) {
         emit(stream, indent);
         String m = getMethod().getHolder() + "::" + getMethod().getName();
         if (getReason() == null) {
             stream.print("  @ " + getBci() + " " + m + " (" + getMethod().getBytes() + " bytes)");
-
         } else {
-            if (isCompat()) {
-                stream.print("  @ " + getBci() + " " + m + " " + getReason());
-            } else {
-                stream.print("- @ " + getBci() + " " + m +
-                        " (" + getMethod().getBytes() + " bytes) " + getReason());
-            }
+            stream.print("  @ " + getBci() + " " + m + " " + getReason());
         }
         stream.printf(" (end time: %6.4f", getTimeStamp());
         if (getEndNodes() > 0) {
@@ -116,13 +187,16 @@
 
         if (getReceiver() != null) {
             emit(stream, indent + 4);
-            //                 stream.println("type profile " + method.holder + " -> " + receiver + " (" +
-            //                                receiver_count + "/" + count + "," + (receiver_count * 100 / count) + "%)");
             stream.println("type profile " + getMethod().getHolder() + " -> " + getReceiver() + " (" +
                     (getReceiverCount() * 100 / getCount()) + "%)");
         }
-        if (getCalls() != null) {
+        if (printInlining && getCalls() != null) {
             for (CallSite site : getCalls()) {
+                site.print(stream, indent + 2, printInlining, printUncommonTraps);
+            }
+        }
+        if (printUncommonTraps && getTraps() != null) {
+            for (UncommonTrap site : getTraps()) {
                 site.print(stream, indent + 2);
             }
         }
@@ -180,16 +254,15 @@
         return calls;
     }
 
-    public void setCalls(List<CallSite> calls) {
-        this.calls = calls;
+    public List<UncommonTrap> getTraps() {
+        return traps;
     }
 
-    public static boolean isCompat() {
-        return compat;
-    }
-
-    public static void setCompat(boolean aCompat) {
-        compat = aCompat;
+    void add(UncommonTrap e) {
+        if (traps == null) {
+            traps = new ArrayList<UncommonTrap>();
+        }
+        traps.add(e);
     }
 
     void setEndNodes(int n) {
@@ -216,21 +289,30 @@
         return timeStamp;
     }
 
+    /**
+     * Check whether this call site matches another. Every late inline call
+     * site has a unique inline ID. If the call site we're looking for has one,
+     * then use it; otherwise rely on method name and byte code index.
+     */
     private boolean matches(CallSite other) {
-        // Every late inline call site has a unique inline id. If the
-        // call site we're looking for has one then use it other rely
-        // on method name and bci.
         if (other.inlineId != 0) {
             return inlineId == other.inlineId;
         }
         return method.equals(other.method) && bci == other.bci;
     }
 
+    /**
+     * Locate a late inline call site: find, in this instance's
+     * {@linkplain #calls call sites}, the one furthest down the given call
+     * stack.
+     *
+     * Multiple chains of identical call sites with the same method name / bci
+     * combination are possible, so we have to try them all until we find the
+     * late inline call site that has a matching inline ID.
+     *
+     * @return a matching call site, or {@code null} if none was found.
+     */
     public CallSite findCallSite(ArrayDeque<CallSite> sites) {
-        // Locate a late inline call site. Multiple chains of
-        // identical call sites with the same method name/bci are
-        // possible so we have to try them all until we find the late
-        // inline call site that has a matching inline id.
         if (calls == null) {
             return null;
         }
@@ -253,6 +335,11 @@
         return null;
     }
 
+    /**
+     * Locate a late inline call site in the tree spanned by all this instance's
+     * {@linkplain #calls call sites}, and return the sequence of call sites
+     * (scopes) leading to that late inline call site.
+     */
     public ArrayDeque<CallSite> findCallSite2(CallSite site) {
         if (calls == null) {
             return null;
@@ -260,7 +347,7 @@
 
         for (CallSite c : calls) {
             if (c.matches(site)) {
-                ArrayDeque<CallSite> stack = new ArrayDeque<CallSite>();
+                ArrayDeque<CallSite> stack = new ArrayDeque<>();
                 stack.push(c);
                 return stack;
             } else {
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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,22 +27,94 @@
 import java.io.PrintStream;
 import java.util.ArrayList;
 
+/**
+ * One particular compilation, represented in the compilation log file as a
+ * {@code task} element.
+ */
 public class Compilation implements LogEvent {
 
+    /**
+     * The compilation ID.
+     */
     private int id;
+
+    /**
+     * Whether this is a compilation for on-stack replacement (OSR).
+     */
     private boolean osr;
+
+    /**
+     * The method being compiled.
+     */
     private Method method;
+
+    /**
+     * The {@linkplain CallSite scope} of this compilation. This is created as
+     * an empty {@link CallSite} instance, to be filled with data (and
+     * meaning) later on.
+     */
     private CallSite call = new CallSite();
+
+    /**
+     * In case a {@code late_inline} event occurs during the compilation, this
+     * field holds the information about it.
+     */
     private CallSite lateInlineCall = new CallSite();
-    private int osrBci;
+
+    /**
+     * The bytecode instruction index for on-stack replacement compilations; -1
+     * if this is not an OSR compilation.
+     */
+    private int bci;
+
+    /**
+     * The method under compilation's invocation count.
+     */
     private String icount;
+
+    /**
+     * The method under compilation's backedge count.
+     */
     private String bcount;
+
+    /**
+     * Additional information for special compilations (e.g., adapters).
+     */
     private String special;
+
+    /**
+     * The name of the compiler performing this compilation.
+     */
+    private String compiler;
+
+    /**
+     * Start time stamp.
+     */
     private double start;
+
+    /**
+     * End time stamp.
+     */
     private double end;
+
+    /**
+     * Trip count of the register allocator.
+     */
     private int attempts;
+
+    /**
+     * The compilation result (a native method).
+     */
     private NMethod nmethod;
-    private ArrayList<Phase> phases = new ArrayList<Phase>(4);
+
+    /**
+     * The phases through which this compilation goes.
+     */
+    private ArrayList<Phase> phases = new ArrayList<>(4);
+
+    /**
+     * In case this compilation fails, the reason for that.
+     */
     private String failureReason;
 
     Compilation(int id) {
@@ -52,9 +124,17 @@
     void reset() {
         call = new CallSite();
         lateInlineCall = new CallSite();
-        phases = new ArrayList<Phase>(4);
+        phases = new ArrayList<>(4);
     }
 
+    /**
+     * Get a compilation phase by name, or {@code null}.
+     *
+     * @param s the name of the phase to retrieve in this compilation.
+     *
+     * @return a compilation phase, or {@code null} if no phase with the given
+     *         name is found.
+     */
     Phase getPhase(String s) {
         for (Phase p : getPhases()) {
             if (p.getName().equals(s)) {
@@ -72,20 +152,32 @@
         return start;
     }
 
+    public void setCompiler(String compiler) {
+        this.compiler = compiler;
+    }
+
+    public String getCompiler() {
+        return compiler;
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append(getId());
         sb.append(" ");
+        sb.append(getCompiler());
+        sb.append(" ");
         sb.append(getMethod());
         sb.append(" ");
         sb.append(getIcount());
         sb.append("+");
         sb.append(getBcount());
         sb.append("\n");
-        for (CallSite site : getCall().getCalls()) {
-            sb.append(site);
-            sb.append("\n");
+        if (getCall() != null && getCall().getCalls() != null) {
+            for (CallSite site : getCall().getCalls()) {
+                sb.append(site);
+                sb.append("\n");
+            }
         }
         if (getLateInlineCall().getCalls() != null) {
             sb.append("late inline:\n");
@@ -101,38 +193,50 @@
         if (getMethod() == null) {
             stream.println(getSpecial());
         } else {
-            int bc = isOsr() ? getOsr_bci() : -1;
-            stream.print(getId() + getMethod().decodeFlags(bc) + getMethod().format(bc));
+            int bc = isOsr() ? getBCI() : -1;
+            stream.print(getId() + getMethod().decodeFlags(bc) + " " + compiler + " " + getMethod().format(bc));
         }
     }
 
-    public void print(PrintStream stream) {
-        print(stream, 0, false);
+    public void print(PrintStream stream, boolean printID) {
+        print(stream, 0, printID, true, false);
     }
 
-    public void print(PrintStream stream, boolean printInlining) {
-        print(stream, 0, printInlining);
+    public void print(PrintStream stream, boolean printID, boolean printInlining) {
+        print(stream, 0, printID, printInlining, false);
     }
 
-    public void print(PrintStream stream, int indent, boolean printInlining) {
+    public void print(PrintStream stream, boolean printID, boolean printInlining, boolean printUncommonTraps) {
+        print(stream, 0, printID, printInlining, printUncommonTraps);
+    }
+
+    public void print(PrintStream stream, int indent, boolean printID, boolean printInlining, boolean printUncommonTraps) {
         if (getMethod() == null) {
             stream.println(getSpecial());
         } else {
-            int bc = isOsr() ? getOsr_bci() : -1;
-            stream.print(getId() + getMethod().decodeFlags(bc) + getMethod().format(bc));
+            if (printID) {
+                stream.print(getId());
+            }
+            int bc = isOsr() ? getBCI() : -1;
+            stream.print(getMethod().decodeFlags(bc) + " " + compiler + " " + getMethod().format(bc));
             stream.println();
             if (getFailureReason() != null) {
-                stream.println("COMPILE FAILED " + getFailureReason());
+                stream.println("COMPILE SKIPPED: " + getFailureReason() + " (not retryable)");
             }
             if (printInlining && call.getCalls() != null) {
                 for (CallSite site : call.getCalls()) {
+                    site.print(stream, indent + 2, printInlining, printUncommonTraps);
+                }
+            }
+            if (printUncommonTraps && call.getTraps() != null) {
+                for (UncommonTrap site : call.getTraps()) {
                     site.print(stream, indent + 2);
                 }
             }
             if (printInlining && lateInlineCall.getCalls() != null) {
                 stream.println("late inline:");
                 for (CallSite site : lateInlineCall.getCalls()) {
-                    site.print(stream, indent + 2);
+                    site.print(stream, indent + 2, printInlining, printUncommonTraps);
                 }
             }
         }
@@ -154,12 +258,12 @@
         this.osr = osr;
     }
 
-    public int getOsr_bci() {
-        return osrBci;
+    public int getBCI() {
+        return bci;
     }
 
-    public void setOsr_bci(int osrBci) {
-        this.osrBci = osrBci;
+    public void setBCI(int osrBci) {
+        this.bci = osrBci;
     }
 
     public String getIcount() {
@@ -230,9 +334,13 @@
         return method;
     }
 
+    /**
+     * Set the method under compilation. If it is already set, ignore the
+     * argument to avoid changing the method by post-parse inlining info.
+     *
+     * @param method the method under compilation. May be ignored.
+     */
     public void setMethod(Method method) {
-        // Don't change method if it is already set to avoid changing
-        // it by post parse inlining info.
         if (getMethod() == null) {
             this.method = method;
         }
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCleanupReader.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCleanupReader.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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
@@ -31,10 +31,9 @@
  * This class is a filter class to deal with malformed XML that used
  * to be produced by the JVM when generating LogCompilation.  In 1.6
  * and later releases it shouldn't be required.
- * @author never
  */
+class LogCleanupReader extends Reader {
 
-class LogCleanupReader extends Reader {
     private Reader reader;
 
     private char[] buffer = new char[4096];
@@ -55,32 +54,38 @@
         reader = r;
     }
 
-    static final private Matcher pattern = Pattern.compile(".+ compile_id='[0-9]+'.*( compile_id='[0-9]+)").matcher("");
-    static final private Matcher pattern2 = Pattern.compile("' (C[12]) compile_id=").matcher("");
-    static final private Matcher pattern3 = Pattern.compile("'(destroy_vm)/").matcher("");
+    static final private Matcher duplicateCompileID = Pattern.compile(".+ compile_id='[0-9]+'.*( compile_id='[0-9]+)").matcher("");
+    static final private Matcher compilerName = Pattern.compile("' (C[12]) compile_id=").matcher("");
+    static final private Matcher destroyVM = Pattern.compile("'(destroy_vm)/").matcher("");
 
+    /**
+     * The log cleanup takes place in this method. If any of the three patterns
+     * ({@link #duplicateCompileID}, {@link #compilerName}, {@link #destroyVM})
+     * match, that indicates a problem in the log. The cleanup is performed by
+     * correcting the input line and writing it back into the {@link #line}
+     * buffer.
+     */
     private void fill() throws IOException {
         rawFill();
         if (length != -1) {
             boolean changed = false;
             String s = new String(line, 0, length);
-            String orig = s;
 
-            pattern2.reset(s);
-            if (pattern2.find()) {
-                s = s.substring(0, pattern2.start(1)) + s.substring(pattern2.end(1) + 1);
+            compilerName.reset(s);
+            if (compilerName.find()) {
+                s = s.substring(0, compilerName.start(1)) + s.substring(compilerName.end(1) + 1);
                 changed = true;
             }
 
-            pattern.reset(s);
-            if (pattern.lookingAt()) {
-                s = s.substring(0, pattern.start(1)) + s.substring(pattern.end(1) + 1);
+            duplicateCompileID.reset(s);
+            if (duplicateCompileID.lookingAt()) {
+                s = s.substring(0, duplicateCompileID.start(1)) + s.substring(duplicateCompileID.end(1) + 1);
                 changed = true;
             }
 
-            pattern3.reset(s);
-            if (pattern3.find()) {
-                s = s.substring(0, pattern3.start(1)) + s.substring(pattern3.end(1));
+            destroyVM.reset(s);
+            if (destroyVM.find()) {
+                s = s.substring(0, destroyVM.start(1)) + s.substring(destroyVM.end(1));
                 changed = true;
             }
 
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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
@@ -22,60 +22,102 @@
  *
  */
 
-/**
- * The main command line driver of a parser for LogCompilation output.
- * @author never
- */
-
 package com.sun.hotspot.tools.compiler;
 
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.PrintStream;
 import java.util.*;
+
 import org.xml.sax.*;
 import org.xml.sax.helpers.*;
 
-public class LogCompilation extends DefaultHandler implements ErrorHandler, Constants {
+/**
+ * The LogCompilation tool parses log files generated by HotSpot using the
+ * {@code -XX:+LogCompilation} command line flag, and outputs the data
+ * collected therein in a nicely formatted way. There are various sorting
+ * options available, as well as options that select specific compilation
+ * events (such as inlining decisions) for inclusion in the output.
+ *
+ * The tool is also capable of fixing broken compilation logs as sometimes
+ * generated by Java 1.5 JVMs.
+ */
+public class LogCompilation extends DefaultHandler implements ErrorHandler {
 
+    /**
+     * Print usage information and terminate with a given exit code.
+     */
     public static void usage(int exitcode) {
         System.out.println("Usage: LogCompilation [ -v ] [ -c ] [ -s ] [ -e | -n ] file1 ...");
+        System.out.println("By default, the tool will print the logged compilations ordered by start time.");
         System.out.println("  -c:   clean up malformed 1.5 xml");
         System.out.println("  -i:   print inlining decisions");
         System.out.println("  -S:   print compilation statistics");
-        System.out.println("  -s:   sort events by start time");
+        System.out.println("  -U:   print uncommon trap statistics");
+        System.out.println("  -t:   print with time stamps");
+        System.out.println("  -s:   sort events by start time (default)");
         System.out.println("  -e:   sort events by elapsed time");
         System.out.println("  -n:   sort events by name and start");
+        System.out.println("  -C:   compare logs (give files to compare on command line)");
+        System.out.println("  -d:   do not print compilation IDs");
         System.exit(exitcode);
     }
 
+    /**
+     * Process command line arguments, parse log files and trigger desired
+     * functionality.
+     */
     public static void main(String[] args) throws Exception {
-        Comparator<LogEvent> defaultSort = LogParser.sortByStart;
+        Comparator<LogEvent> sort = LogParser.sortByStart;
         boolean statistics = false;
         boolean printInlining = false;
         boolean cleanup = false;
+        boolean trapHistory = false;
+        boolean printTimeStamps = false;
+        boolean compare = false;
+        boolean printID = true;
         int index = 0;
 
         while (args.length > index) {
-            if (args[index].equals("-e")) {
-                defaultSort = LogParser.sortByElapsed;
+            String a = args[index];
+            if (a.equals("-e")) {
+                sort = LogParser.sortByElapsed;
+                index++;
+            } else if (a.equals("-n")) {
+                sort = LogParser.sortByNameAndStart;
                 index++;
-            } else if (args[index].equals("-n")) {
-                defaultSort = LogParser.sortByNameAndStart;
+            } else if (a.equals("-s")) {
+                sort = LogParser.sortByStart;
                 index++;
-            } else if (args[index].equals("-s")) {
-                defaultSort = LogParser.sortByStart;
+            } else if (a.equals("-t")) {
+                printTimeStamps = true;
                 index++;
-            } else if (args[index].equals("-c")) {
+            } else if (a.equals("-c")) {
                 cleanup = true;
                 index++;
-            } else if (args[index].equals("-S")) {
+            } else if (a.equals("-S")) {
                 statistics = true;
                 index++;
-            } else if (args[index].equals("-h")) {
+            } else if (a.equals("-U")) {
+                trapHistory = true;
+                index++;
+            } else if (a.equals("-h")) {
                 usage(0);
-            } else if (args[index].equals("-i")) {
+            } else if (a.equals("-i")) {
                 printInlining = true;
                 index++;
+            } else if (a.equals("-C")) {
+                compare = true;
+                index++;
+            } else if (a.equals("-d")) {
+                printID = false;
+                index++;
             } else {
+                if (a.charAt(0) == '-') {
+                    System.out.println("Unknown option '" + a + "', assuming file name.");
+                }
                 break;
             }
         }
@@ -84,19 +126,40 @@
             usage(1);
         }
 
+        if (compare) {
+            compareLogs(index, args);
+            return;
+        }
+
         while (index < args.length) {
-            ArrayList<LogEvent> events = LogParser.parse(args[index], cleanup);
+            ArrayList<LogEvent> events = null;
+            try {
+                events = LogParser.parse(args[index], cleanup);
+            } catch (FileNotFoundException fnfe) {
+                System.out.println("File not found: " + args[index]);
+                System.exit(1);
+            }
+
+            Collections.sort(events, sort);
 
             if (statistics) {
                 printStatistics(events, System.out);
+            } else if (trapHistory) {
+                printTrapHistory(events, System.out);
             } else {
-                Collections.sort(events, defaultSort);
                 for (LogEvent c : events) {
-                    if (printInlining && c instanceof Compilation) {
-                        Compilation comp = (Compilation)c;
-                        comp.print(System.out, true);
+                    if (c instanceof NMethod) {
+                        // skip these
+                        continue;
+                    }
+                    if (printTimeStamps) {
+                        System.out.print(c.getStart() + ": ");
+                    }
+                    if (c instanceof Compilation) {
+                        Compilation comp = (Compilation) c;
+                        comp.print(System.out, printID, printInlining);
                     } else {
-                        c.print(System.out);
+                        c.print(System.out, printID);
                     }
                 }
             }
@@ -104,17 +167,25 @@
         }
     }
 
+    /**
+     * Print extensive statistics from parsed log files.
+     */
     public static void printStatistics(ArrayList<LogEvent> events, PrintStream out) {
+        // track code cache size
         long cacheSize = 0;
         long maxCacheSize = 0;
+        // track number of nmethods
         int nmethodsCreated = 0;
         int nmethodsLive = 0;
+        // track how many compilations were attempted multiple times
+        // (indexed by attempts, mapping to number of compilations)
         int[] attempts = new int[32];
-        double regallocTime = 0;
         int maxattempts = 0;
 
-        LinkedHashMap<String, Double> phaseTime = new LinkedHashMap<String, Double>(7);
-        LinkedHashMap<String, Integer> phaseNodes = new LinkedHashMap<String, Integer>(7);
+        // track time spent in compiler phases
+        LinkedHashMap<String, Double> phaseTime = new LinkedHashMap<>(7);
+        // track nodes created per phase
+        LinkedHashMap<String, Integer> phaseNodes = new LinkedHashMap<>(7);
         double elapsed = 0;
 
         for (LogEvent e : events) {
@@ -137,18 +208,17 @@
                         v2 = Integer.valueOf(0);
                     }
                     phaseNodes.put(phase.getName(), Integer.valueOf(v2.intValue() + phase.getNodes()));
-                    /* Print phase name, elapsed time, nodes at the start of the phase,
-                       nodes created in the phase, live nodes at the start of the phase,
-                       live nodes added in the phase.
-                    */
-                    out.printf("\t%s %6.4f %d %d %d %d\n", phase.getName(), phase.getElapsedTime(), phase.getStartNodes(), phase.getNodes(), phase.getStartLiveNodes(), phase.getLiveNodes());
+                    // Print phase name, elapsed time, nodes at the start of
+                    // the phase, nodes created in the phase, live nodes at the
+                    // start of the phase, live nodes added in the phase.
+                    out.printf("\t%s %6.4f %d %d %d %d\n", phase.getName(), phase.getElapsedTime(), phase.getStartNodes(), phase.getNodes(), phase.getStartLiveNodes(), phase.getAddedLiveNodes());
                 }
             } else if (e instanceof MakeNotEntrantEvent) {
                 MakeNotEntrantEvent mne = (MakeNotEntrantEvent) e;
                 NMethod nm = mne.getNMethod();
                 if (mne.isZombie()) {
                     if (nm == null) {
-                        System.err.println(mne.getId());
+                        System.err.println("zombie make not entrant event without nmethod: " + mne.getId());
                     }
                     cacheSize -= nm.getSize();
                     nmethodsLive--;
@@ -161,8 +231,7 @@
                 maxCacheSize = Math.max(cacheSize, maxCacheSize);
             }
         }
-        out.printf("NMethods: %d created %d live %d bytes (%d peak) in the code cache\n",
-                          nmethodsCreated, nmethodsLive, cacheSize, maxCacheSize);
+        out.printf("NMethods: %d created %d live %d bytes (%d peak) in the code cache\n", nmethodsCreated, nmethodsLive, cacheSize, maxCacheSize);
         out.println("Phase times:");
         for (String name : phaseTime.keySet()) {
             Double v = phaseTime.get(name);
@@ -178,4 +247,265 @@
             }
         }
     }
+
+    /**
+     * Container class for a pair of a method and a bytecode instruction index
+     * used by a compiler. This is used in
+     * {@linkplain #compareLogs() comparing logs}.
+     */
+    static class MethodBCIPair {
+        public MethodBCIPair(Method m, int b, String c) {
+            method = m;
+            bci = b;
+            compiler = c;
+        }
+
+        Method method;
+        int bci;
+        String compiler;
+
+        public boolean equals(Object other) {
+            if (!(other instanceof MethodBCIPair)) {
+                return false;
+            }
+            MethodBCIPair otherp = (MethodBCIPair)other;
+            return (otherp.bci == bci &&
+                    otherp.method.equals(method) &&
+                    otherp.compiler.equals(compiler));
+        }
+
+        public int hashCode() {
+            return method.hashCode() + bci;
+        }
+
+        public String toString() {
+            if (bci != -1) {
+                return method + "@" + bci + " (" + compiler + ")";
+            } else {
+                return method + " (" + compiler + ")";
+            }
+        }
+    }
+
+    /**
+     * Compare a number of compilation log files. Each of the logs is parsed,
+     * and all compilations found therein are written to a sorted file (prefix
+     * {@code sorted-}. A summary is written to a new file {@code summary.txt}.
+     *
+     * @param index the index in the command line arguments at which to start
+     *              looking for files to compare.
+     * @param args  the command line arguments with which {@link LogCompilation}
+     *              was originally invoked.
+     *
+     * @throws Exception in case any exceptions are thrown in the called
+     *         methods.
+     */
+    @SuppressWarnings("unchecked")
+    static void compareLogs(int index, String[] args) throws Exception {
+        HashMap<MethodBCIPair,MethodBCIPair> methods = new HashMap<>();
+        ArrayList<HashMap<MethodBCIPair,Object>> logs = new ArrayList<>();
+        PrintStream[] outs = new PrintStream[args.length - index];
+        PrintStream summary = new PrintStream(new FileOutputStream("summary.txt"));
+        int o = 0;
+        // Process all logs given on the command line: collect compilation
+        // data; in particular, method/bci pairs.
+        while (index < args.length) {
+            String basename = new File(args[index]).getName();
+            String outname = "sorted-" + basename;
+            System.out.println("Sorting " + basename + " to " + outname);
+            outs[o] = new PrintStream(new FileOutputStream(outname));
+            o++;
+            System.out.println("Parsing " + args[index]);
+            ArrayList<LogEvent> events = LogParser.parse(args[index], false);
+            HashMap<MethodBCIPair,Object> compiles = new HashMap<>();
+            logs.add(compiles);
+            for (LogEvent c : events) {
+                if (c instanceof Compilation) {
+                    Compilation comp = (Compilation) c;
+                    MethodBCIPair key = new MethodBCIPair(comp.getMethod(), comp.getBCI(),
+                                                          comp.getCompiler());
+                    MethodBCIPair e = methods.get(key);
+                    if (e == null) {
+                        methods.put(key, key);
+                    } else {
+                        key = e;
+                    }
+                    Object other = compiles.get(key);
+                    if (other == null) {
+                        compiles.put(key, comp);
+                    } else {
+                        if (!(other instanceof List)) {
+                            List<Object> l = new LinkedList<>();
+                            l.add(other);
+                            l.add(comp);
+                            compiles.put(key, l);
+                        } else {
+                            List<Object> l = (List<Object>) other;
+                            l.add(comp);
+                        }
+                    }
+                }
+            }
+            index++;
+        }
+
+        // Process the collected method/bci pairs and write the output.
+        for (MethodBCIPair pair : methods.keySet()) {
+            summary.print(pair + " ");
+            int base = -1;
+            String first = null;
+            boolean mismatch = false;
+            boolean different = false;
+            String[] output = new String[outs.length];
+            o = 0;
+            for (HashMap<MethodBCIPair,Object> set : logs) {
+                Object e = set.get(pair);
+                String thisone = null;
+                Compilation lastc = null;
+                int n;
+                if (e == null) {
+                    n = 0;
+                } else if (e instanceof Compilation) {
+                    n = 1;
+                    lastc = (Compilation) e;
+                } else {
+                    // Compare the last compilation that was done for this method
+                    n = ((List<Object>) e).size();
+                    lastc = (Compilation) ((List<Object>) e).get(n - 1);
+                }
+                if (lastc != null) {
+                    n = 1;
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    PrintStream ps = new PrintStream(baos);
+                    lastc.print(ps, false);
+                    ps.close();
+                    thisone = new String(baos.toByteArray());
+                }
+                if (base == -1) {
+                    base = n;
+                } else if (base != n) {
+                    mismatch = true;
+                }
+                output[o++] = thisone;
+                if (thisone != null) {
+                    if (first == null) {
+                        first = thisone;
+                    } else {
+                        if (!first.equals(thisone)) {
+                            different = true;
+                        }
+                    }
+                }
+                if (different) {
+                    summary.print(n + "d ");
+                } else {
+                    summary.print(n + " ");
+                }
+            }
+            if (mismatch) {
+                summary.print("mismatch");
+            }
+            summary.println();
+            if (different) {
+                for (int i = 0; i < outs.length; i++) {
+                    if (output[i] != null) {
+                        outs[i].println(output[i]);
+                    }
+                }
+            }
+        }
+        for (int i = 0; i < outs.length; i++) {
+            outs[i].close();
+        }
+        if (summary != System.out) {
+            summary.close();
+        }
+    }
+
+    /**
+     * Print the history of uncommon trap events.
+     */
+    public static void printTrapHistory(ArrayList<LogEvent> events, PrintStream out) {
+        // map method names to a list of log events
+        LinkedHashMap<String, ArrayList<LogEvent>> traps = new LinkedHashMap<>();
+        // map compilation IDs to compilations
+        HashMap<Integer, Compilation> comps = new HashMap<>();
+
+        // First, iterate over all logged events, collecting data about
+        // uncommon trap events.
+        for (LogEvent e : events) {
+            if (e instanceof NMethod) {
+                // skip these
+                continue;
+            }
+            if (e instanceof Compilation) {
+                Compilation c = (Compilation) e;
+                String name = c.getMethod().getFullName();
+                ArrayList<LogEvent> elist = traps.get(name);
+                if (elist != null && comps.get(c.getId()) == null) {
+                    comps.put(c.getId(), c);
+                    // If there were previous events for the method
+                    // then keep track of later compiles too.
+                    elist.add(c);
+                }
+                continue;
+            }
+            if (e instanceof BasicLogEvent) {
+                BasicLogEvent ble = (BasicLogEvent) e;
+                Compilation c = ble.getCompilation();
+                if (c == null) {
+                    if (!(ble instanceof NMethod)) {
+                        throw new InternalError("only nmethods should have a null compilation; here's a " + ble.getClass());
+                    }
+                    continue;
+                }
+                String name = c.getMethod().getFullName();
+                ArrayList<LogEvent> elist = traps.get(name);
+                if (elist == null) {
+                    elist = new ArrayList<LogEvent>();
+                    traps.put(name, elist);
+                }
+                int bleId = Integer.parseInt(ble.getId());
+                if (comps.get(bleId) == null) {
+                    comps.put(bleId, c);
+                    // Add the associated compile to the list.  It
+                    // will likely go at the end but we need to search
+                    // backwards for the proper insertion point.
+                    double start = c.getStart();
+                    int ipoint = 0;
+                    while (ipoint < elist.size() && elist.get(ipoint).getStart() < start) {
+                        ipoint++;
+                    }
+                    if (ipoint == elist.size()) {
+                        elist.add(c);
+                    } else {
+                        elist.add(ipoint, c);
+                    }
+                }
+                elist.add(ble);
+            }
+        }
+
+        // Second, iterate over collected traps and output information.
+        for (String c: traps.keySet()) {
+            ArrayList<LogEvent> elist = traps.get(c);
+            String name = ((Compilation) elist.get(0)).getMethod().getFullName();
+            System.out.println(name);
+            double start = 0;
+            for (LogEvent e: elist) {
+                if (start > e.getStart() && e.getStart() != 0) {
+                    throw new InternalError("wrong sorting order for traps");
+                }
+                start = e.getStart();
+                out.print(e.getStart() + ": ");
+                if (e instanceof Compilation) {
+                    ((Compilation) e).print(out, true, true, true);
+                } else {
+                    e.print(out, true);
+                }
+            }
+            out.println();
+        }
+    }
+
 }
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogEvent.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogEvent.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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,14 +25,31 @@
 package com.sun.hotspot.tools.compiler;
 
 import java.io.PrintStream;
-import java.util.*;
 
+/**
+ * The interface of an event from a HotSpot compilation log. Events can have a
+ * duration, e.g., a compiler {@link Phase} is an event, and so is an entire
+ * {@link Compilation}.
+ */
 public interface LogEvent {
+
+    /**
+     * The event's start time.
+     */
     public double getStart();
 
+    /**
+     * The event's duration in milliseconds.
+     */
     public double getElapsedTime();
 
+    /**
+     * The compilation during which this event was signalled.
+     */
     public Compilation getCompilation();
 
-    public void print(PrintStream stream);
+    /**
+     * Print the event to the given stream.
+     */
+    public void print(PrintStream stream, boolean printID);
 }
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java	Wed Jul 05 20:43:22 2017 +0200
@@ -33,30 +33,269 @@
 import java.io.Reader;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
+import java.util.Deque;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
-import java.util.Stack;
+import java.util.regex.Pattern;
+
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
+
 import org.xml.sax.Attributes;
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
 import org.xml.sax.helpers.DefaultHandler;
 
-public class LogParser extends DefaultHandler implements ErrorHandler, Constants {
+/**
+ * A SAX parser for HotSpot compilation logs. The bulk of the parsing and event
+ * maintenance work is done in the {@link #startElement(String,String,String,Attributes)}
+ * and {@link #endElement(String,String,String)} methods.
+ */
+public class LogParser extends DefaultHandler implements ErrorHandler {
+
+    static final Pattern spacePattern = Pattern.compile(" ");
 
-    static final HashMap<String, String> typeMap;
+    /**
+     * Map internal array type descriptors to Java names.
+     */
+    static final HashMap<String, String> type2printableMap;
+
+    /**
+     * Map Java primitive type names to internal type descriptors.
+     */
+    static final HashMap<String, String> type2vmtypeMap;
+
     static {
-        typeMap = new HashMap<String, String>();
-        typeMap.put("[I", "int[]");
-        typeMap.put("[C", "char[]");
-        typeMap.put("[Z", "boolean[]");
-        typeMap.put("[L", "Object[]");
-        typeMap.put("[B", "byte[]");
+        type2printableMap = new HashMap<>();
+        type2printableMap.put("[I", "int[]");
+        type2printableMap.put("[C", "char[]");
+        type2printableMap.put("[Z", "boolean[]");
+        type2printableMap.put("[L", "Object[]");
+        type2printableMap.put("[B", "byte[]");
+
+        type2vmtypeMap = new HashMap<>();
+        type2vmtypeMap.put("void", "V");
+        type2vmtypeMap.put("boolean", "Z");
+        type2vmtypeMap.put("byte", "B");
+        type2vmtypeMap.put("char", "C");
+        type2vmtypeMap.put("short", "S");
+        type2vmtypeMap.put("int", "I");
+        type2vmtypeMap.put("long", "J");
+        type2vmtypeMap.put("float", "F");
+        type2vmtypeMap.put("double", "D");
     }
 
+    static String[] bytecodes = new String[] {
+        "nop",
+        "aconst_null",
+        "iconst_m1",
+        "iconst_0",
+        "iconst_1",
+        "iconst_2",
+        "iconst_3",
+        "iconst_4",
+        "iconst_5",
+        "lconst_0",
+        "lconst_1",
+        "fconst_0",
+        "fconst_1",
+        "fconst_2",
+        "dconst_0",
+        "dconst_1",
+        "bipush",
+        "sipush",
+        "ldc",
+        "ldc_w",
+        "ldc2_w",
+        "iload",
+        "lload",
+        "fload",
+        "dload",
+        "aload",
+        "iload_0",
+        "iload_1",
+        "iload_2",
+        "iload_3",
+        "lload_0",
+        "lload_1",
+        "lload_2",
+        "lload_3",
+        "fload_0",
+        "fload_1",
+        "fload_2",
+        "fload_3",
+        "dload_0",
+        "dload_1",
+        "dload_2",
+        "dload_3",
+        "aload_0",
+        "aload_1",
+        "aload_2",
+        "aload_3",
+        "iaload",
+        "laload",
+        "faload",
+        "daload",
+        "aaload",
+        "baload",
+        "caload",
+        "saload",
+        "istore",
+        "lstore",
+        "fstore",
+        "dstore",
+        "astore",
+        "istore_0",
+        "istore_1",
+        "istore_2",
+        "istore_3",
+        "lstore_0",
+        "lstore_1",
+        "lstore_2",
+        "lstore_3",
+        "fstore_0",
+        "fstore_1",
+        "fstore_2",
+        "fstore_3",
+        "dstore_0",
+        "dstore_1",
+        "dstore_2",
+        "dstore_3",
+        "astore_0",
+        "astore_1",
+        "astore_2",
+        "astore_3",
+        "iastore",
+        "lastore",
+        "fastore",
+        "dastore",
+        "aastore",
+        "bastore",
+        "castore",
+        "sastore",
+        "pop",
+        "pop2",
+        "dup",
+        "dup_x1",
+        "dup_x2",
+        "dup2",
+        "dup2_x1",
+        "dup2_x2",
+        "swap",
+        "iadd",
+        "ladd",
+        "fadd",
+        "dadd",
+        "isub",
+        "lsub",
+        "fsub",
+        "dsub",
+        "imul",
+        "lmul",
+        "fmul",
+        "dmul",
+        "idiv",
+        "ldiv",
+        "fdiv",
+        "ddiv",
+        "irem",
+        "lrem",
+        "frem",
+        "drem",
+        "ineg",
+        "lneg",
+        "fneg",
+        "dneg",
+        "ishl",
+        "lshl",
+        "ishr",
+        "lshr",
+        "iushr",
+        "lushr",
+        "iand",
+        "land",
+        "ior",
+        "lor",
+        "ixor",
+        "lxor",
+        "iinc",
+        "i2l",
+        "i2f",
+        "i2d",
+        "l2i",
+        "l2f",
+        "l2d",
+        "f2i",
+        "f2l",
+        "f2d",
+        "d2i",
+        "d2l",
+        "d2f",
+        "i2b",
+        "i2c",
+        "i2s",
+        "lcmp",
+        "fcmpl",
+        "fcmpg",
+        "dcmpl",
+        "dcmpg",
+        "ifeq",
+        "ifne",
+        "iflt",
+        "ifge",
+        "ifgt",
+        "ifle",
+        "if_icmpeq",
+        "if_icmpne",
+        "if_icmplt",
+        "if_icmpge",
+        "if_icmpgt",
+        "if_icmple",
+        "if_acmpeq",
+        "if_acmpne",
+        "goto",
+        "jsr",
+        "ret",
+        "tableswitch",
+        "lookupswitch",
+        "ireturn",
+        "lreturn",
+        "freturn",
+        "dreturn",
+        "areturn",
+        "return",
+        "getstatic",
+        "putstatic",
+        "getfield",
+        "putfield",
+        "invokevirtual",
+        "invokespecial",
+        "invokestatic",
+        "invokeinterface",
+        "invokedynamic",
+        "new",
+        "newarray",
+        "anewarray",
+        "arraylength",
+        "athrow",
+        "checkcast",
+        "instanceof",
+        "monitorenter",
+        "monitorexit",
+        "wide",
+        "multianewarray",
+        "ifnull",
+        "ifnonnull",
+        "goto_w",
+        "jsr_w",
+        "breakpoint"
+    };
+
+    /**
+     * Sort log events by start time.
+     */
     static Comparator<LogEvent> sortByStart = new Comparator<LogEvent>() {
 
         public int compare(LogEvent a, LogEvent b) {
@@ -80,25 +319,29 @@
             return 7;
         }
     };
+
+    /**
+     * Sort log events first by the name of the compiled method, then by start
+     * time. In case one of the events has no associated compilation (or the
+     * associated compilation has no method name), the event with a compilation
+     * and/or name is considered the larger one.
+     */
     static Comparator<LogEvent> sortByNameAndStart = new Comparator<LogEvent>() {
 
         public int compare(LogEvent a, LogEvent b) {
             Compilation c1 = a.getCompilation();
             Compilation c2 = b.getCompilation();
-            if (c1 != null && c2 != null) {
+            if (c1 != null && c1.getMethod() != null && c2 != null && c2.getMethod() != null) {
                 int result = c1.getMethod().toString().compareTo(c2.getMethod().toString());
                 if (result != 0) {
                     return result;
                 }
-            }
-            double difference = (a.getStart() - b.getStart());
-            if (difference < 0) {
+            } else if ((c1 == null || c1.getMethod() == null) && c2 != null && c2.getMethod() != null) {
                 return -1;
-            }
-            if (difference > 0) {
+            } else if ((c2 == null || c2.getMethod() == null) && c1 != null && c1.getMethod() != null) {
                 return 1;
             }
-            return 0;
+            return Double.compare(a.getStart(), b.getStart());
         }
 
         public boolean equals(Object other) {
@@ -110,6 +353,10 @@
             return 7;
         }
     };
+
+    /**
+     * Sort log events by duration.
+     */
     static Comparator<LogEvent> sortByElapsed = new Comparator<LogEvent>() {
 
         public int compare(LogEvent a, LogEvent b) {
@@ -134,6 +381,10 @@
         }
     };
 
+    /**
+     * Shrink-wrapped representation of a JVMState (tailored to meet this
+     * tool's needs). It only records a method and bytecode instruction index.
+     */
     class Jvms {
         Jvms(Method method, int bci) {
             this.method = method;
@@ -146,12 +397,33 @@
         }
     }
 
+    /**
+     * Representation of a lock elimination. Locks, corresponding to
+     * synchronized blocks and method calls, may be eliminated if the object in
+     * question is guaranteed to be used thread-locally.
+     */
     class LockElimination extends BasicLogEvent {
 
-        ArrayList<Jvms> jvms = new ArrayList<Jvms>(1);
+        /**
+         * Track all locations from which this lock was eliminated.
+         */
+        ArrayList<Jvms> jvms = new ArrayList<>(1);
+
+        /**
+         * The kind of lock (coarsened, nested, non-escaping, unknown).
+         */
         final String kind;
+
+        /**
+         * The lock class (unlock, lock, unknown).
+         */
         final String classId;
+
+        /**
+         * The precise type of lock.
+         */
         final String tagName;
+
         LockElimination(String tagName, double start, String id, String kind, String classId) {
             super(start, id);
             this.kind = kind;
@@ -160,8 +432,11 @@
         }
 
         @Override
-        public void print(PrintStream stream) {
-            stream.printf("%s %s %s %s  %.3f ", getId(), tagName, kind, classId, getStart());
+        public void print(PrintStream stream, boolean printID) {
+            if (printID) {
+                stream.printf("%s ", getId());
+            }
+            stream.printf("%s %s %s  %.3f ", tagName, kind, classId, getStart());
             stream.print(jvms.toString());
             stream.print("\n");
         }
@@ -172,25 +447,154 @@
 
     }
 
-    private ArrayList<LogEvent> events = new ArrayList<LogEvent>();
+    /**
+     * A list of log events. This is populated with the events found in the
+     * compilation log file during parsing.
+     */
+    private ArrayList<LogEvent> events = new ArrayList<>();
+
+    /**
+     * Map compilation log IDs to type names.
+     */
+    private HashMap<String, String> types = new HashMap<>();
 
-    private HashMap<String, String> types = new HashMap<String, String>();
-    private HashMap<String, Method> methods = new HashMap<String, Method>();
-    private LinkedHashMap<String, NMethod> nmethods = new LinkedHashMap<String, NMethod>();
-    private HashMap<String, Compilation> compiles = new HashMap<String, Compilation>();
+    /**
+     * Map compilation log IDs to methods.
+     */
+    private HashMap<String, Method> methods = new HashMap<>();
+
+    /**
+     * Map compilation IDs ({@see #makeId()}) to newly created nmethods.
+     */
+    private LinkedHashMap<String, NMethod> nmethods = new LinkedHashMap<>();
+
+    /**
+     * Map compilation task IDs {@see #makeId()}) to {@link Compilation}
+     * objects.
+     */
+    private HashMap<String, Compilation> compiles = new HashMap<>();
+
+    /**
+     * Track compilation failure reasons.
+     */
     private String failureReason;
-    private int bci;
-    private Stack<CallSite> scopes = new Stack<CallSite>();
+
+    /**
+     * The current bytecode instruction index.
+     */
+    private int current_bci;
+
+    /**
+     * The current bytecode instruction.
+     */
+    private int current_bytecode;
+
+    /**
+     * A sequence of {@link CallSite}s representing a call stack. A scope
+     * typically holds several {@link CallSite}s that represent calls
+     * originating from that scope.
+     *
+     * New scopes are typically pushed when parse log events are encountered
+     * ({@see #startElement()}) and popped when parsing of a given Java method
+     * is done ({@see #endElement()}). Parsing events can be nested. Several
+     * other events add information to scopes ({@see #startElement()}).
+     */
+    private Deque<CallSite> scopes = new ArrayDeque<>();
+
+    /**
+     * The current compilation.
+     */
     private Compilation compile;
+
+    /**
+     * The {@linkplain CallSite compilation scope} currently in focus.
+     */
     private CallSite site;
+
+    /**
+     * The {@linkplain CallSite method handle call site} currently under
+     * observation.
+     */
     private CallSite methodHandleSite;
-    private Stack<Phase> phaseStack = new Stack<Phase>();
+
+    /**
+     * Keep track of potentially nested compiler {@linkplain Phase phases}.
+     */
+    private Deque<Phase> phaseStack = new ArrayDeque<>();
+
+    /**
+     * The {@linkplain LockElimination lock elimination event} currently being
+     * processed.
+     */
     private LockElimination currentLockElimination;
+
+    /**
+     * The {@linkplain UncommonTrapEvent uncommon trap event} currently being
+     * processed.
+     */
     private UncommonTrapEvent currentTrap;
-    private Stack<CallSite> lateInlineScope;
+
+    /**
+     * During the processing of a late inline event, this stack holds the
+     * {@link CallSite}s that represent the inlining event's call stack.
+     */
+    private Deque<CallSite> lateInlineScope;
+
+    /**
+     * Denote whether a late inlining event is currently being processed.
+     */
     private boolean lateInlining;
 
+    /**
+     * A document locator to provide better error messages: this allows the
+     * tool to display in which line of the log file the problem occurred.
+     */
+    private Locator locator;
 
+    /**
+     * Callback for the SAX framework to set the document locator.
+     */
+    @Override
+    public void setDocumentLocator(Locator locator) {
+        this.locator = locator;
+    }
+
+    /**
+     * Report an internal error explicitly raised, i.e., not derived from an
+     * exception.
+     *
+     * @param msg The error message to report.
+     */
+    private void reportInternalError(String msg) {
+        reportInternalError(msg, null);
+    }
+
+    /**
+     * Report an internal error derived from an exception.
+     *
+     * @param msg The beginning of the error message to report. The message
+     * from the exception will be appended to this.
+     * @param e The exception that led to the internal error.
+     */
+    private void reportInternalError(String msg, Exception e) {
+        if (locator != null) {
+            msg += " at " + locator.getLineNumber() + ":" + locator.getColumnNumber();
+            if (e != null) {
+                msg += " - " + e.getMessage();
+            }
+        }
+        if (e != null) {
+            throw new Error(msg, e);
+        } else {
+            throw new Error(msg);
+        }
+    }
+
+    /**
+     * Parse a long hexadecimal address into a {@code long} value. As Java only
+     * supports positive {@code long} values, extra error handling and parsing
+     * logic is provided.
+     */
     long parseLong(String l) {
         try {
             return Long.decode(l).longValue();
@@ -207,16 +611,29 @@
                 System.out.println(v1);
                 System.out.println(v2);
                 System.out.println(Long.toHexString(v1 + v2));
-                throw new InternalError("bad conversion");
+                reportInternalError("bad conversion");
             }
             return v1 + v2;
         }
     }
 
+    /**
+     * Entry point for log file parsing with a file name.
+     *
+     * @param file The name of the log file to parse.
+     * @param cleanup Whether to perform bad XML cleanup during parsing (this
+     * is relevant for some log files generated by the 1.5 JVM).
+     * @return a list of {@link LogEvent} instances describing the events found
+     * in the log file.
+     */
     public static ArrayList<LogEvent> parse(String file, boolean cleanup) throws Exception {
         return parse(new FileReader(file), cleanup);
     }
 
+    /**
+     * Entry point for log file parsing with a file reader.
+     * {@see #parse(String,boolean)}
+     */
     public static ArrayList<LogEvent> parse(Reader reader, boolean cleanup) throws Exception {
         // Create the XML input factory
         SAXParserFactory factory = SAXParserFactory.newInstance();
@@ -238,31 +655,58 @@
             // Carry on with what we've got...
         }
 
-        // Associate compilations with their NMethods
-        for (NMethod nm : log.nmethods.values()) {
-            Compilation c = log.compiles.get(nm.getId());
-            nm.setCompilation(c);
-            // Native wrappers for methods don't have a compilation
-            if (c != null) {
-                c.setNMethod(nm);
+        // Associate compilations with their NMethods and other kinds of events
+        for (LogEvent e : log.events) {
+            if (e instanceof BasicLogEvent) {
+                BasicLogEvent ble = (BasicLogEvent) e;
+                Compilation c = log.compiles.get(ble.getId());
+                if (c == null) {
+                    if (!(ble instanceof NMethod)) {
+                        throw new InternalError("only nmethods should have a null compilation, here's a " + ble.getClass());
+                    }
+                    continue;
+                }
+                ble.setCompilation(c);
+                if (ble instanceof NMethod) {
+                    c.setNMethod((NMethod) ble);
+                }
             }
         }
 
-        // Initially we want the LogEvent log sorted by timestamp
-        Collections.sort(log.events, sortByStart);
-
         return log.events;
     }
 
+    /**
+     * Retrieve a given attribute's value from a collection of XML tag
+     * attributes. Report an error if the requested attribute is not found.
+     *
+     * @param attr A collection of XML tag attributes.
+     * @param name The name of the attribute the value of which is to be found.
+     * @return The value of the requested attribute, or {@code null} if it was
+     * not found.
+     */
     String search(Attributes attr, String name) {
         String result = attr.getValue(name);
         if (result != null) {
             return result;
         } else {
-            throw new InternalError("can't find " + name);
+            reportInternalError("can't find " + name);
+            return null;
         }
     }
 
+    /**
+     * Retrieve a given attribute's value from a collection of XML tag
+     * attributes. Return a default value if the requested attribute is not
+     * found.
+     *
+     * @param attr A collection of XML tag attributes.
+     * @param name The name of the attribute the value of which is to be found.
+     * @param defaultValue The default value to return if the attribute is not
+     * found.
+     * @return The value of the requested attribute, or the default value if it
+     * was not found.
+     */
     String search(Attributes attr, String name, String defaultValue) {
         String result = attr.getValue(name);
         if (result != null) {
@@ -270,33 +714,70 @@
         }
         return defaultValue;
     }
-    int indent = 0;
 
+    /**
+     * Map a type ID from the compilation log to an actual type name. In case
+     * the type represents an internal array type descriptor, return a
+     * Java-level name. If the type ID cannot be mapped to a name, raise an
+     * error.
+     */
     String type(String id) {
         String result = types.get(id);
         if (result == null) {
-            throw new InternalError(id);
+            reportInternalError(id);
         }
-        String remapped = typeMap.get(result);
+        String remapped = type2printableMap.get(result);
         if (remapped != null) {
             return remapped;
         }
         return result;
     }
 
+    /**
+     * Register a mapping from log file type ID to type name.
+     */
     void type(String id, String name) {
         assert type(id) == null;
         types.put(id, name);
     }
 
+    /**
+     * Map a log file type ID to an internal type declarator.
+     */
+    String sigtype(String id) {
+        String result = types.get(id);
+        String remapped = type2vmtypeMap.get(result);
+        if (remapped != null) {
+            return remapped;
+        }
+        if (result == null) {
+            reportInternalError(id);
+        }
+        if (result.charAt(0) == '[') {
+            return result;
+        }
+        return "L" + result + ";";
+    }
+
+    /**
+     * Retrieve a method based on the log file ID it was registered under.
+     * Raise an error if the ID does not map to a method.
+     */
     Method method(String id) {
         Method result = methods.get(id);
         if (result == null) {
-            throw new InternalError(id);
+            reportInternalError(id);
         }
         return result;
     }
 
+    /**
+     * From a compilation ID and kind, assemble a compilation ID for inclusion
+     * in the output.
+     *
+     * @param atts A collection of XML attributes from which the required
+     * attributes are retrieved.
+     */
     public String makeId(Attributes atts) {
         String id = atts.getValue("compile_id");
         String kind = atts.getValue("kind");
@@ -306,11 +787,60 @@
         return id;
     }
 
+    /**
+     * Process the start of a compilation log XML element.<ul>
+     * <li><b>phase:</b> record the beginning of a compilation phase, pushing
+     * it on the {@linkplain #phaseStack phase stack} and collecting
+     * information about the compiler graph.</li>
+     * <li><b>phase_done:</b> record the end of a compilation phase, popping it
+     * off the {@linkplain #phaseStack phase stack} and collecting information
+     * about the compiler graph (number of nodes and live nodes).</li>
+     * <li><b>task:</b> register the start of a new compilation.</li>
+     * <li><b>type:</b> register a type.</li>
+     * <li><b>bc:</b> note the current bytecode index and instruction name,
+     * updating {@link #current_bci} and {@link #current_bytecode}.</li>
+     * <li><b>klass:</b> register a type (class).</li>
+     * <li><b>method:</b> register a Java method.</li>
+     * <li><b>call:</b> process a call, populating {@link #site} with the
+     * appropriate data.</li>
+     * <li><b>regalloc:</b> record the register allocator's trip count in the
+     * {@linkplain #compile current compilation}.</li>
+     * <li><b>inline_fail:</b> record the reason for a failed inline
+     * operation.</li>
+     * <li><b>inline_success:</b> record a successful inlining operation,
+     * noting the success reason in the {@linkplain #site call site}.</li>
+     * <li><b>failure:</b> note a compilation failure, storing the reason
+     * description in {@link #failureReason}.</li>
+     * <li><b>task_done:</b> register the end of a compilation, recording time
+     * stamp and success information.</li>
+     * <li><b>make_not_entrant:</b> deal with making a native method
+     * non-callable (e.g., during an OSR compilation, if there are still
+     * activations) or a zombie (when the method can be deleted).</li>
+     * <li><b>uncommon_trap:</b> process an uncommon trap, setting the
+     * {@link #currentTrap} field.</li>
+     * <li><b>eliminate_lock:</b> record the start of a lock elimination,
+     * setting the {@link #currentLockElimination} event.</li>
+     * <li><b>late_inline:</b> start processing a late inline decision:
+     * initialize the {@linkplain #lateInlineScope inline scope stack}, create
+     * an {@linkplain #site initial scope} with a bogus bytecode index and the
+     * right inline ID, and push the scope with the inline ID attached. Note
+     * that most of late inlining processing happens in
+     * {@link #endElement()}.</li>
+     * <li><b>jvms:</b> record a {@linkplain Jvms JVMState}. Depending on the
+     * context in which this event is encountered, this can mean adding
+     * information to the currently being processed trap, lock elimination, or
+     * inlining operation.</li>
+     * <li><b>inline_id:</b> set the inline ID in the
+     * {@linkplain #site current call site}.</li>
+     * <li><b>nmethod:</b> record the creation of a new {@link NMethod} and
+     * store it in the {@link #nmethods} map.</li>
+     * <li><b>parse:</b> begin parsing a Java method's bytecode and
+     * transforming it into an initial compiler IR graph.</li>
+     * <li><b>parse_done:</b> finish parsing a Java method's bytecode.</li>
+     * </ul>
+     */
     @Override
-    public void startElement(String uri,
-            String localName,
-            String qname,
-            Attributes atts) {
+    public void startElement(String uri, String localName, String qname, Attributes atts) {
         if (qname.equals("phase")) {
             Phase p = new Phase(search(atts, "name"),
                     Double.parseDouble(search(atts, "stamp")),
@@ -322,45 +852,62 @@
             String phaseName = search(atts, "name", null);
             if (phaseName != null && !p.getId().equals(phaseName)) {
                 System.out.println("phase: " + p.getId());
-                throw new InternalError("phase name mismatch");
+                reportInternalError("phase name mismatch");
             }
             p.setEnd(Double.parseDouble(search(atts, "stamp")));
             p.setEndNodes(Integer.parseInt(search(atts, "nodes", "0")));
             p.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0")));
             compile.getPhases().add(p);
         } else if (qname.equals("task")) {
+            String id = makeId(atts);
+
+            // Create the new Compilation instance and populate it with readily
+            // available data.
             compile = new Compilation(Integer.parseInt(search(atts, "compile_id", "-1")));
             compile.setStart(Double.parseDouble(search(atts, "stamp")));
             compile.setICount(search(atts, "count", "0"));
             compile.setBCount(search(atts, "backedge_count", "0"));
-
-            String method = atts.getValue("method");
-            int space = method.indexOf(' ');
-            method = method.substring(0, space) + "::" +
-                    method.substring(space + 1, method.indexOf(' ', space + 1) + 1);
+            compile.setBCI(Integer.parseInt(search(atts, "osr_bci", "-1")));
             String compiler = atts.getValue("compiler");
             if (compiler == null) {
                 compiler = "";
             }
+            compile.setCompiler(compiler);
+
+            // Extract the name of the compiled method.
+            String[] parts = spacePattern.split(atts.getValue("method"));
+            String methodName = parts[0] + "::" + parts[1];
+
+            // Continue collecting compilation meta-data.
             String kind = atts.getValue("compile_kind");
             if (kind == null) {
                 kind = "normal";
             }
             if (kind.equals("osr")) {
                 compile.setOsr(true);
-                compile.setOsr_bci(Integer.parseInt(search(atts, "osr_bci")));
             } else if (kind.equals("c2i")) {
-                compile.setSpecial("--- adapter " + method);
+                compile.setSpecial("--- adapter " + methodName);
             } else {
-                compile.setSpecial(compile.getId() + " " + method + " (0 bytes)");
+                compile.setSpecial(compile.getId() + " " + methodName + " (0 bytes)");
             }
+
+            // Build a dummy method to stuff in the Compilation at the
+            // beginning.
+            Method m = new Method();
+            m.setHolder(parts[0]);
+            m.setName(parts[1]);
+            m.setSignature(parts[2]);
+            m.setFlags("0");
+            m.setBytes("unknown");
+            compile.setMethod(m);
             events.add(compile);
-            compiles.put(makeId(atts), compile);
+            compiles.put(id, compile);
             site = compile.getCall();
         } else if (qname.equals("type")) {
             type(search(atts, "id"), search(atts, "name"));
         } else if (qname.equals("bc")) {
-            bci = Integer.parseInt(search(atts, "bci"));
+            current_bci = Integer.parseInt(search(atts, "bci"));
+            current_bytecode = Integer.parseInt(search(atts, "code"));
         } else if (qname.equals("klass")) {
             type(search(atts, "id"), search(atts, "name"));
         } else if (qname.equals("method")) {
@@ -369,7 +916,19 @@
             m.setHolder(type(search(atts, "holder")));
             m.setName(search(atts, "name"));
             m.setReturnType(type(search(atts, "return")));
-            m.setArguments(search(atts, "arguments", "void"));
+            String arguments = atts.getValue("arguments");;
+            if (arguments == null) {
+                m.setSignature("()" + sigtype(atts.getValue("return")));
+            } else {
+                String[] args = spacePattern.split(arguments);
+                StringBuilder sb = new StringBuilder("(");
+                for (int i = 0; i < args.length; i++) {
+                    sb.append(sigtype(args[i]));
+                }
+                sb.append(")");
+                sb.append(sigtype(atts.getValue("return")));
+                m.setSignature(sb.toString());
+            }
 
             if (search(atts, "unloaded", "0").equals("0")) {
                m.setBytes(search(atts, "bytes"));
@@ -385,15 +944,17 @@
             if (lateInlining && scopes.size() == 0) {
                 // re-attempting already seen call site (late inlining for MH invokes)
                 if (m != site.getMethod()) {
-                    if (bci != site.getBci()) {
-                        System.out.println(m + " bci: " + bci);
-                        System.out.println(site.getMethod() +  " bci: " + site.getBci());
-                        throw new InternalError("bci mismatch after late inlining");
+                    if (current_bci != site.getBci()) {
+                        System.err.println(m + " bci: " + current_bci);
+                        System.err.println(site.getMethod() +  " bci: " + site.getBci());
+                        reportInternalError("bci mismatch after late inlining");
                     }
                     site.setMethod(m);
                 }
             } else {
-                site = new CallSite(bci, m);
+                // We're dealing with a new call site; the called method is
+                // likely to be parsed next.
+                site = new CallSite(current_bci, m);
             }
             site.setCount(Integer.parseInt(search(atts, "count", "0")));
             String receiver = atts.getValue("receiver");
@@ -403,7 +964,8 @@
             }
             int methodHandle = Integer.parseInt(search(atts, "method_handle_intrinsic", "0"));
             if (lateInlining && scopes.size() == 0) {
-                // The call was added before this round of late inlining
+                // The call was already added before this round of late
+                // inlining. Ignore.
             } else if (methodHandle == 0) {
                 scopes.peek().add(site);
             } else {
@@ -421,18 +983,16 @@
                 methodHandleSite = null;
             }
             if (lateInlining && scopes.size() == 0) {
-                site.setReason(search(atts, "reason"));
+                site.setReason("fail: " + search(atts, "reason"));
                 lateInlining = false;
             } else {
-                scopes.peek().last().setReason(search(atts, "reason"));
+                scopes.peek().last().setReason("fail: " + search(atts, "reason"));
             }
         } else if (qname.equals("inline_success")) {
             if (methodHandleSite != null) {
-                throw new InternalError("method handle site should have been replaced");
+                reportInternalError("method handle site should have been replaced");
             }
-            if (lateInlining && scopes.size() == 0) {
-                site.setReason(null);
-            }
+            site.setReason("succeed: " + search(atts, "reason"));
         } else if (qname.equals("failure")) {
             failureReason = search(atts, "reason");
         } else if (qname.equals("task_done")) {
@@ -444,7 +1004,7 @@
         } else if (qname.equals("make_not_entrant")) {
             String id = makeId(atts);
             NMethod nm = nmethods.get(id);
-            if (nm == null) throw new InternalError();
+            if (nm == null) reportInternalError("nm == null");
             LogEvent e = new MakeNotEntrantEvent(Double.parseDouble(search(atts, "stamp")), id,
                                                  atts.getValue("zombie") != null, nm);
             events.add(e);
@@ -459,8 +1019,22 @@
                         Integer.parseInt(search(atts, "count", "0")));
                 events.add(currentTrap);
             } else {
-                // uncommon trap inserted during parsing.
-                // ignore for now
+                if (atts.getValue("method") != null) {
+                    // These are messages from ciTypeFlow that don't
+                    // actually correspond to generated code.
+                    return;
+                }
+                try {
+                    if (scopes.size() == 0) {
+                        reportInternalError("scope underflow");
+                    }
+                    scopes.peek().add(new UncommonTrap(Integer.parseInt(search(atts, "bci")),
+                                                       search(atts, "reason"),
+                                                       search(atts, "action"),
+                                                       bytecodes[current_bytecode]));
+                } catch (Error e) {
+                    e.printStackTrace();
+                }
             }
         } else if (qname.startsWith("eliminate_lock")) {
             String id = atts.getValue("compile_id");
@@ -474,24 +1048,27 @@
         } else if (qname.equals("late_inline")) {
             long inlineId = 0;
             try {
-                Long.parseLong(search(atts, "inline_id"));
+                inlineId = Long.parseLong(search(atts, "inline_id"));
             } catch (InternalError ex) {
                 // Log files from older hotspots may lack inline_id,
                 // and zero is an acceptable substitute that allows processing to continue.
             }
-            lateInlineScope = new Stack<CallSite>();
-            site = new CallSite(-999, method(search(atts, "method")));
+            lateInlineScope = new ArrayDeque<>();
+            Method m = method(search(atts, "method"));
+            site = new CallSite(-999, m);
             site.setInlineId(inlineId);
             lateInlineScope.push(site);
         } else if (qname.equals("jvms")) {
             // <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/>
             if (currentTrap != null) {
-                currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci")));
+                String[] parts = spacePattern.split(atts.getValue("method"));
+                currentTrap.addMethodAndBCI(parts[0].replace('/', '.') + '.' + parts[1] + parts[2], Integer.parseInt(atts.getValue("bci")));
             } else if (currentLockElimination != null) {
                   currentLockElimination.addJVMS(method(atts.getValue("method")), Integer.parseInt(atts.getValue("bci")));
             } else if (lateInlineScope != null) {
-                bci = Integer.parseInt(search(atts, "bci"));
-                site = new CallSite(bci, method(search(atts, "method")));
+                current_bci = Integer.parseInt(search(atts, "bci"));
+                Method m = method(search(atts, "method"));
+                site = new CallSite(current_bci, m);
                 lateInlineScope.push(site);
             } else {
                 // Ignore <eliminate_allocation type='667'>,
@@ -499,7 +1076,7 @@
             }
         } else if (qname.equals("inline_id")) {
             if (methodHandleSite != null) {
-                throw new InternalError("method handle site should have been replaced");
+                reportInternalError("method handle site should have been replaced");
             }
             long id = Long.parseLong(search(atts, "id"));
             site.setInlineId(id);
@@ -513,33 +1090,53 @@
             events.add(nm);
         } else if (qname.equals("parse")) {
             if (failureReason != null && scopes.size() == 0 && !lateInlining) {
+                // A compilation just failed, and we're back at a top
+                // compilation scope.
                 failureReason = null;
                 compile.reset();
                 site = compile.getCall();
             }
 
+            // Error checking.
             if (methodHandleSite != null) {
-                throw new InternalError("method handle site should have been replaced");
+                reportInternalError("method handle site should have been replaced");
             }
-            Method m = method(search(atts, "method"));
+            Method m = method(search(atts, "method")); // this is the method being parsed
             if (lateInlining && scopes.size() == 0) {
                 if (site.getMethod() != m) {
-                    System.out.println(site.getMethod());
-                    System.out.println(m);
-                    throw new InternalError("Unexpected method mismatch during late inlining");
+                    reportInternalError("Unexpected method mismatch during late inlining (method at call site: " +
+                        site.getMethod() + ", method being parsed: " + m + ")");
                 }
             }
+
             if (scopes.size() == 0 && !lateInlining) {
+                // The method being parsed is actually the method being
+                // compiled; i.e., we're dealing with a compilation top scope,
+                // which we must consequently push to the scopes stack.
                 compile.setMethod(m);
                 scopes.push(site);
             } else {
+                // The method being parsed is *not* the current compilation's
+                // top scope; i.e., we're dealing with an actual call site
+                // in the top scope or somewhere further down a call stack.
                 if (site.getMethod() == m) {
+                    // We're dealing with monomorphic inlining that didn't have
+                    // to be narrowed down, because the receiver was known
+                    // beforehand.
                     scopes.push(site);
-                } else if (scopes.peek().getCalls().size() > 2 && m == scopes.peek().last(-2).getMethod()) {
-                    scopes.push(scopes.peek().last(-2));
+                } else if (scopes.peek().getCalls().size() > 2 && m == scopes.peek().lastButOne().getMethod()) {
+                    // We're dealing with an at least bimorphic call site, and
+                    // the compiler has now decided to parse the last-but-one
+                    // method. The last one may already have been parsed for
+                    // inlining.
+                    scopes.push(scopes.peek().lastButOne());
                 } else {
-                    // C1 prints multiple method tags during inlining when it narrows method being inlinied.
-                    // Example:
+                    // The method has been narrowed down to the one we're now
+                    // going to parse, which is inlined here. It's monomorphic
+                    // inlining, but was not immediately clear as such.
+                    //
+                    // C1 prints multiple method tags during inlining when it
+                    // narrows the method being inlined. Example:
                     //   ...
                     //   <method id="813" holder="694" name="toString" return="695" flags="1" bytes="36" iicount="1"/>
                     //   <call method="813" instr="invokevirtual"/>
@@ -552,100 +1149,132 @@
                 }
             }
         } else if (qname.equals("parse_done")) {
-            CallSite call = scopes.pop();
+            // Attach collected information about IR nodes to the current
+            // parsing scope before it's popped off the stack in endElement()
+            // (see where the parse tag is handled).
+            CallSite call = scopes.peek();
             call.setEndNodes(Integer.parseInt(search(atts, "nodes", "0")));
             call.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0")));
             call.setTimeStamp(Double.parseDouble(search(atts, "stamp")));
-            scopes.push(call);
         }
     }
 
+    /**
+     * Process the end of a compilation log XML element.<ul>
+     * <li><b>parse:</b> finish transforming a Java method's bytecode
+     * instructions to an initial compiler IR graph.</li>
+     * <li><b>uncommon_trap:</b> record the end of processing an uncommon trap,
+     * resetting {@link #currentTrap}.</li>
+     * <li><b>eliminate_lock:</b> record the end of a lock elimination,
+     * resetting {@link #currentLockElimination}.</li>
+     * <li><b>late_inline:</b> the closing tag for late_inline does not denote
+     * the end of a late inlining operation, but the end of the descriptive log
+     * data given at its beginning. That is, we're now in the position to
+     * assemble details about the inlining chain (bytecode instruction index in
+     * caller, called method). The {@link #lateInlining} flag is set to
+     * {@code true} here. (It will be reset when parsing the inlined methods is
+     * done; this happens for the successful case in this method as well, when
+     * {@code parse} elements are processed; and for inlining failures, in
+     * {@link #startElement()}, when {@code inline_fail} elements are
+     * processed.)</li>
+     * <li><b>task:</b> perform cleanup at the end of a compilation. Note that
+     * the explicit {@code task_done} event is handled in
+     * {@link #startElement()}.</li>
+     * </ul>
+     */
     @Override
-    public void endElement(String uri,
-            String localName,
-            String qname) {
-        if (qname.equals("parse")) {
-            indent -= 2;
-            scopes.pop();
-            if (scopes.size() == 0) {
-                lateInlining = false;
-            }
-        } else if (qname.equals("uncommon_trap")) {
-            currentTrap = null;
-        } else if (qname.startsWith("eliminate_lock")) {
-            currentLockElimination = null;
-        } else if (qname.equals("late_inline")) {
-            // Populate late inlining info.
-            if (scopes.size() != 0) {
-                throw new InternalError("scopes should be empty for late inline");
-            }
-            // late inline scopes are specified in reverse order:
-            // compiled method should be on top of stack.
-            CallSite caller = lateInlineScope.pop();
-            Method m = compile.getMethod();
-            if (m != caller.getMethod()) {
-                System.err.println(m);
-                System.err.println(caller.getMethod() + " bci: " + bci);
-                throw new InternalError("call site and late_inline info don't match");
-            }
+    public void endElement(String uri, String localName, String qname) {
+        try {
+            if (qname.equals("parse")) {
+                // Finish dealing with the current call scope. If no more are
+                // left, no late inlining can be going on.
+                scopes.pop();
+                if (scopes.size() == 0) {
+                    lateInlining = false;
+                }
+            } else if (qname.equals("uncommon_trap")) {
+                currentTrap = null;
+            } else if (qname.startsWith("eliminate_lock")) {
+                currentLockElimination = null;
+            } else if (qname.equals("late_inline")) {
+                // Populate late inlining info.
+                if (scopes.size() != 0) {
+                    reportInternalError("scopes should be empty for late inline");
+                }
+                // late inline scopes are specified in reverse order:
+                // compiled method should be on top of stack.
+                CallSite caller = lateInlineScope.pop();
+                Method m = compile.getMethod();
+                if (!m.equals(caller.getMethod())) {
+                    reportInternalError(String.format("call site and late_inline info don't match:\n  method %s\n  caller method %s, bci %d", m, caller.getMethod(), current_bci));
+                }
 
-            // late_inline contains caller+bci info, convert it
-            // to bci+callee info used by LogCompilation.
-            CallSite lateInlineSite = compile.getLateInlineCall();
-            ArrayDeque<CallSite> thisCallScopes = new ArrayDeque<CallSite>();
-            do {
-                bci = caller.getBci();
-                // Next inlined call.
-                caller = lateInlineScope.pop();
-                CallSite callee =  new CallSite(bci, caller.getMethod());
-                callee.setInlineId(caller.getInlineId());
-                thisCallScopes.addLast(callee);
-                lateInlineSite.add(callee);
-                lateInlineSite = callee;
-            } while (!lateInlineScope.empty());
+                // Walk down the inlining chain and assemble bci+callee info.
+                // This needs to be converted from caller+bci info contained in
+                // the late_inline data.
+                CallSite lateInlineSite = compile.getLateInlineCall();
+                ArrayDeque<CallSite> thisCallScopes = new ArrayDeque<>();
+                do {
+                    current_bci = caller.getBci();
+                    // Next inlined call.
+                    caller = lateInlineScope.pop();
+                    CallSite callee = new CallSite(current_bci, caller.getMethod());
+                    callee.setInlineId(caller.getInlineId());
+                    thisCallScopes.addLast(callee);
+                    lateInlineSite.add(callee);
+                    lateInlineSite = callee;
+                } while (!lateInlineScope.isEmpty());
 
-            site = compile.getCall().findCallSite(thisCallScopes);
-            if (site == null) {
-                System.out.println("call scopes:");
-                for (CallSite c : thisCallScopes) {
-                    System.out.println(c.getMethod() + " " + c.getBci() + " " + c.getInlineId());
+                site = compile.getCall().findCallSite(thisCallScopes);
+                if (site == null) {
+                    // Call site could not be found - report the problem in detail.
+                    System.err.println("call scopes:");
+                    for (CallSite c : thisCallScopes) {
+                        System.err.println(c.getMethod() + " " + c.getBci() + " " + c.getInlineId());
+                    }
+                    CallSite c = thisCallScopes.getLast();
+                    if (c.getInlineId() != 0) {
+                        System.err.println("Looking for call site in entire tree:");
+                        ArrayDeque<CallSite> stack = compile.getCall().findCallSite2(c);
+                        for (CallSite c2 : stack) {
+                            System.err.println(c2.getMethod() + " " + c2.getBci() + " " + c2.getInlineId());
+                        }
+                    }
+                    System.err.println(caller.getMethod() + " bci: " + current_bci);
+                    reportInternalError("couldn't find call site");
                 }
-                CallSite c = thisCallScopes.getLast();
-                if (c.getInlineId() != 0) {
-                    System.out.println("Looking for call site in entire tree:");
-                    ArrayDeque<CallSite> stack = compile.getCall().findCallSite2(c);
-                    for (CallSite c2 : stack) {
-                        System.out.println(c2.getMethod() + " " + c2.getBci() + " " + c2.getInlineId());
+                lateInlining = true;
+
+                if (caller.getBci() != -999) {
+                    System.out.println(caller.getMethod());
+                    reportInternalError("broken late_inline info");
+                }
+                if (site.getMethod() != caller.getMethod()) {
+                    if (site.getInlineId() == caller.getInlineId()) {
+                        site.setMethod(caller.getMethod());
+                    } else {
+                        System.out.println(site.getMethod());
+                        System.out.println(caller.getMethod());
+                        reportInternalError("call site and late_inline info don't match");
                     }
                 }
-                System.out.println(caller.getMethod() + " bci: " + bci);
-                throw new InternalError("couldn't find call site");
-            }
-            lateInlining = true;
-
-            if (caller.getBci() != -999) {
-                System.out.println(caller.getMethod());
-                throw new InternalError("broken late_inline info");
+                // late_inline is followed by parse with scopes.size() == 0,
+                // 'site' will be pushed to scopes.
+                lateInlineScope = null;
+            } else if (qname.equals("task")) {
+                types.clear();
+                methods.clear();
+                site = null;
             }
-            if (site.getMethod() != caller.getMethod()) {
-                if (site.getInlineId() == caller.getInlineId()) {
-                    site.setMethod(caller.getMethod());
-                } else {
-                    System.out.println(site.getMethod());
-                    System.out.println(caller.getMethod());
-                    throw new InternalError("call site and late_inline info don't match");
-                }
-            }
-            // late_inline is followed by parse with scopes.size() == 0,
-            // 'site' will be pushed to scopes.
-            lateInlineScope = null;
-        } else if (qname.equals("task")) {
-            types.clear();
-            methods.clear();
-            site = null;
+        } catch (Exception e) {
+            reportInternalError("exception while processing end element", e);
         }
     }
 
+    //
+    // Handlers for problems that occur in XML parsing itself.
+    //
+
     @Override
     public void warning(org.xml.sax.SAXParseException e) {
         System.err.println(e.getMessage() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber());
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/MakeNotEntrantEvent.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/MakeNotEntrantEvent.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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,14 +21,25 @@
  * questions.
  *
  */
-
 package com.sun.hotspot.tools.compiler;
 
 import java.io.PrintStream;
 
+/**
+ * In a compilation log, represent the event of making a given compiled method
+ * not-entrant, e.g., during an OSR compilation.
+ */
 class MakeNotEntrantEvent extends BasicLogEvent {
+
+    /**
+     * Denote whether the method is marked as a zombie, i.e., no further
+     * activations exist.
+     */
     private final boolean zombie;
 
+    /**
+     * The method in question.
+     */
     private NMethod nmethod;
 
     MakeNotEntrantEvent(double s, String i, boolean z, NMethod nm) {
@@ -41,7 +52,7 @@
         return nmethod;
     }
 
-    public void print(PrintStream stream) {
+    public void print(PrintStream stream, boolean printID) {
         if (isZombie()) {
             stream.printf("%s make_zombie\n", getId());
         } else {
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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,16 +26,58 @@
 
 import java.util.Arrays;
 
-public class Method implements Constants {
+import static com.sun.hotspot.tools.compiler.Constants.*;
+
+/**
+ * Representation of a Java method in a compilation log.
+ */
+public class Method {
 
+    /**
+     * The name of the class holding the method.
+     */
     private String holder;
+
+    /**
+     * The method's name.
+     */
     private String name;
+
+    /**
+     * The return type of the method, as a fully qualified (source-level) class
+     * or primitive type name.
+     */
     private String returnType;
-    private String arguments;
+
+    /**
+     * The method's signature, in internal form.
+     */
+    private String signature;
+
+    /**
+     * The length of the method's byte code.
+     */
     private String bytes;
+
+    /**
+     * The number of times this method was invoked in the interpreter.
+     */
     private String iicount;
+
+    /**
+     * The method's flags, in the form of a {@code String} representing the
+     * {@code int} encoding them.
+     */
     private String flags;
 
+    /**
+     * Decode the {@link flags} numerical string to a format for console
+     * output. The result does not honour all possible flags but includes
+     * information about OSR compilation.
+     *
+     * @param osr_bci the byte code index at which an OSR compilation takes
+     * place, or -1 if the compilation is not an OSR one.
+     */
     String decodeFlags(int osr_bci) {
         int f = Integer.parseInt(getFlags());
         char[] c = new char[4];
@@ -49,6 +91,12 @@
         return new String(c);
     }
 
+    /**
+     * Format this method for console output.
+     *
+     * @param osr_bci the byte code index at which OSR takes place, or -1 if no
+     * OSR compilation is going on.
+     */
     String format(int osr_bci) {
         if (osr_bci >= 0) {
             return getHolder() + "::" + getName() + " @ " + osr_bci + " (" + getBytes() + " bytes)";
@@ -62,6 +110,10 @@
         return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)";
     }
 
+    public String getFullName() {
+        return getHolder().replace('/', '.') + "." + getName() + signature;
+    }
+
     public String getHolder() {
         return holder;
     }
@@ -86,12 +138,16 @@
         this.returnType = returnType;
     }
 
-    public String getArguments() {
-        return arguments;
+    public String getSignature() {
+        return signature;
     }
 
-    public void setArguments(String arguments) {
-        this.arguments = arguments;
+    public void setSignature(String signature) {
+        this.signature = signature.replace('/', '.');
+    }
+
+    public String getArguments() {
+        return signature.substring(0, signature.indexOf(')') + 1);
     }
 
     public String getBytes() {
@@ -121,10 +177,13 @@
     @Override
     public boolean equals(Object o) {
         if (o instanceof Method) {
-            Method other = (Method)o;
-            return holder.equals(other.holder) && name.equals(other.name) &&
-                arguments.equals(other.arguments) && returnType.equals(other.returnType);
+            Method other = (Method) o;
+            return holder.equals(other.holder) && name.equals(other.name) && signature.equals(other.signature);
         }
         return false;
     }
+
+    public int hashCode() {
+        return holder.hashCode() ^ name.hashCode();
+    }
 }
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/NMethod.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/NMethod.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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,9 +26,20 @@
 
 import java.io.PrintStream;
 
+/**
+ * A compilation log event that is signalled whenever a new nmethod (a native
+ * method, a compilation result) is created.
+ */
 public class NMethod extends BasicLogEvent {
 
+    /**
+     * The nmethod's starting address in memory.
+     */
     private long address;
+
+    /**
+     * The nmethod's size in bytes.
+     */
     private long size;
 
     NMethod(double s, String i, long a, long sz) {
@@ -37,7 +48,7 @@
         size = sz;
     }
 
-    public void print(PrintStream out) {
+    public void print(PrintStream out, boolean printID) {
         // XXX Currently we do nothing
         // throw new InternalError();
     }
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Phase.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Phase.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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,11 +26,30 @@
 
 import java.io.PrintStream;
 
+/**
+ * Representation of a compilation phase as a log event.
+ */
 public class Phase extends BasicLogEvent {
 
+    /**
+     * The number of nodes in the compilation at the beginning of this phase.
+     */
     private final int startNodes;
+
+    /**
+     * The number of nodes in the compilation at the end of this phase.
+     */
     private int endNodes;
+
+    /**
+     * The number of live nodes in the compilation at the beginning of this
+     * phase.
+     */
     private final int startLiveNodes;
+
+    /**
+     * The number of live nodes in the compilation at the end of this phase.
+     */
     private int endLiveNodes;
 
     Phase(String n, double s, int nodes, int live) {
@@ -58,8 +77,11 @@
     public int getEndNodes() {
         return endNodes;
     }
-    /* Number of live nodes added by the phase */
-    int getLiveNodes() {
+
+    /**
+     * The number of live nodes added by this phase.
+     */
+    int getAddedLiveNodes() {
         return getEndLiveNodes() - getStartLiveNodes();
     }
 
@@ -76,7 +98,7 @@
     }
 
     @Override
-    public void print(PrintStream stream) {
+    public void print(PrintStream stream, boolean printID) {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrap.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2009, 2015, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.tools.compiler;
+
+import java.io.PrintStream;
+
+/**
+ * An instance of this class represents an uncommon trap associated with a
+ * given bytecode instruction. An uncommon trap is described in terms of its
+ * reason and action to be taken. An instance of this class is always relative
+ * to a specific method and only contains the relevant bytecode instruction
+ * index.
+ */
+class UncommonTrap {
+
+    private int bci;
+    private String reason;
+    private String action;
+    private String bytecode;
+
+    public UncommonTrap(int b, String r, String a, String bc) {
+        bci = b;
+        reason = r;
+        action = a;
+        bytecode = bc;
+    }
+
+    public int getBCI() {
+        return bci;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public String getAction() {
+        return action;
+    }
+
+    public String getBytecode() {
+        return bytecode;
+    }
+
+    void emit(PrintStream stream, int indent) {
+        for (int i = 0; i < indent; i++) {
+            stream.print(' ');
+        }
+    }
+
+    public void print(PrintStream stream, int indent) {
+        emit(stream, indent);
+        stream.println(this);
+    }
+
+    public String toString() {
+        return "@ " + bci  + " " + getBytecode() + " uncommon trap " + getReason() + " " + getAction();
+    }
+}
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java	Wed Jul 05 20:43:22 2017 +0200
@@ -21,17 +21,33 @@
  * questions.
  *
  */
-
 package com.sun.hotspot.tools.compiler;
 
 import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
 
+/**
+ * Represents an uncommon trap encountered during a compilation.
+ */
 class UncommonTrapEvent extends BasicLogEvent {
 
     private final String reason;
     private final String action;
+
+    /**
+     * Denote how many times this trap has been encountered.
+     */
     private int count;
-    private String jvms = "";
+
+    /**
+     * The name of the bytecode instruction at which the trap occurred.
+     */
+    private String bytecode;
+
+    private List<String> jvmsMethods = new ArrayList<>();
+
+    private List<Integer> jvmsBCIs = new ArrayList<>();
 
     UncommonTrapEvent(double s, String i, String r, String a, int c) {
         super(s, i);
@@ -40,20 +56,26 @@
         count = c;
     }
 
-
-    public void addJVMS(String method, int bci) {
-        setJvms(getJvms() + "  @" + bci + " " + method + "\n");
-    }
-
     public void updateCount(UncommonTrapEvent trap) {
         setCount(Math.max(getCount(), trap.getCount()));
     }
 
-    public void print(PrintStream stream) {
-        stream.printf("%s uncommon trap %.3f %s %s\n", getId(), getStart(), getReason(), getAction());
-        stream.print(getJvms());
+    public void print(PrintStream stream, boolean printID) {
+        if (printID) {
+            stream.print(getId() + " ");
+        }
+        stream.printf("uncommon trap %s %s %s\n", bytecode, getReason(), getAction());
+        int indent = 2;
+        for (int j = 0; j < jvmsMethods.size(); j++) {
+            for (int i = 0; i < indent; i++) {
+                stream.print(' ');
+            }
+            stream.println("@ " + jvmsBCIs.get(j) + " " + jvmsMethods.get(j));
+            indent += 2;
+        }
     }
 
+
     public String getReason() {
         return reason;
     }
@@ -70,15 +92,56 @@
         this.count = count;
     }
 
-    public String getJvms() {
-        return jvms;
+    /**
+     * Set the compilation for this event. This involves identifying the call
+     * site to which this uncommon trap event belongs. In addition to setting
+     * the {@link #compilation} link, this method will consequently also set
+     * the {@link #bytecode} field.
+     */
+    public void setCompilation(Compilation compilation) {
+        super.setCompilation(compilation);
+        // Attempt to associate a bytecode with with this trap
+        CallSite site = compilation.getCall();
+        int i = 0;
+        try {
+            List<UncommonTrap> traps = site.getTraps();
+            while (i + 1 < jvmsMethods.size()) {
+                if (!jvmsMethods.get(i).equals(site.getMethod().getFullName())) {
+                    throw new InternalError(jvmsMethods.get(i) + " != " + site.getMethod().getFullName());
+                }
+                CallSite result = null;
+                for (CallSite call : site.getCalls()) {
+                    if (call.getBci() == jvmsBCIs.get(i) &&
+                        call.getMethod().getFullName().equals(jvmsMethods.get(i + 1)) &&
+                        call.getReceiver() == null) {
+                        result = call;
+                        i++;
+                        break;
+                    }
+                }
+                if (result == null) {
+                    throw new InternalError("couldn't find call site");
+                }
+                site = result;
+                traps = site.getTraps();
+            }
+            for (UncommonTrap trap : traps) {
+                if (trap.getBCI() == jvmsBCIs.get(i) &&
+                    trap.getReason().equals(getReason()) &&
+                    trap.getAction().equals(getAction())) {
+                    bytecode = trap.getBytecode();
+                    return;
+                }
+            }
+            throw new InternalError("couldn't find bytecode");
+        } catch (Exception e) {
+            bytecode = "<unknown>";
+        }
     }
 
-    public void setJvms(String jvms) {
-        this.jvms = jvms;
+    public void addMethodAndBCI(String method, int bci) {
+        jvmsMethods.add(0, method);
+        jvmsBCIs.add(0, bci);
     }
 
-    public void setCompilation(Compilation compilation) {
-        this.compilation = compilation;
-    }
 }
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -75,6 +75,9 @@
 {
   assert(h_m() != NULL, "no null method");
 
+  if (LogTouchedMethods) {
+    h_m()->log_touched(Thread::current());
+  }
   // These fields are always filled in in loaded methods.
   _flags = ciFlags(h_m()->access_flags());
 
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -2698,8 +2698,7 @@
     // Inner class index
     u2 inner_class_info_index = cfs->get_u2_fast();
     check_property(
-      inner_class_info_index == 0 ||
-        valid_klass_reference_at(inner_class_info_index),
+      valid_klass_reference_at(inner_class_info_index),
       "inner_class_info_index %u has bad constant type in class file %s",
       inner_class_info_index, CHECK_0);
     // Outer class index
@@ -5163,8 +5162,8 @@
     // The first non-signature thing better be a ')'
     if ((length > 0) && (*p++ == JVM_SIGNATURE_ENDFUNC)) {
       length--;
-      if (name->utf8_length() > 0 && name->byte_at(0) == '<') {
-        // All internal methods must return void
+      if (name == vmSymbols::object_initializer_name()) {
+        // All "<init>" methods must return void
         if ((length == 1) && (p[0] == JVM_SIGNATURE_VOID)) {
           return args_size;
         }
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -58,14 +58,14 @@
 
   if (DumpSharedSpaces) {
     // Allocate all symbols to CLD shared metaspace
-    sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, -1);
+    sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, PERM_REFCOUNT);
   } else if (c_heap) {
     // refcount starts as 1
     sym = new (len, THREAD) Symbol(name, len, 1);
     assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
   } else {
     // Allocate to global arena
-    sym = new (len, arena(), THREAD) Symbol(name, len, -1);
+    sym = new (len, arena(), THREAD) Symbol(name, len, PERM_REFCOUNT);
   }
   return sym;
 }
--- a/hotspot/src/share/vm/classfile/verifier.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/classfile/verifier.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -2846,7 +2846,7 @@
   if (sig_stream.type() != T_VOID) {
     if (method_name == vmSymbols::object_initializer_name()) {
       // <init> method must have a void return type
-      /* Unreachable?  Class file parser verifies that methods with '<' have
+      /* Unreachable?  Class file parser verifies that <init> methods have
        * void return */
       verify_error(ErrorContext::bad_code(bci),
           "Return type must be void in <init> method");
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -501,8 +501,8 @@
   methodHandle method(thread, this->method());
   ResourceMark rm(thread);
 
-  // <task id='9' method='M' osr_bci='X' level='1' blocking='1' stamp='1.234'>
-  log->print(" compile_id='%d'", _compile_id);
+  // <task compiler='Cx' id='9' method='M' osr_bci='X' level='1' blocking='1' stamp='1.234'>
+  log->print(" compiler='%s' compile_id='%d'", _comp_level <= CompLevel_full_profile ? "C1" : "C2", _compile_id);
   if (_osr_bci != CompileBroker::standard_entry_bci) {
     log->print(" compile_kind='osr'");  // same as nmethod::compile_kind
   } // else compile_kind='c2c'
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -848,7 +848,7 @@
     _gch->oop_since_save_marks_iterate(GenCollectedHeap::YoungGen,
                                        _scan_cur_or_nonheap,
                                        _scan_older);
-  } while (!_gch->no_allocs_since_save_marks(true /* include_young */));
+  } while (!_gch->no_allocs_since_save_marks());
 }
 
 
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -96,7 +96,7 @@
 void DefNewGeneration::EvacuateFollowersClosure::do_void() {
   do {
     _gch->oop_since_save_marks_iterate(GenCollectedHeap::YoungGen, _scan_cur_or_nonheap, _scan_older);
-  } while (!_gch->no_allocs_since_save_marks(GenCollectedHeap::YoungGen));
+  } while (!_gch->no_allocs_since_save_marks());
 }
 
 DefNewGeneration::FastEvacuateFollowersClosure::
@@ -112,7 +112,7 @@
 void DefNewGeneration::FastEvacuateFollowersClosure::do_void() {
   do {
     _gch->oop_since_save_marks_iterate(GenCollectedHeap::YoungGen, _scan_cur_or_nonheap, _scan_older);
-  } while (!_gch->no_allocs_since_save_marks(GenCollectedHeap::YoungGen));
+  } while (!_gch->no_allocs_since_save_marks());
   guarantee(_gen->promo_failure_scan_is_complete(), "Failed to finish scan");
 }
 
@@ -597,7 +597,7 @@
 
   gch->rem_set()->prepare_for_younger_refs_iterate(false);
 
-  assert(gch->no_allocs_since_save_marks(GenCollectedHeap::YoungGen),
+  assert(gch->no_allocs_since_save_marks(),
          "save marks have not been newly set.");
 
   // Not very pretty.
@@ -617,7 +617,7 @@
                                                   &fsc_with_no_gc_barrier,
                                                   &fsc_with_gc_barrier);
 
-  assert(gch->no_allocs_since_save_marks(GenCollectedHeap::YoungGen),
+  assert(gch->no_allocs_since_save_marks(),
          "save marks have not been newly set.");
 
   {
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -741,11 +741,9 @@
 
 #undef GCH_SINCE_SAVE_MARKS_ITERATE_DEFN
 
-bool GenCollectedHeap::no_allocs_since_save_marks(bool include_young) {
-  if (include_young && !_young_gen->no_allocs_since_save_marks()) {
-    return false;
-  }
-  return _old_gen->no_allocs_since_save_marks();
+bool GenCollectedHeap::no_allocs_since_save_marks() {
+  return _young_gen->no_allocs_since_save_marks() &&
+         _old_gen->no_allocs_since_save_marks();
 }
 
 bool GenCollectedHeap::supports_inline_contig_alloc() const {
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -436,7 +436,7 @@
 
   // Returns "true" iff no allocations have occurred since the last
   // call to "save_marks".
-  bool no_allocs_since_save_marks(bool include_young);
+  bool no_allocs_since_save_marks();
 
   // Returns true if an incremental collection is likely to fail.
   // We optionally consult the young gen, if asked to do so;
--- a/hotspot/src/share/vm/oops/markOop.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/oops/markOop.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -32,26 +32,32 @@
 void markOopDesc::print_on(outputStream* st) const {
   if (is_marked()) {
     st->print(" marked(" INTPTR_FORMAT ")", value());
+  } else if (has_monitor()) {
+    // have to check has_monitor() before is_locked()
+    st->print(" monitor(" INTPTR_FORMAT ")=", value());
+    ObjectMonitor* mon = monitor();
+    if (mon == NULL) {
+      st->print("NULL (this should never be seen!)");
+    } else {
+      st->print("{count=" INTPTR_FORMAT ",waiters=" INTPTR_FORMAT
+                ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}",
+                mon->count(), mon->waiters(), mon->recursions(),
+                p2i(mon->owner()));
+    }
   } else if (is_locked()) {
     st->print(" locked(" INTPTR_FORMAT ")->", value());
     if (is_neutral()) {
       st->print("is_neutral");
-      if (has_no_hash()) st->print(" no_hash");
-      else st->print(" hash=" INTPTR_FORMAT, hash());
+      if (has_no_hash()) {
+        st->print(" no_hash");
+      } else {
+        st->print(" hash=" INTPTR_FORMAT, hash());
+      }
       st->print(" age=%d", age());
     } else if (has_bias_pattern()) {
       st->print("is_biased");
       JavaThread* jt = biased_locker();
       st->print(" biased_locker=" INTPTR_FORMAT, p2i(jt));
-    } else if (has_monitor()) {
-      ObjectMonitor* mon = monitor();
-      if (mon == NULL)
-        st->print("monitor=NULL");
-      else {
-        BasicLock * bl = (BasicLock *) mon->owner();
-        st->print("monitor={count=" INTPTR_FORMAT ",waiters=" INTPTR_FORMAT ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}",
-                mon->count(), mon->waiters(), mon->recursions(), p2i(bl));
-      }
     } else {
       st->print("??");
     }
--- a/hotspot/src/share/vm/oops/method.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/oops/method.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -422,6 +422,11 @@
   if (!mh->init_method_counters(counters)) {
     MetadataFactory::free_metadata(mh->method_holder()->class_loader_data(), counters);
   }
+
+  if (LogTouchedMethods) {
+    mh->log_touched(CHECK_NULL);
+  }
+
   return mh->method_counters();
 }
 
@@ -2130,6 +2135,85 @@
 }
 #endif // INCLUDE_SERVICES
 
+// LogTouchedMethods and PrintTouchedMethods
+
+// TouchedMethodRecord -- we can't use a HashtableEntry<Method*> because
+// the Method may be garbage collected. Let's roll our own hash table.
+class TouchedMethodRecord : CHeapObj<mtTracing> {
+public:
+  // It's OK to store Symbols here because they will NOT be GC'ed if
+  // LogTouchedMethods is enabled.
+  TouchedMethodRecord* _next;
+  Symbol* _class_name;
+  Symbol* _method_name;
+  Symbol* _method_signature;
+};
+
+static const int TOUCHED_METHOD_TABLE_SIZE = 20011;
+static TouchedMethodRecord** _touched_method_table = NULL;
+
+void Method::log_touched(TRAPS) {
+
+  const int table_size = TOUCHED_METHOD_TABLE_SIZE;
+  Symbol* my_class = klass_name();
+  Symbol* my_name  = name();
+  Symbol* my_sig   = signature();
+
+  unsigned int hash = my_class->identity_hash() +
+                      my_name->identity_hash() +
+                      my_sig->identity_hash();
+  juint index = juint(hash) % table_size;
+
+  MutexLocker ml(TouchedMethodLog_lock, THREAD);
+  if (_touched_method_table == NULL) {
+    _touched_method_table = NEW_C_HEAP_ARRAY2(TouchedMethodRecord*, table_size,
+                                              mtTracing, CURRENT_PC);
+    memset(_touched_method_table, 0, sizeof(TouchedMethodRecord*)*table_size);
+  }
+
+  TouchedMethodRecord* ptr = _touched_method_table[index];
+  while (ptr) {
+    if (ptr->_class_name       == my_class &&
+        ptr->_method_name      == my_name &&
+        ptr->_method_signature == my_sig) {
+      return;
+    }
+    if (ptr->_next == NULL) break;
+    ptr = ptr->_next;
+  }
+  TouchedMethodRecord* nptr = NEW_C_HEAP_OBJ(TouchedMethodRecord, mtTracing);
+  my_class->set_permanent();  // prevent reclaimed by GC
+  my_name->set_permanent();
+  my_sig->set_permanent();
+  nptr->_class_name         = my_class;
+  nptr->_method_name        = my_name;
+  nptr->_method_signature   = my_sig;
+  nptr->_next               = NULL;
+
+  if (ptr == NULL) {
+    // first
+    _touched_method_table[index] = nptr;
+  } else {
+    ptr->_next = nptr;
+  }
+}
+
+void Method::print_touched_methods(outputStream* out) {
+  MutexLockerEx ml(Thread::current()->is_VM_thread() ? NULL : TouchedMethodLog_lock);
+  out->print_cr("# Method::print_touched_methods version 1");
+  if (_touched_method_table) {
+    for (int i = 0; i < TOUCHED_METHOD_TABLE_SIZE; i++) {
+      TouchedMethodRecord* ptr = _touched_method_table[i];
+      while(ptr) {
+        ptr->_class_name->print_symbol_on(out);       out->print(".");
+        ptr->_method_name->print_symbol_on(out);      out->print(":");
+        ptr->_method_signature->print_symbol_on(out); out->cr();
+        ptr = ptr->_next;
+      }
+    }
+  }
+}
+
 // Verification
 
 void Method::verify_on(outputStream* st) {
--- a/hotspot/src/share/vm/oops/method.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/oops/method.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -625,6 +625,8 @@
 #if INCLUDE_SERVICES
   void collect_statistics(KlassSizeStats *sz) const;
 #endif
+  void log_touched(TRAPS);
+  static void print_touched_methods(outputStream* out);
 
   // interpreter support
   static ByteSize const_offset()                 { return byte_offset_of(Method, _constMethod       ); }
--- a/hotspot/src/share/vm/oops/symbol.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/oops/symbol.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -96,12 +96,16 @@
 // TempNewSymbol (passed in as a parameter) so the reference count on its symbol
 // will be decremented when it goes out of scope.
 
-
 // This cannot be inherited from ResourceObj because it cannot have a vtable.
 // Since sometimes this is allocated from Metadata, pick a base allocation
 // type without virtual functions.
 class ClassLoaderData;
 
+// Set _refcount to PERM_REFCOUNT to prevent the Symbol from being GC'ed.
+#ifndef PERM_REFCOUNT
+#define PERM_REFCOUNT -1
+#endif
+
 // We separate the fields in SymbolBase from Symbol::_body so that
 // Symbol::size(int) can correctly calculate the space needed.
 class SymbolBase : public MetaspaceObj {
@@ -160,6 +164,13 @@
   int refcount() const      { return _refcount; }
   void increment_refcount();
   void decrement_refcount();
+  // Set _refcount non zero to avoid being reclaimed by GC.
+  void set_permanent() {
+    assert(LogTouchedMethods, "Should not be called with LogTouchedMethods off");
+    if (_refcount != PERM_REFCOUNT) {
+      _refcount = PERM_REFCOUNT;
+    }
+  }
 
   int byte_at(int index) const {
     assert(index >=0 && index < _length, "symbol index overflow");
--- a/hotspot/src/share/vm/opto/loopTransform.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -280,6 +280,10 @@
       || (body_size * body_size + phase->C->live_nodes()) > phase->C->max_node_limit() ) {
     return false;           // too large to safely clone
   }
+
+  // check for vectorized loops, any peeling done was already applied
+  if (_head->is_CountedLoop() && _head->as_CountedLoop()->do_unroll_only()) return false;
+
   while( test != _head ) {      // Scan till run off top of loop
     if( test->is_If() ) {       // Test?
       Node *ctrl = phase->get_ctrl(test->in(1));
@@ -656,7 +660,12 @@
   _local_loop_unroll_limit = LoopUnrollLimit;
   _local_loop_unroll_factor = 4;
   int future_unroll_ct = cl->unrolled_count() * 2;
-  if (future_unroll_ct > LoopMaxUnroll) return false;
+  if (!cl->do_unroll_only()) {
+    if (future_unroll_ct > LoopMaxUnroll) return false;
+  } else {
+    // obey user constraints on vector mapped loops with additional unrolling applied
+    if ((future_unroll_ct / cl->slp_max_unroll()) > LoopMaxUnroll) return false;
+  }
 
   // Check for initial stride being a small enough constant
   if (abs(cl->stride_con()) > (1<<2)*future_unroll_ct) return false;
@@ -759,13 +768,19 @@
     if (LoopMaxUnroll > _local_loop_unroll_factor) {
       // Once policy_slp_analysis succeeds, mark the loop with the
       // maximal unroll factor so that we minimize analysis passes
-      if ((future_unroll_ct > _local_loop_unroll_factor) ||
-          (body_size > (uint)_local_loop_unroll_limit)) {
+      if (future_unroll_ct >= _local_loop_unroll_factor) {
         policy_unroll_slp_analysis(cl, phase, future_unroll_ct);
       }
     }
   }
 
+  int slp_max_unroll_factor = cl->slp_max_unroll();
+  if (cl->has_passed_slp()) {
+    if (slp_max_unroll_factor >= future_unroll_ct) return true;
+    // Normal case: loop too big
+    return false;
+  }
+
   // Check for being too big
   if (body_size > (uint)_local_loop_unroll_limit) {
     if (xors_in_loop >= 4 && body_size < (uint)LoopUnrollLimit*4) return true;
@@ -773,6 +788,10 @@
     return false;
   }
 
+  if(cl->do_unroll_only()) {
+    NOT_PRODUCT(if (TraceSuperWordLoopUnrollAnalysis) tty->print_cr("policy_unroll passed vector loop(vlen=%d,factor = %d)\n", slp_max_unroll_factor, future_unroll_ct));
+  }
+
   // Unroll once!  (Each trip will soon do double iterations)
   return true;
 }
@@ -780,28 +799,24 @@
 void IdealLoopTree::policy_unroll_slp_analysis(CountedLoopNode *cl, PhaseIdealLoop *phase, int future_unroll_ct) {
   // Enable this functionality target by target as needed
   if (SuperWordLoopUnrollAnalysis) {
-    if (!cl->has_passed_slp()) {
+    if (!cl->was_slp_analyzed()) {
       SuperWord sw(phase);
       sw.transform_loop(this, false);
 
       // If the loop is slp canonical analyze it
       if (sw.early_return() == false) {
-        sw.unrolling_analysis(cl, _local_loop_unroll_factor);
+        sw.unrolling_analysis(_local_loop_unroll_factor);
       }
     }
 
-    int slp_max_unroll_factor = cl->slp_max_unroll();
-    if ((slp_max_unroll_factor > 4) &&
-        (slp_max_unroll_factor >= future_unroll_ct)) {
-      int new_limit = cl->node_count_before_unroll() * slp_max_unroll_factor;
-      if (new_limit > LoopUnrollLimit) {
-#ifndef PRODUCT
-        if (TraceSuperWordLoopUnrollAnalysis) {
-          tty->print_cr("slp analysis is applying unroll limit  %d, the original limit was %d\n",
-            new_limit, _local_loop_unroll_limit);
+    if (cl->has_passed_slp()) {
+      int slp_max_unroll_factor = cl->slp_max_unroll();
+      if (slp_max_unroll_factor >= future_unroll_ct) {
+        int new_limit = cl->node_count_before_unroll() * slp_max_unroll_factor;
+        if (new_limit > LoopUnrollLimit) {
+          NOT_PRODUCT(if (TraceSuperWordLoopUnrollAnalysis) tty->print_cr("slp analysis unroll=%d, default limit=%d\n", new_limit, _local_loop_unroll_limit));
+          _local_loop_unroll_limit = new_limit;
         }
-#endif
-        _local_loop_unroll_limit = new_limit;
       }
     }
   }
@@ -830,6 +845,9 @@
   if (cl->is_main_no_pre_loop()) return false; // Disallowed for now.
   Node *trip_counter = cl->phi();
 
+  // check for vectorized loops, some opts are no longer needed
+  if (cl->do_unroll_only()) return false;
+
   // Check loop body for tests of trip-counter plus loop-invariant vs
   // loop-invariant.
   for (uint i = 0; i < _body.size(); i++) {
@@ -880,6 +898,8 @@
 // Return TRUE or FALSE if the loop should NEVER be RCE'd or aligned.  Useful
 // for unrolling loops with NO array accesses.
 bool IdealLoopTree::policy_peel_only( PhaseIdealLoop *phase ) const {
+  // check for vectorized loops, any peeling done was already applied
+  if (_head->is_CountedLoop() && _head->as_CountedLoop()->do_unroll_only()) return false;
 
   for( uint i = 0; i < _body.size(); i++ )
     if( _body[i]->is_Mem() )
--- a/hotspot/src/share/vm/opto/loopUnswitch.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/opto/loopUnswitch.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -61,6 +61,12 @@
   if (!_head->is_Loop()) {
     return false;
   }
+
+  // check for vectorized loops, any unswitching was already applied
+  if (_head->is_CountedLoop() && _head->as_CountedLoop()->do_unroll_only()) {
+    return false;
+  }
+
   int nodes_left = phase->C->max_node_limit() - phase->C->live_nodes();
   if ((int)(2 * _body.size()) > nodes_left) {
     return false; // Too speculative if running low on nodes.
--- a/hotspot/src/share/vm/opto/loopnode.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/opto/loopnode.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -2317,7 +2317,11 @@
     // Reassociate invariants and prep for split_thru_phi
     for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
       IdealLoopTree* lpt = iter.current();
-      if (!lpt->is_counted() || !lpt->is_inner()) continue;
+      bool is_counted = lpt->is_counted();
+      if (!is_counted || !lpt->is_inner()) continue;
+
+      // check for vectorized loops, any reassociation of invariants was already done
+      if (is_counted && lpt->_head->as_CountedLoop()->do_unroll_only()) continue;
 
       lpt->reassociate_invariants(this);
 
--- a/hotspot/src/share/vm/opto/loopnode.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/opto/loopnode.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -64,7 +64,9 @@
          PartialPeelLoop=32,
          PartialPeelFailed=64,
          HasReductions=128,
-         PassedSlpAnalysis=256 };
+         WasSlpAnalyzed=256,
+         PassedSlpAnalysis=512,
+         DoUnrollOnly=1024 };
   char _unswitch_count;
   enum { _unswitch_max=3 };
 
@@ -80,7 +82,9 @@
   int partial_peel_has_failed() const { return _loop_flags & PartialPeelFailed; }
   void mark_partial_peel_failed() { _loop_flags |= PartialPeelFailed; }
   void mark_has_reductions() { _loop_flags |= HasReductions; }
+  void mark_was_slp() { _loop_flags |= WasSlpAnalyzed; }
   void mark_passed_slp() { _loop_flags |= PassedSlpAnalysis; }
+  void mark_do_unroll_only() { _loop_flags |= DoUnrollOnly; }
 
   int unswitch_max() { return _unswitch_max; }
   int unswitch_count() { return _unswitch_count; }
@@ -212,7 +216,9 @@
   int is_main_loop     () const { return (_loop_flags&PreMainPostFlagsMask) == Main;   }
   int is_post_loop     () const { return (_loop_flags&PreMainPostFlagsMask) == Post;   }
   int is_reduction_loop() const { return (_loop_flags&HasReductions) == HasReductions; }
+  int was_slp_analyzed () const { return (_loop_flags&WasSlpAnalyzed) == WasSlpAnalyzed; }
   int has_passed_slp   () const { return (_loop_flags&PassedSlpAnalysis) == PassedSlpAnalysis; }
+  int do_unroll_only      () const { return (_loop_flags&DoUnrollOnly) == DoUnrollOnly; }
   int is_main_no_pre_loop() const { return _loop_flags & MainHasNoPreLoop; }
   void set_main_no_pre_loop() { _loop_flags |= MainHasNoPreLoop; }
 
@@ -235,6 +241,9 @@
   void set_nonexact_trip_count() {
     _loop_flags &= ~HasExactTripCount;
   }
+  void set_notpassed_slp() {
+    _loop_flags &= ~PassedSlpAnalysis;
+  }
 
   void set_profile_trip_cnt(float ptc) { _profile_trip_cnt = ptc; }
   float profile_trip_cnt()             { return _profile_trip_cnt; }
--- a/hotspot/src/share/vm/opto/superword.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/opto/superword.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -100,6 +100,10 @@
     return;
   }
 
+  // We only re-enter slp when we vector mapped a queried loop and we want to
+  // continue unrolling, in this case, slp is not subsequently done.
+  if (cl->do_unroll_only()) return;
+
   // Check for pre-loop ending with CountedLoopEnd(Bool(Cmp(x,Opaque1(limit))))
   CountedLoopEndNode* pre_end = get_pre_loop_end(cl);
   if (pre_end == NULL) return;
@@ -121,12 +125,13 @@
 }
 
 //------------------------------early unrolling analysis------------------------------
-void SuperWord::unrolling_analysis(CountedLoopNode *cl, int &local_loop_unroll_factor) {
+void SuperWord::unrolling_analysis(int &local_loop_unroll_factor) {
   bool is_slp = true;
   ResourceMark rm;
   size_t ignored_size = lpt()->_body.size();
   int *ignored_loop_nodes = NEW_RESOURCE_ARRAY(int, ignored_size);
   Node_Stack nstack((int)ignored_size);
+  CountedLoopNode *cl = lpt()->_head->as_CountedLoop();
   Node *cl_exit = cl->loopexit();
 
   // First clear the entries
@@ -249,13 +254,9 @@
 
       // If a max vector exists which is not larger than _local_loop_unroll_factor
       // stop looking, we already have the max vector to map to.
-      if (cur_max_vector <= local_loop_unroll_factor) {
+      if (cur_max_vector < local_loop_unroll_factor) {
         is_slp = false;
-#ifndef PRODUCT
-        if (TraceSuperWordLoopUnrollAnalysis) {
-          tty->print_cr("slp analysis fails: unroll limit equals max vector\n");
-        }
-#endif
+        NOT_PRODUCT(if (TraceSuperWordLoopUnrollAnalysis) tty->print_cr("slp analysis fails: unroll limit greater than max vector\n"));
         break;
       }
 
@@ -268,8 +269,9 @@
     }
     if (is_slp) {
       local_loop_unroll_factor = max_vector;
+      cl->mark_passed_slp();
     }
-    cl->mark_passed_slp();
+    cl->mark_was_slp();
     cl->set_slp_max_unroll(local_loop_unroll_factor);
   }
 }
@@ -1758,7 +1760,9 @@
   }
 
   Compile* C = _phase->C;
+  CountedLoopNode *cl = lpt()->_head->as_CountedLoop();
   uint max_vlen_in_bytes = 0;
+  uint max_vlen = 0;
   for (int i = 0; i < _block.length(); i++) {
     Node* n = _block.at(i);
     Node_List* p = my_pack(n);
@@ -1841,6 +1845,7 @@
       _igvn._worklist.push(vn);
 
       if (vlen_in_bytes > max_vlen_in_bytes) {
+        max_vlen = vlen;
         max_vlen_in_bytes = vlen_in_bytes;
       }
 #ifdef ASSERT
@@ -1852,6 +1857,18 @@
     }
   }
   C->set_max_vector_size(max_vlen_in_bytes);
+  if (SuperWordLoopUnrollAnalysis) {
+    if (cl->has_passed_slp()) {
+      uint slp_max_unroll_factor = cl->slp_max_unroll();
+      if (slp_max_unroll_factor == max_vlen) {
+        NOT_PRODUCT(if (TraceSuperWordLoopUnrollAnalysis) tty->print_cr("vector loop(unroll=%d, len=%d)\n", max_vlen, max_vlen_in_bytes*BitsPerByte));
+        // For atomic unrolled loops which are vector mapped, instigate more unrolling.
+        cl->set_notpassed_slp();
+        C->set_major_progress();
+        cl->mark_do_unroll_only();
+      }
+    }
+  }
 }
 
 //------------------------------vector_opd---------------------------
--- a/hotspot/src/share/vm/opto/superword.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/opto/superword.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -241,7 +241,7 @@
 
   void transform_loop(IdealLoopTree* lpt, bool do_optimization);
 
-  void unrolling_analysis(CountedLoopNode *cl, int &local_loop_unroll_factor);
+  void unrolling_analysis(int &local_loop_unroll_factor);
 
   // Accessors for SWPointer
   PhaseIdealLoop* phase()          { return _phase; }
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -277,6 +277,8 @@
   { "ParallelGCRetainPLAB",          JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { "ThreadSafetyMargin",            JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { "LazyBootClassLoader",           JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "StarvationMonitorInterval",     JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "PreInflateSpin",                JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { NULL, JDK_Version(0), JDK_Version(0) }
 };
 
--- a/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1291,7 +1291,7 @@
   experimental(intx, hashCode, 5,                                           \
                "(Unstable) select hashCode generation algorithm")           \
                                                                             \
-  experimental(intx, WorkAroundNPTLTimedWaitHang, 1,                        \
+  experimental(intx, WorkAroundNPTLTimedWaitHang, 0,                        \
                "(Unstable, Linux-specific) "                                \
                "avoid NPTL-FUTEX hang pthread_cond_timedwait")              \
                                                                             \
@@ -2717,6 +2717,12 @@
   develop(bool, EagerInitialization, false,                                 \
           "Eagerly initialize classes if possible")                         \
                                                                             \
+  diagnostic(bool, LogTouchedMethods, false,                                \
+          "Log methods which have been ever touched in runtime")            \
+                                                                            \
+  diagnostic(bool, PrintTouchedMethodsAtExit, false,                        \
+          "Print all methods that have been ever touched in runtime")       \
+                                                                            \
   develop(bool, TraceMethodReplacement, false,                              \
           "Print when methods are replaced do to recompilation")            \
                                                                             \
@@ -3282,9 +3288,6 @@
   develop(intx, ProfilerNodeSize,  1024,                                    \
           "Size in K to allocate for the Profile Nodes of each thread")     \
                                                                             \
-  product_pd(intx, PreInflateSpin,                                          \
-          "Number of times to spin wait before inflation")                  \
-                                                                            \
   /* gc parameters */                                                       \
   product(size_t, InitialHeapSize, 0,                                       \
           "Initial heap size (in bytes); zero means use ergonomics")        \
@@ -3725,9 +3728,6 @@
   develop(intx, LongCompileThreshold,     50,                               \
           "Used with +TraceLongCompiles")                                   \
                                                                             \
-  product(intx, StarvationMonitorInterval,    200,                          \
-          "Pause between each check (in milliseconds)")                     \
-                                                                            \
   /* recompilation */                                                       \
   product_pd(intx, CompileThreshold,                                        \
           "number of interpreted method invocations before (re-)compiling") \
@@ -4080,9 +4080,6 @@
   develop(bool, TraceDefaultMethods, false,                                 \
           "Trace the default method processing steps")                      \
                                                                             \
-  develop(bool, VerifyGenericSignatures, false,                             \
-          "Abort VM on erroneous or inconsistent generic signatures")       \
-                                                                            \
   diagnostic(bool, WhiteBoxAPI, false,                                      \
           "Enable internal testing APIs")                                   \
                                                                             \
--- a/hotspot/src/share/vm/runtime/java.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/java.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -330,6 +330,10 @@
     SystemDictionary::print();
   }
 
+  if (LogTouchedMethods && PrintTouchedMethodsAtExit) {
+    Method::print_touched_methods(tty);
+  }
+
   if (PrintBiasedLockingStatistics) {
     BiasedLocking::print_counters();
   }
@@ -382,6 +386,10 @@
   if (PrintNMTStatistics) {
     MemTracker::final_report(tty);
   }
+
+  if (LogTouchedMethods && PrintTouchedMethodsAtExit) {
+    Method::print_touched_methods(tty);
+  }
 }
 
 #endif
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -63,6 +63,7 @@
 Mutex*   StringDedupTable_lock        = NULL;
 Monitor* CodeCache_lock               = NULL;
 Mutex*   MethodData_lock              = NULL;
+Mutex*   TouchedMethodLog_lock        = NULL;
 Mutex*   RetData_lock                 = NULL;
 Monitor* VMOperationQueue_lock        = NULL;
 Monitor* VMOperationRequest_lock      = NULL;
@@ -274,6 +275,7 @@
 
   def(Compile_lock                 , Mutex  , nonleaf+3,   true,  Monitor::_safepoint_check_sometimes);
   def(MethodData_lock              , Mutex  , nonleaf+3,   false, Monitor::_safepoint_check_always);
+  def(TouchedMethodLog_lock        , Mutex  , nonleaf+3,   false, Monitor::_safepoint_check_always);
 
   def(MethodCompileQueue_lock      , Monitor, nonleaf+4,   true,  Monitor::_safepoint_check_always);
   def(Debug2_lock                  , Mutex  , nonleaf+4,   true,  Monitor::_safepoint_check_never);
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -55,6 +55,7 @@
 extern Mutex*   StringDedupTable_lock;           // a lock on the string deduplication table
 extern Monitor* CodeCache_lock;                  // a lock on the CodeCache, rank is special, use MutexLockerEx
 extern Mutex*   MethodData_lock;                 // a lock on installation of method data
+extern Mutex*   TouchedMethodLog_lock;           // a lock on allocation of LogExecutedMethods info
 extern Mutex*   RetData_lock;                    // a lock on installation of RetData inside method data
 extern Mutex*   DerivedPointerTableGC_lock;      // a lock to protect the derived pointer table
 extern Monitor* VMOperationQueue_lock;           // a lock on queue of vm_operations waiting to execute
--- a/hotspot/src/share/vm/runtime/objectMonitor.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/objectMonitor.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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
@@ -103,8 +103,10 @@
 // The knob* variables are effectively final.  Once set they should
 // never be modified hence.  Consider using __read_mostly with GCC.
 
+int ObjectMonitor::Knob_ExitRelease = 0;
 int ObjectMonitor::Knob_Verbose     = 0;
 int ObjectMonitor::Knob_VerifyInUse = 0;
+int ObjectMonitor::Knob_VerifyMatch = 0;
 int ObjectMonitor::Knob_SpinLimit   = 5000;    // derived by an external tool -
 static int Knob_LogSpins            = 0;       // enable jvmstat tally for spins
 static int Knob_HandOff             = 0;
@@ -251,24 +253,6 @@
 // -----------------------------------------------------------------------------
 // Enter support
 
-bool ObjectMonitor::try_enter(Thread* THREAD) {
-  if (THREAD != _owner) {
-    if (THREAD->is_lock_owned ((address)_owner)) {
-      assert(_recursions == 0, "internal state error");
-      _owner = THREAD;
-      _recursions = 1;
-      return true;
-    }
-    if (Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) != NULL) {
-      return false;
-    }
-    return true;
-  } else {
-    _recursions++;
-    return true;
-  }
-}
-
 void NOINLINE ObjectMonitor::enter(TRAPS) {
   // The following code is ordered to check the most common cases first
   // and to reduce RTS->RTO cache line upgrades on SPARC and IA32 processors.
@@ -2272,7 +2256,7 @@
 }
 
 inline void ObjectMonitor::AddWaiter(ObjectWaiter* node) {
-  assert(node != NULL, "should not dequeue NULL node");
+  assert(node != NULL, "should not add NULL node");
   assert(node->_prev == NULL, "node already in list");
   assert(node->_next == NULL, "node already in list");
   // put node at end of queue (circular doubly linked list)
@@ -2407,8 +2391,8 @@
   char * v = kvGet(kvList, Key);
   int rslt = v ? ::strtol(v, NULL, 0) : Default;
   if (Knob_ReportSettings && v != NULL) {
-    ::printf ("  SyncKnob: %s %d(%d)\n", Key, rslt, Default) ;
-    ::fflush(stdout);
+    tty->print_cr("INFO: SyncKnob: %s %d(%d)", Key, rslt, Default) ;
+    tty->flush();
   }
   return rslt;
 }
@@ -2442,8 +2426,10 @@
 
   #define SETKNOB(x) { Knob_##x = kvGetInt(knobs, #x, Knob_##x); }
   SETKNOB(ReportSettings);
+  SETKNOB(ExitRelease);
   SETKNOB(Verbose);
   SETKNOB(VerifyInUse);
+  SETKNOB(VerifyMatch);
   SETKNOB(FixedSpin);
   SETKNOB(SpinLimit);
   SETKNOB(SpinBase);
@@ -2477,7 +2463,9 @@
 
   if (os::is_MP()) {
     BackOffMask = (1 << Knob_SpinBackOff) - 1;
-    if (Knob_ReportSettings) ::printf("BackOffMask=%X\n", BackOffMask);
+    if (Knob_ReportSettings) {
+      tty->print_cr("INFO: BackOffMask=0x%X", BackOffMask);
+    }
     // CONSIDER: BackOffMask = ROUNDUP_NEXT_POWER2 (ncpus-1)
   } else {
     Knob_SpinLimit = 0;
--- a/hotspot/src/share/vm/runtime/objectMonitor.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/objectMonitor.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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
@@ -196,8 +196,10 @@
   static PerfCounter * _sync_Deflations;
   static PerfLongVariable * _sync_MonExtant;
 
+  static int Knob_ExitRelease;
   static int Knob_Verbose;
   static int Knob_VerifyInUse;
+  static int Knob_VerifyMatch;
   static int Knob_SpinLimit;
 
   void* operator new (size_t size) throw() {
@@ -317,7 +319,6 @@
   void      print();
 #endif
 
-  bool      try_enter(TRAPS);
   void      enter(TRAPS);
   void      exit(bool not_suspended, TRAPS);
   void      wait(jlong millis, bool interruptable, TRAPS);
@@ -354,14 +355,14 @@
 #undef TEVENT
 #define TEVENT(nom) { if (SyncVerbose) FEVENT(nom); }
 
-#define FEVENT(nom)                 \
-  {                                 \
-    static volatile int ctr = 0;    \
-    int v = ++ctr;                  \
-    if ((v & (v - 1)) == 0) {       \
-      ::printf(#nom " : %d\n", v);  \
-      ::fflush(stdout);             \
-    }                               \
+#define FEVENT(nom)                             \
+  {                                             \
+    static volatile int ctr = 0;                \
+    int v = ++ctr;                              \
+    if ((v & (v - 1)) == 0) {                   \
+      tty->print_cr("INFO: " #nom " : %d", v);  \
+      tty->flush();                             \
+    }                                           \
   }
 
 #undef  TEVENT
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -40,6 +40,7 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/synchronizer.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/vframe.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
 #include "utilities/preserveException.hpp"
@@ -927,8 +928,9 @@
 
   if (ForceMonitorScavenge == 0 && Atomic::xchg (1, &ForceMonitorScavenge) == 0) {
     if (ObjectMonitor::Knob_Verbose) {
-      ::printf ("Monitor scavenge - Induced STW @%s (%d)\n", Whence, ForceMonitorScavenge) ;
-      ::fflush(stdout);
+      tty->print_cr("INFO: Monitor scavenge - Induced STW @%s (%d)",
+                    Whence, ForceMonitorScavenge) ;
+      tty->flush();
     }
     // Induce a 'null' safepoint to scavenge monitors
     // Must VM_Operation instance be heap allocated as the op will be enqueue and posted
@@ -937,8 +939,9 @@
     VMThread::execute(new VM_ForceAsyncSafepoint());
 
     if (ObjectMonitor::Knob_Verbose) {
-      ::printf ("Monitor scavenge - STW posted @%s (%d)\n", Whence, ForceMonitorScavenge) ;
-      ::fflush(stdout);
+      tty->print_cr("INFO: Monitor scavenge - STW posted @%s (%d)",
+                    Whence, ForceMonitorScavenge) ;
+      tty->flush();
     }
   }
 }
@@ -1603,10 +1606,11 @@
   // Consider: audit gFreeList to ensure that gMonitorFreeCount and list agree.
 
   if (ObjectMonitor::Knob_Verbose) {
-    ::printf("Deflate: InCirc=%d InUse=%d Scavenged=%d ForceMonitorScavenge=%d : pop=%d free=%d\n",
-             nInCirculation, nInuse, nScavenged, ForceMonitorScavenge,
-             gMonitorPopulation, gMonitorFreeCount);
-    ::fflush(stdout);
+    tty->print_cr("INFO: Deflate: InCirc=%d InUse=%d Scavenged=%d "
+                  "ForceMonitorScavenge=%d : pop=%d free=%d",
+                  nInCirculation, nInuse, nScavenged, ForceMonitorScavenge,
+                  gMonitorPopulation, gMonitorFreeCount);
+    tty->flush();
   }
 
   ForceMonitorScavenge = 0;    // Reset
@@ -1643,6 +1647,14 @@
   ReleaseJavaMonitorsClosure(Thread* thread) : THREAD(thread) {}
   void do_monitor(ObjectMonitor* mid) {
     if (mid->owner() == THREAD) {
+      if (ObjectMonitor::Knob_VerifyMatch != 0) {
+        Handle obj((oop) mid->object());
+        tty->print("INFO: unexpected locked object:");
+        javaVFrame::print_locked_object_class_name(tty, obj, "locked");
+        fatal(err_msg("exiting JavaThread=" INTPTR_FORMAT
+                      " unexpectedly owns ObjectMonitor=" INTPTR_FORMAT,
+                      THREAD, mid));
+      }
       (void)mid->complete_exit(CHECK);
     }
   }
--- a/hotspot/src/share/vm/runtime/thread.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1802,14 +1802,25 @@
   assert(!this->has_pending_exception(), "ensure_join should have cleared");
 
   // 6282335 JNI DetachCurrentThread spec states that all Java monitors
-  // held by this thread must be released.  A detach operation must only
-  // get here if there are no Java frames on the stack.  Therefore, any
-  // owned monitors at this point MUST be JNI-acquired monitors which are
-  // pre-inflated and in the monitor cache.
+  // held by this thread must be released. The spec does not distinguish
+  // between JNI-acquired and regular Java monitors. We can only see
+  // regular Java monitors here if monitor enter-exit matching is broken.
+  //
+  // Optionally release any monitors for regular JavaThread exits. This
+  // is provided as a work around for any bugs in monitor enter-exit
+  // matching. This can be expensive so it is not enabled by default.
+  // ObjectMonitor::Knob_ExitRelease is a superset of the
+  // JNIDetachReleasesMonitors option.
   //
-  // ensure_join() ignores IllegalThreadStateExceptions, and so does this.
-  if (exit_type == jni_detach && JNIDetachReleasesMonitors) {
-    assert(!this->has_last_Java_frame(), "detaching with Java frames?");
+  // ensure_join() ignores IllegalThreadStateExceptions, and so does
+  // ObjectSynchronizer::release_monitors_owned_by_thread().
+  if ((exit_type == jni_detach && JNIDetachReleasesMonitors) ||
+      ObjectMonitor::Knob_ExitRelease) {
+    // Sanity check even though JNI DetachCurrentThread() would have
+    // returned JNI_ERR if there was a Java frame. JavaThread exit
+    // should be done executing Java code by the time we get here.
+    assert(!this->has_last_Java_frame(),
+           "should not have a Java frame when detaching or exiting");
     ObjectSynchronizer::release_monitors_owned_by_thread(this);
     assert(!this->has_pending_exception(), "release_monitors should have cleared");
   }
--- a/hotspot/src/share/vm/runtime/vframe.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vframe.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -144,7 +144,7 @@
   return result;
 }
 
-static void print_locked_object_class_name(outputStream* st, Handle obj, const char* lock_state) {
+void javaVFrame::print_locked_object_class_name(outputStream* st, Handle obj, const char* lock_state) {
   if (obj.not_null()) {
     st->print("\t- %s <" INTPTR_FORMAT "> ", lock_state, (address)obj());
     if (obj->klass() == SystemDictionary::Class_klass()) {
@@ -160,17 +160,29 @@
 void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) {
   ResourceMark rm;
 
-  // If this is the first frame, and java.lang.Object.wait(...) then print out the receiver.
+  // If this is the first frame and it is java.lang.Object.wait(...)
+  // then print out the receiver. Locals are not always available,
+  // e.g., compiled native frames have no scope so there are no locals.
   if (frame_count == 0) {
     if (method()->name() == vmSymbols::wait_name() &&
         method()->method_holder()->name() == vmSymbols::java_lang_Object()) {
+      const char *wait_state = "waiting on"; // assume we are waiting
+      // If earlier in the output we reported java.lang.Thread.State ==
+      // "WAITING (on object monitor)" and now we report "waiting on", then
+      // we are still waiting for notification or timeout. Otherwise if
+      // we earlier reported java.lang.Thread.State == "BLOCKED (on object
+      // monitor)", then we are actually waiting to re-lock the monitor.
+      // At this level we can't distinguish the two cases to report
+      // "waited on" rather than "waiting on" for the second case.
       StackValueCollection* locs = locals();
       if (!locs->is_empty()) {
         StackValue* sv = locs->at(0);
         if (sv->type() == T_OBJECT) {
           Handle o = locs->at(0)->get_obj();
-          print_locked_object_class_name(st, o, "waiting on");
+          print_locked_object_class_name(st, o, wait_state);
         }
+      } else {
+        st->print_cr("\t- %s <no object reference available>", wait_state);
       }
     } else if (thread()->current_park_blocker() != NULL) {
       oop obj = thread()->current_park_blocker();
@@ -179,8 +191,8 @@
     }
   }
 
-
-  // Print out all monitors that we have locked or are trying to lock
+  // Print out all monitors that we have locked, or are trying to lock,
+  // including re-locking after being notified or timing out in a wait().
   GrowableArray<MonitorInfo*>* mons = monitors();
   if (!mons->is_empty()) {
     bool found_first_monitor = false;
@@ -202,14 +214,14 @@
       if (monitor->owner() != NULL) {
         // the monitor is associated with an object, i.e., it is locked
 
-        // First, assume we have the monitor locked. If we haven't found an
-        // owned monitor before and this is the first frame, then we need to
-        // see if we have completed the lock or we are blocked trying to
-        // acquire it - we can only be blocked if the monitor is inflated
-
         markOop mark = NULL;
         const char *lock_state = "locked"; // assume we have the monitor locked
         if (!found_first_monitor && frame_count == 0) {
+          // If this is the first frame and we haven't found an owned
+          // monitor before, then we need to see if we have completed
+          // the lock or if we are blocked trying to acquire it. Only
+          // an inflated monitor that is first on the monitor list in
+          // the first frame can block us on a monitor enter.
           mark = monitor->owner()->mark();
           if (mark->has_monitor() &&
               ( // we have marked ourself as pending on this monitor
@@ -219,13 +231,35 @@
               )) {
             lock_state = "waiting to lock";
           } else {
-            mark = NULL; // Disable printing below
+            // We own the monitor which is not as interesting so
+            // disable the extra printing below.
+            mark = NULL;
+          }
+        } else if (frame_count != 0 && ObjectMonitor::Knob_Verbose) {
+          // This is not the first frame so we either own this monitor
+          // or we owned the monitor before and called wait(). Because
+          // wait() could have been called on any monitor in a lower
+          // numbered frame on the stack, we have to check all the
+          // monitors on the list for this frame.
+          // Note: Only enable this new output line in verbose mode
+          // since existing tests are not ready for it.
+          mark = monitor->owner()->mark();
+          if (mark->has_monitor() &&
+              ( // we have marked ourself as pending on this monitor
+                mark->monitor() == thread()->current_pending_monitor() ||
+                // we are not the owner of this monitor
+                !mark->monitor()->is_entered(thread())
+              )) {
+            lock_state = "waiting to re-lock in wait()";
+          } else {
+            // We own the monitor which is not as interesting so
+            // disable the extra printing below.
+            mark = NULL;
           }
         }
         print_locked_object_class_name(st, monitor->owner(), lock_state);
-        if (Verbose && mark != NULL) {
-          // match with format above, replacing "-" with " ".
-          st->print("\t  lockbits=");
+        if (ObjectMonitor::Knob_Verbose && mark != NULL) {
+          st->print("\t- lockbits=");
           mark->print_on(st);
           st->cr();
         }
--- a/hotspot/src/share/vm/runtime/vframe.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vframe.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -135,7 +135,8 @@
   // Return an array of monitors locked by this frame in the youngest to oldest order
   GrowableArray<MonitorInfo*>* locked_monitors();
 
-  // printing used during stack dumps
+  // printing used during stack dumps and diagnostics
+  static void print_locked_object_class_name(outputStream* st, Handle obj, const char* lock_state);
   void print_lock_info_on(outputStream* st, int frame_count);
   void print_lock_info(int frame_count) { print_lock_info_on(tty, frame_count); }
 
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -101,6 +101,7 @@
   template(WhiteBoxOperation)                     \
   template(ClassLoaderStatsOperation)             \
   template(DumpHashtable)                         \
+  template(DumpTouchedMethods)                    \
   template(MarkActiveNMethods)                    \
   template(PrintCompileQueue)                     \
   template(PrintCodeList)                         \
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp	Wed Jul 05 20:43:22 2017 +0200
@@ -74,6 +74,7 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompileQueueDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeListDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeCacheDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TouchedMethodsDCmd>(full_export, true, false));
 
   // Enhanced JMX Agent Support
   // These commands won't be exported via the DiagnosticCommandMBean until an
@@ -808,3 +809,35 @@
 }
 
 #endif
+
+class VM_DumpTouchedMethods : public VM_Operation {
+private:
+  outputStream* _out;
+public:
+  VM_DumpTouchedMethods(outputStream* out) {
+    _out = out;
+  }
+
+  virtual VMOp_Type type() const { return VMOp_DumpTouchedMethods; }
+
+  virtual void doit() {
+    Method::print_touched_methods(_out);
+  }
+};
+
+TouchedMethodsDCmd::TouchedMethodsDCmd(outputStream* output, bool heap) :
+                                       DCmdWithParser(output, heap)
+{}
+
+void TouchedMethodsDCmd::execute(DCmdSource source, TRAPS) {
+  if (!UnlockDiagnosticVMOptions) {
+    output()->print_cr("VM.touched_methods command requires -XX:+UnlockDiagnosticVMOptions");
+    return;
+  }
+  VM_DumpTouchedMethods dumper(output());
+  VMThread::execute(&dumper);
+}
+
+int TouchedMethodsDCmd::num_arguments() {
+  return 0;
+}
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp	Wed Jul 05 20:43:22 2017 +0200
@@ -35,6 +35,7 @@
 #include "services/diagnosticFramework.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
+#include "oops/method.hpp"
 
 class HelpDCmd : public DCmdWithParser {
 protected:
@@ -341,6 +342,22 @@
   virtual void execute(DCmdSource source, TRAPS);
 };
 
+class TouchedMethodsDCmd : public DCmdWithParser {
+public:
+  TouchedMethodsDCmd(outputStream* output, bool heap);
+  static const char* name() {
+    return "VM.print_touched_methods";
+  }
+  static const char* description() {
+    return "Print all methods that have ever been touched during the lifetime of this JVM.";
+  }
+  static const char* impact() {
+    return "Medium: Depends on Java content.";
+  }
+  static int num_arguments();
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
 // See also: thread_dump in attachListener.cpp
 class ThreadDumpDCmd : public DCmdWithParser {
 protected:
--- a/hotspot/test/compiler/codegen/7184394/TestAESBase.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/test/compiler/codegen/7184394/TestAESBase.java	Wed Jul 05 20:43:22 2017 +0200
@@ -61,12 +61,12 @@
   final Random random = Utils.getRandomInstance();
   Cipher cipher;
   Cipher dCipher;
-  AlgorithmParameters algParams;
+  AlgorithmParameters algParams = null;
   SecretKey key;
   GCMParameterSpec gcm_spec;
-  byte[] aad;
+  byte[] aad = { 0x11, 0x22, 0x33, 0x44, 0x55 };
   int tlen = 12;
-  byte[] iv;
+  byte[] iv = new byte[16];
 
   static int numThreads = 0;
   int  threadId;
@@ -80,7 +80,10 @@
 
   public void prepare() {
     try {
-    System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr + ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit + ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" + encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize );
+      System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr +
+              ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit +
+              ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" +
+              encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize );
 
       if (encInputOffset % ALIGN != 0 || encOutputOffset % ALIGN != 0 || decOutputOffset % ALIGN !=0 )
         testingMisalignment = true;
@@ -101,22 +104,24 @@
       cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
       dCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
 
+      // CBC init
       if (mode.equals("CBC")) {
-        int ivLen = (algorithm.equals("AES") ? 16 : algorithm.equals("DES") ? 8 : 0);
-        IvParameterSpec initVector = new IvParameterSpec(new byte[ivLen]);
+        IvParameterSpec initVector = new IvParameterSpec(iv);
         cipher.init(Cipher.ENCRYPT_MODE, key, initVector);
+        algParams = cipher.getParameters();
+        dCipher.init(Cipher.DECRYPT_MODE, key, initVector);
+
+      // GCM init
       } else if (mode.equals("GCM")) {
-          iv = new byte[64];
-          random.nextBytes(iv);
-          aad = new byte[5];
-          random.nextBytes(aad);
-          gcm_init();
+        gcm_init(true);
+        gcm_init(false);
+
+      // ECB init
       } else {
-        algParams = cipher.getParameters();
         cipher.init(Cipher.ENCRYPT_MODE, key, algParams);
+        dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
       }
-      algParams = cipher.getParameters();
-      dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
+
       if (threadId == 0) {
         childShowCipher();
       }
@@ -198,11 +203,18 @@
 
   abstract void childShowCipher();
 
-  void gcm_init() throws Exception {
-    tlen = 12;
+  void gcm_init(boolean encrypt) throws Exception {
     gcm_spec = new GCMParameterSpec(tlen * 8, iv);
-    cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
-    cipher.init(Cipher.ENCRYPT_MODE, key, gcm_spec);
-    cipher.update(aad);
+    if (encrypt) {
+      // Get a new instance everytime because of reuse IV restrictions
+      cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
+      cipher.init(Cipher.ENCRYPT_MODE, key, gcm_spec);
+      cipher.updateAAD(aad);
+    } else {
+      dCipher.init(Cipher.DECRYPT_MODE, key, gcm_spec);
+      dCipher.updateAAD(aad);
+
+
+    }
   }
 }
--- a/hotspot/test/compiler/codegen/7184394/TestAESDecode.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/test/compiler/codegen/7184394/TestAESDecode.java	Wed Jul 05 20:43:22 2017 +0200
@@ -32,7 +32,11 @@
   @Override
   public void run() {
     try {
-      if (!noReinit) dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
+      if (mode.equals("GCM")) {
+        gcm_init(false);
+      } else if (!noReinit) {
+        dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
+      }
       decode = new byte[decodeLength];
       if (testingMisalignment) {
         int tempSize = dCipher.update(encode, encOutputOffset, (decodeMsgSize - lastChunkSize), decode, decOutputOffset);
--- a/hotspot/test/compiler/codegen/7184394/TestAESEncode.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/test/compiler/codegen/7184394/TestAESEncode.java	Wed Jul 05 20:43:22 2017 +0200
@@ -33,7 +33,7 @@
   public void run() {
     try {
       if (mode.equals("GCM")) {
-        gcm_init();
+        gcm_init(true);
       } else if (!noReinit) {
         cipher.init(Cipher.ENCRYPT_MODE, key, algParams);
       }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/PrintTouchedMethods.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, 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 8025692
+ * @modules java.base/sun.misc
+ *          java.management
+ * @library /testlibrary
+ * @compile TestLogTouchedMethods.java PrintTouchedMethods.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+LogTouchedMethods PrintTouchedMethods
+ */
+
+import java.io.File;
+import java.util.List;
+import jdk.test.lib.*;
+
+public class PrintTouchedMethods {
+
+    public static void main(String args[]) throws Exception {
+      String[] javaArgs1 = {"-XX:-UnlockDiagnosticVMOptions", "-XX:+LogTouchedMethods", "-XX:+PrintTouchedMethodsAtExit", "TestLogTouchedMethods"};
+      ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(javaArgs1);
+
+      // UnlockDiagnostic turned off, should fail
+      OutputAnalyzer output = new OutputAnalyzer(pb.start());
+      output.shouldContain("Error: VM option 'LogTouchedMethods' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.");
+      output.shouldContain("Error: Could not create the Java Virtual Machine.");
+
+      String[] javaArgs2 = {"-XX:+UnlockDiagnosticVMOptions", "-XX:+LogTouchedMethods", "-XX:+PrintTouchedMethodsAtExit", "TestLogTouchedMethods"};
+      pb = ProcessTools.createJavaProcessBuilder(javaArgs2);
+      output = new OutputAnalyzer(pb.start());
+      // check order:
+      // 1 "# Method::print_touched_methods version 1" is the first in first line
+      // 2 should contain TestLogMethods.methodA:()V
+      // 3 should not contain TestLogMethods.methodB:()V
+      // Repeat above for another run with -Xint
+      List<String> lines = output.asLines();
+
+      if (lines.size() < 1) {
+        throw new Exception("Empty output");
+      }
+
+      String first = lines.get(0);
+      if (!first.equals("# Method::print_touched_methods version 1")) {
+        throw new Exception("First line mismatch");
+      }
+
+      output.shouldContain("TestLogTouchedMethods.methodA:()V");
+      output.shouldNotContain("TestLogTouchedMethods.methodB:()V");
+      output.shouldHaveExitValue(0);
+
+      String[] javaArgs3 = {"-XX:+UnlockDiagnosticVMOptions", "-Xint", "-XX:+LogTouchedMethods", "-XX:+PrintTouchedMethodsAtExit", "TestLogTouchedMethods"};
+      pb = ProcessTools.createJavaProcessBuilder(javaArgs3);
+      output = new OutputAnalyzer(pb.start());
+      lines = output.asLines();
+
+      if (lines.size() < 1) {
+        throw new Exception("Empty output");
+      }
+
+      first = lines.get(0);
+      if (!first.equals("# Method::print_touched_methods version 1")) {
+        throw new Exception("First line mismatch");
+      }
+
+      output.shouldContain("TestLogTouchedMethods.methodA:()V");
+      output.shouldNotContain("TestLogTouchedMethods.methodB:()V");
+      output.shouldHaveExitValue(0);
+
+      // Test jcmd PrintTouchedMethods VM.print_touched_methods
+      String pid = Integer.toString(ProcessTools.getProcessId());
+      pb = new ProcessBuilder();
+      pb.command(new String[] {JDKToolFinder.getJDKTool("jcmd"), pid, "VM.print_touched_methods"});
+      output = new OutputAnalyzer(pb.start());
+      try {
+        output.shouldContain("PrintTouchedMethods.main:([Ljava/lang/String;)V");
+      } catch (RuntimeException e) {
+        output.shouldContain("Unknown diagnostic command");
+      }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/TestLogTouchedMethods.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/* used by PrintTouchedMethods.java */
+public class TestLogTouchedMethods {
+  public static void main(String[] args) {
+    new TestLogTouchedMethods().methodA();
+  }
+
+  public void methodA() {} // called
+  public void methodB() {} // this should not be called
+}
--- a/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java	Wed Jul 05 20:43:22 2017 +0200
@@ -46,16 +46,8 @@
         runTest("-XX:-CreateCoredumpOnCrash").shouldContain("CreateCoredumpOnCrash turned off, no core file dumped");
 
         if (Platform.isWindows()) {
-            runTest("-XX:+CreateCoredumpOnCrash").shouldContain("Core dump will be written. Default location");
-
             // The old CreateMinidumpOnCrash option should still work
-            runTest("-XX:+CreateMinidumpOnCrash").shouldContain("Core dump will be written. Default location");
             runTest("-XX:-CreateMinidumpOnCrash").shouldContain("CreateCoredumpOnCrash turned off, no core file dumped");
-
-            if (Platform.isDebugBuild()) {
-                // Make sure we create dumps on Windows debug builds by default
-                runTest("-Ddummyopt=false").shouldContain("Core dump will be written. Default location");
-            }
         } else {
             runTest("-XX:+CreateCoredumpOnCrash").shouldNotContain("CreateCoredumpOnCrash turned off, no core file dumped");
         }
--- a/hotspot/test/runtime/ErrorHandling/TestOnError.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/test/runtime/ErrorHandling/TestOnError.java	Wed Jul 05 20:43:22 2017 +0200
@@ -45,6 +45,7 @@
         // Execute the VM so that a
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
            "-XX:-TransmitErrorReport",
+           "-XX:-CreateCoredumpOnCrash",
            "-XX:ErrorHandlerTest=12", // trigger potential SEGV
            "-XX:OnError=echo " + msg,
            TestOnError.class.getName());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/classFileParserBug/BadInitMethod.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, 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 8130669
+ * @summary VM prohibits <clinit> methods with return values
+ * @compile ignoredClinit.jasm
+ * @compile badInit.jasm
+ * @run main/othervm -Xverify:all BadInitMethod
+ */
+
+// Test that a non-void <clinit> method does not cause an exception to be
+// thrown.  But that a non-void <init> method causes a ClassFormatError
+// exception.
+public class BadInitMethod {
+    public static void main(String args[]) throws Throwable {
+
+        System.out.println("Regression test for bug 8130669");
+        try {
+            Class newClass = Class.forName("ignoredClinit");
+        } catch (java.lang.Throwable e) {
+            throw new RuntimeException("Unexpected exception: " + e.getMessage());
+        }
+
+        try {
+            Class newClass = Class.forName("badInit");
+            throw new RuntimeException("Expected ClassFormatError exception not thrown");
+        } catch (java.lang.ClassFormatError e) {
+            System.out.println("Test BadInitMethod passed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/classFileParserBug/EnclosingMethod.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, 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 8130183
+ * @summary For InnerClasses attribute, VM permits inner_class_info_index value of zero
+ * @compile badEnclMthd.jcod
+ * @run main/othervm -Xverify:all EnclosingMethod
+ */
+
+// Test that an EnclosingMethod attribute with the value of 0 causes a ClassFormatError.
+public class EnclosingMethod {
+    public static void main(String args[]) throws Throwable {
+
+        System.out.println("Regression test for bug 8130183");
+        try {
+            Class newClass = Class.forName("badEnclMthd");
+            throw new RuntimeException("Expected ClassFormatError exception not thrown");
+        } catch (java.lang.ClassFormatError e) {
+            System.out.println("Test EnclosingMethod passed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/classFileParserBug/badEnclMthd.jcod	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ */
+
+// Source: badEnclMthd
+class badEnclMthd {
+    0xCAFEBABE;
+    0; // minor version
+    50; // major version
+    [] { // Constant Pool
+        ; // first element is empty
+        Utf8 "badEnclMthd"; // #1
+        class #1; // #2
+        Utf8 "java/lang/Object"; // #3
+        class #3; // #4
+        Utf8 "InnerClasses"; // #5
+        Utf8 "badEnclMthd"; // #6
+        class #6; // #7
+        Utf8 "badEnclMthd"; // #8
+        class #8; // #9
+    } // Constant Pool
+    0x0001; // access  public
+    #2;// this_cpx
+    #4;// super_cpx
+    [] { // interfaces
+    } // interfaces
+    [] { // fields
+    } // fields
+    [] { // methods
+    } // methods
+    [] { // attributes
+        Attr(#5) { // InnerClasses
+            [] { // InnerClasses
+                #0 #2 #6 1;  // Bad inner_class_info_index of 0 !!!
+                #9 #0 #8 1;
+            }
+        } // end InnerClasses
+        ;
+    } // attributes
+} // end class badEnclMthd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/classFileParserBug/badInit.jasm	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ */
+
+super public class badInit
+    version 52:0
+{
+
+
+// This <init> method has a non-void signature.  It should cause a
+// ClassFormatError exception.
+Method "<init>":"(I)I"
+    stack 1 locals 2
+{
+    aload_0;
+    invokespecial    Method java/lang/Object."<init>":"()V";
+    iconst_4;
+    ireturn;
+}
+
+public static Method main:"([Ljava/lang/String;)V"
+    stack 0 locals 1
+{
+    return;
+}
+
+} // end Class badInit
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/classFileParserBug/ignoredClinit.jasm	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, 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 class contains a <clinit> method with signature: ()I.  The JVM should
+// not complain about this because methods named <clinit> that have arguments
+// and/or are not void should be ignored by the JVM.
+
+public class ignoredClinit version 51:0
+{
+
+    public static Method "<clinit>":"()I"
+    stack 1 locals 1
+    {
+        iconst_0;
+        ireturn;
+    }
+
+} // end Class ignoredClinit
--- a/hotspot/test/runtime/memory/ReserveMemory.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/test/runtime/memory/ReserveMemory.java	Wed Jul 05 20:43:22 2017 +0200
@@ -60,6 +60,7 @@
           "-XX:+UnlockDiagnosticVMOptions",
           "-XX:+WhiteBoxAPI",
           "-XX:-TransmitErrorReport",
+          "-XX:-CreateCoredumpOnCrash",
           "-Xmx32m",
           "ReserveMemory",
           "test");
--- a/hotspot/test/serviceability/hprof/cpu002.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2015, 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 8076421
- * @summary Test of hprof option crashes Zero
- * @compile cpu002.java
- * @run main/othervm -Xrunhprof:cpu=times,file=cpu002.hprof.out cpu002
- */
-
-import java.io.*;
-
-public class cpu002 {
-    public static final int PASSED = 0;
-    public static final int FAILED = 2;
-    public static final int JCK_STATUS_BASE = 95;
-
-    public static void main (String argv[]) {
-        System.exit(run(argv,System.out) + JCK_STATUS_BASE);
-    }
-
-    public static int run(String argv[], PrintStream out) {
-        return PASSED;
-    }
-}
--- a/hotspot/test/serviceability/sa/TestStackTrace.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/hotspot/test/serviceability/sa/TestStackTrace.java	Wed Jul 05 20:43:22 2017 +0200
@@ -34,6 +34,7 @@
  * @test
  * @library /../../test/lib/share/classes
  * @library /testlibrary
+ * @ignore 8129971
  * @build jdk.test.lib.*
  * @build jdk.test.lib.apps.*
  * @run main TestStackTrace
--- a/jaxp/.hgtags	Wed Jul 05 20:42:40 2017 +0200
+++ b/jaxp/.hgtags	Wed Jul 05 20:43:22 2017 +0200
@@ -316,3 +316,4 @@
 a3200b88f259f904876b9ab13fd4c4ec2726f8ba jdk9-b71
 81e85f3b6174314155991048767452a9931e12e2 jdk9-b72
 be5efc34a43bdd982d1cbe11cb2f6d6a060dde60 jdk9-b73
+eadcb2b55cd1daf77625813aad0f6f3967b1528a jdk9-b74
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/DTDDVFactory.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/DTDDVFactory.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,13 +1,13 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2001, 2002,2004 The Apache Software Foundation.
- *
- * Licensed 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
+ * 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
  *
@@ -20,8 +20,10 @@
 
 package com.sun.org.apache.xerces.internal.impl.dv;
 
+import com.sun.org.apache.xerces.internal.impl.dv.dtd.DTDDVFactoryImpl;
+import com.sun.org.apache.xerces.internal.impl.dv.dtd.XML11DTDDVFactoryImpl;
+import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
 import java.util.Hashtable;
-import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
 
 /**
  * The factory to create and return DTD types. The implementation should
@@ -35,7 +37,11 @@
  */
 public abstract class DTDDVFactory {
 
-    private static final String DEFAULT_FACTORY_CLASS = "com.sun.org.apache.xerces.internal.impl.dv.dtd.DTDDVFactoryImpl";
+    private static final String DEFAULT_FACTORY_CLASS =
+            "com.sun.org.apache.xerces.internal.impl.dv.dtd.DTDDVFactoryImpl";
+
+    private static final String XML11_DATATYPE_VALIDATOR_FACTORY =
+        "com.sun.org.apache.xerces.internal.impl.dv.dtd.XML11DTDDVFactoryImpl";
 
     /**
      * Get an instance of the default DTDDVFactory implementation.
@@ -58,9 +64,15 @@
      */
     public static final DTDDVFactory getInstance(String factoryClass) throws DVFactoryException {
         try {
-            // if the class name is not specified, use the default one
-            return (DTDDVFactory)
-                (ObjectFactory.newInstance(factoryClass, true));
+            if (DEFAULT_FACTORY_CLASS.equals(factoryClass)) {
+                return new DTDDVFactoryImpl();
+            } else if (XML11_DATATYPE_VALIDATOR_FACTORY.equals(factoryClass)) {
+                return new XML11DTDDVFactoryImpl();
+            } else {
+                //fall back for compatibility
+                return (DTDDVFactory)
+                    (ObjectFactory.newInstance(factoryClass, true));
+            }
         }
         catch (ClassCastException e) {
             throw new DVFactoryException("DTD factory class " + factoryClass + " does not extend from DTDDVFactory.");
--- a/jaxws/.hgtags	Wed Jul 05 20:42:40 2017 +0200
+++ b/jaxws/.hgtags	Wed Jul 05 20:43:22 2017 +0200
@@ -319,3 +319,4 @@
 61caeb7061bbf8cc74a767997e5d17cc00712629 jdk9-b71
 1d87054e2d2f405c114f0061b97cbf8214bddf0a jdk9-b72
 285939df908721cdb2b18a119638114306b8dca7 jdk9-b73
+6232472e51418757f7b2bf05332678ea78096e6b jdk9-b74
--- a/jdk/.hgtags	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/.hgtags	Wed Jul 05 20:43:22 2017 +0200
@@ -316,3 +316,4 @@
 e47d3bfbc61accc3fbd372a674fdce2933b54f31 jdk9-b71
 f376824d4940f45719d91838f3f6249f873440db jdk9-b72
 1c8bca2ebba13948199de33a1b71e2d6f1c7a8a6 jdk9-b73
+6dd82d2e4a104f4d204b2890f33ef11ec3e3f8d0 jdk9-b74
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -61,7 +61,6 @@
     private static final String LFN_SIG = "L" + LFN + ";";
     private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
     private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";
-    private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";
 
     /** Name of its super class*/
     private static final String superName = OBJ;
@@ -571,7 +570,7 @@
             mv.visitLdcInsn(constantPlaceholder(cls));
             mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
             mv.visitInsn(Opcodes.SWAP);
-            mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "castReference", CLL_SIG, false);
+            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CLS, "cast", LL_SIG, false);
             if (Object[].class.isAssignableFrom(cls))
                 mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY);
             else if (PROFILE_LEVEL > 0)
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -219,7 +219,7 @@
             if (convSpec == null)  continue;
             MethodHandle fn;
             if (convSpec instanceof Class) {
-                fn = Lazy.MH_castReference.bindTo(convSpec);
+                fn = Lazy.MH_cast.bindTo(convSpec);
             } else {
                 fn = (MethodHandle) convSpec;
             }
@@ -239,7 +239,7 @@
                 if (convSpec == void.class)
                     fn = null;
                 else
-                    fn = Lazy.MH_castReference.bindTo(convSpec);
+                    fn = Lazy.MH_cast.bindTo(convSpec);
             } else {
                 fn = (MethodHandle) convSpec;
             }
@@ -302,7 +302,7 @@
             Name conv;
             if (convSpec instanceof Class) {
                 Class<?> convClass = (Class<?>) convSpec;
-                conv = new Name(Lazy.MH_castReference, convClass, names[INARG_BASE + i]);
+                conv = new Name(Lazy.MH_cast, convClass, names[INARG_BASE + i]);
             } else {
                 MethodHandle fn = (MethodHandle) convSpec;
                 conv = new Name(fn, names[INARG_BASE + i]);
@@ -326,7 +326,7 @@
                 conv = new Name(LambdaForm.constantZero(BasicType.basicType(srcType.returnType())));
             } else if (convSpec instanceof Class) {
                 Class<?> convClass = (Class<?>) convSpec;
-                conv = new Name(Lazy.MH_castReference, convClass, names[OUT_CALL]);
+                conv = new Name(Lazy.MH_cast, convClass, names[OUT_CALL]);
             } else {
                 MethodHandle fn = (MethodHandle) convSpec;
                 if (fn.type().parameterCount() == 0)
@@ -343,25 +343,6 @@
         return SimpleMethodHandle.make(srcType, form);
     }
 
-    /**
-     * Identity function, with reference cast.
-     * @param t an arbitrary reference type
-     * @param x an arbitrary reference value
-     * @return the same value x
-     */
-    @ForceInline
-    @SuppressWarnings("unchecked")
-    static <T,U> T castReference(Class<? extends T> t, U x) {
-        // inlined Class.cast because we can't ForceInline it
-        if (x != null && !t.isInstance(x))
-            throw newClassCastException(t, x);
-        return (T) x;
-    }
-
-    private static ClassCastException newClassCastException(Class<?> t, Object obj) {
-        return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName());
-    }
-
     static Object[] computeValueConversions(MethodType srcType, MethodType dstType,
                                             boolean strict, boolean monobox) {
         final int INARG_COUNT = srcType.parameterCount();
@@ -591,6 +572,7 @@
      */
     static class Lazy {
         private static final Class<?> MHI = MethodHandleImpl.class;
+        private static final Class<?> CLS = Class.class;
 
         private static final MethodHandle[] ARRAYS;
         private static final MethodHandle[] FILL_ARRAYS;
@@ -600,7 +582,7 @@
         static final NamedFunction NF_throwException;
         static final NamedFunction NF_profileBoolean;
 
-        static final MethodHandle MH_castReference;
+        static final MethodHandle MH_cast;
         static final MethodHandle MH_selectAlternative;
         static final MethodHandle MH_copyAsPrimitiveArray;
         static final MethodHandle MH_fillNewTypedArray;
@@ -623,8 +605,8 @@
                 NF_throwException.resolve();
                 NF_profileBoolean.resolve();
 
-                MH_castReference        = IMPL_LOOKUP.findStatic(MHI, "castReference",
-                                            MethodType.methodType(Object.class, Class.class, Object.class));
+                MH_cast                 = IMPL_LOOKUP.findVirtual(CLS, "cast",
+                                            MethodType.methodType(Object.class, Object.class));
                 MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray",
                                             MethodType.methodType(Object.class, Wrapper.class, Object[].class));
                 MH_arrayIdentity        = IMPL_LOOKUP.findStatic(MHI, "identity",
--- a/jdk/src/java.base/share/classes/java/security/CodeSource.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/security/CodeSource.java	Wed Jul 05 20:43:22 2017 +0200
@@ -339,7 +339,7 @@
      * @param strict If true then a strict equality match is performed.
      *               Otherwise a subset match is performed.
      */
-    private boolean matchCerts(CodeSource that, boolean strict)
+    boolean matchCerts(CodeSource that, boolean strict)
     {
         boolean match;
 
--- a/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java	Wed Jul 05 20:43:22 2017 +0200
@@ -25,9 +25,10 @@
 
 package java.security;
 
-import java.util.Map;
+import java.net.URL;
 import java.util.ArrayList;
-import java.net.URL;
+import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 
@@ -50,15 +51,15 @@
     private final boolean initialized;
 
     /*
-     * Map that maps the CodeSource URL (as a String) to ProtectionDomain.
-     * We use a String instead of a CodeSource/URL as the key to avoid
+     * Map that maps the CodeSource to a ProtectionDomain. The key is a
+     * CodeSourceKey class that uses a String instead of a URL to avoid
      * potential expensive name service lookups. This does mean that URLs that
      * are equivalent after nameservice lookup will be placed in separate
      * ProtectionDomains; however during policy enforcement these URLs will be
      * canonicalized and resolved resulting in a consistent set of granted
      * permissions.
      */
-    private final Map<String, ProtectionDomain> pdcache
+    private final Map<CodeSourceKey, ProtectionDomain> pdcache
             = new ConcurrentHashMap<>(11);
 
     private static final Debug debug = Debug.getInstance("scl");
@@ -209,17 +210,14 @@
             return null;
         }
 
-        // Use a String form of the URL as the key. It should behave in the
-        // same manner as the URL when compared for equality except that no
-        // nameservice lookup is done on the hostname (String comparison
+        // Use a CodeSourceKey object key. It should behave in the
+        // same manner as the CodeSource when compared for equality except
+        // that no nameservice lookup is done on the hostname (String comparison
         // only), and the fragment is not considered.
-        String key = cs.getLocationNoFragString();
-        if (key == null) {
-            key = "<null>";
-        }
+        CodeSourceKey key = new CodeSourceKey(cs);
         return pdcache.computeIfAbsent(key, new Function<>() {
             @Override
-            public ProtectionDomain apply(String key /* not used */) {
+            public ProtectionDomain apply(CodeSourceKey key /* not used */) {
                 PermissionCollection perms
                         = SecureClassLoader.this.getPermissions(cs);
                 ProtectionDomain pd = new ProtectionDomain(
@@ -242,4 +240,37 @@
         }
     }
 
+    private static class CodeSourceKey {
+        private final CodeSource cs;
+
+        CodeSourceKey(CodeSource cs) {
+            this.cs = cs;
+        }
+
+        @Override
+        public int hashCode() {
+            String locationNoFrag = cs.getLocationNoFragString();
+            return locationNoFrag != null ? locationNoFrag.hashCode() : 0;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+
+            if (!(obj instanceof CodeSourceKey)) {
+                return false;
+            }
+
+            CodeSourceKey csk = (CodeSourceKey) obj;
+
+            if (!Objects.equals(cs.getLocationNoFragString(),
+                                csk.cs.getLocationNoFragString())) {
+                return false;
+            }
+
+            return cs.matchCerts(csk.cs, true);
+        }
+    }
 }
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java	Wed Jul 05 20:43:22 2017 +0200
@@ -29,6 +29,9 @@
 import java.nio.file.attribute.FileTime;
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
+import java.time.LocalDateTime;
+import java.time.ZonedDateTime;
+import java.time.ZoneId;
 
 import static java.util.zip.ZipConstants64.*;
 
@@ -195,6 +198,85 @@
     }
 
     /**
+     * Sets the last modification time of the entry in local date-time.
+     *
+     * <p> If the entry is output to a ZIP file or ZIP file formatted
+     * output stream the last modification time set by this method will
+     * be stored into the {@code date and time fields} of the zip file
+     * entry and encoded in standard {@code MS-DOS date and time format}.
+     * If the date-time set is out of the range of the standard {@code
+     * MS-DOS date and time format}, the time will also be stored into
+     * zip file entry's extended timestamp fields in {@code optional
+     * extra data} in UTC time. The {@link java.time.ZoneId#systemDefault()
+     * system default TimeZone} is used to convert the local date-time
+     * to UTC time.
+     *
+     * <p> {@code LocalDateTime} uses a precision of nanoseconds, whereas
+     * this class uses a precision of milliseconds. The conversion will
+     * truncate any excess precision information as though the amount in
+     * nanoseconds was subject to integer division by one million.
+     *
+     * @param  time
+     *         The last modification time of the entry in local date-time
+     *
+     * @see #getTimeLocal()
+     * @since 1.9
+     */
+    public void setTimeLocal(LocalDateTime time) {
+        int year = time.getYear() - 1980;
+        if (year < 0) {
+            this.xdostime = DOSTIME_BEFORE_1980;
+        } else {
+            this.xdostime = (year << 25 |
+                time.getMonthValue() << 21 |
+                time.getDayOfMonth() << 16 |
+                time.getHour() << 11 |
+                time.getMinute() << 5 |
+                time.getSecond() >> 1)
+                + ((long)(((time.getSecond() & 0x1) * 1000) +
+                      time.getNano() / 1000_000) << 32);
+        }
+        if (xdostime != DOSTIME_BEFORE_1980 && year <= 0x7f) {
+            this.mtime = null;
+        } else {
+            this.mtime = FileTime.from(
+                ZonedDateTime.of(time, ZoneId.systemDefault()).toInstant());
+        }
+    }
+
+    /**
+     * Returns the last modification time of the entry in local date-time.
+     *
+     * <p> If the entry is read from a ZIP file or ZIP file formatted
+     * input stream, this is the last modification time from the zip
+     * file entry's {@code optional extra data} if the extended timestamp
+     * fields are present. Otherwise, the last modification time is read
+     * from entry's standard MS-DOS formatted {@code date and time fields}.
+     *
+     * <p> The {@link java.time.ZoneId#systemDefault() system default TimeZone}
+     * is used to convert the UTC time to local date-time.
+     *
+     * @return  The last modification time of the entry in local date-time
+     *
+     * @see #setTimeLocal(LocalDateTime)
+     * @since 1.9
+     */
+    public LocalDateTime getTimeLocal() {
+        if (mtime != null) {
+            return LocalDateTime.ofInstant(mtime.toInstant(), ZoneId.systemDefault());
+        }
+        int ms = (int)(xdostime >> 32);
+        return LocalDateTime.of((int)(((xdostime >> 25) & 0x7f) + 1980),
+                             (int)((xdostime >> 21) & 0x0f),
+                             (int)((xdostime >> 16) & 0x1f),
+                             (int)((xdostime >> 11) & 0x1f),
+                             (int)((xdostime >> 5) & 0x3f),
+                             (int)((xdostime << 1) & 0x3e) + ms / 1000,
+                             (ms % 1000) * 1000_000);
+    }
+
+
+    /**
      * Sets the last modification time of the entry.
      *
      * <p> When output to a ZIP file or ZIP file formatted output stream
@@ -498,15 +580,15 @@
                     // flag its presence or absence. But if mtime is present
                     // in LOC it must be present in CEN as well.
                     if ((flag & 0x1) != 0 && (sz0 + 4) <= sz) {
-                        mtime = unixTimeToFileTime(get32(extra, off + sz0));
+                        mtime = unixTimeToFileTime(get32S(extra, off + sz0));
                         sz0 += 4;
                     }
                     if ((flag & 0x2) != 0 && (sz0 + 4) <= sz) {
-                        atime = unixTimeToFileTime(get32(extra, off + sz0));
+                        atime = unixTimeToFileTime(get32S(extra, off + sz0));
                         sz0 += 4;
                     }
                     if ((flag & 0x4) != 0 && (sz0 + 4) <= sz) {
-                        ctime = unixTimeToFileTime(get32(extra, off + sz0));
+                        ctime = unixTimeToFileTime(get32S(extra, off + sz0));
                         sz0 += 4;
                     }
                     break;
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java	Wed Jul 05 20:43:22 2017 +0200
@@ -99,9 +99,9 @@
         if (year < 1980) {
             return ZipEntry.DOSTIME_BEFORE_1980;
         }
-        return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
-               d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
-               d.getSeconds() >> 1;
+        return ((year - 1980) << 25 | (d.getMonth() + 1) << 21 |
+                d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
+                d.getSeconds() >> 1) & 0xffffffffL;
     }
 
     /**
@@ -144,4 +144,13 @@
     public static final long get64(byte b[], int off) {
         return get32(b, off) | (get32(b, off+4) << 32);
     }
+
+    /**
+     * Fetches signed 32-bit value from byte array at specified offset.
+     * The bytes are assumed to be in Intel (little-endian) byte order.
+     *
+     */
+    public static final int get32S(byte b[], int off) {
+        return (get16(b, off) | (get16(b, off+2) << 16));
+    }
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageNativeSubstrate.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageNativeSubstrate.java	Wed Jul 05 20:43:22 2017 +0200
@@ -112,7 +112,12 @@
 
     @Override
     public byte[] getStringBytes(int offset) {
-        return getStringBytes(id, offset);
+        byte[] ret = getStringBytes(id, offset);
+        if (ret == null) {
+            throw new OutOfMemoryError("Error accessing array at offset "
+                    + offset);
+        }
+        return ret;
     }
 
     @Override
--- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeHash.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeHash.java	Wed Jul 05 20:43:22 2017 +0200
@@ -355,7 +355,7 @@
         try {
             return cloneDigest(finMD).digest();
         } catch (Exception e) {
-            throw new Error("BAD");
+            throw new Error("Error during hash calculation", e);
         }
     }
 }
--- a/jdk/src/java.base/share/native/libjava/Image.c	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.base/share/native/libjava/Image.c	Wed Jul 05 20:43:22 2017 +0200
@@ -104,6 +104,9 @@
     size = strlen(data);
     // Allocate byte array.
     byteArray = (*env)->NewByteArray(env, (jsize) size);
+    if (byteArray == NULL) {
+        return NULL;
+    }
     // Get array base address.
     rawBytes = (*env)->GetByteArrayElements(env, byteArray, NULL);
     // Copy bytes from image string table.
@@ -122,6 +125,9 @@
     jlong* ret;
 
     attributes = (*env)->NewLongArray(env, JVM_ImageGetAttributesCount(env));
+    if (attributes == NULL) {
+        return NULL;
+    }
     // Get base address for jlong array.
     rawAttributes = (*env)->GetLongArrayElements(env, attributes, NULL);
     ret = JVM_ImageGetAttributes(env, rawAttributes, id, offset);
@@ -143,6 +149,9 @@
 
     count = JVM_ImageGetAttributesCount(env);
     attributes = (*env)->NewLongArray(env, JVM_ImageGetAttributesCount(env));
+    if (attributes == NULL) {
+        return NULL;
+    }
     // Get base address for jlong array.
     rawAttributes = (*env)->GetLongArrayElements(env, attributes, NULL);
     size = (*env)->GetArrayLength(env, utf8);
@@ -165,6 +174,9 @@
 
     length = JVM_ImageAttributeOffsetsLength(env, id);
     offsets = (*env)->NewIntArray(env, length);
+    if (offsets == NULL) {
+        return NULL;
+    }
     // Get base address of result.
     rawOffsets = (*env)->GetIntArrayElements(env, offsets, NULL);
     ret = JVM_ImageAttributeOffsets(env, rawOffsets, length, id);
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KrbKdcRep.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KrbKdcRep.java	Wed Jul 05 20:43:22 2017 +0200
@@ -75,10 +75,11 @@
             }
         }
 
-        // XXX Can renew a ticket but not ask for a renewable renewed ticket
-        // See impl of Credentials.renew().
-        if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE) !=
-            rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) {
+        // Reply to a renewable request should be renewable, but if request does
+        // not contain renewable, KDC is free to issue a renewable ticket (for
+        // example, if ticket_lifetime is too big).
+        if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE) &&
+                !rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) {
             throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
         }
 
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/ssl/Krb5KeyExchangeService.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/ssl/Krb5KeyExchangeService.java	Wed Jul 05 20:43:22 2017 +0200
@@ -83,6 +83,12 @@
                     (PrivilegedExceptionAction<ServiceCreds>)
                             () -> Krb5Util.getServiceCreds(
                                     GSSCaller.CALLER_SSL_SERVER, null, acc));
+            if (serviceCreds == null) {
+                if (debug != null && Debug.isOn("handshake")) {
+                    System.out.println("Kerberos serviceCreds not available");
+                }
+                return null;
+            }
             if (debug != null && Debug.isOn("handshake")) {
                 System.out.println("Using Kerberos creds");
             }
--- a/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/PolicyTool.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/PolicyTool.java	Wed Jul 05 20:43:22 2017 +0200
@@ -633,17 +633,16 @@
             type.equals(PolicyParser.PrincipalEntry.REPLACE_NAME)) {
             return;
         }
-        Class<?> PRIN = Class.forName("java.security.Principal");
         Class<?> pc = Class.forName(type, true,
                 Thread.currentThread().getContextClassLoader());
-        if (!PRIN.isAssignableFrom(pc)) {
+        if (!Principal.class.isAssignableFrom(pc)) {
             MessageFormat form = new MessageFormat(getMessage
                         ("Illegal.Principal.Type.type"));
             Object[] source = {type};
             throw new InstantiationException(form.format(source));
         }
 
-        if (ToolDialog.X500_PRIN_CLASS.equals(pc.getName())) {
+        if (X500Principal.class.getName().equals(pc.getName())) {
             // PolicyParser checks validity of X500Principal name
             // - PolicyTool needs to as well so that it doesn't store
             //   an invalid name that can't be read in later
@@ -1563,14 +1562,6 @@
     public static final int NEW                 = 2;
     public static final int OPEN                = 3;
 
-    public static final String ALL_PERM_CLASS   =
-                "java.security.AllPermission";
-    public static final String FILE_PERM_CLASS  =
-                "java.io.FilePermission";
-
-    public static final String X500_PRIN_CLASS         =
-                "javax.security.auth.x500.X500Principal";
-
     /* popup menus */
     public static final String PERM             =
         PolicyTool.getMessage
@@ -1752,11 +1743,11 @@
         for (int i = 0; i < PERM_ARRAY.size(); i++) {
             Perm next = PERM_ARRAY.get(i);
             if (fullClassName) {
-                if (next.FULL_CLASS.equals(clazz)) {
+                if (next.getName().equals(clazz)) {
                     return next;
                 }
             } else {
-                if (next.CLASS.equals(clazz)) {
+                if (next.getSimpleName().equals(clazz)) {
                     return next;
                 }
             }
@@ -1772,11 +1763,11 @@
         for (int i = 0; i < PRIN_ARRAY.size(); i++) {
             Prin next = PRIN_ARRAY.get(i);
             if (fullClassName) {
-                if (next.FULL_CLASS.equals(clazz)) {
+                if (next.getName().equals(clazz)) {
                     return next;
                 }
             } else {
-                if (next.CLASS.equals(clazz)) {
+                if (next.getSimpleName().equals(clazz)) {
                     return next;
                 }
             }
@@ -2170,7 +2161,7 @@
         choice.getAccessibleContext().setAccessibleName(PRIN_TYPE);
         for (int i = 0; i < PRIN_ARRAY.size(); i++) {
             Prin next = PRIN_ARRAY.get(i);
-            choice.addItem(next.CLASS);
+            choice.addItem(next.getSimpleName());
         }
 
         if (edit) {
@@ -2180,7 +2171,7 @@
             } else {
                 Prin inputPrin = getPrin(editMe.getPrincipalClass(), true);
                 if (inputPrin != null) {
-                    choice.setSelectedItem(inputPrin.CLASS);
+                    choice.setSelectedItem(inputPrin.getSimpleName());
                 }
             }
         }
@@ -2286,7 +2277,7 @@
         choice.getAccessibleContext().setAccessibleName(PERM);
         for (int i = 0; i < PERM_ARRAY.size(); i++) {
             Perm next = PERM_ARRAY.get(i);
-            choice.addItem(next.CLASS);
+            choice.addItem(next.getSimpleName());
         }
         tw.addNewComponent(newTD, choice, PD_PERM_CHOICE,
                            0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.BOTH,
@@ -2300,7 +2291,7 @@
         if (edit) {
             Perm inputPerm = getPerm(editMe.permission, true);
             if (inputPerm != null) {
-                choice.setSelectedItem(inputPerm.CLASS);
+                choice.setSelectedItem(inputPerm.getSimpleName());
             }
         }
         tw.addNewComponent(newTD, tf, PD_PERM_TEXTFIELD,
@@ -2417,7 +2408,7 @@
                         "\t'" + pname + "' will be interpreted " +
                                 "as a key store alias.\n" +
                         "\tThe final principal class will be " +
-                                ToolDialog.X500_PRIN_CLASS + ".\n" +
+                                X500Principal.class.getName() + ".\n" +
                         "\tThe final principal name will be " +
                                 "determined by the following:\n" +
                         "\n" +
@@ -2452,7 +2443,7 @@
         if (tf.getText().trim().equals("") == false)
             name = new String(tf.getText().trim());
         if (permission.equals("") ||
-            (!permission.equals(ALL_PERM_CLASS) && name == null)) {
+            (!permission.equals(AllPermission.class.getName()) && name == null)) {
             throw new InvalidParameterException(PolicyTool.getMessage
                 ("Permission.and.Target.Name.must.have.a.value"));
         }
@@ -2467,7 +2458,8 @@
         // \\server\share     0, legal
         // \\\\server\share   2, illegal
 
-        if (permission.equals(FILE_PERM_CLASS) && name.lastIndexOf("\\\\") > 0) {
+        if (permission.equals(FilePermission.class.getName())
+                && name.lastIndexOf("\\\\") > 0) {
             char result = tw.displayYesNoDialog(this,
                     PolicyTool.getMessage("Warning"),
                     PolicyTool.getMessage(
@@ -3645,7 +3637,7 @@
             if (prinField.getText() != null &&
                 prinField.getText().length() > 0) {
                 Prin inputPrin = ToolDialog.getPrin(prinField.getText(), true);
-                prin.setSelectedItem(inputPrin.CLASS);
+                prin.setSelectedItem(inputPrin.getSimpleName());
             }
             return;
         }
@@ -3660,7 +3652,7 @@
         // set of names and actions
         Prin inputPrin = ToolDialog.getPrin((String)e.getItem(), false);
         if (inputPrin != null) {
-            prinField.setText(inputPrin.FULL_CLASS);
+            prinField.setText(inputPrin.getName());
         }
     }
 }
@@ -3711,7 +3703,7 @@
 
                 Perm inputPerm = ToolDialog.getPerm(permField.getText(), true);
                 if (inputPerm != null) {
-                    perms.setSelectedItem(inputPerm.CLASS);
+                    perms.setSelectedItem(inputPerm.getSimpleName());
                 }
             }
             return;
@@ -3732,7 +3724,7 @@
         if (inputPerm == null) {
             permField.setText("");
         } else {
-            permField.setText(inputPerm.FULL_CLASS);
+            permField.setText(inputPerm.getName());
         }
         td.setPermissionNames(inputPerm, names, nameField);
         td.setPermissionActions(inputPerm, actions, actionsField);
@@ -4082,26 +4074,30 @@
  */
 
 class Prin {
-    public final String CLASS;
-    public final String FULL_CLASS;
-
-    public Prin(String clazz, String fullClass) {
+    final Class<? extends Principal> CLASS;
+
+    Prin(Class<? extends Principal> clazz) {
         this.CLASS = clazz;
-        this.FULL_CLASS = fullClass;
+    }
+
+    String getName() {
+        return CLASS.getName();
+    }
+
+    String getSimpleName() {
+        return CLASS.getSimpleName();
     }
 }
 
 class KrbPrin extends Prin {
-    public KrbPrin() {
-        super("KerberosPrincipal",
-                "javax.security.auth.kerberos.KerberosPrincipal");
+    KrbPrin() {
+        super(javax.security.auth.kerberos.KerberosPrincipal.class);
     }
 }
 
 class X500Prin extends Prin {
-    public X500Prin() {
-        super("X500Principal",
-                "javax.security.auth.x500.X500Principal");
+    X500Prin() {
+        super(javax.security.auth.x500.X500Principal.class);
     }
 }
 
@@ -4110,44 +4106,48 @@
  */
 
 class Perm {
-    public final String CLASS;
-    public final String FULL_CLASS;
-    public final String[] TARGETS;
-    public final String[] ACTIONS;
-
-    public Perm(String clazz, String fullClass,
+    final Class<? extends Permission> CLASS;
+    final String[] TARGETS;
+    final String[] ACTIONS;
+
+    Perm(Class<? extends Permission> clazz,
                 String[] targets, String[] actions) {
 
         this.CLASS = clazz;
-        this.FULL_CLASS = fullClass;
         this.TARGETS = targets;
         this.ACTIONS = actions;
     }
+
+    String getName() {
+        return CLASS.getName();
+    }
+
+    String getSimpleName() {
+        return CLASS.getSimpleName();
+    }
 }
 
 class AllPerm extends Perm {
-    public AllPerm() {
-        super("AllPermission", "java.security.AllPermission", null, null);
+    AllPerm() {
+        super(java.security.AllPermission.class, null, null);
     }
 }
 
 class AudioPerm extends Perm {
-    public AudioPerm() {
-        super("AudioPermission",
-        "javax.sound.sampled.AudioPermission",
-        new String[]    {
+    AudioPerm() {
+        super(javax.sound.sampled.AudioPermission.class,
+            new String[]    {
                 "play",
                 "record"
                 },
-        null);
+            null);
     }
 }
 
 class AuthPerm extends Perm {
-    public AuthPerm() {
-    super("AuthPermission",
-        "javax.security.auth.AuthPermission",
-        new String[]    {
+    AuthPerm() {
+        super(javax.security.auth.AuthPermission.class,
+            new String[]    {
                 "doAs",
                 "doAsPrivileged",
                 "getSubject",
@@ -4165,15 +4165,14 @@
                         PolicyTool.getMessage("configuration.type") + ">",
                 "refreshLoginConfiguration"
                 },
-        null);
+            null);
     }
 }
 
 class AWTPerm extends Perm {
-    public AWTPerm() {
-    super("AWTPermission",
-        "java.awt.AWTPermission",
-        new String[]    {
+    AWTPerm() {
+        super(java.awt.AWTPermission.class,
+            new String[]    {
                 "accessClipboard",
                 "accessEventQueue",
                 "accessSystemTray",
@@ -4187,30 +4186,28 @@
                 "showWindowWithoutWarningBanner",
                 "toolkitModality",
                 "watchMousePointer"
-        },
-        null);
+                },
+            null);
     }
 }
 
 class DelegationPerm extends Perm {
-    public DelegationPerm() {
-    super("DelegationPermission",
-        "javax.security.auth.kerberos.DelegationPermission",
-        new String[]    {
+    DelegationPerm() {
+        super(javax.security.auth.kerberos.DelegationPermission.class,
+            new String[]    {
                 // allow user input
                 },
-        null);
+            null);
     }
 }
 
 class FilePerm extends Perm {
-    public FilePerm() {
-    super("FilePermission",
-        "java.io.FilePermission",
-        new String[]    {
+    FilePerm() {
+        super(java.io.FilePermission.class,
+            new String[]    {
                 "<<ALL FILES>>"
                 },
-        new String[]    {
+            new String[]    {
                 "read",
                 "write",
                 "delete",
@@ -4220,64 +4217,59 @@
 }
 
 class URLPerm extends Perm {
-    public URLPerm() {
-        super("URLPermission",
-                "java.net.URLPermission",
-                new String[]    {
-                    "<"+ PolicyTool.getMessage("url") + ">",
-                },
-                new String[]    {
-                    "<" + PolicyTool.getMessage("method.list") + ">:<"
-                        + PolicyTool.getMessage("request.headers.list") + ">",
-                });
+    URLPerm() {
+        super(java.net.URLPermission.class,
+            new String[]    {
+                "<"+ PolicyTool.getMessage("url") + ">",
+            },
+            new String[]    {
+                "<" + PolicyTool.getMessage("method.list") + ">:<"
+                    + PolicyTool.getMessage("request.headers.list") + ">",
+            });
     }
 }
 
 class InqSecContextPerm extends Perm {
-    public InqSecContextPerm() {
-    super("InquireSecContextPermission",
-        "com.sun.security.jgss.InquireSecContextPermission",
-        new String[]    {
+    InqSecContextPerm() {
+        super(com.sun.security.jgss.InquireSecContextPermission.class,
+            new String[]    {
                 "KRB5_GET_SESSION_KEY",
                 "KRB5_GET_TKT_FLAGS",
                 "KRB5_GET_AUTHZ_DATA",
                 "KRB5_GET_AUTHTIME"
                 },
-        null);
+            null);
     }
 }
 
 class LogPerm extends Perm {
-    public LogPerm() {
-    super("LoggingPermission",
-        "java.util.logging.LoggingPermission",
-        new String[]    {
+    LogPerm() {
+        super(java.util.logging.LoggingPermission.class,
+            new String[]    {
                 "control"
                 },
-        null);
+            null);
     }
 }
 
 class MgmtPerm extends Perm {
-    public MgmtPerm() {
-    super("ManagementPermission",
-        "java.lang.management.ManagementPermission",
-        new String[]    {
+    MgmtPerm() {
+        super(java.lang.management.ManagementPermission.class,
+            new String[]    {
                 "control",
                 "monitor"
                 },
-        null);
+            null);
     }
 }
 
 class MBeanPerm extends Perm {
-    public MBeanPerm() {
-    super("MBeanPermission",
-        "javax.management.MBeanPermission",
-        new String[]    {
+    MBeanPerm() {
+        super(javax.management.MBeanPermission.class,
+            new String[]    {
                 // allow user input
                 },
-        new String[]    {
+            new String[]    {
                 "addNotificationListener",
                 "getAttribute",
                 "getClassLoader",
@@ -4300,35 +4292,32 @@
 }
 
 class MBeanSvrPerm extends Perm {
-    public MBeanSvrPerm() {
-    super("MBeanServerPermission",
-        "javax.management.MBeanServerPermission",
-        new String[]    {
+    MBeanSvrPerm() {
+        super(javax.management.MBeanServerPermission.class,
+            new String[]    {
                 "createMBeanServer",
                 "findMBeanServer",
                 "newMBeanServer",
                 "releaseMBeanServer"
                 },
-        null);
+            null);
     }
 }
 
 class MBeanTrustPerm extends Perm {
-    public MBeanTrustPerm() {
-    super("MBeanTrustPermission",
-        "javax.management.MBeanTrustPermission",
-        new String[]    {
+    MBeanTrustPerm() {
+        super(javax.management.MBeanTrustPermission.class,
+            new String[]    {
                 "register"
                 },
-        null);
+            null);
     }
 }
 
 class NetPerm extends Perm {
-    public NetPerm() {
-    super("NetPermission",
-        "java.net.NetPermission",
-        new String[]    {
+    NetPerm() {
+        super(java.net.NetPermission.class,
+            new String[]    {
                 "allowHttpTrace",
                 "setDefaultAuthenticator",
                 "requestPasswordAuthentication",
@@ -4341,43 +4330,40 @@
                 "setResponseCache",
                 "getResponseCache"
                 },
-        null);
+            null);
     }
 }
 
 class NetworkPerm extends Perm {
-    public NetworkPerm() {
-    super("NetworkPermission",
-        "jdk.net.NetworkPermission",
-        new String[]    {
+    NetworkPerm() {
+        super(jdk.net.NetworkPermission.class,
+            new String[]    {
                 "setOption.SO_FLOW_SLA",
                 "getOption.SO_FLOW_SLA"
                 },
-        null);
+            null);
     }
 }
 
 class PrivCredPerm extends Perm {
-    public PrivCredPerm() {
-    super("PrivateCredentialPermission",
-        "javax.security.auth.PrivateCredentialPermission",
-        new String[]    {
+    PrivCredPerm() {
+        super(javax.security.auth.PrivateCredentialPermission.class,
+            new String[]    {
                 // allow user input
                 },
-        new String[]    {
+            new String[]    {
                 "read"
                 });
     }
 }
 
 class PropPerm extends Perm {
-    public PropPerm() {
-    super("PropertyPermission",
-        "java.util.PropertyPermission",
-        new String[]    {
+    PropPerm() {
+        super(java.util.PropertyPermission.class,
+            new String[]    {
                 // allow user input
                 },
-        new String[]    {
+            new String[]    {
                 "read",
                 "write"
                 });
@@ -4385,21 +4371,19 @@
 }
 
 class ReflectPerm extends Perm {
-    public ReflectPerm() {
-    super("ReflectPermission",
-        "java.lang.reflect.ReflectPermission",
-        new String[]    {
+    ReflectPerm() {
+        super(java.lang.reflect.ReflectPermission.class,
+            new String[]    {
                 "suppressAccessChecks"
                 },
-        null);
+            null);
     }
 }
 
 class RuntimePerm extends Perm {
-    public RuntimePerm() {
-    super("RuntimePermission",
-        "java.lang.RuntimePermission",
-        new String[]    {
+    RuntimePerm() {
+        super(java.lang.RuntimePermission.class,
+            new String[]    {
                 "createClassLoader",
                 "getClassLoader",
                 "setContextClassLoader",
@@ -4432,15 +4416,14 @@
                 "usePolicy",
                 // "inheritedChannel"
                 },
-        null);
+            null);
     }
 }
 
 class SecurityPerm extends Perm {
-    public SecurityPerm() {
-    super("SecurityPermission",
-        "java.security.SecurityPermission",
-        new String[]    {
+    SecurityPerm() {
+        super(java.security.SecurityPermission.class,
+            new String[]    {
                 "createAccessControlContext",
                 "getDomainCombiner",
                 "getPolicy",
@@ -4470,30 +4453,28 @@
                 //"getSignerPrivateKey",
                 //"setSignerKeyPair"
                 },
-        null);
+            null);
     }
 }
 
 class SerialPerm extends Perm {
-    public SerialPerm() {
-    super("SerializablePermission",
-        "java.io.SerializablePermission",
-        new String[]    {
+    SerialPerm() {
+        super(java.io.SerializablePermission.class,
+            new String[]    {
                 "enableSubclassImplementation",
                 "enableSubstitution"
                 },
-        null);
+            null);
     }
 }
 
 class ServicePerm extends Perm {
-    public ServicePerm() {
-    super("ServicePermission",
-        "javax.security.auth.kerberos.ServicePermission",
-        new String[]    {
+    ServicePerm() {
+        super(javax.security.auth.kerberos.ServicePermission.class,
+            new String[]    {
                 // allow user input
                 },
-        new String[]    {
+            new String[]    {
                 "initiate",
                 "accept"
                 });
@@ -4501,13 +4482,12 @@
 }
 
 class SocketPerm extends Perm {
-    public SocketPerm() {
-    super("SocketPermission",
-        "java.net.SocketPermission",
-        new String[]    {
+    SocketPerm() {
+        super(java.net.SocketPermission.class,
+            new String[]    {
                 // allow user input
                 },
-        new String[]    {
+            new String[]    {
                 "accept",
                 "connect",
                 "listen",
@@ -4517,38 +4497,35 @@
 }
 
 class SQLPerm extends Perm {
-    public SQLPerm() {
-    super("SQLPermission",
-        "java.sql.SQLPermission",
-        new String[]    {
+    SQLPerm() {
+        super(java.sql.SQLPermission.class,
+            new String[]    {
                 "setLog",
                 "callAbort",
                 "setSyncFactory",
                 "setNetworkTimeout",
                 },
-        null);
+            null);
     }
 }
 
 class SSLPerm extends Perm {
-    public SSLPerm() {
-    super("SSLPermission",
-        "javax.net.ssl.SSLPermission",
-        new String[]    {
+    SSLPerm() {
+        super(javax.net.ssl.SSLPermission.class,
+            new String[]    {
                 "setHostnameVerifier",
                 "getSSLSessionContext"
                 },
-        null);
+            null);
     }
 }
 
 class SubjDelegPerm extends Perm {
-    public SubjDelegPerm() {
-    super("SubjectDelegationPermission",
-        "javax.management.remote.SubjectDelegationPermission",
-        new String[]    {
+    SubjDelegPerm() {
+        super(javax.management.remote.SubjectDelegationPermission.class,
+            new String[]    {
                 // allow user input
                 },
-        null);
+            null);
     }
 }
--- a/jdk/test/ProblemList.txt	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/ProblemList.txt	Wed Jul 05 20:43:22 2017 +0200
@@ -154,17 +154,6 @@
 
 ############################################################################
 
-# jdk_math
-
-############################################################################
-
-# jdk_other
-
-# 6988950
-demo/jvmti/compiledMethodLoad/CompiledMethodLoadTest.java	generic-all
-
-############################################################################
-
 # jdk_net
 
 # 7148829
@@ -390,10 +379,4 @@
 # 8064572 8060736 8062938
 sun/jvmstat/monitor/MonitoredVm/CR6672135.java			generic-all
 
-# 8079273
-demo/jvmti/hprof/CpuOldTest.java            generic-all
-demo/jvmti/hprof/CpuTimesTest.java          generic-all
-demo/jvmti/hprof/OptionsTest.java           generic-all
-demo/jvmti/hprof/StackMapTableTest.java     generic-all
-
 ############################################################################
--- a/jdk/test/TEST.groups	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/TEST.groups	Wed Jul 05 20:43:22 2017 +0200
@@ -42,7 +42,8 @@
     :jdk_svc
 
 tier3 = \
-    :jdk_rmi
+    :jdk_rmi \
+    :jdk_beans
 
 ###############################################################################
 #
--- a/jdk/test/demo/jvmti/DemoRun.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/demo/jvmti/DemoRun.java	Wed Jul 05 20:43:22 2017 +0200
@@ -122,7 +122,6 @@
         String libprefix = os_name.contains("Windows")?"":"lib";
         String libsuffix = os_name.contains("Windows")?".dll":
                                 os_name.contains("OS X")?".dylib":".so";
-        boolean hprof    = demo_name.equals("hprof");
         String java      = sdk_home
                              + File.separator + "bin"
                              + File.separator + "java";
@@ -155,22 +154,15 @@
         cmdLine += (cmd[i++] = "-Xcheck:jni");
         cmdLine += " ";
         cmdLine += (cmd[i++] = "-Xverify:all");
-        if ( hprof ) {
-            /* Load hprof with -agentlib since it's part of jre */
-            cmdLine += " ";
-            cmdLine += (cmd[i++] = "-agentlib:" + demo_name
-                     + (demo_options.equals("")?"":("="+demo_options)));
-        } else {
-            String libname  = sdk_home
-                         + File.separator + "demo"
-                         + File.separator + "jvmti"
-                         + File.separator + demo_name
-                         + File.separator + "lib"
-                         + File.separator + libprefix + demo_name + libsuffix;
-            cmdLine += " ";
-            cmdLine += (cmd[i++] = "-agentpath:" + libname
-                     + (demo_options.equals("")?"":("="+demo_options)));
-        }
+        String libname = sdk_home
+                + File.separator + "demo"
+                + File.separator + "jvmti"
+                + File.separator + demo_name
+                + File.separator + "lib"
+                + File.separator + libprefix + demo_name + libsuffix;
+        cmdLine += " ";
+        cmdLine += (cmd[i++] = "-agentpath:" + libname
+                + (demo_options.equals("") ? "" : ("=" + demo_options)));
         /* Add any special VM options */
         for ( j = 0; j < nvm_options; j++ ) {
             cmdLine += " ";
--- a/jdk/test/demo/jvmti/hprof/CpuOldTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5012882 6299047
- * @summary Test jvmti hprof
- *
- * @compile -g HelloWorld.java ../DemoRun.java
- * @build CpuOldTest
- * @run main CpuOldTest HelloWorld
- */
-
-public class CpuOldTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-
-        /* Run JVMTI hprof agent with cpu=old */
-        hprof = new DemoRun("hprof", "cpu=old,file=cpuold.txt");
-        hprof.runit(args[0]);
-
-        /* Make sure patterns in output look ok */
-        if (hprof.output_contains("ERROR")) {
-            throw new RuntimeException("Test failed - ERROR seen in output");
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/CpuSamplesTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5012882
- * @summary Test jvmti hprof
- *
- * @compile -g:lines HelloWorld.java ../DemoRun.java
- * @build CpuSamplesTest
- * @run main CpuSamplesTest HelloWorld
- */
-
-public class CpuSamplesTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-
-        /* Run JVMTI hprof agent with cpu=samples */
-        hprof = new DemoRun("hprof", "cpu=samples,file=cpusamples.txt");
-        hprof.runit(args[0]);
-
-        /* Make sure patterns in output look ok */
-        if (hprof.output_contains("ERROR")) {
-            throw new RuntimeException("Test failed - ERROR seen in output");
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/CpuTimesDefineClassTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5097131 6299047
- * @summary Test jvmti hprof
- *
- * @compile -g HelloWorld.java DefineClass.java ../DemoRun.java
- * @build CpuTimesDefineClassTest
- * @run main CpuTimesDefineClassTest DefineClass
- *
- *
- */
-
-public class CpuTimesDefineClassTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-
-        /* Run JVMTI hprof agent with cpu=times */
-        hprof = new DemoRun("hprof", "cpu=times,file=cputimedefineclass.txt");
-        hprof.runit(args[0]);
-
-        /* Make sure patterns in output look ok */
-        if (hprof.output_contains("ERROR")) {
-            throw new RuntimeException("Test failed - ERROR seen in output");
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/CpuTimesTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5012882 6299047
- * @summary Test jvmti hprof
- *
- * @compile -g HelloWorld.java ../DemoRun.java
- * @build CpuTimesTest
- * @run main CpuTimesTest HelloWorld
- */
-
-public class CpuTimesTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-
-        /* Run JVMTI hprof agent with cpu=times */
-        hprof = new DemoRun("hprof", "cpu=times,file=cputimes.txt");
-        hprof.runit(args[0]);
-
-        /* Make sure patterns in output look ok */
-        if (hprof.output_contains("ERROR")) {
-            throw new RuntimeException("Test failed - ERROR seen in output");
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/DefineClass.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2004, 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.
- */
-
-
-/* Testcase that does a defineClass with a NULL name on HelloWorld.class */
-
-import java.io.*;
-
-public class DefineClass extends ClassLoader {
-    public static void main(String args[]) {
-        DefineClass t = new DefineClass();
-        t.run(args);
-    }
-    public void run(String args[]) {
-        Class n;
-        byte b[] = new byte[10000];
-        int len = 0;
-        String cdir;
-        String cfile;
-
-        /* Class is found here: */
-        cdir = System.getProperty("test.classes", ".");
-        cfile = cdir + java.io.File.separator + "HelloWorld.class";
-
-        try {
-            /* Construct byte array with complete class image in it. */
-            FileInputStream fis = new FileInputStream(cfile);
-            int nbytes;
-            do {
-                nbytes = fis.read(b, len, b.length-len);
-                if ( nbytes > 0 ) {
-                    len += nbytes;
-                }
-            } while ( nbytes > 0 );
-        } catch ( Throwable x ) {
-            System.err.println("Cannot find " + cfile);
-            x.printStackTrace();
-        }
-
-        /* Define the class with null for the name */
-        n = defineClass(null, b, 0, len);
-
-        /* Try to create an instance of it */
-        try {
-            n.newInstance();
-        } catch ( Throwable x ) {
-            x.printStackTrace();
-        }
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/HeapAllTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5012882 6299047
- * @summary Test jvmti hprof
- *
- * @compile -g HelloWorld.java ../DemoRun.java
- * @build HeapAllTest
- * @run main HeapAllTest HelloWorld
- */
-
-public class HeapAllTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-
-        /* Run JVMTI hprof agent with heap=all */
-        hprof = new DemoRun("hprof", "heap=all,file=heapall.txt");
-        hprof.runit(args[0]);
-
-        /* Make sure patterns in output look ok */
-        if (hprof.output_contains("ERROR")) {
-            throw new RuntimeException("Test failed - ERROR seen in output");
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/HeapBinaryFormatTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2005, 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 4965057 6313381
- * @summary Test jvmti hprof format=b
- *
- * @compile -g:source HelloWorld.java ../DemoRun.java
- * @build HeapBinaryFormatTest
- * @run main HeapBinaryFormatTest HelloWorld
- */
-
-public class HeapBinaryFormatTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-
-        /* Run JVMTI hprof agent to get binary format dump */
-        hprof = new DemoRun("hprof", "heap=dump,format=b,logflags=4,file=heapbinaryformat.txt");
-        hprof.runit(args[0]);
-
-        /* Make sure patterns in output look ok */
-        if (hprof.output_contains("ERROR")) {
-            throw new RuntimeException("Test failed - ERROR seen in output");
-        }
-
-        /* Try a variation */
-        String vm_opts[] = new String[1];
-        vm_opts[0] = "-Xmx2100m";
-        /* Crashes on small Linux machines: (like fyi)
-           How can I tell how much real memory is on a machine?
-           hprof.runit(args[0], vm_opts);
-        */
-
-        /* Make sure patterns in output look ok */
-        if (hprof.output_contains("ERROR")) {
-            throw new RuntimeException("Test failed - ERROR seen in output");
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/HeapDumpTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5012882 6299047
- * @summary Test jvmti hprof
- *
- * @compile -g:source HelloWorld.java ../DemoRun.java
- * @build HeapDumpTest
- * @run main HeapDumpTest HelloWorld
- */
-
-public class HeapDumpTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-
-        /* Run JVMTI hprof agent with heap=dump */
-        hprof = new DemoRun("hprof", "heap=dump,file=heapdump.txt");
-        hprof.runit(args[0]);
-
-        /* Make sure patterns in output look ok */
-        if (hprof.output_contains("ERROR")) {
-            throw new RuntimeException("Test failed - ERROR seen in output");
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/HeapSitesTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5012882 6299047
- * @summary Test jvmti hprof
- *
- * @compile -g:vars HelloWorld.java ../DemoRun.java
- * @build HeapSitesTest
- * @run main HeapSitesTest HelloWorld
- */
-
-public class HeapSitesTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-
-        /* Run JVMTI hprof agent with heap=sites */
-        hprof = new DemoRun("hprof", "heap=sites,file=heapsites.txt");
-        hprof.runit(args[0]);
-
-        /* Make sure patterns in output look ok */
-        if (hprof.output_contains("ERROR")) {
-            throw new RuntimeException("Test failed - ERROR seen in output");
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/HelloWorld.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2004, 2009, 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.
- */
-
-
-/* HelloWorld:
- *
- *   Sample target application for HPROF tests
- *
- */
-
-/* Just some classes that create a variety of references */
-
-class AAAA {
-    public int                  AAAA_i;
-    public static int           AAAA_si;
-    public Object               AAAA_j;
-    public static Object        AAAA_sj;
-    public long                 AAAA_k;
-    public static long          AAAA_sk;
-}
-
-interface IIII {
-    Object o = new Object();
-}
-
-class BBBB extends AAAA implements IIII {
-    public byte                 BBBB_ii;
-    public static byte          BBBB_sii;
-    public Object               BBBB_jj;
-    public static Object        BBBB_sjj;
-    public short                BBBB_kk;
-    public static short         BBBB_skk;
-}
-
-class REFS {
-    private static String s1    = new String("REFS_string1");
-    private String is2          = new String("REFS_string2");
-    private static String s3    = new String("REFS_string3");
-    private static String s4    = new String("REFS_string4");
-    private String is5          = new String("REFS_string5");
-
-    private AAAA aaaa;
-    private BBBB bbbb;
-
-    public void test() {
-        aaaa    = new AAAA();
-        bbbb    = new BBBB();
-
-        aaaa.AAAA_i     = 1;
-        AAAA.AAAA_si    = 2;
-        aaaa.AAAA_j     = s1;
-        AAAA.AAAA_sj    = is2;
-        aaaa.AAAA_k     = 5;
-        AAAA.AAAA_sk    = 6;
-
-        bbbb.BBBB_ii    = 11;
-        BBBB.BBBB_sii   = 22;
-        bbbb.BBBB_jj    = s3;
-        BBBB.BBBB_sjj   = s4;
-        bbbb.BBBB_kk    = 55;
-        BBBB.BBBB_skk   = 66;
-
-        bbbb.AAAA_i     = 111;
-        bbbb.AAAA_j     = is5;
-        bbbb.AAAA_k     = 555;
-    }
-}
-
-/* Fairly simple hello world program that does some exercises first. */
-
-public class HelloWorld {
-    public static void main(String args[]) {
-
-        /* References exercise. */
-        REFS r = new REFS();
-        r.test();
-
-        /* Use a generic type exercise. */
-        java.util.List<String> l = new java.util.ArrayList<String>();
-        String.format("%s", "");
-
-        /* Create a class that has lots of different bytecodes exercise. */
-                     /* (Don't run it!) */
-        UseAllBytecodes x = new UseAllBytecodes(1,2);
-
-        /* Just some code with branches exercise. */
-        try {
-            if ( args.length == 0 ) {
-                System.out.println("No arguments passed in (doesn't matter)");
-            } else {
-                System.out.println("Arguments passed in (doesn't matter)");
-            }
-        } catch ( Throwable e ) {
-            System.out.println("ERROR: System.out.println() did a throw");
-        } finally {
-            System.out.println("Hello, world!");
-        }
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/MonitorTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5012882
- * @summary Test jvmti hprof
- *
- * @compile -g ../Context.java ../DemoRun.java
- * @build MonitorTest
- * @run main MonitorTest Context 25 200 1000
- */
-
-/* To create monitor contention, increase the default configuration.
- *   Hprof seems to have historically not output anything unless certain
- *   limits have been reached on the total contention time.
- */
-
-public class MonitorTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-
-        /* Run JVMTI hprof agent with monitor=y */
-        hprof = new DemoRun("hprof", "monitor=y,file=monitor.txt");
-        hprof.runit(args[0]);
-
-        /* Make sure patterns in output look ok */
-        if (hprof.output_contains("ERROR")) {
-            throw new RuntimeException("Test failed - ERROR seen in output");
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/OptionsTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5083441 6299047
- * @summary Test jvmti hprof
- *
- * @compile -g:lines HelloWorld.java ../DemoRun.java
- * @build OptionsTest
- * @run main OptionsTest HelloWorld
- */
-
-import java.util.*;
-
-public class OptionsTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-        List<String> options = new LinkedList<String>();
-
-        options.add("cpu=samples,depth=0,file=options0.txt");
-        options.add("cpu=times,depth=0,file=options1.txt");
-        options.add("cpu=old,depth=0,file=options2.txt");
-        options.add("depth=0,file=options3.txt");
-
-        for(String option: options) {
-            /* Run JVMTI hprof agent with various options */
-            hprof = new DemoRun("hprof", option);
-            hprof.runit(args[0]);
-
-            /* Make sure patterns in output look ok */
-            if (hprof.output_contains("ERROR")) {
-                throw new RuntimeException("Test failed with " + option
-                                           + " - ERROR seen in output");
-            }
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/StackMapTableTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2005, 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 6266289 6299047 6855180 6855551
- * @summary Test jvmti hprof and java_crw_demo with StackMapTable attributes
- *
- * @compile ../DemoRun.java
- * @compile -g:lines HelloWorld.java
- * @build StackMapTableTest
- * @run main StackMapTableTest HelloWorld
- */
-
-import java.util.*;
-
-public class StackMapTableTest {
-
-    public static void main(String args[]) throws Exception {
-        DemoRun hprof;
-        List<String> options = new LinkedList<String>();
-
-        options.add("cpu=samples,file=stackmaptable0.txt");
-        options.add("cpu=times,file=stackmaptable1.txt");
-        options.add("heap=sites,file=stackmaptable2.txt");
-        options.add("file=stackmaptable3.txt");
-
-        for(String option: options) {
-            /* Run JVMTI hprof agent with various options */
-            hprof = new DemoRun("hprof", option);
-            hprof.runit(args[0]);
-
-            /* Make sure patterns in output look ok */
-            if (hprof.output_contains("ERROR")) {
-                throw new RuntimeException("Test failed with " + option
-                                           + " - ERROR seen in output");
-            }
-        }
-
-        /* Must be a pass. */
-        System.out.println("Test passed - cleanly terminated");
-    }
-}
--- a/jdk/test/demo/jvmti/hprof/UseAllBytecodes.java	Wed Jul 05 20:42:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,309 +0,0 @@
-/*
- * Copyright (c) 1996, 2005, 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.
- */
-/*
-        A simple Java class definition that helps self-test the runtime
-        interpreter.  Used for getfield/putfield, invoke* opcodes and
-        their _quick variants.
-
-        See src/share/java/runtime/selftest.c for details of the test
-        environment.
-*/
-
-/* Used to be sun/misc/SelfTest.java */
-
-interface UseAllBytecodesInterface
-{
-    public void test_an_interface(int p1);
-}
-
-public class UseAllBytecodes implements UseAllBytecodesInterface
-{
-        public int i1, i2;
-        public float f1, f2;
-        public double d1, d2;
-        public long l1, l2;
-
-        public static int si1, si2;
-        public static float sf1, sf2;
-        public static double sd1, sd2;
-        public static long sl1, sl2;
-
-        public UseAllBytecodesInterface interfaceObject;
-
-        public int multi[][][];
-
-        public UseAllBytecodes()
-        {
-                /*      This constructor is not intended to ever be run.  It is here
-                        to force CONSTANT_Methodref constants into the CP */
-                set_i1(11);
-                set_i2(22);
-                set_f1(1.1f);
-                set_f2(2.2f);
-                set_d1(1.0);
-                set_d2(2.0);
-                set_l1(3);
-                set_l2(4);
-
-                set_si1(33);
-                set_si2(44);
-                set_sf1(3.3f);
-                set_sf2(4.4f);
-                set_sd1(3.0);
-                set_sd2(4.0);
-                set_sl1(5);
-                set_sl2(6);
-
-                test_areturn();
-                test_athrow1();
-                test_athrow2();
-                test_athrow3();
-                test_athrow4();
-
-                /*      This puts a CONSTANT_InterfaceMethodref into the CP */
-                interfaceObject.test_an_interface(1234);
-
-                /*      This creates an array and puts it into the CP */
-                multi = new int[2][3][4];
-        }
-
-        public UseAllBytecodes(int p1)
-        {
-                i1 = p1;
-                i2 = 12345678;  /* This puts a CONSTANT_Integer into the CP */
-                d1 = (double) p1;
-                d2 = 1.2e234;   /* This puts a CONSTANT_Double into the CP */
-        }
-
-        public UseAllBytecodes(int p1, int p2)
-        {
-                i1 = p1;
-                i2 = p2;
-        }
-
-        /*      These methods should return something other than their
-                arguments, so the self test can easily determine that
-                the correct value was returned. */
-        public int set_i1(int p1)
-        {
-                i1 = p1;
-                return i1 + 1;
-        }
-
-        public int set_i2(int p2)
-        {
-                i2 = p2;
-                return i2 + 1;
-        }
-
-        public float set_f1(float p1)
-        {
-                f1 = p1;
-                return f1 + 1.0e34f;
-        }
-
-        public float set_f2(float p2)
-        {
-                f2 = p2;
-                return f2 + 1.0e34f;
-        }
-
-        public double set_d1(double p1)
-        {
-                d1 = p1;
-                return d1 + 1.0e234;
-        }
-
-        public double set_d2(double p2)
-        {
-                d2 = p2;
-                return d2 + 1.0e234;
-        }
-
-        public long set_l1(long p1)
-        {
-                l1 = p1;
-                return l1 + 1;
-        }
-
-        public long set_l2(long p2)
-        {
-                l2 = p2;
-                return l2 + 1;
-        }
-
-        public static void set_si1(int p1)
-        {
-                si1 = p1;
-        }
-
-        public static void set_si2(int p2)
-        {
-                si2 = p2;
-        }
-
-        public static void set_sf1(float p1)
-        {
-                sf1 = p1;
-        }
-
-        public static void set_sf2(float p2)
-        {
-                sf2 = p2;
-        }
-
-        public static void set_sd1(double p1)
-        {
-                sd1 = p1;
-        }
-
-        public static void set_sd2(double p2)
-        {
-                sd2 = p2;
-        }
-
-        public static void set_sl1(long p1)
-        {
-                sl1 = p1;
-        }
-
-        public static void set_sl2(long p2)
-        {
-                sl2 = p2;
-        }
-
-        public UseAllBytecodes test_areturn()
-        {
-                return this;
-        }
-
-        /*      This method does the same thing as set_i1.
-                It is here to test the invokeinterface opcode. */
-        public void test_an_interface(int p1)
-        {
-                i1 = p1;
-        }
-
-        /*      The following 10 methods test various permutations of
-                try-and-catch. */
-        public static void test_athrow1() throws NullPointerException
-        {
-                try
-                {
-                        si1 = -1;
-                        throw new NullPointerException();
-                }
-                catch (Exception e)
-                {
-                        si1 = 1;
-                }
-        }
-
-        public static void test_athrow2()
-        {
-                int i = 1;
-                try
-                {
-                        si1 = -1;
-                        test_athrow1();
-                }
-                catch (Exception e)
-                {
-                        // This should *not* catch the exception;
-                        // should be caught in test_athrow1.
-                        si1 = i + 1;
-                }
-        }
-
-        public static void test_athrow3()
-        {
-                int i = 1;
-                try
-                {
-                        // Ultimately throws NullPointerException
-                        si1 = -1;
-                        si2 = -1;
-                        test_athrow5();
-                }
-                catch (NullPointerException np)
-                {
-                        si1 = i + 1;
-                }
-                catch (NoSuchMethodException e)
-                {
-                        si2 = i + 1;
-                }
-                si1++;  // total is 3
-        }
-
-        public static void test_athrow4()
-        {
-                int i = 2;
-                try
-                {
-                        // Ultimately throws NoSuchMethodException
-                        si1 = -1;
-                        si2 = -1;
-                        test_athrow7();
-                }
-                catch (NullPointerException e)
-                {
-                        si1 = i + 1;
-                }
-                catch (NoSuchMethodException nsm)
-                {
-                        si2 = i + 1;
-                }
-                si2++;  // total is 4
-        }
-
-        public static void test_throw_nosuchmethod() throws NoSuchMethodException
-        {
-                throw new NoSuchMethodException();
-        }
-
-        public static void test_throw_nullpointer() throws NullPointerException
-        {
-                throw new NullPointerException();
-        }
-
-        public static void test_athrow5() throws NullPointerException, NoSuchMethodException
-        {
-                test_athrow6();
-        }
-
-        public static void test_athrow6() throws NullPointerException, NoSuchMethodException
-        {
-                test_throw_nullpointer();
-        }
-
-        public static void test_athrow7() throws NullPointerException, NoSuchMethodException
-        {
-                test_athrow8();
-        }
-
-        public static void test_athrow8() throws NullPointerException, NoSuchMethodException
-        {
-                test_throw_nosuchmethod();
-        }
-}
--- a/jdk/test/java/lang/invoke/MethodHandles/CatchExceptionTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/java/lang/invoke/MethodHandles/CatchExceptionTest.java	Wed Jul 05 20:43:22 2017 +0200
@@ -168,6 +168,11 @@
         try {
             returned = target.invokeWithArguments(args);
         } catch (Throwable ex) {
+            if (CodeCacheOverflowProcessor.isThrowableCausedByVME(ex)) {
+                // This error will be treated by CodeCacheOverflowProcessor
+                // to prevent the test from failing because of code cache overflow.
+                throw new Error(ex);
+            }
             testCase.assertCatch(ex);
             returned = ex;
         }
--- a/jdk/test/java/nio/channels/ServerSocketChannel/AdaptServerSocket.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/AdaptServerSocket.java	Wed Jul 05 20:43:22 2017 +0200
@@ -123,7 +123,7 @@
 
     public static void main(String[] args) throws Exception {
         test(0, 0, false);
-        test(50, 500, false);
+        test(50, 5000, false);
         test(500, 50, true);
     }
 
--- a/jdk/test/java/security/SecureClassLoader/DefineClass.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/java/security/SecureClassLoader/DefineClass.java	Wed Jul 05 20:43:22 2017 +0200
@@ -21,28 +21,44 @@
  * questions.
  */
 
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.net.URL;
 import java.security.CodeSource;
+import java.security.Key;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
 import java.security.Permission;
 import java.security.Policy;
 import java.security.ProtectionDomain;
+import java.security.Provider;
 import java.security.SecureClassLoader;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.URIParameter;
 import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
 import java.util.List;
 import java.util.PropertyPermission;
 
 /*
  * @test
- * @bug 6826789
+ * @bug 6826789 8131486
  * @summary Make sure equivalent ProtectionDomains are granted the same
  *          permissions when the CodeSource URLs are different but resolve
  *          to the same ip address after name service resolution.
- * @run main/othervm/java.security.policy=DefineClass.policy DefineClass
+ * @run main/othervm DefineClass
  */
 
 public class DefineClass {
@@ -53,42 +69,100 @@
         new PropertyPermission("user.name", "read")
     };
 
-    // Base64 encoded bytes of a simple class: "public class Foo {}"
+    // Base64 encoded bytes of simple class: "package foo; public class Foo {}"
     private final static String FOO_CLASS =
+        "yv66vgAAADMADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" +
+        "D0xpbmVOdW1iZXJUYWJsZQEAClNvdXJjZUZpbGUBAAhGb28uamF2YQwABAAF" +
+        "AQAHZm9vL0ZvbwEAEGphdmEvbGFuZy9PYmplY3QAIQACAAMAAAAAAAEAAQAE" +
+        "AAUAAQAGAAAAHQABAAEAAAAFKrcAAbEAAAABAAcAAAAGAAEAAAABAAEACAAA" +
+        "AAIACQ==";
+
+    // Base64 encoded bytes of simple class: "package bar; public class Bar {}"
+    private final static String BAR_CLASS =
+        "yv66vgAAADMADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" +
+        "D0xpbmVOdW1iZXJUYWJsZQEAClNvdXJjZUZpbGUBAAhCYXIuamF2YQwABAAF" +
+        "AQAHYmFyL0JhcgEAEGphdmEvbGFuZy9PYmplY3QAIQACAAMAAAAAAAEAAQAE" +
+        "AAUAAQAGAAAAHQABAAEAAAAFKrcAAbEAAAABAAcAAAAGAAEAAAABAAEACAAA" +
+        "AAIACQ==";
+
+    // Base64 encoded bytes of simple class: "package baz; public class Baz {}"
+    private final static String BAZ_CLASS =
         "yv66vgAAADQADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" +
-        "D0xpbmVOdW1iZXJUYWJsZQEAClNvdXJjZUZpbGUBAAhGb28uamF2YQwABAAF" +
-        "AQADRm9vAQAQamF2YS9sYW5nL09iamVjdAAhAAIAAwAAAAAAAQABAAQABQAB" +
-        "AAYAAAAdAAEAAQAAAAUqtwABsQAAAAEABwAAAAYAAQAAAAEAAQAIAAAAAgAJ";
+        "D0xpbmVOdW1iZXJUYWJsZQEAClNvdXJjZUZpbGUBAAhCYXouamF2YQwABAAF" +
+        "AQAHYmF6L0JhegEAEGphdmEvbGFuZy9PYmplY3QAIQACAAMAAAAAAAEAAQAE" +
+        "AAUAAQAGAAAAHQABAAEAAAAFKrcAAbEAAAABAAcAAAAGAAEAAAABAAEACAAA" +
+        "AAIACQ==";
 
-    // Base64 encoded bytes of a simple class: "public class Bar {}"
-    private final static String BAR_CLASS =
-        "yv66vgAAADQADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" +
-        "D0xpbmVOdW1iZXJUYWJsZQEAClNvdXJjZUZpbGUBAAhCYXIuamF2YQwABAAF" +
-        "AQADQmFyAQAQamF2YS9sYW5nL09iamVjdAAhAAIAAwAAAAAAAQABAAQABQAB" +
-        "AAYAAAAdAAEAAQAAAAUqtwABsQAAAAEABwAAAAYAAQAAAAEAAQAIAAAAAgAJ";
+    private final static String BAZ_CERT =
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIEFzCCA8OgAwIBAgIESpPf8TANBglghkgBZQMEAwIFADAOMQwwCgYDVQQDEwNG\n" +
+        "b28wHhcNMTUwNzE1MTY1ODM5WhcNMTUxMDEzMTY1ODM5WjAOMQwwCgYDVQQDEwNG\n" +
+        "b28wggNCMIICNQYHKoZIzjgEATCCAigCggEBAI95Ndm5qum/q+2Ies9JUbbzLsWe\n" +
+        "O683GOjqxJYfPv02BudDUanEGDM5uAnnwq4cU5unR1uF0BGtuLR5h3VJhGlcrA6P\n" +
+        "FLM2CCiiL/onEQo9YqmTRTQJoP5pbEZY+EvdIIGcNwmgEFexla3NACM9ulSEtikf\n" +
+        "nWSO+INEhneXnOwEtDSmrC516Zhd4j2wKS/BEYyf+p2BgeczjbeStzDXueNJWS9o\n" +
+        "CZhyFTkV6j1ri0ZTxjNFj4A7MqTC4PJykCVuTj+KOwg4ocRQ5OGMGimjfd9eoUPe\n" +
+        "S2b/BJA+1c8WI+FY1IfGCOl/IRzYHcojy244B2X4IuNCvkhMBXY5OWAc1mcCHQC6\n" +
+        "9pamhXj3397n+mfJd8eF7zKyM7rlgMC81WldAoIBABamXFggSFBwTnUCo5dXBA00\n" +
+        "2jo0eMFU1OSlwC0kLuBPluYeS9CQSr2sjzfuseCfMYLSPJBDy2QviABBYO35ygmz\n" +
+        "IHannDKmJ/JHPpGHm6LE50S9IIFUTLVbgCw2jR+oPtSJ6U4PoGiOMkKKXHjEeMaN\n" +
+        "BSe3HJo6uwsL4SxEaJY559POdNsQGmWqK4f2TGgm2z7HL0tVmYNLtO2wL3yQ6aSW\n" +
+        "06VdU1vr/EXU9hn2Pz3tu4c5JcLyJOB3MSltqIfsHkdI+H77X963VIQxayIy3uVT\n" +
+        "3a8CESsNHwLaMJcyJP4nrtqLnUspItm6i+Oe2eEDpjxSgQvGiLfi7UMW4e8X294D\n" +
+        "ggEFAAKCAQBsGeU8/STExzQsJ8kFM9xarA/2VAFMzyUpd3IQ2UGHQC5rEnGh/RiU\n" +
+        "T20y7a2hCpQ1f/qgLnY8hku9GRVY3z8WamBzWLzCAEAx67EsS58mf4o8R3sUbkH5\n" +
+        "/mRaZoNVSPUy+tXoLmTzIetU4W+JT8Rq4OcXXU9uo9TreeBehhVexS3vpVgQeUIn\n" +
+        "MmMma8WHpovIJQQlp4cyjalX7Beda/tqX/HPLkAS4TRqQAz7hFr3FqFrVMKFSGo4\n" +
+        "fTS06GGdQ4tw9c6NQLuQ9WF9BxYSwSk9yENQvKDZaBNarqPMnsh1Gi/QcKMRBVhM\n" +
+        "RT/9vb4QUi/pOowhhKCDBLgjY60QgX3HoyEwHzAdBgNVHQ4EFgQUa787CE+3ZNAb\n" +
+        "g1ql9yJVVrRCdx0wDQYJYIZIAWUDBAMCBQADPwAwPAIcCUkZIRrBlKdTzhKYBEOm\n" +
+        "E1i45MMum1RuHc28agIcfHQkkjBA4FfH5UMRgKpIyRR8V/dVboxDj4hKOA==\n" +
+        "-----END CERTIFICATE-----";
 
     public static void main(String[] args) throws Exception {
 
+        Security.addProvider(new TestProvider());
+
         MySecureClassLoader scl = new MySecureClassLoader();
-        Policy p = Policy.getPolicy();
+
+        File policyFile = new File(System.getProperty("test.src", "."),
+                                   "DefineClass.policy");
+        Policy p = Policy.getInstance("JavaPolicy",
+                                      new URIParameter(policyFile.toURI()));
+        Policy.setPolicy(p);
+
+        System.setSecurityManager(new SecurityManager());
         ArrayList<Permission> perms1 = getPermissions(scl, p,
                                                       "http://localhost/",
-                                                      "Foo", FOO_CLASS);
+                                                      "foo.Foo", FOO_CLASS,
+                                                      null);
         checkPerms(perms1, GRANTED_PERMS);
         ArrayList<Permission> perms2 = getPermissions(scl, p,
                                                       "http://127.0.0.1/",
-                                                      "Bar", BAR_CLASS);
+                                                      "bar.Bar", BAR_CLASS,
+                                                      null);
         checkPerms(perms2, GRANTED_PERMS);
         assert(perms1.equals(perms2));
+
+        // check that class signed by baz is granted an additional permission
+        Certificate[] chain = new Certificate[] {getCert(BAZ_CERT)};
+        ArrayList<Permission> perms3 = getPermissions(scl, p,
+                                                      "http://localhost/",
+                                                      "baz.Baz", BAZ_CLASS,
+                                                      chain);
+        List<Permission> perms = new ArrayList<>(Arrays.asList(GRANTED_PERMS));
+        perms.add(new PropertyPermission("user.dir", "read"));
+        checkPerms(perms3, perms.toArray(new Permission[0]));
     }
 
     // returns the permissions granted to the codebase URL
     private static ArrayList<Permission> getPermissions(MySecureClassLoader scl,
                                                         Policy p, String url,
                                                         String className,
-                                                        String classBytes)
+                                                        String classBytes,
+                                                        Certificate[] chain)
                                                         throws IOException {
-        CodeSource cs = new CodeSource(new URL(url), (Certificate[])null);
+        CodeSource cs = new CodeSource(new URL(url), chain);
         Base64.Decoder bd = Base64.getDecoder();
         byte[] bytes = bd.decode(classBytes);
         Class<?> c = scl.defineMyClass(className, bytes, cs);
@@ -105,10 +179,125 @@
         }
     }
 
+    private static Certificate getCert(String base64Cert) throws Exception {
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        InputStream is = new ByteArrayInputStream(base64Cert.getBytes("UTF-8"));
+        return cf.generateCertificate(is);
+    }
+
     // A SecureClassLoader that allows the test to define its own classes
     private static class MySecureClassLoader extends SecureClassLoader {
         Class<?> defineMyClass(String name, byte[] b, CodeSource cs) {
             return super.defineClass(name, b, 0, b.length, cs);
         }
     }
+
+    private static class TestProvider extends Provider {
+        TestProvider() {
+            super("Test8131486", 0.0, "For testing only");
+            putService(new Provider.Service(this, "KeyStore", "Test8131486",
+                       "DefineClass$TestKeyStore", null, null));
+        }
+    }
+
+    /**
+     * A KeyStore containing a single certificate entry named "baz".
+     */
+    public static class TestKeyStore extends KeyStoreSpi {
+        private final String baz = "baz";
+        private final List<String> aliases = Collections.singletonList(baz);
+        private final Certificate bazCert;
+
+        public TestKeyStore() {
+            try {
+                this.bazCert = getCert(BAZ_CERT);
+            } catch (Exception e) {
+                throw new Error();
+            }
+        }
+
+        @Override
+        public Enumeration<String> engineAliases() {
+            return Collections.enumeration(aliases);
+        }
+
+        @Override
+        public boolean engineContainsAlias(String alias) {
+            return alias.equals(baz);
+        }
+
+        @Override
+        public void engineDeleteEntry(String alias) throws KeyStoreException {
+            throw new KeyStoreException();
+        }
+
+        @Override
+        public Certificate engineGetCertificate(String alias) {
+            return alias.equals(baz) ? bazCert : null;
+        }
+
+        @Override
+        public String engineGetCertificateAlias(Certificate cert) {
+            return cert.equals(bazCert) ? baz : null;
+        }
+
+        @Override
+        public Certificate[] engineGetCertificateChain(String alias) {
+            return alias.equals(baz) ? new Certificate[] {bazCert} : null;
+        }
+
+        @Override
+        public Date engineGetCreationDate(String alias) {
+            return alias.equals(baz) ? new Date() : null;
+        }
+
+        @Override
+        public Key engineGetKey(String alias, char[] password)
+            throws NoSuchAlgorithmException, UnrecoverableKeyException {
+            return null;
+        }
+
+        @Override
+        public boolean engineIsCertificateEntry(String alias) {
+            return alias.equals(baz);
+        }
+
+        @Override
+        public boolean engineIsKeyEntry(String alias) {
+            return false;
+        }
+
+        @Override
+        public void engineLoad(InputStream stream, char[] password)
+            throws IOException, NoSuchAlgorithmException, CertificateException {
+        }
+
+        @Override
+        public void engineSetCertificateEntry(String alias, Certificate cert)
+            throws KeyStoreException {
+            throw new KeyStoreException();
+        }
+
+        @Override
+        public void engineSetKeyEntry(String alias, byte[] key,
+                                      Certificate[] chain)
+            throws KeyStoreException {
+            throw new KeyStoreException();
+        }
+
+        @Override
+        public void engineSetKeyEntry(String alias, Key key, char[] password,
+                                      Certificate[] chain)
+            throws KeyStoreException {
+            throw new KeyStoreException();
+        }
+
+        @Override
+        public int engineSize() { return 1; }
+
+        @Override
+        public void engineStore(OutputStream stream, char[] password)
+            throws IOException, NoSuchAlgorithmException, CertificateException {
+        }
+    }
 }
--- a/jdk/test/java/security/SecureClassLoader/DefineClass.policy	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/java/security/SecureClassLoader/DefineClass.policy	Wed Jul 05 20:43:22 2017 +0200
@@ -1,7 +1,7 @@
+keystore "NONE", "Test8131486", "Test8131486";
+
 grant {
-    permission java.lang.RuntimePermission "createClassLoader";
     permission java.lang.RuntimePermission "getProtectionDomain";
-    permission java.security.SecurityPermission "getPolicy";
 };
 grant codebase "http://localhost/" {
     permission java.util.PropertyPermission "user.home", "read";
@@ -9,3 +9,6 @@
 grant codebase "http://127.0.0.1/" {
     permission java.util.PropertyPermission "user.name", "read";
 };
+grant codebase "http://localhost/", signedby "baz" {
+    permission java.util.PropertyPermission "user.dir", "read";
+};
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java	Wed Jul 05 20:43:22 2017 +0200
@@ -120,7 +120,8 @@
             }
         };
 
-        int ps = Runtime.getRuntime().availableProcessors();
+        // Bound concurrency to avoid degenerate performance
+        int ps = Math.min(Runtime.getRuntime().availableProcessors(), 32);
         Stream<CompletableFuture> runners = IntStream.range(0, ps)
                 .mapToObj(i -> sr.get())
                 .map(CompletableFuture::runAsync);
--- a/jdk/test/java/util/zip/TestExtraTime.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/java/util/zip/TestExtraTime.java	Wed Jul 05 20:43:22 2017 +0200
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 4759491 6303183 7012868 8015666 8023713 8068790 8076641
+ * @bug 4759491 6303183 7012868 8015666 8023713 8068790 8076641 8075526 8130914
  * @summary Test ZOS and ZIS timestamp in extra field correctly
  */
 
@@ -54,8 +54,12 @@
 
             for (byte[] extra : new byte[][] { null, new byte[] {1, 2, 3}}) {
                 test(mtime, null, null, null, extra);
+
                 // ms-dos 1980 epoch problem
                 test(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null, extra);
+                // negative epoch time
+                test(FileTime.from(-100, TimeUnit.DAYS), null, null, null, extra);
+
                 // non-default tz
                 test(mtime, null, null, tz, extra);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/zip/TestLocalTime.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015, 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 8075526
+ * @summary Test timestamp via ZipEntry.get/setTimeLocal()
+ */
+
+import java.io.*;
+import java.nio.file.*;
+import java.time.*;
+import java.util.*;
+import java.util.zip.*;
+
+public class TestLocalTime {
+    private static TimeZone tz0 = TimeZone.getDefault();
+
+    public static void main(String[] args) throws Throwable{
+        try {
+            LocalDateTime ldt = LocalDateTime.now();
+            test(getBytes(ldt), ldt);    // now
+            ldt = ldt.withYear(1968); test(getBytes(ldt), ldt);
+            ldt = ldt.withYear(1970); test(getBytes(ldt), ldt);
+            ldt = ldt.withYear(1982); test(getBytes(ldt), ldt);
+            ldt = ldt.withYear(2037); test(getBytes(ldt), ldt);
+            ldt = ldt.withYear(2100); test(getBytes(ldt), ldt);
+            ldt = ldt.withYear(2106); test(getBytes(ldt), ldt);
+
+            TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+            // dos time does not support < 1980, have to use
+            // utc in mtime.
+            testWithTZ(tz, ldt.withYear(1982));
+            testWithTZ(tz, ldt.withYear(2037));
+            testWithTZ(tz, ldt.withYear(2100));
+            testWithTZ(tz, ldt.withYear(2106));
+        } finally {
+            TimeZone.setDefault(tz0);
+        }
+    }
+
+    static byte[] getBytes(LocalDateTime mtime) throws Throwable {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ZipOutputStream zos = new ZipOutputStream(baos);
+        ZipEntry ze = new ZipEntry("TestLocalTime.java");
+        ze.setTimeLocal(mtime);
+        check(ze, mtime);
+
+        zos.putNextEntry(ze);
+        zos.write(new byte[] { 1, 2, 3, 4});
+        zos.close();
+        return baos.toByteArray();
+    }
+
+    static void testWithTZ(TimeZone tz, LocalDateTime ldt) throws Throwable {
+       TimeZone.setDefault(tz);
+       byte[] zbytes = getBytes(ldt);
+       TimeZone.setDefault(tz0);
+       test(zbytes, ldt);
+    }
+
+    static void test(byte[] zbytes, LocalDateTime expected) throws Throwable {
+        System.out.printf("--------------------%nTesting: [%s]%n", expected);
+        // ZipInputStream
+        ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zbytes));
+        ZipEntry ze = zis.getNextEntry();
+        zis.close();
+        check(ze, expected);
+
+        // ZipFile
+        Path zpath = Paths.get(System.getProperty("test.dir", "."),
+                               "TestLocalTime.zip");
+        try {
+            Files.copy(new ByteArrayInputStream(zbytes), zpath);
+            ZipFile zf = new ZipFile(zpath.toFile());
+            ze = zf.getEntry("TestLocalTime.java");
+            check(ze, expected);
+            zf.close();
+        } finally {
+            Files.deleteIfExists(zpath);
+        }
+    }
+
+    static void check(ZipEntry ze, LocalDateTime expected) {
+        LocalDateTime ldt = ze.getTimeLocal();
+        if (ldt.atOffset(ZoneOffset.UTC).toEpochSecond() >> 1
+            != expected.atOffset(ZoneOffset.UTC).toEpochSecond() >> 1) {
+            throw new RuntimeException("Timestamp: storing mtime failed!");
+        }
+    }
+}
--- a/jdk/test/javax/net/ssl/TLS/TestJSSE.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/javax/net/ssl/TLS/TestJSSE.java	Wed Jul 05 20:43:22 2017 +0200
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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
@@ -72,7 +72,6 @@
  *        -DCLIENT_PROTOCOL=DEFAULT -Djdk.tls.client.protocols=TLSv1.2
  *        -DCIPHER=SSL_RSA_WITH_RC4_128_MD5
  *        TestJSSE javax.net.ssl.SSLHandshakeException
- * @key intermittent
  *
  */
 
--- a/jdk/test/sun/management/HotspotRuntimeMBean/GetTotalSafepointTime.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/sun/management/HotspotRuntimeMBean/GetTotalSafepointTime.java	Wed Jul 05 20:43:22 2017 +0200
@@ -26,7 +26,7 @@
  * @bug     4858522
  * @modules java.management/sun.management
  * @summary Basic unit test of HotspotRuntimeMBean.getTotalSafepointTime()
- * @author  Steve Bohne
+ * @run main/othervm -XX:+UsePerfData GetTotalSafepointTime
  */
 
 /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/BogusKDC.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+/*
+ * @test
+ * @bug 4515853 8075297
+ * @summary Checks that Kerberos client tries slave KDC
+ *          if master KDC is not responding
+ * @run main/othervm BogusKDC
+ */
+public class BogusKDC {
+
+    static final String TEST_SRC = System.getProperty("test.src", ".");
+    static final String HOST = "localhost";
+    static final String NOT_EXISTING_HOST = "not.existing.host";
+    static final String REALM = "TEST.REALM";
+    static final String USER = "USER";
+    static final String USER_PRINCIPAL = USER + "@" + REALM;
+    static final String USER_PASSWORD = "password";
+    static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM;
+    static final String KRB5_CONF = "krb5.conf";
+    static final int WRONG_KDC_PORT = 21;
+
+    static final String KRB5_CONF_TEMPLATE = ""
+            + "[libdefaults]\n"
+            + "default_realm = TEST.REALM\n"
+            + "max_retries = 1\n"
+            + "\n"
+            + "[realms]\n"
+            + "TEST.REALM = {\n"
+            + "    kdc = %s\n"
+            + "    kdc = localhost:%d\n"
+            + "}";
+
+    public static void main(String[] args) throws LoginException, IOException {
+        Map<String, String> principals = new HashMap<>();
+        principals.put(USER_PRINCIPAL, USER_PASSWORD);
+        principals.put(KRBTGT_PRINCIPAL, null);
+
+        System.setProperty("java.security.krb5.conf", KRB5_CONF);
+
+        // start a local KDC
+        KDC kdc = KDC.startKDC(HOST, KRB5_CONF, REALM, principals, null, null);
+
+        System.setProperty("java.security.auth.login.config",
+                TEST_SRC + File.separator + "refreshKrb5Config.jaas");
+
+        CallbackHandler handler = new Helper.UserPasswordHandler(
+                USER, USER_PASSWORD);
+
+        // create a krb5 config with non-existing host for master KDC,
+        // and wrong port for slave KDC
+        try (PrintWriter w = new PrintWriter(new FileWriter(KRB5_CONF))) {
+            w.write(String.format(KRB5_CONF_TEMPLATE,
+                    KDC.KDCNameService.NOT_EXISTING_HOST, WRONG_KDC_PORT));
+            w.flush();
+        }
+
+        // login with not-refreshable config
+        try {
+            new LoginContext("NotRefreshable", handler).login();
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (LoginException le) {
+            System.out.println("Expected login failure: " + le);
+        }
+
+        // create a krb5 config with non-existing host for master KDC,
+        // but correct port for slave KDC
+        try (PrintWriter w = new PrintWriter(new FileWriter(KRB5_CONF))) {
+            w.write(String.format(KRB5_CONF_TEMPLATE,
+                    KDC.KDCNameService.NOT_EXISTING_HOST, kdc.getPort()));
+            w.flush();
+        }
+
+        // login with not-refreshable config
+        try {
+            new LoginContext("NotRefreshable", handler).login();
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (LoginException le) {
+            System.out.println("Expected login failure: " + le);
+        }
+
+        // login with refreshable config
+        new LoginContext("Refreshable", handler).login();
+
+        System.out.println("Test passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/Helper.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+public class Helper {
+
+    static class UserPasswordHandler implements CallbackHandler {
+
+        private final String name;
+        private final String password;
+
+        UserPasswordHandler(String name, String password) {
+            this.name = name;
+            this.password = password;
+        }
+
+        @Override
+        public void handle(Callback[] callbacks)
+                throws UnsupportedCallbackException {
+            for (Callback callback : callbacks) {
+                if (callback instanceof PasswordCallback) {
+                    ((PasswordCallback) callback).setPassword(
+                            password.toCharArray());
+                } else if (callback instanceof NameCallback) {
+                    ((NameCallback)callback).setName(name);
+                } else {
+                    throw new UnsupportedCallbackException(callback);
+                }
+            }
+        }
+    }
+}
--- a/jdk/test/sun/security/krb5/auto/KDC.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/sun/security/krb5/auto/KDC.java	Wed Jul 05 20:43:22 2017 +0200
@@ -28,6 +28,10 @@
 import java.io.*;
 import java.lang.reflect.Method;
 import java.security.SecureRandom;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalUnit;
 import java.util.*;
 import java.util.concurrent.*;
 
@@ -939,6 +943,13 @@
             } else if (till.isZero()) {
                 till = new KerberosTime(
                         new Date().getTime() + 1000 * DEFAULT_LIFETIME);
+            } else if (till.greaterThan(new KerberosTime(Instant.now()
+                    .plus(1, ChronoUnit.DAYS)))) {
+                // If till is more than 1 day later, make it renewable
+                till = new KerberosTime(
+                        new Date().getTime() + 1000 * DEFAULT_LIFETIME);
+                body.kdcOptions.set(KDCOptions.RENEWABLE, true);
+                if (rtime == null) rtime = till;
             }
             if (rtime == null && body.kdcOptions.get(KDCOptions.RENEWABLE)) {
                 rtime = new KerberosTime(
@@ -1320,14 +1331,17 @@
         }
     }
 
-    public static void startKDC(final String host, final String krbConfFileName,
+    public static KDC startKDC(final String host, final String krbConfFileName,
             final String realm, final Map<String, String> principals,
             final String ktab, final KtabMode mode) {
 
+        KDC kdc;
         try {
-            KDC kdc = KDC.create(realm, host, 0, true);
+            kdc = KDC.create(realm, host, 0, true);
             kdc.setOption(KDC.Option.PREAUTH_REQUIRED, Boolean.FALSE);
-            KDC.saveConfig(krbConfFileName, kdc);
+            if (krbConfFileName != null) {
+                KDC.saveConfig(krbConfFileName, kdc);
+            }
 
             // Add principals
             if (principals != null) {
@@ -1379,6 +1393,7 @@
             throw new RuntimeException("KDC: unexpected exception", e);
         }
 
+        return kdc;
     }
 
     /**
@@ -1428,13 +1443,20 @@
     }
 
     public static class KDCNameService implements NameServiceDescriptor {
+
+        public static String NOT_EXISTING_HOST = "not.existing.host";
+
         @Override
         public NameService createNameService() throws Exception {
             NameService ns = new NameService() {
                 @Override
                 public InetAddress[] lookupAllHostAddr(String host)
                         throws UnknownHostException {
-                    // Everything is localhost
+                    // Everything is localhost except NOT_EXISTING_HOST
+                    if (NOT_EXISTING_HOST.equals(host)) {
+                        throw new UnknownHostException("Unknown host name: "
+                                + NOT_EXISTING_HOST);
+                    }
                     return new InetAddress[]{
                         InetAddress.getByAddress(host, new byte[]{127,0,0,1})
                     };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/LongLife.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015, 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 8131051
+ * @summary KDC might issue a renewable ticket even if not requested
+ * @compile -XDignore.symbol.file LongLife.java
+ * @run main/othervm LongLife
+ */
+
+import sun.security.krb5.Config;
+
+public class LongLife {
+
+    public static void main(String[] args) throws Exception {
+
+        OneKDC kdc = new OneKDC(null).writeJAASConf();
+
+        // A lifetime 2d will make it renewable
+        KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+                "ticket_lifetime = 2d");
+        Config.refresh();
+
+        Context.fromJAAS("client");
+    }
+}
--- a/jdk/test/sun/security/krb5/auto/OneKDC.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/jdk/test/sun/security/krb5/auto/OneKDC.java	Wed Jul 05 20:43:22 2017 +0200
@@ -95,7 +95,7 @@
      * entries with names using existing OneKDC principals.
      * @throws java.lang.Exception if anything goes wrong
      */
-    public void writeJAASConf() throws IOException {
+    public OneKDC writeJAASConf() throws IOException {
         System.setProperty("java.security.auth.login.config", JAAS_CONF);
         File f = new File(JAAS_CONF);
         FileOutputStream fos = new FileOutputStream(f);
@@ -123,6 +123,7 @@
                 "    isInitiator=false;\n};\n"
                 ).getBytes());
         fos.close();
+        return this;
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/RefreshKrb5Config.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+/*
+ * @test
+ * @bug 4745056 8075297
+ * @summary Checks if refreshKrb5Config is set to true for Krb5LoginModule,
+ *          then configuration will be refreshed before login() method is called
+ * @run main/othervm RefreshKrb5Config
+ */
+public class RefreshKrb5Config {
+
+    static final String TEST_SRC = System.getProperty("test.src", ".");
+    static final String HOST = "localhost";
+    static final String NOT_EXISTING_HOST = "not.existing.host";
+    static final String REALM = "TEST.REALM";
+    static final String USER = "USER";
+    static final String USER_PRINCIPAL = USER + "@" + REALM;
+    static final String USER_PASSWORD = "password";
+    static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM;
+    static final String KRB5_CONF_FILENAME = "krb5.conf";
+
+    public static void main(String[] args) throws LoginException, IOException {
+        Map<String, String> principals = new HashMap<>();
+        principals.put(USER_PRINCIPAL, USER_PASSWORD);
+        principals.put(KRBTGT_PRINCIPAL, null);
+
+        System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME);
+
+        // start a local KDC, and save krb5 config
+        KDC kdc = KDC.startKDC(HOST, null, REALM, principals, null, null);
+        KDC.saveConfig(KRB5_CONF_FILENAME, kdc, "max_retries = 1");
+
+        System.setProperty("java.security.auth.login.config",
+                TEST_SRC + File.separator + "refreshKrb5Config.jaas");
+
+        CallbackHandler handler = new Helper.UserPasswordHandler(
+                USER, USER_PASSWORD);
+
+        // set incorrect KDC
+        System.out.println("java.security.krb5.kdc = " + NOT_EXISTING_HOST);
+        System.setProperty("java.security.krb5.kdc", NOT_EXISTING_HOST);
+        System.out.println("java.security.krb5.realm = " + REALM);
+        System.setProperty("java.security.krb5.realm", REALM);
+        try {
+            new LoginContext("Refreshable", handler).login();
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (LoginException le) {
+            System.out.println("Expected login failure: " + le);
+        }
+
+        // reset properties
+        System.out.println("Reset java.security.krb5.kdc");
+        System.clearProperty("java.security.krb5.kdc");
+        System.out.println("Reset java.security.krb5.realm");
+        System.clearProperty("java.security.krb5.realm");
+
+        // login with not-refreshable config
+        try {
+            new LoginContext("NotRefreshable", handler).login();
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (LoginException le) {
+            System.out.println("Expected login failure: " + le);
+        }
+
+        // login with refreshable config
+        new LoginContext("Refreshable", handler).login();
+
+        System.out.println("Test passed");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/refreshKrb5Config.jaas	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,11 @@
+Refreshable {
+    com.sun.security.auth.module.Krb5LoginModule required
+        useTicketCache=false
+        refreshKrb5Config=true;
+};
+
+NotRefreshable {
+    com.sun.security.auth.module.Krb5LoginModule required
+        useTicketCache=false
+        refreshKrb5Config=false;
+};
--- a/langtools/.hgtags	Wed Jul 05 20:42:40 2017 +0200
+++ b/langtools/.hgtags	Wed Jul 05 20:43:22 2017 +0200
@@ -316,3 +316,4 @@
 dc35e315436d21eab68ef44909922fb3424917f3 jdk9-b71
 832e51533706b633d37a77282ae94d016b95e649 jdk9-b72
 1fccc38cd6f56cb2173195e317ba2784b484c2d1 jdk9-b73
+02681b7c4232ba5d43ccba794492db9502211ff0 jdk9-b74
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java	Wed Jul 05 20:43:22 2017 +0200
@@ -151,32 +151,57 @@
      * directed graph in linear time. Works on TarjanNode.
      */
     public static <D, N extends TarjanNode<D, N>> List<? extends List<? extends N>> tarjan(Iterable<? extends N> nodes) {
-        ListBuffer<List<N>> cycles = new ListBuffer<>();
-        ListBuffer<N> stack = new ListBuffer<>();
+        Tarjan<D, N> tarjan = new Tarjan<>();
+        return tarjan.findSCC(nodes);
+    }
+    //where
+    private static class Tarjan<D, N extends TarjanNode<D, N>> {
+
+        /** Unique node identifier. */
         int index = 0;
-        for (N node: nodes) {
-            if (node.index == -1) {
-                index += tarjan(node, index, stack, cycles);
+
+        /** List of SCCs found fso far. */
+        ListBuffer<List<N>> sccs = new ListBuffer<>();
+
+        /** Stack of all reacheable nodes from given root. */
+        ListBuffer<N> stack = new ListBuffer<>();
+
+        private List<? extends List<? extends N>> findSCC(Iterable<? extends N> nodes) {
+            for (N node : nodes) {
+                if (node.index == -1) {
+                    findSCC(node);
+                }
+            }
+            return sccs.toList();
+        }
+
+        private void findSCC(N v) {
+            visitNode(v);
+            for (N n: v.getAllDependencies()) {
+                if (n.index == -1) {
+                    //it's the first time we see this node
+                    findSCC(n);
+                    v.lowlink = Math.min(v.lowlink, n.lowlink);
+                } else if (stack.contains(n)) {
+                    //this node is already reachable from current root
+                    v.lowlink = Math.min(v.lowlink, n.index);
+                }
+            }
+            if (v.lowlink == v.index) {
+                //v is the root of a SCC
+                addSCC(v);
             }
         }
-        return cycles.toList();
-    }
 
-    private static <D, N extends TarjanNode<D, N>> int tarjan(N v, int index, ListBuffer<N> stack, ListBuffer<List<N>> cycles) {
-        v.index = index;
-        v.lowlink = index;
-        index++;
-        stack.prepend(v);
-        v.active = true;
-        for (N n: v.getAllDependencies()) {
-            if (n.index == -1) {
-                tarjan(n, index, stack, cycles);
-                v.lowlink = Math.min(v.lowlink, n.lowlink);
-            } else if (stack.contains(n)) {
-                v.lowlink = Math.min(v.lowlink, n.index);
-            }
+        private void visitNode(N n) {
+            n.index = index;
+            n.lowlink = index;
+            index++;
+            stack.prepend(n);
+            n.active = true;
         }
-        if (v.lowlink == v.index) {
+
+        private void addSCC(N v) {
             N n;
             ListBuffer<N> cycle = new ListBuffer<>();
             do {
@@ -184,9 +209,8 @@
                 n.active = false;
                 cycle.add(n);
             } while (n != v);
-            cycles.add(cycle.toList());
+            sccs.add(cycle.toList());
         }
-        return index;
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8130304/T8130304.java	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/**
+ * @test
+ * @bug 8130304
+ * @summary Inference: NodeNotFoundException thrown with deep generic method call chain
+ * @compile T8130304.java
+ */
+class T8130304 {
+
+    void test() {
+        outer(
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner(),
+            inner());
+    }
+
+    <T> void outer(T... ts) { }
+
+    <T,V,W extends V> T inner() {
+        return null;
+    }
+}
--- a/make/jprt.properties	Wed Jul 05 20:42:40 2017 +0200
+++ b/make/jprt.properties	Wed Jul 05 20:43:22 2017 +0200
@@ -121,10 +121,11 @@
     ${jprt.fastdebugOpen.build.configure.args}
 jprt.i586.productOpen.build.configure.args=				\
     ${my.i586.default.build.configure.args}				\
-    ${jprt.productOpen.build.configure.args}jprt.windows_i586.build.configure.args= \
-    --with-devkit=$VS2013_HOME \
+    ${jprt.productOpen.build.configure.args}
+jprt.windows_i586.build.configure.args=					\
+    --with-devkit=$VS2013_HOME						\
     ${jprt.i586.build.configure.args}
-jprt.windows_x64.build.configure.args= \
+jprt.windows_x64.build.configure.args=					\
     --with-devkit=$VS2013_HOME
 
 ########
--- a/modules.xml	Wed Jul 05 20:42:40 2017 +0200
+++ b/modules.xml	Wed Jul 05 20:43:22 2017 +0200
@@ -1777,6 +1777,11 @@
     <name>jdk.policytool</name>
     <depend>java.base</depend>
     <depend>java.desktop</depend>
+    <depend>java.logging</depend>
+    <depend>java.management</depend>
+    <depend>java.security.jgss</depend>
+    <depend>java.sql</depend>
+    <depend>jdk.security.jgss</depend>
   </module>
   <module>
     <name>jdk.rmic</name>
--- a/nashorn/.hgtags	Wed Jul 05 20:42:40 2017 +0200
+++ b/nashorn/.hgtags	Wed Jul 05 20:43:22 2017 +0200
@@ -307,3 +307,4 @@
 7066af6e7b06f3c6ebf449c88fc1064d2181237a jdk9-b71
 d017877b3b8cd39337f1bdc00d958f821433c4c3 jdk9-b72
 548f1eb2c3c89e024ef3805f48ceed9de503588f jdk9-b73
+2e8bb16872d7b15dc0a4f8e45c6ad65f762c1b04 jdk9-b74
--- a/nashorn/make/build.xml	Wed Jul 05 20:42:40 2017 +0200
+++ b/nashorn/make/build.xml	Wed Jul 05 20:43:22 2017 +0200
@@ -48,7 +48,9 @@
     <condition property="git.executable" value="/usr/local/bin/git" else="git">
       <available file="/usr/local/bin/git"/>
     </condition>
-    <!-- check if testng.jar is avaiable -->
+    <!-- check if testng.jar is avaiable, and download it if it isn't -->
+    <available property="testng.already.present" file="${file.reference.testng.jar}"/>
+    <antcall target="get-testng"/>
     <available property="testng.available" file="${file.reference.testng.jar}"/>
     <!-- check if Jemmy ang testng.jar are avaiable -->
     <condition property="jemmy.jfx.testng.available" value="true">
@@ -484,7 +486,7 @@
     </testng>
   </target>
 
-  <target name="test" depends="get-testng, javadocnh, test-pessimistic, test-optimistic"/>
+  <target name="test" depends="prepare, javadocnh, test-pessimistic, test-optimistic"/>
 
   <target name="test-optimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
     <echo message="Running test suite in OPTIMISTIC mode..."/>
@@ -514,7 +516,7 @@
     <echo message="WARNING: Jemmy or JavaFX or TestNG not available, will not run tests. Please copy testng.jar, JemmyCore.jar, JemmyFX.jar, JemmyAWTInput.jar under test${file.separator}lib directory. And make sure you have jfxrt.jar in ${java.home}${file.separator}lib${file.separator}ext dir."/>
   </target>
 
-  <target name="testjfx" depends="jar, get-testng, check-jemmy.jfx.testng, compile-test" if="jemmy.jfx.testng.available">
+  <target name="testjfx" depends="jar, check-jemmy.jfx.testng, compile-test" if="jemmy.jfx.testng.available">
     <fileset id="test.classes" dir="${build.test.classes.dir}">
        <include name="**/framework/*Test.class"/>
     </fileset>
@@ -542,7 +544,7 @@
     </testng>
   </target>
 
-  <target name="testmarkdown" depends="jar, get-testng, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+  <target name="testmarkdown" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
     <fileset id="test.classes" dir="${build.test.classes.dir}">
        <include name="**/framework/*Test.class"/>
     </fileset>
@@ -561,7 +563,7 @@
     </testng>
   </target>
 
-  <target name="test262" depends="jar, get-testng, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+  <target name="test262" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
     <fileset id="test.classes" dir="${build.test.classes.dir}">
        <include name="**/framework/*Test.class"/>
     </fileset>
@@ -585,7 +587,7 @@
 
   <target name="test262parallel" depends="test262-parallel"/>
 
-  <target name="test262-parallel" depends="jar, get-testng, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+  <target name="test262-parallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
     <!-- use just build.test.classes.dir to avoid referring to TestNG -->
     <java classname="${parallel.test.runner}" dir="${basedir}" fork="true">
       <jvmarg line="${boot.class.path}"/>
@@ -604,7 +606,7 @@
 
   <target name="testparallel" depends="test-parallel"/>
 
-  <target name="test-parallel" depends="jar, get-testng, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+  <target name="test-parallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
       <!-- use just build.test.classes.dir to avoid referring to TestNG -->
       <java classname="${parallel.test.runner}" dir="${basedir}"
         failonerror="true"
@@ -709,7 +711,7 @@
   </target>
 
   <!-- get all external test scripts -->
-  <target name="externals" depends="init, check-external-tests, get-test262, get-octane, get-sunspider, get-testng">
+  <target name="externals" depends="init, check-external-tests, get-test262, get-octane, get-sunspider">
     <!-- make external test dir -->
     <mkdir dir="${test.external.dir}"/>
 
@@ -746,7 +748,7 @@
   <target name="perf" depends="externals, update-externals, sunspider, octane"/>
 
   <!-- download and install testng.jar -->
-  <target name="get-testng" depends="prepare" unless="testng.available">
+  <target name="get-testng" unless="testng.already.present">
     <get src="http://testng.org/testng-6.8.zip" dest="${test.lib}" skipexisting="true" ignoreerrors="true"/>
     <unzip src="${test.lib}${file.separator}testng-6.8.zip" dest="${test.lib}">
       <patternset>
@@ -758,7 +760,7 @@
   </target>
 
   <!-- run all tests -->
-  <target name="alltests" depends="get-testng, externals, update-externals, test, test262parallel, testmarkdown, perf"/>
+  <target name="alltests" depends="externals, update-externals, test, test262parallel, testmarkdown, perf"/>
 
   <import file="build-benchmark.xml"/>
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java	Wed Jul 05 20:43:22 2017 +0200
@@ -783,12 +783,13 @@
             // If this is a declared variable or a function parameter, delete always fails (except for globals).
             final String name = ident.getName();
             final Symbol symbol = ident.getSymbol();
-            final boolean failDelete = strictMode || (!symbol.isScope() && (symbol.isParam() || (symbol.isVar() && !symbol.isProgramLevel())));
 
-            if (failDelete && symbol.isThis()) {
+            if (symbol.isThis()) {
+                // Can't delete "this", ignore and return true
                 return LiteralNode.newInstance(unaryNode, true).accept(this);
             }
             final Expression literalNode = (Expression)LiteralNode.newInstance(unaryNode, name).accept(this);
+            final boolean failDelete = strictMode || (!symbol.isScope() && (symbol.isParam() || (symbol.isVar() && !symbol.isProgramLevel())));
 
             if (!failDelete) {
                 args.add(compilerConstantIdentifier(SCOPE));
@@ -798,6 +799,8 @@
 
             if (failDelete) {
                 request = Request.FAIL_DELETE;
+            } else if (symbol.isGlobal() && !symbol.isFunctionDeclaration()) {
+                request = Request.SLOW_DELETE;
             }
         } else if (rhs instanceof AccessNode) {
             final Expression base     = ((AccessNode)rhs).getBase();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/RuntimeNode.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/RuntimeNode.java	Wed Jul 05 20:43:22 2017 +0200
@@ -56,6 +56,8 @@
         REFERENCE_ERROR,
         /** Delete operator */
         DELETE(TokenType.DELETE, Type.BOOLEAN, 1),
+        /** Delete operator for slow scopes */
+        SLOW_DELETE(TokenType.DELETE, Type.BOOLEAN, 1, false),
         /** Delete operator that always fails -- see Lower */
         FAIL_DELETE(TokenType.DELETE, Type.BOOLEAN, 1, false),
         /** === operator with at least one object */
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Wed Jul 05 20:43:22 2017 +0200
@@ -27,6 +27,7 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodType;
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -72,11 +73,6 @@
     }
 
     @Override
-    boolean isRecompilable() {
-        return false;
-    }
-
-    @Override
     protected boolean needsCallee() {
         final boolean needsCallee = code.getFirst().needsCallee();
         assert allNeedCallee(needsCallee);
@@ -93,6 +89,20 @@
     }
 
     @Override
+    CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
+        assert isValidCallSite(callSiteType) : callSiteType;
+
+        CompiledFunction best = null;
+        for (final CompiledFunction candidate: code) {
+            if (!forbidden.contains(candidate) && candidate.betterThanFinal(best, callSiteType)) {
+                best = candidate;
+            }
+        }
+
+        return best;
+    }
+
+    @Override
     MethodType getGenericType() {
         // We need to ask the code for its generic type. We can't just rely on this function data's arity, as it's not
         // actually correct for lots of built-ins. E.g. ECMAScript 5.1 section 15.5.3.2 prescribes that
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed Jul 05 20:43:22 2017 +0200
@@ -617,6 +617,7 @@
     private CompiledFunction addCode(final MethodHandle target, final Map<Integer, Type> invalidatedProgramPoints,
                                      final MethodType callSiteType, final int fnFlags) {
         final CompiledFunction cfn = new CompiledFunction(target, this, invalidatedProgramPoints, callSiteType, fnFlags);
+        assert noDuplicateCode(cfn) : "duplicate code";
         code.add(cfn);
         return cfn;
     }
@@ -683,14 +684,17 @@
 
     @Override
     synchronized CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
-        CompiledFunction existingBest = super.getBest(callSiteType, runtimeScope, forbidden);
+        assert isValidCallSite(callSiteType) : callSiteType;
+
+        CompiledFunction existingBest = pickFunction(callSiteType, false);
+        if (existingBest == null) {
+            existingBest = pickFunction(callSiteType, true); // try vararg last
+        }
         if (existingBest == null) {
             existingBest = addCode(compileTypeSpecialization(callSiteType, runtimeScope, true), callSiteType);
         }
 
         assert existingBest != null;
-        //we are calling a vararg method with real args
-        boolean varArgWithRealArgs = existingBest.isVarArg() && !CompiledFunction.isVarArgsType(callSiteType);
 
         //if the best one is an apply to call, it has to match the callsite exactly
         //or we need to regenerate
@@ -699,27 +703,18 @@
             if (best != null) {
                 return best;
             }
-            varArgWithRealArgs = true;
-        }
 
-        if (varArgWithRealArgs) {
             // special case: we had an apply to call, but we failed to make it fit.
             // Try to generate a specialized one for this callsite. It may
             // be another apply to call specialization, or it may not, but whatever
             // it is, it is a specialization that is guaranteed to fit
-            final FunctionInitializer fnInit = compileTypeSpecialization(callSiteType, runtimeScope, false);
-            existingBest = addCode(fnInit, callSiteType);
+            existingBest = addCode(compileTypeSpecialization(callSiteType, runtimeScope, false), callSiteType);
         }
 
         return existingBest;
     }
 
     @Override
-    boolean isRecompilable() {
-        return true;
-    }
-
-    @Override
     public boolean needsCallee() {
         return getFunctionFlag(FunctionNode.NEEDS_CALLEE);
     }
@@ -827,6 +822,16 @@
         return newFn;
     }
 
+    // Make sure code does not contain a compiled function with the same signature as compiledFunction
+    private boolean noDuplicateCode(final CompiledFunction compiledFunction) {
+        for (final CompiledFunction cf : code) {
+            if (cf.type().equals(compiledFunction.type())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
         in.defaultReadObject();
         createLogger();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Wed Jul 05 20:43:22 2017 +0200
@@ -359,31 +359,13 @@
      * scope is not known, but that might cause compilation of code that will need more deoptimization passes.
      * @return the best function for the specified call site type.
      */
-    CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
-        assert callSiteType.parameterCount() >= 2 : callSiteType; // Must have at least (callee, this)
-        assert callSiteType.parameterType(0).isAssignableFrom(ScriptFunction.class) : callSiteType; // Callee must be assignable from script function
-
-        if (isRecompilable()) {
-            final CompiledFunction candidate = pickFunction(callSiteType, false);
-            if (candidate != null) {
-                return candidate;
-            }
-            return pickFunction(callSiteType, true); //try vararg last
-        }
+    abstract CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden);
 
-        CompiledFunction best = null;
-        for (final CompiledFunction candidate: code) {
-            if (!forbidden.contains(candidate) && candidate.betterThanFinal(best, callSiteType)) {
-                best = candidate;
-            }
-        }
-
-        return best;
+    boolean isValidCallSite(final MethodType callSiteType) {
+        return callSiteType.parameterCount() >= 2  && // Must have at least (callee, this)
+               callSiteType.parameterType(0).isAssignableFrom(ScriptFunction.class); // Callee must be assignable from script function
     }
 
-
-    abstract boolean isRecompilable();
-
     CompiledFunction getGeneric(final ScriptObject runtimeScope) {
         return getBest(getGenericType(), runtimeScope, CompiledFunction.NO_FUNCTIONS);
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptRuntime.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptRuntime.java	Wed Jul 05 20:43:22 2017 +0200
@@ -685,6 +685,33 @@
     }
 
     /**
+     * ECMA 11.4.1 - delete operator, implementation for slow scopes
+     *
+     * This implementation of 'delete' walks the scope chain to find the scope that contains the
+     * property to be deleted, then invokes delete on it.
+     *
+     * @param obj       top scope object
+     * @param property  property to delete
+     * @param strict    are we in strict mode
+     *
+     * @return true if property was successfully found and deleted
+     */
+    public static boolean SLOW_DELETE(final Object obj, final Object property, final Object strict) {
+        if (obj instanceof ScriptObject) {
+            ScriptObject sobj = (ScriptObject) obj;
+            final String key = property.toString();
+            while (sobj != null && sobj.isScope()) {
+                final FindProperty find = sobj.findProperty(key, false);
+                if (find != null) {
+                    return sobj.delete(key, Boolean.TRUE.equals(strict));
+                }
+                sobj = sobj.getProto();
+            }
+        }
+        return DELETE(obj, property, strict);
+    }
+
+    /**
      * ECMA 11.4.1 - delete operator, special case
      *
      * This is 'delete' that always fails. We have to check strict mode and throw error.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8131340.js	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/**
+ * JDK-8131340:  Varargs function is recompiled each time it is linked
+ *
+ * @test
+ * @run
+ */
+
+// This is an indirect test. If repeated calls were to cause recompilation
+// this would trigger an assertion in RecompilableScriptFunctionData.
+
+function varargs() {
+    return arguments;
+}
+
+varargs(1);
+varargs(2);
+varargs(3);
+varargs(4);
+varargs(5);
+varargs(6);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8131683.js	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/**
+ * JDK-8131683: Delete fails over multiple scopes
+ *
+ * @test
+ * @run
+ */
+
+a = 1;
+b = 2;
+c = 3;
+
+var A = 1;
+var B = 2;
+var C = 3;
+function D() {}
+
+print((function() {
+    var x; // force creation of scope
+    (function() { x; })();
+    return delete a;
+})());
+
+print((function() {
+    eval("");
+    return delete b;
+})());
+
+print((function() {
+    return eval("delete c");
+})());
+
+print((function() {
+    eval("d = 4");
+    return eval("delete d");
+})());
+
+print(typeof a);
+print(typeof b);
+print(typeof c);
+print(typeof d);
+
+print((function() {
+    var x; // force creation of scope
+    (function() { x; })();
+    return delete A;
+})());
+
+print((function() {
+    eval("");
+    return delete B;
+})());
+
+print((function() {
+    return eval("delete C");
+})());
+
+print((function() {
+    eval("");
+    return delete D;
+})());
+
+print(typeof A);
+print(typeof B);
+print(typeof C);
+print(typeof D);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8131683.js.EXPECTED	Wed Jul 05 20:43:22 2017 +0200
@@ -0,0 +1,16 @@
+true
+true
+true
+true
+undefined
+undefined
+undefined
+undefined
+false
+false
+false
+false
+number
+number
+number
+function
--- a/test/lib/share/classes/jdk/test/lib/hprof/model/Snapshot.java	Wed Jul 05 20:42:40 2017 +0200
+++ b/test/lib/share/classes/jdk/test/lib/hprof/model/Snapshot.java	Wed Jul 05 20:43:22 2017 +0200
@@ -276,10 +276,8 @@
         fakeClasses.clear();
 
         weakReferenceClass = findClass("java.lang.ref.Reference");
-        if (weakReferenceClass == null)  {      // JDK 1.1.x
-            weakReferenceClass = findClass("sun.misc.Ref");
-            referentFieldIndex = 0;
-        } else {
+        referentFieldIndex = 0;
+        if (weakReferenceClass != null)  {
             JavaField[] fields = weakReferenceClass.getFieldsForInstance();
             for (int i = 0; i < fields.length; i++) {
                 if ("referent".equals(fields[i].getName())) {