OpenJDK / amber / amber
changeset 56873:a1b8e9c3de61 patterns
Automatic merge with patterns-stage-1
author | mcimadamore |
---|---|
date | Thu, 20 Jun 2019 22:06:48 +0200 |
parents | 91e02ad382d2 af2b0c9d2769 |
children | 5137dd14728a f6a80788dc08 |
files | |
diffstat | 134 files changed, 2841 insertions(+), 720 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Mon Jun 17 17:18:22 2019 +0200 +++ b/.hgtags Thu Jun 20 22:06:48 2019 +0200 @@ -563,3 +563,6 @@ b034d2dee5fc93d42a81b65e58ce3f91e42586ff jdk-13+23 7e2238451585029680f126ccbb46d01f2ff5607f jdk-13+24 22b3b7983adab54e318f75aeb94471f7a4429c1e jdk-14+0 +22b3b7983adab54e318f75aeb94471f7a4429c1e jdk-13+25 +2f4e214781a1d597ed36bf5a36f20928c6c82996 jdk-14+1 +43627549a488b7d0b4df8fad436e36233df89877 jdk-14+2
--- a/make/autoconf/build-aux/config.guess Mon Jun 17 17:18:22 2019 +0200 +++ b/make/autoconf/build-aux/config.guess Thu Jun 20 22:06:48 2019 +0200 @@ -63,7 +63,7 @@ # Test and fix wsl echo $OUT | grep x86_64-unknown-linux-gnu > /dev/null 2> /dev/null if test $? = 0; then - uname -r | grep Microsoft > /dev/null 2> /dev/null + uname -r | grep -i microsoft > /dev/null 2> /dev/null if test $? = 0; then OUT="x86_64-pc-wsl" fi
--- a/make/conf/jib-profiles.js Mon Jun 17 17:18:22 2019 +0200 +++ b/make/conf/jib-profiles.js Thu Jun 20 22:06:48 2019 +0200 @@ -1041,7 +1041,7 @@ // build_number: "b07", // file: "bundles/jcov-3_0.zip", organization: common.organization, - revision: "3.0-57-support+1.0", + revision: "3.0-58-support+1.0", ext: "zip", environment_name: "JCOV_HOME", },
--- a/make/data/jdwp/jdwp.spec Mon Jun 17 17:18:22 2019 +0200 +++ b/make/data/jdwp/jdwp.spec Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2019, 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 @@ -602,7 +602,7 @@ (Command Signature=1 "Returns the JNI signature of a reference type. " "JNI signature formats are described in the " - "<a href=\"http://java.sun.com/products/jdk/1.2/docs/guide/jni/index.html\">Java Native Inteface Specification</a>" + "<a href=\"../jni/index.html\">Java Native Interface Specification</a>" "<p> "For primitive classes " "the returned signature is the signature of the corresponding primitive "
--- a/make/jdk/src/classes/build/tools/generatecacerts/GenerateCacerts.java Mon Jun 17 17:18:22 2019 +0200 +++ b/make/jdk/src/classes/build/tools/generatecacerts/GenerateCacerts.java Thu Jun 20 22:06:48 2019 +0200 @@ -25,12 +25,23 @@ package build.tools.generatecacerts; +import java.io.DataOutputStream; import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; import java.nio.file.Files; import java.nio.file.Path; -import java.security.KeyStore; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; /** * Generate cacerts @@ -39,23 +50,99 @@ */ public class GenerateCacerts { public static void main(String[] args) throws Exception { - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(null, null); - CertificateFactory cf = CertificateFactory.getInstance("X509"); - Files.list(Path.of(args[0])) - .filter(p -> !p.getFileName().toString().equals("README")) - .forEach(p -> { - try { - String alias = p.getFileName().toString() + " [jdk]"; - try (InputStream fis = Files.newInputStream(p)) { - ks.setCertificateEntry(alias, cf.generateCertificate(fis)); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - }); try (FileOutputStream fos = new FileOutputStream(args[1])) { - ks.store(fos, "changeit".toCharArray()); + store(args[0], fos, "changeit".toCharArray()); } } + + // The following code are copied from JavaKeyStore.java. + + private static final int MAGIC = 0xfeedfeed; + private static final int VERSION_2 = 0x02; + + // This method is a simplified version of JavaKeyStore::engineStore. + // A new "dir" argument is added. All cert names in "dir" is collected into + // a sorted array. Each cert is stored with a creation date set to its + // notBefore value. Thus the output is determined as long as the certs + // are the same. + public static void store(String dir, OutputStream stream, char[] password) + throws IOException, NoSuchAlgorithmException, CertificateException + { + byte[] encoded; // the certificate encoding + CertificateFactory cf = CertificateFactory.getInstance("X509"); + + MessageDigest md = getPreKeyedHash(password); + DataOutputStream dos + = new DataOutputStream(new DigestOutputStream(stream, md)); + + dos.writeInt(MAGIC); + // always write the latest version + dos.writeInt(VERSION_2); + + // All file names in dir sorted. + // README is excluded. Name starting with "." excluded. + List<String> entries = Files.list(Path.of(dir)) + .map(p -> p.getFileName().toString()) + .filter(s -> !s.equals("README") && !s.startsWith(".")) + .collect(Collectors.toList()); + + entries.sort(String::compareTo); + + dos.writeInt(entries.size()); + + for (String entry : entries) { + + String alias = entry + " [jdk]"; + X509Certificate cert; + try (InputStream fis = Files.newInputStream(Path.of(dir, entry))) { + cert = (X509Certificate) cf.generateCertificate(fis); + } + + dos.writeInt(2); + + // Write the alias + dos.writeUTF(alias); + + // Write the (entry creation) date, which is notBefore of the cert + dos.writeLong(cert.getNotBefore().getTime()); + + // Write the trusted certificate + encoded = cert.getEncoded(); + dos.writeUTF(cert.getType()); + dos.writeInt(encoded.length); + dos.write(encoded); + } + + /* + * Write the keyed hash which is used to detect tampering with + * the keystore (such as deleting or modifying key or + * certificate entries). + */ + byte[] digest = md.digest(); + + dos.write(digest); + dos.flush(); + } + + private static MessageDigest getPreKeyedHash(char[] password) + throws NoSuchAlgorithmException, UnsupportedEncodingException + { + + MessageDigest md = MessageDigest.getInstance("SHA"); + byte[] passwdBytes = convertToBytes(password); + md.update(passwdBytes); + Arrays.fill(passwdBytes, (byte) 0x00); + md.update("Mighty Aphrodite".getBytes("UTF8")); + return md; + } + + private static byte[] convertToBytes(char[] password) { + int i, j; + byte[] passwdBytes = new byte[password.length * 2]; + for (i=0, j=0; i<password.length; i++) { + passwdBytes[j++] = (byte)(password[i] >> 8); + passwdBytes[j++] = (byte)password[i]; + } + return passwdBytes; + } }
--- a/src/hotspot/cpu/aarch64/aarch64.ad Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/cpu/aarch64/aarch64.ad Thu Jun 20 22:06:48 2019 +0200 @@ -14255,7 +14255,7 @@ format %{ "fcmps $src1, 0.0" %} ins_encode %{ - __ fcmps(as_FloatRegister($src1$$reg), 0.0D); + __ fcmps(as_FloatRegister($src1$$reg), 0.0); %} ins_pipe(pipe_class_compare); @@ -14284,7 +14284,7 @@ format %{ "fcmpd $src1, 0.0" %} ins_encode %{ - __ fcmpd(as_FloatRegister($src1$$reg), 0.0D); + __ fcmpd(as_FloatRegister($src1$$reg), 0.0); %} ins_pipe(pipe_class_compare); @@ -14360,7 +14360,7 @@ Label done; FloatRegister s1 = as_FloatRegister($src1$$reg); Register d = as_Register($dst$$reg); - __ fcmps(s1, 0.0D); + __ fcmps(s1, 0.0); // installs 0 if EQ else -1 __ csinvw(d, zr, zr, Assembler::EQ); // keeps -1 if less or unordered else installs 1 @@ -14387,7 +14387,7 @@ Label done; FloatRegister s1 = as_FloatRegister($src1$$reg); Register d = as_Register($dst$$reg); - __ fcmpd(s1, 0.0D); + __ fcmpd(s1, 0.0); // installs 0 if EQ else -1 __ csinvw(d, zr, zr, Assembler::EQ); // keeps -1 if less or unordered else installs 1
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -276,7 +276,7 @@ unsigned get(int msb = 31, int lsb = 0) { int nbits = msb - lsb + 1; unsigned mask = ((1U << nbits) - 1) << lsb; - assert_cond(bits & mask == mask); + assert_cond((bits & mask) == mask); return (insn & mask) >> lsb; } @@ -2644,7 +2644,7 @@ // RBIT only allows T8B and T16B but encodes them oddly. Argh... void rbit(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) { assert((ASSERTION), MSG); - _rbit(Vd, SIMD_Arrangement(T & 1 | 0b010), Vn); + _rbit(Vd, SIMD_Arrangement((T & 1) | 0b010), Vn); } #undef ASSERTION
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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. * @@ -1078,8 +1078,8 @@ // Assembler::EQ does not permit unordered branches, so we add // another branch here. Likewise, Assembler::NE does not permit // ordered branches. - if (is_unordered && op->cond() == lir_cond_equal - || !is_unordered && op->cond() == lir_cond_notEqual) + if ((is_unordered && op->cond() == lir_cond_equal) + || (!is_unordered && op->cond() == lir_cond_notEqual)) __ br(Assembler::VS, *(op->ublock()->label())); switch(op->cond()) { case lir_cond_equal: acond = Assembler::EQ; break; @@ -1789,18 +1789,22 @@ switch (code) { case lir_add: __ fadds (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; case lir_sub: __ fsubs (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; + case lir_mul_strictfp: // fall through case lir_mul: __ fmuls (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; + case lir_div_strictfp: // fall through case lir_div: __ fdivs (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break; default: ShouldNotReachHere(); } } else if (left->is_double_fpu()) { if (right->is_double_fpu()) { - // cpu register - cpu register + // fpu register - fpu register switch (code) { case lir_add: __ faddd (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; case lir_sub: __ fsubd (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; + case lir_mul_strictfp: // fall through case lir_mul: __ fmuld (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; + case lir_div_strictfp: // fall through case lir_div: __ fdivd (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break; default: ShouldNotReachHere();
--- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, 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. * @@ -426,7 +426,7 @@ tmp = new_register(T_DOUBLE); } - arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), NULL); + arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), x->is_strictfp()); set_result(x, round_item(reg)); }
--- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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. * @@ -768,11 +768,13 @@ extern "C" void pf(unsigned long sp, unsigned long fp, unsigned long pc, unsigned long bcx, unsigned long thread) { - RegisterMap map((JavaThread*)thread, false); if (!reg_map) { - reg_map = (RegisterMap*)os::malloc(sizeof map, mtNone); + reg_map = NEW_C_HEAP_OBJ(RegisterMap, mtNone); + ::new (reg_map) RegisterMap((JavaThread*)thread, false); + } else { + *reg_map = RegisterMap((JavaThread*)thread, false); } - memcpy(reg_map, &map, sizeof map); + { CodeBlob *cb = CodeCache::find_blob((address)pc); if (cb && cb->frame_size())
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -38,8 +38,6 @@ protected: protected: - using MacroAssembler::call_VM_leaf_base; - // Interpreter specific version of call_VM_base using MacroAssembler::call_VM_leaf_base;
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -2681,7 +2681,7 @@ if ((offset & (size-1)) && offset >= (1<<8)) { add(tmp, base, offset & ((1<<12)-1)); base = tmp; - offset &= -1<<12; + offset &= -1u<<12; } if (offset >= (1<<12) * size) {
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_log.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_log.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -286,7 +286,7 @@ frecpe(vtmp5, vtmp5, S); // vtmp5 ~= 1/vtmp5 lsr(tmp2, rscratch1, 48); movz(tmp4, 0x77f0, 48); - fmovd(vtmp4, 1.0d); + fmovd(vtmp4, 1.0); movz(tmp1, INF_OR_NAN_PREFIX, 48); bfm(tmp4, rscratch1, 0, 51); // tmp4 = 0x77F0 << 48 | mantissa(X) // vtmp1 = AS_DOUBLE_BITS(0x77F0 << 48 | mantissa(X)) == mx @@ -358,7 +358,7 @@ br(GE, DONE); cmp(rscratch1, tmp2); br(NE, CHECKED_CORNER_CASES); - fmovd(v0, 0.0d); + fmovd(v0, 0.0); } bind(DONE); ret(lr);
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -381,11 +381,11 @@ } block_comment("nx calculation with unrolled while(tx[nx-1]==zeroA) nx--;"); { - fcmpd(v26, 0.0d); // if NE then jx == 2. else it's 1 or 0 + fcmpd(v26, 0.0); // if NE then jx == 2. else it's 1 or 0 add(iqBase, sp, 480); // base of iq[] fmuld(v3, v26, v10); br(NE, NX_SET); - fcmpd(v7, 0.0d); // v7 == 0 => jx = 0. Else jx = 1 + fcmpd(v7, 0.0); // v7 == 0 => jx = 0. Else jx = 1 csetw(jx, NE); } bind(NX_SET); @@ -696,7 +696,7 @@ cmpw(jv, zr); addw(tmp4, jx, 4); // tmp4 = m = jx + jk = jx + 4. jx is in {0,1,2} so m is in [4,5,6] cselw(jv, jv, zr, GE); - fmovd(v26, 0.0d); + fmovd(v26, 0.0); addw(tmp5, jv, 1); // jv+1 subsw(j, jv, jx); add(qBase, sp, 320); // base of q[] @@ -819,8 +819,8 @@ movw(jz, 4); fmovd(v17, i); // v17 = twon24 fmovd(v30, tmp5); // 2^q0 - fmovd(v21, 0.125d); - fmovd(v20, 8.0d); + fmovd(v21, 0.125); + fmovd(v20, 8.0); fmovd(v22, tmp4); // 2^-q0 block_comment("recompute loop"); { @@ -877,7 +877,7 @@ lsr(ih, tmp2, 23); // ih = iq[z-1] >> 23 b(Q0_ZERO_CMP_DONE); bind(Q0_ZERO_CMP_LT); - fmovd(v4, 0.5d); + fmovd(v4, 0.5); fcmpd(v18, v4); cselw(ih, zr, ih, LT); // if (z<0.5) ih = 0 } @@ -924,7 +924,7 @@ br(NE, IH_HANDLED); block_comment("if(ih==2) {"); { - fmovd(v25, 1.0d); + fmovd(v25, 1.0); fsubd(v18, v25, v18); // z = one - z; cbzw(rscratch2, IH_HANDLED); fsubd(v18, v18, v30); // z -= scalbnA(one,q0); @@ -932,7 +932,7 @@ } bind(IH_HANDLED); // check if recomputation is needed - fcmpd(v18, 0.0d); + fcmpd(v18, 0.0); br(NE, RECOMP_CHECK_DONE_NOT_ZERO); block_comment("if(z==zeroB) {"); { @@ -994,7 +994,7 @@ } bind(RECOMP_CHECK_DONE); // chop off zero terms - fcmpd(v18, 0.0d); + fcmpd(v18, 0.0); br(EQ, Z_IS_ZERO); block_comment("else block of if(z==0.0) {"); { @@ -1053,7 +1053,7 @@ movw(tmp2, zr); // tmp2 will keep jz - i == 0 at start bind(COMP_FOR); // for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; - fmovd(v30, 0.0d); + fmovd(v30, 0.0); add(tmp5, qBase, i, LSL, 3); // address of q[i+k] for k==0 movw(tmp3, 4); movw(tmp4, zr); // used as k @@ -1081,7 +1081,7 @@ // remember prec == 2 block_comment("for (i=jz;i>=0;i--) fw += fq[i];"); { - fmovd(v4, 0.0d); + fmovd(v4, 0.0); mov(i, jz); bind(FW_FOR1); ldrd(v1, Address(rscratch2, i, Address::lsl(3))); @@ -1319,7 +1319,7 @@ ld1(C1, C2, C3, C4, T1D, Address(rscratch2)); // load C1..C3\4 block_comment("calculate r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))))"); { fmaddd(r, z, C6, C5); - fmovd(half, 0.5d); + fmovd(half, 0.5); fmaddd(r, z, r, C4); fmuld(y, x, y); fmaddd(r, z, r, C3); @@ -1329,7 +1329,7 @@ fmaddd(r, z, r, C1); // r = C1+z(C2+z(C4+z(C5+z*C6))) } // need to multiply r by z to have "final" r value - fmovd(one, 1.0d); + fmovd(one, 1.0); cmp(ix, rscratch1); br(GT, IX_IS_LARGE); block_comment("if(ix < 0x3FD33333) return one - (0.5*z - (z*r - x*y))"); { @@ -1352,7 +1352,7 @@ b(QX_SET); bind(SET_QX_CONST); block_comment("if(ix > 0x3fe90000) qx = 0.28125;"); { - fmovd(qx, 0.28125d); + fmovd(qx, 0.28125); } bind(QX_SET); fnmsub(C6, x, r, y); // z*r - xy @@ -1443,7 +1443,7 @@ block_comment("kernel_sin/kernel_cos: if(ix<0x3e400000) {<fast return>}"); { bind(TINY_X); if (isCos) { - fmovd(v0, 1.0d); + fmovd(v0, 1.0); } ret(lr); }
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -177,7 +177,7 @@ if (FILE *f = fopen("/proc/cpuinfo", "r")) { char buf[128], *p; while (fgets(buf, sizeof (buf), f) != NULL) { - if (p = strchr(buf, ':')) { + if ((p = strchr(buf, ':')) != NULL) { long v = strtol(p+1, NULL, 0); if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) { _cpu = v;
--- a/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -40,7 +40,9 @@ { template<typename I, typename D> D add_and_fetch(I add_value, D volatile* dest, atomic_memory_order order) const { - return __sync_add_and_fetch(dest, add_value); + D res = __atomic_add_fetch(dest, add_value, __ATOMIC_RELEASE); + FULL_MEM_BARRIER; + return res; } };
--- a/src/hotspot/os_cpu/linux_aarch64/copy_linux_aarch64.s Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/os_cpu/linux_aarch64/copy_linux_aarch64.s Thu Jun 20 22:06:48 2019 +0200 @@ -159,7 +159,7 @@ blo bwd_copy_drain bwd_copy_again: - prfm pldl1keep, [s, #-256] + prfum pldl1keep, [s, #-256] stp t0, t1, [d, #-16] ldp t0, t1, [s, #-16] stp t2, t3, [d, #-32]
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -83,19 +83,13 @@ #define REG_SP REG_RSP #define REG_PC REG_RIP #define REG_FP REG_RBP -#define SPELL_REG_SP "rsp" -#define SPELL_REG_FP "rbp" #else #define REG_FP 29 #define REG_LR 30 - -#define SPELL_REG_SP "sp" -#define SPELL_REG_FP "x29" #endif -address os::current_stack_pointer() { - register void *esp __asm__ (SPELL_REG_SP); - return (address) esp; +NOINLINE address os::current_stack_pointer() { + return (address)__builtin_frame_address(0); } char* os::non_memory_address_word() { @@ -230,23 +224,8 @@ #endif } -intptr_t* _get_previous_fp() { - register intptr_t **fp __asm__ (SPELL_REG_FP); - - // fp is for this frame (_get_previous_fp). We want the fp for the - // caller of os::current_frame*(), so go up two frames. However, for - // optimized builds, _get_previous_fp() will be inlined, so only go - // up 1 frame in that case. - #ifdef _NMT_NOINLINE_ - return **(intptr_t***)fp; - #else - return *fp; - #endif -} - - -frame os::current_frame() { - intptr_t* fp = _get_previous_fp(); +NOINLINE frame os::current_frame() { + intptr_t *fp = *(intptr_t **)__builtin_frame_address(0); frame myframe((intptr_t*)os::current_stack_pointer(), (intptr_t*)fp, CAST_FROM_FN_PTR(address, os::current_frame)); @@ -259,12 +238,6 @@ } // Utility functions - -// From IA32 System Programming Guide -enum { - trap_page_fault = 0xE -}; - #ifdef BUILTIN_SIM extern "C" void Fetch32PFI () ; extern "C" void Fetch32Resume () ; @@ -667,42 +640,42 @@ return 0; } - void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { + void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { if (from > to) { - jshort *end = from + count; + const jshort *end = from + count; while (from < end) *(to++) = *(from++); } else if (from < to) { - jshort *end = from; + const jshort *end = from; from += count - 1; to += count - 1; while (from >= end) *(to--) = *(from--); } } - void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) { + void _Copy_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { if (from > to) { - jint *end = from + count; + const jint *end = from + count; while (from < end) *(to++) = *(from++); } else if (from < to) { - jint *end = from; + const jint *end = from; from += count - 1; to += count - 1; while (from >= end) *(to--) = *(from--); } } - void _Copy_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) { + void _Copy_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { if (from > to) { - jlong *end = from + count; + const jlong *end = from + count; while (from < end) os::atomic_copy64(from++, to++); } else if (from < to) { - jlong *end = from; + const jlong *end = from; from += count - 1; to += count - 1; while (from >= end) @@ -710,22 +683,22 @@ } } - void _Copy_arrayof_conjoint_bytes(HeapWord* from, + void _Copy_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { memmove(to, from, count); } - void _Copy_arrayof_conjoint_jshorts(HeapWord* from, + void _Copy_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { memmove(to, from, count * 2); } - void _Copy_arrayof_conjoint_jints(HeapWord* from, + void _Copy_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { memmove(to, from, count * 4); } - void _Copy_arrayof_conjoint_jlongs(HeapWord* from, + void _Copy_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { memmove(to, from, count * 8);
--- a/src/hotspot/share/asm/assembler.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/asm/assembler.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -313,25 +313,22 @@ bool MacroAssembler::uses_implicit_null_check(void* address) { // Exception handler checks the nmethod's implicit null checks table // only when this method returns false. - intptr_t int_address = reinterpret_cast<intptr_t>(address); - intptr_t cell_header_size = Universe::heap()->cell_header_size(); - size_t region_size = os::vm_page_size() + cell_header_size; + uintptr_t addr = reinterpret_cast<uintptr_t>(address); + uintptr_t page_size = (uintptr_t)os::vm_page_size(); #ifdef _LP64 if (UseCompressedOops && CompressedOops::base() != NULL) { // A SEGV can legitimately happen in C2 code at address // (heap_base + offset) if Matcher::narrow_oop_use_complex_address // is configured to allow narrow oops field loads to be implicitly // null checked - intptr_t start = ((intptr_t)CompressedOops::base()) - cell_header_size; - intptr_t end = start + region_size; - if (int_address >= start && int_address < end) { + uintptr_t start = (uintptr_t)CompressedOops::base(); + uintptr_t end = start + page_size; + if (addr >= start && addr < end) { return true; } } #endif - intptr_t start = -cell_header_size; - intptr_t end = start + region_size; - return int_address >= start && int_address < end; + return addr < page_size; } bool MacroAssembler::needs_explicit_null_check(intptr_t offset) { @@ -341,12 +338,8 @@ // with -1. Another example is GraphBuilder::access_field(...) which uses -1 as placeholder // for offsets to be patched in later. The -1 there means the offset is not yet known // and may lie outside of the zero-trapping page, and thus we need to ensure we're forcing - // an explicit null check for -1, even if it may otherwise be in the range - // [-cell_header_size, os::vm_page_size). - // TODO: Find and replace all relevant uses of -1 with a reasonably named constant. - if (offset == -1) return true; + // an explicit null check for -1. - // Check if offset is outside of [-cell_header_size, os::vm_page_size) - return offset < -Universe::heap()->cell_header_size() || - offset >= os::vm_page_size(); + // Check if offset is outside of [0, os::vm_page_size()] + return offset < 0 || offset >= os::vm_page_size(); }
--- a/src/hotspot/share/classfile/classFileParser.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/classfile/classFileParser.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -4958,6 +4958,7 @@ bool ClassFileParser::verify_unqualified_name(const char* name, unsigned int length, int type) { + if (length == 0) return false; // Must have at least one char. for (const char* p = name; p != name + length; p++) { switch(*p) { case '.': @@ -5107,7 +5108,7 @@ int newlen = c - (char*) signature; bool legal = verify_unqualified_name(signature, newlen, LegalClass); if (!legal) { - classfile_parse_error("Class name contains illegal character " + classfile_parse_error("Class name is empty or contains illegal character " "in descriptor in class file %s", CHECK_0); return NULL;
--- a/src/hotspot/share/classfile/systemDictionary.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/classfile/systemDictionary.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -2861,14 +2861,17 @@ } TableStatistics SystemDictionary::placeholders_statistics() { + MutexLocker ml(SystemDictionary_lock); return placeholders()->statistics_calculate(); } TableStatistics SystemDictionary::loader_constraints_statistics() { + MutexLocker ml(SystemDictionary_lock); return constraints()->statistics_calculate(); } TableStatistics SystemDictionary::protection_domain_cache_statistics() { + MutexLocker ml(SystemDictionary_lock); return pd_cache_table()->statistics_calculate(); }
--- a/src/hotspot/share/classfile/verifier.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/classfile/verifier.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -165,22 +165,28 @@ PerfClassTraceTime::CLASS_VERIFY); // If the class should be verified, first see if we can use the split - // verifier. If not, or if verification fails and FailOverToOldVerifier - // is set, then call the inference verifier. + // verifier. If not, or if verification fails and can failover, then + // call the inference verifier. Symbol* exception_name = NULL; const size_t message_buffer_len = klass->name()->utf8_length() + 1024; char* message_buffer = NULL; char* exception_message = NULL; - bool can_failover = FailOverToOldVerifier && - klass->major_version() < NOFAILOVER_MAJOR_VERSION; - log_info(class, init)("Start class verification for: %s", klass->external_name()); if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) { ClassVerifier split_verifier(klass, THREAD); split_verifier.verify_class(THREAD); exception_name = split_verifier.result(); - if (can_failover && !HAS_PENDING_EXCEPTION && + + // If DumpSharedSpaces is set then don't fall back to the old verifier on + // verification failure. If a class fails verification with the split verifier, + // it might fail the CDS runtime verifier constraint check. In that case, we + // don't want to share the class. We only archive classes that pass the split + // verifier. + bool can_failover = !DumpSharedSpaces && + klass->major_version() < NOFAILOVER_MAJOR_VERSION; + + if (can_failover && !HAS_PENDING_EXCEPTION && // Split verifier doesn't set PENDING_EXCEPTION for failure (exception_name == vmSymbols::java_lang_VerifyError() || exception_name == vmSymbols::java_lang_ClassFormatError())) { log_info(verification)("Fail over class verification to old verifier for: %s", klass->external_name());
--- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -391,8 +391,6 @@ #endif // !PRODUCT HeapWord* G1BlockOffsetTablePart::initialize_threshold_raw() { - assert(!G1CollectedHeap::heap()->is_in_reserved(_bot->_offset_array), - "just checking"); _next_offset_index = _bot->index_for_raw(_space->bottom()); _next_offset_index++; _next_offset_threshold = @@ -401,8 +399,6 @@ } void G1BlockOffsetTablePart::zero_bottom_entry_raw() { - assert(!G1CollectedHeap::heap()->is_in_reserved(_bot->_offset_array), - "just checking"); size_t bottom_index = _bot->index_for_raw(_space->bottom()); assert(_bot->address_for_index_raw(bottom_index) == _space->bottom(), "Precondition of call"); @@ -410,8 +406,6 @@ } HeapWord* G1BlockOffsetTablePart::initialize_threshold() { - assert(!G1CollectedHeap::heap()->is_in_reserved(_bot->_offset_array), - "just checking"); _next_offset_index = _bot->index_for(_space->bottom()); _next_offset_index++; _next_offset_threshold =
--- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -52,7 +52,7 @@ // Array for keeping offsets for retrieving object start fast given an // address. - u_char* _offset_array; // byte array keeping backwards offsets + volatile u_char* _offset_array; // byte array keeping backwards offsets void check_offset(size_t offset, const char* msg) const { assert(offset <= BOTConstants::N_words, @@ -64,10 +64,7 @@ // For performance these have to devolve to array accesses in product builds. inline u_char offset_array(size_t index) const; - void set_offset_array_raw(size_t index, u_char offset) { - _offset_array[index] = offset; - } - + inline void set_offset_array_raw(size_t index, u_char offset); inline void set_offset_array(size_t index, u_char offset); inline void set_offset_array(size_t index, HeapWord* high, HeapWord* low);
--- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -29,6 +29,7 @@ #include "gc/g1/heapRegion.hpp" #include "gc/shared/memset_with_concurrent_readers.hpp" #include "gc/shared/space.hpp" +#include "runtime/atomic.hpp" inline HeapWord* G1BlockOffsetTablePart::block_start(const void* addr) { if (addr >= _space->bottom() && addr < _space->end()) { @@ -51,7 +52,11 @@ u_char G1BlockOffsetTable::offset_array(size_t index) const { check_index(index, "index out of range"); - return _offset_array[index]; + return Atomic::load(&_offset_array[index]); +} + +void G1BlockOffsetTable::set_offset_array_raw(size_t index, u_char offset) { + Atomic::store(offset, &_offset_array[index]); } void G1BlockOffsetTable::set_offset_array(size_t index, u_char offset) { @@ -71,7 +76,8 @@ check_index(right, "right index out of range"); assert(left <= right, "indexes out of order"); size_t num_cards = right - left + 1; - memset_with_concurrent_readers(&_offset_array[left], offset, num_cards); + memset_with_concurrent_readers + (const_cast<u_char*> (&_offset_array[left]), offset, num_cards); } // Variant of index_for that does not check the index for validity.
--- a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -308,7 +308,6 @@ virtual bool escape_add_to_con_graph(ConnectionGraph* conn_graph, PhaseGVN* gvn, Unique_Node_List* delayed_worklist, Node* n, uint opcode) const { return false; } virtual bool escape_add_final_edges(ConnectionGraph* conn_graph, PhaseGVN* gvn, Node* n, uint opcode) const { return false; } virtual bool escape_has_out_with_unsafe_object(Node* n) const { return false; } - virtual bool escape_is_barrier_node(Node* n) const { return false; } virtual bool matcher_find_shared_visit(Matcher* matcher, Matcher::MStack& mstack, Node* n, uint opcode, bool& mem_op, int& mem_addr_idx) const { return false; }; virtual bool matcher_find_shared_post_visit(Matcher* matcher, Node* n, uint opcode) const { return false; };
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -534,11 +534,6 @@ virtual size_t obj_size(oop obj) const; - // Cells are memory slices allocated by the allocator. Objects are initialized - // in cells. The cell itself may have a header, found at a negative offset of - // oops. Usually, the size of the cell header is 0, but it may be larger. - virtual ptrdiff_t cell_header_size() const { return 0; } - // Non product verification and debugging. #ifndef PRODUCT // Support for PromotionFailureALot. Return true if it's time to cause a
--- a/src/hotspot/share/gc/shared/gcLocker.inline.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shared/gcLocker.inline.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -26,7 +26,7 @@ #define SHARE_GC_SHARED_GCLOCKER_INLINE_HPP #include "gc/shared/gcLocker.hpp" -#include "runtime/thread.hpp" +#include "runtime/thread.inline.hpp" void GCLocker::lock_critical(JavaThread* thread) { if (!thread->in_critical()) {
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -1194,10 +1194,6 @@ } -bool ShenandoahBarrierSetC2::escape_is_barrier_node(Node* n) const { - return n->Opcode() == Op_ShenandoahLoadReferenceBarrier; -} - bool ShenandoahBarrierSetC2::matcher_find_shared_post_visit(Matcher* matcher, Node* n, uint opcode) const { switch (opcode) { case Op_ShenandoahCompareAndExchangeP:
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -144,7 +144,6 @@ virtual bool escape_add_to_con_graph(ConnectionGraph* conn_graph, PhaseGVN* gvn, Unique_Node_List* delayed_worklist, Node* n, uint opcode) const; virtual bool escape_add_final_edges(ConnectionGraph* conn_graph, PhaseGVN* gvn, Node* n, uint opcode) const; virtual bool escape_has_out_with_unsafe_object(Node* n) const; - virtual bool escape_is_barrier_node(Node* n) const; virtual bool matcher_find_shared_post_visit(Matcher* matcher, Node* n, uint opcode) const; virtual bool matcher_is_store_load_barrier(Node* x, uint xop) const;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * 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. + * + */ + +#include "precompiled.hpp" + +#include "gc/shenandoah/shenandoahConcurrentRoots.hpp" +#include "gc/shenandoah/shenandoahHeap.inline.hpp" + +bool ShenandoahConcurrentRoots::can_do_concurrent_roots() { + // Don't support traversal GC at this moment + return !ShenandoahHeap::heap()->is_concurrent_traversal_in_progress(); +} + +bool ShenandoahConcurrentRoots::should_do_concurrent_roots() { + ShenandoahHeap* const heap = ShenandoahHeap::heap(); + bool stw_gc_in_progress = heap->is_full_gc_in_progress() || + heap->is_degenerated_gc_in_progress(); + return can_do_concurrent_roots() && + !stw_gc_in_progress; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * 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. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCONCURRENTROOTS_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHCONCURRENTROOTS_HPP + +#include "memory/allocation.hpp" + +class ShenandoahConcurrentRoots : public AllStatic { +public: + // Can GC settings allow concurrent root processing + static bool can_do_concurrent_roots(); + // If current GC cycle can process roots concurrently + static bool should_do_concurrent_roots(); +}; + + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCONCURRENTROOTS_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -377,6 +377,9 @@ // Complete marking under STW, and start evacuation heap->vmop_entry_final_mark(); + // Evacuate concurrent roots + heap->entry_roots(); + // Final mark might have reclaimed some immediate garbage, kick cleanup to reclaim // the space. This would be the last action if there is nothing to evacuate. heap->entry_cleanup();
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -38,6 +38,7 @@ #include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" +#include "gc/shenandoah/shenandoahConcurrentRoots.hpp" #include "gc/shenandoah/shenandoahControlThread.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" @@ -1071,9 +1072,11 @@ DerivedPointerTable::clear(); #endif assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped"); - { - ShenandoahRootEvacuator rp(workers()->active_workers(), ShenandoahPhaseTimings::init_evac); + // Include concurrent roots if current cycle can not process those roots concurrently + ShenandoahRootEvacuator rp(workers()->active_workers(), + ShenandoahPhaseTimings::init_evac, + !ShenandoahConcurrentRoots::should_do_concurrent_roots()); ShenandoahEvacuateUpdateRootsTask roots_task(&rp); workers()->run_task(&roots_task); } @@ -1276,10 +1279,15 @@ Stack<oop,mtGC> oop_stack; - // First, we process all GC roots. This populates the work stack with initial objects. - ShenandoahAllRootScanner rp(1, ShenandoahPhaseTimings::_num_phases); + // First, we process GC roots according to current GC cycle. This populates the work stack with initial objects. + ShenandoahHeapIterationRootScanner rp; ObjectIterateScanRootClosure oops(&_aux_bit_map, &oop_stack); - rp.roots_do_unchecked(&oops); + + if (unload_classes()) { + rp.strong_roots_do(&oops); + } else { + rp.roots_do(&oops); + } // Work through the oop stack to traverse heap. while (! oop_stack.is_empty()) { @@ -1512,7 +1520,11 @@ } if (ShenandoahVerify) { - verifier()->verify_roots_no_forwarded(); + if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { + verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::JNIHandleRoots); + } else { + verifier()->verify_roots_no_forwarded(); + } verifier()->verify_during_evacuation(); } } else { @@ -1573,6 +1585,30 @@ free_set()->recycle_trash(); } +class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask { +private: + ShenandoahJNIHandleRoots<true /*concurrent*/> _jni_roots; + +public: + ShenandoahConcurrentRootsEvacUpdateTask() : + AbstractGangTask("Shenandoah Evacuate/Update Concurrent Roots Task") { + } + + void work(uint worker_id) { + ShenandoahEvacOOMScope oom; + ShenandoahEvacuateUpdateRootsClosure cl; + _jni_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl); + } +}; + +void ShenandoahHeap::op_roots() { + if (is_evacuation_in_progress() && + ShenandoahConcurrentRoots::should_do_concurrent_roots()) { + ShenandoahConcurrentRootsEvacUpdateTask task; + workers()->run_task(&task); + } +} + void ShenandoahHeap::op_reset() { reset_mark_bitmap(); } @@ -2173,6 +2209,11 @@ concurrent_mark()->update_thread_roots(ShenandoahPhaseTimings::final_update_refs_roots); } + // Has to be done before cset is clear + if (ShenandoahVerify) { + verifier()->verify_roots_in_to_space(); + } + ShenandoahGCPhase final_update_refs(ShenandoahPhaseTimings::final_update_refs_recycle); trash_cset_regions(); @@ -2180,7 +2221,6 @@ set_update_refs_in_progress(false); if (ShenandoahVerify) { - verifier()->verify_roots_no_forwarded(); verifier()->verify_after_updaterefs(); } @@ -2550,6 +2590,22 @@ try_inject_alloc_failure(); op_updaterefs(); } + +void ShenandoahHeap::entry_roots() { + ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_roots); + + static const char* msg = "Concurrent roots processing"; + GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true); + EventMark em("%s", msg); + + ShenandoahWorkerScope scope(workers(), + ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(), + "concurrent root processing"); + + try_inject_alloc_failure(); + op_roots(); +} + void ShenandoahHeap::entry_cleanup() { ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_cleanup);
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -391,6 +391,7 @@ void entry_reset(); void entry_mark(); void entry_preclean(); + void entry_roots(); void entry_cleanup(); void entry_evac(); void entry_updaterefs(); @@ -414,6 +415,7 @@ void op_reset(); void op_mark(); void op_preclean(); + void op_roots(); void op_cleanup(); void op_conc_evac(); void op_stw_evac();
--- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -306,6 +306,7 @@ f(conc_mark, "Concurrent Marking") \ f(conc_termination, " Termination") \ f(conc_preclean, "Concurrent Precleaning") \ + f(conc_roots, "Concurrent Roots") \ f(conc_evac, "Concurrent Evacuation") \ f(conc_update_refs, "Concurrent Update Refs") \ f(conc_cleanup, "Concurrent Cleanup") \
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -71,10 +71,6 @@ _jvmti_root.oops_do(cl, worker_id); } -ShenandoahJNIHandleRoots::ShenandoahJNIHandleRoots() : - ShenandoahSerialRoot(&JNIHandles::oops_do, ShenandoahPhaseTimings::JNIRoots) { -} - ShenandoahThreadRoots::ShenandoahThreadRoots(bool is_par) : _is_par(is_par) { Threads::change_thread_claim_token(); } @@ -126,16 +122,6 @@ } } -ShenandoahClassLoaderDataRoots::ShenandoahClassLoaderDataRoots() { - ClassLoaderDataGraph::clear_claimed_marks(); -} - -void ShenandoahClassLoaderDataRoots::clds_do(CLDClosure* strong_clds, CLDClosure* weak_clds, uint worker_id) { - ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); - ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id); - ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds); -} - ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) : _heap(ShenandoahHeap::heap()), _phase(phase) { @@ -148,21 +134,22 @@ _heap->phase_timings()->record_workers_end(_phase); } -ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase) : +ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots) : ShenandoahRootProcessor(phase), _thread_roots(n_workers > 1), - _weak_roots(n_workers) { + _weak_roots(n_workers), + _include_concurrent_roots(include_concurrent_roots) { } void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) { MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations); CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong); - CLDToOopClosure* weak_clds = ShenandoahHeap::heap()->unload_classes() ? NULL : &clds; - AlwaysTrueClosure always_true; _serial_roots.oops_do(oops, worker_id); - _jni_roots.oops_do(oops, worker_id); + if (_include_concurrent_roots) { + _jni_roots.oops_do<OopClosure>(oops, worker_id); + } _thread_roots.oops_do(oops, NULL, worker_id); _cld_roots.clds_do(&clds, &clds, worker_id); @@ -201,3 +188,37 @@ _weak_roots.oops_do<AlwaysTrueClosure, OopClosure>(&always_true, oops, worker_id); _dedup_roots.oops_do(&always_true, oops, worker_id); } + + ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() : + ShenandoahRootProcessor(ShenandoahPhaseTimings::_num_phases), + _thread_roots(false /*is par*/) { + } + + void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) { + assert(Thread::current()->is_VM_thread(), "Only by VM thread"); + // Must use _claim_none to avoid interfering with concurrent CLDG iteration + CLDToOopClosure clds(oops, ClassLoaderData::_claim_none); + MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations); + ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL); + ResourceMark rm; + + _serial_roots.oops_do(oops, 0); + _jni_roots.oops_do(oops, 0); + _cld_roots.clds_do(&clds, &clds, 0); + _thread_roots.threads_do(&tc_cl, 0); + _code_roots.code_blobs_do(&code, 0); + } + + void ShenandoahHeapIterationRootScanner::strong_roots_do(OopClosure* oops) { + assert(Thread::current()->is_VM_thread(), "Only by VM thread"); + // Must use _claim_none to avoid interfering with concurrent CLDG iteration + CLDToOopClosure clds(oops, ClassLoaderData::_claim_none); + MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations); + ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL); + ResourceMark rm; + + _serial_roots.oops_do(oops, 0); + _jni_roots.oops_do(oops, 0); + _cld_roots.clds_do(&clds, NULL, 0); + _thread_roots.threads_do(&tc_cl, 0); + }
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -61,9 +61,15 @@ void oops_do(OopClosure* cl, uint worker_id); }; -class ShenandoahJNIHandleRoots : public ShenandoahSerialRoot { +template <bool CONCURRENT> +class ShenandoahJNIHandleRoots { +private: + OopStorage::ParState<CONCURRENT, false /* is_const */> _itr; public: ShenandoahJNIHandleRoots(); + + template <typename T> + void oops_do(T* cl, uint worker_id = 0); }; class ShenandoahThreadRoots { @@ -108,6 +114,7 @@ void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id); }; +template <bool SINGLE_THREADED> class ShenandoahClassLoaderDataRoots { public: ShenandoahClassLoaderDataRoots(); @@ -129,11 +136,11 @@ template <typename ITR> class ShenandoahRootScanner : public ShenandoahRootProcessor { private: - ShenandoahSerialRoots _serial_roots; - ShenandoahJNIHandleRoots _jni_roots; - ShenandoahClassLoaderDataRoots _cld_roots; - ShenandoahThreadRoots _thread_roots; - ShenandoahCodeCacheRoots<ITR> _code_roots; + ShenandoahSerialRoots _serial_roots; + ShenandoahThreadRoots _thread_roots; + ShenandoahCodeCacheRoots<ITR> _code_roots; + ShenandoahJNIHandleRoots<false /*concurrent*/ > _jni_roots; + ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots; public: ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); @@ -146,26 +153,42 @@ // roots when class unloading is disabled during this cycle void roots_do(uint worker_id, OopClosure* cl); void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); - // For heap object iteration - void roots_do_unchecked(OopClosure* cl); }; typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; +// This scanner is only for SH::object_iteration() and only supports single-threaded +// root scanning +class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor { +private: + ShenandoahSerialRoots _serial_roots; + ShenandoahThreadRoots _thread_roots; + ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; + ShenandoahClassLoaderDataRoots<true /*single threaded*/> _cld_roots; + ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; + +public: + ShenandoahHeapIterationRootScanner(); + + void roots_do(OopClosure* cl); + void strong_roots_do(OopClosure* cl); +}; + // Evacuate all roots at a safepoint class ShenandoahRootEvacuator : public ShenandoahRootProcessor { private: - ShenandoahSerialRoots _serial_roots; - ShenandoahJNIHandleRoots _jni_roots; - ShenandoahClassLoaderDataRoots _cld_roots; - ShenandoahThreadRoots _thread_roots; - ShenandoahWeakRoots _weak_roots; - ShenandoahStringDedupRoots _dedup_roots; + ShenandoahSerialRoots _serial_roots; + ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; + ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots; + ShenandoahThreadRoots _thread_roots; + ShenandoahWeakRoots _weak_roots; + ShenandoahStringDedupRoots _dedup_roots; ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; + bool _include_concurrent_roots; public: - ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase); + ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots); void roots_do(uint worker_id, OopClosure* oops); }; @@ -173,14 +196,14 @@ // Update all roots at a safepoint class ShenandoahRootUpdater : public ShenandoahRootProcessor { private: - ShenandoahSerialRoots _serial_roots; - ShenandoahJNIHandleRoots _jni_roots; - ShenandoahClassLoaderDataRoots _cld_roots; - ShenandoahThreadRoots _thread_roots; - ShenandoahWeakRoots _weak_roots; - ShenandoahStringDedupRoots _dedup_roots; + ShenandoahSerialRoots _serial_roots; + ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; + ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots; + ShenandoahThreadRoots _thread_roots; + ShenandoahWeakRoots _weak_roots; + ShenandoahStringDedupRoots _dedup_roots; ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; - const bool _update_code_cache; + const bool _update_code_cache; public: ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache); @@ -192,13 +215,13 @@ // Adjuster all roots at a safepoint during full gc class ShenandoahRootAdjuster : public ShenandoahRootProcessor { private: - ShenandoahSerialRoots _serial_roots; - ShenandoahJNIHandleRoots _jni_roots; - ShenandoahClassLoaderDataRoots _cld_roots; - ShenandoahThreadRoots _thread_roots; - ShenandoahWeakRoots _weak_roots; - ShenandoahStringDedupRoots _dedup_roots; - ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; + ShenandoahSerialRoots _serial_roots; + ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; + ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots; + ShenandoahThreadRoots _thread_roots; + ShenandoahWeakRoots _weak_roots; + ShenandoahStringDedupRoots _dedup_roots; + ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; public: ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase);
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -24,17 +24,58 @@ #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP +#include "classfile/classLoaderDataGraph.hpp" +#include "gc/shared/oopStorageParState.inline.hpp" #include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahRootProcessor.hpp" #include "gc/shenandoah/shenandoahTimingTracker.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" #include "memory/resourceArea.hpp" +#include "runtime/safepoint.hpp" + +template <bool CONCURRENT> +ShenandoahJNIHandleRoots<CONCURRENT>::ShenandoahJNIHandleRoots() : + _itr(JNIHandles::global_handles()) { +} + +template <bool CONCURRENT> +template <typename T> +void ShenandoahJNIHandleRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) { + if (CONCURRENT) { + _itr.oops_do(cl); + } else { + ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id); + _itr.oops_do(cl); + } +} template <typename IsAlive, typename KeepAlive> void ShenandoahWeakRoots::oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id) { _task.work<IsAlive, KeepAlive>(worker_id, is_alive, keep_alive); } +template <bool SINGLE_THREADED> +ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() { + if (!SINGLE_THREADED) { + ClassLoaderDataGraph::clear_claimed_marks(); + } +} + +template <bool SINGLE_THREADED> +void ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::clds_do(CLDClosure* strong_clds, CLDClosure* weak_clds, uint worker_id) { + if (SINGLE_THREADED) { + assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); + assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread"); + + ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds); + } else { + ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); + ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id); + ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds); + } +} + template <typename ITR> ShenandoahCodeCacheRoots<ITR>::ShenandoahCodeCacheRoots() { nmethod::oops_do_marking_prologue(); @@ -112,20 +153,6 @@ } template <typename ITR> -void ShenandoahRootScanner<ITR>::roots_do_unchecked(OopClosure* oops) { - CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong); - MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations); - ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL); - ResourceMark rm; - - _serial_roots.oops_do(oops, 0); - _jni_roots.oops_do(oops, 0); - _cld_roots.clds_do(&clds, &clds, 0); - _thread_roots.threads_do(&tc_cl, 0); - _code_roots.code_blobs_do(&code, 0); -} - -template <typename ITR> void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) { assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading"); ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
--- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -964,6 +964,44 @@ void do_oop(oop* p) { do_oop_work(p); } }; +class ShenandoahVerifyInToSpaceClosure : public OopClosure { +private: + template <class T> + void do_oop_work(T* p) { + T o = RawAccess<>::oop_load(p); + if (!CompressedOops::is_null(o)) { + oop obj = CompressedOops::decode_not_null(o); + ShenandoahHeap* heap = ShenandoahHeap::heap_no_check(); + + if (!heap->marking_context()->is_marked(obj)) { + ShenandoahAsserts::print_failure(ShenandoahAsserts::_safe_all, obj, p, NULL, + "Verify Roots In To-Space", "Should be marked", __FILE__, __LINE__); + } + + if (heap->in_collection_set(obj)) { + ShenandoahAsserts::print_failure(ShenandoahAsserts::_safe_all, obj, p, NULL, + "Verify Roots In To-Space", "Should not be in collection set", __FILE__, __LINE__); + } + + oop fwd = (oop) ShenandoahForwarding::get_forwardee_raw_unchecked(obj); + if (!oopDesc::equals_raw(obj, fwd)) { + ShenandoahAsserts::print_failure(ShenandoahAsserts::_safe_all, obj, p, NULL, + "Verify Roots In To-Space", "Should not be forwarded", __FILE__, __LINE__); + } + } + } + +public: + void do_oop(narrowOop* p) { do_oop_work(p); } + void do_oop(oop* p) { do_oop_work(p); } +}; + +void ShenandoahVerifier::verify_roots_in_to_space() { + ShenandoahRootVerifier verifier; + ShenandoahVerifyInToSpaceClosure cl; + verifier.oops_do(&cl); +} + void ShenandoahVerifier::verify_roots_no_forwarded() { ShenandoahRootVerifier verifier; ShenandoahVerifyNoForwared cl;
--- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -189,6 +189,7 @@ void verify_generic(VerifyOption option); // Roots should only contain to-space oops + void verify_roots_in_to_space(); void verify_roots_no_forwarded(); void verify_roots_no_forwarded_except(ShenandoahRootVerifier::RootTypes types); };
--- a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -30,6 +30,7 @@ uint ShenandoahWorkerPolicy::_prev_par_marking = 0; uint ShenandoahWorkerPolicy::_prev_conc_marking = 0; uint ShenandoahWorkerPolicy::_prev_conc_evac = 0; +uint ShenandoahWorkerPolicy::_prev_conc_root_proc = 0; uint ShenandoahWorkerPolicy::_prev_fullgc = 0; uint ShenandoahWorkerPolicy::_prev_degengc = 0; uint ShenandoahWorkerPolicy::_prev_stw_traversal = 0; @@ -63,6 +64,16 @@ return _prev_par_marking; } +// Calculate workers for concurrent root processing +uint ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing() { + uint active_workers = (_prev_conc_root_proc == 0) ? ConcGCThreads : _prev_conc_root_proc; + _prev_conc_root_proc = + WorkerPolicy::calc_active_conc_workers(ConcGCThreads, + active_workers, + Threads::number_of_non_daemon_threads()); + return _prev_conc_root_proc; +} + // Calculate workers for concurrent evacuation (concurrent GC) uint ShenandoahWorkerPolicy::calc_workers_for_conc_evac() { uint active_workers = (_prev_conc_evac == 0) ? ConcGCThreads : _prev_conc_evac;
--- a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -30,6 +30,7 @@ private: static uint _prev_par_marking; static uint _prev_conc_marking; + static uint _prev_conc_root_proc; static uint _prev_conc_evac; static uint _prev_fullgc; static uint _prev_degengc; @@ -50,6 +51,9 @@ // Calculate the number of workers for final marking static uint calc_workers_for_final_marking(); + // Calculate workers for concurrent root processing + static uint calc_workers_for_conc_root_processing(); + // Calculate workers for concurrent evacuation (concurrent GC) static uint calc_workers_for_conc_evac();
--- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -308,7 +308,8 @@ BOXED_BOOLEAN(box, *(jbyte*) vmField.address); assert(box.is_non_null(), "must have a box"); } else if (strcmp(vmField.typeString, "int") == 0 || - strcmp(vmField.typeString, "jint") == 0) { + strcmp(vmField.typeString, "jint") == 0 || + strcmp(vmField.typeString, "uint32_t") == 0) { BOXED_LONG(box, *(jint*) vmField.address); assert(box.is_non_null(), "must have a box"); } else if (strcmp(vmField.typeString, "uint64_t") == 0) {
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -691,10 +691,10 @@ #endif -// AARCH64 is defined in closed port, too. TARGET_ARCH_aarch64 is not. -#ifdef TARGET_ARCH_aarch64 +#ifdef AARCH64 #define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ + static_field(VM_Version, _psr_info.dczid_el0, uint32_t) \ volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) #define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
--- a/src/hotspot/share/opto/escape.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/opto/escape.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -2346,8 +2346,7 @@ assert(opcode == Op_ConP || opcode == Op_ThreadLocal || opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() || (uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) || - (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()) || - BarrierSet::barrier_set()->barrier_set_c2()->escape_is_barrier_node(uncast_base), "sanity"); + (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity"); } } return base; @@ -3085,7 +3084,6 @@ n->is_CheckCastPP() || n->is_EncodeP() || n->is_DecodeN() || - BarrierSet::barrier_set()->barrier_set_c2()->escape_is_barrier_node(n) || (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) { if (visited.test_set(n->_idx)) { assert(n->is_Phi(), "loops only through Phi's"); @@ -3156,7 +3154,6 @@ use->is_CheckCastPP() || use->is_EncodeNarrowPtr() || use->is_DecodeNarrowPtr() || - BarrierSet::barrier_set()->barrier_set_c2()->escape_is_barrier_node(use) || (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) { alloc_worklist.append_if_missing(use); #ifdef ASSERT
--- a/src/hotspot/share/opto/library_call.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/opto/library_call.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -4501,8 +4501,8 @@ ciMethod* trap_method = alloc->jvms()->method(); int trap_bci = alloc->jvms()->bci(); - if (!C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_intrinsic) & - !C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_null_check)) { + if (!C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_intrinsic) && + !C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_null_check)) { // Make sure there's no store between the allocation and the // arraycopy otherwise visible side effects could be rexecuted // in case of deoptimization and cause incorrect execution.
--- a/src/hotspot/share/opto/type.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/opto/type.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -2109,7 +2109,7 @@ const TypeAry *a = t->is_ary(); return TypeAry::make(_elem->meet_speculative(a->_elem), _size->xmeet(a->_size)->is_int(), - _stable & a->_stable); + _stable && a->_stable); } case Top: break; @@ -3879,7 +3879,7 @@ bool subtype_exact = false; if( tinst_klass->equals(this_klass) ) { subtype = this_klass; - subtype_exact = below_centerline(ptr) ? (this_xk & tinst_xk) : (this_xk | tinst_xk); + subtype_exact = below_centerline(ptr) ? (this_xk && tinst_xk) : (this_xk || tinst_xk); } else if( !tinst_xk && this_klass->is_subtype_of( tinst_klass ) ) { subtype = this_klass; // Pick subtyping class subtype_exact = this_xk; @@ -4361,7 +4361,7 @@ if (below_centerline(this->_ptr)) { xk = this->_klass_is_exact; } else { - xk = (tap->_klass_is_exact | this->_klass_is_exact); + xk = (tap->_klass_is_exact || this->_klass_is_exact); } return make(ptr, const_oop(), tary, lazy_klass, xk, off, instance_id, speculative, depth); case Constant: {
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -1083,7 +1083,7 @@ // If the monitor has no owner, then a non-suspended contending // thread could potentially change the state of the monitor by // entering it. The JVM/TI spec doesn't allow this. - if (owning_thread == NULL && !at_safepoint & + if (owning_thread == NULL && !at_safepoint && !pending_thread->is_thread_fully_suspended(true, &debug_bits)) { if (ret.owner != NULL) { destroy_jni_reference(calling_thread, ret.owner);
--- a/src/hotspot/share/runtime/arguments.cpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/runtime/arguments.cpp Thu Jun 20 22:06:48 2019 +0200 @@ -533,7 +533,6 @@ { "InitialRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() }, { "UseMembar", JDK_Version::jdk(10), JDK_Version::jdk(12), JDK_Version::undefined() }, { "CompilationPolicyChoice", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::undefined() }, - { "FailOverToOldVerifier", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::undefined() }, { "AllowJNIEnvProxy", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::jdk(15) }, { "ThreadLocalHandshakes", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::jdk(15) }, { "AllowRedefinitionToAddDeleteMethods", JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() }, @@ -563,6 +562,7 @@ { "ProfilerNumberOfRuntimeStubNodes", JDK_Version::undefined(), JDK_Version::jdk(13), JDK_Version::jdk(14) }, { "UseImplicitStableValues", JDK_Version::undefined(), JDK_Version::jdk(13), JDK_Version::jdk(14) }, { "NeedsDeoptSuspend", JDK_Version::undefined(), JDK_Version::jdk(13), JDK_Version::jdk(14) }, + { "FailOverToOldVerifier", JDK_Version::undefined(), JDK_Version::jdk(14), JDK_Version::jdk(15) }, #ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS // These entries will generate build errors. Their purpose is to test the macros. @@ -3465,14 +3465,6 @@ void Arguments::set_shared_spaces_flags() { if (DumpSharedSpaces) { - if (FailOverToOldVerifier) { - // Don't fall back to the old verifier on verification failure. If a - // class fails verification with the split verifier, it might fail the - // CDS runtime verifier constraint check. In that case, we don't want - // to share the class. We only archive classes that pass the split verifier. - FLAG_SET_DEFAULT(FailOverToOldVerifier, false); - } - if (RequireSharedSpaces) { warning("Cannot dump shared archive while using shared archive"); }
--- a/src/hotspot/share/runtime/globals.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/runtime/globals.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -405,9 +405,6 @@ notproduct(bool, VerifyLastFrame, false, \ "Verify oops on last frame on entry to VM") \ \ - product(bool, FailOverToOldVerifier, true, \ - "Fail over to old verifier when split verifier fails") \ - \ product(bool, SafepointTimeout, false, \ "Time out and warn or fail after SafepointTimeoutDelay " \ "milliseconds if failed to reach safepoint") \
--- a/src/hotspot/share/runtime/vframe.inline.hpp Mon Jun 17 17:18:22 2019 +0200 +++ b/src/hotspot/share/runtime/vframe.inline.hpp Thu Jun 20 22:06:48 2019 +0200 @@ -26,6 +26,7 @@ #define SHARE_RUNTIME_VFRAME_INLINE_HPP #include "runtime/frame.inline.hpp" +#include "runtime/thread.inline.hpp" #include "runtime/vframe.hpp" inline vframeStreamCommon::vframeStreamCommon(JavaThread* thread) : _reg_map(thread, false) {
--- a/src/java.base/share/classes/java/lang/Integer.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/share/classes/java/lang/Integer.java Thu Jun 20 22:06:48 2019 +0200 @@ -347,59 +347,53 @@ int chars = Math.max(((mag + (shift - 1)) / shift), 1); if (COMPACT_STRINGS) { byte[] buf = new byte[chars]; - formatUnsignedInt(val, shift, buf, 0, chars); + formatUnsignedInt(val, shift, buf, chars); return new String(buf, LATIN1); } else { byte[] buf = new byte[chars * 2]; - formatUnsignedIntUTF16(val, shift, buf, 0, chars); + formatUnsignedIntUTF16(val, shift, buf, chars); return new String(buf, UTF16); } } /** - * Format an {@code int} (treated as unsigned) into a character buffer. If + * Format an {@code int} (treated as unsigned) into a byte buffer (LATIN1 version). If * {@code len} exceeds the formatted ASCII representation of {@code val}, * {@code buf} will be padded with leading zeroes. * * @param val the unsigned int to format * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary) - * @param buf the character buffer to write to - * @param offset the offset in the destination buffer to start at + * @param buf the byte buffer to write to * @param len the number of characters to write */ - static void formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) { - // assert shift > 0 && shift <=5 : "Illegal shift value"; - // assert offset >= 0 && offset < buf.length : "illegal offset"; - // assert len > 0 && (offset + len) <= buf.length : "illegal length"; - int charPos = offset + len; - int radix = 1 << shift; - int mask = radix - 1; - do { - buf[--charPos] = Integer.digits[val & mask]; - val >>>= shift; - } while (charPos > offset); - } - - /** byte[]/LATIN1 version */ - static void formatUnsignedInt(int val, int shift, byte[] buf, int offset, int len) { - int charPos = offset + len; + private static void formatUnsignedInt(int val, int shift, byte[] buf, int len) { + int charPos = len; int radix = 1 << shift; int mask = radix - 1; do { buf[--charPos] = (byte)Integer.digits[val & mask]; val >>>= shift; - } while (charPos > offset); + } while (charPos > 0); } - /** byte[]/UTF16 version */ - private static void formatUnsignedIntUTF16(int val, int shift, byte[] buf, int offset, int len) { - int charPos = offset + len; + /** + * Format an {@code int} (treated as unsigned) into a byte buffer (UTF16 version). If + * {@code len} exceeds the formatted ASCII representation of {@code val}, + * {@code buf} will be padded with leading zeroes. + * + * @param val the unsigned int to format + * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary) + * @param buf the byte buffer to write to + * @param len the number of characters to write + */ + private static void formatUnsignedIntUTF16(int val, int shift, byte[] buf, int len) { + int charPos = len; int radix = 1 << shift; int mask = radix - 1; do { StringUTF16.putChar(buf, --charPos, Integer.digits[val & mask]); val >>>= shift; - } while (charPos > offset); + } while (charPos > 0); } static final byte[] DigitTens = { @@ -698,7 +692,7 @@ */ public static int parseInt(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException { - s = Objects.requireNonNull(s); + Objects.requireNonNull(s); if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) { throw new IndexOutOfBoundsException(); @@ -881,7 +875,7 @@ */ public static int parseUnsignedInt(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException { - s = Objects.requireNonNull(s); + Objects.requireNonNull(s); if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) { throw new IndexOutOfBoundsException();
--- a/src/java.base/share/classes/java/lang/Long.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/share/classes/java/lang/Long.java Thu Jun 20 22:06:48 2019 +0200 @@ -398,19 +398,17 @@ } /** - * Format a long (treated as unsigned) into a character buffer. If + * Format a long (treated as unsigned) into a byte buffer (LATIN1 version). If * {@code len} exceeds the formatted ASCII representation of {@code val}, * {@code buf} will be padded with leading zeroes. * * @param val the unsigned long to format * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary) - * @param buf the character buffer to write to + * @param buf the byte buffer to write to * @param offset the offset in the destination buffer to start at * @param len the number of characters to write */ - - /** byte[]/LATIN1 version */ - static void formatUnsignedLong0(long val, int shift, byte[] buf, int offset, int len) { + private static void formatUnsignedLong0(long val, int shift, byte[] buf, int offset, int len) { int charPos = offset + len; int radix = 1 << shift; int mask = radix - 1; @@ -420,7 +418,17 @@ } while (charPos > offset); } - /** byte[]/UTF16 version */ + /** + * Format a long (treated as unsigned) into a byte buffer (UTF16 version). If + * {@code len} exceeds the formatted ASCII representation of {@code val}, + * {@code buf} will be padded with leading zeroes. + * + * @param val the unsigned long to format + * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary) + * @param buf the byte buffer to write to + * @param offset the offset in the destination buffer to start at + * @param len the number of characters to write + */ private static void formatUnsignedLong0UTF16(long val, int shift, byte[] buf, int offset, int len) { int charPos = offset + len; int radix = 1 << shift; @@ -739,7 +747,7 @@ */ public static long parseLong(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException { - s = Objects.requireNonNull(s); + Objects.requireNonNull(s); if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) { throw new IndexOutOfBoundsException(); @@ -985,7 +993,7 @@ */ public static long parseUnsignedLong(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException { - s = Objects.requireNonNull(s); + Objects.requireNonNull(s); if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) { throw new IndexOutOfBoundsException();
--- a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java Thu Jun 20 22:06:48 2019 +0200 @@ -396,15 +396,16 @@ * 'Z' when the offset to be output would be zero, whereas pattern letter 'x' * (lower case) will output '+00', '+0000', or '+00:00'. * <p> - * <b>Offset O</b>: This formats the localized offset based on the number of - * pattern letters. One letter outputs the {@linkplain TextStyle#SHORT short} - * form of the localized offset, which is localized offset text, such as 'GMT', - * with hour without leading zero, optional 2-digit minute and second if - * non-zero, and colon, for example 'GMT+8'. Four letters outputs the - * {@linkplain TextStyle#FULL full} form, which is localized offset text, - * such as 'GMT, with 2-digit hour and minute field, optional second field - * if non-zero, and colon, for example 'GMT+08:00'. Any other count of letters - * throws {@code IllegalArgumentException}. + * <b>Offset O</b>: With a non-zero offset, this formats the localized offset + * based on the number of pattern letters. One letter outputs the + * {@linkplain TextStyle#SHORT short} form of the localized offset, which is + * localized offset text, such as 'GMT', with hour without leading zero, optional + * 2-digit minute and second if non-zero, and colon, for example 'GMT+8'. Four + * letters outputs the {@linkplain TextStyle#FULL full} form, which is localized + * offset text, such as 'GMT, with 2-digit hour and minute field, optional second + * field if non-zero, and colon, for example 'GMT+08:00'. If the offset is zero, + * only localized text is output. Any other count of letters throws + * {@code IllegalArgumentException}. * <p> * <b>Offset Z</b>: This formats the offset based on the number of pattern * letters. One, two or three letters outputs the hour and minute, without a
--- a/src/java.base/share/classes/java/util/HashMap.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/share/classes/java/util/HashMap.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -911,6 +911,74 @@ return ks; } + /** + * Prepares the array for {@link Collection#toArray(Object[])} implementation. + * If supplied array is smaller than this map size, a new array is allocated. + * If supplied array is bigger than this map size, a null is written at size index. + * + * @param a an original array passed to {@code toArray()} method + * @param <T> type of array elements + * @return an array ready to be filled and returned from {@code toArray()} method. + */ + @SuppressWarnings("unchecked") + final <T> T[] prepareArray(T[] a) { + int size = this.size; + if (a.length < size) { + return (T[]) java.lang.reflect.Array + .newInstance(a.getClass().getComponentType(), size); + } + if (a.length > size) { + a[size] = null; + } + return a; + } + + /** + * Fills an array with this map keys and returns it. This method assumes + * that input array is big enough to fit all the keys. Use + * {@link #prepareArray(Object[])} to ensure this. + * + * @param a an array to fill + * @param <T> type of array elements + * @return supplied array + */ + <T> T[] keysToArray(T[] a) { + Object[] r = a; + Node<K,V>[] tab; + int idx = 0; + if (size > 0 && (tab = table) != null) { + for (Node<K,V> e : tab) { + for (; e != null; e = e.next) { + r[idx++] = e.key; + } + } + } + return a; + } + + /** + * Fills an array with this map values and returns it. This method assumes + * that input array is big enough to fit all the values. Use + * {@link #prepareArray(Object[])} to ensure this. + * + * @param a an array to fill + * @param <T> type of array elements + * @return supplied array + */ + <T> T[] valuesToArray(T[] a) { + Object[] r = a; + Node<K,V>[] tab; + int idx = 0; + if (size > 0 && (tab = table) != null) { + for (Node<K,V> e : tab) { + for (; e != null; e = e.next) { + r[idx++] = e.value; + } + } + } + return a; + } + final class KeySet extends AbstractSet<K> { public final int size() { return size; } public final void clear() { HashMap.this.clear(); } @@ -922,6 +990,15 @@ public final Spliterator<K> spliterator() { return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0); } + + public Object[] toArray() { + return keysToArray(new Object[size]); + } + + public <T> T[] toArray(T[] a) { + return keysToArray(prepareArray(a)); + } + public final void forEach(Consumer<? super K> action) { Node<K,V>[] tab; if (action == null) @@ -970,6 +1047,15 @@ public final Spliterator<V> spliterator() { return new ValueSpliterator<>(HashMap.this, 0, -1, 0, 0); } + + public Object[] toArray() { + return valuesToArray(new Object[size]); + } + + public <T> T[] toArray(T[] a) { + return valuesToArray(prepareArray(a)); + } + public final void forEach(Consumer<? super V> action) { Node<K,V>[] tab; if (action == null)
--- a/src/java.base/share/classes/java/util/HashSet.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/share/classes/java/util/HashSet.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -358,4 +358,14 @@ public Spliterator<E> spliterator() { return new HashMap.KeySpliterator<>(map, 0, -1, 0, 0); } + + @Override + public Object[] toArray() { + return map.keysToArray(new Object[map.size()]); + } + + @Override + public <T> T[] toArray(T[] a) { + return map.keysToArray(map.prepareArray(a)); + } }
--- a/src/java.base/share/classes/java/util/LinkedHashMap.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -536,6 +536,26 @@ return ks; } + @Override + final <T> T[] keysToArray(T[] a) { + Object[] r = a; + int idx = 0; + for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after) { + r[idx++] = e.key; + } + return a; + } + + @Override + final <T> T[] valuesToArray(T[] a) { + Object[] r = a; + int idx = 0; + for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after) { + r[idx++] = e.value; + } + return a; + } + final class LinkedKeySet extends AbstractSet<K> { public final int size() { return size; } public final void clear() { LinkedHashMap.this.clear(); } @@ -551,6 +571,15 @@ Spliterator.ORDERED | Spliterator.DISTINCT); } + + public Object[] toArray() { + return keysToArray(new Object[size]); + } + + public <T> T[] toArray(T[] a) { + return keysToArray(prepareArray(a)); + } + public final void forEach(Consumer<? super K> action) { if (action == null) throw new NullPointerException(); @@ -600,6 +629,15 @@ return Spliterators.spliterator(this, Spliterator.SIZED | Spliterator.ORDERED); } + + public Object[] toArray() { + return valuesToArray(new Object[size]); + } + + public <T> T[] toArray(T[] a) { + return valuesToArray(prepareArray(a)); + } + public final void forEach(Consumer<? super V> action) { if (action == null) throw new NullPointerException();
--- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Thu Jun 20 22:06:48 2019 +0200 @@ -38,6 +38,7 @@ import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiFunction; import javax.net.ssl.HandshakeCompletedListener; @@ -618,27 +619,76 @@ // Need a lock here so that the user_canceled alert and the // close_notify alert can be delivered together. - conContext.outputRecord.recordLock.lock(); - try { + int linger = getSoLinger(); + if (linger >= 0) { + // don't wait more than SO_LINGER for obtaining the + // the lock. + // + // keep and clear the current thread interruption status. + boolean interrupted = Thread.interrupted(); try { - // send a user_canceled alert if needed. - if (useUserCanceled) { - conContext.warning(Alert.USER_CANCELED); + if (conContext.outputRecord.recordLock.tryLock() || + conContext.outputRecord.recordLock.tryLock( + linger, TimeUnit.SECONDS)) { + try { + handleClosedNotifyAlert(useUserCanceled); + } finally { + conContext.outputRecord.recordLock.unlock(); + } + } else { + // For layered, non-autoclose sockets, we are not + // able to bring them into a usable state, so we + // treat it as fatal error. + if (!super.isOutputShutdown()) { + if (isLayered() && !autoClose) { + throw new SSLException( + "SO_LINGER timeout, " + + "close_notify message cannot be sent."); + } else { + super.shutdownOutput(); + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.warning( + "SSLSocket output duplex close failed: " + + "SO_LINGER timeout, " + + "close_notify message cannot be sent."); + } + } + } + + // RFC2246 requires that the session becomes + // unresumable if any connection is terminated + // without proper close_notify messages with + // level equal to warning. + // + // RFC4346 no longer requires that a session not be + // resumed if failure to properly close a connection. + // + // We choose to make the session unresumable if + // failed to send the close_notify message. + // + conContext.conSession.invalidate(); + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.warning( + "Invalidate the session: SO_LINGER timeout, " + + "close_notify message cannot be sent."); + } } + } catch (InterruptedException ex) { + // keep interrupted status + interrupted = true; + } - // send a close_notify alert - conContext.warning(Alert.CLOSE_NOTIFY); + // restore the interrupted status + if (interrupted) { + Thread.currentThread().interrupt(); + } + } else { + conContext.outputRecord.recordLock.lock(); + try { + handleClosedNotifyAlert(useUserCanceled); } finally { - if (!conContext.isOutboundClosed()) { - conContext.outputRecord.close(); - } - - if ((autoClose || !isLayered()) && !super.isOutputShutdown()) { - super.shutdownOutput(); - } + conContext.outputRecord.recordLock.unlock(); } - } finally { - conContext.outputRecord.recordLock.unlock(); } if (!isInputShutdown()) { @@ -646,6 +696,28 @@ } } + private void handleClosedNotifyAlert( + boolean useUserCanceled) throws IOException { + try { + // send a user_canceled alert if needed. + if (useUserCanceled) { + conContext.warning(Alert.USER_CANCELED); + } + + // send a close_notify alert + conContext.warning(Alert.CLOSE_NOTIFY); + } finally { + if (!conContext.isOutboundClosed()) { + conContext.outputRecord.close(); + } + + if (!super.isOutputShutdown() && + (autoClose || !isLayered())) { + super.shutdownOutput(); + } + } + } + /** * Duplex close, start from closing inbound. *
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu Jun 20 22:06:48 2019 +0200 @@ -2418,9 +2418,9 @@ out.println(form.format(source)); out.println(); - for (Enumeration<String> e = keyStore.aliases(); - e.hasMoreElements(); ) { - String alias = e.nextElement(); + List<String> aliases = Collections.list(keyStore.aliases()); + aliases.sort(String::compareTo); + for (String alias : aliases) { doPrintEntry("<" + alias + ">", alias, out); if (verbose || rfc) { out.println(rb.getString("NEWLINE"));
--- a/src/java.base/unix/native/libjava/ProcessImpl_md.c Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/unix/native/libjava/ProcessImpl_md.c Thu Jun 20 22:06:48 2019 +0200 @@ -354,6 +354,27 @@ free(errmsg); } +/** + * Throws an IOException with a message composed from the result of waitpid status. + */ +static void throwExitCause(JNIEnv *env, int pid, int status) { + char ebuf[128]; + if (WIFEXITED(status)) { + snprintf(ebuf, sizeof ebuf, + "Failed to exec spawn helper: pid: %d, exit value: %d", + pid, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + snprintf(ebuf, sizeof ebuf, + "Failed to exec spawn helper: pid: %d, signal: %d", + pid, WTERMSIG(status)); + } else { + snprintf(ebuf, sizeof ebuf, + "Failed to exec spawn helper: pid: %d, status: 0x%08x", + pid, status); + } + throwIOException(env, 0, ebuf); +} + #ifdef DEBUG_PROCESS /* Debugging process code is difficult; where to write debug output? */ static void @@ -690,9 +711,12 @@ if (c->sendAlivePing) { switch(readFully(fail[0], &errnum, sizeof(errnum))) { case 0: /* First exec failed; */ - waitpid(resultPid, NULL, 0); - throwIOException(env, 0, "Failed to exec spawn helper."); - goto Catch; + { + int tmpStatus = 0; + int p = waitpid(resultPid, &tmpStatus, 0); + throwExitCause(env, p, tmpStatus); + goto Catch; + } case sizeof(errnum): assert(errnum == CHILD_IS_ALIVE); if (errnum != CHILD_IS_ALIVE) { @@ -700,7 +724,7 @@ * helper should do is to send an alive ping to the parent, * before doing any subsequent work. */ throwIOException(env, 0, "Bad code from spawn helper " - "(Failed to exec spawn helper."); + "(Failed to exec spawn helper)"); goto Catch; } break;
--- a/src/java.base/windows/native/libnet/Inet4AddressImpl.c Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/windows/native/libnet/Inet4AddressImpl.c Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -359,7 +359,8 @@ } if (dwRetVal == 0) { // if the call failed - TCHAR *buf; + TCHAR *buf = NULL; + DWORD n; DWORD err = WSAGetLastError(); switch (err) { case ERROR_NO_NETWORK: @@ -379,9 +380,17 @@ case IP_REQ_TIMED_OUT: break; default: - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&buf, 0, NULL); + n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&buf, 0, NULL); + if (n > 3) { + // Drop final '.', CR, LF + if (buf[n - 1] == TEXT('\n')) n--; + if (buf[n - 1] == TEXT('\r')) n--; + if (buf[n - 1] == TEXT('.')) n--; + buf[n] = TEXT('\0'); + } NET_ThrowNew(env, err, buf); LocalFree(buf); break;
--- a/src/java.base/windows/native/libnio/ch/Iocp.c Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/windows/native/libnio/ch/Iocp.c Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -142,6 +142,14 @@ if (len == 0) { return NULL; } else { + if (len > 3) { + // Drop final '.', CR, LF + if (message[len - 1] == L'\n') len--; + if (message[len - 1] == L'\r') len--; + if (message[len - 1] == L'.') len--; + message[len] = L'\0'; + } + return (*env)->NewString(env, (const jchar *)message, (jsize)wcslen(message)); } }
--- a/src/java.base/windows/native/libnio/fs/WindowsNativeDispatcher.c Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.base/windows/native/libnio/fs/WindowsNativeDispatcher.c Thu Jun 20 22:06:48 2019 +0200 @@ -177,6 +177,14 @@ if (len == 0) { return NULL; } else { + if (len > 3) { + // Drop final '.', CR, LF + if (message[len - 1] == L'\n') len--; + if (message[len - 1] == L'\r') len--; + if (message[len - 1] == L'.') len--; + message[len] = L'\0'; + } + return (*env)->NewString(env, (const jchar *)message, (jsize)wcslen(message)); } }
--- a/src/java.net.http/share/classes/java/net/http/HttpResponse.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.net.http/share/classes/java/net/http/HttpResponse.java Thu Jun 20 22:06:48 2019 +0200 @@ -1253,7 +1253,7 @@ /** * Returns a {@code BodySubscriber} which buffers data before delivering * it to the given downstream subscriber. The subscriber guarantees to - * deliver {@code buffersize} bytes of data to each invocation of the + * deliver {@code bufferSize} bytes of data to each invocation of the * downstream's {@link BodySubscriber#onNext(Object) onNext} method, * except for the final invocation, just before * {@link BodySubscriber#onComplete() onComplete} is invoked. The final
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1HeaderParser.java Thu Jun 20 22:06:48 2019 +0200 @@ -194,7 +194,15 @@ if (statusLine.length() < 12) { throw protocolException("Invalid status line: \"%s\"", statusLine); } - responseCode = Integer.parseInt(statusLine.substring(9, 12)); + try { + responseCode = Integer.parseInt(statusLine.substring(9, 12)); + } catch (NumberFormatException nfe) { + throw protocolException("Invalid status line: \"%s\"", statusLine); + } + // response code expected to be a 3-digit integer (RFC-2616, section 6.1.1) + if (responseCode < 100) { + throw protocolException("Invalid status line: \"%s\"", statusLine); + } state = State.STATUS_LINE_END; }
--- a/src/java.net.http/share/classes/jdk/internal/net/http/LineSubscriberAdapter.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/LineSubscriberAdapter.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ import java.util.concurrent.Flow; import java.util.concurrent.Flow.Subscriber; import java.util.concurrent.Flow.Subscription; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; @@ -56,6 +57,7 @@ private final Function<? super S, ? extends R> finisher; private final Charset charset; private final String eol; + private final AtomicBoolean subscribed = new AtomicBoolean(); private volatile LineSubscription downstream; private LineSubscriberAdapter(S subscriber, @@ -72,6 +74,12 @@ @Override public void onSubscribe(Subscription subscription) { + Objects.requireNonNull(subscription); + if (!subscribed.compareAndSet(false, true)) { + subscription.cancel(); + return; + } + downstream = LineSubscription.create(subscription, charset, eol, @@ -82,6 +90,7 @@ @Override public void onNext(List<ByteBuffer> item) { + Objects.requireNonNull(item); try { downstream.submit(item); } catch (Throwable t) { @@ -91,6 +100,7 @@ @Override public void onError(Throwable throwable) { + Objects.requireNonNull(throwable); try { downstream.signalError(throwable); } finally {
--- a/src/java.net.http/share/classes/jdk/internal/net/http/PullPublisher.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/PullPublisher.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, 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,11 +103,19 @@ } while (demand.tryDecrement() && !cancelled) { - if (!iter.hasNext()) { - break; - } else { - subscriber.onNext(iter.next()); + T next; + try { + if (!iter.hasNext()) { + break; + } + next = iter.next(); + } catch (Throwable t1) { + completed = true; + pullScheduler.stop(); + subscriber.onError(t1); + return; } + subscriber.onNext(next); } if (!iter.hasNext() && !cancelled) { completed = true; @@ -123,7 +131,7 @@ return; // no-op if (n <= 0) { - error = new IllegalArgumentException("illegal non-positive request:" + n); + error = new IllegalArgumentException("non-positive subscription request: " + n); } else { demand.increase(n); }
--- a/src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, 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 @@ -271,12 +271,13 @@ @Override public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) { - InputStream is; + InputStream is = null; + Throwable t = null; if (System.getSecurityManager() == null) { try { is = new FileInputStream(file); } catch (IOException ioe) { - throw new UncheckedIOException(ioe); + t = ioe; } } else { try { @@ -284,11 +285,16 @@ () -> new FileInputStream(file); is = AccessController.doPrivileged(pa, null, filePermissions); } catch (PrivilegedActionException pae) { - throw new UncheckedIOException((IOException) pae.getCause()); + t = pae.getCause(); } } - PullPublisher<ByteBuffer> publisher = - new PullPublisher<>(() -> new StreamIterator(is)); + final InputStream fis = is; + PullPublisher<ByteBuffer> publisher; + if (t == null) { + publisher = new PullPublisher<>(() -> new StreamIterator(fis)); + } else { + publisher = new PullPublisher<>(null, t); + } publisher.subscribe(subscriber); }
--- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java Thu Jun 20 22:06:48 2019 +0200 @@ -125,6 +125,7 @@ @Override public void onSubscribe(Flow.Subscription subscription) { + Objects.requireNonNull(subscription); if (!subscribed.compareAndSet(false, true)) { subscription.cancel(); } else { @@ -135,6 +136,7 @@ @Override public void onNext(List<ByteBuffer> items) { + Objects.requireNonNull(items); for (ByteBuffer item : items) { byte[] buf = new byte[item.remaining()]; item.get(buf); @@ -145,6 +147,7 @@ @Override public void onError(Throwable throwable) { + Objects.requireNonNull(throwable); result.completeExceptionally(throwable); } @@ -172,6 +175,7 @@ private final FilePermission[] filePermissions; private final CompletableFuture<Path> result = new MinimalFuture<>(); + private final AtomicBoolean subscribed = new AtomicBoolean(); private volatile Flow.Subscription subscription; private volatile FileChannel out; @@ -211,6 +215,12 @@ @Override public void onSubscribe(Flow.Subscription subscription) { + Objects.requireNonNull(subscription); + if (!subscribed.compareAndSet(false, true)) { + subscription.cancel(); + return; + } + this.subscription = subscription; if (System.getSecurityManager() == null) { try { @@ -470,6 +480,7 @@ @Override public void onSubscribe(Flow.Subscription s) { + Objects.requireNonNull(s); try { if (!subscribed.compareAndSet(false, true)) { s.cancel(); @@ -600,6 +611,7 @@ @Override public void onSubscribe(Flow.Subscription subscription) { + Objects.requireNonNull(subscription); if (!subscribed.compareAndSet(false, true)) { subscription.cancel(); } else { @@ -614,6 +626,7 @@ @Override public void onError(Throwable throwable) { + Objects.requireNonNull(throwable); cf.completeExceptionally(throwable); } @@ -907,13 +920,21 @@ } } + private final AtomicBoolean subscribed = new AtomicBoolean(); + @Override public void onSubscribe(Flow.Subscription subscription) { - subscriptionCF.complete(subscription); + Objects.requireNonNull(subscription); + if (!subscribed.compareAndSet(false, true)) { + subscription.cancel(); + } else { + subscriptionCF.complete(subscription); + } } @Override public void onNext(List<ByteBuffer> item) { + Objects.requireNonNull(item); try { // cannot be called before onSubscribe() assert subscriptionCF.isDone(); @@ -941,6 +962,7 @@ // onError can be called before request(1), and therefore can // be called before subscriberRef is set. signalError(throwable); + Objects.requireNonNull(throwable); } @Override
--- a/src/java.sql.rowset/share/classes/com/sun/rowset/providers/RIXMLProvider.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/providers/RIXMLProvider.java Thu Jun 20 22:06:48 2019 +0200 @@ -46,7 +46,7 @@ * to read an XML data source or to write itself in XML format using the * <code>WebRowSet</code> XML schema definition available at * <pre> - * <a href="http://java.sun.com/xml/ns/jdbc/webrowset.xsd">http://java.sun.com/xml/ns/jdbc/webrowset.xsd</a> + * <a href="http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd">http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd</a> * </pre> * The <code>RIXMLProvider</code> implementation has a synchronization level of * GRADE_NONE, which means that it does no checking at all for conflicts. It
--- a/src/java.sql.rowset/share/classes/javax/sql/rowset/WebRowSet.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.sql.rowset/share/classes/javax/sql/rowset/WebRowSet.java Thu Jun 20 22:06:48 2019 +0200 @@ -44,7 +44,7 @@ * URI: * <ul> * <li> - * <a href="http://java.sun.com/xml/ns/jdbc/webrowset.xsd">http://java.sun.com/xml/ns/jdbc/webrowset.xsd</a> + * <a href="http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd">http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd</a> * </li> * </ul> * It describes the standard XML document format required when describing a
--- a/src/java.sql.rowset/share/classes/javax/sql/rowset/package-info.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/java.sql.rowset/share/classes/javax/sql/rowset/package-info.java Thu Jun 20 22:06:48 2019 +0200 @@ -95,8 +95,8 @@ * <code>SyncFactory</code> in the form of <code>SyncProvider</code> * implementations. In order to ensure well formed XML usage, a standard generic XML * Schema is defined and published at - * <a href="http://java.sun.com/xml/ns/jdbc/webrowset.xsd"> - * <code>http://java.sun.com/xml/ns/jdbc/webrowset.xsd</code></a>. + * <a href="http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd"> + * <code>http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd</code></a>. * * <li><a href="FilteredRowSet.html"><b><code>FilteredRowSet</code></b></a> - A * <code>FilteredRowSet</code> object provides filtering functionality in a programmatic @@ -154,7 +154,8 @@ * <code>RowSet</code> objects exist in a connected or disconnected environment. * The <code>BaseRowSet</code> abstract class provides any <code>RowSet</code> implementation * with its base functionality, including property manipulation and event notification - * that is fully compliant with <a href="http://java.sun.com/products/javabeans">JavaBeans</a> + * that is fully compliant with + * <a href="https://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html">JavaBeans</a> * component requirements. As an example, all implementations provided in the * reference implementations (contained in the <code>com.sun.rowset</code> package) use * the <code>BaseRowSet</code> class as a basis for their implementations.
--- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java Thu Jun 20 22:06:48 2019 +0200 @@ -233,7 +233,7 @@ * InputStream for the socket connection to get target VM */ private class SocketInputStream extends InputStream { - int s; + int s = -1; public SocketInputStream(int s) { this.s = s; @@ -261,7 +261,12 @@ } public void close() throws IOException { - VirtualMachineImpl.close(s); + synchronized (this) { + if (s != -1) { + VirtualMachineImpl.close(s); + s = -1; + } + } } }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Thu Jun 20 22:06:48 2019 +0200 @@ -2063,7 +2063,8 @@ @DefinedBy(Api.LANGUAGE_MODEL) public Type getReceiverType() { - return asType().getReceiverType(); + Type result = asType().getReceiverType(); + return (result == null) ? Type.noType : result; } @DefinedBy(Api.LANGUAGE_MODEL)
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Thu Jun 20 22:06:48 2019 +0200 @@ -477,7 +477,7 @@ } try (InputStream in = getClass().getResourceAsStream('/' + className.replace('.', '/') + ".class")) { - final String algorithm = "MD5"; + final String algorithm = "SHA-256"; byte[] digest; MessageDigest md = MessageDigest.getInstance(algorithm); try (DigestInputStream din = new DigestInputStream(in, md)) {
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c Thu Jun 20 22:06:48 2019 +0200 @@ -51,6 +51,7 @@ #include <stdlib.h> #include <string.h> #include <assert.h> +#include "jlong.h" #include "sun_security_pkcs11_wrapper_PKCS11.h" @@ -96,8 +97,8 @@ Java_sun_security_pkcs11_wrapper_PKCS11_freeMechanism (JNIEnv *env, jclass thisClass, jlong ckpMechanism) { if (ckpMechanism != 0L) { - freeCKMechanismPtr((CK_MECHANISM_PTR) ckpMechanism); - TRACE1("DEBUG PKCS11_freeMechanism: free pMech = %x\n", (jlong)ckpMechanism); + freeCKMechanismPtr(jlong_to_ptr(ckpMechanism)); + TRACE1("DEBUG PKCS11_freeMechanism: free pMech = %x\n", ckpMechanism); } return 0L; }
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c Thu Jun 20 22:06:48 2019 +0200 @@ -91,8 +91,8 @@ (ckpMechanism->pParameter == NULL)) { freeCKMechanismPtr(ckpMechanism); } else { - (*env)->SetLongField(env, jMechanism, mech_pHandleID, (jlong)ckpMechanism); - TRACE1("DEBUG C_SignInit: stored pMech = 0x%lX\n", (jlong)ckpMechanism); + (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism)); + TRACE1("DEBUG C_SignInit: stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism)); } TRACE0("FINISHED\n"); } @@ -303,8 +303,8 @@ (ckpMechanism->pParameter == NULL)) { freeCKMechanismPtr(ckpMechanism); } else { - (*env)->SetLongField(env, jMechanism, mech_pHandleID, (jlong)ckpMechanism); - TRACE1("DEBUG C_SignRecoverInit, stored pMech = 0x%lX\n", (jlong)ckpMechanism); + (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism)); + TRACE1("DEBUG C_SignRecoverInit, stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism)); } TRACE0("FINISHED\n"); } @@ -413,8 +413,8 @@ (ckpMechanism->pParameter == NULL)) { freeCKMechanismPtr(ckpMechanism); } else { - (*env)->SetLongField(env, jMechanism, mech_pHandleID, (jlong)ckpMechanism); - TRACE1("DEBUG C_VerifyInit: stored pMech = 0x%lX\n", (jlong)ckpMechanism); + (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism)); + TRACE1("DEBUG C_VerifyInit: stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism)); } TRACE0("FINISHED\n"); } @@ -601,8 +601,8 @@ (ckpMechanism->pParameter == NULL)) { freeCKMechanismPtr(ckpMechanism); } else { - (*env)->SetLongField(env, jMechanism, mech_pHandleID, (jlong)ckpMechanism); - TRACE1("DEBUG C_VerifyRecoverInit: stored pMech = 0x%lX\n", (jlong)ckpMechanism); + (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism)); + TRACE1("DEBUG C_VerifyRecoverInit: stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism)); } TRACE0("FINISHED\n"); }
--- a/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c Thu Jun 20 22:06:48 2019 +0200 @@ -839,8 +839,51 @@ #define LD_BASE_OFFSET offsetof(struct r_debug, r_ldbase) #define LINK_MAP_ADDR_OFFSET offsetof(struct link_map, l_addr) #define LINK_MAP_NAME_OFFSET offsetof(struct link_map, l_name) +#define LINK_MAP_LD_OFFSET offsetof(struct link_map, l_ld) #define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next) +// Calculate the load address of shared library +// on prelink-enabled environment. +// +// In case of GDB, it would be calculated by offset of link_map.l_ld +// and the address of .dynamic section. +// See GDB implementation: lm_addr_check @ solib-svr4.c +static uintptr_t calc_prelinked_load_address(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* elf_ehdr, uintptr_t link_map_addr) { + ELF_PHDR *phbuf; + uintptr_t lib_ld; + uintptr_t lib_dyn_addr = 0L; + uintptr_t load_addr; + int i; + + phbuf = read_program_header_table(lib_fd, elf_ehdr); + if (phbuf == NULL) { + print_debug("can't read program header of shared object\n"); + return 0L; + } + + // Get the address of .dynamic section from shared library. + for (i = 0; i < elf_ehdr->e_phnum; i++) { + if (phbuf[i].p_type == PT_DYNAMIC) { + lib_dyn_addr = phbuf[i].p_vaddr; + break; + } + } + + free(phbuf); + + if (ps_pdread(ph, (psaddr_t)link_map_addr + LINK_MAP_LD_OFFSET, + &lib_ld, sizeof(uintptr_t)) != PS_OK) { + print_debug("can't read address of dynamic section in shared object\n"); + return 0L; + } + + // Return the load address which is calculated by the address of .dynamic + // and link_map.l_ld . + load_addr = lib_ld - lib_dyn_addr; + print_debug("lib_ld = 0x%lx, lib_dyn_addr = 0x%lx -> lib_base_diff = 0x%lx\n", lib_ld, lib_dyn_addr, load_addr); + return load_addr; +} + // read shared library info from runtime linker's data structures. // This work is done by librtlb_db in Solaris static bool read_shared_lib_info(struct ps_prochandle* ph) { @@ -942,6 +985,14 @@ // continue with other libraries... } else { if (read_elf_header(lib_fd, &elf_ehdr)) { + if (lib_base_diff == 0x0L) { + lib_base_diff = calc_prelinked_load_address(ph, lib_fd, &elf_ehdr, link_map_addr); + if (lib_base_diff == 0x0L) { + close(lib_fd); + return false; + } + } + lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr); print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n", lib_name, lib_base, lib_base_diff);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java Thu Jun 20 22:06:48 2019 +0200 @@ -64,8 +64,6 @@ public abstract long capacity(); public abstract long used(); - public long oopOffset() { return 0; } - public MemRegion reservedRegion() { return new MemRegion(addr.addOffsetTo(reservedFieldOffset)); }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahHeap.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahHeap.java Thu Jun 20 22:06:48 2019 +0200 @@ -48,7 +48,6 @@ static private CIntegerField logMinObjAlignmentInBytes; static private long regionPtrFieldSize; - static private long brookPtrSize; static { VM.registerVMInitializedObserver(new Observer() { public void update(Observable o, Object data) { @@ -65,7 +64,6 @@ regions = type.getAddressField("_regions"); logMinObjAlignmentInBytes = type.getCIntegerField("_log_min_obj_alignment_in_bytes"); - brookPtrSize = db.lookupIntConstant("HeapWordSize").longValue(); Type regionPtrType = db.lookupType("ShenandoahHeapRegion*"); regionPtrFieldSize = regionPtrType.getSize(); } @@ -75,11 +73,6 @@ } @Override - public long oopOffset() { - return brookPtrSize; - } - - @Override public CollectedHeapName kind() { return CollectedHeapName.SHENANDOAH; }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahHeapRegion.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahHeapRegion.java Thu Jun 20 22:06:48 2019 +0200 @@ -184,10 +184,10 @@ if (regionStart == null) { regionStart = start; } else { - regionEnd = start.addOffsetTo(heap.oopOffset() + size); + regionEnd = start.addOffsetTo(size); } } - start = start.addOffsetTo(heap.oopOffset() + size); + start = start.addOffsetTo(size); } if (regionStart != null) { @@ -201,15 +201,13 @@ } private boolean hasForwardee(Address rawPtr) { - // Use Mark as a helper to read forward pointer value. + // Forwarding pointer is stored in mark word when it is flagged "marked" Mark mark = new Mark(rawPtr); - Address forwardee = mark.valueAsAddress(); - return (forwardee != rawPtr.addOffsetTo(heap.oopOffset())); + return mark.isMarked(); } private long getObjectSize(Address rawPtr) { - // Dealing with a raw pointer, offsets forward pointer to find real Oop. - OopHandle handle = rawPtr.addOffsetToAsOopHandle(heap.oopOffset()); + OopHandle handle = rawPtr.addOffsetToAsOopHandle(0); Oop obj = null; try {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Thu Jun 20 22:06:48 2019 +0200 @@ -256,8 +256,6 @@ while (handle.lessThan(top)) { Oop obj = null; - // Raw pointer walk - handle = handle.addOffsetToAsOopHandle(heap.oopOffset()); try { obj = newOop(handle);
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/JavapTask.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/JavapTask.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2019, 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 @@ -808,7 +808,7 @@ MessageDigest md = null; if (options.sysInfo || options.verbose) { try { - md = MessageDigest.getInstance("MD5"); + md = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException ignore) { } in = new DigestInputStream(in, md); @@ -829,7 +829,7 @@ if (options.sysInfo || options.verbose) { classWriter.setFile(info.fo.toUri()); classWriter.setLastModified(info.fo.getLastModified()); - classWriter.setDigest("MD5", info.digest); + classWriter.setDigest("SHA-256", info.digest); classWriter.setFileSize(info.size); }
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap.properties Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap.properties Thu Jun 20 22:06:48 2019 +0200 @@ -99,7 +99,7 @@ \ -constants Show final constants main.opt.sysinfo=\ -\ -sysinfo Show system info (path, size, date, MD5 hash)\n\ +\ -sysinfo Show system info (path, size, date, SHA-256 hash)\n\ \ of class being processed main.opt.module=\
--- a/src/jdk.jshell/share/classes/jdk/jshell/Corraller.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.jshell/share/classes/jdk/jshell/Corraller.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, 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,132 +25,226 @@ package jdk.jshell; -import java.io.IOException; -import java.io.StringWriter; import com.sun.source.tree.ClassTree; import com.sun.source.tree.MethodTree; import com.sun.source.tree.Tree; -import com.sun.tools.javac.code.Flags; +import com.sun.source.tree.Tree.Kind; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; -import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; -import com.sun.tools.javac.tree.JCTree.JCNewClass; -import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.Pretty; -import com.sun.tools.javac.tree.TreeMaker; -import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.tree.JCTree.Visitor; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; -import com.sun.tools.javac.util.Names; +import static com.sun.tools.javac.code.Flags.FINAL; +import static com.sun.tools.javac.code.Flags.PUBLIC; import static com.sun.tools.javac.code.Flags.STATIC; import static com.sun.tools.javac.code.Flags.INTERFACE; import static com.sun.tools.javac.code.Flags.ENUM; -import static com.sun.tools.javac.code.Flags.PUBLIC; -import com.sun.tools.javac.util.Name; -import jdk.jshell.spi.SPIResolutionException; +import jdk.jshell.Wrap.CompoundWrap; +import jdk.jshell.Wrap.Range; +import jdk.jshell.Wrap.RangeWrap; /** * Produce a corralled version of the Wrap for a snippet. - * Incoming tree is mutated. - * - * @author Robert Field */ -class Corraller extends Pretty { +class Corraller extends Visitor { - private final StringWriter out; - private final int keyIndex; - private final TreeMaker make; - private final Names names; - private JCBlock resolutionExceptionBlock; + /** Visitor result field: a Wrap + */ + protected Wrap result; - public Corraller(int keyIndex, Context context) { - this(new StringWriter(), keyIndex, context); + private final TreeDissector dis; + private final String resolutionExceptionBlock; + private final String source; + + public Corraller(TreeDissector dis, int keyIndex, String source) { + this.dis = dis; + this.resolutionExceptionBlock = "\n { throw new jdk.jshell.spi.SPIResolutionException(" + keyIndex + "); }"; + this.source = source; } - private Corraller(StringWriter out, int keyIndex, Context context) { - super(out, false); - this.out = out; - this.keyIndex = keyIndex; - this.make = TreeMaker.instance(context); - this.names = Names.instance(context); + public Wrap corralType(ClassTree tree) { + return corralToWrap(tree); } - public Wrap corralType(ClassTree ct) { - ((JCClassDecl) ct).mods.flags |= Flags.STATIC | Flags.PUBLIC; - return corral(ct); + public Wrap corralMethod(MethodTree tree) { + return corralToWrap(tree); } - public Wrap corralMethod(MethodTree mt) { - ((JCMethodDecl) mt).mods.flags |= Flags.STATIC | Flags.PUBLIC; - return corral(mt); + private Wrap corralToWrap(Tree tree) { + try { + JCTree jct = (JCTree) tree; + Wrap w = new CompoundWrap( + " public static\n ", + corral(jct)); + debugWrap("corralToWrap SUCCESS source: %s -- wrap:\n %s\n", tree, w.wrapped()); + return w; + } catch (Exception ex) { + debugWrap("corralToWrap FAIL: %s - %s\n", tree, ex); + //ex.printStackTrace(System.err); + return null; + } } - private Wrap corral(Tree tree) { - try { - printStat((JCTree) tree); - } catch (IOException e) { - throw new AssertionError(e); + // Corral a single node. +// @SuppressWarnings("unchecked") + private <T extends JCTree> Wrap corral(T tree) { + if (tree == null) { + return null; + } else { + tree.accept(this); + Wrap tmpResult = this.result; + this.result = null; + return tmpResult; } - return Wrap.simpleWrap(out.toString()); + } + + private String defaultConstructor(JCClassDecl tree) { + return " public " + tree.name.toString() + "() " + + resolutionExceptionBlock; + } + + /* *************************************************************************** + * Visitor methods + ****************************************************************************/ + + @Override + public void visitClassDef(JCClassDecl tree) { + boolean isEnum = (tree.mods.flags & ENUM) != 0; + boolean isInterface = (tree.mods.flags & INTERFACE ) != 0; + int classBegin = dis.getStartPosition(tree); + int classEnd = dis.getEndPosition(tree); + //debugWrap("visitClassDef: %d-%d = %s\n", classBegin, classEnd, source.substring(classBegin, classEnd)); + ListBuffer<Object> wrappedDefs = new ListBuffer<>(); + int bodyBegin = -1; + if (tree.defs != null && !tree.defs.isEmpty()) { + if (isEnum) { + // copy the enum constants verbatim + int enumBegin = dis.getStartPosition(tree.defs.head); + JCTree t = null; // null to shut-up compiler, always set because non-empty + List<? extends JCTree> l = tree.defs; + for (; l.nonEmpty(); l = l.tail) { + t = l.head; + if (t.getKind() == Kind.VARIABLE) { + if ((((JCVariableDecl)t).mods.flags & (PUBLIC | STATIC | FINAL)) != (PUBLIC | STATIC | FINAL)) { + // non-enum constant, process normally + break; + } + } else { + // non-variable, process normally + break; + } + } + int constEnd = l.nonEmpty() // end of constants + ? dis.getStartPosition(l.head) - 1 // is one before next defs, if there is one + : dis.getEndPosition(t); // and otherwise end of the last constant + wrappedDefs.append(new RangeWrap(source, new Range(enumBegin, constEnd))); + // handle any other defs + for (; l.nonEmpty(); l = l.tail) { + wrappedDefs.append("\n"); + t = l.head; + wrappedDefs.append(corral(t)); + } + } else { + // non-enum + boolean constructorSeen = false; + for (List<? extends JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { + wrappedDefs.append("\n "); + JCTree t = l.head; + switch (t.getKind()) { + case METHOD: + constructorSeen = constructorSeen || ((MethodTree)t).getName() == tree.name.table.names.init; + break; + case BLOCK: + // throw exception in instance initializer too -- inline because String not Wrap + wrappedDefs.append((((JCBlock)t).flags & STATIC) != 0 + ? new RangeWrap(source, dis.treeToRange(t)) + : resolutionExceptionBlock); + continue; // already appended, skip append below + } + wrappedDefs.append(corral(t)); + } + if (!constructorSeen && !isInterface && !isEnum) { + // Generate a default constructor, since + // this is a regular class and there are no constructors + if (wrappedDefs.length() > 0) { + wrappedDefs.append("\n "); + } + wrappedDefs.append(defaultConstructor(tree)); + } + } + bodyBegin = dis.getStartPosition(tree.defs.head); + } + Object defs = wrappedDefs.length() == 1 + ? wrappedDefs.first() + : new CompoundWrap(wrappedDefs.toArray()); + if (bodyBegin < 0) { + int brace = source.indexOf('{', classBegin); + if (brace < 0 || brace >= classEnd) { + throw new IllegalArgumentException("No brace found: " + source.substring(classBegin, classEnd)); + } + bodyBegin = brace + 1; + } + // body includes openning brace + result = new CompoundWrap( + new RangeWrap(source, new Range(classBegin, bodyBegin)), + defs, + "\n}" + ); + } + + // Corral the body + @Override + public void visitMethodDef(JCMethodDecl tree) { + int methodBegin = dis.getStartPosition(tree); + int methodEnd = dis.getEndPosition(tree); + //debugWrap("+visitMethodDef: %d-%d = %s\n", methodBegin, methodEnd, + // source.substring(methodBegin, methodEnd)); + int bodyBegin = dis.getStartPosition(tree.getBody()); + if (bodyBegin < 0) { + bodyBegin = source.indexOf('{', methodBegin); + if (bodyBegin > methodEnd) { + bodyBegin = -1; + } + } + if (bodyBegin > 0) { + //debugWrap("-visitMethodDef BEGIN: %d = '%s'\n", bodyBegin, + // source.substring(methodBegin, bodyBegin)); + Range noBodyRange = new Range(methodBegin, bodyBegin); + result = new CompoundWrap( + new RangeWrap(source, noBodyRange), + resolutionExceptionBlock); + } else { + Range range = new Range(methodBegin, methodEnd); + result = new RangeWrap(source, range); + } + } + + // Remove initializer, if present + @Override + public void visitVarDef(JCVariableDecl tree) { + int begin = dis.getStartPosition(tree); + int end = dis.getEndPosition(tree); + if (tree.init == null) { + result = new RangeWrap(source, new Range(begin, end)); + } else { + int sinit = dis.getStartPosition(tree.init); + int eq = source.lastIndexOf('=', sinit); + if (eq < begin) { + throw new IllegalArgumentException("Equals not found before init: " + source + " @" + sinit); + } + result = new CompoundWrap(new RangeWrap(source, new Range(begin, eq - 1)), ";"); + } } @Override - public void visitBlock(JCBlock tree) { - // Top-level executable blocks (usually method bodies) are corralled - super.visitBlock((tree.flags & STATIC) != 0 - ? tree - : resolutionExceptionBlock()); + public void visitTree(JCTree tree) { + throw new IllegalArgumentException("Unexpected tree: " + tree); } - @Override - public void visitVarDef(JCVariableDecl tree) { - // No field inits in corralled classes - tree.init = null; - super.visitVarDef(tree); - } - - @Override - public void visitClassDef(JCClassDecl tree) { - if ((tree.mods.flags & (INTERFACE | ENUM)) == 0 && - !tree.getMembers().stream() - .anyMatch(t -> t.getKind() == Tree.Kind.METHOD && - ((MethodTree) t).getName() == tree.name.table.names.init)) { - // Generate a default constructor, since - // this is a regular class and there are no constructors - ListBuffer<JCTree> ndefs = new ListBuffer<>(); - ndefs.addAll(tree.defs); - ndefs.add(make.MethodDef(make.Modifiers(PUBLIC), - tree.name.table.names.init, - null, List.nil(), List.nil(), List.nil(), - resolutionExceptionBlock(), null)); - tree.defs = ndefs.toList(); - } - super.visitClassDef(tree); - } - - // Build a compiler tree for an exception throwing block, e.g.: - // { - // throw new jdk.jshell.spi.SPIResolutionException(9); - // } - private JCBlock resolutionExceptionBlock() { - if (resolutionExceptionBlock == null) { - JCExpression expClass = null; - // Split the exception class name at dots - for (String id : SPIResolutionException.class.getName().split("\\.")) { - Name nm = names.fromString(id); - if (expClass == null) { - expClass = make.Ident(nm); - } else { - expClass = make.Select(expClass, nm); - } - } - JCNewClass exp = make.NewClass(null, - null, expClass, List.of(make.Literal(keyIndex)), null); - resolutionExceptionBlock = make.Block(0L, List.of(make.Throw(exp))); - } - return resolutionExceptionBlock; + void debugWrap(String format, Object... args) { + //state.debug(this, InternalDebugControl.DBG_WRAP, format, args); } }
--- a/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, 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 @@ -44,7 +44,6 @@ import com.sun.source.tree.NewClassTree; import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; -import com.sun.source.util.TreeScanner; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.Pretty; import java.io.IOException; @@ -622,7 +621,6 @@ name = "$" + ++varNumber; } } - TreeDissector dis = TreeDissector.createByFirstClass(pt); ExpressionInfo varEI = ExpressionToTypeInfo.localVariableTypeForInitializer(compileSource, state, true); String declareTypeName; @@ -634,6 +632,7 @@ fullTypeName = varEI.fullTypeName; displayTypeName = varEI.displayTypeName; + TreeDissector dis = TreeDissector.createByFirstClass(pt); Pair<Wrap, Wrap> anonymous2Member = anonymous2Member(varEI, compileSource, new Range(0, compileSource.length()), dis, expr.getExpression()); guts = Wrap.tempVarWrap(anonymous2Member.second.wrapped(), declareTypeName, name, anonymous2Member.first); @@ -680,8 +679,8 @@ String name = klassTree.getSimpleName().toString(); DiagList modDiag = modifierDiagnostics(klassTree.getModifiers(), dis, false); TypeDeclKey key = state.keyMap.keyForClass(name); - // Corralling mutates. Must be last use of pt, unitTree, klassTree - Wrap corralled = new Corraller(key.index(), pt.getContext()).corralType(klassTree); + // Corralling + Wrap corralled = new Corraller(dis, key.index(), compileSource).corralType(klassTree); Wrap guts = Wrap.classMemberWrap(compileSource); Snippet snip = new TypeDeclSnippet(key, userSource, guts, @@ -752,8 +751,8 @@ Tree returnType = mt.getReturnType(); DiagList modDiag = modifierDiagnostics(mt.getModifiers(), dis, true); MethodKey key = state.keyMap.keyForMethod(name, parameterTypes); - // Corralling mutates. Must be last use of pt, unitTree, mt - Wrap corralled = new Corraller(key.index(), pt.getContext()).corralMethod(mt); + // Corralling + Wrap corralled = new Corraller(dis, key.index(), compileSource).corralMethod(mt); if (modDiag.hasErrors()) { return compileFailResult(modDiag, userSource, Kind.METHOD);
--- a/src/jdk.jshell/share/classes/jdk/jshell/GeneralWrap.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.jshell/share/classes/jdk/jshell/GeneralWrap.java Thu Jun 20 22:06:48 2019 +0200 @@ -28,7 +28,10 @@ /** * Common interface for all wrappings of snippet source to Java source. * - * @author Robert Field + * Snippet index is index into the source of the snippet. Note: If the snippet is a sub-range of + * the source, the index is not the index in the snippet. + * + * Wrap index is index into the wrapped snippet. */ interface GeneralWrap {
--- a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, 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 @@ -301,7 +301,7 @@ SourcePositions sp = at.trees().getSourcePositions(); CompilationUnitTree topLevel = at.firstCuTree(); List<Suggestion> result = new ArrayList<>(); - TreePath tp = pathFor(topLevel, sp, code.snippetIndexToWrapIndex(cursor)); + TreePath tp = pathFor(topLevel, sp, code, cursor); if (tp != null) { Scope scope = at.trees().getScope(tp); Predicate<Element> accessibility = createAccessibilityFilter(at, tp); @@ -563,7 +563,10 @@ } } - private TreePath pathFor(CompilationUnitTree topLevel, SourcePositions sp, int pos) { + private TreePath pathFor(CompilationUnitTree topLevel, SourcePositions sp, GeneralWrap wrap, int snippetEndPos) { + int wrapEndPos = snippetEndPos == 0 + ? wrap.snippetIndexToWrapIndex(snippetEndPos) + : wrap.snippetIndexToWrapIndex(snippetEndPos - 1) + 1; TreePath[] deepest = new TreePath[1]; new TreePathScanner<Void, Void>() { @@ -576,7 +579,7 @@ long end = sp.getEndPosition(topLevel, tree); long prevEnd = deepest[0] != null ? sp.getEndPosition(topLevel, deepest[0].getLeaf()) : -1; - if (start <= pos && pos <= end && + if (start <= wrapEndPos && wrapEndPos <= end && (start != end || prevEnd != end || deepest[0] == null || deepest[0].getParentPath().getLeaf() != getCurrentPath().getLeaf())) { deepest[0] = new TreePath(getCurrentPath(), tree); @@ -1176,7 +1179,7 @@ return proc.taskFactory.analyze(codeWrap, List.of(keepParameterNames), at -> { SourcePositions sp = at.trees().getSourcePositions(); CompilationUnitTree topLevel = at.firstCuTree(); - TreePath tp = pathFor(topLevel, sp, codeWrap.snippetIndexToWrapIndex(cursor)); + TreePath tp = pathFor(topLevel, sp, codeWrap, cursor); if (tp == null) return Collections.emptyList(); @@ -1526,7 +1529,7 @@ return proc.taskFactory.analyze(codeWrap, at -> { SourcePositions sp = at.trees().getSourcePositions(); CompilationUnitTree topLevel = at.firstCuTree(); - TreePath tp = pathFor(topLevel, sp, codeWrap.snippetIndexToWrapIndex(codeFin.length())); + TreePath tp = pathFor(topLevel, sp, codeWrap, codeFin.length()); if (tp.getLeaf().getKind() != Kind.IDENTIFIER) { return new QualifiedNames(Collections.emptyList(), -1, true, false); }
--- a/src/jdk.jshell/share/classes/jdk/jshell/Wrap.java Mon Jun 17 17:18:22 2019 +0200 +++ b/src/jdk.jshell/share/classes/jdk/jshell/Wrap.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,6 @@ /** * Wrapping of source into Java methods, fields, etc. All but outer layer * wrapping with imports and class. - * - * @author Robert Field */ abstract class Wrap implements GeneralWrap { @@ -184,7 +182,7 @@ public static final class Range { final int begin; - final int end; + final int end; // exclusive Range(int begin, int end) { this.begin = begin; @@ -216,7 +214,7 @@ @Override public String toString() { - return "Range[" + begin + "," + end + "]"; + return "Range[" + begin + "," + end + ")"; } } @@ -280,8 +278,12 @@ before += s.length(); } else if (o instanceof Wrap) { Wrap w = (Wrap) o; - if (sni >= w.firstSnippetIndex() && sni <= w.lastSnippetIndex()) { - return w.snippetIndexToWrapIndex(sni) + before; + if (sni >= w.firstSnippetIndex() && sni < w.lastSnippetIndex()) { + int wwi = w.snippetIndexToWrapIndex(sni); + debugWrap("\nCommoundWrap.snippetIndexToWrapIndex: SnippetIndex(%d) -> WrapIndex(%d + %d = %d)" + + "\n === %s", + sni, wwi, before, wwi + before, wrapped()); + return wwi + before; } before += w.wrapped().length(); } @@ -300,8 +302,8 @@ w = (Wrap) o; int len = w.wrapped().length(); if ((wi - before) <= len) { - //System.err.printf("Defer to wrap %s - wi: %d. before; %d -- %s >>> %s\n", - // w, wi, before, w.debugPos(wi - before), w.wrapped()); + debugWrap("CommoundWrap.wrapIndexToWrap: Defer to wrap %s - wi: %d. before; %d >>> %s\n", + w, wi, before, w.wrapped()); return w; } before += len; @@ -321,9 +323,10 @@ Wrap w = (Wrap) o; int len = w.wrapped().length(); if ((wi - before) <= len) { - //System.err.printf("Defer to wrap %s - wi: %d. before; %d -- %s >>> %s\n", - // w, wi, before, w.debugPos(wi - before), w.wrapped()); - return w.wrapIndexToSnippetIndex(wi - before); + int si = w.wrapIndexToSnippetIndex(wi - before); + debugWrap("\nCommoundWrap.wrapIndexToSnippetIndex: WrapIndex(%d) -> SnippetIndex(%d)\n", + wi, si); + return si; } before += len; } @@ -369,7 +372,7 @@ } else if (o instanceof Wrap) { w = (Wrap) o; int lns = countLines(w.wrapped()); - if ((wline - before) < lns) { + if ((wline - before) <= lns) { return w; } before += lns; @@ -388,7 +391,7 @@ } else if (o instanceof Wrap) { Wrap w = (Wrap) o; int lns = countLines(w.wrapped()); - if ((wline - before) < lns) { + if ((wline - before) <= lns) { return w.wrapLineToSnippetLine(wline - before); } before += lns; @@ -409,16 +412,21 @@ @Override public String toString() { - return "CompoundWrap(" + Arrays.stream(os).map(Object::toString).collect(joining(",")) + ")"; + return "CompoundWrap(" + Arrays.stream(os) + .map(o -> (o instanceof String) + ? "\"" + o + "\"" + : o.toString()) + .collect(joining(",")) + + ")"; } } - private static class RangeWrap extends Wrap { + static class RangeWrap extends Wrap { final Range range; - final String wrapped; - final int firstSnline; - final int lastSnline; + final String wrapped; // The snippet portion of the source + final int firstSnline; // Line count to start of snippet portion + final int lastSnline; // Line count to end of snippet portion RangeWrap(String snippetSource, Range usedWithinSnippet) { this.range = usedWithinSnippet; @@ -436,24 +444,39 @@ @Override public int snippetIndexToWrapIndex(int sni) { if (sni < range.begin) { + debugWrap("\nRangeWrap.snippetIndexToWrapIndex: ERR before SnippetIndex(%d) -> WrapIndex(%d + %d = %d)\n", + sni, 0); return 0; } if (sni > range.end) { + debugWrap("\nRangeWrap.snippetIndexToWrapIndex: ERR after SnippetIndex(%d) -> WrapIndex(%d + %d = %d)\n", + sni, range.length()); return range.length(); } - return sni - range.begin; + int wi = sni - range.begin; + debugWrap("\nRangeWrap.snippetIndexToWrapIndex: SnippetIndex(%d) -> WrapIndex(%d + %d = %d)" + + "\n === %s", + sni, sni, range.begin, sni - range.begin, wrapped()); + return wi; } @Override public int wrapIndexToSnippetIndex(int wi) { if (wi < 0) { + debugWrap("\nRangeWrap.wrapIndexToSnippetIndex: ERR before WrapIndex(%d) -> SnippetIndex(%d)\n", + wi, 0); return 0; // bad index } int max = range.length(); if (wi > max) { - wi = max; + debugWrap("\nRangeWrap.wrapIndexToSnippetIndex: ERR after WrapIndex(%d) -> SnippetIndex(%d)\n", + wi, max + range.begin); + return max + range.begin; } - return wi + range.begin; + int sni = wi + range.begin; + debugWrap("\nRangeWrap.wrapIndexToSnippetIndex: WrapIndex(%d) -> SnippetIndex(%d)\n", + wi, sni); + return sni; } @Override @@ -535,4 +558,9 @@ super(" public static ", wtype, brackets + " ", wname, semi(wname)); } } + + void debugWrap(String format, Object... args) { + //System.err.printf(format, args); + //state.debug(this, InternalDebugControl.DBG_WRAP, format, args); + } }
--- a/test/hotspot/jtreg/ProblemList-graal.txt Mon Jun 17 17:18:22 2019 +0200 +++ b/test/hotspot/jtreg/ProblemList-graal.txt Thu Jun 20 22:06:48 2019 +0200 @@ -43,8 +43,6 @@ compiler/graalunit/JttThreadsTest.java 8207757 generic-all -compiler/jvmci/SecurityRestrictionsTest.java 8181837 generic-all - compiler/unsafe/UnsafeGetConstantField.java 8181833 generic-all compiler/unsafe/UnsafeGetStableArrayElement.java 8181833 generic-all compiler/unsafe/UnsafeOffHeapBooleanTest.java 8181833 generic-all @@ -62,7 +60,7 @@ gc/g1/TestPeriodicCollection.java 8196611 generic-all gc/g1/TestFromCardCacheIndex.java 8196611 generic-all gc/parallel/TestPrintGCDetailsVerbose.java 8196611 generic-all -vm/gc/InfiniteList.java 8196611 generic-all +gc/InfiniteList.java 8196611 generic-all vmTestbase/gc/lock/jni/jnilock001/TestDescription.java 8196611 generic-all vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java 8196611 generic-all @@ -149,16 +147,16 @@ # jvmti tests vmTestbase/nsk/jvmti/PopFrame/popframe009/TestDescription.java 8195639 generic-all -vmTestbase/nsk/jvmti/ForceEarlyReturn/ForceEarlyReturn001/TestDescription.java 8195674 generic-all -vmTestbase/nsk/jvmti/ForceEarlyReturn/ForceEarlyReturn002/TestDescription.java 8195674 generic-all +vmTestbase/nsk/jvmti/ForceEarlyReturn/ForceEarlyReturn001/TestDescription.java 8195674,8195635 generic-all +vmTestbase/nsk/jvmti/ForceEarlyReturn/ForceEarlyReturn002/TestDescription.java 8195674,8195635 generic-all runtime/appcds/cacheObject/RedefineClassTest.java 8204506 macosx-all -vmTestbase/nsk/jvmti/scenarios/hotswap/HS102/hs102t001/TestDescription.java 8204506 macosx-all +vmTestbase/nsk/jvmti/scenarios/hotswap/HS102/hs102t001/TestDescription.java 8204506,8195635 macosx-all,generic-all vmTestbase/nsk/jvmti/scenarios/hotswap/HS102/hs102t002/TestDescription.java 8204506 macosx-all -vmTestbase/nsk/jvmti/PopFrame/popframe001/TestDescription.java 8207013 generic-all -vmTestbase/nsk/jvmti/PopFrame/popframe003/TestDescription.java 8207013 generic-all -vmTestbase/nsk/jvmti/PopFrame/popframe005/TestDescription.java 8207013 generic-all +vmTestbase/nsk/jvmti/PopFrame/popframe001/TestDescription.java 8207013,8195635 generic-all +vmTestbase/nsk/jvmti/PopFrame/popframe003/TestDescription.java 8207013,8195635 generic-all +vmTestbase/nsk/jvmti/PopFrame/popframe005/TestDescription.java 8207013,8195635 generic-all vmTestbase/nsk/jvmti/StopThread/stopthrd007/TestDescription.java 8207013 generic-all serviceability/jvmti/FieldAccessWatch/FieldAccessWatch.java 8202482 generic-all @@ -176,7 +174,6 @@ vmTestbase/nsk/jdi/BScenarios/hotswap/tc08x001/TestDescription.java 8195635 generic-all vmTestbase/nsk/jdi/BScenarios/hotswap/tc10x002/TestDescription.java 8195635 generic-all vmTestbase/nsk/jdi/MethodExitEvent/returnValue/returnValue003/returnValue003.java 8195635 generic-all -vmTestbase/nsk/jdi/Scenarios/invokeMethod/popframes001/TestDescription.jav 8195635 generic-all vmTestbase/nsk/jdi/Scenarios/invokeMethod/popframes001/TestDescription.java 8195635 generic-all vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes001/TestDescription.java 8195635 generic-all vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses002/TestDescription.java 8195635 generic-all @@ -184,14 +181,8 @@ vmTestbase/nsk/jdi/stress/serial/forceEarlyReturn002/TestDescription.java 8195635 generic-all vmTestbase/nsk/jdi/stress/serial/mixed002/TestDescription.java 8195635 generic-all vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java 8195635 generic-all -vmTestbase/nsk/jvmti/ForceEarlyReturn/ForceEarlyReturn001/TestDescription.java 8195635 generic-all -vmTestbase/nsk/jvmti/ForceEarlyReturn/ForceEarlyReturn002/TestDescription.java 8195635 generic-all -vmTestbase/nsk/jvmti/PopFrame/popframe001/TestDescription.java 8195635 generic-all -vmTestbase/nsk/jvmti/PopFrame/popframe003/TestDescription.java 8195635 generic-all -vmTestbase/nsk/jvmti/PopFrame/popframe005/TestDescription.java 8195635 generic-all vmTestbase/nsk/jvmti/scenarios/capability/CM01/cm01t007/TestDescription.java 8195635 generic-all vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 8195635 generic-all -vmTestbase/nsk/jvmti/scenarios/hotswap/HS102/hs102t001/TestDescription.java 8195635 generic-all vmTestbase/nsk/jvmti/scenarios/hotswap/HS201/hs201t001/TestDescription.java 8195635 generic-all vmTestbase/nsk/jvmti/scenarios/hotswap/HS201/hs201t002/TestDescription.java 8195635 generic-all vmTestbase/nsk/jvmti/scenarios/hotswap/HS202/hs202t002/hs202t002.java 8195635 generic-all
--- a/test/hotspot/jtreg/ProblemList.txt Mon Jun 17 17:18:22 2019 +0200 +++ b/test/hotspot/jtreg/ProblemList.txt Thu Jun 20 22:06:48 2019 +0200 @@ -49,8 +49,8 @@ compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java 8163894 generic-all compiler/tiered/LevelTransitionTest.java 8067651 generic-all -compiler/types/correctness/CorrectnessTest.java 8225620 solaris-sparcv9 -compiler/types/correctness/OffTest.java 8225620 solaris-sparcv9 +compiler/types/correctness/CorrectnessTest.java 8225670,8225620 generic-all,solaris-sparcv9 +compiler/types/correctness/OffTest.java 8225670,8225620 generic-all,solaris-sparcv9 compiler/c2/Test6852078.java 8194310 generic-all compiler/c2/Test8004741.java 8214904 generic-all @@ -80,7 +80,6 @@ # :hotspot_runtime -runtime/SharedArchiveFile/SASymbolTableTest.java 8193639 solaris-all runtime/jni/terminatedThread/TestTerminatedThread.java 8219652 aix-ppc64 ############################################################################# @@ -107,8 +106,6 @@ serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java 8193639 solaris-all serviceability/sa/ClhsdbScanOops.java 8193639,8211767 solaris-all,linux-ppc64le,linux-ppc64 serviceability/sa/ClhsdbSource.java 8193639,8211767 solaris-all,linux-ppc64le,linux-ppc64 -serviceability/sa/ClhsdbSymbol.java 8193639 solaris-all -serviceability/sa/ClhsdbSymbolTable.java 8193639 solaris-all serviceability/sa/ClhsdbThread.java 8193639,8211767 solaris-all,linux-ppc64le,linux-ppc64 serviceability/sa/ClhsdbVmStructsDump.java 8193639 solaris-all serviceability/sa/ClhsdbWhere.java 8193639,8211767 solaris-all,linux-ppc64le,linux-ppc64
--- a/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Command.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/Command.java Thu Jun 20 22:06:48 2019 +0200 @@ -33,8 +33,8 @@ public enum Command { COMPILEONLY("compileonly", ".*", "-Xbatch"), EXCLUDE("exclude", "", "-Xbatch"), - INLINE("inline", ".*", "-Xbatch"), - DONTINLINE("dontinline", "", "-Xbatch"), + INLINE("inline", ".*", "-Xbatch", "-XX:InlineSmallCode=4000"), + DONTINLINE("dontinline", "", "-Xbatch", "-XX:InlineSmallCode=4000"), LOG("log", "", "-XX:+UnlockDiagnosticVMOptions", "-XX:+LogCompilation", "-XX:LogFile=" + LogProcessor.LOG_FILE), PRINT("print", ""),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/classFileParserBug/EmptyUnqName.jasm Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019, 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 EmptyUnqName version 56:0 { + + public Method "<init>":"()V" stack 1 locals 1 { + aload_0; + invokespecial Method java/lang/Object."<init>":"()V"; + return; + } + + public static Method main:"([Ljava/lang/String;)V" stack 2 locals 1 { + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + ldc String "Testing method param types"; + invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V"; + return; + } + + public static Method func:"(L;)V" stack 0 locals 1 { + return; + } + +} // end Class EmptyUnqName
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/classFileParserBug/TestEmptyUnqName.java Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, 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 8225789 + * @summary Test that an unqualified name of "L;" causes a ClassFormatError exception. + * @compile EmptyUnqName.jasm + * @run main/othervm -Xverify:remote TestEmptyUnqName + */ + +public class TestEmptyUnqName { + public static void main(String args[]) throws Throwable { + + System.out.println("Regression test for bug 8225789"); + + try { + Class newClass = Class.forName("EmptyUnqName"); + throw new RuntimeException("Expected ClassFormatError exception not thrown"); + } catch (java.lang.ClassFormatError e) { + if (!e.getMessage().contains("Class name is empty or contains illegal character")) { + throw new RuntimeException("Wrong ClassFormatError: " + e.getMessage()); + } + } + } +}
--- a/test/hotspot/jtreg/runtime/verifier/TestSigParse.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/hotspot/jtreg/runtime/verifier/TestSigParse.java Thu Jun 20 22:06:48 2019 +0200 @@ -63,7 +63,7 @@ throw new RuntimeException("Expected ClasFormatError exception not thrown"); } catch (java.lang.ClassFormatError e) { String eMsg = e.getMessage(); - if (!eMsg.contains("Class name contains illegal character")) { + if (!eMsg.contains("Class name is empty or contains illegal character")) { throw new RuntimeException("Unexpected exception: " + eMsg); } }
--- a/test/jdk/ProblemList-aot.txt Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/ProblemList-aot.txt Thu Jun 20 22:06:48 2019 +0200 @@ -30,3 +30,5 @@ java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java 8222445 windows-x64 java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java 8222445 windows-x64 java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java 8222445 windows-x64 +java/lang/reflect/PublicMethods/PublicMethodsTest.java 8226309 generic-all +java/lang/constant/MethodTypeDescTest.java 8225349 windows-x64
--- a/test/jdk/ProblemList-graal.txt Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/ProblemList-graal.txt Thu Jun 20 22:06:48 2019 +0200 @@ -76,30 +76,15 @@ java/lang/ref/SoftReference/Pin.java 8196611 generic-all java/lang/Runtime/exec/LotsOfOutput.java 8196611 generic-all java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java 8196611 generic-all -vm/gc/InfiniteList.java 8196611 generic-all # tests require pop_frame and force_early_return capabilities -com/sun/jdi/RedefineTTYLineNumber.java 8195635 generic-all -com/sun/jdi/RedefineG.java 8195635 generic-all -com/sun/jdi/RedefineCrossStart.java 8195635 generic-all -com/sun/jdi/PopSynchronousTest.java 8195635 generic-all -com/sun/jdi/RedefineTTYLineNumber.java 8195635 generic-all -com/sun/jdi/RedefineG.java 8195635 generic-all -com/sun/jdi/RedefineCrossStart.java 8195635 generic-all -com/sun/jdi/PopSynchronousTest.java 8195635 generic-all -com/sun/jdi/PopAsynchronousTest.java 8195635 generic-all +com/sun/jdi/EarlyReturnTest.java 8195635 generic-all com/sun/jdi/PopAndStepTest.java 8195635 generic-all com/sun/jdi/PopAsynchronousTest.java 8195635 generic-all -com/sun/jdi/PopAndStepTest.java 8195635 generic-all -com/sun/jdi/EarlyReturnTest.java 8195635 generic-all +com/sun/jdi/PopSynchronousTest.java 8195635 generic-all +com/sun/jdi/RedefineCrossStart.java 8195635 generic-all +com/sun/jdi/RedefineG.java 8195635 generic-all com/sun/jdi/RedefineTTYLineNumber.java 8195635 generic-all -com/sun/jdi/RedefineG.java 8195635 generic-all -com/sun/jdi/RedefineCrossStart.java 8195635 generic-all -com/sun/jdi/PopSynchronousTest.java 8195635 generic-all -com/sun/jdi/PopAsynchronousTest.java 8195635 generic-all -com/sun/jdi/PopAndStepTest.java 8195635 generic-all -com/sun/jdi/EarlyReturnTest.java 8195635 generic-all -com/sun/jdi/EarlyReturnTest.java 8195635 generic-all # Next JFR tests fail with Graal. Assuming 8193210. jdk/jfr/event/compiler/TestCodeSweeper.java 8193210 generic-all
--- a/test/jdk/java/net/Authenticator/AuthNPETest.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/AuthNPETest.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, 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 @@ -24,11 +24,15 @@ import java.io.*; import java.net.*; import java.util.*; +import jdk.test.lib.net.URIBuilder; /** * @test * @bug 4662246 * @summary REGRESSION: plugin 14x client authentication dialog returns NullPointerException + * @library /test/lib + * @run main/othervm AuthNPETest + * @run main/othervm -Djava.net.preferIPv6Addresses=true AuthNPETest */ public class AuthNPETest { @@ -53,45 +57,45 @@ "Content-Type: text/html; charset=iso-8859-1\r\n" + "Content-Length: 10\r\n\r\n"; - BasicServer (ServerSocket s) { + BasicServer(ServerSocket s) { server = s; } - void readAll (Socket s) throws IOException { + void readAll(Socket s) throws IOException { byte[] buf = new byte [128]; - InputStream is = s.getInputStream (); + InputStream is = s.getInputStream(); s.setSoTimeout(1000); try { while (is.read(buf) > 0) ; } catch (SocketTimeoutException x) { } } - public void run () { + public void run() { try { - System.out.println ("Server 1: accept"); - s = server.accept (); - System.out.println ("accepted"); + System.out.println("Server 1: accept"); + s = server.accept(); + System.out.println("accepted"); os = s.getOutputStream(); - os.write (reply1.getBytes()); - readAll (s); - s.close (); + os.write(reply1.getBytes()); + readAll(s); + s.close(); - System.out.println ("Server 2: accept"); - s = server.accept (); - System.out.println ("accepted"); + System.out.println("Server 2: accept"); + s = server.accept(); + System.out.println("accepted"); os = s.getOutputStream(); - os.write ((reply2+"HelloWorld").getBytes()); - readAll (s); - s.close (); + os.write((reply2+"HelloWorld").getBytes()); + readAll(s); + s.close(); } catch (Exception e) { System.out.println (e); } - finished (); + finished(); } - public synchronized void finished () { + public synchronized void finished() { notifyAll(); } @@ -99,48 +103,54 @@ static class MyAuthenticator extends Authenticator { - MyAuthenticator () { - super (); + MyAuthenticator() { + super(); } int count = 0; - public PasswordAuthentication getPasswordAuthentication () + public PasswordAuthentication getPasswordAuthentication() { - count ++; - System.out.println ("Auth called"); - return (new PasswordAuthentication ("user", "passwordNotCheckedAnyway".toCharArray())); + count++; + System.out.println("Auth called"); + return (new PasswordAuthentication("user", "passwordNotCheckedAnyway".toCharArray())); } - public int getCount () { - return (count); + public int getCount() { + return count; } } - static void read (InputStream is) throws IOException { + static void read(InputStream is) throws IOException { int c; - System.out.println ("reading"); + System.out.println("reading"); while ((c=is.read()) != -1) { - System.out.write (c); + System.out.write(c); } - System.out.println (""); - System.out.println ("finished reading"); + System.out.println(""); + System.out.println("finished reading"); } - public static void main (String args[]) throws Exception { - MyAuthenticator auth = new MyAuthenticator (); - Authenticator.setDefault (auth); - ServerSocket ss = new ServerSocket (0); - int port = ss.getLocalPort (); - BasicServer server = new BasicServer (ss); + public static void main(String args[]) throws Exception { + MyAuthenticator auth = new MyAuthenticator(); + Authenticator.setDefault(auth); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ServerSocket ss = new ServerSocket(); + ss.bind(new InetSocketAddress(loopback, 0)); + int port = ss.getLocalPort(); + BasicServer server = new BasicServer(ss); synchronized (server) { server.start(); System.out.println ("client 1"); - URL url = new URL ("http://localhost:"+port); - URLConnection urlc = url.openConnection (); - InputStream is = urlc.getInputStream (); - read (is); + URL url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .toURL(); + URLConnection urlc = url.openConnection(Proxy.NO_PROXY); + InputStream is = urlc.getInputStream(); + read(is); is.close(); } }
--- a/test/jdk/java/net/Authenticator/B4678055.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/B4678055.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, 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,16 @@ * @test * @bug 4678055 * @modules java.base/sun.net.www - * @library ../../../sun/net/www/httptest/ + * @library ../../../sun/net/www/httptest/ /test/lib * @build HttpCallback TestHttpServer ClosedChannelList HttpTransaction - * @run main B4678055 + * @run main/othervm B4678055 + * @run main/othervm -Djava.net.preferIPv6Addresses=true B4678055 * @summary Basic Authentication fails with multiple realms */ import java.io.*; import java.net.*; +import jdk.test.lib.net.URIBuilder; public class B4678055 implements HttpCallback { @@ -125,12 +127,21 @@ public static void main (String[] args) throws Exception { MyAuthenticator auth = new MyAuthenticator (); Authenticator.setDefault (auth); + ProxySelector.setDefault(ProxySelector.of(null)); // no proxy try { - server = new TestHttpServer (new B4678055(), 1, 10, 0); - System.out.println ("Server: listening on port: " + server.getLocalPort()); - client ("http://localhost:"+server.getLocalPort()+"/d1/foo.html"); - client ("http://localhost:"+server.getLocalPort()+"/d2/foo.html"); - client ("http://localhost:"+server.getLocalPort()+"/d2/foo.html"); + InetAddress loopback = InetAddress.getLoopbackAddress(); + server = new TestHttpServer(new B4678055(), 1, 10, loopback, 0); + String serverURL = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(server.getLocalPort()) + .path("/") + .build() + .toString(); + System.out.println("Server: listening at: " + serverURL); + client(serverURL + "d1/foo.html"); + client(serverURL + "d2/foo.html"); + client(serverURL + "d2/foo.html"); } catch (Exception e) { if (server != null) { server.terminate();
--- a/test/jdk/java/net/Authenticator/B4759514.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/B4759514.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, 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,16 @@ * @test * @bug 4759514 * @modules java.base/sun.net.www - * @library ../../../sun/net/www/httptest/ + * @library ../../../sun/net/www/httptest/ /test/lib * @build HttpCallback TestHttpServer ClosedChannelList HttpTransaction - * @run main B4759514 + * @run main/othervm B4759514 + * @run main/othervm -Djava.net.preferIPv6Addresses=true B4759514 * @summary Digest Authentication is erroniously quoting the nc value, contrary to RFC 2617 */ import java.io.*; import java.net.*; +import jdk.test.lib.net.URIBuilder; public class B4759514 implements HttpCallback { @@ -97,10 +99,19 @@ public static void main (String[] args) throws Exception { MyAuthenticator auth = new MyAuthenticator (); Authenticator.setDefault (auth); + ProxySelector.setDefault(ProxySelector.of(null)); // no proxy try { - server = new TestHttpServer (new B4759514(), 1, 10, 0); - System.out.println ("Server: listening on port: " + server.getLocalPort()); - client ("http://localhost:"+server.getLocalPort()+"/d1/foo.html"); + InetAddress loopback = InetAddress.getLoopbackAddress(); + server = new TestHttpServer (new B4759514(), 1, 10, loopback, 0); + String serverURL = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(server.getLocalPort()) + .path("/") + .build() + .toString(); + System.out.println("Server: listening at: " + serverURL); + client(serverURL + "d1/foo.html"); } catch (Exception e) { if (server != null) { server.terminate();
--- a/test/jdk/java/net/Authenticator/B4769350.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/B4769350.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ * @modules jdk.httpserver * @run main/othervm B4769350 server * @run main/othervm B4769350 proxy + * @run main/othervm -Djava.net.preferIPv6Addresses=true B4769350 server + * @run main/othervm -Djava.net.preferIPv6Addresses=true B4769350 proxy * @summary proxy authentication username and password caching only works in serial case * Run in othervm since the test sets system properties that are read by the * networking stack and cached when the HTTP handler is invoked, and previous @@ -99,7 +101,8 @@ } public void startServer() { - InetSocketAddress addr = new InetSocketAddress(0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + InetSocketAddress addr = new InetSocketAddress(loopback, 0); try { server = HttpServer.create(addr, 0); @@ -456,17 +459,28 @@ System.out.println ("Server: listening on port: " + server.getPort()); if (proxy) { - System.setProperty ("http.proxyHost", "localhost"); + System.setProperty ("http.proxyHost", + InetAddress.getLoopbackAddress().getHostAddress()); System.setProperty ("http.proxyPort", Integer.toString(server.getPort())); doProxyTests ("www.foo.com", server); } else { - doServerTests ("localhost:"+server.getPort(), server); + ProxySelector.setDefault(ProxySelector.of(null)); + doServerTests (authority(server.getPort()), server); } } } + static String authority(int port) { + InetAddress loopback = InetAddress.getLoopbackAddress(); + String hoststr = loopback.getHostAddress(); + if (hoststr.indexOf(':') > -1) { + hoststr = "[" + hoststr + "]"; + } + return hoststr + ":" + port; + } + public static void except (String s, Server server) { server.close(); throw new RuntimeException (s); @@ -496,4 +510,3 @@ } } } -
--- a/test/jdk/java/net/Authenticator/B4921848.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/B4921848.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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,17 @@ * @test * @bug 4921848 * @modules java.base/sun.net.www - * @library ../../../sun/net/www/httptest/ + * @library ../../../sun/net/www/httptest/ /test/lib * @build HttpCallback TestHttpServer ClosedChannelList HttpTransaction * @run main/othervm -Dhttp.auth.preference=basic B4921848 + * @run main/othervm -Djava.net.preferIPv6Addresses=true + * -Dhttp.auth.preference=basic B4921848 * @summary Allow user control over authentication schemes */ import java.io.*; import java.net.*; +import jdk.test.lib.net.URIBuilder; public class B4921848 implements HttpCallback { @@ -88,10 +91,19 @@ public static void main (String[] args) throws Exception { MyAuthenticator auth = new MyAuthenticator (); Authenticator.setDefault (auth); + ProxySelector.setDefault(ProxySelector.of(null)); // no proxy try { - server = new TestHttpServer (new B4921848(), 1, 10, 0); - System.out.println ("Server started: listening on port: " + server.getLocalPort()); - client ("http://localhost:"+server.getLocalPort()+"/d1/d2/d3/foo.html"); + InetAddress loopback = InetAddress.getLoopbackAddress(); + server = new TestHttpServer (new B4921848(), 1, 10, loopback, 0); + String serverURL = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(server.getLocalPort()) + .path("/") + .build() + .toString(); + System.out.println("Server: listening at: " + serverURL); + client(serverURL + "d1/d2/d3/foo.html"); } catch (Exception e) { if (server != null) { server.terminate();
--- a/test/jdk/java/net/Authenticator/B4933582.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/B4933582.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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,10 +21,15 @@ * questions. */ +// Note: this test saves a cache.ser file in the scratch directory, +// which the cache implementation will load its configuration +// from. Therefore adding several @run lines does not work. + /* * @test * @bug 4933582 - * @library ../../../sun/net/www/httptest + * @key intermittent + * @library ../../../sun/net/www/httptest /test/lib * @modules java.base/sun.net.www * java.base/sun.net.www.protocol.http * @build HttpCallback HttpTransaction TestHttpServer B4933582 @@ -34,6 +39,7 @@ import java.net.*; import java.util.*; import sun.net.www.protocol.http.*; +import jdk.test.lib.net.URIBuilder; public class B4933582 implements HttpCallback { @@ -133,12 +139,21 @@ public static void main (String[] args) throws Exception { MyAuthenticator auth = new MyAuthenticator (); Authenticator.setDefault (auth); + ProxySelector.setDefault(ProxySelector.of(null)); // no proxy + InetAddress loopback = InetAddress.getLoopbackAddress(); CacheImpl cache; try { - server = new TestHttpServer (new B4933582(), 1, 10, 0); + server = new TestHttpServer(new B4933582(), 1, 10, loopback, 0); cache = new CacheImpl (server.getLocalPort()); AuthCacheValue.setAuthCache (cache); - client ("http://localhost:"+server.getLocalPort()+"/d1/foo.html"); + String serverURL = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(server.getLocalPort()) + .path("/") + .build() + .toString(); + client(serverURL + "d1/foo.html"); } finally { if (server != null) { server.terminate(); @@ -157,7 +172,7 @@ while (true) { try { server = new TestHttpServer(new B4933582(), 1, 10, - cache.getPort()); + loopback, cache.getPort()); break; } catch (BindException e) { if (retries++ < 5) { @@ -173,7 +188,14 @@ try { AuthCacheValue.setAuthCache(cache); - client("http://localhost:" + server.getLocalPort() + "/d1/foo.html"); + String serverURL = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(server.getLocalPort()) + .path("/") + .build() + .toString(); + client(serverURL + "d1/foo.html"); } finally { if (server != null) { server.terminate();
--- a/test/jdk/java/net/Authenticator/B4962064.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/B4962064.java Thu Jun 20 22:06:48 2019 +0200 @@ -28,6 +28,7 @@ * @library ../../../sun/net/www/httptest/ * @build HttpCallback TestHttpServer ClosedChannelList HttpTransaction * @run main/othervm B4962064 + * @run main/othervm -Djava.net.preferIPv6Addresses=true B4962064 * @summary Extend Authenticator to provide access to request URI and server/proxy */ @@ -91,18 +92,24 @@ public static void main (String[] args) throws Exception { try { - server = new TestHttpServer (new B4962064(), 1, 10, 0); + InetAddress address = InetAddress.getLoopbackAddress(); + InetAddress resolved = InetAddress.getByName(address.getHostName()); + System.out.println("Lookup: " + address + " -> \"" + + address.getHostName() + "\" -> " + + resolved); + server = new TestHttpServer (new B4962064(), 1, 10, address, 0); int port = server.getLocalPort(); - System.setProperty ("http.proxyHost", "localhost"); + String proxyHost = address.equals(resolved) + ? address.getHostName() + : address.getHostAddress(); + System.setProperty ("http.proxyHost", proxyHost); System.setProperty ("http.proxyPort", Integer.toString (port)); MyAuthenticator auth = new MyAuthenticator (); Authenticator.setDefault (auth); System.out.println ("Server started: listening on port: " + port); - //String s = new String ("http://localhost:"+port+"/d1/d2/d3/foo.html"); String s = new String ("http://foo.com/d1/d2/d3/foo.html"); urlsave = new URL (s); client (s); - //s = new String ("http://localhost:"+port+"/dr/d3/foo.html"); s = new String ("http://bar.com/dr/d3/foo.html"); urlsave = new URL (s); client (s);
--- a/test/jdk/java/net/Authenticator/B6870935.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/B6870935.java Thu Jun 20 22:06:48 2019 +0200 @@ -26,6 +26,8 @@ * @bug 6870935 * @modules java.base/sun.net.www * @run main/othervm -Dhttp.nonProxyHosts="" -Dhttp.auth.digest.validateProxy=true B6870935 + * @run main/othervm -Djava.net.preferIPv6Addresses=true + * -Dhttp.nonProxyHosts="" -Dhttp.auth.digest.validateProxy=true B6870935 */ import java.io.*; @@ -80,18 +82,21 @@ public void run () { try { + System.out.println("Server started"); Socket s1 = s.accept (); is = s1.getInputStream (); os = s1.getOutputStream (); is.read (); os.write (reply1.getBytes()); + System.out.println("First response sent"); Thread.sleep (2000); s1.close (); + System.out.println("First connection closed"); s1 = s.accept (); is = s1.getInputStream (); os = s1.getOutputStream (); - is.read (); + // is.read (); // need to get the cnonce out of the response MessageHeader header = new MessageHeader (is); String raw = header.findValue ("Proxy-Authorization"); @@ -115,12 +120,16 @@ cnstring, passwd, username ) +"\r\n"; os.write (reply.getBytes()); + System.out.println("Second response sent"); Thread.sleep (2000); s1.close (); + System.out.println("Second connection closed"); } catch (Exception e) { System.out.println (e); e.printStackTrace(); + } finally { + System.out.println("Server finished"); } } @@ -225,8 +234,17 @@ DigestServer server; ServerSocket sock; + InetAddress address = InetAddress.getLoopbackAddress(); + InetAddress resolved = InetAddress.getByName(address.getHostName()); + System.out.println("Lookup: " + + address + " -> \"" + address.getHostName() + "\" -> " + + resolved); + String proxyHost = address.equals(resolved) + ? address.getHostName() + : address.getHostAddress(); try { - sock = new ServerSocket (0); + sock = new ServerSocket(); + sock.bind(new InetSocketAddress(address, 0)); port = sock.getLocalPort (); } catch (Exception e) { @@ -238,12 +256,12 @@ server.start (); try { - Authenticator.setDefault (new MyAuthenticator ()); - SocketAddress addr = new InetSocketAddress (InetAddress.getLoopbackAddress(), port); + SocketAddress addr = InetSocketAddress.createUnresolved(proxyHost, port); Proxy proxy = new Proxy (Proxy.Type.HTTP, addr); String s = "http://www.ibm.com"; URL url = new URL(s); + System.out.println("opening connection through proxy: " + addr); java.net.URLConnection conURL = url.openConnection(proxy); InputStream in = conURL.getInputStream(); @@ -255,6 +273,9 @@ catch(IOException e) { e.printStackTrace(); error = true; + sock.close(); + } finally { + server.join(); } if (error) { throw new RuntimeException ("Error in test");
--- a/test/jdk/java/net/Authenticator/B8034170.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/B8034170.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, 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 @@ -24,13 +24,16 @@ import java.io.*; import java.net.*; import java.util.*; +import jdk.test.lib.net.URIBuilder; /** * @test * @bug 8034170 * @summary Digest authentication interop issue + * @library /test/lib * @run main/othervm B8034170 unquoted * @run main/othervm -Dhttp.auth.digest.quoteParameters=true B8034170 quoted + * @run main/othervm -Djava.net.preferIPv6Addresses=true B8034170 unquoted */ public class B8034170 { @@ -176,14 +179,21 @@ MyAuthenticator3 auth = new MyAuthenticator3 (); Authenticator.setDefault (auth); - ServerSocket ss = new ServerSocket (0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ServerSocket ss = new ServerSocket(); + ss.bind(new InetSocketAddress(loopback, 0)); int port = ss.getLocalPort (); BasicServer server = new BasicServer (ss); synchronized (server) { server.start(); System.out.println ("client 1"); - URL url = new URL ("http://localhost:"+port+"/d1/d2/d3/foo.html"); - URLConnection urlc = url.openConnection (); + URL url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .path("/d1/d2/d3/foo.html") + .toURL(); + URLConnection urlc = url.openConnection(Proxy.NO_PROXY); InputStream is = urlc.getInputStream (); read (is); is.close ();
--- a/test/jdk/java/net/Authenticator/BasicTest.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/BasicTest.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -24,11 +24,15 @@ import java.io.*; import java.net.*; import java.util.*; +import jdk.test.lib.net.URIBuilder; /** * @test * @bug 4474947 * @summary fix for bug #4244472 is incomplete - HTTP authorization still needs work + * @library /test/lib + * @run main/othervm BasicTest + * @run main/othervm -Djava.net.preferIPv6Addresses=true BasicTest */ /* @@ -151,19 +155,28 @@ public static void main (String args[]) throws Exception { MyAuthenticator auth = new MyAuthenticator (); Authenticator.setDefault (auth); - ServerSocket ss = new ServerSocket (0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ServerSocket ss = new ServerSocket(); + ss.bind(new InetSocketAddress(loopback, 0)); int port = ss.getLocalPort (); BasicServer server = new BasicServer (ss); synchronized (server) { server.start(); System.out.println ("client 1"); - URL url = new URL ("http://localhost:"+port+"/d1/d2/d3/foo.html"); - URLConnection urlc = url.openConnection (); + String base = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .path("/") + .build() + .toString(); + URL url = new URL(base + "d1/d2/d3/foo.html"); + URLConnection urlc = url.openConnection(Proxy.NO_PROXY); InputStream is = urlc.getInputStream (); read (is); System.out.println ("client 2"); - url = new URL ("http://localhost:"+port+"/d1/foo.html"); - urlc = url.openConnection (); + url = new URL(base + "d1/foo.html"); + urlc = url.openConnection(Proxy.NO_PROXY); is = urlc.getInputStream (); read (is); server.wait ();
--- a/test/jdk/java/net/Authenticator/BasicTest3.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/BasicTest3.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, 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 @@ -24,11 +24,15 @@ import java.io.*; import java.net.*; import java.util.*; +import jdk.test.lib.net.URIBuilder; /** * @test * @bug 4513440 * @summary BasicAuthentication is zeroing out the given password + * @library /test/lib + * @run main/othervm BasicTest3 + * @run main/othervm -Djava.net.preferIPv6Addresses=true BasicTest3 */ public class BasicTest3 { @@ -130,14 +134,21 @@ public static void main (String args[]) throws Exception { MyAuthenticator3 auth = new MyAuthenticator3 (); Authenticator.setDefault (auth); - ServerSocket ss = new ServerSocket (0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ServerSocket ss = new ServerSocket(); + ss.bind(new InetSocketAddress(loopback, 0)); int port = ss.getLocalPort (); BasicServer3 server = new BasicServer3 (ss); synchronized (server) { server.start(); System.out.println ("client 1"); - URL url = new URL ("http://localhost:"+port+"/d1/d2/d3/foo.html"); - URLConnection urlc = url.openConnection (); + URL url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .path("/d1/d2/d3/foo.html") + .toURL(); + URLConnection urlc = url.openConnection(Proxy.NO_PROXY); InputStream is = urlc.getInputStream (); read (is); is.close ();
--- a/test/jdk/java/net/Authenticator/BasicTest4.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/BasicTest4.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, 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 @@ -24,11 +24,15 @@ import java.io.*; import java.net.*; import java.util.*; +import jdk.test.lib.net.URIBuilder; /** * @test * @bug 4623722 * @summary performance hit for Basic Authentication + * @library /test/lib + * @run main/othervm BasicTest4 + * @run main/othervm -Djava.net.preferIPv6Addresses=true BasicTest4 */ public class BasicTest4 { @@ -59,12 +63,17 @@ static boolean checkFor (InputStream in, char[] seq) throws IOException { System.out.println ("checkfor"); + StringBuilder message = new StringBuilder(); try { int i=0, count=0; while (true) { int c = in.read(); - if (c == -1) + if (c == -1) { + System.out.println(new String(seq) + " not found in \n<<" + + message + ">>"); return false; + } + message.append((char)c); count++; if (c == seq[i]) { i++; @@ -77,6 +86,7 @@ } } catch (SocketTimeoutException e) { + System.out.println("checkFor: " + e); return false; } } @@ -194,23 +204,33 @@ public static void main (String args[]) throws Exception { MyAuthenticator auth = new MyAuthenticator (); Authenticator.setDefault (auth); - ServerSocket ss = new ServerSocket (0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ServerSocket ss = new ServerSocket(); + ss.bind(new InetSocketAddress(loopback, 0)); int port = ss.getLocalPort (); BasicServer server = new BasicServer (ss); synchronized (server) { server.start(); System.out.println ("client 1"); - URL url = new URL ("http://localhost:"+port+"/d1/d3/foo.html"); - URLConnection urlc = url.openConnection (); + String base = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .path("/d1/") + .build() + .toString(); + System.out.println("Base URL: " + base); + URL url = new URL (base + "d3/foo.html"); + URLConnection urlc = url.openConnection(Proxy.NO_PROXY); InputStream is = urlc.getInputStream (); read (is); System.out.println ("client 2"); - url = new URL ("http://localhost:"+port+"/d1/d2/bar.html"); - urlc = url.openConnection (); + url = new URL (base + "d2/bar.html"); + urlc = url.openConnection(Proxy.NO_PROXY); is = urlc.getInputStream (); System.out.println ("client 3"); - url = new URL ("http://localhost:"+port+"/d1/d4/foobar.html"); - urlc = url.openConnection (); + url = new URL (base + "d4/foobar.html"); + urlc = url.openConnection(Proxy.NO_PROXY); is = urlc.getInputStream (); read (is); server.wait ();
--- a/test/jdk/java/net/Authenticator/Deadlock.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/Authenticator/Deadlock.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,10 @@ * @test * @bug 6648001 * @modules jdk.httpserver + * @library /test/lib * @run main/othervm/timeout=20 -ea:sun.net.www.protocol.http.AuthenticationInfo -Dhttp.auth.serializeRequests=true Deadlock + * @run main/othervm/timeout=20 -Djava.net.preferIPv6Addresses=true + * -ea:sun.net.www.protocol.http.AuthenticationInfo -Dhttp.auth.serializeRequests=true Deadlock * @summary cancelling HTTP authentication causes deadlock */ @@ -34,8 +37,10 @@ import java.io.InputStream; import java.io.IOException; import java.net.HttpURLConnection; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.PasswordAuthentication; +import java.net.Proxy; import java.net.URL; import com.sun.net.httpserver.BasicAuthenticator; import com.sun.net.httpserver.Headers; @@ -44,12 +49,14 @@ import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpPrincipal; import com.sun.net.httpserver.HttpServer; +import jdk.test.lib.net.URIBuilder; public class Deadlock { public static void main (String[] args) throws Exception { Handler handler = new Handler(); - InetSocketAddress addr = new InetSocketAddress (0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + InetSocketAddress addr = new InetSocketAddress (loopback, 0); HttpServer server = HttpServer.create(addr, 0); HttpContext ctx = server.createContext("/test", handler); BasicAuthenticator a = new BasicAuthenticator("foobar@test.realm") { @@ -97,8 +104,13 @@ URL url; HttpURLConnection urlc; try { - url = new URL("http://localhost:"+server.getAddress().getPort()+"/test/foo.html"); - urlc = (HttpURLConnection)url.openConnection (); + url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(server.getAddress().getPort()) + .path("/test/foo.html") + .toURLUnchecked(); + urlc = (HttpURLConnection)url.openConnection (Proxy.NO_PROXY); } catch (IOException e) { error = true; return;
--- a/test/jdk/java/net/CookieHandler/CookieHandlerTest.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/CookieHandler/CookieHandlerTest.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019 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 @@ -24,7 +24,9 @@ /* @test * @summary Unit test for java.net.CookieHandler * @bug 4696506 + * @library /test/lib * @run main/othervm CookieHandlerTest + * @run main/othervm -Djava.net.preferIPv6Addresses=true CookieHandlerTest * @author Yingxian Wang */ @@ -34,6 +36,7 @@ import java.net.*; import java.util.*; import java.io.*; +import jdk.test.lib.net.URIBuilder; public class CookieHandlerTest implements Runnable { static Map<String,String> cookies; @@ -92,15 +95,19 @@ CookieHandlerTest() throws Exception { /* start the server */ - ss = new ServerSocket(0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ss = new ServerSocket(); + ss.bind(new InetSocketAddress(loopback, 0)); (new Thread(this)).start(); /* establish http connection to server */ - String uri = "http://localhost:" + - Integer.toString(ss.getLocalPort()); - URL url = new URL(uri); + URL url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(ss.getLocalPort()) + .toURL(); - HttpURLConnection http = (HttpURLConnection)url.openConnection(); + HttpURLConnection http = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY); int respCode = http.getResponseCode(); http.disconnect();
--- a/test/jdk/java/net/CookieHandler/CookieManagerTest.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/CookieHandler/CookieManagerTest.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,8 +57,9 @@ } catch (IOException x) { System.out.println("Debug: caught:" + x); } - System.out.println("Using: \"127.0.0.1\""); - return "127.0.0.1"; + InetAddress loopback = InetAddress.getLoopbackAddress(); + System.out.println("Using: \"" + loopback.getHostAddress() + "\""); + return loopback.getHostAddress(); } public static void main(String[] args) throws Exception { @@ -73,7 +74,7 @@ public static void startHttpServer() throws IOException { httpTrans = new CookieTransactionHandler(); - server = HttpServer.create(new InetSocketAddress(0), 0); + server = HttpServer.create(new InetSocketAddress(hostAddress, 0), 0); server.createContext("/", httpTrans); server.start(); }
--- a/test/jdk/java/net/CookieHandler/EmptyCookieHeader.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/CookieHandler/EmptyCookieHeader.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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,6 +26,9 @@ * @bug 8015799 * @modules jdk.httpserver * @summary HttpURLConnection.getHeaderFields() throws IllegalArgumentException + * @library /test/lib + * @run main EmptyCookieHeader + * @run main/othervm -Djava.net.preferIPv6Addresses=true EmptyCookieHeader */ import com.sun.net.httpserver.*; @@ -33,6 +36,7 @@ import java.io.OutputStream; import java.net.*; import java.util.*; +import jdk.test.lib.net.URIBuilder; public class EmptyCookieHeader { @@ -43,11 +47,17 @@ public void runTest() throws Exception { final CookieHandler oldHandler = CookieHandler.getDefault(); CookieHandler.setDefault(new TestCookieHandler()); - HttpServer s = HttpServer.create(new InetSocketAddress(0), 0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + HttpServer s = HttpServer.create(new InetSocketAddress(loopback, 0), 0); try { startServer(s); - URL url = new URL("http://localhost:" + s.getAddress().getPort() + "/"); - HttpURLConnection c = (HttpURLConnection)url.openConnection(); + URL url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(s.getAddress().getPort()) + .path("/") + .toURL(); + HttpURLConnection c = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY); c.getHeaderFields(); } finally { CookieHandler.setDefault(oldHandler);
--- a/test/jdk/java/net/CookieHandler/LocalHostCookie.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/CookieHandler/LocalHostCookie.java Thu Jun 20 22:06:48 2019 +0200 @@ -33,8 +33,11 @@ /* * @test * @bug 7169142 + * @key intermittent * @modules jdk.httpserver - * @summary CookieHandler does not work with localhost + * @summary CookieHandler does not work with localhost. This requires + * binding to the wildcard address and might fail intermittently + * due to port reuse issues. * @run main/othervm LocalHostCookie */ public class LocalHostCookie { @@ -126,4 +129,3 @@ } } } -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/net/httpclient/BodySubscribersTest.java Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2019, 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 + * @summary Basic test for the standard BodySubscribers default behavior + * @bug 8225583 + * @run testng BodySubscribersTest + */ + +import java.net.http.HttpResponse.BodySubscriber; +import java.nio.ByteBuffer; +import java.nio.file.Path; +import java.util.List; +import java.util.concurrent.Flow; +import java.util.function.Supplier; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import static java.lang.System.out; +import static java.net.http.HttpResponse.BodySubscribers.*; +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.nio.file.StandardOpenOption.CREATE; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.expectThrows; +import static org.testng.Assert.fail; + +public class BodySubscribersTest { + + static final Class<NullPointerException> NPE = NullPointerException.class; + + // Supplier of BodySubscriber<?>, with a descriptive name + static class BSSupplier implements Supplier<BodySubscriber<?>> { + private final Supplier<BodySubscriber<?>> supplier; + private final String name; + private BSSupplier(Supplier<BodySubscriber<?>> supplier, String name) { + this.supplier = supplier; + this.name = name; + } + static BSSupplier create(String name, Supplier<BodySubscriber<?>> supplier) { + return new BSSupplier(supplier, name); + } + @Override public BodySubscriber<?> get() { return supplier.get(); } + @Override public String toString() { return name; } + } + + static class LineSubscriber implements Flow.Subscriber<String> { + @Override public void onSubscribe(Flow.Subscription subscription) { } + @Override public void onNext(String item) { fail(); } + @Override public void onError(Throwable throwable) { fail(); } + @Override public void onComplete() { fail(); } + } + + static class BBSubscriber implements Flow.Subscriber<List<ByteBuffer>> { + @Override public void onSubscribe(Flow.Subscription subscription) { } + @Override public void onNext(List<ByteBuffer> item) { fail(); } + @Override public void onError(Throwable throwable) { fail(); } + @Override public void onComplete() { fail(); } + } + + @DataProvider(name = "bodySubscriberSuppliers") + public Object[][] bodySubscriberSuppliers() { ; + List<Supplier<BodySubscriber<?>>> list = List.of( + BSSupplier.create("ofByteArray", () -> ofByteArray()), + BSSupplier.create("ofInputStream", () -> ofInputStream()), + BSSupplier.create("ofBAConsumer", () -> ofByteArrayConsumer(ba -> { })), + BSSupplier.create("ofLines", () -> ofLines(UTF_8)), + BSSupplier.create("ofPublisher", () -> ofPublisher()), + BSSupplier.create("ofFile", () -> ofFile(Path.of("f"))), + BSSupplier.create("ofFile-opts)", () -> ofFile(Path.of("f"), CREATE)), + BSSupplier.create("ofString", () -> ofString(UTF_8)), + BSSupplier.create("buffering", () -> buffering(ofByteArray(), 10)), + BSSupplier.create("discarding", () -> discarding()), + BSSupplier.create("mapping", () -> mapping(ofString(UTF_8), s -> s)), + BSSupplier.create("replacing", () -> replacing("hello")), + BSSupplier.create("fromSubscriber-1", () -> fromSubscriber(new BBSubscriber())), + BSSupplier.create("fromSubscriber-2", () -> fromSubscriber(new BBSubscriber(), s -> s)), + BSSupplier.create("fromLineSubscriber-1", () -> fromLineSubscriber(new LineSubscriber())), + BSSupplier.create("fromLineSubscriber-2", () -> fromLineSubscriber(new LineSubscriber(), s -> s, UTF_8, ",")) + ); + + return list.stream().map(x -> new Object[] { x }).toArray(Object[][]::new); + } + + @Test(dataProvider = "bodySubscriberSuppliers") + void nulls(Supplier<BodySubscriber<?>> bodySubscriberSupplier) { + BodySubscriber<?> bodySubscriber = bodySubscriberSupplier.get(); + boolean subscribed = false; + + do { + assertNotNull(bodySubscriber.getBody()); + assertNotNull(bodySubscriber.getBody()); + assertNotNull(bodySubscriber.getBody()); + expectThrows(NPE, () -> bodySubscriber.onSubscribe(null)); + expectThrows(NPE, () -> bodySubscriber.onSubscribe(null)); + expectThrows(NPE, () -> bodySubscriber.onSubscribe(null)); + + expectThrows(NPE, () -> bodySubscriber.onNext(null)); + expectThrows(NPE, () -> bodySubscriber.onNext(null)); + expectThrows(NPE, () -> bodySubscriber.onNext(null)); + expectThrows(NPE, () -> bodySubscriber.onNext(null)); + + expectThrows(NPE, () -> bodySubscriber.onError(null)); + expectThrows(NPE, () -> bodySubscriber.onError(null)); + expectThrows(NPE, () -> bodySubscriber.onError(null)); + + if (!subscribed) { + out.println("subscribing"); + // subscribe the Subscriber and repeat + bodySubscriber.onSubscribe(new Flow.Subscription() { + @Override public void request(long n) { /* do nothing */ } + @Override public void cancel() { fail(); } + }); + subscribed = true; + continue; + } + break; + } while (true); + } + + @Test(dataProvider = "bodySubscriberSuppliers") + void subscribeMoreThanOnce(Supplier<BodySubscriber<?>> bodySubscriberSupplier) { + BodySubscriber<?> bodySubscriber = bodySubscriberSupplier.get(); + bodySubscriber.onSubscribe(new Flow.Subscription() { + @Override public void request(long n) { /* do nothing */ } + @Override public void cancel() { fail(); } + }); + + for (int i = 0; i < 5; i++) { + var subscription = new Flow.Subscription() { + volatile boolean cancelled; + @Override public void request(long n) { fail(); } + @Override public void cancel() { cancelled = true; } + }; + bodySubscriber.onSubscribe(subscription); + assertTrue(subscription.cancelled); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/net/httpclient/RelayingPublishers.java Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2019, 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 jdk.test.lib.util.FileUtils; +import org.testng.annotations.Test; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.http.HttpRequest.BodyPublisher; +import java.net.http.HttpRequest.BodyPublishers; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Flow; + +import static org.testng.Assert.assertEquals; + +/* + * @test + * @summary Verifies that some of the standard BodyPublishers relay exception + * rather than throw it + * @bug 8226303 + * @library /test/lib + * @run testng/othervm RelayingPublishers + */ +public class RelayingPublishers { + + @Test + public void ofFile0() throws IOException { + Path directory = Files.createDirectory(Path.of("d")); + // Even though the path exists, the publisher should not be able + // to read from it, as that path denotes a directory, not a file + BodyPublisher pub = BodyPublishers.ofFile(directory); + CompletableSubscriber<ByteBuffer> s = new CompletableSubscriber<>(); + pub.subscribe(s); + s.future().join(); + // Interestingly enough, it's FileNotFoundException if a file + // is a directory + assertEquals(s.future().join().getClass(), FileNotFoundException.class); + } + + @Test + public void ofFile1() throws IOException { + Path file = Files.createFile(Path.of("f")); + BodyPublisher pub = BodyPublishers.ofFile(file); + FileUtils.deleteFileWithRetry(file); + CompletableSubscriber<ByteBuffer> s = new CompletableSubscriber<>(); + pub.subscribe(s); + assertEquals(s.future().join().getClass(), FileNotFoundException.class); + } + + @Test + public void ofByteArrays() { + List<byte[]> bytes = new ArrayList<>(); + bytes.add(null); + BodyPublisher pub = BodyPublishers.ofByteArrays(bytes); + CompletableSubscriber<ByteBuffer> s = new CompletableSubscriber<>(); + pub.subscribe(s); + assertEquals(s.future().join().getClass(), NullPointerException.class); + } + + static class CompletableSubscriber<T> implements Flow.Subscriber<T> { + + final CompletableFuture<Throwable> f = new CompletableFuture<>(); + + @Override + public void onSubscribe(Flow.Subscription subscription) { + subscription.request(1); + } + + @Override + public void onNext(T item) { + f.completeExceptionally(new RuntimeException("Unexpected onNext")); + } + + @Override + public void onError(Throwable throwable) { + f.complete(throwable); + } + + @Override + public void onComplete() { + f.completeExceptionally(new RuntimeException("Unexpected onNext")); + } + + CompletableFuture<Throwable> future() { + return f.copy(); + } + } +}
--- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/Http1HeaderParserTest.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/Http1HeaderParserTest.java Thu Jun 20 22:06:48 2019 +0200 @@ -375,6 +375,17 @@ "HTTP/1.1 200OK\r\n\rT", "HTTP/1.1 200OK\rT", + + "HTTP/1.0 FOO\r\n", + + "HTTP/1.1 BAR\r\n", + + "HTTP/1.1 +99\r\n", + + "HTTP/1.1 -22\r\n", + + "HTTP/1.1 -20 \r\n" + }; Arrays.stream(bad).forEach(responses::add);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/util/HashMap/ToArray.java Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2019, 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.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.stream.LongStream; + +/* + * @test + * @summary HashMap.toArray() behavior tests + * @author tvaleev + */ +public class ToArray { + public static void main(String[] args) { + checkMap(false); + checkMap(true); + checkSet(false); + checkSet(true); + } + + private static <T extends Comparable<T>> void checkToArray(String message, T[] expected, Collection<T> collection, + boolean ignoreOrder) { + if (ignoreOrder) { + Arrays.sort(expected); + } + checkToObjectArray(message, expected, collection, ignoreOrder); + checkToTypedArray(message, expected, Arrays.copyOf(expected, 0), collection, ignoreOrder); + checkToTypedArray(message, expected, expected.clone(), collection, ignoreOrder); + if (expected.length > 0) { + T[] biggerArray = Arrays.copyOf(expected, expected.length * 2); + System.arraycopy(expected, 0, biggerArray, expected.length, expected.length); + checkToTypedArray(message, expected, biggerArray, collection, ignoreOrder); + } + } + + private static <T extends Comparable<T>> void checkToTypedArray(String message, T[] expected, T[] inputArray, + Collection<T> collection, boolean ignoreOrder) { + T[] res = collection.toArray(inputArray); + if (expected.length <= inputArray.length && res != inputArray) { + throw new AssertionError(message + ": not the same array returned"); + } + if (res.getClass() != expected.getClass()) { + throw new AssertionError(message + ": wrong class returned: " + res.getClass()); + } + if (res.length < expected.length) { + throw new AssertionError(message + ": length is smaller than expected: " + res.length + " < " + expected.length); + } + if (ignoreOrder) { + Arrays.sort(res, 0, Math.min(res.length, expected.length)); + } + if (inputArray.length <= expected.length) { + if (!Arrays.equals(res, expected)) { + throw new AssertionError(message + ": not equal: " + Arrays.toString(expected) + " != " + + Arrays.toString(res)); + } + } else { + int mismatch = Arrays.mismatch(expected, res); + if (mismatch != expected.length) { + throw new AssertionError(message + ": mismatch at " + mismatch); + } + if (res[expected.length] != null) { + throw new AssertionError(message + ": no null at position " + expected.length); + } + // The tail of bigger array after expected.length position must be untouched + mismatch = Arrays + .mismatch(expected, 1, expected.length, res, expected.length + 1, res.length); + if (mismatch != -1) { + throw new AssertionError(message + ": mismatch at " + mismatch); + } + } + } + + private static <T extends Comparable<T>> void checkToObjectArray(String message, T[] expected, + Collection<T> collection, boolean ignoreOrder) { + Object[] objects = collection.toArray(); + if (objects.getClass() != Object[].class) { + throw new AssertionError(message + ": wrong class returned: " + objects.getClass()); + } + if (ignoreOrder) { + Arrays.sort(objects); + } + int mismatch = Arrays.mismatch(expected, objects); + if (mismatch != -1) { + throw new AssertionError(message + ": mismatch at " + mismatch); + } + } + + private static void checkMap(boolean ordered) { + Map<String, String> map = ordered ? new LinkedHashMap<>() : new HashMap<>(); + checkToArray("Empty-keys", new String[0], map.keySet(), !ordered); + checkToArray("Empty-values", new String[0], map.values(), !ordered); + + List<String> keys = new ArrayList<>(); + List<String> values = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + keys.add(String.valueOf(i)); + values.add(String.valueOf(i * 2)); + map.put(String.valueOf(i), String.valueOf(i * 2)); + checkToArray(i + "-keys", keys.toArray(new String[0]), map.keySet(), !ordered); + checkToArray(i + "-values", values.toArray(new String[0]), map.values(), !ordered); + } + map.clear(); + checkToArray("Empty-keys", new String[0], map.keySet(), !ordered); + checkToArray("Empty-values", new String[0], map.values(), !ordered); + } + + private static void checkSet(boolean ordered) { + Collection<String> set = ordered ? new LinkedHashSet<>() : new HashSet<>(); + checkToArray("Empty", new String[0], set, !ordered); + set.add("foo"); + checkToArray("One", new String[]{"foo"}, set, !ordered); + set.add("bar"); + checkToArray("Two", new String[]{"foo", "bar"}, set, !ordered); + + Collection<Long> longSet = ordered ? new LinkedHashSet<>() : new HashSet<>(); + for (int x = 0; x < 100; x++) { + longSet.add((long) x); + } + checkToArray("100", LongStream.range(0, 100).boxed().toArray(Long[]::new), longSet, !ordered); + longSet.clear(); + checkToArray("After clear", new Long[0], longSet, !ordered); + for (int x = 0; x < 100; x++) { + longSet.add(((long) x) | (((long) x) << 32)); + } + checkToArray("Collisions", LongStream.range(0, 100).mapToObj(x -> x | (x << 32)) + .toArray(Long[]::new), longSet, !ordered); + } +}
--- a/test/jdk/java/util/zip/ZipFile/MultiThreadedReadTest.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/java/util/zip/ZipFile/MultiThreadedReadTest.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,14 +28,14 @@ * @build jdk.test.lib.Platform * jdk.test.lib.util.FileUtils * @run main MultiThreadedReadTest - * @key randomness */ +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.nio.file.Paths; -import java.util.Random; +import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; @@ -44,7 +44,8 @@ public class MultiThreadedReadTest extends Thread { private static final int NUM_THREADS = 10; - private static final String ZIPFILE_NAME = "large.zip"; + private static final String ZIPFILE_NAME = + System.currentTimeMillis() + "-bug8038491-tmp.large.zip"; private static final String ZIPENTRY_NAME = "random.txt"; private static InputStream is = null; @@ -63,23 +64,30 @@ threadArray[i].join(); } } finally { + long t = System.currentTimeMillis(); FileUtils.deleteFileIfExistsWithRetry(Paths.get(ZIPFILE_NAME)); + System.out.println("Deleting zip file took:" + + (System.currentTimeMillis() - t) + "ms"); } } private static void createZipFile() throws Exception { - try (ZipOutputStream zos = - new ZipOutputStream(new FileOutputStream(ZIPFILE_NAME))) { - - zos.putNextEntry(new ZipEntry(ZIPENTRY_NAME)); - StringBuilder sb = new StringBuilder(); - Random rnd = new Random(); - for(int i = 0; i < 1000; i++) { - // append some random string for ZipEntry - sb.append(Long.toString(rnd.nextLong())); - } - byte[] b = sb.toString().getBytes(); - zos.write(b, 0, b.length); + CRC32 crc32 = new CRC32(); + long t = System.currentTimeMillis(); + File zipFile = new File(ZIPFILE_NAME); + try (FileOutputStream fos = new FileOutputStream(zipFile); + BufferedOutputStream bos = new BufferedOutputStream(fos); + ZipOutputStream zos = new ZipOutputStream(bos)) { + ZipEntry e = new ZipEntry(ZIPENTRY_NAME); + e.setMethod(ZipEntry.STORED); + byte[] toWrite = "BLAH".repeat(10_000).getBytes(); + e.setTime(t); + e.setSize(toWrite.length); + crc32.reset(); + crc32.update(toWrite); + e.setCrc(crc32.getValue()); + zos.putNextEntry(e); + zos.write(toWrite); } } @@ -88,6 +96,7 @@ try { while (is.read() != -1) { } } catch (Exception e) { + System.out.println("read exception:" + e); // Swallow any Exceptions (which are expected) - we're only interested in the crash } }
--- a/test/jdk/javax/net/ssl/SSLSocket/Tls13PacketSize.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/javax/net/ssl/SSLSocket/Tls13PacketSize.java Thu Jun 20 22:06:48 2019 +0200 @@ -53,6 +53,9 @@ @Override protected void runServerApplication(SSLSocket socket) throws Exception { + // Set SO_LINGER in case of slow socket + socket.setSoLinger(true, 10); + // here comes the test logic InputStream sslIS = socket.getInputStream(); OutputStream sslOS = socket.getOutputStream(); @@ -81,6 +84,9 @@ * @see #isCustomizedClientConnection() */ protected void runClientApplication(SSLSocket socket) throws Exception { + // Set SO_LINGER in case of slow socket + socket.setSoLinger(true, 10); + socket.setEnabledProtocols(new String[] {"TLSv1.3"}); InputStream sslIS = socket.getInputStream(); OutputStream sslOS = socket.getOutputStream();
--- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java Thu Jun 20 22:06:48 2019 +0200 @@ -26,11 +26,13 @@ * @test * @bug 8189131 8198240 8191844 8189949 8191031 8196141 8204923 8195774 8199779 * 8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136 - * 8223499 + * 8223499 8225392 * @summary Check root CA entries in cacerts file */ +import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FileInputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.security.KeyStore; import java.security.MessageDigest; import java.security.cert.Certificate; @@ -52,6 +54,11 @@ // The numbers of certs now. private static final int COUNT = 88; + // SHA-256 of cacerts, can be generated with + // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 + private static final String CHECKSUM + = "4E:21:94:7C:1D:49:28:BB:34:B0:40:DF:AE:19:B4:41:C6:B5:8A:EE:EB:D5:DE:B4:EF:07:AF:63:18:73:A6:FE"; + // map of cert alias to SHA-256 fingerprint @SuppressWarnings("serial") private static final Map<String, String> FINGERPRINT_MAP = new HashMap<>() { @@ -255,8 +262,16 @@ public static void main(String[] args) throws Exception { System.out.println("cacerts file: " + CACERTS); md = MessageDigest.getInstance("SHA-256"); + + byte[] data = Files.readAllBytes(Path.of(CACERTS)); + String checksum = toHexString(md.digest(data)); + if (!checksum.equals(CHECKSUM)) { + atLeastOneFailed = true; + System.err.println("ERROR: wrong checksum\n" + checksum); + } + KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(CACERTS), "changeit".toCharArray()); + ks.load(new ByteArrayInputStream(data), "changeit".toCharArray()); // check the count of certs inside if (ks.size() != COUNT) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2019, 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. + */ + +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + +/* + * @test + * @bug 8224829 + * @summary AsyncSSLSocketClose.java has timing issue + * @run main/othervm BlockedAsyncClose + */ + +import javax.net.ssl.*; +import java.io.*; +import java.net.SocketException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class BlockedAsyncClose implements Runnable { + SSLSocket socket; + SSLServerSocket ss; + + // Is the socket ready to close? + private final CountDownLatch closeCondition = new CountDownLatch(1); + + // Where do we find the keystores? + static String pathToStores = "../../../../javax/net/ssl/etc"; + static String keyStoreFile = "keystore"; + static String trustStoreFile = "truststore"; + static String passwd = "passphrase"; + + public static void main(String[] args) throws Exception { + String keyFilename = + System.getProperty("test.src", "./") + "/" + pathToStores + + "/" + keyStoreFile; + String trustFilename = + System.getProperty("test.src", "./") + "/" + pathToStores + + "/" + trustStoreFile; + + System.setProperty("javax.net.ssl.keyStore", keyFilename); + System.setProperty("javax.net.ssl.keyStorePassword", passwd); + System.setProperty("javax.net.ssl.trustStore", trustFilename); + System.setProperty("javax.net.ssl.trustStorePassword", passwd); + + new BlockedAsyncClose(); + } + + public BlockedAsyncClose() throws Exception { + SSLServerSocketFactory sslssf = + (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ss = (SSLServerSocket)sslssf.createServerSocket(); + ss.bind(new InetSocketAddress(loopback, 0)); + + SSLSocketFactory sslsf = + (SSLSocketFactory)SSLSocketFactory.getDefault(); + socket = (SSLSocket)sslsf.createSocket(loopback, ss.getLocalPort()); + SSLSocket serverSoc = (SSLSocket)ss.accept(); + ss.close(); + + (new Thread(this)).start(); + serverSoc.startHandshake(); + + boolean closeIsReady = closeCondition.await(90L, TimeUnit.SECONDS); + if (!closeIsReady) { + System.out.println( + "Ignore, the closure is not ready yet in 90 seconds."); + return; + } + + socket.setSoLinger(true, 10); + System.out.println("Calling Socket.close"); + + // Sleep for a while so that the write thread blocks by hitting the + // output stream buffer limit. + Thread.sleep(1000); + + socket.close(); + System.out.println("ssl socket get closed"); + System.out.flush(); + } + + // block in write + public void run() { + byte[] ba = new byte[1024]; + for (int i = 0; i < ba.length; i++) { + ba[i] = 0x7A; + } + + try { + OutputStream os = socket.getOutputStream(); + int count = 0; + + // 1st round write + count += ba.length; + System.out.println(count + " bytes to be written"); + os.write(ba); + System.out.println(count + " bytes written"); + + // Signal, ready to close. + closeCondition.countDown(); + + // write more + while (true) { + count += ba.length; + System.out.println(count + " bytes to be written"); + os.write(ba); + System.out.println(count + " bytes written"); + } + } catch (SocketException se) { + // the closing may be in progress + System.out.println("interrupted? " + se); + } catch (Exception e) { + if (socket.isClosed() || socket.isOutputShutdown()) { + System.out.println("interrupted, the socket is closed"); + } else { + throw new RuntimeException("interrupted?", e); + } + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sun/security/tools/keytool/ListOrder.java Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019, 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 8225392 + * @summary Comparison builds are failing due to cacerts file + * @library /test/lib + */ + +import jdk.test.lib.SecurityTools; + +import java.util.Random; + +public class ListOrder { + + public static void main(String[] args) throws Throwable { + + Random rand = new Random(); + for (int i = 0; i < 10; i++) { + gen(String.format("a%02d", rand.nextInt(100))); + } + + String last = ""; + for (String line : SecurityTools.keytool( + "-keystore ks -storepass changeit -list").asLines()) { + if (line.contains("PrivateKeyEntry")) { + // This is the line starting with the alias + System.out.println(line); + if (line.compareTo(last) <= 0) { + throw new RuntimeException("Not ordered"); + } else { + last = line; + } + } + } + } + + static void gen(String a) throws Exception { + // Do not check result, there might be duplicated alias(es). + SecurityTools.keytool("-keystore ks -storepass changeit " + + "-keyalg ec -genkeypair -alias " + a + " -dname CN=" + a); + } +}
--- a/test/langtools/ProblemList.txt Mon Jun 17 17:18:22 2019 +0200 +++ b/test/langtools/ProblemList.txt Thu Jun 20 22:06:48 2019 +0200 @@ -37,7 +37,6 @@ jdk/jshell/UserJdiUserRemoteTest.java 8173079 linux-all jdk/jshell/UserInputTest.java 8169536 generic-all -jdk/jshell/ExceptionsTest.java 8200701 windows-all ########################################################################### #
--- a/test/langtools/jdk/jshell/ClassesTest.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/langtools/jdk/jshell/ClassesTest.java Thu Jun 20 22:06:48 2019 +0200 @@ -344,7 +344,7 @@ " public T get() {return null;}\n" + "}", added(VALID), - ste(aClass, Status.RECOVERABLE_DEFINED, Status.VALID, true, null)); + ste(aClass, Status.RECOVERABLE_DEFINED, Status.VALID, false, null)); assertEval("new A()"); }
--- a/test/langtools/jdk/jshell/ExceptionsTest.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/langtools/jdk/jshell/ExceptionsTest.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, 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 @@ -24,7 +24,7 @@ /* * @test * @summary Tests for exceptions - * @bug 8198801 + * @bug 8198801 8212167 * @build KullaTesting TestingInputStream * @run testng ExceptionsTest */ @@ -207,6 +207,49 @@ newStackTraceElement("", "", cr2.snippet(), 1))); } + // test 8212167 + public void throwLineFormat1() { + SnippetEvent se = assertEvalException( + "if (true) { \n" + + " int x = 10; \n" + + " int y = 10 / 0;}" + ); + assertExceptionMatch(se, + new ExceptionInfo(ArithmeticException.class, "/ by zero", + newStackTraceElement("", "", se.snippet(), 3))); + } + + public void throwLineFormat3() { + Snippet sp = methodKey(assertEval( + "int p() \n" + + " { return 4/0; }")); + Snippet sm = methodKey(assertEval( + "int m(int x)\n" + + " \n" + + " {\n" + + " return p() + x; \n" + + " }")); + Snippet sn = methodKey(assertEval( + "int n(int x) {\n" + + " try {\n" + + " return m(x);\n" + + " }\n" + + " catch (Throwable ex) {\n" + + " throw new IllegalArgumentException( \"GOT:\", ex);\n" + + " }\n" + + " }")); + SnippetEvent se = assertEvalException("n(33);"); + assertExceptionMatch(se, + new ExceptionInfo(IllegalArgumentException.class, null, + new ExceptionInfo(ArithmeticException.class, "/ by zero", + newStackTraceElement("", "p", sp, 2), + newStackTraceElement("", "m", sm, 4), + newStackTraceElement("", "n", sn, 3), + newStackTraceElement("", "", se.snippet(), 1)), + newStackTraceElement("", "n", sn, 6), + newStackTraceElement("", "", se.snippet(), 1))); + } + @Test(enabled = false) // TODO 8129427 public void outOfMemory() { assertEval("import java.util.*;"); @@ -333,7 +376,8 @@ } assertEquals(actualElement.getFileName(), expectedElement.getFileName(), message + " : file names"); assertEquals(actualElement.getLineNumber(), expectedElement.getLineNumber(), message + " : line numbers" - + " -- actual: " + actual + ", expected: " + expected); + + " -- actual: " + actualElement.getLineNumber() + ", expected: " + expectedElement.getLineNumber() + + " -- in: " + actualElement.getClassName()); } } }
--- a/test/langtools/jdk/jshell/KullaTesting.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/langtools/jdk/jshell/KullaTesting.java Thu Jun 20 22:06:48 2019 +0200 @@ -911,7 +911,10 @@ public void assertCompletionIncludesExcludes(String code, Boolean isSmart, Set<String> expected, Set<String> notExpected) { List<String> completions = computeCompletions(code, isSmart); - assertTrue(completions.containsAll(expected), String.valueOf(completions)); + assertTrue(completions.containsAll(expected), "Expected completions: " + + String.valueOf(expected) + + ", got: " + + String.valueOf(completions)); assertTrue(Collections.disjoint(completions, notExpected), String.valueOf(completions)); }
--- a/test/langtools/jdk/jshell/WrapperTest.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/langtools/jdk/jshell/WrapperTest.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8159111 + * @bug 8159111 8159740 * @summary test wrappers and dependencies * @modules jdk.jshell/jdk.jshell * @build KullaTesting @@ -62,15 +62,126 @@ assertPosition(swg, src, 15, 6); } - @Test(enabled = false) // TODO 8159740 + // test 8159740 public void testMethodCorralled() { String src = "void glib() { f(); }"; + // _123456789_123456789 Snippet g = methodKey(assertEval(src, added(RECOVERABLE_DEFINED))); SnippetWrapper swg = getState().sourceCodeAnalysis().wrapper(g); - assertWrapperHas(swg, src, Kind.METHOD, "void", "glib"); + assertWrapperHas(swg, src, Kind.METHOD, "SPIResolutionException", + "void", "glib"); + assertPosition(swg, src, 0, 4); assertPosition(swg, src, 5, 4); } + // test 8159740 + public void testClassCorralled0() { + String src = "class AAA { float mmm(double d1234) { return (float) (f0 * d1234); } }"; + // _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED))); + SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a); + assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException", + "class", "AAA", "float", "mmm", "double", "d1234"); + assertPosition(swa, src, 0, 5); + assertPosition(swa, src, 6, 3); + assertPosition(swa, src, 12, 5); + assertPosition(swa, src, 18, 3); + assertPosition(swa, src, 22, 6); + assertPosition(swa, src, 29, 5); + } + + // test 8159740 + public void testClassCorralled() { + String src = "class AAA { int xxx = x0 + 4; float mmm(float ffff) { return f0 * ffff; } }"; + // _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED))); + SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a); + assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException", + "class", "AAA", "int", "xxx", "float", "mmm", "ffff"); + assertPosition(swa, src, 0, 5); + assertPosition(swa, src, 6, 3); + assertPosition(swa, src, 12, 3); + assertPosition(swa, src, 16, 3); + assertPosition(swa, src, 30, 5); + assertPosition(swa, src, 36, 3); + assertPosition(swa, src, 40, 5); + assertPosition(swa, src, 46, 4); + } + + // test 8159740 + public void testClassWithConstructorCorralled() { + String src = "public class AAA { AAA(String b) {} int xxx = x0 + 4; float mmm(float ffff) { return f0 * ffff; } }"; + // _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED))); + SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a); + assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException", + "class", "AAA", "String", "int", "xxx", "float", "mmm", "ffff"); + assertPosition(swa, src, 7, 5); + assertPosition(swa, src, 13, 3); + assertPosition(swa, src, 19, 3); + assertPosition(swa, src, 23, 5); + assertPosition(swa, src, 30, 1); + assertPosition(swa, src, 36, 3); + assertPosition(swa, src, 40, 3); + assertPosition(swa, src, 54, 5); + assertPosition(swa, src, 60, 3); + assertPosition(swa, src, 64, 5); + assertPosition(swa, src, 70, 4); + } + + // test 8159740 + public void testInterfaceCorralled() { + String src = "interface AAA { default float mmm(double d1234) { return (float) (f0 * d1234); } }"; + // _123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED))); + SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a); + assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException", + "interface", "AAA", "float", "mmm", "double", "d1234"); + assertPosition(swa, src, 0, 9); + assertPosition(swa, src, 10, 3); + assertPosition(swa, src, 16, 7); + assertPosition(swa, src, 24, 5); + assertPosition(swa, src, 30, 3); + assertPosition(swa, src, 34, 6); + assertPosition(swa, src, 41, 5); + } + + // test 8159740 + public void testEnumCorralled() { + String src = + "public enum Planet {\n" + + " MERCURY (3.303e+23, 2.4397e6),\n" + + " VENUS (4.869e+24, 6.0518e6),\n" + + " EARTH (5.976e+24, 6.37814e6),\n" + + " MARS (6.421e+23, 3.3972e6),\n" + + " JUPITER (1.9e+27, 7.1492e7),\n" + + " SATURN (5.688e+26, 6.0268e7),\n" + + " URANUS (8.686e+25, 2.5559e7),\n" + + " NEPTUNE (1.024e+26, 2.4746e7);\n" + + "\n" + + " private final double mass; // in kilograms\n" + + " private final double radius; // in meters\n" + + " Planet(double mass, double radius) {\n" + + " this.mass = mass;\n" + + " this.radius = radius;\n" + + " }\n" + + " private double mass() { return mass; }\n" + + " private double radius() { return radius; }\n" + + "\n" + + " double surfaceGravity() {\n" + + " return GRAVITATIONAL_CONSTANT * mass / (radius * radius);\n" + + " }\n" + + " double surfaceWeight(double otherMass) {\n" + + " return otherMass * surfaceGravity();\n" + + " }\n" + + "}\n"; + Snippet a = classKey(assertEval(src, added(RECOVERABLE_DEFINED))); + SnippetWrapper swa = getState().sourceCodeAnalysis().wrapper(a); + assertWrapperHas(swa, src, Kind.TYPE_DECL, "SPIResolutionException", + "enum", "Planet", "double", "mass", "EARTH", "NEPTUNE", "MERCURY", + "radius", "surfaceGravity", "surfaceWeight"); + } + public void testMethodBad() { String src = "void flob() { ?????; }"; List<SnippetWrapper> swl = getState().sourceCodeAnalysis().wrappers(src); @@ -182,23 +293,36 @@ private void assertWrapperHas(SnippetWrapper sw, String source, Kind kind, String... has) { assertEquals(sw.source(), source); assertEquals(sw.kind(), kind); + String s = sw.wrapped(); if (kind == Kind.IMPORT) { - assertTrue(sw.wrapped().contains("import")); + assertHas(s, "import"); } else { String cn = sw.fullClassName(); int idx = cn.lastIndexOf("."); - assertTrue(sw.wrapped().contains(cn.substring(idx+1))); - assertTrue(sw.wrapped().contains("class")); + assertHas(s, cn.substring(idx+1)); + assertHas(s, "class"); } - for (String s : has) { - assertTrue(sw.wrapped().contains(s)); + for (String hx : has) { + assertHas(s, hx); } } + private void assertHas(String s, String has) { + assertTrue(s.contains(has), "Expected to find '" + has + "' in: '" + s + "'"); + } + private void assertPosition(SnippetWrapper sw, String source, int start, int length) { + //System.err.printf("\n#assertPosition:\n# debug-source: %s\n# SnippetWrapper --\n# source: %s\n# wrapped: %s\n", + // source, sw.source(), sw.wrapped()); + //System.err.printf("# start: %d length: %d\n", start, length); int wpg = sw.sourceToWrappedPosition(start); - assertEquals(sw.wrapped().substring(wpg, wpg+length), - source.substring(start, start+length), + //System.err.printf("# wrappedPos: %d\n", wpg); + String wrappedPart = sw.wrapped().substring(wpg, wpg+length); + String sourcePart = source.substring(start, start+length); + //System.err.printf("# wrapped @ wrappedPos: %s\n", wrappedPart); + //System.err.printf("# source @ start: %s\n", sourcePart); + + assertEquals(wrappedPart, sourcePart, "position " + wpg + " in " + sw.wrapped()); assertEquals(sw.wrappedToSourcePosition(wpg), start); }
--- a/test/langtools/tools/javac/T6942649.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/langtools/tools/javac/T6942649.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 6942649 + * @bug 6942649 8225748 * @summary add hidden option to identify location and version of javac classes * @modules jdk.compiler */ @@ -60,7 +60,7 @@ throw new Exception("location of class not found in output"); } - if (!out.contains("MD5 checksum: ")) + if (!out.contains("SHA-256 checksum: ")) throw new Exception("checksum not found in output"); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/processing/model/element/TestExecutableReceiverType.java Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013, 2019, 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 8222369 + * @summary Test behavior of ExecutableElement.getReceiverType + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor TestExecutableReceiverType + * @compile -processor TestExecutableReceiverType -proc:only TestExecutableReceiverType.java + */ + +import java.util.Set; +import java.lang.annotation.*; +import javax.annotation.processing.*; +import javax.lang.model.element.*; +import javax.lang.model.type.*; +import javax.lang.model.util.*; +import static javax.tools.Diagnostic.Kind.*; + +/** + * Verify that proper type objects are returned from ExecutableElement.getReceiverType + */ +public class TestExecutableReceiverType extends JavacTestingAbstractProcessor { + public boolean process(Set<? extends TypeElement> annotations, + RoundEnvironment roundEnv) { + if (!roundEnv.processingOver()) { + int count = 0; + count += testType(elements.getTypeElement("MethodHost")); + count += testType(elements.getTypeElement("MethodHost.Nested")); + + if (count == 0) { + messager.printMessage(ERROR, "No executables visited."); + } + } + return true; + } + + int testType(TypeElement typeElement) { + int count = 0; + for (ExecutableElement executable : + ElementFilter.constructorsIn(typeElement.getEnclosedElements())) { + count += testExecutable(executable); + } + + for (ExecutableElement executable : + ElementFilter.methodsIn(typeElement.getEnclosedElements())) { + count += testExecutable(executable); + } + return count; + } + + int testExecutable(ExecutableElement executable) { + TypeKind expectedKind = executable.getAnnotation(ReceiverTypeKind.class).value(); + TypeKind actualKind = executable.getReceiverType().getKind(); + + if (actualKind != expectedKind) { + messager.printMessage(ERROR, + String.format("Unexpected TypeKind on receiver of %s:" + + " expected %s\t got %s%n", + executable, expectedKind, actualKind)); + } + return 1; + } +} + +@Retention(RetentionPolicy.RUNTIME) +@interface ReceiverTypeKind { + TypeKind value(); +} + +/** + * Class to host various methods, etc. + */ +class MethodHost { + @ReceiverTypeKind(TypeKind.NONE) + public MethodHost() {} + + @ReceiverTypeKind(TypeKind.NONE) + public static void foo() {return;} + + @ReceiverTypeKind(TypeKind.NONE) + public void bar() {return;} + + @ReceiverTypeKind(TypeKind.DECLARED) + public void quux(MethodHost this) {return;} + + private class Nested { + @ReceiverTypeKind(TypeKind.DECLARED) + public Nested(MethodHost MethodHost.this) {} + } +}
--- a/test/langtools/tools/javac/sym/ElementStructureTest.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/langtools/tools/javac/sym/ElementStructureTest.java Thu Jun 20 22:06:48 2019 +0200 @@ -409,7 +409,7 @@ for (VariableElement param : e.getParameters()) { visit(param, p); } - out.write(String.valueOf(e.getReceiverType())); + out.write(String.valueOf(typeMirrorTranslate(e.getReceiverType()))); write(e.getReturnType()); out.write(e.getSimpleName().toString()); writeTypes(e.getThrownTypes()); @@ -425,6 +425,18 @@ return null; } + /** + * Original implementation of getReceiverType returned null + * for many cases where TypeKind.NONE was specified; translate + * back to null to compare against old hashes. + */ + private TypeMirror typeMirrorTranslate(TypeMirror type) { + if (type.getKind() == javax.lang.model.type.TypeKind.NONE) + return null; + else + return type; + } + @Override public Void visitPackage(PackageElement e, Void p) { List<Element> types = new ArrayList<>(e.getEnclosedElements());
--- a/test/langtools/tools/javap/T4884240.java Mon Jun 17 17:18:22 2019 +0200 +++ b/test/langtools/tools/javap/T4884240.java Thu Jun 20 22:06:48 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4884240 + * @bug 4884240 8225748 * @summary additional option required for javap * @modules jdk.jdeps/com.sun.tools.javap */ @@ -47,7 +47,7 @@ if (lines.length < 3 || !lines[0].trim().startsWith("Classfile") || !lines[1].trim().startsWith("Last modified") - || !lines[2].trim().startsWith("MD5")) { + || !lines[2].trim().startsWith("SHA-256")) { System.out.println(sw); throw new Exception("unexpected output"); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/micro/org/openjdk/bench/java/util/HashMapToArray.java Thu Jun 20 22:06:48 2019 +0200 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Fork(3) +@State(Scope.Thread) +public class HashMapToArray { + + @Param({"0", "1", "10", "1000", "100000"}) + public int size; + + @Param({"HashMap", "LinkedHashMap"}) + public String mapType; + + private Map<Integer, Integer> map; + + @Setup + public void setup() { + switch (mapType) { + case "HashMap": + map = new HashMap<>(); + break; + case "LinkedHashMap": + map = new LinkedHashMap<>(); + break; + default: + throw new IllegalStateException(); + } + for (int i = 0; i < size; i++) { + map.put(i, i * i); + } + } + + @Benchmark + public Object[] testKeySetToArray() { + return map.keySet().toArray(); + } + + @Benchmark + public Object[] testKeySetToArrayTyped() { + return map.keySet().toArray(new Integer[0]); + } + + @Benchmark + public Object[] testValuesToArray() { + return map.values().toArray(); + } + + @Benchmark + public Object[] testValuesToArrayTyped() { + return map.values().toArray(new Integer[0]); + } +}