{@link SecureRandomSpi#engineReseed(SecureRandomParameters)}
*
*
+ * @spec https://www.rfc-editor.org/info/rfc4086
+ * RFC 4086: Randomness Requirements for Security
+ * @spec https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.140-2.pdf
+ * Security Requirements for Cryptographic Modules
+ *
* @see java.security.SecureRandomSpi
* @see java.util.Random
*
diff --git a/src/java.base/share/classes/java/security/Security.java b/src/java.base/share/classes/java/security/Security.java
index 6628b717eb0..322605ef5ed 100644
--- a/src/java.base/share/classes/java/security/Security.java
+++ b/src/java.base/share/classes/java/security/Security.java
@@ -423,6 +423,7 @@ private static String getProviderProperty(String key, Provider provider) {
*
* @return the value of the specified property.
*
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
* @deprecated This method used to return the value of a proprietary
* property in the master file of the "SUN" Cryptographic Service
* Provider in order to determine how to parse algorithm-specific
@@ -657,6 +658,7 @@ public static Provider getProvider(String name) {
* if the filter is not in the required format
* @throws NullPointerException if filter is {@code null}
*
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
* @see #getProviders(java.util.Map)
* @since 1.3
*/
@@ -734,6 +736,7 @@ public static Provider[] getProviders(String filter) {
* if the filter is not in the required format
* @throws NullPointerException if filter is {@code null}
*
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
* @see #getProviders(java.lang.String)
* @since 1.3
*/
diff --git a/src/java.base/share/classes/java/security/cert/CRL.java b/src/java.base/share/classes/java/security/cert/CRL.java
index fec267de051..fee08c3c2ed 100644
--- a/src/java.base/share/classes/java/security/cert/CRL.java
+++ b/src/java.base/share/classes/java/security/cert/CRL.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, 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
@@ -56,6 +56,8 @@ public abstract class CRL {
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names document
* for information about standard CRL types.
+ *
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
*/
protected CRL(String type) {
this.type = type;
diff --git a/src/java.base/share/classes/java/security/cert/CRLReason.java b/src/java.base/share/classes/java/security/cert/CRLReason.java
index 2bc83f3356b..c2b19136c43 100644
--- a/src/java.base/share/classes/java/security/cert/CRLReason.java
+++ b/src/java.base/share/classes/java/security/cert/CRLReason.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,9 @@
* RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL
* Profile.
*
+ * @spec https://www.rfc-editor.org/info/rfc5280
+ * RFC 5280: Internet X.509 Public Key Infrastructure Certificate
+ * and Certificate Revocation List (CRL) Profile
* @author Sean Mullan
* @since 1.7
* @see X509CRLEntry#getRevocationReason
diff --git a/src/java.base/share/classes/java/security/cert/PKIXRevocationChecker.java b/src/java.base/share/classes/java/security/cert/PKIXRevocationChecker.java
index d36fcafd3e0..387b5ed8185 100644
--- a/src/java.base/share/classes/java/security/cert/PKIXRevocationChecker.java
+++ b/src/java.base/share/classes/java/security/cert/PKIXRevocationChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -81,14 +81,13 @@
* necessary locking. Multiple threads each manipulating separate objects
* need not synchronize.
*
+ * @spec https://www.rfc-editor.org/info/rfc2560
+ * RFC 2560: X.509 Internet Public Key Infrastructure Online Certificate
+ * Status Protocol - OCSP
+ * @spec https://www.rfc-editor.org/info/rfc5280
+ * RFC 5280: Internet X.509 Public Key Infrastructure Certificate
+ * and Certificate Revocation List (CRL) Profile
* @since 1.8
- *
- * @see RFC 2560: X.509
- * Internet Public Key Infrastructure Online Certificate Status Protocol -
- * OCSP
- * @see RFC 5280:
- * Internet X.509 Public Key Infrastructure Certificate and Certificate
- * Revocation List (CRL) Profile
*/
public abstract class PKIXRevocationChecker extends PKIXCertPathChecker {
private URI ocspResponder;
diff --git a/src/java.base/share/classes/java/security/cert/TrustAnchor.java b/src/java.base/share/classes/java/security/cert/TrustAnchor.java
index 2626bcf3c2d..33d1e5fb433 100644
--- a/src/java.base/share/classes/java/security/cert/TrustAnchor.java
+++ b/src/java.base/share/classes/java/security/cert/TrustAnchor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2024, 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
@@ -125,6 +125,10 @@ public class TrustAnchor {
* decoded
* @throws NullPointerException if the specified
* {@code X509Certificate} is {@code null}
+ *
+ * @spec https://www.rfc-editor.org/info/rfc5280
+ * RFC 5280: Internet X.509 Public Key Infrastructure Certificate
+ * and Certificate Revocation List (CRL) Profile
*/
public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints)
{
@@ -207,6 +211,10 @@ public TrustAnchor(X500Principal caPrincipal, PublicKey pubKey,
* or incorrectly formatted or the name constraints cannot be decoded
* @throws NullPointerException if the specified {@code caName} or
* {@code pubKey} parameter is {@code null}
+ *
+ * @spec https://www.rfc-editor.org/info/rfc2253
+ * RFC 2253: Lightweight Directory Access Protocol (v3):
+ * UTF-8 String Representation of Distinguished Names
*/
public TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints)
{
diff --git a/src/java.base/share/classes/java/security/cert/X509CRL.java b/src/java.base/share/classes/java/security/cert/X509CRL.java
index ddb622af1fe..111de1daf0e 100644
--- a/src/java.base/share/classes/java/security/cert/X509CRL.java
+++ b/src/java.base/share/classes/java/security/cert/X509CRL.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -95,6 +95,9 @@
* }
* }
*
+ * @spec https://www.rfc-editor.org/info/rfc5280
+ * RFC 5280: Internet X.509 Public Key Infrastructure Certificate
+ * and Certificate Revocation List (CRL) Profile
* @author Hemma Prafullchandra
* @since 1.2
*
@@ -457,6 +460,11 @@ public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
* relevant ASN.1 definitions.
*
* @return the signature algorithm OID string.
+ *
+ * @spec https://www.rfc-editor.org/info/rfc3279
+ * RFC 3279: Algorithms and Identifiers for the Internet X.509
+ * Public Key Infrastructure Certificate and Certificate
+ * Revocation List (CRL) Profile
*/
public abstract String getSigAlgOID();
diff --git a/src/java.base/share/classes/java/security/cert/X509CRLSelector.java b/src/java.base/share/classes/java/security/cert/X509CRLSelector.java
index 337dcc6342d..5660749884a 100644
--- a/src/java.base/share/classes/java/security/cert/X509CRLSelector.java
+++ b/src/java.base/share/classes/java/security/cert/X509CRLSelector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2024, 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
@@ -65,6 +65,9 @@
* provide the necessary locking. Multiple threads each manipulating
* separate objects need not synchronize.
*
+ * @spec https://www.rfc-editor.org/info/rfc5280
+ * RFC 5280: Internet X.509 Public Key Infrastructure Certificate
+ * and Certificate Revocation List (CRL) Profile
* @see CRLSelector
* @see X509CRL
*
@@ -193,6 +196,10 @@ public void setIssuers(Collection issuers) {
*
* @param names a {@code Collection} of names (or {@code null})
* @throws IOException if a parsing error occurs
+ *
+ * @spec https://www.rfc-editor.org/info/rfc2253
+ * RFC 2253: Lightweight Directory Access Protocol (v3):
+ * UTF-8 String Representation of Distinguished Names
* @see #getIssuerNames
*/
public void setIssuerNames(Collection> names) throws IOException {
@@ -238,6 +245,9 @@ public void addIssuer(X500Principal issuer) {
* RFC 2253 form
* @throws IOException if a parsing error occurs
*
+ * @spec https://www.rfc-editor.org/info/rfc2253
+ * RFC 2253: Lightweight Directory Access Protocol (v3):
+ * UTF-8 String Representation of Distinguished Names
* @deprecated Use {@link #addIssuer(X500Principal)} or
* {@link #addIssuerName(byte[])} instead. This method should not be
* relied on as it can fail to match some CRLs because of a loss of
@@ -493,6 +503,10 @@ public Collection getIssuers() {
* protect against subsequent modifications.
*
* @return a {@code Collection} of names (or {@code null})
+ *
+ * @spec https://www.rfc-editor.org/info/rfc2253
+ * RFC 2253: Lightweight Directory Access Protocol (v3):
+ * UTF-8 String Representation of Distinguished Names
* @see #setIssuerNames
*/
public Collection
*
*
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
* @since 1.4
*/
package javax.crypto;
diff --git a/src/java.base/share/classes/javax/crypto/spec/ChaCha20ParameterSpec.java b/src/java.base/share/classes/javax/crypto/spec/ChaCha20ParameterSpec.java
index 75c05269460..b1752ef940d 100644
--- a/src/java.base/share/classes/javax/crypto/spec/ChaCha20ParameterSpec.java
+++ b/src/java.base/share/classes/javax/crypto/spec/ChaCha20ParameterSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, 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
@@ -39,6 +39,8 @@
*
This class can be used to initialize a {@code Cipher} object that
* implements the ChaCha20 algorithm.
*
+ * @spec https://www.rfc-editor.org/info/rfc7539
+ * RFC 7539: ChaCha20 and Poly1305 for IETF Protocols
* @since 11
*/
public final class ChaCha20ParameterSpec implements AlgorithmParameterSpec {
diff --git a/src/java.base/share/classes/javax/crypto/spec/GCMParameterSpec.java b/src/java.base/share/classes/javax/crypto/spec/GCMParameterSpec.java
index 879d729c2ca..bb5fe5cdd5c 100644
--- a/src/java.base/share/classes/javax/crypto/spec/GCMParameterSpec.java
+++ b/src/java.base/share/classes/javax/crypto/spec/GCMParameterSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2024, 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
@@ -56,6 +56,12 @@
* applications. Other values can be specified for this class, but not
* all CSP implementations will support them.
*
+ * @spec https://www.rfc-editor.org/info/rfc5116
+ * RFC 5116: An Interface and Algorithms for Authenticated Encryption
+ * @spec https://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+ * Recommendation for Block Cipher Modes of Operation: Galois/Counter
+ * Mode (GCM) and GMAC
+ *
* @see javax.crypto.Cipher
*
* @since 1.7
diff --git a/src/java.base/share/classes/javax/crypto/spec/OAEPParameterSpec.java b/src/java.base/share/classes/javax/crypto/spec/OAEPParameterSpec.java
index efc8f370877..ba46399f044 100644
--- a/src/java.base/share/classes/javax/crypto/spec/OAEPParameterSpec.java
+++ b/src/java.base/share/classes/javax/crypto/spec/OAEPParameterSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, 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
@@ -72,6 +72,8 @@
* EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
*
*
+ * @spec https://www.rfc-editor.org/info/rfc8017
+ * RFC 8017: PKCS #1: RSA Cryptography Specifications Version 2.2
* @see java.security.spec.MGF1ParameterSpec
* @see PSource
*
diff --git a/src/java.base/share/classes/javax/crypto/spec/PBEKeySpec.java b/src/java.base/share/classes/javax/crypto/spec/PBEKeySpec.java
index b21b610e780..e47deab6fbe 100644
--- a/src/java.base/share/classes/javax/crypto/spec/PBEKeySpec.java
+++ b/src/java.base/share/classes/javax/crypto/spec/PBEKeySpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -54,6 +54,8 @@
* this class requests the password as a char array, so it can be overwritten
* when done.
*
+ * @spec https://www.rfc-editor.org/info/rfc2898
+ * RFC 2898: PKCS #5: Password-Based Cryptography Specification Version 2.0
* @author Jan Luehe
* @author Valerie Peng
*
diff --git a/src/java.base/share/classes/javax/crypto/spec/PBEParameterSpec.java b/src/java.base/share/classes/javax/crypto/spec/PBEParameterSpec.java
index 84d175dfd9f..a44822bafec 100644
--- a/src/java.base/share/classes/javax/crypto/spec/PBEParameterSpec.java
+++ b/src/java.base/share/classes/javax/crypto/spec/PBEParameterSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,8 @@
* PKCS #5
* standard.
*
+ * @spec https://www.rfc-editor.org/info/rfc2898
+ * RFC 2898: PKCS #5: Password-Based Cryptography Specification Version 2.0
* @author Jan Luehe
*
* @since 1.4
diff --git a/src/java.base/share/classes/javax/crypto/spec/PSource.java b/src/java.base/share/classes/javax/crypto/spec/PSource.java
index 1cd57c6f03b..19546a630de 100644
--- a/src/java.base/share/classes/javax/crypto/spec/PSource.java
+++ b/src/java.base/share/classes/javax/crypto/spec/PSource.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, 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
@@ -42,6 +42,9 @@
* }
* EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
*
+ *
+ * @spec https://www.rfc-editor.org/info/rfc8017
+ * RFC 8017: PKCS #1: RSA Cryptography Specifications Version 2.2
* @author Valerie Peng
*
* @since 1.5
diff --git a/src/java.base/share/classes/javax/crypto/spec/RC2ParameterSpec.java b/src/java.base/share/classes/javax/crypto/spec/RC2ParameterSpec.java
index 6c32ee119c5..3c2e5a57da6 100644
--- a/src/java.base/share/classes/javax/crypto/spec/RC2ParameterSpec.java
+++ b/src/java.base/share/classes/javax/crypto/spec/RC2ParameterSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, 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
@@ -39,6 +39,8 @@
*
This class can be used to initialize a {@code Cipher} object that
* implements the RC2 algorithm.
*
+ * @spec https://www.rfc-editor.org/info/rfc2268
+ * RFC 2268: A Description of the RC2(r) Encryption Algorithm
* @author Jan Luehe
*
* @since 1.4
diff --git a/src/java.base/share/classes/javax/crypto/spec/RC5ParameterSpec.java b/src/java.base/share/classes/javax/crypto/spec/RC5ParameterSpec.java
index 67daf8bb19a..86d128afbf8 100644
--- a/src/java.base/share/classes/javax/crypto/spec/RC5ParameterSpec.java
+++ b/src/java.base/share/classes/javax/crypto/spec/RC5ParameterSpec.java
@@ -39,6 +39,8 @@
*
This class can be used to initialize a {@code Cipher} object that
* implements the RC5 algorithm.
*
+ * @spec https://www.rfc-editor.org/info/rfc2040
+ * RFC 2040: The RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS Algorithms
* @author Jan Luehe
*
* @since 1.4
diff --git a/src/java.base/share/classes/javax/crypto/spec/SecretKeySpec.java b/src/java.base/share/classes/javax/crypto/spec/SecretKeySpec.java
index 2ad9a7748f2..d36510a21a8 100644
--- a/src/java.base/share/classes/javax/crypto/spec/SecretKeySpec.java
+++ b/src/java.base/share/classes/javax/crypto/spec/SecretKeySpec.java
@@ -98,6 +98,8 @@ public class SecretKeySpec implements KeySpec, SecretKey {
* for information about standard algorithm names.
* @exception IllegalArgumentException if algorithm
* is null or key is null or empty.
+ *
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
*/
public SecretKeySpec(byte[] key, String algorithm) {
String errMsg = doSanityCheck(key, algorithm);
@@ -144,6 +146,8 @@ public SecretKeySpec(byte[] key, String algorithm) {
* @exception ArrayIndexOutOfBoundsException is thrown if
* offset or len index bytes outside the
* key.
+ *
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
*/
public SecretKeySpec(byte[] key, int offset, int len, String algorithm) {
if (key == null || algorithm == null) {
diff --git a/src/java.base/share/classes/javax/net/ssl/ExtendedSSLSession.java b/src/java.base/share/classes/javax/net/ssl/ExtendedSSLSession.java
index c1ddf221ab5..2b98f4845cf 100644
--- a/src/java.base/share/classes/javax/net/ssl/ExtendedSSLSession.java
+++ b/src/java.base/share/classes/javax/net/ssl/ExtendedSSLSession.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2024, 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
@@ -63,6 +63,7 @@ public ExtendedSSLSession() {}
* order of preference. The return value is an empty array if
* no signature algorithm is supported.
*
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
* @see SSLParameters#getAlgorithmConstraints
*/
public abstract String[] getLocalSupportedSignatureAlgorithms();
@@ -86,6 +87,7 @@ public ExtendedSSLSession() {}
* order of preference. The return value is an empty array if
* the peer has not sent the supported signature algorithms.
*
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
* @see X509KeyManager
* @see X509ExtendedKeyManager
*/
diff --git a/src/java.base/share/classes/javax/net/ssl/SNIHostName.java b/src/java.base/share/classes/javax/net/ssl/SNIHostName.java
index 5abb9df1200..039ee41aab0 100644
--- a/src/java.base/share/classes/javax/net/ssl/SNIHostName.java
+++ b/src/java.base/share/classes/javax/net/ssl/SNIHostName.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, 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
@@ -53,6 +53,11 @@
*
* Note that {@code SNIHostName} objects are immutable.
*
+ * @spec https://www.rfc-editor.org/info/rfc5890
+ * RFC 5890: Internationalized Domain Names for Applications (IDNA):
+ * Definitions and Document Framework
+ * @spec https://www.rfc-editor.org/info/rfc6066
+ * RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions
* @see SNIServerName
* @see StandardConstants#SNI_HOST_NAME
*
@@ -92,6 +97,15 @@ public final class SNIHostName extends SNIServerName {
*
* @throws NullPointerException if {@code hostname} is {@code null}
* @throws IllegalArgumentException if {@code hostname} is illegal
+ *
+ * @spec https://www.rfc-editor.org/info/rfc1122
+ * RFC 1122: Requirements for Internet Hosts - Communication Layers
+ * @spec https://www.rfc-editor.org/info/rfc1123
+ * RFC 1123: Requirements for Internet Hosts - Application and Support
+ * @spec https://www.rfc-editor.org/info/rfc3490
+ * RFC 3490: Internationalizing Domain Names in Applications (IDNA)
+ * @spec https://www.rfc-editor.org/info/rfc6066
+ * RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions
*/
public SNIHostName(String hostname) {
// IllegalArgumentException will be thrown if {@code hostname} is
@@ -159,6 +173,17 @@ public SNIHostName(String hostname) {
*
* @throws NullPointerException if {@code encoded} is {@code null}
* @throws IllegalArgumentException if {@code encoded} is illegal
+ *
+ * @spec https://www.rfc-editor.org/info/rfc1122
+ * RFC 1122: Requirements for Internet Hosts - Communication Layers
+ * @spec https://www.rfc-editor.org/info/rfc1123
+ * RFC 1123: Requirements for Internet Hosts - Application and Support
+ * @spec https://www.rfc-editor.org/info/rfc3490
+ * RFC 3490: Internationalizing Domain Names in Applications (IDNA)
+ * @spec https://www.rfc-editor.org/info/rfc4366
+ * RFC 4366: Transport Layer Security (TLS) Extensions
+ * @spec https://www.rfc-editor.org/info/rfc6066
+ * RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions
*/
public SNIHostName(byte[] encoded) {
// NullPointerException will be thrown if {@code encoded} is null
@@ -198,6 +223,11 @@ public SNIHostName(byte[] encoded) {
*
* @return the {@link StandardCharsets#US_ASCII}-compliant hostname
* of this {@code SNIHostName} object
+ *
+ * @spec https://www.rfc-editor.org/info/rfc5890
+ * RFC 5890: Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework
+ * @spec https://www.rfc-editor.org/info/rfc6066
+ * RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions
*/
public String getAsciiName() {
return hostname;
@@ -215,6 +245,9 @@ public String getAsciiName() {
* the other server name object to compare with.
* @return true if, and only if, the {@code other} is considered
* equal to this instance
+ *
+ * @spec https://www.rfc-editor.org/info/rfc6066
+ * RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions
*/
@Override
public boolean equals(Object other) {
diff --git a/src/java.base/share/classes/javax/net/ssl/SNIServerName.java b/src/java.base/share/classes/javax/net/ssl/SNIServerName.java
index 142bb33de8e..85eab316664 100644
--- a/src/java.base/share/classes/javax/net/ssl/SNIServerName.java
+++ b/src/java.base/share/classes/javax/net/ssl/SNIServerName.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, 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
@@ -41,6 +41,8 @@
* {@code SNIServerName} objects are immutable. Subclasses should not provide
* methods that can change the state of an instance once it has been created.
*
+ * @spec https://www.rfc-editor.org/info/rfc6066
+ * RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions
* @see SSLParameters#getServerNames()
* @see SSLParameters#setServerNames(List)
*
diff --git a/src/java.base/share/classes/javax/net/ssl/SSLEngine.java b/src/java.base/share/classes/javax/net/ssl/SSLEngine.java
index 9a74c69f9f5..27f3c31e0e9 100644
--- a/src/java.base/share/classes/javax/net/ssl/SSLEngine.java
+++ b/src/java.base/share/classes/javax/net/ssl/SSLEngine.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, 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
@@ -413,6 +413,8 @@
* because there is no way to guarantee the eventual packet ordering.
*
*
+ * @spec https://www.rfc-editor.org/info/rfc2246
+ * RFC 2246: The TLS Protocol Version 1.0
* @see SSLContext
* @see SSLSocket
* @see SSLServerSocket
@@ -859,6 +861,8 @@ public abstract SSLEngineResult unwrap(ByteBuffer src,
* if this engine has not received the proper SSL/TLS/DTLS close
* notification message from the peer.
*
+ * @spec https://www.rfc-editor.org/info/rfc2246
+ * RFC 2246: The TLS Protocol Version 1.0
* @see #isInboundDone()
* @see #isOutboundDone()
*/
@@ -1351,6 +1355,8 @@ public void setSSLParameters(SSLParameters params) {
* Application-Layer Protocol Negotiation (ALPN), can negotiate
* application-level values between peers.
*
+ * @spec https://www.rfc-editor.org/info/rfc7301
+ * RFC 7301: Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension
* @implSpec
* The implementation in this class throws
* {@code UnsupportedOperationException} and performs no other action.
diff --git a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java
index eabf0a13f67..e1f43994064 100644
--- a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java
+++ b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, 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
@@ -300,6 +300,7 @@ public String getEndpointIdentificationAlgorithm() {
* Java Security Standard Algorithm Names document
* for information about standard algorithm names.
*
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
* @see X509ExtendedTrustManager
*
* @since 1.7
@@ -674,6 +675,9 @@ public String[] getApplicationProtocols() {
* @throws IllegalArgumentException if protocols is null, or if
* any element in a non-empty array is null or an
* empty (zero-length) string
+ *
+ * @spec https://www.rfc-editor.org/info/rfc7301
+ * RFC 7301: Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension
* @see #getApplicationProtocols
* @since 9
*/
diff --git a/src/java.base/share/classes/javax/net/ssl/SSLSocket.java b/src/java.base/share/classes/javax/net/ssl/SSLSocket.java
index d0c3c9ac2dd..25d572a5616 100644
--- a/src/java.base/share/classes/javax/net/ssl/SSLSocket.java
+++ b/src/java.base/share/classes/javax/net/ssl/SSLSocket.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -770,6 +770,9 @@ public void setSSLParameters(SSLParameters params) {
* if a value was successfully negotiated.
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
+ *
+ * @spec https://www.rfc-editor.org/info/rfc7301
+ * RFC 7301: Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension
* @since 9
*/
public String getApplicationProtocol() {
diff --git a/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java b/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java
index bd7c3d0157a..cb5e3318052 100644
--- a/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java
+++ b/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -198,6 +198,8 @@ public abstract Socket createSocket(Socket s, String host,
* does not implement the operation
* @throws NullPointerException if {@code s} is {@code null}
*
+ * @spec https://www.rfc-editor.org/info/rfc6066
+ * RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions
* @since 1.8
*/
public Socket createSocket(Socket s, InputStream consumed,
diff --git a/src/java.base/share/classes/javax/net/ssl/StandardConstants.java b/src/java.base/share/classes/javax/net/ssl/StandardConstants.java
index 8e1df977b97..ca560390cb1 100644
--- a/src/java.base/share/classes/javax/net/ssl/StandardConstants.java
+++ b/src/java.base/share/classes/javax/net/ssl/StandardConstants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, 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
@@ -49,6 +49,8 @@ private StandardConstants() {
*
* The value of this constant is {@value}.
*
+ * @spec https://www.rfc-editor.org/info/rfc6066
+ * RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions
* @see SNIServerName
* @see SNIHostName
*/
diff --git a/src/java.base/share/classes/javax/net/ssl/package-info.java b/src/java.base/share/classes/javax/net/ssl/package-info.java
index f41b3b7f19a..cdf3b2246f6 100644
--- a/src/java.base/share/classes/javax/net/ssl/package-info.java
+++ b/src/java.base/share/classes/javax/net/ssl/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2024, 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
@@ -36,6 +36,7 @@
*
*
*
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
* @since 1.4
*/
package javax.net.ssl;
diff --git a/src/java.base/share/classes/javax/security/auth/login/package-info.java b/src/java.base/share/classes/javax/security/auth/login/package-info.java
index 70d25f1acaa..658f219f20b 100644
--- a/src/java.base/share/classes/javax/security/auth/login/package-info.java
+++ b/src/java.base/share/classes/javax/security/auth/login/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
*
*
*
+ * @spec security/standard-names.html Java Security Standard Algorithm Names
* @since 1.4
*/
package javax.security.auth.login;
diff --git a/src/java.base/share/classes/javax/security/auth/x500/X500Principal.java b/src/java.base/share/classes/javax/security/auth/x500/X500Principal.java
index efc5b7891b8..93e34ad65ef 100644
--- a/src/java.base/share/classes/javax/security/auth/x500/X500Principal.java
+++ b/src/java.base/share/classes/javax/security/auth/x500/X500Principal.java
@@ -60,6 +60,14 @@
* {@code X509Certificate} return X500Principals representing the
* issuer and subject fields of the certificate.
*
+ * @spec https://www.rfc-editor.org/info/rfc1779
+ * RFC 1779: A String Representation of Distinguished Names
+ * @spec https://www.rfc-editor.org/info/rfc2253
+ * RFC 2253: Lightweight Directory Access Protocol (v3):
+ * UTF-8 String Representation of Distinguished Names
+ * @spec https://www.rfc-editor.org/info/rfc5280
+ * RFC 5280: Internet X.509 Public Key Infrastructure Certificate
+ * and Certificate Revocation List (CRL) Profile
* @see java.security.cert.X509Certificate
* @since 1.4
*/
@@ -141,6 +149,10 @@ public X500Principal asX500Principal(X500Name name) {
* is {@code null}
* @exception IllegalArgumentException if the {@code name}
* is improperly specified
+ *
+ * @spec https://www.rfc-editor.org/info/rfc4512
+ * RFC 4512: Lightweight Directory Access Protocol (LDAP):
+ * Directory Information Models
*/
public X500Principal(String name) {
this(name, Collections.emptyMap());
@@ -181,6 +193,10 @@ public X500Principal(String name) {
* @exception IllegalArgumentException if the {@code name} is
* improperly specified or a keyword in the {@code name} maps to an
* OID that is not in the correct form
+ *
+ * @spec https://www.rfc-editor.org/info/rfc4512
+ * RFC 4512: Lightweight Directory Access Protocol (LDAP):
+ * Directory Information Models
* @since 1.6
*/
public X500Principal(String name, Map keywordMap) {
diff --git a/src/java.base/share/classes/javax/security/auth/x500/package-info.java b/src/java.base/share/classes/javax/security/auth/x500/package-info.java
index 45859a79bed..b2afa89d251 100644
--- a/src/java.base/share/classes/javax/security/auth/x500/package-info.java
+++ b/src/java.base/share/classes/javax/security/auth/x500/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2024, 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,6 +44,17 @@
* Directory Information Models
*
*
+ * @spec https://www.rfc-editor.org/info/rfc1779
+ * RFC 1779: A String Representation of Distinguished Names
+ * @spec https://www.rfc-editor.org/info/rfc2253
+ * RFC 2253: Lightweight Directory Access Protocol (v3):
+ * UTF-8 String Representation of Distinguished Names
+ * @spec https://www.rfc-editor.org/info/rfc4512
+ * RFC 4512: Lightweight Directory Access Protocol (LDAP):
+ * Directory Information Models
+ * @spec https://www.rfc-editor.org/info/rfc5280
+ * RFC 5280: Internet X.509 Public Key Infrastructure Certificate
+ * and Certificate Revocation List (CRL) Profile
* @since 1.4
*/
package javax.security.auth.x500;
From 6648524bd718f90ed43bcd70d856d88240e3805f Mon Sep 17 00:00:00 2001
From: Alexey Semenyuk
Date: Sat, 26 Oct 2024 14:01:19 +0000
Subject: [PATCH 002/159] 8343102: Remove `--compress` from jlink command lines
from jpackage tests
Reviewed-by: almatvee
---
test/jdk/tools/jpackage/share/RuntimeImageTest.java | 9 ++-------
test/jdk/tools/jpackage/share/RuntimePackageTest.java | 3 +--
2 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/test/jdk/tools/jpackage/share/RuntimeImageTest.java b/test/jdk/tools/jpackage/share/RuntimeImageTest.java
index 44088778589..64908b6ac99 100644
--- a/test/jdk/tools/jpackage/share/RuntimeImageTest.java
+++ b/test/jdk/tools/jpackage/share/RuntimeImageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, 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,6 @@
import java.nio.file.Path;
import jdk.jpackage.test.TKit;
import jdk.jpackage.test.Annotations.Test;
-import jdk.jpackage.test.Annotations.Parameter;
import jdk.jpackage.test.JPackageCommand;
import jdk.jpackage.test.JavaTool;
import jdk.jpackage.test.Executor;
@@ -45,10 +44,7 @@
public class RuntimeImageTest {
@Test
- @Parameter("0")
- @Parameter("1")
- @Parameter("2")
- public static void test(String compression) throws Exception {
+ public static void test() throws Exception {
final Path workDir = TKit.createTempDirectory("runtime").resolve("data");
final Path jlinkOutputDir = workDir.resolve("temp.runtime");
Files.createDirectories(jlinkOutputDir.getParent());
@@ -58,7 +54,6 @@ public static void test(String compression) throws Exception {
.dumpOutput()
.addArguments(
"--output", jlinkOutputDir.toString(),
- "--compress=" + compression,
"--add-modules", "ALL-MODULE-PATH",
"--strip-debug",
"--no-header-files",
diff --git a/test/jdk/tools/jpackage/share/RuntimePackageTest.java b/test/jdk/tools/jpackage/share/RuntimePackageTest.java
index 12edff1cea5..da58ed3a73c 100644
--- a/test/jdk/tools/jpackage/share/RuntimePackageTest.java
+++ b/test/jdk/tools/jpackage/share/RuntimePackageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, 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
@@ -113,7 +113,6 @@ private static PackageTest init(Set types) {
.dumpOutput()
.addArguments(
"--output", runtimeImageDir.toString(),
- "--compress=0",
"--add-modules", "ALL-MODULE-PATH",
"--strip-debug",
"--no-header-files",
From 0995dd6a3f4eefa02280e10754ceeffc3eb85c69 Mon Sep 17 00:00:00 2001
From: Chen Liang
Date: Sat, 26 Oct 2024 14:45:04 +0000
Subject: [PATCH 003/159] 8342865: Use type parameter for
Class::getPrimitiveClass
Reviewed-by: darcy
---
src/java.base/share/classes/java/lang/Boolean.java | 3 +--
src/java.base/share/classes/java/lang/Byte.java | 3 +--
src/java.base/share/classes/java/lang/Character.java | 3 +--
src/java.base/share/classes/java/lang/Class.java | 6 +++---
src/java.base/share/classes/java/lang/Double.java | 3 +--
src/java.base/share/classes/java/lang/Float.java | 3 +--
src/java.base/share/classes/java/lang/Integer.java | 3 +--
src/java.base/share/classes/java/lang/Long.java | 3 +--
src/java.base/share/classes/java/lang/Short.java | 3 +--
src/java.base/share/classes/java/lang/Void.java | 5 ++---
10 files changed, 13 insertions(+), 22 deletions(-)
diff --git a/src/java.base/share/classes/java/lang/Boolean.java b/src/java.base/share/classes/java/lang/Boolean.java
index 38b830fc0cf..31507f60e37 100644
--- a/src/java.base/share/classes/java/lang/Boolean.java
+++ b/src/java.base/share/classes/java/lang/Boolean.java
@@ -78,8 +78,7 @@ public final class Boolean implements java.io.Serializable,
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class TYPE = (Class) Class.getPrimitiveClass("boolean");
+ public static final Class TYPE = Class.getPrimitiveClass("boolean");
/**
* The value of the Boolean.
diff --git a/src/java.base/share/classes/java/lang/Byte.java b/src/java.base/share/classes/java/lang/Byte.java
index 35a537a0903..c78e11ae067 100644
--- a/src/java.base/share/classes/java/lang/Byte.java
+++ b/src/java.base/share/classes/java/lang/Byte.java
@@ -79,8 +79,7 @@ public final class Byte extends Number implements Comparable, Constable {
* The {@code Class} instance representing the primitive type
* {@code byte}.
*/
- @SuppressWarnings("unchecked")
- public static final Class TYPE = (Class) Class.getPrimitiveClass("byte");
+ public static final Class TYPE = Class.getPrimitiveClass("byte");
/**
* Returns a new {@code String} object representing the
diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java
index 5844805c858..101eabcbcc0 100644
--- a/src/java.base/share/classes/java/lang/Character.java
+++ b/src/java.base/share/classes/java/lang/Character.java
@@ -232,8 +232,7 @@ class Character implements java.io.Serializable, Comparable, Constabl
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class TYPE = (Class) Class.getPrimitiveClass("char");
+ public static final Class TYPE = Class.getPrimitiveClass("char");
/*
* Normative general types
diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java
index 79cd57011b0..93a675c83a4 100644
--- a/src/java.base/share/classes/java/lang/Class.java
+++ b/src/java.base/share/classes/java/lang/Class.java
@@ -3278,10 +3278,10 @@ ProtectionDomain protectionDomain() {
private native ProtectionDomain getProtectionDomain0();
/*
- * Return the Virtual Machine's Class object for the named
- * primitive type.
+ * Returns the Class object for the named primitive type. Type parameter T
+ * avoids redundant casts for trusted code.
*/
- static native Class> getPrimitiveClass(String name);
+ static native Class getPrimitiveClass(String name);
/*
* Check if client is allowed to access members. If access is denied,
diff --git a/src/java.base/share/classes/java/lang/Double.java b/src/java.base/share/classes/java/lang/Double.java
index 7216e20d6c3..ed23f7d39c9 100644
--- a/src/java.base/share/classes/java/lang/Double.java
+++ b/src/java.base/share/classes/java/lang/Double.java
@@ -459,8 +459,7 @@ public final class Double extends Number
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class TYPE = (Class) Class.getPrimitiveClass("double");
+ public static final Class TYPE = Class.getPrimitiveClass("double");
/**
* Returns a string representation of the {@code double}
diff --git a/src/java.base/share/classes/java/lang/Float.java b/src/java.base/share/classes/java/lang/Float.java
index af076e9417b..821a05fa00a 100644
--- a/src/java.base/share/classes/java/lang/Float.java
+++ b/src/java.base/share/classes/java/lang/Float.java
@@ -175,8 +175,7 @@ public final class Float extends Number
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class TYPE = (Class) Class.getPrimitiveClass("float");
+ public static final Class TYPE = Class.getPrimitiveClass("float");
/**
* Returns a string representation of the {@code float}
diff --git a/src/java.base/share/classes/java/lang/Integer.java b/src/java.base/share/classes/java/lang/Integer.java
index 5f64c1b8660..84fa5303ac7 100644
--- a/src/java.base/share/classes/java/lang/Integer.java
+++ b/src/java.base/share/classes/java/lang/Integer.java
@@ -95,8 +95,7 @@ public final class Integer extends Number
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class TYPE = (Class) Class.getPrimitiveClass("int");
+ public static final Class TYPE = Class.getPrimitiveClass("int");
/**
* All possible chars for representing a number as a String
diff --git a/src/java.base/share/classes/java/lang/Long.java b/src/java.base/share/classes/java/lang/Long.java
index 5f4c2b15d03..78a2402ba0e 100644
--- a/src/java.base/share/classes/java/lang/Long.java
+++ b/src/java.base/share/classes/java/lang/Long.java
@@ -95,8 +95,7 @@ public final class Long extends Number
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class TYPE = (Class) Class.getPrimitiveClass("long");
+ public static final Class TYPE = Class.getPrimitiveClass("long");
/**
* Returns a string representation of the first argument in the
diff --git a/src/java.base/share/classes/java/lang/Short.java b/src/java.base/share/classes/java/lang/Short.java
index 914d9cc67db..a2d31ee07c3 100644
--- a/src/java.base/share/classes/java/lang/Short.java
+++ b/src/java.base/share/classes/java/lang/Short.java
@@ -79,8 +79,7 @@ public final class Short extends Number implements Comparable, Constable
* The {@code Class} instance representing the primitive type
* {@code short}.
*/
- @SuppressWarnings("unchecked")
- public static final Class TYPE = (Class) Class.getPrimitiveClass("short");
+ public static final Class TYPE = Class.getPrimitiveClass("short");
/**
* Returns a new {@code String} object representing the
diff --git a/src/java.base/share/classes/java/lang/Void.java b/src/java.base/share/classes/java/lang/Void.java
index 3ea0e79e61c..9a3adafec33 100644
--- a/src/java.base/share/classes/java/lang/Void.java
+++ b/src/java.base/share/classes/java/lang/Void.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2024, 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
@@ -39,8 +39,7 @@ class Void {
* The {@code Class} object representing the pseudo-type corresponding to
* the keyword {@code void}.
*/
- @SuppressWarnings("unchecked")
- public static final Class TYPE = (Class) Class.getPrimitiveClass("void");
+ public static final Class TYPE = Class.getPrimitiveClass("void");
/*
* The Void class cannot be instantiated.
From 719aa58ba626ae51afe508d4994c1b25c030a8a3 Mon Sep 17 00:00:00 2001
From: Chen Liang
Date: Sat, 26 Oct 2024 14:45:19 +0000
Subject: [PATCH 004/159] 8335880: More troubleshooting tips around windows
space in path
Reviewed-by: erikj, ihse
---
doc/building.html | 16 ++++++++++++----
doc/building.md | 14 +++++++++++---
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/doc/building.html b/doc/building.html
index c91d876246c..63af224584a 100644
--- a/doc/building.html
+++ b/doc/building.html
@@ -2016,10 +2016,18 @@
Spaces in Path
have short
paths. You can run fsutil file setshortname in
-cmd on certain directories, such as
-Microsoft Visual Studio or Windows Kits, to
-assign arbitrary short paths so configure can access
-them.
+cmd on directories to assign arbitrary short paths so
+configure can access them. If the result says "Access
+denied", it may be that there are processes running in that directory;
+in this case, you can reboot Windows in safe mode and run the command on
+those directories again.
+
The only directories required to have short paths are
+Microsoft Visual Studio and Windows Kits; the
+rest of the "contains space" warnings from configure, such
+as IntelliJ IDEA, can be ignored. You can choose any short
+name; once it is set, configure's tools like
+cygpath can convert the directory with spaces to your
+chosen short name and pass it to the build system.
Getting Help
If none of the suggestions in this document helps you, or if you find
what you believe is a bug in the build system, please contact the Build
diff --git a/doc/building.md b/doc/building.md
index 47ad9e7c72b..466e8d7edf8 100644
--- a/doc/building.md
+++ b/doc/building.md
@@ -1800,9 +1800,17 @@ temporarily.
On Windows, when configuring, `fixpath.sh` may report that some directory names
have spaces. Usually, it assumes those directories have [short
paths](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-8dot3name).
-You can run `fsutil file setshortname` in `cmd` on certain directories, such as
-`Microsoft Visual Studio` or `Windows Kits`, to assign arbitrary short paths so
-`configure` can access them.
+You can run `fsutil file setshortname` in `cmd` on directories to assign
+arbitrary short paths so `configure` can access them. If the result says "Access
+denied", it may be that there are processes running in that directory; in this
+case, you can reboot Windows in safe mode and run the command on those directories
+again.
+
+The only directories required to have short paths are `Microsoft Visual Studio`
+and `Windows Kits`; the rest of the "contains space" warnings from `configure`,
+such as `IntelliJ IDEA`, can be ignored. You can choose any short name; once it
+is set, `configure`'s tools like `cygpath` can convert the directory with spaces
+to your chosen short name and pass it to the build system.
### Getting Help
From c5ce2174381932f316371237f0d27070a3f00d15 Mon Sep 17 00:00:00 2001
From: Andrey Turbanov
Date: Sat, 26 Oct 2024 17:59:15 +0000
Subject: [PATCH 005/159] 8342083: Make a few fields in FileSystemPreferences
final
Reviewed-by: jpai, bpb
---
.../classes/java/util/prefs/FileSystemPreferences.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java b/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java
index 5f0531c0ff7..756eedade72 100644
--- a/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java
+++ b/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java
@@ -450,7 +450,7 @@ private void replayChanges() {
changeLog.get(i).replay();
}
- private static Timer syncTimer = new Timer(true); // Daemon Thread
+ private static final Timer syncTimer = new Timer(true); // Daemon Thread
static {
addShutdownHook();
@@ -540,7 +540,7 @@ public Void run() {
}
});
if (newNode) {
- // These 2 things guarantee node will get wrtten at next flush/sync
+ // These 2 things guarantee node will get written at next flush/sync
prefsCache = new TreeMap<>();
nodeCreate = new NodeCreate();
changeLog.add(nodeCreate);
@@ -1008,12 +1008,12 @@ private void checkLockFile0ErrorCode (int errorCode)
* Initial time between lock attempts, in ms. The time is doubled
* after each failing attempt (except the first).
*/
- private static int INIT_SLEEP_TIME = 50;
+ private static final int INIT_SLEEP_TIME = 50;
/**
* Maximum number of lock attempts.
*/
- private static int MAX_ATTEMPTS = 5;
+ private static final int MAX_ATTEMPTS = 5;
/**
* Release the appropriate file lock (user or system).
From fedcdcfdba1cda41d775c696970bccd125cb2ed3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonathan=20Lamp=C3=A9rth?=
Date: Mon, 28 Oct 2024 09:42:03 +0000
Subject: [PATCH 006/159] 8034066: Incorrect alignment in the "Code" section
for "-c -XDdetails" options
Reviewed-by: jvernee, liach
---
.../com/sun/tools/javap/ClassWriter.java | 4 +-
.../com/sun/tools/javap/CodeWriter.java | 26 ++--
.../javap/ClassWriterCodeIndentTest.java | 113 ++++++++++++++++++
3 files changed, 133 insertions(+), 10 deletions(-)
create mode 100644 test/langtools/tools/javap/ClassWriterCodeIndentTest.java
diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java
index 77fbce8839e..92a0c06c1c3 100644
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java
@@ -576,9 +576,7 @@ protected void writeMethod(MethodModel m) {
attrWriter.write(m.attributes());
} else if (code != null) {
if (options.showDisassembled) {
- println("Code:");
- codeWriter.writeInstrs(code);
- codeWriter.writeExceptionTable(code);
+ codeWriter.writeMinimal(code);
}
if (options.showLineAndLocalVariableTables) {
diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java
index 8f6b9b1d2ed..cb401c9f197 100644
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java
@@ -70,13 +70,11 @@ protected CodeWriter(Context context) {
}
void write(CodeAttribute attr) {
- println("Code:");
- indent(+1);
- writeVerboseHeader(attr);
- writeInstrs(attr);
- writeExceptionTable(attr);
- attrWriter.write(attr.attributes(), attr);
- indent(-1);
+ writeInternal(attr, false);
+ }
+
+ void writeMinimal(CodeAttribute attr) {
+ writeInternal(attr, true);
}
public void writeVerboseHeader(CodeAttribute attr) {
@@ -259,6 +257,20 @@ private List getDetailWriters(CodeAttribute attr) {
return detailWriters;
}
+ private void writeInternal(CodeAttribute attr, boolean minimal) {
+ println("Code:");
+ indent(+1);
+ if (!minimal) {
+ writeVerboseHeader(attr);
+ }
+ writeInstrs(attr);
+ writeExceptionTable(attr);
+ if (!minimal) {
+ attrWriter.write(attr.attributes(), attr);
+ }
+ indent(-1);
+ }
+
private AttributeWriter attrWriter;
private ClassWriter classWriter;
private ConstantWriter constantWriter;
diff --git a/test/langtools/tools/javap/ClassWriterCodeIndentTest.java b/test/langtools/tools/javap/ClassWriterCodeIndentTest.java
new file mode 100644
index 00000000000..993c0a4364a
--- /dev/null
+++ b/test/langtools/tools/javap/ClassWriterCodeIndentTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2024, 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 8034066
+ * @summary javap incorrect indentation when CodeWriter called via ClassWriter
+ * @run main ClassWriterCodeIndentTest
+ * @modules jdk.jdeps/com.sun.tools.javap
+ */
+
+import java.io.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ClassWriterCodeIndentTest {
+ public static void main(String[] args) {
+ new ClassWriterCodeIndentTest().run();
+ }
+
+ public void run() {
+ /*
+ * Partial expected output within a larger file. There exists another "Code: " section above, and thus we
+ * select the second occurrence in `findNthMatchPrecedingSpaces(output, "Code:", 1);`
+ * ...
+ * Code:
+ * 0: iconst_0
+ * 1: istore_1
+ * StackMap locals: this int
+ * StackMap stack:
+ * ...
+ */
+ String output = javap();
+
+ int codeHeaderIndent = findNthMatchPrecedingSpaces(output, "Code:", 1);
+ int detailIndent = findNthMatchPrecedingSpaces(output, "StackMap ", 0);
+ int bytecodeIndent = findNthMatchPrecedingSpaces(output, "0: iconst_0", 0);
+
+ if (detailIndent - codeHeaderIndent != 2) {
+ error("Details are not indented correctly with respect to code header.");
+ }
+
+ if (bytecodeIndent - codeHeaderIndent != 5) {
+ error("Bytecode is not indented correctly with respect to code header.");
+ }
+
+ if (errors > 0) {
+ throw new Error(errors + " found.");
+ }
+ }
+
+ String javap() {
+ StringWriter sw = new StringWriter();
+ PrintWriter out = new PrintWriter(sw);
+ int rc = com.sun.tools.javap.Main.run(new String[]{"-c", "-XDdetails:stackMaps",
+ System.getProperty("test.classes") + "/EmptyLoop.class"}, out);
+ if (rc != 0)
+ throw new Error("javap failed. rc=" + rc);
+ out.close();
+ System.out.println(sw.toString());
+ return sw.toString();
+ }
+
+ public static int findNthMatchPrecedingSpaces(String inputString, String searchString, int occurrence) {
+ String regex = "^(\\s*)" + Pattern.quote(searchString);
+ Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
+ Matcher matcher = pattern.matcher(inputString);
+
+ int count = 0;
+ while (matcher.find()) {
+ if (count == occurrence) {
+ return matcher.group(1).length();
+ }
+ count++;
+ }
+
+ throw new Error("Could not find " + searchString + " in " + inputString);
+ }
+
+ void error(String msg) {
+ System.err.println(msg);
+ errors++;
+ }
+
+ int errors;
+}
+
+class EmptyLoop {
+ public void emptyLoop() {
+ for (int i = 0; i < 10; i++) {
+ }
+ }
+}
\ No newline at end of file
From 724c495cb09b4f3a806b1a1e0c1fd1a2a2f2e4ef Mon Sep 17 00:00:00 2001
From: Coleen Phillimore
Date: Mon, 28 Oct 2024 13:48:23 +0000
Subject: [PATCH 007/159] 8342561: Metaspace for generated reflection classes
is no longer needed
Reviewed-by: shade, stuefe
---
.../metaspace/test_arenagrowthpolicy.cpp | 4 +--
.../gtest/metaspace/test_metaspacearena.cpp | 35 +++++--------------
.../metaspace/test_metaspacearena_stress.cpp | 2 +-
3 files changed, 11 insertions(+), 30 deletions(-)
diff --git a/test/hotspot/gtest/metaspace/test_arenagrowthpolicy.cpp b/test/hotspot/gtest/metaspace/test_arenagrowthpolicy.cpp
index a37af058e09..80e6c1d77da 100644
--- a/test/hotspot/gtest/metaspace/test_arenagrowthpolicy.cpp
+++ b/test/hotspot/gtest/metaspace/test_arenagrowthpolicy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -61,8 +61,6 @@ TEST_VM(metaspace, arena_growth_policy_##spacetype##_##is_class) { \
test_arena_growth_policy(Metaspace::spacetype, is_class); \
}
-DEFINE_GROWTH_POLICY_TEST(ReflectionMetaspaceType, true)
-DEFINE_GROWTH_POLICY_TEST(ReflectionMetaspaceType, false)
DEFINE_GROWTH_POLICY_TEST(ClassMirrorHolderMetaspaceType, true)
DEFINE_GROWTH_POLICY_TEST(ClassMirrorHolderMetaspaceType, false)
DEFINE_GROWTH_POLICY_TEST(StandardMetaspaceType, true)
diff --git a/test/hotspot/gtest/metaspace/test_metaspacearena.cpp b/test/hotspot/gtest/metaspace/test_metaspacearena.cpp
index aee53ea32aa..2e5a6d40ce7 100644
--- a/test/hotspot/gtest/metaspace/test_metaspacearena.cpp
+++ b/test/hotspot/gtest/metaspace/test_metaspacearena.cpp
@@ -218,7 +218,8 @@ class MetaspaceArenaTestHelper {
static void test_basics(size_t commit_limit, bool is_micro) {
MetaspaceGtestContext context(commit_limit);
- MetaspaceArenaTestHelper helper(context, is_micro ? Metaspace::ReflectionMetaspaceType : Metaspace::StandardMetaspaceType, false);
+ const Metaspace::MetaspaceType type = is_micro ? Metaspace::ClassMirrorHolderMetaspaceType : Metaspace::StandardMetaspaceType;
+ MetaspaceArenaTestHelper helper(context, type, false);
helper.allocate_from_arena_with_tests(1);
helper.allocate_from_arena_with_tests(128);
@@ -278,11 +279,11 @@ TEST_VM(metaspace, MetaspaceArena_test_enlarge_in_place_standard_nc) {
}
TEST_VM(metaspace, MetaspaceArena_test_enlarge_in_place_micro_c) {
- test_chunk_enlargment_simple(Metaspace::ReflectionMetaspaceType, true);
+ test_chunk_enlargment_simple(Metaspace::ClassMirrorHolderMetaspaceType, true);
}
TEST_VM(metaspace, MetaspaceArena_test_enlarge_in_place_micro_nc) {
- test_chunk_enlargment_simple(Metaspace::ReflectionMetaspaceType, false);
+ test_chunk_enlargment_simple(Metaspace::ClassMirrorHolderMetaspaceType, false);
}
// Test chunk enlargement:
@@ -434,8 +435,8 @@ static void test_recover_from_commit_limit_hit() {
// The first MetaspaceArena mimicks a micro loader. This will fill the free
// chunk list with very small chunks. We allocate from them in an interleaved
// way to cause fragmentation.
- MetaspaceArenaTestHelper helper1(context, Metaspace::ReflectionMetaspaceType, false);
- MetaspaceArenaTestHelper helper2(context, Metaspace::ReflectionMetaspaceType, false);
+ MetaspaceArenaTestHelper helper1(context, Metaspace::ClassMirrorHolderMetaspaceType, false);
+ MetaspaceArenaTestHelper helper2(context, Metaspace::ClassMirrorHolderMetaspaceType, false);
// This MetaspaceArena should hit the limit. We use BootMetaspaceType here since
// it gets a large initial chunk which is committed
@@ -495,7 +496,9 @@ static void test_controlled_growth(Metaspace::MetaspaceType type, bool is_class,
MetaspaceGtestContext context;
MetaspaceArenaTestHelper smhelper(context, type, is_class, "Grower");
- MetaspaceArenaTestHelper smhelper_harrasser(context, Metaspace::ReflectionMetaspaceType, true, "Harasser");
+ const Metaspace::MetaspaceType other_type =
+ (type == Metaspace::StandardMetaspaceType) ? Metaspace::ClassMirrorHolderMetaspaceType : Metaspace::StandardMetaspaceType;
+ MetaspaceArenaTestHelper smhelper_harrasser(context, other_type, true, "Harasser");
size_t used = 0, committed = 0, capacity = 0;
const size_t alloc_words = 16;
@@ -617,16 +620,6 @@ static void test_controlled_growth(Metaspace::MetaspaceType type, bool is_class,
}
// these numbers have to be in sync with arena policy numbers (see memory/metaspace/arenaGrowthPolicy.cpp)
-TEST_VM(metaspace, MetaspaceArena_growth_refl_c_inplace) {
- test_controlled_growth(Metaspace::ReflectionMetaspaceType, true,
- word_size_for_level(CHUNK_LEVEL_1K), true);
-}
-
-TEST_VM(metaspace, MetaspaceArena_growth_refl_c_not_inplace) {
- test_controlled_growth(Metaspace::ReflectionMetaspaceType, true,
- word_size_for_level(CHUNK_LEVEL_1K), false);
-}
-
TEST_VM(metaspace, MetaspaceArena_growth_anon_c_inplace) {
test_controlled_growth(Metaspace::ClassMirrorHolderMetaspaceType, true,
word_size_for_level(CHUNK_LEVEL_1K), true);
@@ -660,16 +653,6 @@ TEST_VM(metaspace, MetaspaceArena_growth_boot_c_not_inplace) {
}
*/
-TEST_VM(metaspace, MetaspaceArena_growth_refl_nc_inplace) {
- test_controlled_growth(Metaspace::ReflectionMetaspaceType, false,
- word_size_for_level(CHUNK_LEVEL_2K), true);
-}
-
-TEST_VM(metaspace, MetaspaceArena_growth_refl_nc_not_inplace) {
- test_controlled_growth(Metaspace::ReflectionMetaspaceType, false,
- word_size_for_level(CHUNK_LEVEL_2K), false);
-}
-
TEST_VM(metaspace, MetaspaceArena_growth_anon_nc_inplace) {
test_controlled_growth(Metaspace::ClassMirrorHolderMetaspaceType, false,
word_size_for_level(CHUNK_LEVEL_1K), true);
diff --git a/test/hotspot/gtest/metaspace/test_metaspacearena_stress.cpp b/test/hotspot/gtest/metaspace/test_metaspacearena_stress.cpp
index e94f733e45b..bb536dfd0e2 100644
--- a/test/hotspot/gtest/metaspace/test_metaspacearena_stress.cpp
+++ b/test/hotspot/gtest/metaspace/test_metaspacearena_stress.cpp
@@ -227,7 +227,7 @@ class MetaspaceArenaTest {
void create_random_test_bed_at(int slotindex) {
SizeRange allocation_range(1, 100); // randomize too?
const ArenaGrowthPolicy* growth_policy = ArenaGrowthPolicy::policy_for_space_type(
- (fifty_fifty() ? Metaspace::StandardMetaspaceType : Metaspace::ReflectionMetaspaceType),
+ (fifty_fifty() ? Metaspace::StandardMetaspaceType : Metaspace::ClassMirrorHolderMetaspaceType),
fifty_fifty());
create_new_test_bed_at(slotindex, growth_policy, allocation_range);
}
From 415320de1ed466f426cd43c1a83db7de7fe0fbe4 Mon Sep 17 00:00:00 2001
From: Matias Saavedra Silva
Date: Mon, 28 Oct 2024 14:31:35 +0000
Subject: [PATCH 008/159] 8341371: CDS cannot load archived heap objects with
-XX:+UseSerialGC -XX:-UseCompressedOops
Reviewed-by: ccheung, iklam
---
.../cds/appcds/TestEpsilonGCWithCDS.java | 32 ++++++++++++++++++-
.../cds/appcds/TestParallelGCWithCDS.java | 32 +++++++++++++++++++
.../cds/appcds/TestSerialGCWithCDS.java | 24 +++-----------
.../cds/appcds/TestShenandoahWithCDS.java | 27 ++++++++++++++++
4 files changed, 95 insertions(+), 20 deletions(-)
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestEpsilonGCWithCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/TestEpsilonGCWithCDS.java
index fe7c5a4ae31..132f63ba850 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/TestEpsilonGCWithCDS.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/TestEpsilonGCWithCDS.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024, 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
@@ -37,16 +37,41 @@
* @run driver TestEpsilonGCWithCDS
*/
+// Below is exactly the same as above, except:
+// - requires vm.bits == "64"
+// - extra argument "false"
+
+/*
+ * @test Loading CDS archived heap objects into EpsilonGC
+ * @bug 8234679 8341371
+ * @requires vm.cds
+ * @requires vm.gc.Epsilon
+ * @requires vm.gc.G1
+ * @requires vm.bits == "64"
+ *
+ * @comment don't run this test if any -XX::+Use???GC options are specified, since they will
+ * interfere with the test.
+ * @requires vm.gc == null
+ *
+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
+ * @compile test-classes/Hello.java
+ * @run driver TestEpsilonGCWithCDS false
+ */
import jdk.test.lib.Platform;
import jdk.test.lib.process.OutputAnalyzer;
public class TestEpsilonGCWithCDS {
public final static String HELLO = "Hello World";
static String helloJar;
+ static boolean useCompressedOops = true;
public static void main(String... args) throws Exception {
helloJar = JarBuilder.build("hello", "Hello");
+ if (args.length > 0 && args[0].equals("false")) {
+ useCompressedOops = false;
+ }
+
// Check if we can use EpsilonGC during dump time, or run time, or both.
test(false, true);
test(true, false);
@@ -70,6 +95,8 @@ static void test(boolean dumpWithEpsilon, boolean execWithEpsilon, boolean useSm
String execGC = execWithEpsilon ? Epsilon : G1;
String small1 = useSmallRegions ? "-Xmx256m" : "-showversion";
String small2 = useSmallRegions ? "-XX:ObjectAlignmentInBytes=64" : "-showversion";
+ String errMsg = "Cannot use CDS heap data. Selected GC not compatible -XX:-UseCompressedOops";
+ String coops = useCompressedOops ? "-XX:+UseCompressedOops" : "-XX:-UseCompressedOops";
OutputAnalyzer out;
System.out.println("0. Dump with " + dumpGC);
@@ -79,6 +106,7 @@ static void test(boolean dumpWithEpsilon, boolean execWithEpsilon, boolean useSm
dumpGC,
small1,
small2,
+ coops,
"-Xlog:cds");
out.shouldContain("Dumping shared data to file:");
out.shouldHaveExitValue(0);
@@ -89,9 +117,11 @@ static void test(boolean dumpWithEpsilon, boolean execWithEpsilon, boolean useSm
execGC,
small1,
small2,
+ coops,
"-Xlog:cds",
"Hello");
out.shouldContain(HELLO);
+ out.shouldNotContain(errMsg);
out.shouldHaveExitValue(0);
}
}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java
index 691c87fef36..705df07f841 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java
@@ -37,16 +37,41 @@
* @run driver TestParallelGCWithCDS
*/
+// Below is exactly the same as above, except:
+// - requires vm.bits == "64"
+// - extra argument "false"
+
+ /*
+ * @test Loading CDS archived heap objects into ParallelGC
+ * @bug 8274788 8341371
+ * @requires vm.cds
+ * @requires vm.gc.Parallel
+ * @requires vm.gc.G1
+ * @requires vm.bits == "64"
+ *
+ * @comment don't run this test if any -XX::+Use???GC options are specified, since they will
+ * interfere with the test.
+ * @requires vm.gc == null
+ *
+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
+ * @compile test-classes/Hello.java
+ * @run driver TestParallelGCWithCDS false
+ */
import jdk.test.lib.Platform;
import jdk.test.lib.process.OutputAnalyzer;
public class TestParallelGCWithCDS {
public final static String HELLO = "Hello World";
static String helloJar;
+ static boolean useCompressedOops = true;
public static void main(String... args) throws Exception {
helloJar = JarBuilder.build("hello", "Hello");
+ if (args.length > 0 && args[0].equals("false")) {
+ useCompressedOops = false;
+ }
+
// Check if we can use ParallelGC during dump time, or run time, or both.
test(false, true);
test(true, false);
@@ -69,6 +94,8 @@ static void test(boolean dumpWithParallel, boolean execWithParallel, boolean use
String execGC = execWithParallel ? Parallel : G1;
String small1 = useSmallRegions ? "-Xmx256m" : "-showversion";
String small2 = useSmallRegions ? "-XX:ObjectAlignmentInBytes=64" : "-showversion";
+ String errMsg = "Cannot use CDS heap data. Selected GC not compatible -XX:-UseCompressedOops";
+ String coops = useCompressedOops ? "-XX:+UseCompressedOops" : "-XX:-UseCompressedOops";
OutputAnalyzer out;
System.out.println("0. Dump with " + dumpGC);
@@ -77,6 +104,7 @@ static void test(boolean dumpWithParallel, boolean execWithParallel, boolean use
dumpGC,
small1,
small2,
+ coops,
"-Xlog:cds");
out.shouldContain("Dumping shared data to file:");
out.shouldHaveExitValue(0);
@@ -86,9 +114,11 @@ static void test(boolean dumpWithParallel, boolean execWithParallel, boolean use
execGC,
small1,
small2,
+ coops,
"-Xlog:cds",
"Hello");
out.shouldContain(HELLO);
+ out.shouldNotContain(errMsg);
out.shouldHaveExitValue(0);
int n = 2;
@@ -109,10 +139,12 @@ static void test(boolean dumpWithParallel, boolean execWithParallel, boolean use
small1,
small2,
xmx,
+ coops,
"-Xlog:cds",
"Hello");
if (out.getExitValue() == 0) {
out.shouldContain(HELLO);
+ out.shouldNotContain(errMsg);
} else {
String pattern = "((Too small maximum heap)" +
"|(GC triggered before VM initialization completed)" +
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestSerialGCWithCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/TestSerialGCWithCDS.java
index 8c8cb4d932a..b191b5f395b 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/TestSerialGCWithCDS.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/TestSerialGCWithCDS.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024, 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
@@ -98,6 +98,7 @@ static void test(boolean dumpWithSerial, boolean execWithSerial, boolean useSmal
String execGC = execWithSerial ? Serial : G1;
String small1 = useSmallRegions ? "-Xmx256m" : DUMMY;
String small2 = useSmallRegions ? "-XX:ObjectAlignmentInBytes=64" : DUMMY;
+ String errMsg = "Cannot use CDS heap data. Selected GC not compatible -XX:-UseCompressedOops";
String coops;
if (Platform.is64bit()) {
coops = useCompressedOops ? "-XX:+UseCompressedOops" : "-XX:-UseCompressedOops";
@@ -125,7 +126,7 @@ static void test(boolean dumpWithSerial, boolean execWithSerial, boolean useSmal
coops,
"-Xlog:cds",
"Hello");
- checkExecOutput(dumpWithSerial, execWithSerial, out);
+ out.shouldNotContain(errMsg);
System.out.println("2. Exec with " + execGC + " and test ArchiveRelocationMode");
out = TestCommon.exec(helloJar,
@@ -136,7 +137,7 @@ static void test(boolean dumpWithSerial, boolean execWithSerial, boolean useSmal
"-Xlog:cds,cds+heap",
"-XX:ArchiveRelocationMode=1", // always relocate shared metadata
"Hello");
- checkExecOutput(dumpWithSerial, execWithSerial, out);
+ out.shouldNotContain(errMsg);
int n = 2;
if (dumpWithSerial == false && execWithSerial == true) {
@@ -160,7 +161,7 @@ static void test(boolean dumpWithSerial, boolean execWithSerial, boolean useSmal
"-Xlog:cds",
"Hello");
if (out.getExitValue() == 0) {
- checkExecOutput(dumpWithSerial, execWithSerial, out);
+ out.shouldNotContain(errMsg);
} else {
String output = out.getStdout() + out.getStderr();
String exp1 = "Too small maximum heap";
@@ -173,19 +174,4 @@ static void test(boolean dumpWithSerial, boolean execWithSerial, boolean useSmal
}
}
}
-
- static void checkExecOutput(boolean dumpWithSerial, boolean execWithSerial, OutputAnalyzer out) {
- String errMsg = "Cannot use CDS heap data. UseG1GC is required for -XX:-UseCompressedOops";
- if (Platform.is64bit() &&
- !Platform.isWindows() && // archive heap not supported on Windows.
- !dumpWithSerial && // Dumped with G1, so we have an archived heap
- execWithSerial && // Running with serial
- !useCompressedOops) { // ArchiveHeapLoader::can_load() always returns false when COOP is disabled
- out.shouldContain(errMsg);
- }
- if (!execWithSerial) {
- // We should never see this message with G1
- out.shouldNotContain(errMsg);
- }
- }
}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestShenandoahWithCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/TestShenandoahWithCDS.java
index 83442c1e159..d8bbfee504b 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/TestShenandoahWithCDS.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/TestShenandoahWithCDS.java
@@ -35,16 +35,38 @@
* @run driver TestShenandoahWithCDS
*/
+// Below is exactly the same as above, except:
+// - requires vm.bits == "64"
+// - extra argument "false"
+
+/*
+ * @test
+ * @bug 8293650 8341371
+ * @requires vm.cds
+ * @requires vm.bits == 64
+ * @requires vm.gc.Shenandoah
+ * @requires vm.gc.G1
+ * @requires vm.gc == null
+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
+ * @compile test-classes/Hello.java
+ * @run driver TestShenandoahWithCDS false
+ */
+
import jdk.test.lib.Platform;
import jdk.test.lib.process.OutputAnalyzer;
public class TestShenandoahWithCDS {
public final static String HELLO = "Hello World";
static String helloJar;
+ static boolean useCompressedOops = true;
public static void main(String... args) throws Exception {
helloJar = JarBuilder.build("hello", "Hello");
+ if (args.length > 0 && args[0].equals("false")) {
+ useCompressedOops = false;
+ }
+
// Run with the variety of region sizes, and combinations
// of G1/Shenandoah at dump/exec times. "-1" means to use G1.
final int[] regionSizes = { -1, 256, 512, 1024, 2048 };
@@ -62,6 +84,8 @@ static void test(int dumpRegionSize, int execRegionSize) throws Exception {
String optExecGC = (execRegionSize != -1) ? "-XX:+UseShenandoahGC" : "-XX:+UseG1GC";
String optDumpRegionSize = (dumpRegionSize != -1) ? "-XX:ShenandoahRegionSize=" + dumpRegionSize + "K" : exp;
String optExecRegionSize = (execRegionSize != -1) ? "-XX:ShenandoahRegionSize=" + execRegionSize + "K" : exp;
+ String errMsg = "Cannot use CDS heap data. Selected GC not compatible -XX:-UseCompressedOops";
+ String coops = useCompressedOops ? "-XX:+UseCompressedOops" : "-XX:-UseCompressedOops";
OutputAnalyzer out;
System.out.println("0. Dump with " + optDumpGC + " and " + optDumpRegionSize);
@@ -71,6 +95,7 @@ static void test(int dumpRegionSize, int execRegionSize) throws Exception {
"-Xmx1g",
optDumpGC,
optDumpRegionSize,
+ coops,
"-Xlog:cds");
out.shouldContain("Dumping shared data to file:");
out.shouldHaveExitValue(0);
@@ -81,9 +106,11 @@ static void test(int dumpRegionSize, int execRegionSize) throws Exception {
"-Xmx1g",
optExecGC,
optExecRegionSize,
+ coops,
"-Xlog:cds",
"Hello");
out.shouldContain(HELLO);
+ out.shouldNotContain(errMsg);
out.shouldHaveExitValue(0);
}
}
From e9de2ce140e63f1fdf22de1c6b38b6580c1ea663 Mon Sep 17 00:00:00 2001
From: Jatin Bhateja
Date: Mon, 28 Oct 2024 16:30:29 +0000
Subject: [PATCH 009/159] 8338021: Support new unsigned and saturating vector
operators in VectorAPI
Reviewed-by: psandoz, epeter, sviswanathan
---
.../jdk/internal/vm/vector/VectorSupport.java | 7 +
.../jdk/incubator/vector/ByteVector.java | 12 +
.../jdk/incubator/vector/IntVector.java | 12 +
.../jdk/incubator/vector/LongVector.java | 12 +
.../jdk/incubator/vector/ShortVector.java | 12 +
.../jdk/incubator/vector/VectorMath.java | 586 ++++++++++++++++++
.../jdk/incubator/vector/VectorOperators.java | 36 +-
.../incubator/vector/X-Vector.java.template | 12 +
.../vectorapi/VectorCompareWithImmTest.java | 16 +-
.../vectorapi/VectorCompareWithZeroTest.java | 6 +-
.../incubator/vector/Byte128VectorTests.java | 326 +++++++++-
.../incubator/vector/Byte256VectorTests.java | 326 +++++++++-
.../incubator/vector/Byte512VectorTests.java | 326 +++++++++-
.../incubator/vector/Byte64VectorTests.java | 326 +++++++++-
.../incubator/vector/ByteMaxVectorTests.java | 326 +++++++++-
.../incubator/vector/Int128VectorTests.java | 326 +++++++++-
.../incubator/vector/Int256VectorTests.java | 326 +++++++++-
.../incubator/vector/Int512VectorTests.java | 326 +++++++++-
.../incubator/vector/Int64VectorTests.java | 326 +++++++++-
.../incubator/vector/IntMaxVectorTests.java | 326 +++++++++-
.../incubator/vector/Long128VectorTests.java | 326 +++++++++-
.../incubator/vector/Long256VectorTests.java | 326 +++++++++-
.../incubator/vector/Long512VectorTests.java | 326 +++++++++-
.../incubator/vector/Long64VectorTests.java | 326 +++++++++-
.../incubator/vector/LongMaxVectorTests.java | 326 +++++++++-
.../incubator/vector/Short128VectorTests.java | 326 +++++++++-
.../incubator/vector/Short256VectorTests.java | 326 +++++++++-
.../incubator/vector/Short512VectorTests.java | 326 +++++++++-
.../incubator/vector/Short64VectorTests.java | 326 +++++++++-
.../incubator/vector/ShortMaxVectorTests.java | 326 +++++++++-
.../jdk/incubator/vector/VectorMathTest.java | 245 ++++++++
test/jdk/jdk/incubator/vector/gen-template.sh | 22 +-
...Kernel-SaturatingBinary-Masked-op.template | 13 +
.../Kernel-SaturatingBinary-op.template | 11 +
.../Unit-SaturatingBinary-Masked-op.template | 7 +
.../Unit-SaturatingBinary-op.template | 10 +
.../vector/templates/Unit-header.template | 58 ++
37 files changed, 7257 insertions(+), 340 deletions(-)
create mode 100644 src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMath.java
create mode 100644 test/jdk/jdk/incubator/vector/VectorMathTest.java
create mode 100644 test/jdk/jdk/incubator/vector/templates/Kernel-SaturatingBinary-Masked-op.template
create mode 100644 test/jdk/jdk/incubator/vector/templates/Kernel-SaturatingBinary-op.template
create mode 100644 test/jdk/jdk/incubator/vector/templates/Unit-SaturatingBinary-Masked-op.template
create mode 100644 test/jdk/jdk/incubator/vector/templates/Unit-SaturatingBinary-op.template
diff --git a/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java b/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java
index 63cab418d46..afd6cc62ce5 100644
--- a/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java
+++ b/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java
@@ -114,6 +114,13 @@ public class VectorSupport {
public static final int VECTOR_OP_EXPM1 = 117;
public static final int VECTOR_OP_HYPOT = 118;
+ public static final int VECTOR_OP_SADD = 119;
+ public static final int VECTOR_OP_SSUB = 120;
+ public static final int VECTOR_OP_SUADD = 121;
+ public static final int VECTOR_OP_SUSUB = 122;
+ public static final int VECTOR_OP_UMIN = 123;
+ public static final int VECTOR_OP_UMAX = 124;
+
// See src/hotspot/share/opto/subnode.hpp
// struct BoolTest, and enclosed enum mask
public static final int BT_eq = 0; // 0000
diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java
index 11c0fda80a4..f36215ffe12 100644
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java
@@ -884,6 +884,18 @@ private static BinaryOperation> binaryOperations(in
v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
+ case VECTOR_OP_UMAX: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (byte)VectorMath.maxUnsigned(a, b));
+ case VECTOR_OP_UMIN: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (byte)VectorMath.minUnsigned(a, b));
+ case VECTOR_OP_SADD: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (byte)(VectorMath.addSaturating(a, b)));
+ case VECTOR_OP_SSUB: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (byte)(VectorMath.subSaturating(a, b)));
+ case VECTOR_OP_SUADD: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (byte)(VectorMath.addSaturatingUnsigned(a, b)));
+ case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (byte)(VectorMath.subSaturatingUnsigned(a, b)));
default: return null;
}
}
diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java
index b61e2fc991e..6cb81767cdd 100644
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java
@@ -884,6 +884,18 @@ private static BinaryOperation> binaryOperations(
v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
+ case VECTOR_OP_UMAX: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (int)VectorMath.maxUnsigned(a, b));
+ case VECTOR_OP_UMIN: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (int)VectorMath.minUnsigned(a, b));
+ case VECTOR_OP_SADD: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (int)(VectorMath.addSaturating(a, b)));
+ case VECTOR_OP_SSUB: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (int)(VectorMath.subSaturating(a, b)));
+ case VECTOR_OP_SUADD: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (int)(VectorMath.addSaturatingUnsigned(a, b)));
+ case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (int)(VectorMath.subSaturatingUnsigned(a, b)));
case VECTOR_OP_COMPRESS_BITS: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> Integer.compress(a, n));
case VECTOR_OP_EXPAND_BITS: return (v0, v1, vm) ->
diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java
index 68166bd9852..a740c9d49cf 100644
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java
@@ -842,6 +842,18 @@ private static BinaryOperation> binaryOperations(in
v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
+ case VECTOR_OP_UMAX: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (long)VectorMath.maxUnsigned(a, b));
+ case VECTOR_OP_UMIN: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (long)VectorMath.minUnsigned(a, b));
+ case VECTOR_OP_SADD: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (long)(VectorMath.addSaturating(a, b)));
+ case VECTOR_OP_SSUB: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (long)(VectorMath.subSaturating(a, b)));
+ case VECTOR_OP_SUADD: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (long)(VectorMath.addSaturatingUnsigned(a, b)));
+ case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (long)(VectorMath.subSaturatingUnsigned(a, b)));
case VECTOR_OP_COMPRESS_BITS: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> Long.compress(a, n));
case VECTOR_OP_EXPAND_BITS: return (v0, v1, vm) ->
diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java
index 2f1ea210b90..0e3ff9aaa87 100644
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java
@@ -884,6 +884,18 @@ private static BinaryOperation> binaryOperations(
v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
+ case VECTOR_OP_UMAX: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (short)VectorMath.maxUnsigned(a, b));
+ case VECTOR_OP_UMIN: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (short)VectorMath.minUnsigned(a, b));
+ case VECTOR_OP_SADD: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (short)(VectorMath.addSaturating(a, b)));
+ case VECTOR_OP_SSUB: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (short)(VectorMath.subSaturating(a, b)));
+ case VECTOR_OP_SUADD: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (short)(VectorMath.addSaturatingUnsigned(a, b)));
+ case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> (short)(VectorMath.subSaturatingUnsigned(a, b)));
default: return null;
}
}
diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMath.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMath.java
new file mode 100644
index 00000000000..0d590d2d49a
--- /dev/null
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMath.java
@@ -0,0 +1,586 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.vector;
+
+/**
+ * The class {@code VectorMath} contains methods for performing
+ * scalar numeric operations in support of vector numeric operations.
+ * @since 24
+ */
+public final class VectorMath {
+
+ private VectorMath() {
+ }
+
+ /**
+ * Returns the smaller of two {@code long} values numerically treating
+ * the values as unsigned. That is, the result is the operand closer
+ * to the value of the expression {@code 0L}. If the operands have the
+ * same value, the result is that same value.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the smaller of {@code a} and {@code b}.
+ * @see VectorOperators#UMIN
+ */
+ public static long minUnsigned(long a, long b) {
+ return Long.compareUnsigned(a, b) < 0 ? a : b;
+ }
+
+ /**
+ * Returns the greater of two {@code long} values numerically treating
+ * the values as unsigned. That is, the result is the operand closer
+ * to the value of the expression {@code 0xFFFFFFFF_FFFFFFFFL} numerically
+ * treating it as unsigned. If the operands have the same value,
+ * the result is that same value.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the larger of {@code a} and {@code b}.
+ * @see VectorOperators#UMAX
+ */
+ public static long maxUnsigned(long a, long b) {
+ return Long.compareUnsigned(a, b) > 0 ? a : b;
+ }
+
+ /**
+ * Adds two {@code long} values using saturation
+ * arithemetic. The lower and upper (inclusive) bounds are
+ * {@code Long.MIN_VALUE} and {@code Long.MAX_VALUE}, respectively.
+ *
+ * If the result of the addition would otherwise overflow from
+ * a positive value to a negative value then the result is clamped
+ * to the upper bound {@code Long.MAX_VALUE}.
+ * If the result of the addition would otherwise underflow from
+ * a negative value to a positive value then the result is clamped
+ * to lower bound {@code Long.MIN_VALUE}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating addition of the operands.
+ * @see VectorOperators#SADD
+ */
+ public static long addSaturating(long a, long b) {
+ long res = a + b;
+ // HD 2-12 Overflow iff both arguments have the opposite sign of the result
+ if (((a ^ res) & (b ^ res)) < 0) {
+ return res < 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
+ } else {
+ return res;
+ }
+ }
+
+ /**
+ * Subtracts two {@code long} values using saturation
+ * arithemetic. The lower and upper (inclusive) bounds are
+ * {@code Long.MIN_VALUE} and {@code Long.MAX_VALUE}, respectively.
+ *
+ * If the result of the subtraction would otherwise overflow from
+ * a positive value to a negative value then the result is clamped
+ * to the upper bound {@code Long.MAX_VALUE}.
+ * If the result of the subtraction would otherwise underflow from
+ * a negative value to a positive value then the result is clamped
+ * to lower bound {@code Long.MIN_VALUE}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating difference of the operands.
+ * @see VectorOperators#SSUB
+ */
+ public static long subSaturating(long a, long b) {
+ long res = a - b;
+ // HD 2-12 Overflow iff the arguments have different signs and
+ // the sign of the result is different from the sign of a
+ if (((a ^ b) & (a ^ res)) < 0) {
+ return a < 0 ? Long.MIN_VALUE : Long.MAX_VALUE;
+ } else {
+ return res;
+ }
+ }
+
+ /**
+ * Adds two {@code long} values using saturation
+ * arithemetic and numerically treating the values
+ * as unsigned. The lower and upper (inclusive) bounds
+ * are {@code 0L} and {@code 0xFFFFFFFF_FFFFFFFFL}, respectively,
+ * numerically treating them as unsigned.
+ *
+ * If the result of the unsigned addition would otherwise overflow
+ * from the greater of the two operands to a lesser value then the
+ * result is clamped to the upper bound {@code 0xFFFFFFFF_FFFFFFFFL}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating addition of the operands.
+ * @see VectorOperators#SUADD
+ */
+ public static long addSaturatingUnsigned(long a, long b) {
+ long res = a + b;
+ boolean overflow = Long.compareUnsigned(res, (a | b)) < 0;
+ if (overflow) {
+ return -1L;
+ } else {
+ return res;
+ }
+ }
+
+ /**
+ * Subtracts two {@code long} values using saturation
+ * arithemetic and numerically treating the values
+ * as unsigned. The lower and upper (inclusive) bounds
+ * are {@code 0L} and {@code 0xFFFFFFFF_FFFFFFFFL}, respectively,
+ * numerically treating them as unsigned.
+ *
+ * If the result of the unsigned subtraction would otherwise underflow
+ * from the lesser of the two operands to a greater value then the
+ * result is clamped to the lower bound {@code 0L}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating difference of the operands.
+ * @see VectorOperators#SUSUB
+ */
+ public static long subSaturatingUnsigned(long a, long b) {
+ if (Long.compareUnsigned(b, a) < 0) {
+ return a - b;
+ } else {
+ return 0;
+ }
+ }
+
+
+ /**
+ * Returns the smaller of two {@code int} values numerically treating
+ * the values as unsigned. That is, the result is the operand closer
+ * to the value of the expression {@code 0}. If the operands have the
+ * same value, the result is that same value.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the smaller of {@code a} and {@code b}.
+ * @see VectorOperators#UMIN
+ */
+ public static int minUnsigned(int a, int b) {
+ return Integer.compareUnsigned(a, b) < 0 ? a : b;
+ }
+
+ /**
+ * Returns the greater of two {@code int} values numerically treating
+ * the values as unsigned. That is, the result is the operand closer
+ * to the value of the expression {@code 0xFFFFFFFF} numerically
+ * treating it as unsigned. If the operands have the same value,
+ * the result is that same value.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the larger of {@code a} and {@code b}.
+ * @see VectorOperators#UMAX
+ */
+ public static int maxUnsigned(int a, int b) {
+ return Integer.compareUnsigned(a, b) > 0 ? a : b;
+ }
+
+ /**
+ * Adds two {@code int} values using saturation
+ * arithemetic. The lower and upper (inclusive) bounds are
+ * {@code Integer.MIN_VALUE} and {@code Integer.MAX_VALUE}, respectively.
+ *
+ * If the result of the addition would otherwise overflow from
+ * a positive value to a negative value then the result is clamped
+ * to the upper bound {@code Integer.MAX_VALUE}.
+ * If the result of the addition would otherwise underflow from
+ * a negative value to a positive value then the result is clamped
+ * to lower bound {@code Integer.MIN_VALUE}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating addition of the operands.
+ * @see VectorOperators#SADD
+ */
+ public static int addSaturating(int a, int b) {
+ long res = (long)a + (long)b;
+ if (res > Integer.MAX_VALUE) {
+ return Integer.MAX_VALUE;
+ } else if (res < Integer.MIN_VALUE) {
+ return Integer.MIN_VALUE;
+ } else {
+ return (int)res;
+ }
+ }
+
+ /**
+ * Subtracts two {@code int} values using saturation
+ * arithemetic. The lower and upper (inclusive) bounds are
+ * {@code Integer.MIN_VALUE} and {@code Integer.MAX_VALUE}, respectively.
+ *
+ * If the result of the subtraction would otherwise overflow from
+ * a positive value to a negative value then the result is clamped
+ * to the upper bound {@code Integer.MAX_VALUE}.
+ * If the result of the subtraction would otherwise underflow from
+ * a negative value to a positive value then the result is clamped
+ * to lower bound {@code Integer.MIN_VALUE}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating difference of the operands.
+ * @see VectorOperators#SSUB
+ */
+ public static int subSaturating(int a, int b) {
+ long res = (long)a - (long)b;
+ if (res > Integer.MAX_VALUE) {
+ return Integer.MAX_VALUE;
+ } else if (res < Integer.MIN_VALUE) {
+ return Integer.MIN_VALUE;
+ } else {
+ return (int)res;
+ }
+ }
+
+ /**
+ * Adds two {@code int} values using saturation
+ * arithemetic and numerically treating the values
+ * as unsigned. The lower and upper (inclusive) bounds
+ * are {@code 0} and {@code 0xFFFFFFFF}, respectively,
+ * numerically treating them as unsigned.
+ *
+ * If the result of the unsigned addition would otherwise overflow
+ * from the greater of the two operands to a lesser value then the
+ * result is clamped to the upper bound {@code 0xFFFFFFFF}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating addition of the operands.
+ * @see VectorOperators#SUADD
+ */
+ public static int addSaturatingUnsigned(int a, int b) {
+ int res = a + b;
+ boolean overflow = Integer.compareUnsigned(res, (a | b)) < 0;
+ if (overflow) {
+ return -1;
+ } else {
+ return res;
+ }
+ }
+
+ /**
+ * Subtracts two {@code int} values using saturation
+ * arithemetic and numerically treating the values
+ * as unsigned. The lower and upper (inclusive) bounds
+ * are {@code 0} and {@code -0xFFFFFFFF}, respectively,
+ * numerically treating them as unsigned.
+ *
+ * If the result of the unsigned subtraction would otherwise underflow
+ * from the lesser of the two operands to a greater value then the
+ * result is clamped to the lower bound {@code 0}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating difference of the operands.
+ * @see VectorOperators#SUSUB
+ */
+ public static int subSaturatingUnsigned(int a, int b) {
+ if (Integer.compareUnsigned(b, a) < 0) {
+ return a - b;
+ } else {
+ return 0;
+ }
+ }
+
+
+ /**
+ * Returns the smaller of two {@code short} values numerically treating
+ * the values as unsigned. That is, the result is the operand closer
+ * to the value of the expression {@code 0}. If the operands have the
+ * same value, the result is that same value.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the smaller of {@code a} and {@code b}.
+ * @see VectorOperators#UMIN
+ */
+ public static short minUnsigned(short a, short b) {
+ return Short.compareUnsigned(a, b) < 0 ? a : b;
+ }
+
+ /**
+ * Returns the greater of two {@code short} values numerically treating
+ * the values as unsigned. That is, the result is the operand closer
+ * to the value of the expression {@code 0xFFFF} numerically
+ * treating it as unsigned. If the operands have the same value,
+ * the result is that same value.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the larger of {@code a} and {@code b}.
+ * @see VectorOperators#UMAX
+ */
+ public static short maxUnsigned(short a, short b) {
+ return Short.compareUnsigned(a, b) > 0 ? a : b;
+ }
+
+ /**
+ * Adds two {@code short} values using saturation
+ * arithemetic. The lower and upper (inclusive) bounds are
+ * {@code Short.MIN_VALUE} and {@code Short.MAX_VALUE}, respectively.
+ *
+ * If the result of the addition would otherwise overflow from
+ * a positive value to a negative value then the result is clamped
+ * to the upper bound {@code Short.MAX_VALUE}.
+ * If the result of the addition would otherwise underflow from
+ * a negative value to a positive value then the result is clamped
+ * to lower bound {@code Short.MIN_VALUE}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating addition of the operands.
+ * @see VectorOperators#SADD
+ */
+ public static short addSaturating(short a, short b) {
+ int res = a + b;
+ if (res > Short.MAX_VALUE) {
+ return Short.MAX_VALUE;
+ } else if (res < Short.MIN_VALUE) {
+ return Short.MIN_VALUE;
+ } else {
+ return (short)res;
+ }
+ }
+
+ /**
+ * Subtracts two {@code short} values using saturation
+ * arithemetic. The lower and upper (inclusive) bounds are
+ * {@code Short.MIN_VALUE} and {@code Short.MAX_VALUE}, respectively.
+ *
+ * If the result of the subtraction would otherwise overflow from
+ * a positive value to a negative value then the result is clamped
+ * to the upper bound {@code Short.MAX_VALUE}.
+ * If the result of the subtraction would otherwise underflow from
+ * a negative value to a positive value then the result is clamped
+ * to lower bound {@code Short.MIN_VALUE}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating difference of the operands.
+ * @see VectorOperators#SSUB
+ */
+ public static short subSaturating(short a, short b) {
+ int res = a - b;
+ if (res > Short.MAX_VALUE) {
+ return Short.MAX_VALUE;
+ } else if (res < Short.MIN_VALUE) {
+ return Short.MIN_VALUE;
+ } else {
+ return (short)res;
+ }
+ }
+
+ /**
+ * Adds two {@code short} values using saturation
+ * arithemetic and numerically treating the values
+ * as unsigned. The lower and upper (inclusive) bounds
+ * are {@code 0} and {@code 0xFFFF}, respectively,
+ * numerically treating them as unsigned.
+ *
+ * If the result of the unsigned addition would otherwise overflow
+ * from the greater of the two operands to a lesser value then the
+ * result is clamped to the upper bound {@code 0xFFFF}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating addition of the operands.
+ * @see VectorOperators#SUADD
+ */
+ public static short addSaturatingUnsigned(short a, short b) {
+ short res = (short)(a + b);
+ boolean overflow = Short.compareUnsigned(res, (short)(a | b)) < 0;
+ if (overflow) {
+ return (short)(-1);
+ } else {
+ return res;
+ }
+ }
+
+ /**
+ * Subtracts two {@code short} values using saturation
+ * arithemetic and numerically treating the values
+ * as unsigned. The lower and upper (inclusive) bounds
+ * are {@code 0} and {@code 0xFFFF}, respectively,
+ * numerically treating them as unsigned.
+ *
+ * If the result of the unsigned subtraction would otherwise underflow
+ * from the lesser of the two operands to a greater value then the
+ * result is clamped to the lower bound {@code 0}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating difference of the operands.
+ * @see VectorOperators#SUSUB
+ */
+ public static short subSaturatingUnsigned(short a, short b) {
+ if (Short.compareUnsigned(b, a) < 0) {
+ return (short)(a - b);
+ } else {
+ return 0;
+ }
+ }
+
+
+ /**
+ * Returns the smaller of two {@code byte} values numerically treating
+ * the values as unsigned. That is, the result is the operand closer
+ * to the value of the expression {@code 0}. If the operands have the
+ * same value, the result is that same value.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the smaller of {@code a} and {@code b}.
+ * @see VectorOperators#UMIN
+ */
+ public static byte minUnsigned(byte a, byte b) {
+ return Byte.compareUnsigned(a, b) < 0 ? a : b;
+ }
+
+ /**
+ * Returns the greater of two {@code byte} values numerically treating
+ * the values as unsigned. That is, the result is the operand closer
+ * to the value of the expression {@code 0xFF} numerically
+ * treating it as unsigned. If the operands have the same value,
+ * the result is that same value.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the larger of {@code a} and {@code b}.
+ * @see VectorOperators#UMAX
+ */
+ public static byte maxUnsigned(byte a, byte b) {
+ return Byte.compareUnsigned(a, b) > 0 ? a : b;
+ }
+
+ /**
+ * Adds two {@code byte} values using saturation
+ * arithemetic. The lower and upper (inclusive) bounds are
+ * {@code Byte.MIN_VALUE} and {@code Byte.MAX_VALUE}, respectively.
+ *
+ * If the result of the addition would otherwise overflow from
+ * a positive value to a negative value then the result is clamped
+ * to the upper bound {@code Byte.MAX_VALUE}.
+ * If the result of the addition would otherwise underflow from
+ * a negative value to a positive value then the result is clamped
+ * to lower bound {@code Byte.MIN_VALUE}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating addition of the operands.
+ * @see VectorOperators#SADD
+ */
+ public static byte addSaturating(byte a, byte b) {
+ int res = a + b;
+ if (res > Byte.MAX_VALUE) {
+ return Byte.MAX_VALUE;
+ } else if (res < Byte.MIN_VALUE) {
+ return Byte.MIN_VALUE;
+ } else {
+ return (byte)res;
+ }
+ }
+
+ /**
+ * Subtracts two {@code byte} values using saturation
+ * arithemetic. The lower and upper (inclusive) bounds are
+ * {@code Byte.MIN_VALUE} and {@code Byte.MAX_VALUE}, respectively.
+ *
+ * If the result of the subtraction would otherwise overflow from
+ * a positive value to a negative value then the result is clamped
+ * to the upper bound {@code Byte.MAX_VALUE}.
+ * If the result of the subtraction would otherwise underflow from
+ * a negative value to a positive value then the result is clamped
+ * to lower bound {@code Byte.MIN_VALUE}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating difference of the operands.
+ * @see VectorOperators#SSUB
+ */
+ public static byte subSaturating(byte a, byte b) {
+ int res = a - b;
+ if (res > Byte.MAX_VALUE) {
+ return Byte.MAX_VALUE;
+ } else if (res < Byte.MIN_VALUE) {
+ return Byte.MIN_VALUE;
+ } else {
+ return (byte)res;
+ }
+ }
+
+ /**
+ * Adds two {@code byte} values using saturation
+ * arithemetic and numerically treating the values
+ * as unsigned. The lower and upper (inclusive) bounds
+ * are {@code 0} and {@code 0xFF}, respectively,
+ * numerically treating them as unsigned.
+ *
+ * If the result of the unsigned addition would otherwise overflow
+ * from the greater of the two operands to a lesser value then the
+ * result is clamped to the upper bound {@code 0xFF}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating addition of the operands.
+ * @see VectorOperators#SUADD
+ */
+ public static byte addSaturatingUnsigned(byte a, byte b) {
+ byte res = (byte)(a + b);
+ boolean overflow = Byte.compareUnsigned(res, (byte)(a | b)) < 0;
+ if (overflow) {
+ return (byte)(-1);
+ } else {
+ return res;
+ }
+ }
+
+ /**
+ * Subtracts two {@code byte} values using saturation
+ * arithemetic and numerically treating the values
+ * as unsigned. The lower and upper (inclusive) bounds
+ * are {@code 0} and {@code 0xFF}, respectively,
+ * numerically treating them as unsigned.
+ *
+ * If the result of the unsigned subtraction would otherwise underflow
+ * from the lesser of the two operands to a greater value then the
+ * result is clamped to the lower bound {@code 0}.
+ *
+ * @param a the first operand.
+ * @param b the second operand.
+ * @return the saturating difference of the operands.
+ * @see VectorOperators#SUSUB
+ */
+ public static byte subSaturatingUnsigned(byte a, byte b) {
+ if (Byte.compareUnsigned(b, a) < 0) {
+ return (byte)(a - b);
+ } else {
+ return 0;
+ }
+ }
+}
diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java
index 38c4b1c94fe..fa70d65c742 100644
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2024, 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
@@ -567,6 +567,32 @@ static boolean opKind(Operator op, int bit) {
/** Produce {@code a^b}. Integral only. */
public static final /*bitwise*/ Associative XOR = assoc("XOR", "^", VectorSupport.VECTOR_OP_XOR, VO_NOFP+VO_ASSOC);
+ /** Produce saturating {@code a+b}. Integral only.
+ * @see VectorMath#addSaturating(int, int)
+ */
+ public static final Binary SADD = binary("SADD", "+", VectorSupport.VECTOR_OP_SADD, VO_NOFP);
+ /** Produce saturating unsigned {@code a+b}. Integral only.
+ * @see VectorMath#addSaturatingUnsigned(int, int)
+ */
+ public static final Binary SUADD = binary("SUADD", "+", VectorSupport.VECTOR_OP_SUADD, VO_NOFP);
+ /** Produce saturating {@code a-b}. Integral only.
+ * @see VectorMath#subSaturating(int, int)
+ */
+ public static final Binary SSUB = binary("SSUB", "-", VectorSupport.VECTOR_OP_SSUB, VO_NOFP);
+ /** Produce saturating unsigned {@code a-b}. Integral only.
+ * @see VectorMath#subSaturatingUnsigned(int, int)
+ */
+ public static final Binary SUSUB = binary("SUSUB", "-", VectorSupport.VECTOR_OP_SUSUB, VO_NOFP);
+ /** Produce unsigned {@code min(a,b)}. Integral only.
+ * @see VectorMath#minUnsigned(int, int) (int, int)
+ */
+ public static final Associative UMIN = assoc("UMIN", "umin", VectorSupport.VECTOR_OP_UMIN, VO_NOFP+VO_ASSOC);
+ /** Produce unsigned {@code max(a,b)}. Integral only.
+ * @see VectorMath#maxUnsigned(int, int) (int, int)
+ */
+ public static final Associative UMAX = assoc("UMAX", "umax", VectorSupport.VECTOR_OP_UMAX, VO_NOFP+VO_ASSOC);
+
+
/** Produce {@code a<<(n&(ESIZE*8-1))}. Integral only. */
public static final /*bitwise*/ Binary LSHL = binary("LSHL", "<<", VectorSupport.VECTOR_OP_LSHIFT, VO_SHIFT);
/** Produce {@code a>>(n&(ESIZE*8-1))}. Integral only. */
@@ -636,22 +662,22 @@ static boolean opKind(Operator op, int bit) {
* @see java.lang.Integer#compareUnsigned
* @see java.lang.Long#compareUnsigned
*/
- public static final Comparison UNSIGNED_LT = compare("UNSIGNED_LT", "<", VectorSupport.BT_ult, VO_NOFP);
+ public static final Comparison ULT = compare("ULT", "<", VectorSupport.BT_ult, VO_NOFP);
/** Unsigned compare {@code a<=b}. Integral only.
* @see java.lang.Integer#compareUnsigned
* @see java.lang.Long#compareUnsigned
*/
- public static final Comparison UNSIGNED_LE = compare("UNSIGNED_LE", "<=", VectorSupport.BT_ule, VO_NOFP);
+ public static final Comparison ULE = compare("ULE", "<=", VectorSupport.BT_ule, VO_NOFP);
/** Unsigned compare {@code a>b}. Integral only.
* @see java.lang.Integer#compareUnsigned
* @see java.lang.Long#compareUnsigned
*/
- public static final Comparison UNSIGNED_GT = compare("UNSIGNED_GT", ">", VectorSupport.BT_ugt, VO_NOFP);
+ public static final Comparison UGT = compare("UGT", ">", VectorSupport.BT_ugt, VO_NOFP);
/** Unsigned compare {@code a>=b}. Integral only.
* @see java.lang.Integer#compareUnsigned
* @see java.lang.Long#compareUnsigned
*/
- public static final Comparison UNSIGNED_GE = compare("UNSIGNED_GE", ">=", VectorSupport.BT_uge, VO_NOFP);
+ public static final Comparison UGE = compare("UGE", ">=", VectorSupport.BT_uge, VO_NOFP);
// Conversion operators
diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template
index b9a48005ccf..b5f3a4b7d87 100644
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template
@@ -980,6 +980,18 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
+ case VECTOR_OP_UMAX: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> ($type$)VectorMath.maxUnsigned(a, b));
+ case VECTOR_OP_UMIN: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> ($type$)VectorMath.minUnsigned(a, b));
+ case VECTOR_OP_SADD: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.addSaturating(a, b)));
+ case VECTOR_OP_SSUB: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.subSaturating(a, b)));
+ case VECTOR_OP_SUADD: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.addSaturatingUnsigned(a, b)));
+ case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
+ v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.subSaturatingUnsigned(a, b)));
#if[intOrLong]
case VECTOR_OP_COMPRESS_BITS: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> $Boxtype$.compress(a, n));
diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorCompareWithImmTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorCompareWithImmTest.java
index b7c192778bd..833ef2b614c 100644
--- a/test/hotspot/jtreg/compiler/vectorapi/VectorCompareWithImmTest.java
+++ b/test/hotspot/jtreg/compiler/vectorapi/VectorCompareWithImmTest.java
@@ -143,7 +143,7 @@ public static void testByteGTInRange_runner() {
@IR(counts = { IRNode.VMASK_CMPU_IMM_I_SVE, ">= 1" })
public static void testByteUnsignedGTInRange() {
ByteVector av = ByteVector.fromArray(B_SPECIES, ba, 0);
- av.compare(VectorOperators.UNSIGNED_GT, 64).intoArray(br, 0);
+ av.compare(VectorOperators.UGT, 64).intoArray(br, 0);
}
@Run(test = "testByteUnsignedGTInRange")
@@ -163,7 +163,7 @@ public static void testByteGTOutOfRange() {
@IR(failOn = { IRNode.VMASK_CMPU_IMM_I_SVE })
public static void testByteUnsignedGTOutOfRange() {
ByteVector av = ByteVector.fromArray(B_SPECIES, ba, 0);
- av.compare(VectorOperators.UNSIGNED_GT, -91).intoArray(br, 0);
+ av.compare(VectorOperators.UGT, -91).intoArray(br, 0);
}
@Test
@@ -183,7 +183,7 @@ public static void testShortGEInRange_runner() {
@IR(counts = { IRNode.VMASK_CMPU_IMM_I_SVE, ">= 1" })
public static void testShortUnsignedGEInRange() {
ShortVector av = ShortVector.fromArray(S_SPECIES, sa, 0);
- av.compare(VectorOperators.UNSIGNED_GE, 56).intoArray(sr, 0);
+ av.compare(VectorOperators.UGE, 56).intoArray(sr, 0);
}
@Run(test = "testShortUnsignedGEInRange")
@@ -203,7 +203,7 @@ public static void testShortGEOutOfRange() {
@IR(failOn = { IRNode.VMASK_CMPU_IMM_I_SVE })
public static void testShortUnsignedGEOutOfRange() {
ShortVector av = ShortVector.fromArray(S_SPECIES, sa, 0);
- av.compare(VectorOperators.UNSIGNED_GE, -85).intoArray(sr, 0);
+ av.compare(VectorOperators.UGE, -85).intoArray(sr, 0);
}
@Test
@@ -223,7 +223,7 @@ public static void testIntLTInRange_runner() {
@IR(counts = { IRNode.VMASK_CMPU_IMM_I_SVE, ">= 1" })
public static void testIntUnsignedLTInRange() {
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
- av.compare(VectorOperators.UNSIGNED_LT, 101).intoArray(ir, 0);
+ av.compare(VectorOperators.ULT, 101).intoArray(ir, 0);
}
@Run(test = "testIntUnsignedLTInRange")
@@ -243,7 +243,7 @@ public static void testIntLTOutOfRange() {
@IR(failOn = { IRNode.VMASK_CMPU_IMM_I_SVE })
public static void testIntUnsignedLTOutOfRange() {
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
- av.compare(VectorOperators.UNSIGNED_LT, -110).intoArray(ir, 0);
+ av.compare(VectorOperators.ULT, -110).intoArray(ir, 0);
}
@Test
@@ -263,7 +263,7 @@ public static void testLongLEInRange_runner() {
@IR(counts = { IRNode.VMASK_CMPU_IMM_L_SVE, ">= 1" })
public static void testLongUnsignedLEInRange() {
LongVector av = LongVector.fromArray(L_SPECIES, la, 0);
- av.compare(VectorOperators.UNSIGNED_LE, 95).intoArray(lr, 0);
+ av.compare(VectorOperators.ULE, 95).intoArray(lr, 0);
}
@Run(test = "testLongUnsignedLEInRange")
@@ -283,7 +283,7 @@ public static void testLongLEOutOfRange() {
@IR(failOn = { IRNode.VMASK_CMPU_IMM_L_SVE })
public static void testLongUnsignedLEOutOfRange() {
LongVector av = LongVector.fromArray(L_SPECIES, la, 0);
- av.compare(VectorOperators.UNSIGNED_LE, -99).intoArray(lr, 0);
+ av.compare(VectorOperators.ULE, -99).intoArray(lr, 0);
}
@Test
diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorCompareWithZeroTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorCompareWithZeroTest.java
index 21ad4a524d2..26e159fb768 100644
--- a/test/hotspot/jtreg/compiler/vectorapi/VectorCompareWithZeroTest.java
+++ b/test/hotspot/jtreg/compiler/vectorapi/VectorCompareWithZeroTest.java
@@ -240,14 +240,14 @@ public static void testDoubleVectorLessThanZero_runner() {
@IR(failOn = { IRNode.VMASK_CMP_ZERO_I_NEON })
public static void testIntVectorUnsignedCondition() {
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
- av.compare(VectorOperators.UNSIGNED_GT, 0).intoArray(ir, 0);
+ av.compare(VectorOperators.UGT, 0).intoArray(ir, 0);
}
@Test
@IR(failOn = { IRNode.VMASK_CMP_ZERO_L_NEON })
public static void testLongVectorUnsignedCondition() {
LongVector av = LongVector.fromArray(L_SPECIES, la, 0);
- av.compare(VectorOperators.UNSIGNED_GE, 0).intoArray(lr, 0);
+ av.compare(VectorOperators.UGE, 0).intoArray(lr, 0);
}
public static void main(String[] args) {
@@ -257,4 +257,4 @@ public static void main(String[] args) {
.addFlags("-XX:UseSVE=0")
.start();
}
-}
\ No newline at end of file
+}
diff --git a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java
index eda803b3f35..36a140c474a 100644
--- a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java
@@ -38,6 +38,7 @@
import jdk.incubator.vector.VectorMask;
import jdk.incubator.vector.VectorOperators;
import jdk.incubator.vector.Vector;
+import jdk.incubator.vector.VectorMath;
import jdk.incubator.vector.ByteVector;
@@ -962,6 +963,33 @@ static byte bits(byte e) {
})
);
+ static final List> BYTE_SATURATING_GENERATORS = List.of(
+ withToString("byte[Byte.MIN_VALUE]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MIN_VALUE));
+ }),
+ withToString("byte[Byte.MAX_VALUE]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MAX_VALUE));
+ }),
+ withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MAX_VALUE - 100));
+ }),
+ withToString("byte[Byte.MIN_VALUE + 100]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MIN_VALUE + 100));
+ }),
+ withToString("byte[-i * 5]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(-i * 5));
+ }),
+ withToString("byte[i * 5]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(i * 5));
+ })
+ );
+
// Create combinations of pairs
// @@@ Might be sensitive to order e.g. div by 0
static final List>> BYTE_GENERATOR_PAIRS =
@@ -969,6 +997,11 @@ static byte bits(byte e) {
flatMap(fa -> BYTE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
collect(Collectors.toList());
+ static final List>> BYTE_SATURATING_GENERATOR_PAIRS =
+ Stream.of(BYTE_GENERATORS.get(0)).
+ flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
+ collect(Collectors.toList());
+
@DataProvider
public Object[][] boolUnaryOpProvider() {
return BOOL_ARRAY_GENERATORS.stream().
@@ -999,12 +1032,27 @@ public Object[][] byteBinaryOpProvider() {
toArray(Object[][]::new);
}
+ @DataProvider
+ public Object[][] byteSaturatingBinaryOpProvider() {
+ return BYTE_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
+ toArray(Object[][]::new);
+ }
+
@DataProvider
public Object[][] byteIndexedOpProvider() {
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
toArray(Object[][]::new);
}
+ @DataProvider
+ public Object[][] byteSaturatingBinaryOpMaskProvider() {
+ return BOOLEAN_MASK_GENERATORS.stream().
+ flatMap(fm -> BYTE_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
+ return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
+ })).
+ toArray(Object[][]::new);
+ }
+
@DataProvider
public Object[][] byteBinaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@@ -2939,6 +2987,252 @@ static void maxByte128VectorTests(IntFunction fa, IntFunction fb
assertArraysEquals(r, a, b, Byte128VectorTests::max);
}
+ static byte UMIN(byte a, byte b) {
+ return (byte)(VectorMath.minUnsigned(a, b));
+ }
+
+ @Test(dataProvider = "byteBinaryOpProvider")
+ static void UMINByte128VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte128VectorTests::UMIN);
+ }
+
+ @Test(dataProvider = "byteBinaryOpMaskProvider")
+ static void UMINByte128VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte128VectorTests::UMIN);
+ }
+
+ static byte UMAX(byte a, byte b) {
+ return (byte)(VectorMath.maxUnsigned(a, b));
+ }
+
+ @Test(dataProvider = "byteBinaryOpProvider")
+ static void UMAXByte128VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte128VectorTests::UMAX);
+ }
+
+ @Test(dataProvider = "byteBinaryOpMaskProvider")
+ static void UMAXByte128VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte128VectorTests::UMAX);
+ }
+
+ static byte SADD(byte a, byte b) {
+ return (byte)(VectorMath.addSaturating(a, b));
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpProvider")
+ static void SADDByte128VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte128VectorTests::SADD);
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
+ static void SADDByte128VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte128VectorTests::SADD);
+ }
+
+ static byte SSUB(byte a, byte b) {
+ return (byte)(VectorMath.subSaturating(a, b));
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpProvider")
+ static void SSUBByte128VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte128VectorTests::SSUB);
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
+ static void SSUBByte128VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte128VectorTests::SSUB);
+ }
+
+ static byte SUADD(byte a, byte b) {
+ return (byte)(VectorMath.addSaturatingUnsigned(a, b));
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpProvider")
+ static void SUADDByte128VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte128VectorTests::SUADD);
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
+ static void SUADDByte128VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte128VectorTests::SUADD);
+ }
+
+ static byte SUSUB(byte a, byte b) {
+ return (byte)(VectorMath.subSaturatingUnsigned(a, b));
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpProvider")
+ static void SUSUBByte128VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte128VectorTests::SUSUB);
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
+ static void SUSUBByte128VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte128VectorTests::SUSUB);
+ }
+
@Test(dataProvider = "byteBinaryOpProvider")
static void MINByte128VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) {
byte[] a = fa.apply(SPECIES.length());
@@ -4147,7 +4441,7 @@ static void GEByte128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) {
+ static void ULTByte128VectorTests(IntFunction fa, IntFunction fb) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4155,7 +4449,7 @@ static void UNSIGNED_LTByte128VectorTests(IntFunction fa, IntFunction mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
+ VectorMask mv = av.compare(VectorOperators.ULT, bv);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4166,7 +4460,7 @@ static void UNSIGNED_LTByte128VectorTests(IntFunction fa, IntFunction fa, IntFunction fb,
+ static void ULTByte128VectorTestsMasked(IntFunction fa, IntFunction fb,
IntFunction fm) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4178,7 +4472,7 @@ static void UNSIGNED_LTByte128VectorTestsMasked(IntFunction fa, IntFunct
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
- VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
+ VectorMask mv = av.compare(VectorOperators.ULT, bv, vmask);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4189,7 +4483,7 @@ static void UNSIGNED_LTByte128VectorTestsMasked(IntFunction fa, IntFunct
}
@Test(dataProvider = "byteCompareOpProvider")
- static void UNSIGNED_GTByte128VectorTests(IntFunction fa, IntFunction fb) {
+ static void UGTByte128VectorTests(IntFunction fa, IntFunction fb) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4197,7 +4491,7 @@ static void UNSIGNED_GTByte128VectorTests(IntFunction fa, IntFunction mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
+ VectorMask mv = av.compare(VectorOperators.UGT, bv);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4208,7 +4502,7 @@ static void UNSIGNED_GTByte128VectorTests(IntFunction fa, IntFunction fa, IntFunction fb,
+ static void UGTByte128VectorTestsMasked(IntFunction fa, IntFunction fb,
IntFunction fm) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4220,7 +4514,7 @@ static void UNSIGNED_GTByte128VectorTestsMasked(IntFunction fa, IntFunct
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
- VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
+ VectorMask mv = av.compare(VectorOperators.UGT, bv, vmask);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4231,7 +4525,7 @@ static void UNSIGNED_GTByte128VectorTestsMasked(IntFunction fa, IntFunct
}
@Test(dataProvider = "byteCompareOpProvider")
- static void UNSIGNED_LEByte128VectorTests(IntFunction fa, IntFunction fb) {
+ static void ULEByte128VectorTests(IntFunction fa, IntFunction fb) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4239,7 +4533,7 @@ static void UNSIGNED_LEByte128VectorTests(IntFunction fa, IntFunction mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
+ VectorMask mv = av.compare(VectorOperators.ULE, bv);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4250,7 +4544,7 @@ static void UNSIGNED_LEByte128VectorTests(IntFunction fa, IntFunction fa, IntFunction fb,
+ static void ULEByte128VectorTestsMasked(IntFunction fa, IntFunction fb,
IntFunction fm) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4262,7 +4556,7 @@ static void UNSIGNED_LEByte128VectorTestsMasked(IntFunction fa, IntFunct
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
- VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
+ VectorMask mv = av.compare(VectorOperators.ULE, bv, vmask);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4273,7 +4567,7 @@ static void UNSIGNED_LEByte128VectorTestsMasked(IntFunction fa, IntFunct
}
@Test(dataProvider = "byteCompareOpProvider")
- static void UNSIGNED_GEByte128VectorTests(IntFunction fa, IntFunction fb) {
+ static void UGEByte128VectorTests(IntFunction fa, IntFunction fb) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4281,7 +4575,7 @@ static void UNSIGNED_GEByte128VectorTests(IntFunction fa, IntFunction mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
+ VectorMask mv = av.compare(VectorOperators.UGE, bv);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4292,7 +4586,7 @@ static void UNSIGNED_GEByte128VectorTests(IntFunction fa, IntFunction fa, IntFunction fb,
+ static void UGEByte128VectorTestsMasked(IntFunction fa, IntFunction fb,
IntFunction fm) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4304,7 +4598,7 @@ static void UNSIGNED_GEByte128VectorTestsMasked(IntFunction fa, IntFunct
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
- VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
+ VectorMask mv = av.compare(VectorOperators.UGE, bv, vmask);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
diff --git a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java
index 06cc13c0b12..0ad567b5ee4 100644
--- a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java
@@ -38,6 +38,7 @@
import jdk.incubator.vector.VectorMask;
import jdk.incubator.vector.VectorOperators;
import jdk.incubator.vector.Vector;
+import jdk.incubator.vector.VectorMath;
import jdk.incubator.vector.ByteVector;
@@ -962,6 +963,33 @@ static byte bits(byte e) {
})
);
+ static final List> BYTE_SATURATING_GENERATORS = List.of(
+ withToString("byte[Byte.MIN_VALUE]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MIN_VALUE));
+ }),
+ withToString("byte[Byte.MAX_VALUE]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MAX_VALUE));
+ }),
+ withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MAX_VALUE - 100));
+ }),
+ withToString("byte[Byte.MIN_VALUE + 100]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MIN_VALUE + 100));
+ }),
+ withToString("byte[-i * 5]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(-i * 5));
+ }),
+ withToString("byte[i * 5]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(i * 5));
+ })
+ );
+
// Create combinations of pairs
// @@@ Might be sensitive to order e.g. div by 0
static final List>> BYTE_GENERATOR_PAIRS =
@@ -969,6 +997,11 @@ static byte bits(byte e) {
flatMap(fa -> BYTE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
collect(Collectors.toList());
+ static final List>> BYTE_SATURATING_GENERATOR_PAIRS =
+ Stream.of(BYTE_GENERATORS.get(0)).
+ flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
+ collect(Collectors.toList());
+
@DataProvider
public Object[][] boolUnaryOpProvider() {
return BOOL_ARRAY_GENERATORS.stream().
@@ -999,12 +1032,27 @@ public Object[][] byteBinaryOpProvider() {
toArray(Object[][]::new);
}
+ @DataProvider
+ public Object[][] byteSaturatingBinaryOpProvider() {
+ return BYTE_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
+ toArray(Object[][]::new);
+ }
+
@DataProvider
public Object[][] byteIndexedOpProvider() {
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
toArray(Object[][]::new);
}
+ @DataProvider
+ public Object[][] byteSaturatingBinaryOpMaskProvider() {
+ return BOOLEAN_MASK_GENERATORS.stream().
+ flatMap(fm -> BYTE_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
+ return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
+ })).
+ toArray(Object[][]::new);
+ }
+
@DataProvider
public Object[][] byteBinaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@@ -2939,6 +2987,252 @@ static void maxByte256VectorTests(IntFunction fa, IntFunction fb
assertArraysEquals(r, a, b, Byte256VectorTests::max);
}
+ static byte UMIN(byte a, byte b) {
+ return (byte)(VectorMath.minUnsigned(a, b));
+ }
+
+ @Test(dataProvider = "byteBinaryOpProvider")
+ static void UMINByte256VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte256VectorTests::UMIN);
+ }
+
+ @Test(dataProvider = "byteBinaryOpMaskProvider")
+ static void UMINByte256VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte256VectorTests::UMIN);
+ }
+
+ static byte UMAX(byte a, byte b) {
+ return (byte)(VectorMath.maxUnsigned(a, b));
+ }
+
+ @Test(dataProvider = "byteBinaryOpProvider")
+ static void UMAXByte256VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte256VectorTests::UMAX);
+ }
+
+ @Test(dataProvider = "byteBinaryOpMaskProvider")
+ static void UMAXByte256VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte256VectorTests::UMAX);
+ }
+
+ static byte SADD(byte a, byte b) {
+ return (byte)(VectorMath.addSaturating(a, b));
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpProvider")
+ static void SADDByte256VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte256VectorTests::SADD);
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
+ static void SADDByte256VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte256VectorTests::SADD);
+ }
+
+ static byte SSUB(byte a, byte b) {
+ return (byte)(VectorMath.subSaturating(a, b));
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpProvider")
+ static void SSUBByte256VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte256VectorTests::SSUB);
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
+ static void SSUBByte256VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte256VectorTests::SSUB);
+ }
+
+ static byte SUADD(byte a, byte b) {
+ return (byte)(VectorMath.addSaturatingUnsigned(a, b));
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpProvider")
+ static void SUADDByte256VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte256VectorTests::SUADD);
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
+ static void SUADDByte256VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte256VectorTests::SUADD);
+ }
+
+ static byte SUSUB(byte a, byte b) {
+ return (byte)(VectorMath.subSaturatingUnsigned(a, b));
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpProvider")
+ static void SUSUBByte256VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte256VectorTests::SUSUB);
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
+ static void SUSUBByte256VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte256VectorTests::SUSUB);
+ }
+
@Test(dataProvider = "byteBinaryOpProvider")
static void MINByte256VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) {
byte[] a = fa.apply(SPECIES.length());
@@ -4147,7 +4441,7 @@ static void GEByte256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) {
+ static void ULTByte256VectorTests(IntFunction fa, IntFunction fb) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4155,7 +4449,7 @@ static void UNSIGNED_LTByte256VectorTests(IntFunction fa, IntFunction mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
+ VectorMask mv = av.compare(VectorOperators.ULT, bv);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4166,7 +4460,7 @@ static void UNSIGNED_LTByte256VectorTests(IntFunction fa, IntFunction fa, IntFunction fb,
+ static void ULTByte256VectorTestsMasked(IntFunction fa, IntFunction fb,
IntFunction fm) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4178,7 +4472,7 @@ static void UNSIGNED_LTByte256VectorTestsMasked(IntFunction fa, IntFunct
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
- VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
+ VectorMask mv = av.compare(VectorOperators.ULT, bv, vmask);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4189,7 +4483,7 @@ static void UNSIGNED_LTByte256VectorTestsMasked(IntFunction fa, IntFunct
}
@Test(dataProvider = "byteCompareOpProvider")
- static void UNSIGNED_GTByte256VectorTests(IntFunction fa, IntFunction fb) {
+ static void UGTByte256VectorTests(IntFunction fa, IntFunction fb) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4197,7 +4491,7 @@ static void UNSIGNED_GTByte256VectorTests(IntFunction fa, IntFunction mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
+ VectorMask mv = av.compare(VectorOperators.UGT, bv);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4208,7 +4502,7 @@ static void UNSIGNED_GTByte256VectorTests(IntFunction fa, IntFunction fa, IntFunction fb,
+ static void UGTByte256VectorTestsMasked(IntFunction fa, IntFunction fb,
IntFunction fm) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4220,7 +4514,7 @@ static void UNSIGNED_GTByte256VectorTestsMasked(IntFunction fa, IntFunct
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
- VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
+ VectorMask mv = av.compare(VectorOperators.UGT, bv, vmask);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4231,7 +4525,7 @@ static void UNSIGNED_GTByte256VectorTestsMasked(IntFunction fa, IntFunct
}
@Test(dataProvider = "byteCompareOpProvider")
- static void UNSIGNED_LEByte256VectorTests(IntFunction fa, IntFunction fb) {
+ static void ULEByte256VectorTests(IntFunction fa, IntFunction fb) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4239,7 +4533,7 @@ static void UNSIGNED_LEByte256VectorTests(IntFunction fa, IntFunction mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
+ VectorMask mv = av.compare(VectorOperators.ULE, bv);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4250,7 +4544,7 @@ static void UNSIGNED_LEByte256VectorTests(IntFunction fa, IntFunction fa, IntFunction fb,
+ static void ULEByte256VectorTestsMasked(IntFunction fa, IntFunction fb,
IntFunction fm) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4262,7 +4556,7 @@ static void UNSIGNED_LEByte256VectorTestsMasked(IntFunction fa, IntFunct
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
- VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
+ VectorMask mv = av.compare(VectorOperators.ULE, bv, vmask);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4273,7 +4567,7 @@ static void UNSIGNED_LEByte256VectorTestsMasked(IntFunction fa, IntFunct
}
@Test(dataProvider = "byteCompareOpProvider")
- static void UNSIGNED_GEByte256VectorTests(IntFunction fa, IntFunction fb) {
+ static void UGEByte256VectorTests(IntFunction fa, IntFunction fb) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4281,7 +4575,7 @@ static void UNSIGNED_GEByte256VectorTests(IntFunction fa, IntFunction mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
+ VectorMask mv = av.compare(VectorOperators.UGE, bv);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
@@ -4292,7 +4586,7 @@ static void UNSIGNED_GEByte256VectorTests(IntFunction fa, IntFunction fa, IntFunction fb,
+ static void UGEByte256VectorTestsMasked(IntFunction fa, IntFunction fb,
IntFunction fm) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
@@ -4304,7 +4598,7 @@ static void UNSIGNED_GEByte256VectorTestsMasked(IntFunction fa, IntFunct
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
- VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
+ VectorMask mv = av.compare(VectorOperators.UGE, bv, vmask);
// Check results as part of computation.
for (int j = 0; j < SPECIES.length(); j++) {
diff --git a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java
index a75aa42ef20..0edc66dfccc 100644
--- a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java
@@ -38,6 +38,7 @@
import jdk.incubator.vector.VectorMask;
import jdk.incubator.vector.VectorOperators;
import jdk.incubator.vector.Vector;
+import jdk.incubator.vector.VectorMath;
import jdk.incubator.vector.ByteVector;
@@ -962,6 +963,33 @@ static byte bits(byte e) {
})
);
+ static final List> BYTE_SATURATING_GENERATORS = List.of(
+ withToString("byte[Byte.MIN_VALUE]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MIN_VALUE));
+ }),
+ withToString("byte[Byte.MAX_VALUE]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MAX_VALUE));
+ }),
+ withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MAX_VALUE - 100));
+ }),
+ withToString("byte[Byte.MIN_VALUE + 100]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(Byte.MIN_VALUE + 100));
+ }),
+ withToString("byte[-i * 5]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(-i * 5));
+ }),
+ withToString("byte[i * 5]", (int s) -> {
+ return fill(s * BUFFER_REPS,
+ i -> (byte)(i * 5));
+ })
+ );
+
// Create combinations of pairs
// @@@ Might be sensitive to order e.g. div by 0
static final List>> BYTE_GENERATOR_PAIRS =
@@ -969,6 +997,11 @@ static byte bits(byte e) {
flatMap(fa -> BYTE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
collect(Collectors.toList());
+ static final List>> BYTE_SATURATING_GENERATOR_PAIRS =
+ Stream.of(BYTE_GENERATORS.get(0)).
+ flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
+ collect(Collectors.toList());
+
@DataProvider
public Object[][] boolUnaryOpProvider() {
return BOOL_ARRAY_GENERATORS.stream().
@@ -999,12 +1032,27 @@ public Object[][] byteBinaryOpProvider() {
toArray(Object[][]::new);
}
+ @DataProvider
+ public Object[][] byteSaturatingBinaryOpProvider() {
+ return BYTE_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
+ toArray(Object[][]::new);
+ }
+
@DataProvider
public Object[][] byteIndexedOpProvider() {
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
toArray(Object[][]::new);
}
+ @DataProvider
+ public Object[][] byteSaturatingBinaryOpMaskProvider() {
+ return BOOLEAN_MASK_GENERATORS.stream().
+ flatMap(fm -> BYTE_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
+ return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
+ })).
+ toArray(Object[][]::new);
+ }
+
@DataProvider
public Object[][] byteBinaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@@ -2939,6 +2987,252 @@ static void maxByte512VectorTests(IntFunction fa, IntFunction fb
assertArraysEquals(r, a, b, Byte512VectorTests::max);
}
+ static byte UMIN(byte a, byte b) {
+ return (byte)(VectorMath.minUnsigned(a, b));
+ }
+
+ @Test(dataProvider = "byteBinaryOpProvider")
+ static void UMINByte512VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte512VectorTests::UMIN);
+ }
+
+ @Test(dataProvider = "byteBinaryOpMaskProvider")
+ static void UMINByte512VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte512VectorTests::UMIN);
+ }
+
+ static byte UMAX(byte a, byte b) {
+ return (byte)(VectorMath.maxUnsigned(a, b));
+ }
+
+ @Test(dataProvider = "byteBinaryOpProvider")
+ static void UMAXByte512VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte512VectorTests::UMAX);
+ }
+
+ @Test(dataProvider = "byteBinaryOpMaskProvider")
+ static void UMAXByte512VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction fm) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+ boolean[] mask = fm.apply(SPECIES.length());
+ VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0);
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, mask, Byte512VectorTests::UMAX);
+ }
+
+ static byte SADD(byte a, byte b) {
+ return (byte)(VectorMath.addSaturating(a, b));
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpProvider")
+ static void SADDByte512VectorTests(IntFunction fa, IntFunction fb) {
+ byte[] a = fa.apply(SPECIES.length());
+ byte[] b = fb.apply(SPECIES.length());
+ byte[] r = fr.apply(SPECIES.length());
+
+ for (int ic = 0; ic < INVOC_COUNT; ic++) {
+ for (int i = 0; i < a.length; i += SPECIES.length()) {
+ ByteVector av = ByteVector.fromArray(SPECIES, a, i);
+ ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
+ av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
+ }
+ }
+
+ assertArraysEquals(r, a, b, Byte512VectorTests::SADD);
+ }
+
+ @Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
+ static void SADDByte512VectorTestsMasked(IntFunction fa, IntFunction fb,
+ IntFunction