src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationEncoding.java
changeset 58793 81ad1da857f6
parent 54669 ad45b3802d4e
equal deleted inserted replaced
58790:5a9dba5a3eeb 58793:81ad1da857f6
    27 import java.io.IOException;
    27 import java.io.IOException;
    28 import java.security.MessageDigest;
    28 import java.security.MessageDigest;
    29 import java.security.NoSuchAlgorithmException;
    29 import java.security.NoSuchAlgorithmException;
    30 import java.util.Arrays;
    30 import java.util.Arrays;
    31 
    31 
    32 import jdk.vm.ci.common.JVMCIError;
       
    33 import jdk.vm.ci.meta.ResolvedJavaMethod;
    32 import jdk.vm.ci.meta.ResolvedJavaMethod;
    34 import jdk.vm.ci.meta.ResolvedJavaType;
    33 import jdk.vm.ci.meta.ResolvedJavaType;
    35 import jdk.vm.ci.meta.SpeculationLog.SpeculationReasonEncoding;
    34 import jdk.vm.ci.meta.SpeculationLog.SpeculationReasonEncoding;
    36 
    35 
    37 /**
    36 /**
    38  * Implements a {@link SpeculationReasonEncoding} that {@linkplain #getByteArray() produces} a byte
    37  * Implements a {@link SpeculationReasonEncoding} that {@linkplain #getByteArray() produces} a byte
    39  * array. Data is added via a {@link DataOutputStream}. When producing the final byte array, if the
    38  * array. Data is added via a {@link DataOutputStream}. When producing the final byte array, if the
    40  * total length of data exceeds the length of a SHA-1 digest, then a SHA-1 digest of the data is
    39  * total length of data exceeds the length of a SHA-1 digest and a SHA-1 digest algorithm is
    41  * produced instead.
    40  * available, then a SHA-1 digest of the data is produced instead.
    42  */
    41  */
    43 final class HotSpotSpeculationEncoding extends ByteArrayOutputStream implements SpeculationReasonEncoding {
    42 final class HotSpotSpeculationEncoding extends ByteArrayOutputStream implements SpeculationReasonEncoding {
    44 
    43 
    45     private DataOutputStream dos = new DataOutputStream(this);
    44     private DataOutputStream dos = new DataOutputStream(this);
    46     private byte[] result;
    45     private byte[] result;
   150         }
   149         }
   151         return false;
   150         return false;
   152     }
   151     }
   153 
   152 
   154     /**
   153     /**
   155      * Prototype SHA1 digest that is cloned before use.
   154      * Prototype SHA1 digest.
   156      */
   155      */
   157     private static final MessageDigest SHA1 = getSHA1();
   156     private static final MessageDigest SHA1;
   158     private static final int SHA1_LENGTH = SHA1.getDigestLength();
   157 
   159 
   158     /**
   160     private static MessageDigest getSHA1() {
   159      * Cloning the prototype is quicker than calling {@link MessageDigest#getInstance(String)} every
   161         try {
   160      * time.
   162             MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
   161      */
       
   162     private static final boolean SHA1_IS_CLONEABLE;
       
   163     private static final int SHA1_LENGTH;
       
   164 
       
   165     static {
       
   166         MessageDigest sha1 = null;
       
   167         boolean sha1IsCloneable = false;
       
   168         try {
       
   169             sha1 = MessageDigest.getInstance("SHA-1");
   163             sha1.clone();
   170             sha1.clone();
   164             return sha1;
   171             sha1IsCloneable = true;
   165         } catch (CloneNotSupportedException | NoSuchAlgorithmException e) {
   172         } catch (NoSuchAlgorithmException e) {
   166             // Should never happen given that SHA-1 is mandated in a
   173             // Should never happen given that SHA-1 is mandated in a
   167             // compliant Java platform implementation.
   174             // compliant Java platform implementation. However, be
   168             throw new JVMCIError("Expect a cloneable implementation of a SHA-1 message digest to be available", e);
   175             // conservative and fall back to not using a digest.
   169         }
   176         } catch (CloneNotSupportedException e) {
       
   177         }
       
   178         SHA1 = sha1;
       
   179         SHA1_IS_CLONEABLE = sha1IsCloneable;
       
   180         SHA1_LENGTH = SHA1 == null ? 20 : SHA1.getDigestLength();
   170     }
   181     }
   171 
   182 
   172     /**
   183     /**
   173      * Gets the final encoded byte array and closes this encoding such that any further attempts to
   184      * Gets the final encoded byte array and closes this encoding such that any further attempts to
   174      * update it result in an {@link IllegalArgumentException}.
   185      * update it result in an {@link IllegalArgumentException}.
   175      */
   186      */
   176     byte[] getByteArray() {
   187     byte[] getByteArray() {
   177         if (result == null) {
   188         if (result == null) {
   178             if (count > SHA1_LENGTH) {
   189             if (SHA1 != null && count > SHA1_LENGTH) {
   179                 try {
   190                 try {
   180                     MessageDigest md = (MessageDigest) SHA1.clone();
   191                     MessageDigest md = SHA1_IS_CLONEABLE ? (MessageDigest) SHA1.clone() : MessageDigest.getInstance("SHA-1");
   181                     md.update(buf, 0, count);
   192                     md.update(buf, 0, count);
   182                     result = md.digest();
   193                     result = md.digest();
   183                 } catch (CloneNotSupportedException e) {
   194                 } catch (CloneNotSupportedException | NoSuchAlgorithmException e) {
   184                     throw new InternalError(e);
   195                     throw new InternalError(e);
   185                 }
   196                 }
   186             } else {
   197             } else {
   187                 if (buf.length == count) {
   198                 if (buf.length == count) {
   188                     // No need to copy the byte array
   199                     // No need to copy the byte array