Merge jdk8u242-b04

Wed, 04 Dec 2019 16:23:46 +0000

author
andrew
date
Wed, 04 Dec 2019 16:23:46 +0000
changeset 9790
20258ba5a788
parent 9786
ff1018e27c6e
parent 9789
e55d4d896e30
child 9791
371da86379cf

Merge

     1.1 --- a/src/cpu/ppc/vm/vm_version_ppc.cpp	Wed Nov 27 05:33:18 2019 +0000
     1.2 +++ b/src/cpu/ppc/vm/vm_version_ppc.cpp	Wed Dec 04 16:23:46 2019 +0000
     1.3 @@ -194,6 +194,11 @@
     1.4      FLAG_SET_DEFAULT(UseAESIntrinsics, false);
     1.5    }
     1.6  
     1.7 +  if (UseGHASHIntrinsics) {
     1.8 +    warning("GHASH intrinsics are not available on this CPU");
     1.9 +    FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
    1.10 +  }
    1.11 +
    1.12    if (has_vshasig()) {
    1.13      if (FLAG_IS_DEFAULT(UseSHA)) {
    1.14        UseSHA = true;
     2.1 --- a/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Nov 27 05:33:18 2019 +0000
     2.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Dec 04 16:23:46 2019 +0000
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -129,6 +129,7 @@
    2.11      flog3_op3    = 0x36,
    2.12      edge_op3     = 0x36,
    2.13      fsrc_op3     = 0x36,
    2.14 +    xmulx_op3    = 0x36,
    2.15      impdep2_op3  = 0x37,
    2.16      stpartialf_op3 = 0x37,
    2.17      jmpl_op3     = 0x38,
    2.18 @@ -220,6 +221,8 @@
    2.19      mdtox_opf          = 0x110,
    2.20      mstouw_opf         = 0x111,
    2.21      mstosw_opf         = 0x113,
    2.22 +    xmulx_opf          = 0x115,
    2.23 +    xmulxhi_opf        = 0x116,
    2.24      mxtod_opf          = 0x118,
    2.25      mwtos_opf          = 0x119,
    2.26  
    2.27 @@ -1212,6 +1215,9 @@
    2.28    void movwtos( Register s, FloatRegister d ) { vis3_only();  emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); }
    2.29    void movxtod( Register s, FloatRegister d ) { vis3_only();  emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); }
    2.30  
    2.31 +  void xmulx(Register s1, Register s2, Register d) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(xmulx_op3) | rs1(s1) | opf(xmulx_opf) | rs2(s2)); }
    2.32 +  void xmulxhi(Register s1, Register s2, Register d) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(xmulx_op3) | rs1(s1) | opf(xmulxhi_opf) | rs2(s2)); }
    2.33 +
    2.34    // Crypto SHA instructions
    2.35  
    2.36    void sha1()   { sha1_only();    emit_int32( op(arith_op) | op3(sha_op3) | opf(sha1_opf)); }
     3.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Nov 27 05:33:18 2019 +0000
     3.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Dec 04 16:23:46 2019 +0000
     3.3 @@ -4788,6 +4788,130 @@
     3.4      return start;
     3.5    }
     3.6  
     3.7 +  /* Single and multi-block ghash operations */
     3.8 +  address generate_ghash_processBlocks() {
     3.9 +      __ align(CodeEntryAlignment);
    3.10 +      Label L_ghash_loop, L_aligned, L_main;
    3.11 +      StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks");
    3.12 +      address start = __ pc();
    3.13 +
    3.14 +      Register state = I0;
    3.15 +      Register subkeyH = I1;
    3.16 +      Register data = I2;
    3.17 +      Register len = I3;
    3.18 +
    3.19 +      __ save_frame(0);
    3.20 +
    3.21 +      __ ldx(state, 0, O0);
    3.22 +      __ ldx(state, 8, O1);
    3.23 +
    3.24 +      // Loop label for multiblock operations
    3.25 +      __ BIND(L_ghash_loop);
    3.26 +
    3.27 +      // Check if 'data' is unaligned
    3.28 +      __ andcc(data, 7, G1);
    3.29 +      __ br(Assembler::zero, false, Assembler::pt, L_aligned);
    3.30 +      __ delayed()->nop();
    3.31 +
    3.32 +      Register left_shift = L1;
    3.33 +      Register right_shift = L2;
    3.34 +      Register data_ptr = L3;
    3.35 +
    3.36 +      // Get left and right shift values in bits
    3.37 +      __ sll(G1, LogBitsPerByte, left_shift);
    3.38 +      __ mov(64, right_shift);
    3.39 +      __ sub(right_shift, left_shift, right_shift);
    3.40 +
    3.41 +      // Align to read 'data'
    3.42 +      __ sub(data, G1, data_ptr);
    3.43 +
    3.44 +      // Load first 8 bytes of 'data'
    3.45 +      __ ldx(data_ptr, 0, O4);
    3.46 +      __ sllx(O4, left_shift, O4);
    3.47 +      __ ldx(data_ptr, 8, O5);
    3.48 +      __ srlx(O5, right_shift, G4);
    3.49 +      __ bset(G4, O4);
    3.50 +
    3.51 +      // Load second 8 bytes of 'data'
    3.52 +      __ sllx(O5, left_shift, O5);
    3.53 +      __ ldx(data_ptr, 16, G4);
    3.54 +      __ srlx(G4, right_shift, G4);
    3.55 +      __ ba(L_main);
    3.56 +      __ delayed()->bset(G4, O5);
    3.57 +
    3.58 +      // If 'data' is aligned, load normally
    3.59 +      __ BIND(L_aligned);
    3.60 +      __ ldx(data, 0, O4);
    3.61 +      __ ldx(data, 8, O5);
    3.62 +
    3.63 +      __ BIND(L_main);
    3.64 +      __ ldx(subkeyH, 0, O2);
    3.65 +      __ ldx(subkeyH, 8, O3);
    3.66 +
    3.67 +      __ xor3(O0, O4, O0);
    3.68 +      __ xor3(O1, O5, O1);
    3.69 +
    3.70 +      __ xmulxhi(O0, O3, G3);
    3.71 +      __ xmulx(O0, O2, O5);
    3.72 +      __ xmulxhi(O1, O2, G4);
    3.73 +      __ xmulxhi(O1, O3, G5);
    3.74 +      __ xmulx(O0, O3, G1);
    3.75 +      __ xmulx(O1, O3, G2);
    3.76 +      __ xmulx(O1, O2, O3);
    3.77 +      __ xmulxhi(O0, O2, O4);
    3.78 +
    3.79 +      __ mov(0xE1, O0);
    3.80 +      __ sllx(O0, 56, O0);
    3.81 +
    3.82 +      __ xor3(O5, G3, O5);
    3.83 +      __ xor3(O5, G4, O5);
    3.84 +      __ xor3(G5, G1, G1);
    3.85 +      __ xor3(G1, O3, G1);
    3.86 +      __ srlx(G2, 63, O1);
    3.87 +      __ srlx(G1, 63, G3);
    3.88 +      __ sllx(G2, 63, O3);
    3.89 +      __ sllx(G2, 58, O2);
    3.90 +      __ xor3(O3, O2, O2);
    3.91 +
    3.92 +      __ sllx(G1, 1, G1);
    3.93 +      __ or3(G1, O1, G1);
    3.94 +
    3.95 +      __ xor3(G1, O2, G1);
    3.96 +
    3.97 +      __ sllx(G2, 1, G2);
    3.98 +
    3.99 +      __ xmulxhi(G1, O0, O1);
   3.100 +      __ xmulx(G1, O0, O2);
   3.101 +      __ xmulxhi(G2, O0, O3);
   3.102 +      __ xmulx(G2, O0, G1);
   3.103 +
   3.104 +      __ xor3(O4, O1, O4);
   3.105 +      __ xor3(O5, O2, O5);
   3.106 +      __ xor3(O5, O3, O5);
   3.107 +
   3.108 +      __ sllx(O4, 1, O2);
   3.109 +      __ srlx(O5, 63, O3);
   3.110 +
   3.111 +      __ or3(O2, O3, O0);
   3.112 +
   3.113 +      __ sllx(O5, 1, O1);
   3.114 +      __ srlx(G1, 63, O2);
   3.115 +      __ or3(O1, O2, O1);
   3.116 +      __ xor3(O1, G3, O1);
   3.117 +
   3.118 +      __ deccc(len);
   3.119 +      __ br(Assembler::notZero, true, Assembler::pt, L_ghash_loop);
   3.120 +      __ delayed()->add(data, 16, data);
   3.121 +
   3.122 +      __ stx(O0, I0, 0);
   3.123 +      __ stx(O1, I0, 8);
   3.124 +
   3.125 +      __ ret();
   3.126 +      __ delayed()->restore();
   3.127 +
   3.128 +      return start;
   3.129 +  }
   3.130 +
   3.131    void generate_initial() {
   3.132      // Generates all stubs and initializes the entry points
   3.133  
   3.134 @@ -4860,6 +4984,10 @@
   3.135        StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
   3.136        StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
   3.137      }
   3.138 +    // generate GHASH intrinsics code
   3.139 +    if (UseGHASHIntrinsics) {
   3.140 +      StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks();
   3.141 +    }
   3.142  
   3.143      // generate SHA1/SHA256/SHA512 intrinsics code
   3.144      if (UseSHA1Intrinsics) {
     4.1 --- a/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Nov 27 05:33:18 2019 +0000
     4.2 +++ b/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Dec 04 16:23:46 2019 +0000
     4.3 @@ -319,6 +319,17 @@
     4.4      }
     4.5    }
     4.6  
     4.7 +  // GHASH/GCM intrinsics
     4.8 +  if (has_vis3() && (UseVIS > 2)) {
     4.9 +    if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
    4.10 +      UseGHASHIntrinsics = true;
    4.11 +    }
    4.12 +  } else if (UseGHASHIntrinsics) {
    4.13 +    if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics))
    4.14 +      warning("GHASH intrinsics require VIS3 insructions support. Intriniscs will be disabled");
    4.15 +    FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
    4.16 +  }
    4.17 +
    4.18    // SHA1, SHA256, and SHA512 instructions were added to SPARC T-series at different times
    4.19    if (has_sha1() || has_sha256() || has_sha512()) {
    4.20      if (UseVIS > 0) { // SHA intrinsics use VIS1 instructions
     5.1 --- a/src/cpu/x86/vm/assembler_x86.cpp	Wed Nov 27 05:33:18 2019 +0000
     5.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Wed Dec 04 16:23:46 2019 +0000
     5.3 @@ -2575,6 +2575,15 @@
     5.4    emit_int8(shift);
     5.5  }
     5.6  
     5.7 +void Assembler::pslldq(XMMRegister dst, int shift) {
     5.8 +  // Shift left 128 bit value in xmm register by number of bytes.
     5.9 +  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
    5.10 +  int encode = simd_prefix_and_encode(xmm7, dst, dst, VEX_SIMD_66);
    5.11 +  emit_int8(0x73);
    5.12 +  emit_int8((unsigned char)(0xC0 | encode));
    5.13 +  emit_int8(shift);
    5.14 +}
    5.15 +
    5.16  void Assembler::ptest(XMMRegister dst, Address src) {
    5.17    assert(VM_Version::supports_sse4_1(), "");
    5.18    assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
     6.1 --- a/src/cpu/x86/vm/assembler_x86.hpp	Wed Nov 27 05:33:18 2019 +0000
     6.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp	Wed Dec 04 16:23:46 2019 +0000
     6.3 @@ -1527,6 +1527,8 @@
     6.4  
     6.5    // Shift Right by bytes Logical DoubleQuadword Immediate
     6.6    void psrldq(XMMRegister dst, int shift);
     6.7 +  // Shift Left by bytes Logical DoubleQuadword Immediate
     6.8 +  void pslldq(XMMRegister dst, int shift);
     6.9  
    6.10    // Logical Compare 128bit
    6.11    void ptest(XMMRegister dst, XMMRegister src);
     7.1 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Nov 27 05:33:18 2019 +0000
     7.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Dec 04 16:23:46 2019 +0000
     7.3 @@ -2719,6 +2719,169 @@
     7.4      return start;
     7.5    }
     7.6  
     7.7 +  // byte swap x86 long
     7.8 +  address generate_ghash_long_swap_mask() {
     7.9 +    __ align(CodeEntryAlignment);
    7.10 +    StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask");
    7.11 +    address start = __ pc();
    7.12 +    __ emit_data(0x0b0a0908, relocInfo::none, 0);
    7.13 +    __ emit_data(0x0f0e0d0c, relocInfo::none, 0);
    7.14 +    __ emit_data(0x03020100, relocInfo::none, 0);
    7.15 +    __ emit_data(0x07060504, relocInfo::none, 0);
    7.16 +
    7.17 +  return start;
    7.18 +  }
    7.19 +
    7.20 +  // byte swap x86 byte array
    7.21 +  address generate_ghash_byte_swap_mask() {
    7.22 +    __ align(CodeEntryAlignment);
    7.23 +    StubCodeMark mark(this, "StubRoutines", "ghash_byte_swap_mask");
    7.24 +    address start = __ pc();
    7.25 +    __ emit_data(0x0c0d0e0f, relocInfo::none, 0);
    7.26 +    __ emit_data(0x08090a0b, relocInfo::none, 0);
    7.27 +    __ emit_data(0x04050607, relocInfo::none, 0);
    7.28 +    __ emit_data(0x00010203, relocInfo::none, 0);
    7.29 +  return start;
    7.30 +  }
    7.31 +
    7.32 +  /* Single and multi-block ghash operations */
    7.33 +  address generate_ghash_processBlocks() {
    7.34 +    assert(UseGHASHIntrinsics, "need GHASH intrinsics and CLMUL support");
    7.35 +    __ align(CodeEntryAlignment);
    7.36 +    Label L_ghash_loop, L_exit;
    7.37 +    StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks");
    7.38 +    address start = __ pc();
    7.39 +
    7.40 +    const Register state        = rdi;
    7.41 +    const Register subkeyH      = rsi;
    7.42 +    const Register data         = rdx;
    7.43 +    const Register blocks       = rcx;
    7.44 +
    7.45 +    const Address  state_param(rbp, 8+0);
    7.46 +    const Address  subkeyH_param(rbp, 8+4);
    7.47 +    const Address  data_param(rbp, 8+8);
    7.48 +    const Address  blocks_param(rbp, 8+12);
    7.49 +
    7.50 +    const XMMRegister xmm_temp0 = xmm0;
    7.51 +    const XMMRegister xmm_temp1 = xmm1;
    7.52 +    const XMMRegister xmm_temp2 = xmm2;
    7.53 +    const XMMRegister xmm_temp3 = xmm3;
    7.54 +    const XMMRegister xmm_temp4 = xmm4;
    7.55 +    const XMMRegister xmm_temp5 = xmm5;
    7.56 +    const XMMRegister xmm_temp6 = xmm6;
    7.57 +    const XMMRegister xmm_temp7 = xmm7;
    7.58 +
    7.59 +    __ enter();
    7.60 +    handleSOERegisters(true);  // Save registers
    7.61 +
    7.62 +    __ movptr(state, state_param);
    7.63 +    __ movptr(subkeyH, subkeyH_param);
    7.64 +    __ movptr(data, data_param);
    7.65 +    __ movptr(blocks, blocks_param);
    7.66 +
    7.67 +    __ movdqu(xmm_temp0, Address(state, 0));
    7.68 +    __ pshufb(xmm_temp0, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr()));
    7.69 +
    7.70 +    __ movdqu(xmm_temp1, Address(subkeyH, 0));
    7.71 +    __ pshufb(xmm_temp1, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr()));
    7.72 +
    7.73 +    __ BIND(L_ghash_loop);
    7.74 +    __ movdqu(xmm_temp2, Address(data, 0));
    7.75 +    __ pshufb(xmm_temp2, ExternalAddress(StubRoutines::x86::ghash_byte_swap_mask_addr()));
    7.76 +
    7.77 +    __ pxor(xmm_temp0, xmm_temp2);
    7.78 +
    7.79 +    //
    7.80 +    // Multiply with the hash key
    7.81 +    //
    7.82 +    __ movdqu(xmm_temp3, xmm_temp0);
    7.83 +    __ pclmulqdq(xmm_temp3, xmm_temp1, 0);      // xmm3 holds a0*b0
    7.84 +    __ movdqu(xmm_temp4, xmm_temp0);
    7.85 +    __ pclmulqdq(xmm_temp4, xmm_temp1, 16);     // xmm4 holds a0*b1
    7.86 +
    7.87 +    __ movdqu(xmm_temp5, xmm_temp0);
    7.88 +    __ pclmulqdq(xmm_temp5, xmm_temp1, 1);      // xmm5 holds a1*b0
    7.89 +    __ movdqu(xmm_temp6, xmm_temp0);
    7.90 +    __ pclmulqdq(xmm_temp6, xmm_temp1, 17);     // xmm6 holds a1*b1
    7.91 +
    7.92 +    __ pxor(xmm_temp4, xmm_temp5);      // xmm4 holds a0*b1 + a1*b0
    7.93 +
    7.94 +    __ movdqu(xmm_temp5, xmm_temp4);    // move the contents of xmm4 to xmm5
    7.95 +    __ psrldq(xmm_temp4, 8);    // shift by xmm4 64 bits to the right
    7.96 +    __ pslldq(xmm_temp5, 8);    // shift by xmm5 64 bits to the left
    7.97 +    __ pxor(xmm_temp3, xmm_temp5);
    7.98 +    __ pxor(xmm_temp6, xmm_temp4);      // Register pair <xmm6:xmm3> holds the result
    7.99 +                                        // of the carry-less multiplication of
   7.100 +                                        // xmm0 by xmm1.
   7.101 +
   7.102 +    // We shift the result of the multiplication by one bit position
   7.103 +    // to the left to cope for the fact that the bits are reversed.
   7.104 +    __ movdqu(xmm_temp7, xmm_temp3);
   7.105 +    __ movdqu(xmm_temp4, xmm_temp6);
   7.106 +    __ pslld (xmm_temp3, 1);
   7.107 +    __ pslld(xmm_temp6, 1);
   7.108 +    __ psrld(xmm_temp7, 31);
   7.109 +    __ psrld(xmm_temp4, 31);
   7.110 +    __ movdqu(xmm_temp5, xmm_temp7);
   7.111 +    __ pslldq(xmm_temp4, 4);
   7.112 +    __ pslldq(xmm_temp7, 4);
   7.113 +    __ psrldq(xmm_temp5, 12);
   7.114 +    __ por(xmm_temp3, xmm_temp7);
   7.115 +    __ por(xmm_temp6, xmm_temp4);
   7.116 +    __ por(xmm_temp6, xmm_temp5);
   7.117 +
   7.118 +    //
   7.119 +    // First phase of the reduction
   7.120 +    //
   7.121 +    // Move xmm3 into xmm4, xmm5, xmm7 in order to perform the shifts
   7.122 +    // independently.
   7.123 +    __ movdqu(xmm_temp7, xmm_temp3);
   7.124 +    __ movdqu(xmm_temp4, xmm_temp3);
   7.125 +    __ movdqu(xmm_temp5, xmm_temp3);
   7.126 +    __ pslld(xmm_temp7, 31);    // packed right shift shifting << 31
   7.127 +    __ pslld(xmm_temp4, 30);    // packed right shift shifting << 30
   7.128 +    __ pslld(xmm_temp5, 25);    // packed right shift shifting << 25
   7.129 +    __ pxor(xmm_temp7, xmm_temp4);      // xor the shifted versions
   7.130 +    __ pxor(xmm_temp7, xmm_temp5);
   7.131 +    __ movdqu(xmm_temp4, xmm_temp7);
   7.132 +    __ pslldq(xmm_temp7, 12);
   7.133 +    __ psrldq(xmm_temp4, 4);
   7.134 +    __ pxor(xmm_temp3, xmm_temp7);      // first phase of the reduction complete
   7.135 +
   7.136 +    //
   7.137 +    // Second phase of the reduction
   7.138 +    //
   7.139 +    // Make 3 copies of xmm3 in xmm2, xmm5, xmm7 for doing these
   7.140 +    // shift operations.
   7.141 +    __ movdqu(xmm_temp2, xmm_temp3);
   7.142 +    __ movdqu(xmm_temp7, xmm_temp3);
   7.143 +    __ movdqu(xmm_temp5, xmm_temp3);
   7.144 +    __ psrld(xmm_temp2, 1);     // packed left shifting >> 1
   7.145 +    __ psrld(xmm_temp7, 2);     // packed left shifting >> 2
   7.146 +    __ psrld(xmm_temp5, 7);     // packed left shifting >> 7
   7.147 +    __ pxor(xmm_temp2, xmm_temp7);      // xor the shifted versions
   7.148 +    __ pxor(xmm_temp2, xmm_temp5);
   7.149 +    __ pxor(xmm_temp2, xmm_temp4);
   7.150 +    __ pxor(xmm_temp3, xmm_temp2);
   7.151 +    __ pxor(xmm_temp6, xmm_temp3);      // the result is in xmm6
   7.152 +
   7.153 +    __ decrement(blocks);
   7.154 +    __ jcc(Assembler::zero, L_exit);
   7.155 +    __ movdqu(xmm_temp0, xmm_temp6);
   7.156 +    __ addptr(data, 16);
   7.157 +    __ jmp(L_ghash_loop);
   7.158 +
   7.159 +    __ BIND(L_exit);
   7.160 +       // Byte swap 16-byte result
   7.161 +    __ pshufb(xmm_temp6, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr()));
   7.162 +    __ movdqu(Address(state, 0), xmm_temp6);   // store the result
   7.163 +
   7.164 +    handleSOERegisters(false);  // restore registers
   7.165 +    __ leave();
   7.166 +    __ ret(0);
   7.167 +    return start;
   7.168 +  }
   7.169 +
   7.170    /**
   7.171     *  Arguments:
   7.172     *
   7.173 @@ -3018,6 +3181,13 @@
   7.174        StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt();
   7.175      }
   7.176  
   7.177 +    // Generate GHASH intrinsics code
   7.178 +    if (UseGHASHIntrinsics) {
   7.179 +      StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask();
   7.180 +      StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask();
   7.181 +      StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks();
   7.182 +    }
   7.183 +
   7.184      // Safefetch stubs.
   7.185      generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
   7.186                                                     &StubRoutines::_safefetch32_fault_pc,
     8.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Nov 27 05:33:18 2019 +0000
     8.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Dec 04 16:23:46 2019 +0000
     8.3 @@ -3639,6 +3639,175 @@
     8.4      return start;
     8.5    }
     8.6  
     8.7 +
     8.8 +  // byte swap x86 long
     8.9 +  address generate_ghash_long_swap_mask() {
    8.10 +    __ align(CodeEntryAlignment);
    8.11 +    StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask");
    8.12 +    address start = __ pc();
    8.13 +    __ emit_data64(0x0f0e0d0c0b0a0908, relocInfo::none );
    8.14 +    __ emit_data64(0x0706050403020100, relocInfo::none );
    8.15 +  return start;
    8.16 +  }
    8.17 +
    8.18 +  // byte swap x86 byte array
    8.19 +  address generate_ghash_byte_swap_mask() {
    8.20 +    __ align(CodeEntryAlignment);
    8.21 +    StubCodeMark mark(this, "StubRoutines", "ghash_byte_swap_mask");
    8.22 +    address start = __ pc();
    8.23 +    __ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none );
    8.24 +    __ emit_data64(0x0001020304050607, relocInfo::none );
    8.25 +  return start;
    8.26 +  }
    8.27 +
    8.28 +  /* Single and multi-block ghash operations */
    8.29 +  address generate_ghash_processBlocks() {
    8.30 +    __ align(CodeEntryAlignment);
    8.31 +    Label L_ghash_loop, L_exit;
    8.32 +    StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks");
    8.33 +    address start = __ pc();
    8.34 +
    8.35 +    const Register state        = c_rarg0;
    8.36 +    const Register subkeyH      = c_rarg1;
    8.37 +    const Register data         = c_rarg2;
    8.38 +    const Register blocks       = c_rarg3;
    8.39 +
    8.40 +#ifdef _WIN64
    8.41 +    const int XMM_REG_LAST  = 10;
    8.42 +#endif
    8.43 +
    8.44 +    const XMMRegister xmm_temp0 = xmm0;
    8.45 +    const XMMRegister xmm_temp1 = xmm1;
    8.46 +    const XMMRegister xmm_temp2 = xmm2;
    8.47 +    const XMMRegister xmm_temp3 = xmm3;
    8.48 +    const XMMRegister xmm_temp4 = xmm4;
    8.49 +    const XMMRegister xmm_temp5 = xmm5;
    8.50 +    const XMMRegister xmm_temp6 = xmm6;
    8.51 +    const XMMRegister xmm_temp7 = xmm7;
    8.52 +    const XMMRegister xmm_temp8 = xmm8;
    8.53 +    const XMMRegister xmm_temp9 = xmm9;
    8.54 +    const XMMRegister xmm_temp10 = xmm10;
    8.55 +
    8.56 +    __ enter();
    8.57 +
    8.58 +#ifdef _WIN64
    8.59 +    // save the xmm registers which must be preserved 6-10
    8.60 +    __ subptr(rsp, -rsp_after_call_off * wordSize);
    8.61 +    for (int i = 6; i <= XMM_REG_LAST; i++) {
    8.62 +      __ movdqu(xmm_save(i), as_XMMRegister(i));
    8.63 +    }
    8.64 +#endif
    8.65 +
    8.66 +    __ movdqu(xmm_temp10, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr()));
    8.67 +
    8.68 +    __ movdqu(xmm_temp0, Address(state, 0));
    8.69 +    __ pshufb(xmm_temp0, xmm_temp10);
    8.70 +
    8.71 +
    8.72 +    __ BIND(L_ghash_loop);
    8.73 +    __ movdqu(xmm_temp2, Address(data, 0));
    8.74 +    __ pshufb(xmm_temp2, ExternalAddress(StubRoutines::x86::ghash_byte_swap_mask_addr()));
    8.75 +
    8.76 +    __ movdqu(xmm_temp1, Address(subkeyH, 0));
    8.77 +    __ pshufb(xmm_temp1, xmm_temp10);
    8.78 +
    8.79 +    __ pxor(xmm_temp0, xmm_temp2);
    8.80 +
    8.81 +    //
    8.82 +    // Multiply with the hash key
    8.83 +    //
    8.84 +    __ movdqu(xmm_temp3, xmm_temp0);
    8.85 +    __ pclmulqdq(xmm_temp3, xmm_temp1, 0);      // xmm3 holds a0*b0
    8.86 +    __ movdqu(xmm_temp4, xmm_temp0);
    8.87 +    __ pclmulqdq(xmm_temp4, xmm_temp1, 16);     // xmm4 holds a0*b1
    8.88 +
    8.89 +    __ movdqu(xmm_temp5, xmm_temp0);
    8.90 +    __ pclmulqdq(xmm_temp5, xmm_temp1, 1);      // xmm5 holds a1*b0
    8.91 +    __ movdqu(xmm_temp6, xmm_temp0);
    8.92 +    __ pclmulqdq(xmm_temp6, xmm_temp1, 17);     // xmm6 holds a1*b1
    8.93 +
    8.94 +    __ pxor(xmm_temp4, xmm_temp5);      // xmm4 holds a0*b1 + a1*b0
    8.95 +
    8.96 +    __ movdqu(xmm_temp5, xmm_temp4);    // move the contents of xmm4 to xmm5
    8.97 +    __ psrldq(xmm_temp4, 8);    // shift by xmm4 64 bits to the right
    8.98 +    __ pslldq(xmm_temp5, 8);    // shift by xmm5 64 bits to the left
    8.99 +    __ pxor(xmm_temp3, xmm_temp5);
   8.100 +    __ pxor(xmm_temp6, xmm_temp4);      // Register pair <xmm6:xmm3> holds the result
   8.101 +                                        // of the carry-less multiplication of
   8.102 +                                        // xmm0 by xmm1.
   8.103 +
   8.104 +    // We shift the result of the multiplication by one bit position
   8.105 +    // to the left to cope for the fact that the bits are reversed.
   8.106 +    __ movdqu(xmm_temp7, xmm_temp3);
   8.107 +    __ movdqu(xmm_temp8, xmm_temp6);
   8.108 +    __ pslld(xmm_temp3, 1);
   8.109 +    __ pslld(xmm_temp6, 1);
   8.110 +    __ psrld(xmm_temp7, 31);
   8.111 +    __ psrld(xmm_temp8, 31);
   8.112 +    __ movdqu(xmm_temp9, xmm_temp7);
   8.113 +    __ pslldq(xmm_temp8, 4);
   8.114 +    __ pslldq(xmm_temp7, 4);
   8.115 +    __ psrldq(xmm_temp9, 12);
   8.116 +    __ por(xmm_temp3, xmm_temp7);
   8.117 +    __ por(xmm_temp6, xmm_temp8);
   8.118 +    __ por(xmm_temp6, xmm_temp9);
   8.119 +
   8.120 +    //
   8.121 +    // First phase of the reduction
   8.122 +    //
   8.123 +    // Move xmm3 into xmm7, xmm8, xmm9 in order to perform the shifts
   8.124 +    // independently.
   8.125 +    __ movdqu(xmm_temp7, xmm_temp3);
   8.126 +    __ movdqu(xmm_temp8, xmm_temp3);
   8.127 +    __ movdqu(xmm_temp9, xmm_temp3);
   8.128 +    __ pslld(xmm_temp7, 31);    // packed right shift shifting << 31
   8.129 +    __ pslld(xmm_temp8, 30);    // packed right shift shifting << 30
   8.130 +    __ pslld(xmm_temp9, 25);    // packed right shift shifting << 25
   8.131 +    __ pxor(xmm_temp7, xmm_temp8);      // xor the shifted versions
   8.132 +    __ pxor(xmm_temp7, xmm_temp9);
   8.133 +    __ movdqu(xmm_temp8, xmm_temp7);
   8.134 +    __ pslldq(xmm_temp7, 12);
   8.135 +    __ psrldq(xmm_temp8, 4);
   8.136 +    __ pxor(xmm_temp3, xmm_temp7);      // first phase of the reduction complete
   8.137 +
   8.138 +    //
   8.139 +    // Second phase of the reduction
   8.140 +    //
   8.141 +    // Make 3 copies of xmm3 in xmm2, xmm4, xmm5 for doing these
   8.142 +    // shift operations.
   8.143 +    __ movdqu(xmm_temp2, xmm_temp3);
   8.144 +    __ movdqu(xmm_temp4, xmm_temp3);
   8.145 +    __ movdqu(xmm_temp5, xmm_temp3);
   8.146 +    __ psrld(xmm_temp2, 1);     // packed left shifting >> 1
   8.147 +    __ psrld(xmm_temp4, 2);     // packed left shifting >> 2
   8.148 +    __ psrld(xmm_temp5, 7);     // packed left shifting >> 7
   8.149 +    __ pxor(xmm_temp2, xmm_temp4);      // xor the shifted versions
   8.150 +    __ pxor(xmm_temp2, xmm_temp5);
   8.151 +    __ pxor(xmm_temp2, xmm_temp8);
   8.152 +    __ pxor(xmm_temp3, xmm_temp2);
   8.153 +    __ pxor(xmm_temp6, xmm_temp3);      // the result is in xmm6
   8.154 +
   8.155 +    __ decrement(blocks);
   8.156 +    __ jcc(Assembler::zero, L_exit);
   8.157 +    __ movdqu(xmm_temp0, xmm_temp6);
   8.158 +    __ addptr(data, 16);
   8.159 +    __ jmp(L_ghash_loop);
   8.160 +
   8.161 +    __ BIND(L_exit);
   8.162 +    __ pshufb(xmm_temp6, xmm_temp10);          // Byte swap 16-byte result
   8.163 +    __ movdqu(Address(state, 0), xmm_temp6);   // store the result
   8.164 +
   8.165 +#ifdef _WIN64
   8.166 +    // restore xmm regs belonging to calling function
   8.167 +    for (int i = 6; i <= XMM_REG_LAST; i++) {
   8.168 +      __ movdqu(as_XMMRegister(i), xmm_save(i));
   8.169 +    }
   8.170 +#endif
   8.171 +    __ leave();
   8.172 +    __ ret(0);
   8.173 +    return start;
   8.174 +  }
   8.175 +
   8.176    /**
   8.177     *  Arguments:
   8.178     *
   8.179 @@ -4077,6 +4246,13 @@
   8.180        StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
   8.181      }
   8.182  
   8.183 +    // Generate GHASH intrinsics code
   8.184 +    if (UseGHASHIntrinsics) {
   8.185 +      StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask();
   8.186 +      StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask();
   8.187 +      StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks();
   8.188 +    }
   8.189 +
   8.190      // Safefetch stubs.
   8.191      generate_safefetch("SafeFetch32", sizeof(int),     &StubRoutines::_safefetch32_entry,
   8.192                                                         &StubRoutines::_safefetch32_fault_pc,
     9.1 --- a/src/cpu/x86/vm/stubRoutines_x86.cpp	Wed Nov 27 05:33:18 2019 +0000
     9.2 +++ b/src/cpu/x86/vm/stubRoutines_x86.cpp	Wed Dec 04 16:23:46 2019 +0000
     9.3 @@ -1,5 +1,5 @@
     9.4  /*
     9.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     9.6 + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
     9.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.8   *
     9.9   * This code is free software; you can redistribute it and/or modify it
    9.10 @@ -33,6 +33,8 @@
    9.11  
    9.12  address StubRoutines::x86::_verify_mxcsr_entry = NULL;
    9.13  address StubRoutines::x86::_key_shuffle_mask_addr = NULL;
    9.14 +address StubRoutines::x86::_ghash_long_swap_mask_addr = NULL;
    9.15 +address StubRoutines::x86::_ghash_byte_swap_mask_addr = NULL;
    9.16  
    9.17  uint64_t StubRoutines::x86::_crc_by128_masks[] =
    9.18  {
    10.1 --- a/src/cpu/x86/vm/stubRoutines_x86.hpp	Wed Nov 27 05:33:18 2019 +0000
    10.2 +++ b/src/cpu/x86/vm/stubRoutines_x86.hpp	Wed Dec 04 16:23:46 2019 +0000
    10.3 @@ -1,5 +1,5 @@
    10.4  /*
    10.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    10.6 + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
    10.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.8   *
    10.9   * This code is free software; you can redistribute it and/or modify it
   10.10 @@ -36,10 +36,15 @@
   10.11    // masks and table for CRC32
   10.12    static uint64_t _crc_by128_masks[];
   10.13    static juint    _crc_table[];
   10.14 +  // swap mask for ghash
   10.15 +  static address _ghash_long_swap_mask_addr;
   10.16 +  static address _ghash_byte_swap_mask_addr;
   10.17  
   10.18   public:
   10.19    static address verify_mxcsr_entry()    { return _verify_mxcsr_entry; }
   10.20    static address key_shuffle_mask_addr() { return _key_shuffle_mask_addr; }
   10.21    static address crc_by128_masks_addr()  { return (address)_crc_by128_masks; }
   10.22 +  static address ghash_long_swap_mask_addr() { return _ghash_long_swap_mask_addr; }
   10.23 +  static address ghash_byte_swap_mask_addr() { return _ghash_byte_swap_mask_addr; }
   10.24  
   10.25  #endif // CPU_X86_VM_STUBROUTINES_X86_32_HPP
    11.1 --- a/src/cpu/x86/vm/vm_version_x86.cpp	Wed Nov 27 05:33:18 2019 +0000
    11.2 +++ b/src/cpu/x86/vm/vm_version_x86.cpp	Wed Dec 04 16:23:46 2019 +0000
    11.3 @@ -594,6 +594,17 @@
    11.4      FLAG_SET_DEFAULT(UseAESIntrinsics, false);
    11.5    }
    11.6  
    11.7 +  // GHASH/GCM intrinsics
    11.8 +  if (UseCLMUL && (UseSSE > 2)) {
    11.9 +    if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
   11.10 +      UseGHASHIntrinsics = true;
   11.11 +    }
   11.12 +  } else if (UseGHASHIntrinsics) {
   11.13 +    if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics))
   11.14 +      warning("GHASH intrinsic requires CLMUL and SSE2 instructions on this CPU");
   11.15 +    FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
   11.16 +  }
   11.17 +
   11.18    if (UseSHA) {
   11.19      warning("SHA instructions are not available on this CPU");
   11.20      FLAG_SET_DEFAULT(UseSHA, false);
    12.1 --- a/src/share/vm/classfile/vmSymbols.hpp	Wed Nov 27 05:33:18 2019 +0000
    12.2 +++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Dec 04 16:23:46 2019 +0000
    12.3 @@ -863,6 +863,12 @@
    12.4     do_name(     implCompressMB_name,                               "implCompressMultiBlock0")                           \
    12.5     do_signature(implCompressMB_signature,                          "([BII)I")                                           \
    12.6                                                                                                                          \
    12.7 +  /* support for com.sun.crypto.provider.GHASH */                                                                       \
    12.8 +  do_class(com_sun_crypto_provider_ghash, "com/sun/crypto/provider/GHASH")                                              \
    12.9 +  do_intrinsic(_ghash_processBlocks, com_sun_crypto_provider_ghash, processBlocks_name, ghash_processBlocks_signature, F_S) \
   12.10 +   do_name(processBlocks_name, "processBlocks")                                                                         \
   12.11 +   do_signature(ghash_processBlocks_signature, "([BII[J[J)V")                                                           \
   12.12 +                                                                                                                        \
   12.13    /* support for java.util.zip */                                                                                       \
   12.14    do_class(java_util_zip_CRC32,           "java/util/zip/CRC32")                                                        \
   12.15    do_intrinsic(_updateCRC32,               java_util_zip_CRC32,   update_name, int2_int_signature,               F_SN)  \
    13.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Nov 27 05:33:18 2019 +0000
    13.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Dec 04 16:23:46 2019 +0000
    13.3 @@ -2520,6 +2520,12 @@
    13.4            }
    13.5          }
    13.6        }
    13.7 +    } else if (GC_locker::should_discard(cause, gc_count_before)) {
    13.8 +      // Return to be consistent with VMOp failure due to another
    13.9 +      // collection slipping in after our gc_count but before our
   13.10 +      // request is processed.  _gc_locker collections upgraded by
   13.11 +      // GCLockerInvokesConcurrent are handled above and never discarded.
   13.12 +      return;
   13.13      } else {
   13.14        if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc
   13.15            DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) {
    14.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Nov 27 05:33:18 2019 +0000
    14.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Dec 04 16:23:46 2019 +0000
    14.3 @@ -530,6 +530,10 @@
    14.4      full_gc_count = Universe::heap()->total_full_collections();
    14.5    }
    14.6  
    14.7 +  if (GC_locker::should_discard(cause, gc_count)) {
    14.8 +    return;
    14.9 +  }
   14.10 +
   14.11    VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause);
   14.12    VMThread::execute(&op);
   14.13  }
    15.1 --- a/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp	Wed Nov 27 05:33:18 2019 +0000
    15.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp	Wed Dec 04 16:23:46 2019 +0000
    15.3 @@ -52,11 +52,16 @@
    15.4    }
    15.5  }
    15.6  
    15.7 +static bool is_cause_full(GCCause::Cause cause) {
    15.8 +  return (cause != GCCause::_gc_locker) && (cause != GCCause::_wb_young_gc)
    15.9 +         DEBUG_ONLY(&& (cause != GCCause::_scavenge_alot));
   15.10 +}
   15.11 +
   15.12  // Only used for System.gc() calls
   15.13  VM_ParallelGCSystemGC::VM_ParallelGCSystemGC(uint gc_count,
   15.14                                               uint full_gc_count,
   15.15                                               GCCause::Cause gc_cause) :
   15.16 -  VM_GC_Operation(gc_count, gc_cause, full_gc_count, true /* full */)
   15.17 +  VM_GC_Operation(gc_count, gc_cause, full_gc_count, is_cause_full(gc_cause))
   15.18  {
   15.19  }
   15.20  
   15.21 @@ -68,8 +73,7 @@
   15.22      "must be a ParallelScavengeHeap");
   15.23  
   15.24    GCCauseSetter gccs(heap, _gc_cause);
   15.25 -  if (_gc_cause == GCCause::_gc_locker || _gc_cause == GCCause::_wb_young_gc
   15.26 -      DEBUG_ONLY(|| _gc_cause == GCCause::_scavenge_alot)) {
   15.27 +  if (!_full) {
   15.28      // If (and only if) the scavenge fails, this will invoke a full gc.
   15.29      heap->invoke_scavenge();
   15.30    } else {
    16.1 --- a/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Wed Nov 27 05:33:18 2019 +0000
    16.2 +++ b/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Wed Dec 04 16:23:46 2019 +0000
    16.3 @@ -201,6 +201,19 @@
    16.4    }
    16.5  }
    16.6  
    16.7 +static bool is_full_gc(int max_level) {
    16.8 +  // Return true if max_level is all generations
    16.9 +  return (max_level == (GenCollectedHeap::heap()->n_gens() - 1));
   16.10 +}
   16.11 +
   16.12 +VM_GenCollectFull::VM_GenCollectFull(uint gc_count_before,
   16.13 +                                     uint full_gc_count_before,
   16.14 +                                     GCCause::Cause gc_cause,
   16.15 +                                     int max_level) :
   16.16 +  VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before,
   16.17 +                  is_full_gc(max_level) /* full */),
   16.18 +  _max_level(max_level) { }
   16.19 +
   16.20  void VM_GenCollectFull::doit() {
   16.21    SvcGCMarker sgcm(SvcGCMarker::FULL);
   16.22  
    17.1 --- a/src/share/vm/gc_implementation/shared/vmGCOperations.hpp	Wed Nov 27 05:33:18 2019 +0000
    17.2 +++ b/src/share/vm/gc_implementation/shared/vmGCOperations.hpp	Wed Dec 04 16:23:46 2019 +0000
    17.3 @@ -201,9 +201,7 @@
    17.4    VM_GenCollectFull(uint gc_count_before,
    17.5                      uint full_gc_count_before,
    17.6                      GCCause::Cause gc_cause,
    17.7 -                    int max_level)
    17.8 -    : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */),
    17.9 -      _max_level(max_level) { }
   17.10 +                    int max_level);
   17.11    ~VM_GenCollectFull() {}
   17.12    virtual VMOp_Type type() const { return VMOp_GenCollectFull; }
   17.13    virtual void doit();
    18.1 --- a/src/share/vm/memory/gcLocker.cpp	Wed Nov 27 05:33:18 2019 +0000
    18.2 +++ b/src/share/vm/memory/gcLocker.cpp	Wed Dec 04 16:23:46 2019 +0000
    18.3 @@ -31,6 +31,7 @@
    18.4  volatile jint GC_locker::_jni_lock_count = 0;
    18.5  volatile bool GC_locker::_needs_gc       = false;
    18.6  volatile bool GC_locker::_doing_gc       = false;
    18.7 +unsigned int  GC_locker::_total_collections = 0;
    18.8  
    18.9  #ifdef ASSERT
   18.10  volatile jint GC_locker::_debug_jni_lock_count = 0;
   18.11 @@ -94,6 +95,11 @@
   18.12    }
   18.13  }
   18.14  
   18.15 +bool GC_locker::should_discard(GCCause::Cause cause, uint total_collections) {
   18.16 +  return (cause == GCCause::_gc_locker) &&
   18.17 +         (_total_collections != total_collections);
   18.18 +}
   18.19 +
   18.20  void GC_locker::jni_lock(JavaThread* thread) {
   18.21    assert(!thread->in_critical(), "shouldn't currently be in a critical region");
   18.22    MutexLocker mu(JNICritical_lock);
   18.23 @@ -117,7 +123,13 @@
   18.24    decrement_debug_jni_lock_count();
   18.25    thread->exit_critical();
   18.26    if (needs_gc() && !is_active_internal()) {
   18.27 -    // We're the last thread out. Cause a GC to occur.
   18.28 +    // We're the last thread out. Request a GC.
   18.29 +    // Capture the current total collections, to allow detection of
   18.30 +    // other collections that make this one unnecessary.  The value of
   18.31 +    // total_collections() is only changed at a safepoint, so there
   18.32 +    // must not be a safepoint between the lock becoming inactive and
   18.33 +    // getting the count, else there may be unnecessary GCLocker GCs.
   18.34 +    _total_collections = Universe::heap()->total_collections();
   18.35      _doing_gc = true;
   18.36      {
   18.37        // Must give up the lock while at a safepoint
    19.1 --- a/src/share/vm/memory/gcLocker.hpp	Wed Nov 27 05:33:18 2019 +0000
    19.2 +++ b/src/share/vm/memory/gcLocker.hpp	Wed Dec 04 16:23:46 2019 +0000
    19.3 @@ -26,6 +26,7 @@
    19.4  #define SHARE_VM_MEMORY_GCLOCKER_HPP
    19.5  
    19.6  #include "gc_interface/collectedHeap.hpp"
    19.7 +#include "gc_interface/gcCause.hpp"
    19.8  #include "memory/genCollectedHeap.hpp"
    19.9  #include "memory/universe.hpp"
   19.10  #include "oops/oop.hpp"
   19.11 @@ -57,6 +58,7 @@
   19.12    static volatile bool _needs_gc;        // heap is filling, we need a GC
   19.13                                           // note: bool is typedef'd as jint
   19.14    static volatile bool _doing_gc;        // unlock_critical() is doing a GC
   19.15 +  static uint _total_collections;        // value for _gc_locker collection
   19.16  
   19.17  #ifdef ASSERT
   19.18    // This lock count is updated for all operations and is used to
   19.19 @@ -116,6 +118,12 @@
   19.20    // Sets _needs_gc if is_active() is true. Returns is_active().
   19.21    static bool check_active_before_gc();
   19.22  
   19.23 +  // Return true if the designated collection is a GCLocker request
   19.24 +  // that should be discarded.  Returns true if cause == GCCause::_gc_locker
   19.25 +  // and the given total collection value indicates a collection has been
   19.26 +  // done since the GCLocker request was made.
   19.27 +  static bool should_discard(GCCause::Cause cause, uint total_collections);
   19.28 +
   19.29    // Stalls the caller (who should not be in a jni critical section)
   19.30    // until needs_gc() clears. Note however that needs_gc() may be
   19.31    // set at a subsequent safepoint and/or cleared under the
    20.1 --- a/src/share/vm/memory/genCollectedHeap.cpp	Wed Nov 27 05:33:18 2019 +0000
    20.2 +++ b/src/share/vm/memory/genCollectedHeap.cpp	Wed Dec 04 16:23:46 2019 +0000
    20.3 @@ -796,8 +796,11 @@
    20.4  #else  // INCLUDE_ALL_GCS
    20.5      ShouldNotReachHere();
    20.6  #endif // INCLUDE_ALL_GCS
    20.7 -  } else if (cause == GCCause::_wb_young_gc) {
    20.8 -    // minor collection for WhiteBox API
    20.9 +  } else if ((cause == GCCause::_wb_young_gc) ||
   20.10 +             (cause == GCCause::_gc_locker)) {
   20.11 +    // minor collection for WhiteBox or GCLocker.
   20.12 +    // _gc_locker collections upgraded by GCLockerInvokesConcurrent
   20.13 +    // are handled above and never discarded.
   20.14      collect(cause, 0);
   20.15    } else {
   20.16  #ifdef ASSERT
   20.17 @@ -835,6 +838,11 @@
   20.18    // Read the GC count while holding the Heap_lock
   20.19    unsigned int gc_count_before      = total_collections();
   20.20    unsigned int full_gc_count_before = total_full_collections();
   20.21 +
   20.22 +  if (GC_locker::should_discard(cause, gc_count_before)) {
   20.23 +    return;
   20.24 +  }
   20.25 +
   20.26    {
   20.27      MutexUnlocker mu(Heap_lock);  // give up heap lock, execute gets it back
   20.28      VM_GenCollectFull op(gc_count_before, full_gc_count_before,
   20.29 @@ -887,24 +895,16 @@
   20.30  
   20.31  void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs,
   20.32                                            int max_level) {
   20.33 -  int local_max_level;
   20.34 -  if (!incremental_collection_will_fail(false /* don't consult_young */) &&
   20.35 -      gc_cause() == GCCause::_gc_locker) {
   20.36 -    local_max_level = 0;
   20.37 -  } else {
   20.38 -    local_max_level = max_level;
   20.39 -  }
   20.40  
   20.41    do_collection(true                 /* full */,
   20.42                  clear_all_soft_refs  /* clear_all_soft_refs */,
   20.43                  0                    /* size */,
   20.44                  false                /* is_tlab */,
   20.45 -                local_max_level      /* max_level */);
   20.46 +                max_level            /* max_level */);
   20.47    // Hack XXX FIX ME !!!
   20.48    // A scavenge may not have been attempted, or may have
   20.49    // been attempted and failed, because the old gen was too full
   20.50 -  if (local_max_level == 0 && gc_cause() == GCCause::_gc_locker &&
   20.51 -      incremental_collection_will_fail(false /* don't consult_young */)) {
   20.52 +  if (gc_cause() == GCCause::_gc_locker && incremental_collection_failed()) {
   20.53      if (PrintGCDetails) {
   20.54        gclog_or_tty->print_cr("GC locker: Trying a full collection "
   20.55                               "because scavenge failed");
    21.1 --- a/src/share/vm/opto/escape.cpp	Wed Nov 27 05:33:18 2019 +0000
    21.2 +++ b/src/share/vm/opto/escape.cpp	Wed Dec 04 16:23:46 2019 +0000
    21.3 @@ -952,6 +952,7 @@
    21.4                    strcmp(call->as_CallLeaf()->_name, "aescrypt_decryptBlock") == 0 ||
    21.5                    strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_encryptAESCrypt") == 0 ||
    21.6                    strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0 ||
    21.7 +                  strcmp(call->as_CallLeaf()->_name, "ghash_processBlocks") == 0 ||
    21.8                    strcmp(call->as_CallLeaf()->_name, "sha1_implCompress") == 0 ||
    21.9                    strcmp(call->as_CallLeaf()->_name, "sha1_implCompressMB") == 0 ||
   21.10                    strcmp(call->as_CallLeaf()->_name, "sha256_implCompress") == 0 ||
    22.1 --- a/src/share/vm/opto/library_call.cpp	Wed Nov 27 05:33:18 2019 +0000
    22.2 +++ b/src/share/vm/opto/library_call.cpp	Wed Dec 04 16:23:46 2019 +0000
    22.3 @@ -311,6 +311,7 @@
    22.4    Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
    22.5    Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
    22.6    Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
    22.7 +  bool inline_ghash_processBlocks();
    22.8    bool inline_sha_implCompress(vmIntrinsics::ID id);
    22.9    bool inline_digestBase_implCompressMB(int predicate);
   22.10    bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
   22.11 @@ -570,6 +571,10 @@
   22.12      predicates = 3;
   22.13      break;
   22.14  
   22.15 +  case vmIntrinsics::_ghash_processBlocks:
   22.16 +    if (!UseGHASHIntrinsics) return NULL;
   22.17 +    break;
   22.18 +
   22.19    case vmIntrinsics::_updateCRC32:
   22.20    case vmIntrinsics::_updateBytesCRC32:
   22.21    case vmIntrinsics::_updateByteBufferCRC32:
   22.22 @@ -957,6 +962,9 @@
   22.23    case vmIntrinsics::_montgomerySquare:
   22.24      return inline_montgomerySquare();
   22.25  
   22.26 +  case vmIntrinsics::_ghash_processBlocks:
   22.27 +    return inline_ghash_processBlocks();
   22.28 +
   22.29    case vmIntrinsics::_encodeISOArray:
   22.30      return inline_encodeISOArray();
   22.31  
   22.32 @@ -6599,6 +6607,35 @@
   22.33    return _gvn.transform(region);
   22.34  }
   22.35  
   22.36 +//------------------------------inline_ghash_processBlocks
   22.37 +bool LibraryCallKit::inline_ghash_processBlocks() {
   22.38 +  address stubAddr;
   22.39 +  const char *stubName;
   22.40 +  assert(UseGHASHIntrinsics, "need GHASH intrinsics support");
   22.41 +
   22.42 +  stubAddr = StubRoutines::ghash_processBlocks();
   22.43 +  stubName = "ghash_processBlocks";
   22.44 +
   22.45 +  Node* data           = argument(0);
   22.46 +  Node* offset         = argument(1);
   22.47 +  Node* len            = argument(2);
   22.48 +  Node* state          = argument(3);
   22.49 +  Node* subkeyH        = argument(4);
   22.50 +
   22.51 +  Node* state_start  = array_element_address(state, intcon(0), T_LONG);
   22.52 +  assert(state_start, "state is NULL");
   22.53 +  Node* subkeyH_start  = array_element_address(subkeyH, intcon(0), T_LONG);
   22.54 +  assert(subkeyH_start, "subkeyH is NULL");
   22.55 +  Node* data_start  = array_element_address(data, offset, T_BYTE);
   22.56 +  assert(data_start, "data is NULL");
   22.57 +
   22.58 +  Node* ghash = make_runtime_call(RC_LEAF|RC_NO_FP,
   22.59 +                                  OptoRuntime::ghash_processBlocks_Type(),
   22.60 +                                  stubAddr, stubName, TypePtr::BOTTOM,
   22.61 +                                  state_start, subkeyH_start, data_start, len);
   22.62 +  return true;
   22.63 +}
   22.64 +
   22.65  //------------------------------inline_sha_implCompress-----------------------
   22.66  //
   22.67  // Calculate SHA (i.e., SHA-1) for single-block byte[] array.
    23.1 --- a/src/share/vm/opto/runtime.cpp	Wed Nov 27 05:33:18 2019 +0000
    23.2 +++ b/src/share/vm/opto/runtime.cpp	Wed Dec 04 16:23:46 2019 +0000
    23.3 @@ -92,7 +92,25 @@
    23.4  // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000
    23.5  
    23.6  
    23.7 +// GHASH block processing
    23.8 +const TypeFunc* OptoRuntime::ghash_processBlocks_Type() {
    23.9 +    int argcnt = 4;
   23.10  
   23.11 +    const Type** fields = TypeTuple::fields(argcnt);
   23.12 +    int argp = TypeFunc::Parms;
   23.13 +    fields[argp++] = TypePtr::NOTNULL;    // state
   23.14 +    fields[argp++] = TypePtr::NOTNULL;    // subkeyH
   23.15 +    fields[argp++] = TypePtr::NOTNULL;    // data
   23.16 +    fields[argp++] = TypeInt::INT;        // blocks
   23.17 +    assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
   23.18 +    const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
   23.19 +
   23.20 +    // result type needed
   23.21 +    fields = TypeTuple::fields(1);
   23.22 +    fields[TypeFunc::Parms+0] = NULL; // void
   23.23 +    const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
   23.24 +    return TypeFunc::make(domain, range);
   23.25 +}
   23.26  
   23.27  // Compiled code entry points
   23.28  address OptoRuntime::_new_instance_Java                           = NULL;
    24.1 --- a/src/share/vm/opto/runtime.hpp	Wed Nov 27 05:33:18 2019 +0000
    24.2 +++ b/src/share/vm/opto/runtime.hpp	Wed Dec 04 16:23:46 2019 +0000
    24.3 @@ -311,6 +311,8 @@
    24.4    static const TypeFunc* montgomeryMultiply_Type();
    24.5    static const TypeFunc* montgomerySquare_Type();
    24.6  
    24.7 +  static const TypeFunc* ghash_processBlocks_Type();
    24.8 +
    24.9    static const TypeFunc* updateBytesCRC32_Type();
   24.10  
   24.11    // leaf on stack replacement interpreter accessor types
    25.1 --- a/src/share/vm/runtime/globals.hpp	Wed Nov 27 05:33:18 2019 +0000
    25.2 +++ b/src/share/vm/runtime/globals.hpp	Wed Dec 04 16:23:46 2019 +0000
    25.3 @@ -602,6 +602,9 @@
    25.4    product(bool, UseSHA, false,                                              \
    25.5            "Control whether SHA instructions can be used on SPARC")          \
    25.6                                                                              \
    25.7 +  product(bool, UseGHASHIntrinsics, false,                                  \
    25.8 +          "Use intrinsics for GHASH versions of crypto")                    \
    25.9 +                                                                            \
   25.10    product(uintx, LargePageSizeInBytes, 0,                                   \
   25.11            "Large page size (0 to let VM choose the page size)")             \
   25.12                                                                              \
    26.1 --- a/src/share/vm/runtime/stubRoutines.cpp	Wed Nov 27 05:33:18 2019 +0000
    26.2 +++ b/src/share/vm/runtime/stubRoutines.cpp	Wed Dec 04 16:23:46 2019 +0000
    26.3 @@ -124,6 +124,7 @@
    26.4  address StubRoutines::_aescrypt_decryptBlock               = NULL;
    26.5  address StubRoutines::_cipherBlockChaining_encryptAESCrypt = NULL;
    26.6  address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL;
    26.7 +address StubRoutines::_ghash_processBlocks                 = NULL;
    26.8  
    26.9  address StubRoutines::_sha1_implCompress     = NULL;
   26.10  address StubRoutines::_sha1_implCompressMB   = NULL;
    27.1 --- a/src/share/vm/runtime/stubRoutines.hpp	Wed Nov 27 05:33:18 2019 +0000
    27.2 +++ b/src/share/vm/runtime/stubRoutines.hpp	Wed Dec 04 16:23:46 2019 +0000
    27.3 @@ -197,6 +197,7 @@
    27.4    static address _aescrypt_decryptBlock;
    27.5    static address _cipherBlockChaining_encryptAESCrypt;
    27.6    static address _cipherBlockChaining_decryptAESCrypt;
    27.7 +  static address _ghash_processBlocks;
    27.8  
    27.9    static address _sha1_implCompress;
   27.10    static address _sha1_implCompressMB;
   27.11 @@ -359,6 +360,7 @@
   27.12    static address aescrypt_decryptBlock()                { return _aescrypt_decryptBlock; }
   27.13    static address cipherBlockChaining_encryptAESCrypt()  { return _cipherBlockChaining_encryptAESCrypt; }
   27.14    static address cipherBlockChaining_decryptAESCrypt()  { return _cipherBlockChaining_decryptAESCrypt; }
   27.15 +  static address ghash_processBlocks() { return _ghash_processBlocks; }
   27.16  
   27.17    static address sha1_implCompress()     { return _sha1_implCompress; }
   27.18    static address sha1_implCompressMB()   { return _sha1_implCompressMB; }
    28.1 --- a/src/share/vm/runtime/vmStructs.cpp	Wed Nov 27 05:33:18 2019 +0000
    28.2 +++ b/src/share/vm/runtime/vmStructs.cpp	Wed Dec 04 16:23:46 2019 +0000
    28.3 @@ -810,6 +810,7 @@
    28.4       static_field(StubRoutines,                _aescrypt_decryptBlock,                        address)                               \
    28.5       static_field(StubRoutines,                _cipherBlockChaining_encryptAESCrypt,          address)                               \
    28.6       static_field(StubRoutines,                _cipherBlockChaining_decryptAESCrypt,          address)                               \
    28.7 +     static_field(StubRoutines,                _ghash_processBlocks,                          address)                               \
    28.8       static_field(StubRoutines,                _updateBytesCRC32,                             address)                               \
    28.9       static_field(StubRoutines,                _crc_table_adr,                                address)                               \
   28.10       static_field(StubRoutines,                _multiplyToLen,                                address)                               \
    29.1 --- a/test/compiler/7184394/TestAESBase.java	Wed Nov 27 05:33:18 2019 +0000
    29.2 +++ b/test/compiler/7184394/TestAESBase.java	Wed Dec 04 16:23:46 2019 +0000
    29.3 @@ -29,6 +29,7 @@
    29.4  import javax.crypto.Cipher;
    29.5  import javax.crypto.KeyGenerator;
    29.6  import javax.crypto.SecretKey;
    29.7 +import javax.crypto.spec.GCMParameterSpec;
    29.8  import javax.crypto.spec.IvParameterSpec;
    29.9  import javax.crypto.spec.SecretKeySpec;
   29.10  import java.security.AlgorithmParameters;
   29.11 @@ -62,8 +63,12 @@
   29.12    Random random = new Random(0);
   29.13    Cipher cipher;
   29.14    Cipher dCipher;
   29.15 -  AlgorithmParameters algParams;
   29.16 +  AlgorithmParameters algParams = null;
   29.17    SecretKey key;
   29.18 +  GCMParameterSpec gcm_spec;
   29.19 +  byte[] aad = { 0x11, 0x22, 0x33, 0x44, 0x55 };
   29.20 +  int tlen = 12;
   29.21 +  byte[] iv = new byte[16];
   29.22  
   29.23    static int numThreads = 0;
   29.24    int  threadId;
   29.25 @@ -77,7 +82,10 @@
   29.26  
   29.27    public void prepare() {
   29.28      try {
   29.29 -    System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr + ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit + ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" + encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize );
   29.30 +      System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr +
   29.31 +              ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit +
   29.32 +              ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" +
   29.33 +              encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize );
   29.34  
   29.35        if (encInputOffset % ALIGN != 0 || encOutputOffset % ALIGN != 0 || decOutputOffset % ALIGN !=0 )
   29.36          testingMisalignment = true;
   29.37 @@ -98,16 +106,24 @@
   29.38        cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
   29.39        dCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
   29.40  
   29.41 +      // CBC init
   29.42        if (mode.equals("CBC")) {
   29.43 -        int ivLen = (algorithm.equals("AES") ? 16 : algorithm.equals("DES") ? 8 : 0);
   29.44 -        IvParameterSpec initVector = new IvParameterSpec(new byte[ivLen]);
   29.45 +        IvParameterSpec initVector = new IvParameterSpec(iv);
   29.46          cipher.init(Cipher.ENCRYPT_MODE, key, initVector);
   29.47 +        algParams = cipher.getParameters();
   29.48 +        dCipher.init(Cipher.DECRYPT_MODE, key, initVector);
   29.49 +
   29.50 +      // GCM init
   29.51 +      } else if (mode.equals("GCM")) {
   29.52 +        gcm_init(true);
   29.53 +        gcm_init(false);
   29.54 +
   29.55 +      // ECB init
   29.56        } else {
   29.57 -        algParams = cipher.getParameters();
   29.58          cipher.init(Cipher.ENCRYPT_MODE, key, algParams);
   29.59 +        dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
   29.60        }
   29.61 -      algParams = cipher.getParameters();
   29.62 -      dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
   29.63 +
   29.64        if (threadId == 0) {
   29.65          childShowCipher();
   29.66        }
   29.67 @@ -188,4 +204,19 @@
   29.68    }
   29.69  
   29.70    abstract void childShowCipher();
   29.71 +
   29.72 +  void gcm_init(boolean encrypt) throws Exception {
   29.73 +    gcm_spec = new GCMParameterSpec(tlen * 8, iv);
   29.74 +    if (encrypt) {
   29.75 +      // Get a new instance everytime because of reuse IV restrictions
   29.76 +      cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
   29.77 +      cipher.init(Cipher.ENCRYPT_MODE, key, gcm_spec);
   29.78 +      cipher.updateAAD(aad);
   29.79 +    } else {
   29.80 +      dCipher.init(Cipher.DECRYPT_MODE, key, gcm_spec);
   29.81 +      dCipher.updateAAD(aad);
   29.82 +
   29.83 +
   29.84 +    }
   29.85 +  }
   29.86  }
    30.1 --- a/test/compiler/7184394/TestAESDecode.java	Wed Nov 27 05:33:18 2019 +0000
    30.2 +++ b/test/compiler/7184394/TestAESDecode.java	Wed Dec 04 16:23:46 2019 +0000
    30.3 @@ -32,7 +32,11 @@
    30.4    @Override
    30.5    public void run() {
    30.6      try {
    30.7 -      if (!noReinit) dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
    30.8 +      if (mode.equals("GCM")) {
    30.9 +        gcm_init(false);
   30.10 +      } else if (!noReinit) {
   30.11 +        dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
   30.12 +      }
   30.13        decode = new byte[decodeLength];
   30.14        if (testingMisalignment) {
   30.15          int tempSize = dCipher.update(encode, encOutputOffset, (decodeMsgSize - lastChunkSize), decode, decOutputOffset);
    31.1 --- a/test/compiler/7184394/TestAESEncode.java	Wed Nov 27 05:33:18 2019 +0000
    31.2 +++ b/test/compiler/7184394/TestAESEncode.java	Wed Dec 04 16:23:46 2019 +0000
    31.3 @@ -1,5 +1,5 @@
    31.4  /*
    31.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
    31.6 + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
    31.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    31.8   *
    31.9   * This code is free software; you can redistribute it and/or modify it
   31.10 @@ -32,7 +32,11 @@
   31.11    @Override
   31.12    public void run() {
   31.13      try {
   31.14 -      if (!noReinit) cipher.init(Cipher.ENCRYPT_MODE, key, algParams);
   31.15 +      if (mode.equals("GCM")) {
   31.16 +        gcm_init(true);
   31.17 +      } else if (!noReinit) {
   31.18 +        cipher.init(Cipher.ENCRYPT_MODE, key, algParams);
   31.19 +      }
   31.20        encode = new byte[encodeLength];
   31.21        if (testingMisalignment) {
   31.22          int tempSize = cipher.update(input, encInputOffset, (msgSize - lastChunkSize), encode, encOutputOffset);
    32.1 --- a/test/compiler/7184394/TestAESMain.java	Wed Nov 27 05:33:18 2019 +0000
    32.2 +++ b/test/compiler/7184394/TestAESMain.java	Wed Dec 04 16:23:46 2019 +0000
    32.3 @@ -41,6 +41,13 @@
    32.4   * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 TestAESMain
    32.5   * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 TestAESMain
    32.6   * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=ECB -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 -DpaddingStr=NoPadding -DmsgSize=640 TestAESMain
    32.7 + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM TestAESMain
    32.8 + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 TestAESMain
    32.9 + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencOutputOffset=1 TestAESMain
   32.10 + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DdecOutputOffset=1 TestAESMain
   32.11 + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 TestAESMain
   32.12 + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 TestAESMain
   32.13 + * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=GCM -DencInputOffset=1 -DencOutputOffset=1 -DdecOutputOffset=1 -DpaddingStr=NoPadding -DmsgSize=640 TestAESMain
   32.14   *
   32.15   * @author Tom Deneau
   32.16   */
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/test/gc/stress/gclocker/TestExcessGCLockerCollections.java	Wed Dec 04 16:23:46 2019 +0000
    33.3 @@ -0,0 +1,285 @@
    33.4 +/*
    33.5 + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
    33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    33.7 + *
    33.8 + * This code is free software; you can redistribute it and/or modify it
    33.9 + * under the terms of the GNU General Public License version 2 only, as
   33.10 + * published by the Free Software Foundation.
   33.11 + *
   33.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   33.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   33.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   33.15 + * version 2 for more details (a copy is included in the LICENSE file that
   33.16 + * accompanied this code).
   33.17 + *
   33.18 + * You should have received a copy of the GNU General Public License version
   33.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   33.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   33.21 + *
   33.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   33.23 + * or visit www.oracle.com if you need additional information or have any
   33.24 + * questions.
   33.25 + */
   33.26 +
   33.27 +package gc.stress.gclocker;
   33.28 +
   33.29 +// Based on Kim Barrett;s test for JDK-8048556
   33.30 +
   33.31 +/*
   33.32 + * @test TestExcessGCLockerCollections
   33.33 + * @key gc
   33.34 + * @bug 8048556
   33.35 + * @summary Check for GC Locker initiated GCs that immediately follow another
   33.36 + * GC and so have very little needing to be collected.
   33.37 + * @library /testlibrary
   33.38 + * @run driver/timeout=1000 gc.stress.gclocker.TestExcessGCLockerCollections 300 4 2
   33.39 + */
   33.40 +
   33.41 +import java.util.HashMap;
   33.42 +import java.util.Map;
   33.43 +
   33.44 +import java.util.zip.Deflater;
   33.45 +
   33.46 +import java.util.ArrayList;
   33.47 +import java.util.Arrays;
   33.48 +
   33.49 +import javax.management.MBeanServer;
   33.50 +import javax.management.Notification;
   33.51 +import javax.management.NotificationListener;
   33.52 +import javax.management.openmbean.CompositeData;
   33.53 +import java.lang.management.ManagementFactory;
   33.54 +import java.lang.management.GarbageCollectorMXBean;
   33.55 +import java.lang.management.MemoryUsage;
   33.56 +import java.util.List;
   33.57 +import com.sun.management.GarbageCollectionNotificationInfo;
   33.58 +import com.sun.management.GcInfo;
   33.59 +
   33.60 +import com.oracle.java.testlibrary.Asserts;
   33.61 +import com.oracle.java.testlibrary.ProcessTools;
   33.62 +import com.oracle.java.testlibrary.OutputAnalyzer;
   33.63 +
   33.64 +class TestExcessGCLockerCollectionsStringConstants {
   33.65 +    // Some constant strings used in both GC logging and error detection
   33.66 +    static public final String GCLOCKER_CAUSE = "GCLocker Initiated GC";
   33.67 +    static public final String USED_TOO_LOW = "TOO LOW";
   33.68 +    static public final String USED_OK = "OK";
   33.69 +}
   33.70 +
   33.71 +class TestExcessGCLockerCollectionsAux {
   33.72 +    static private final int LARGE_MAP_SIZE = 64 * 1024;
   33.73 +
   33.74 +    static private final int MAP_ARRAY_LENGTH = 4;
   33.75 +    static private final int MAP_SIZE = 1024;
   33.76 +
   33.77 +    static private final int BYTE_ARRAY_LENGTH = 128 * 1024;
   33.78 +
   33.79 +    static private void println(String str) { System.out.println(str); }
   33.80 +    static private void println()           { System.out.println();    }
   33.81 +
   33.82 +    static private volatile boolean keepRunning = true;
   33.83 +
   33.84 +    static Map<Integer,String> populateMap(int size) {
   33.85 +        Map<Integer,String> map = new HashMap<Integer,String>();
   33.86 +        for (int i = 0; i < size; i += 1) {
   33.87 +            Integer keyInt = Integer.valueOf(i);
   33.88 +            String valStr = "value is [" + i + "]";
   33.89 +            map.put(keyInt,valStr);
   33.90 +        }
   33.91 +        return map;
   33.92 +    }
   33.93 +
   33.94 +    static private class AllocatingWorker implements Runnable {
   33.95 +        private final Object[] array = new Object[MAP_ARRAY_LENGTH];
   33.96 +        private int arrayIndex = 0;
   33.97 +
   33.98 +        private void doStep() {
   33.99 +            Map<Integer,String> map = populateMap(MAP_SIZE);
  33.100 +            array[arrayIndex] = map;
  33.101 +            arrayIndex = (arrayIndex + 1) % MAP_ARRAY_LENGTH;
  33.102 +        }
  33.103 +
  33.104 +        public void run() {
  33.105 +            while (keepRunning) {
  33.106 +                doStep();
  33.107 +            }
  33.108 +        }
  33.109 +    }
  33.110 +
  33.111 +    static private class JNICriticalWorker implements Runnable {
  33.112 +        private int count;
  33.113 +
  33.114 +        private void doStep() {
  33.115 +            byte[] inputArray = new byte[BYTE_ARRAY_LENGTH];
  33.116 +            for (int i = 0; i < inputArray.length; i += 1) {
  33.117 +                inputArray[i] = (byte) (count + i);
  33.118 +            }
  33.119 +
  33.120 +            Deflater deflater = new Deflater();
  33.121 +            deflater.setInput(inputArray);
  33.122 +            deflater.finish();
  33.123 +
  33.124 +            byte[] outputArray = new byte[2 * inputArray.length];
  33.125 +            deflater.deflate(outputArray);
  33.126 +
  33.127 +            count += 1;
  33.128 +        }
  33.129 +
  33.130 +        public void run() {
  33.131 +            while (keepRunning) {
  33.132 +                doStep();
  33.133 +            }
  33.134 +        }
  33.135 +    }
  33.136 +
  33.137 +    static class GCNotificationListener implements NotificationListener {
  33.138 +        static private final double MIN_USED_PERCENT = 40.0;
  33.139 +
  33.140 +        static private final List<String> newGenPoolNames = Arrays.asList(
  33.141 +                "G1 Eden Space",           // OpenJDK G1GC: -XX:+UseG1GC
  33.142 +                "PS Eden Space",           // OpenJDK ParallelGC: -XX:+ParallelGC
  33.143 +                "Par Eden Space",          // OpenJDK ConcMarkSweepGC: -XX:+ConcMarkSweepGC
  33.144 +                "Eden Space"               // OpenJDK SerialGC: -XX:+UseSerialGC
  33.145 +                                           // OpenJDK ConcMarkSweepGC: -XX:+ConcMarkSweepGC -XX:-UseParNewGC
  33.146 +        );
  33.147 +
  33.148 +        @Override
  33.149 +        public void handleNotification(Notification notification, Object handback) {
  33.150 +            try {
  33.151 +                if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
  33.152 +                    GarbageCollectionNotificationInfo info =
  33.153 +                            GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData());
  33.154 +
  33.155 +                    String gc_cause = info.getGcCause();
  33.156 +
  33.157 +                    if (gc_cause.equals(TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE)) {
  33.158 +                        Map<String, MemoryUsage> memory_before_gc = info.getGcInfo().getMemoryUsageBeforeGc();
  33.159 +
  33.160 +                        for (String newGenPoolName : newGenPoolNames) {
  33.161 +                            MemoryUsage usage = memory_before_gc.get(newGenPoolName);
  33.162 +                            if (usage == null) continue;
  33.163 +
  33.164 +                            double startTime = ((double) info.getGcInfo().getStartTime()) / 1000.0;
  33.165 +                            long used = usage.getUsed();
  33.166 +                            long committed = usage.getCommitted();
  33.167 +                            long max = usage.getMax();
  33.168 +                            double used_percent = (((double) used) / Math.max(committed, max)) * 100.0;
  33.169 +
  33.170 +                            System.out.printf("%6.3f: (%s) %d/%d/%d, %8.4f%% (%s)\n",
  33.171 +                                              startTime, gc_cause, used, committed, max, used_percent,
  33.172 +                                              ((used_percent < MIN_USED_PERCENT) ? TestExcessGCLockerCollectionsStringConstants.USED_TOO_LOW
  33.173 +                                                                                 : TestExcessGCLockerCollectionsStringConstants.USED_OK));
  33.174 +                        }
  33.175 +                    }
  33.176 +                }
  33.177 +            } catch (RuntimeException ex) {
  33.178 +                System.err.println("Exception during notification processing:" + ex);
  33.179 +                ex.printStackTrace();
  33.180 +            }
  33.181 +        }
  33.182 +
  33.183 +        public static boolean register() {
  33.184 +            try {
  33.185 +                MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
  33.186 +
  33.187 +                // Get the list of MX
  33.188 +                List<GarbageCollectorMXBean> gc_mxbeans = ManagementFactory.getGarbageCollectorMXBeans();
  33.189 +
  33.190 +                // Create the notification listener
  33.191 +                GCNotificationListener gcNotificationListener = new GCNotificationListener();
  33.192 +
  33.193 +                for (GarbageCollectorMXBean gcbean : gc_mxbeans) {
  33.194 +                  // Add notification listener for the MXBean
  33.195 +                  mbeanServer.addNotificationListener(gcbean.getObjectName(), gcNotificationListener, null, null);
  33.196 +                }
  33.197 +            } catch (Exception ex) {
  33.198 +                System.err.println("Exception during mbean registration:" + ex);
  33.199 +                ex.printStackTrace();
  33.200 +                // We've failed to set up, terminate
  33.201 +                return false;
  33.202 +            }
  33.203 +
  33.204 +            return true;
  33.205 +        }
  33.206 +    }
  33.207 +
  33.208 +    static public Map<Integer,String> largeMap;
  33.209 +
  33.210 +    static public void main(String args[]) {
  33.211 +        long durationSec = Long.parseLong(args[0]);
  33.212 +        int allocThreadNum = Integer.parseInt(args[1]);
  33.213 +        int jniCriticalThreadNum = Integer.parseInt(args[2]);
  33.214 +
  33.215 +        println("Running for " + durationSec + " secs");
  33.216 +
  33.217 +        if (!GCNotificationListener.register()) {
  33.218 +          println("failed to register GC notification listener");
  33.219 +          System.exit(-1);
  33.220 +        }
  33.221 +
  33.222 +        largeMap = populateMap(LARGE_MAP_SIZE);
  33.223 +
  33.224 +        println("Starting " + allocThreadNum + " allocating threads");
  33.225 +        for (int i = 0; i < allocThreadNum; i += 1) {
  33.226 +            new Thread(new AllocatingWorker()).start();
  33.227 +        }
  33.228 +
  33.229 +        println("Starting " + jniCriticalThreadNum + " jni critical threads");
  33.230 +        for (int i = 0; i < jniCriticalThreadNum; i += 1) {
  33.231 +            new Thread(new JNICriticalWorker()).start();
  33.232 +        }
  33.233 +
  33.234 +        long durationMS = (long) (1000 * durationSec);
  33.235 +        long start = System.currentTimeMillis();
  33.236 +        long now = start;
  33.237 +        long soFar = now - start;
  33.238 +        while (soFar < durationMS) {
  33.239 +            try {
  33.240 +                Thread.sleep(durationMS - soFar);
  33.241 +            } catch (Exception e) {
  33.242 +            }
  33.243 +            now = System.currentTimeMillis();
  33.244 +            soFar = now - start;
  33.245 +        }
  33.246 +        println("Done.");
  33.247 +        keepRunning = false;
  33.248 +    }
  33.249 +}
  33.250 +
  33.251 +public class TestExcessGCLockerCollections {
  33.252 +    private static final String USED_OK_LINE =
  33.253 +        "\\(" + TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE + "\\)"
  33.254 +              + " .* " +
  33.255 +        "\\(" + TestExcessGCLockerCollectionsStringConstants.USED_OK + "\\)";
  33.256 +    private static final String USED_TOO_LOW_LINE =
  33.257 +        "\\(" + TestExcessGCLockerCollectionsStringConstants.GCLOCKER_CAUSE + "\\)"
  33.258 +              + " .* " +
  33.259 +        "\\(" + TestExcessGCLockerCollectionsStringConstants.USED_TOO_LOW + "\\)";
  33.260 +
  33.261 +    private static final String[] COMMON_OPTIONS = new String[] {
  33.262 +        "-Xmx1G", "-Xms1G", "-Xmn256M" };
  33.263 +
  33.264 +    public static void main(String args[]) throws Exception {
  33.265 +        if (args.length < 3) {
  33.266 +            System.out.println("usage: TestExcessGCLockerCollections" +
  33.267 +                               " <duration sec> <alloc threads>" +
  33.268 +                               " <jni critical threads>");
  33.269 +            throw new RuntimeException("Invalid arguments");
  33.270 +        }
  33.271 +
  33.272 +        ArrayList<String> finalArgs = new ArrayList<String>();
  33.273 +        finalArgs.addAll(Arrays.asList(COMMON_OPTIONS));
  33.274 +        finalArgs.add(TestExcessGCLockerCollectionsAux.class.getName());
  33.275 +        finalArgs.addAll(Arrays.asList(args));
  33.276 +
  33.277 +        // GC and other options obtained from test framework.
  33.278 +        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
  33.279 +            true, finalArgs.toArray(new String[0]));
  33.280 +        OutputAnalyzer output = new OutputAnalyzer(pb.start());
  33.281 +        output.shouldHaveExitValue(0);
  33.282 +        //System.out.println("------------- begin stdout ----------------");
  33.283 +        //System.out.println(output.getStdout());
  33.284 +        //System.out.println("------------- end stdout ----------------");
  33.285 +        output.stdoutShouldMatch(USED_OK_LINE);
  33.286 +        output.stdoutShouldNotMatch(USED_TOO_LOW_LINE);
  33.287 +    }
  33.288 +}

mercurial