Compare commits

...

34 Commits

Author SHA1 Message Date
Andrew Hughes
34f6172404 Sync the copy of the portable specfile with the latest update
Related: RHEL-235627
2026-08-23 13:55:53 +01:00
Andrew Hughes
a36c6aeb52 Sync the copy of the portable specfile with the latest update
Related: RHEL-235627
2026-08-12 23:38:40 +01:00
Andrew Hughes
78fdbbb4a5 Update to jdk-25.0.4.1+1 (GA)
- Update release notes to 25.0.4.1+1
- Report pkgos value during build

** This tarball is embargoed until 2026-08-18 @ 1pm PT. **

Resolves: RHEL-235627
2026-08-12 23:37:36 +01:00
Andrew Hughes
7c973acb0b Sync the copy of the portable specfile with the latest update
Related: RHEL-188883
2026-07-29 11:47:09 +01:00
Andrew Hughes
73bef61a3b Add CVEs to NEWS file
- Update to tarball with final changeset ID

Related: RHEL-188883
2026-07-29 11:45:35 +01:00
Andrew Hughes
963e0071dd Sync the copy of the portable specfile with the latest update
Related: RHEL-188883
Related: RHEL-212296
2026-07-17 23:36:42 +01:00
Andrew Hughes
88cb1b4ccc Make zone string debug output optional in TestTranslations
Resolves: RHEL-212296
2026-07-17 23:31:31 +01:00
Andrew Hughes
a9e65481d5 Simplify TestTranslations run now there is only the CLDR provider and one set of data (JDK-8174269)
Related: RHEL-188883
2026-07-17 23:26:07 +01:00
Andrew Hughes
d58af87d52 Revert fr_FR and de_DE changes made in d43f0e6186370fdeb0ca2f3594f39783e20eef1c now JDK-8382020 is fixed
Related: RHEL-188883
2026-07-17 23:25:31 +01:00
Andrew Hughes
1860b311ee Obsolete old RHEL releases (9.7.0-z, 10.1-z)
Resolves: RHEL-212294
2026-07-17 23:23:20 +01:00
Andrew Hughes
c6cc2f0044 Update to jdk-25.0.4+7 (GA)
- Update release notes to 25.0.4+7
- Bump freetype version to 2.14.3 following JDK-8385390
- Bump giflib version to 6.1.3 following JDK-8384902
- Bump HarfBuzz version to 14.2.0 following JDK-8385490
- Bump lcms2 version to 2.19.1 following JDK-8375065 & JDK-8383354
- Bump libpng version to 1.6.58 following JDK-8384495
- Require tzdata 2026b due to upstream inclusion of JDK-8383175
- Drop local copy of JDK-8375294 EOPNOTSUPP patch

** This tarball is embargoed until 2026-07-21 @ 1pm PT. **

Resolves: RHEL-188883
2026-07-17 23:21:34 +01:00
Andrew Hughes
a8272180a4 Sync the copy of the portable specfile with the latest update
Related: RHEL-150977
Related: RHEL-210972
Related: RHEL-210993
2026-07-15 15:02:24 +01:00
Andrew Hughes
4fa0394a1a Add 25u backports of JDK-8347901 & JDK-8378713 C2 performance fixes
Resolves: RHEL-210993
2026-07-15 14:45:51 +01:00
Andrew Hughes
6fe56ef268 Specify portablerelease and rpmrelease (always 0 for portables) in the Release field
Resolves: RHEL-210972
2026-07-15 14:45:22 +01:00
Andrew Hughes
a4048c8693 Move version information and core NVR definitions back towards the top of the file
Related: RHEL-210972
2026-07-15 13:37:58 +01:00
Andrew Hughes
f8659abd07 Remove macro references in comments where possible (%dnl not compatible enough yet)
- After discussion with fitzsim, it is easier and more compatible
- to rewrite (or just plain drop in the case of the %patch examples)
- macros in comments.  There doesn't seem to be a way to detect the
- presence of %dnl on older RPM versions, so we can't use it until
- we are only working on RHEL >= 9.

- While it works fine locally, attempting to build on CentOS 9 causes
- the srpm stage to fail with:
- error: /builddir/build/SPECS/java-25-openjdk.spec: line 3: %dnl: unexpected argument

Resolves: RHEL-150977
2026-07-14 23:44:44 +01:00
Andrew Hughes
bc0c9a72cb Cleanup tagging and gating scripts to appease shellcheck:
* scripts/builds/build_vanilla.sh: Use an array to handle the varying arguments to rhpkg.
* scripts/builds/check_signatures.sh: Quote variable usage.
* scripts/builds/waive_issue.sh: Remove redundant 'test "x"' usage.
* scripts/builds/waive_leapp_issue.sh: Likewise.
* scripts/builds/waive_rpminspect.sh: Likewise.
* scripts/builds/waive_usual_rpminspect.sh: Likewise and add missing WORKING_DIR variable.
* scripts/builds/waive_usual_tier0.sh: Remove redundant 'test "x"' usage.

Related: RHEL-155327
Related: RHEL-155339
2026-07-14 23:18:20 +01:00
Andrew Hughes
f2aac50928 Sync the copy of the portable specfile with the latest update
Related: RHEL-169620
Related: RHEL-157091
Related: RHEL-161217
Related: RHEL-161333
Related: RHEL-169613
2026-04-20 22:25:46 +01:00
Andrew Hughes
4e62176a93 Add JDK-8375294 EOPNOTSUPP patch ahead of 25.0.4
Resolves: RHEL-169613
2026-04-20 22:25:38 +01:00
Andrew Hughes
04075977d1 Update to jdk-25.0.3+9 (GA)
- Update release notes to 25.0.3+9
- Update FIPS patch to 57722aab802 version synced with 25.0.3+8
- Drop local libpng patches now JDK-8372534, JDK-8375063 & JDK-8377526 are included upstream
- Drop local HarfBuzz patch now JDK-8375057 is included upstream
- Bump freetype version to 2.14.2 following JDK-8373290 & JDK-8379158
- Bump giflib version to 6.1.2 following JDK-8379256 & JDK-8380078
- Bump libpng version to 1.6.57 following JDK-8380959 & JDK-8382047
- Bump zlib version to 1.3.2 following JDK-8378631
- Bump tzdata version to 2026a following JDK-8379035

** This tarball is embargoed until 2026-04-21 @ 1pm PT. **

Resolves: RHEL-169620
Resolves: RHEL-157091
Resolves: RHEL-161217
Resolves: RHEL-161333
2026-04-20 22:25:01 +01:00
Andrew Hughes
be99dd1d42 Sync the copy of the portable specfile with the latest update
Related: RHEL-155000
Related: RHEL-146649
Related: RHEL-148327
Related: RHEL-148830
2026-03-12 02:28:03 +00:00
Andrew Hughes
a95cdd67f4 Add gating scripts to simplify obtaining results and waiving issues
Resolves: RHEL-155339
2026-03-12 02:24:56 +00:00
Andrew Hughes
fde787d90e Update tagged versions to include 9.8.0-z, 9.9.0, 10.2-z & 10.3.
Resolves: RHEL-155337
2026-03-12 02:22:43 +00:00
Andrew Hughes
68b316d15b Add tagging scripts with signature checks and gating handling
Resolves: RHEL-147634
2026-03-12 02:22:14 +00:00
Thomas Fitzsimmons
3b28f41666 rpminspect.yaml: Disable abidiff inspection
- Avoid out-of-memory on the CentOS test farm:
- See: https://docs.testing-farm.io/Testing%20Farm/0.1/errors.html#TFE-1

Resolves: RHEL-150976
2026-03-11 10:07:54 +00:00
Andrew Hughes
5ce4c845bd Bump nssadapter version to bring in shared PKCS11 session fix
- Drop LDFLAGS nssadapter patch which is now upstream in 0.1.1

Resolves: RHEL-155044
2026-03-11 10:07:39 +00:00
Andrew Hughes
b1b2f62915 Include backports of libpng & harfbuzz updates ahead of 25.0.3
- Add JDK-8375063 libpng 1.6.54 ahead of 25.0.3
- Add JDK-8375057 harfbuzz 12.3.2 ahead of 25.0.3
- Add JDK-8377526 libpng 1.6.55 ahead of 25.0.3
- Bump libpng version to 1.6.55 following JDK-8375063 & JDK-8377526
- Bump harfbuzz version to 12.3.2 following JDK-8375057

Resolves: RHEL-146649
Resolves: RHEL-148327
Resolves: RHEL-148830
2026-03-11 08:56:21 +00:00
Andrew Hughes
b87969b5b6 Update FIPS patch to e55ada9353e to include the fix for the too restrictive provider lockdown
- Fix FIPS issue list to represent the new 25u version

Resolves: RHEL-155000
2026-03-11 07:34:09 +00:00
Andrew Hughes
1b0015ae51 Bump rpmrelease for CentOS build
Related: RHEL-139579
Related: RHEL-131430
Related: RHEL-131443
Related: RHEL-142855
Related: RHEL-142799
2026-02-18 00:14:37 +00:00
Andrew Hughes
3b11e4f0b9 Sync the copy of the portable specfile with the latest update
Related: RHEL-139579
Related: RHEL-131430
Related: RHEL-131443
2026-01-21 02:04:43 +00:00
Andrew Hughes
e9f1748580 Handle 'upgrade' as an alternative to 'update' in openjdk_news.sh
Resolves: RHEL-142799
2026-01-21 01:44:51 +00:00
Andrew Hughes
baaa3c2085 Test for java.security's existence in create-redhat-properties-files.bash
- Execute create-redhat-properties-files.bash with '-e' to exit on failure

Resolves: RHEL-142855
2026-01-21 01:36:53 +00:00
Andrew Hughes
979b722d77 Add JDK-8372534 libpng 1.6.51 ahead of 25.0.3
- Bump libpng version to 1.6.51 following JDK-8372534
- Bump ID of NSS adapter patch so we can stay in sync with portable on the libpng patch

Resolves: RHEL-131430
Resolves: RHEL-131443
2026-01-20 22:44:13 +00:00
Andrew Hughes
603ebefa46 Update to jdk-25.0.2+10 (GA)
- Update release notes to 25.0.2+10

** This tarball is embargoed until 2026-01-20 @ 1pm PT. **

Resolves: RHEL-139579
2026-01-20 20:46:19 +00:00
27 changed files with 4112 additions and 538 deletions

5
.gitignore vendored
View File

@ -44,3 +44,8 @@
/openjdk-25+36.tar.xz
/openjdk-25.0.1+8.tar.xz
/nssadapter-0.1.0.tar.xz
/openjdk-25.0.2+10.tar.xz
/nssadapter-0.1.1.tar.xz
/openjdk-25.0.3+9.tar.xz
/openjdk-25.0.4+7.tar.xz
/openjdk-25.0.4.1+1.tar.xz

1216
NEWS

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* TestTranslations -- Ensure translations are available for new timezones
Copyright (C) 2022 Red Hat, Inc.
Copyright (C) 2026 Red Hat, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -50,25 +50,38 @@ public class TestTranslations {
"Mountain Daylight Time", "MDT", "MDT",
"Mountain Time", "MT", "MT"});
map.put(Locale.FRANCE, new String[] { "heure normale des Rocheuses", "UTC\u221207:00", "MST",
"heure d\u2019\u00e9t\u00e9 des Rocheuses", "UTC\u221206:00", "MST",
"heure des Rocheuses", "UTC\u221207:00", "MST"});
"heure d\u2019\u00e9t\u00e9 des Rocheuses", "UTC\u221206:00", "MDT",
"heure des Rocheuses", "UTC\u221207:00", "MT"});
map.put(Locale.GERMANY, new String[] { "Rocky-Mountains-Normalzeit", "GMT-07:00", "MST",
"Rocky-Mountains-Sommerzeit", "GMT-06:00", "MST",
"Rocky-Mountains-Zeit", "GMT-07:00", "MST"});
"Rocky-Mountains-Sommerzeit", "GMT-06:00", "MDT",
"Rocky-Mountains-Zeit", "GMT-07:00", "MT"});
CIUDAD_JUAREZ = Collections.unmodifiableMap(map);
}
public static void main(String[] args) {
if (args.length < 1) {
System.err.println("Test must be started with the name of the locale provider.");
System.exit(1);
boolean debug = false;
if (args.length > 0) {
debug = Boolean.parseBoolean(args[0]);
}
System.err.printf("Debugging: %s\n", debug);
testZoneStrings(debug);
testZone(KYIV,
new String[] { "Europe/Kiev", "Europe/Kyiv", "Europe/Uzhgorod", "Europe/Zaporozhye" });
testZone(CIUDAD_JUAREZ,
new String[] { "America/Cambridge_Bay", "America/Ciudad_Juarez" });
}
private static void testZoneStrings(final boolean debug) {
System.out.println("Checking sanity of full zone string set...");
boolean invalid = Arrays.stream(Locale.getAvailableLocales())
.peek(l -> System.out.println("Locale: " + l))
.peek(l -> System.out.printf(debug ? "Locale: %s\n" : "", l))
.map(l -> DateFormatSymbols.getInstance(l).getZoneStrings())
.peek(df -> System.out.printf(debug ? "Zone string size: %s\n" : "", df.length))
.flatMap(zs -> Arrays.stream(zs))
.flatMap(names -> Arrays.stream(names))
.filter(name -> Objects.isNull(name) || name.isEmpty())
@ -78,15 +91,9 @@ public class TestTranslations {
System.err.println("Zone string for a locale returned null or empty string");
System.exit(2);
}
String localeProvider = args[0];
testZone(localeProvider, KYIV,
new String[] { "Europe/Kiev", "Europe/Kyiv", "Europe/Uzhgorod", "Europe/Zaporozhye" });
testZone(localeProvider, CIUDAD_JUAREZ,
new String[] { "America/Cambridge_Bay", "America/Ciudad_Juarez" });
}
private static void testZone(String localeProvider, Map<Locale,String[]> exp, String[] ids) {
private static void testZone(Map<Locale,String[]> exp, String[] ids) {
for (Locale l : exp.keySet()) {
String[] expected = exp.get(l);
System.out.printf("Expected values for %s are %s\n", l, Arrays.toString(expected));
@ -97,16 +104,11 @@ public class TestTranslations {
System.out.printf("Checking locale %s for %s...\n", l, id);
if ("JRE".equals(localeProvider) || "CLDR".equals(localeProvider)) {
expectedShortStd = expected[2];
expectedShortDST = expected[5];
expectedShortGen = expected[8];
} else {
System.err.printf("Invalid locale provider %s\n", localeProvider);
System.exit(3);
}
System.out.printf("Locale Provider is %s, using short values %s, %s and %s\n",
localeProvider, expectedShortStd, expectedShortDST, expectedShortGen);
expectedShortStd = expected[2];
expectedShortDST = expected[5];
expectedShortGen = expected[8];
System.out.printf("Using short values %s, %s and %s\n",
expectedShortStd, expectedShortDST, expectedShortGen);
String longStd = TimeZone.getTimeZone(id).getDisplayName(false, TimeZone.LONG, l);
String shortStd = TimeZone.getTimeZone(id).getDisplayName(false, TimeZone.SHORT, l);

View File

@ -109,6 +109,8 @@ security.provider.8=
keystore.type=pkcs12
EOF
# Make sure java.security exists before appending
test -e "${SECURITY}"/java.security || ( echo "${SECURITY}/java.security not found" && false )
cat >> "${SECURITY}"/java.security <<'EOF'
#

View File

@ -1,8 +1,8 @@
diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java
index de2845fb550..b1e416b90f4 100644
index de2845fb550..60eeab678ca 100644
--- a/src/java.base/share/classes/java/security/Provider.java
+++ b/src/java.base/share/classes/java/security/Provider.java
@@ -1203,6 +1203,39 @@ public Set<Service> getServices() {
@@ -1203,6 +1203,34 @@ public Set<Service> getServices() {
return serviceSet;
}
@ -10,9 +10,7 @@ index de2845fb550..b1e416b90f4 100644
+ private static final class RedHatFIPSFilter {
+ static final boolean IS_ON = Boolean.parseBoolean(
+ Security.getProperty("__redhat_fips_filter__"));
+ private static final Set<String> ANY_SERVICE_TYPE = Set.of();
+ private static final Map<String, Set<String>> ALLOW_LIST = Map.of(
+ "SunPKCS11-FIPS", ANY_SERVICE_TYPE,
+ "SUN", Set.of(
+ "AlgorithmParameterGenerator",
+ "AlgorithmParameters", "CertificateFactory",
@ -20,21 +18,18 @@ index de2845fb550..b1e416b90f4 100644
+ "Configuration", "KeyStore"),
+ "SunEC", Set.of(
+ "AlgorithmParameters", "KeyFactory"),
+ "SunJSSE", ANY_SERVICE_TYPE,
+ "SunJCE", Set.of(
+ "AlgorithmParameters",
+ "AlgorithmParameterGenerator", "KeyFactory",
+ "SecretKeyFactory"),
+ "SunRsaSign", Set.of(
+ "KeyFactory", "AlgorithmParameters"),
+ "XMLDSig", ANY_SERVICE_TYPE
+ "KeyFactory", "AlgorithmParameters")
+ );
+
+ static boolean isAllowed(String provName, String serviceType) {
+ Set<String> allowedServiceTypes = ALLOW_LIST.get(provName);
+ return allowedServiceTypes != null &&
+ (allowedServiceTypes == ANY_SERVICE_TYPE ||
+ allowedServiceTypes.contains(serviceType));
+ return allowedServiceTypes == null ||
+ allowedServiceTypes.contains(serviceType);
+ }
+ }
+ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
@ -42,7 +37,7 @@ index de2845fb550..b1e416b90f4 100644
/**
* Add a service. If a service of the same type with the same algorithm
* name exists, and it was added using {@link #putService putService()},
@@ -1231,6 +1264,15 @@ protected void putService(Service s) {
@@ -1231,6 +1259,15 @@ protected void putService(Service s) {
("service.getProvider() must match this Provider object");
}
String type = s.getType();

View File

@ -1,4 +1,105 @@
# debug_package %%{nil} is portable-jdks specific
# New Version-String scheme-style defines
%global featurever 25
%global interimver 0
%global updatever 4
%global patchver 1
%global buildver 1
%global portablerelease 2
%global rpmrelease 0
# Define IcedTea version used for SystemTap tapsets and desktop file
%global icedteaver 6.0.0pre00-c848b93a8598
# Define current Git revision for the FIPS support patches
%global fipsver 57722aab802
# Define JDK versions
%global newjavaver %{featurever}.%{interimver}.%{updatever}.%{patchver}
%global javaver %{featurever}
# Strip up to 6 trailing zeros in newjavaver, as the JDK does, to get the correct version used in filenames
%global filever %(svn=%{newjavaver}; for i in 1 2 3 4 5 6 ; do svn=${svn%%.0} ; done; echo ${svn})
# The tag used to create the OpenJDK tarball
%global vcstag jdk-%{filever}+%{buildver}%{?tagsuffix:-%{tagsuffix}}
# Standard JPackage naming and versioning defines
%global origin openjdk
%global origin_nice OpenJDK
%global top_level_dir_name %{vcstag}
%global top_level_dir_name_backup %{top_level_dir_name}-backup
# Define an optional suffix for the OS this package is built on
# The portable package is intended to be built on either RHEL 8
# or CentOS Stream 9; any other OS will automatically get an
# appropriate suffix
%global rhel_buildos 8
%global centos_buildos 9
%if 0%{?centos} == 0 && 0%{?rhel} != 0%{rhel_buildos}
%global pkgos rhel%{?rhel}
%endif
%if 0%{?centos} != 0 && 0%{?centos} != 0%{centos_buildos}
%global pkgos rhel%{?centos}
%endif
# Define milestone (EA for pre-releases, GA for releases)
# Release will be (where N is usually a number starting at 1):
# - 0.N.ea<dist> for EA releases,
# - N<dist> for GA releases
%global is_ga 1
%if %{is_ga}
%global build_type GA
%global ea_designator ""
%global ea_designator_zip %{nil}
%global extraver %{nil}
%global eaprefix %{nil}
%else
%global build_type EA
%global ea_designator ea
%global ea_designator_zip -%{ea_designator}
%global extraver .%{ea_designator}
%global eaprefix 0.
%endif
%global compatiblename java-%{javaver}-%{origin}
Name: %{compatiblename}-portable%{?pkgos:-%{pkgos}}
Version: %{newjavaver}.%{buildver}
Release: %{?eaprefix}%{portablerelease}.%{rpmrelease}%{?extraver}%{?dist}
%global fullversion %{compatiblename}-%{version}-%{release}
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
# also included the epoch in their virtual provides. This created a
# situation where in-the-wild java-1.5.0-ibm packages provided "java =
# 1:1.5.0". In RPM terms, "1.6.0 < 1:1.5.0" since 1.6.0 is
# interpreted as 0:1.6.0. So the "java >= 1.6.0" requirement would be
# satisfied by the 1:1.5.0 packages. Thus we need to set the epoch in
# JDK package >= 1.6.0 to 1, and packages referring to JDK virtual
# provides >= 1.6.0 must specify the epoch, "java >= 1:1.6.0".
Epoch: 1
Summary: %{origin_nice} %{featurever} Runtime Environment portable edition
# Groups are only used up to RHEL 8 and on Fedora versions prior to F30
%if (0%{?rhel} > 0 && 0%{?rhel} <= 8) || (0%{?fedora} >= 0 && 0%{?fedora} < 30)
Group: Development/Languages
%endif
# HotSpot code is licensed under GPLv2
# JDK library code is licensed under GPLv2 with the Classpath exception
# The Apache license is used in code taken from Apache projects (primarily xalan & xerces)
# DOM levels 2 & 3 and the XML digital signature schemas are licensed under the W3C Software License
# The JSR166 concurrency code is in the public domain
# The BSD and MIT licenses are used for a number of third-party libraries (see ADDITIONAL_LICENSE_INFO)
# The OpenJDK source tree includes:
# - JPEG library (IJG), zlib & libpng (zlib), giflib (MIT), harfbuzz (ISC),
# - freetype (FTL), jline (BSD) and LCMS (MIT)
# - jquery (MIT), jdk.crypto.cryptoki PKCS 11 wrapper (RSA)
# - public_suffix_list.dat from publicsuffix.org (MPLv2.0)
# The test code includes copies of NSS under the Mozilla Public License v2.0
# The PCSClite headers are under a BSD with advertising license
# The elliptic curve cryptography (ECC) source code is licensed under the LGPLv2.1 or any later version
License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib and ISC and FTL and RSA
URL: http://openjdk.java.net/
# We are producing RPMs containing only tarballs
# and checksums so there are no binaries outside
# the tarballs to be processed for debuginfo
%define debug_package %{nil}
# RPM conditionals so as to be able to dynamically produce
@ -96,25 +197,6 @@
%global normal_build %{nil}
%endif
# We have hardcoded list of files, which is appearing in alternatives, and in files
# in alternatives those are slaves and master, very often triplicated by man pages
# in files all masters and slaves are ghosted
# the ghosts are here to allow installation via query like `dnf install /usr/bin/java`
# you can list those files, with appropriate sections: cat *.spec | grep -e --install -e --slave -e post_
# TODO - fix those hardcoded lists via single list
# Those files must *NOT* be ghosted for *slowdebug* packages
# FIXME - if you are moving jshell or jlink or similar, always modify all three sections
# you can check via headless and devels:
# rpm -ql --noghost java-11-openjdk-headless-11.0.1.13-8.fc29.x86_64.rpm | grep bin
# == rpm -ql java-11-openjdk-headless-slowdebug-11.0.1.13-8.fc29.x86_64.rpm | grep bin
# != rpm -ql java-11-openjdk-headless-11.0.1.13-8.fc29.x86_64.rpm | grep bin
# similarly for other %%{_jvmdir}/{jre,java} and %%{_javadocdir}/{java,java-zip}
%define is_release_build() %( if [ "%{?1}" == "%{debug_suffix_unquoted}" -o "%{?1}" == "%{fastdebug_suffix_unquoted}" ]; then echo "0" ; else echo "1"; fi )
# while JDK is a techpreview(is_system_jdk=0), some provides are turned off. Once jdk stops to be an techpreview, move it to 1
# as sytem JDK, we mean any JDK which can run whole system java stack without issues (like bytecode issues, module issues, dependencies...)
%global is_system_jdk 0
%global aarch64 aarch64 arm64 armv8
# we need to distinguish between big and little endian PPC64
%global ppc64le ppc64le
@ -161,7 +243,7 @@
# Set of architectures for which we have a devkit
# Only used on RHEL
%if 0%{?centos} == 0
%global devkit_arches %{aarch64} %{ppc64le} riscv64 s390x x86_64
%global devkit_arches %{aarch64} %{ppc64le} s390x x86_64
%endif
# By default, we build a slowdebug build during main build on JIT architectures
@ -333,17 +415,14 @@
%global with_systemtap 0
%endif
# New Version-String scheme-style defines
%global featurever 25
%global interimver 0
%global updatever 1
%global patchver 0
# buildjdkver is usually same as %%{featurever},
# but in time of bootstrap of next jdk, it is featurever-1,
# buildjdkver is usually same as featurever,
# but at the time of bootstrap of the next jdk, it is featurever-1,
# and this it is better to change it here, on single place
%global buildjdkver %{featurever}
# We don't add any LTS designator for STS packages (Fedora and EPEL).
# We need to explicitly exclude EPEL as it would have the %%{rhel} macro defined.
# We need to explicitly exclude EPEL as it has the rhel macro defined.
%if 0%{?rhel} && !0%{?epel}
%global lts_designator "LTS"
%global lts_designator_zip -%{lts_designator}
@ -355,7 +434,8 @@
# Define vendor information used by OpenJDK
%global oj_vendor Red Hat, Inc.
%global oj_vendor_url https://www.redhat.com/
# Define what url should JVM offer in case of a crash report
# Define what url the JVM should offer in case of a crash report
# order may be important, epel may have rhel declared
%if 0%{?epel}
%global oj_vendor_bug_url https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora%20EPEL&component=%{name}&version=epel%{epel}
@ -371,67 +451,13 @@
%endif
%endif
%endif
%global oj_vendor_version (Red_Hat-%{version}-%{rpmrelease})
%global oj_vendor_version (Red_Hat-%{version}-%{portablerelease})
# Define IcedTea version used for SystemTap tapsets and desktop file
%global icedteaver 6.0.0pre00-c848b93a8598
# Define current Git revision for the FIPS support patches
%global fipsver df044414ef4
# Define JDK versions
%global newjavaver %{featurever}.%{interimver}.%{updatever}.%{patchver}
%global javaver %{featurever}
# Strip up to 6 trailing zeros in newjavaver, as the JDK does, to get the correct version used in filenames
%global filever %(svn=%{newjavaver}; for i in 1 2 3 4 5 6 ; do svn=${svn%%.0} ; done; echo ${svn})
# The tag used to create the OpenJDK tarball
%global vcstag jdk-%{filever}+%{buildver}%{?tagsuffix:-%{tagsuffix}}
# Standard JPackage naming and versioning defines
%global origin openjdk
%global origin_nice OpenJDK
%global top_level_dir_name %{vcstag}
%global top_level_dir_name_backup %{top_level_dir_name}-backup
%global buildver 8
%global rpmrelease 2
#%%global tagsuffix %%{nil}
# Priority must be 8 digits in total; up to openjdk 1.8, we were using 18..... so when we moved to 11, we had to add another digit
%if %is_system_jdk
# Using 10 digits may overflow the int used for priority, so we combine the patch and build versions
# It is very unlikely we will ever have a patch version > 4 or a build version > 20, so we combine as (patch * 20) + build.
# This means 11.0.9.0+11 would have had a priority of 11000911 as before
# A 11.0.9.1+1 would have had a priority of 11000921 (20 * 1 + 1), thus ensuring it is bigger than 11.0.9.0+11
%global combiver $( expr 20 '*' %{patchver} + %{buildver} )
%global priority %( printf '%02d%02d%02d%02d' %{featurever} %{interimver} %{updatever} %{combiver} )
%else
# for techpreview, using 1, so slowdebugs can have 0
%global priority %( printf '%08d' 1 )
%endif
# Define milestone (EA for pre-releases, GA for releases)
# Release will be (where N is usually a number starting at 1):
# - 0.N%%{?extraver}%%{?dist} for EA releases,
# - N%%{?extraver}{?dist} for GA releases
%global is_ga 1
%if %{is_ga}
%global build_type GA
%global ea_designator ""
%global ea_designator_zip %{nil}
%global extraver %{nil}
%global eaprefix %{nil}
%else
%global build_type EA
%global ea_designator ea
%global ea_designator_zip -%{ea_designator}
%global extraver .%{ea_designator}
%global eaprefix 0.
%endif
# parametrized macros are order-sensitive
%global compatiblename java-%{featurever}-%{origin}
%global fullversion %{compatiblename}-%{version}-%{release}
# images directories from upstream build
%global jdkimage jdk
%global static_libs_image static-libs-graal
# output dir stub
# Parameterised macros are order-sensitive
%define buildoutputdir() %{expand:build/jdk%{featurever}.build%{?1}}
%define installoutputdir() %{expand:install/jdk%{featurever}.install%{?1}}
%global altjavaoutputdir install/altjava.install
@ -442,20 +468,29 @@
%define uniquesuffix() %{expand:%{fullversion}.%{_arch}%{?1}}
# portable only declarations
%global jreimage jre
%define jreportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}\\(_[0-9]\\)*;portable%{1}.jre;g")
%define jdkportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}\\(_[0-9]\\)*;portable%{1}.jdk;g")
%define staticlibsportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}\\(_[0-9]\\)*;portable%{1}.static-libs;g")
%define jreportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}[^.]*;portable%{1}.jre;g")
%define jdkportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}[^.]*;portable%{1}.jdk;g")
%define staticlibsportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}[^.]*;portable%{1}.static-libs;g")
# RPM 4.19 no longer accept our double percentaged %%{nil} passed to %%{1}
# so we have to pass in "" but evaluate it, otherwise files will include it
%define jreportablearchive() %{expand:%{jreportablenameimpl -- %%{1}}.tar.xz}
%define jreportablearchive_for_files() %(echo %{jreportablearchive -- ""})
%define jdkportablearchive() %{expand:%{jdkportablenameimpl -- %%{1}}.tar.xz}
%define jdkportablearchive_for_files() %(echo %{jdkportablearchive -- ""})
%define staticlibsportablearchive() %{expand:%{staticlibsportablenameimpl -- %%{1}}.tar.xz}
%define staticlibsportablearchive_for_files() %(echo %{staticlibsportablearchive -- ""})
%define jreportablename() %{expand:%{jreportablenameimpl -- %%{1}}}
%define jdkportablename() %{expand:%{jdkportablenameimpl -- %%{1}}}
# Intentionally use jdkportablenameimpl here since we want to have static-libs files overlayed on
# top of the JDK archive
# We intentionally use jdkportablenameimpl here since we want to have
# static-libs files overlayed on top of the JDK archive
%define staticlibsportablename() %{expand:%{jdkportablenameimpl -- %%{1}}}
%define docportablename() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}\\(_[0-9]\\)*;portable.docs;g")
# These macros are not parameterised as the same is shared by all builds
%define docportablename() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}[^.]*;portable.docs;g")
%define docportablearchive() %{docportablename}.tar.xz
%define miscportablename() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}\\(_[0-9]\\)*;portable.misc;g")
%define miscportablename() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}[^.]*;portable.misc;g")
%define miscportablearchive() %{miscportablename}.tar.xz
# JDK to use for bootstrapping
@ -474,26 +509,6 @@
%global build_hotspot_first 0
%endif
#################################################################
# fix for https://bugzilla.redhat.com/show_bug.cgi?id=1111349
# https://bugzilla.redhat.com/show_bug.cgi?id=1590796#c14
# https://bugzilla.redhat.com/show_bug.cgi?id=1655938
%global _privatelibs libsplashscreen[.]so.*|libawt_xawt[.]so.*|libjli[.]so.*|libattach[.]so.*|libawt[.]so.*|libextnet[.]so.*|libawt_headless[.]so.*|libdt_socket[.]so.*|libfontmanager[.]so.*|libinstrument[.]so.*|libj2gss[.]so.*|libj2pcsc[.]so.*|libj2pkcs11[.]so.*|libjaas[.]so.*|libjavajpeg[.]so.*|libjdwp[.]so.*|libjimage[.]so.*|libjsound[.]so.*|liblcms[.]so.*|libmanagement[.]so.*|libmanagement_agent[.]so.*|libmanagement_ext[.]so.*|libmlib_image[.]so.*|libnet[.]so.*|libnio[.]so.*|libprefs[.]so.*|librmi[.]so.*|libsaproc[.]so.*|libsctp[.]so.*|libsystemconf[.]so.*|libzip[.]so.*%{freetype_lib}
%global _publiclibs libjawt[.]so.*|libjava[.]so.*|libjvm[.]so.*|libverify[.]so.*|libjsig[.]so.*
%if %is_system_jdk
%global __provides_exclude ^(%{_privatelibs})$
%global __requires_exclude ^(%{_privatelibs})$
# Never generate lib-style provides/requires for slowdebug packages
%global __provides_exclude_from ^.*/%{uniquesuffix -- %{debug_suffix_unquoted}}/.*$
%global __requires_exclude_from ^.*/%{uniquesuffix -- %{debug_suffix_unquoted}}/.*$
%global __provides_exclude_from ^.*/%{uniquesuffix -- %{fastdebug_suffix_unquoted}}/.*$
%global __requires_exclude_from ^.*/%{uniquesuffix -- %{fastdebug_suffix_unquoted}}/.*$
%else
# Don't generate provides/requires for JDK provided shared libraries at all.
%global __provides_exclude ^(%{_privatelibs}|%{_publiclibs})$
%global __requires_exclude ^(%{_privatelibs}|%{_publiclibs})$
%endif
# VM variant being built
%ifarch %{zero_arches}
%global vm_variant zero
@ -501,28 +516,11 @@
%global vm_variant server
%endif
%global etcjavasubdir %{_sysconfdir}/java/java-%{javaver}-%{origin}
%define etcjavadir() %{expand:%{etcjavasubdir}/%{uniquesuffix -- %{?1}}}
# Standard JPackage directories and symbolic links.
%define sdkdir() %{expand:%{uniquesuffix -- %{?1}}}
%define jrelnk() %{expand:jre-%{javaver}-%{origin}-%{version}-%{release}.%{_arch}%{?1}}
%define sdkbindir() %{expand:%{_jvmdir}/%{sdkdir -- %{?1}}/bin}
%define jrebindir() %{expand:%{_jvmdir}/%{sdkdir -- %{?1}}/bin}
%global alt_java_name alt-java
%global devkit_name %{origin}-devkit
%global rpm_state_dir %{_localstatedir}/lib/rpm-state/
# For flatpack builds hard-code /usr/sbin/alternatives,
# otherwise use %%{_sbindir} relative path.
%if 0%{?flatpak}
%global alternatives_requires /usr/sbin/alternatives
%else
%global alternatives_requires %{_sbindir}/alternatives
%endif
# Portables have no repo (requires/provides), but these are awesome for orientation in spec
# Also scriptlets are happily missing and files are handled old fashion
# not-duplicated requires/provides/obsoletes for normal/debug packages
@ -547,56 +545,20 @@
# Prevent brp-java-repack-jars from being run
%global __jar_repack 0
# Define an optional suffix for the OS this package is built on
%if 0%{?rhel} == 7
%global pkgos rhel7
%endif
# Define the architectures on which we build
# On RHEL, this should be the architectures with a devkit
# The exception is riscv64, which was introduced too recently
# for a devkit to exist. In that case, we build without devkit
%if 0%{?centos} == 0
%if 0%{?rhel} >= 10
ExclusiveArch: %{devkit_arches} riscv64
%else
ExclusiveArch: %{devkit_arches}
%endif
%else
ExclusiveArch: %{aarch64} %{ppc64le} s390x x86_64 riscv64
%endif
Name: java-%{javaver}-%{origin}-portable%{?pkgos:-%{pkgos}}
Version: %{newjavaver}.%{buildver}
Release: %{?eaprefix}%{rpmrelease}%{?extraver}%{?dist}
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
# also included the epoch in their virtual provides. This created a
# situation where in-the-wild java-1.5.0-ibm packages provided "java =
# 1:1.5.0". In RPM terms, "1.6.0 < 1:1.5.0" since 1.6.0 is
# interpreted as 0:1.6.0. So the "java >= 1.6.0" requirement would be
# satisfied by the 1:1.5.0 packages. Thus we need to set the epoch in
# JDK package >= 1.6.0 to 1, and packages referring to JDK virtual
# provides >= 1.6.0 must specify the epoch, "java >= 1:1.6.0".
Epoch: 1
Summary: %{origin_nice} %{featurever} Runtime Environment portable edition
# Groups are only used up to RHEL 8 and on Fedora versions prior to F30
%if (0%{?rhel} > 0 && 0%{?rhel} <= 8) || (0%{?fedora} >= 0 && 0%{?fedora} < 30)
Group: Development/Languages
%endif
# HotSpot code is licensed under GPLv2
# JDK library code is licensed under GPLv2 with the Classpath exception
# The Apache license is used in code taken from Apache projects (primarily xalan & xerces)
# DOM levels 2 & 3 and the XML digital signature schemas are licensed under the W3C Software License
# The JSR166 concurrency code is in the public domain
# The BSD and MIT licenses are used for a number of third-party libraries (see ADDITIONAL_LICENSE_INFO)
# The OpenJDK source tree includes:
# - JPEG library (IJG), zlib & libpng (zlib), giflib (MIT), harfbuzz (ISC),
# - freetype (FTL), jline (BSD) and LCMS (MIT)
# - jquery (MIT), jdk.crypto.cryptoki PKCS 11 wrapper (RSA)
# - public_suffix_list.dat from publicsuffix.org (MPLv2.0)
# The test code includes copies of NSS under the Mozilla Public License v2.0
# The PCSClite headers are under a BSD with advertising license
# The elliptic curve cryptography (ECC) source code is licensed under the LGPLv2.1 or any later version
License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib and ISC and FTL and RSA
URL: http://openjdk.java.net/
# The source tarball, generated using generate_source_tarball.sh
Source0: https://openjdk-sources.osci.io/openjdk%{featurever}/open%{vcstag}%{ea_designator_zip}.tar.xz
@ -638,42 +600,17 @@ Source18: TestTranslations.java
# RPM/distribution specific patches
#
############################################
# Crypto policy and FIPS support patches
# Patch is generated from the fips-25u tree at https://github.com/rh-openjdk/jdk/tree/fips-25u
# as follows: git diff %%{vcstag} src make test > fips-25u-$(git show -s --format=%h HEAD).patch
# as follows: git diff <vcstag> src make test > fips-25u-$(git show -s --format=%h HEAD).patch
# Diff is limited to src and make subdirectories to exclude .github changes
# Fixes currently included:
# PR3183, RH1340845: Follow system wide crypto policy
# PR3695: Allow use of system crypto policy to be disabled by the user
# RH1655466: Support RHEL FIPS mode using SunPKCS11 provider
# RH1818909: No ciphersuites availale for SSLSocket in FIPS mode
# RH1860986: Disable TLSv1.3 with the NSS-FIPS provider until PKCS#11 v3.0 support is available
# RH1915071: Always initialise JavaSecuritySystemConfiguratorAccess
# RH1929465: Improve system FIPS detection
# RH1995150: Disable non-FIPS crypto in SUN and SunEC security providers
# RH1996182: Login to the NSS software token in FIPS mode
# RH1991003: Allow plain key import unless com.redhat.fips.plainKeySupport is set to false
# RH2021263: Resolve outstanding FIPS issues
# RH2052819: Fix FIPS reliance on crypto policies
# RH2052829: Detect NSS at Runtime for FIPS detection
# RH2052070: Enable AlgorithmParameters and AlgorithmParameterGenerator services in FIPS mode
# RH2023467: Enable FIPS keys export
# RH2094027: SunEC runtime permission for FIPS
# RH2036462: sun.security.pkcs11.wrapper.PKCS11.getInstance breakage
# RH2090378: Revert to disabling system security properties and FIPS mode support together
# RH2104724: Avoid import/export of DH private keys
# RH2092507: P11Key.getEncoded does not work for DH keys in FIPS mode
# Build the systemconf library on all platforms
# RH2048582: Support PKCS#12 keystores [now part of JDK-8301553 upstream]
# RH2020290: Support TLS 1.3 in FIPS mode
# Add nss.fips.cfg support to OpenJDK tree
# RH2117972: Extend the support for NSS DBs (PKCS11) in FIPS mode
# Remove forgotten dead code from RH2020290 and RH2104724
# OJ1357: Fix issue on FIPS with a SecurityManager in place
# RH2134669: Add missing attributes when registering services in FIPS mode.
# test/jdk/sun/security/pkcs11/fips/VerifyMissingAttributes.java: fixed jtreg main class
# RH1940064: Enable XML Signature provider in FIPS mode
# RH2173781: Avoid calling C_GetInfo() too early, before cryptoki is initialized [now part of JDK-8301553 upstream]
# OPENJDK-2108: Internal __redhat_fips__ property
# OPENJDK-2123: Algorithms lockdown
# OPENJDK-4559: Red Hat Build of OpenJDK 25 should not restrict all the providers in FIPS
Patch1001: fips-%{featurever}u-%{fipsver}.patch
#############################################
@ -690,7 +627,10 @@ Patch1001: fips-%{featurever}u-%{fipsver}.patch
#
#############################################
# Currently empty
# JDK-8347901: C2 should remove unused leaf / pure runtime calls
Patch2002: jdk8347901-c2_unused_leaf_removal.patch
# JDK-83787313: C2: performance regression due to missing constant folding for Math.pow()
Patch2003: jdk8378713-c2_missing_pow_constant_folding.patch
#############################################
#
@ -773,19 +713,19 @@ BuildRequires: libpng-devel
BuildRequires: zlib-devel
%else
# Version in src/java.desktop/share/legal/freetype.md
Provides: bundled(freetype) = 2.13.3
Provides: bundled(freetype) = 2.14.3
# Version in src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h
Provides: bundled(giflib) = 5.2.2
Provides: bundled(giflib) = 6.1.3
# Version in src/java.desktop/share/native/libharfbuzz/hb-version.h
Provides: bundled(harfbuzz) = 10.4.0
Provides: bundled(harfbuzz) = 14.2.0
# Version in src/java.desktop/share/native/liblcms/lcms2.h
Provides: bundled(lcms2) = 2.17.0
Provides: bundled(lcms2) = 2.19.1
# Version in src/java.desktop/share/native/libjavajpeg/jpeglib.h
Provides: bundled(libjpeg) = 6b
# Version in src/java.desktop/share/native/libsplashscreen/libpng/png.h
Provides: bundled(libpng) = 1.6.47
Provides: bundled(libpng) = 1.6.58
# Version in src/java.base/share/native/libzip/zlib/zlib.h
Provides: bundled(zlib) = 1.3.1
Provides: bundled(zlib) = 1.3.2
# We link statically against libstdc++ to increase portability
%ifnarch %{devkit_arches}
BuildRequires: libstdc++-static
@ -935,6 +875,7 @@ The %{origin_nice} %{featurever} miscellany.
# Using the echo macro breaks rpmdev-bumpspec, as it parses the first line of stdout :-(
echo "Preparing %{oj_vendor_version}"
echo "System is RHEL=%{?rhel}%{!?rhel:0}, CentOS=%{?centos}%{!?centos:0}, EPEL=%{?epel}%{!?epel:0}, Fedora=%{?fedora}%{!?fedora:0}"
echo "Portable suffix is %{?pkgos}%{!?pkgos:unset}"
echo "Build JDK version is %{buildjdkver}, bootstrap JDK package is %{bootjdkpkg}"
%if 0%{?stapinstall:1}
@ -974,11 +915,6 @@ fi
export XZ_OPT="-T0"
%setup -q -c -n %{uniquesuffix ""} -T -a 0
# https://bugzilla.redhat.com/show_bug.cgi?id=1189084
prioritylength=`expr length %{priority}`
if [ $prioritylength -ne 8 ] ; then
echo "priority must be 8 digits in total, violated"
exit 14
fi
# OpenJDK patches
@ -988,22 +924,13 @@ sh %{SOURCE12} %{top_level_dir_name}
%endif
# Patch the JDK
# This syntax is deprecated:
# %patchN [...]
# and should be replaced with:
# %patch -PN [...]
# For example:
# %patch1001 -p1
# becomes:
# %patch -P1001 -p1
# The replacement format suggested by recent (circa Fedora 38) RPM
# deprecation messages:
# %patch N [...]
# is not backward-compatible with prior (circa RHEL-8) versions of
# rpmbuild.
pushd %{top_level_dir_name}
# Add crypto policy and FIPS support
%patch -P1001 -p1
# Add C2 patches
%patch -P2002 -p1
%patch -P2003 -p1
popd # openjdk
echo "Generating %{alt_java_name} man page"
@ -1087,7 +1014,6 @@ cat %{bootjdk}/release
export NUM_PROC=%(/usr/bin/getconf _NPROCESSORS_ONLN 2> /dev/null || :)
export NUM_PROC=${NUM_PROC:-1}
%if 0%{?_smp_ncpus_max}
# Honor %%_smp_ncpus_max
[ ${NUM_PROC} -gt %{?_smp_ncpus_max} ] && export NUM_PROC=%{?_smp_ncpus_max}
%endif
export XZ_OPT="-T0"
@ -1207,8 +1133,8 @@ function buildjdk() {
mkdir -p ${outputdir}
pushd ${outputdir}
# Note: zlib and freetype use %{link_type}
# rather than ${link_opt} as the system versions
# Note: zlib and freetype use link_type (macro)
# rather than link_opt (shell var) as the system versions
# are always used in a system_libs build, even
# for the static library build
LD_LIBRARY_PATH=${LIBPATH} \
@ -1717,12 +1643,14 @@ $JAVA_HOME/bin/java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -versi
# Check translations are available for new timezones (during flatpak builds, the
# tzdb.dat used by this test is not where the test expects it, so this is
# disabled for flatpak builds)
# Disable test until we are on the latest JDK
$JAVA_HOME/bin/javac -d . %{SOURCE18}
$JAVA_HOME/bin/java $(echo $(basename %{SOURCE18})|sed "s|\.java||") JRE
$JAVA_HOME/bin/java -Djava.locale.providers=CLDR $(echo $(basename %{SOURCE18})|sed "s|\.java||") CLDR
$JAVA_HOME/bin/java %{SOURCE18}
%endif
# Check blocked.certs is valid (OPENJDK-4362)
jtreg_test=$(pwd)/%{top_level_dir_name}/test/jdk/sun/security/lib/CheckBlockedCerts.java
jtreg_dir=$(dirname ${jtreg_test})
$JAVA_HOME/bin/java --add-exports java.base/sun.security.util=ALL-UNNAMED -Dtest.src=${jtreg_dir} ${jtreg_test}
# Check src.zip has all sources. See RHBZ#1130490
unzip -l $JAVA_HOME/lib/src.zip | grep 'sun.misc.Unsafe'
@ -1894,8 +1822,8 @@ done
%files
# main package builds always
%{_jvmdir}/%{jreportablearchive -- %%{nil}}
%{_jvmdir}/%{jreportablearchive -- %%{nil}}.sha256sum
%{_jvmdir}/%{jreportablearchive_for_files}
%{_jvmdir}/%{jreportablearchive_for_files}.sha256sum
%else
%files
# placeholder
@ -1904,15 +1832,15 @@ done
%if %{include_normal_build}
%files devel
%{_jvmdir}/%{jdkportablearchive -- %%{nil}}
%{_jvmdir}/%{jdkportablearchive_for_files}
%{_jvmdir}/%{jdkportablearchive -- .debuginfo}
%{_jvmdir}/%{jdkportablearchive -- %%{nil}}.sha256sum
%{_jvmdir}/%{jdkportablearchive_for_files}.sha256sum
%{_jvmdir}/%{jdkportablearchive -- .debuginfo}.sha256sum
%if %{include_staticlibs}
%files static-libs
%{_jvmdir}/%{staticlibsportablearchive -- %%{nil}}
%{_jvmdir}/%{staticlibsportablearchive -- %%{nil}}.sha256sum
%{_jvmdir}/%{staticlibsportablearchive_for_files}
%{_jvmdir}/%{staticlibsportablearchive_for_files}.sha256sum
%endif
%files unstripped
@ -1966,6 +1894,117 @@ done
%endif
%changelog
* Thu Aug 20 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.4.1.1-2.0
- Add CVEs for August 2026 release
- Related: OPENJDK-5043
* Fri Aug 07 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.4.1.1-1.0
- Update to jdk-25.0.4.1+1 (GA)
- Update release notes to 25.0.4.1+1
- Make rhel usage in pkgos optional as it may be undefined
- Simplify pkgos conditional to work on RHEL 8
- ** This tarball is embargoed until 2026-08-18 @ 1pm PT. **
- Resolves: OPENJDK-5043
* Fri Aug 07 2026 Andrea Bolognani <abologna@redhat.com> - 1:25.0.4.0.7-3.0
- Automatically set pkgos when necessary
- Don't attempt to use devkit on riscv64
- Resolves: OPENJDK-5030
- Resolves: OPENJDK-5031
* Thu Jul 23 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.4.0.7-2.0
- Add CVEs to NEWS file
- Update to tarball with final changeset ID
- Related: OPENJDK-4865
* Thu Jul 16 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.4.0.7-1.0
- Update to jdk-25.0.4+7 (GA)
- Update release notes to 25.0.4+7
- Bump freetype version to 2.14.3 following JDK-8385390
- Bump giflib version to 6.1.3 following JDK-8384902
- Bump HarfBuzz version to 14.2.0 following JDK-8385490
- Bump lcms2 version to 2.19.1 following JDK-8375065 & JDK-8383354
- Bump libpng version to 1.6.58 following JDK-8384495
- Drop local copy of JDK-8375294 EOPNOTSUPP patch
- Revert fr_FR and de_DE changes made in d43f0e6186370fdeb0ca2f3594f39783e20eef1c now JDK-8382020 is fixed
- Simplify TestTranslations run now there is only the CLDR provider and one set of data (JDK-8174269)
- Make zone string debug output optional in TestTranslations
- ** This tarball is embargoed until 2026-07-21 @ 1pm PT. **
- Resolves: OPENJDK-4865
- Resolves: OPENJDK-4902
* Mon Jul 13 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.3.0.9-3.0
- Add 25u backports of JDK-8347901 & JDK-8378713 C2 performance fixes
- Resolves: OPENJDK-4885
* Thu Jul 02 2026 Andrea Bolognani <abologna@redhat.com> - 1:25.0.3.0.9-3.0
- Strip %%{dist} more thoroughly
- Resolves: OPENJDK-4881
* Fri Jun 26 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.3.0.9-2.0
- Port ForFiles patch to RHEL and update to use standard function naming format
- Remove macro references in comments where possible (%dnl not compatible enough yet)
- Drop unused tagsuffix line which causes issues on older RPM versions without %dnl
- Cleanup RPM only macros unused in the portable spec file
- Move version information and core NVR definitions back towards the top of the file
- Specify portablerelease and rpmrelease (always 0 for portables) in the Release field
- Related: OPENJDK-4872
- Resolves: OPENJDK-4873
- Resolves: OPENJDK-4875
- Resolves: OPENJDK-4876
* Fri Jun 26 2026 Jiri Vanek <jvanek@redhat.com> - 1:25.0.3.0.9-2
- Redeclared ForFiles release sections as %%nil no longer works with %%1
- RPM 4.19 no longer accept our double percentaged %%{nil} passed to %%{1}
- so we have to pass in "" but evaluate it, otherwise files record will include it
- Resolves: OPENJDK-4872
* Sat Apr 18 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.3.0.9-1
- Update to jdk-25.0.3+9 (GA)
- Update release notes to 25.0.3+9
- Update FIPS patch to 57722aab802 version synced with 25.0.3+8
- Drop local libpng patches now JDK-8372534, JDK-8375063 & JDK-8377526 are included upstream
- Drop local HarfBuzz patch now JDK-8375057 is included upstream
- Bump freetype version to 2.14.2 following JDK-8373290 & JDK-8379158
- Bump giflib version to 6.1.2 following JDK-8379256 & JDK-8380078
- Bump libpng version to 1.6.57 following JDK-8380959 & JDK-8382047
- Bump zlib version to 1.3.2 following JDK-8378631
- Add JDK-8375294 EOPNOTSUPP patch ahead of 25.0.4
- ** This tarball is embargoed until 2026-04-21 @ 1pm PT. **
- Resolves: OPENJDK-4634
- Resolves: OPENJDK-4656
- Resolves: OPENJDK-4607
- Resolves: OPENJDK-4675
* Tue Mar 03 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.2.0.10-3
- Update FIPS patch to e55ada9353e to include the fix for the too restrictive provider lockdown
- Fix FIPS issue list to represent the new 25u version
- Add JDK-8375063 libpng 1.6.54 ahead of 25.0.3
- Add JDK-8375057 harfbuzz 12.3.2 ahead of 25.0.3
- Add JDK-8377526 libpng 1.6.55 ahead of 25.0.3
- Bump libpng version to 1.6.55 following JDK-8375063 & JDK-8377526
- Bump harfbuzz version to 12.3.2 following JDK-8375057
- Resolves: OPENJDK-4570
- Resolves: OPENJDK-4304
- Resolves: OPENJDK-4524
- Resolves: OPENJDK-4544
- Resolves: OPENJDK-4553
* Mon Jan 12 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.2.0.10-2
- Add JDK-8372534 libpng 1.6.51 ahead of 25.0.3
- Bump libpng version to 1.6.51 following JDK-8372534
- Add CVEs for 25.0.2 to NEWS
- Correct version and date for this upcoming release in NEWS
- Related: OPENJDK-4359
* Mon Jan 12 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.2.0.10-1
- Update to jdk-25.0.2+10 (GA)
- Update release notes to 25.0.2+10
- Add test to ensure blocked.certs is valid (OPENJDK-4362)
- ** This tarball is embargoed until 2026-01-20 @ 1pm PT. **
- Resolves: OPENJDK-4359
- Resolves: OPENJDK-4362
* Tue Dec 02 2025 Severin Gehwolf <sgehwolf@redhat.com> - 1:25.0.1.0.8-2
- Switch from static-libs-image to static-libs-graal-image to avoid large unneeded libjvm.a
- Resolves: OPENJDK-4197

View File

@ -3,6 +3,124 @@
# it and then adjust portablerelease and portablesuffix
# to match the new portable.
# New Version-String scheme-style defines
%global featurever 25
%global interimver 0
%global updatever 4
%global patchver 1
%global buildver 1
%global portablerelease 2
%global rpmrelease 1
# Define IcedTea version used for SystemTap tapsets and desktop file
%global icedteaver 6.0.0pre00-c848b93a8598
# Define current Git revision for the FIPS support patches
%global fipsver 57722aab802
# Define nssadapter variables
%global nssadapter_version 0.1.1
%global nssadapter_name nssadapter-%{nssadapter_version}
# Define whether the crypto policy is expected to be active when testing
%global crypto_policy_active true
# Define JDK versions
%global newjavaver %{featurever}.%{interimver}.%{updatever}.%{patchver}
%global javaver %{featurever}
# Strip up to 6 trailing zeros in newjavaver, as the JDK does, to get the correct version used in filenames
%global filever %(svn=%{newjavaver}; for i in 1 2 3 4 5 6 ; do svn=${svn%%.0} ; done; echo ${svn})
# The tag used to create the OpenJDK tarball
%global vcstag jdk-%{filever}+%{buildver}%{?tagsuffix:-%{tagsuffix}}
# Standard JPackage naming and versioning defines
%global origin openjdk
%global origin_nice OpenJDK
%global top_level_dir_name %{vcstag}
%global top_level_dir_name_backup %{top_level_dir_name}-backup
# Define milestone (EA for pre-releases, GA for releases)
# Release will be (where N is usually a number starting at 1):
# - 0.N.ea<dist> for EA releases,
# - N<dist> for GA releases
%global is_ga 1
%if %{is_ga}
%global build_type GA
%global ea_designator ""
%global ea_designator_zip %{nil}
%global extraver %{nil}
%global eaprefix %{nil}
%else
%global build_type EA
%global ea_designator ea
%global ea_designator_zip -%{ea_designator}
%global extraver .%{ea_designator}
%global eaprefix 0.
%endif
%global compatiblename java-%{javaver}-%{origin}
Name: %{compatiblename}
Version: %{newjavaver}.%{buildver}
Release: %{?eaprefix}%{portablerelease}.%{rpmrelease}%{?extraver}%{?dist}
%global fullversion %{compatiblename}-%{version}-%{release}
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
# also included the epoch in their virtual provides. This created a
# situation where in-the-wild java-1.5.0-ibm packages provided "java =
# 1:1.5.0". In RPM terms, "1.6.0 < 1:1.5.0" since 1.6.0 is
# interpreted as 0:1.6.0. So the "java >= 1.6.0" requirement would be
# satisfied by the 1:1.5.0 packages. Thus we need to set the epoch in
# JDK package >= 1.6.0 to 1, and packages referring to JDK virtual
# provides >= 1.6.0 must specify the epoch, "java >= 1:1.6.0".
Epoch: 1
Summary: %{origin_nice} %{featurever} Runtime Environment
# Groups are only used up to RHEL 8 and on Fedora versions prior to F30
%if (0%{?rhel} > 0 && 0%{?rhel} <= 8) || (0%{?fedora} >= 0 && 0%{?fedora} < 30)
Group: Development/Languages
%endif
# HotSpot code is licensed under GPLv2
# JDK library code is licensed under GPLv2 with the Classpath exception
# The Apache license is used in code taken from Apache projects (primarily xalan & xerces)
# DOM levels 2 & 3 and the XML digital signature schemas are licensed under the W3C Software License
# The JSR166 concurrency code is in the public domain
# The BSD and MIT licenses are used for a number of third-party libraries (see ADDITIONAL_LICENSE_INFO)
# The OpenJDK source tree includes:
# - JPEG library (IJG), zlib & libpng (zlib), giflib (MIT), harfbuzz (ISC),
# - freetype (FTL), jline (BSD) and LCMS (MIT)
# - jquery (MIT), jdk.crypto.cryptoki PKCS 11 wrapper (RSA)
# - public_suffix_list.dat from publicsuffix.org (MPLv2.0)
# The test code includes copies of NSS under the Mozilla Public License v2.0
# The PCSClite headers are under a BSD with advertising license
# The elliptic curve cryptography (ECC) source code is licensed under the LGPLv2.1 or any later version
License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib and ISC and FTL and RSA
URL: http://openjdk.java.net/
# Define the OS the portable JDK is built on
# This is undefined for CentOS & openjdk-portable-rhel-8 builds and
# equals 'rhel7' for openjdk-portable-rhel-7 builds
%if 0
%global pkgos rhel7
%endif
# Define the root name of the portable packages
%global pkgnameroot java-%{featurever}-%{origin}-portable%{?pkgos:-%{pkgos}}
# Release field for the portable build
# The rpmrelease field is always zero for portables
%global prelease %{?eaprefix}%{portablerelease}.0%{?extraver}
# Portable suffix differs between RHEL and CentOS
%if 0%{?centos} == 0
%global portablerhel %{?pkgos:7_9}%{!?pkgos:8}
%else
%global portablerhel 9
%endif
%global portablebuilddir /builddir/build/BUILD
%global portablesuffix el%{portablerhel}
# Check if pandoc was available to generate docs (including man pages)
%if 0%{?portablerhel} == 8
%global pandoc_available 1
%else
%global pandoc_available 0
%endif
# RPM conditionals so as to be able to dynamically produce
# slowdebug/release builds. See:
# http://rpm.org/user_doc/conditional_builds.html
@ -87,19 +205,20 @@
%global normal_build %{nil}
%endif
# We have hardcoded list of files, which is appearing in alternatives, and in files
# in alternatives those are slaves and master, very often triplicated by man pages
# in files all masters and slaves are ghosted
# the ghosts are here to allow installation via query like `dnf install /usr/bin/java`
# you can list those files, with appropriate sections: cat *.spec | grep -e --install -e --slave -e post_ -e alternatives
# We have a hardcoded list of files, which appears in alternatives and in files
# In alternatives, those are slaves and master, very often triplicated by man pages
# In files, all masters and slaves are ghosted
# The ghosts are here to allow installation via query like `dnf install /usr/bin/java`
# You can list those files, with appropriate sections: cat *.spec | grep -e --install -e --slave -e post_ -e alternatives
# TODO - fix those hardcoded lists via single list
# Those files must *NOT* be ghosted for *slowdebug* packages
# Those files must *NOT* be ghosted for *debug* packages
# FIXME - if you are moving jshell or jlink or similar, always modify all three sections
# you can check via headless and devels:
# You can check via headless and devels:
# rpm -ql --noghost java-11-openjdk-headless-11.0.1.13-8.fc29.x86_64.rpm | grep bin
# == rpm -ql java-11-openjdk-headless-slowdebug-11.0.1.13-8.fc29.x86_64.rpm | grep bin
# != rpm -ql java-11-openjdk-headless-11.0.1.13-8.fc29.x86_64.rpm | grep bin
# similarly for other %%{_jvmdir}/{jre,java} and %%{_javadocdir}/{java,java-zip}
# and similarly for other packages.
%define is_release_build() %( if [ "%{?1}" == "%{debug_suffix_unquoted}" -o "%{?1}" == "%{fastdebug_suffix_unquoted}" ]; then echo "0" ; else echo "1"; fi )
# Indicates whether this is the default JDK on this version of RHEL
@ -283,13 +402,8 @@
%global with_systemtap 0
%endif
# New Version-String scheme-style defines
%global featurever 25
%global interimver 0
%global updatever 1
%global patchver 0
# We don't add any LTS designator for STS packages (Fedora and EPEL).
# We need to explicitly exclude EPEL as it would have the %%{rhel} macro defined.
# We need to explicitly exclude EPEL as it has the rhel macro defined.
%if 0%{?rhel} && !0%{?epel}
%global lts_designator "LTS"
%global lts_designator_zip -%{lts_designator}
@ -301,7 +415,8 @@
# Define vendor information used by OpenJDK
%global oj_vendor Red Hat, Inc.
%global oj_vendor_url https://www.redhat.com/
# Define what url should JVM offer in case of a crash report
# Define what url the JVM should offer in case of a crash report
# order may be important, epel may have rhel declared
%if 0%{?epel}
%global oj_vendor_bug_url https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora%20EPEL&component=%{name}&version=epel%{epel}
@ -319,54 +434,6 @@
%endif
%global oj_vendor_version (Red_Hat-%{version}-%{portablerelease})
# Define IcedTea version used for SystemTap tapsets and desktop file
%global icedteaver 6.0.0pre00-c848b93a8598
# Define current Git revision for the crypto policy & FIPS support patches
%global fipsver df044414ef4
# Define nssadapter variables
%global nssadapter_version 0.1.0
%global nssadapter_name nssadapter-%{nssadapter_version}
# Define whether the crypto policy is expected to be active when testing
%global crypto_policy_active true
# Define JDK versions
%global newjavaver %{featurever}.%{interimver}.%{updatever}.%{patchver}
%global javaver %{featurever}
# Strip up to 6 trailing zeros in newjavaver, as the JDK does, to get the correct version used in filenames
%global filever %(svn=%{newjavaver}; for i in 1 2 3 4 5 6 ; do svn=${svn%%.0} ; done; echo ${svn})
# The tag used to create the OpenJDK tarball
%global vcstag jdk-%{filever}+%{buildver}%{?tagsuffix:-%{tagsuffix}}
# Define the OS the portable JDK is built on
# This is undefined for CentOS & openjdk-portable-rhel-8 builds and
# equals 'rhel7' for openjdk-portable-rhel-7 builds
%if 0
%global pkgos rhel7
%endif
# Standard JPackage naming and versioning defines
%global origin openjdk
%global origin_nice OpenJDK
%global top_level_dir_name %{vcstag}
%global top_level_dir_name_backup %{top_level_dir_name}-backup
%global buildver 8
%global rpmrelease 6
# Settings used by the portable build
%global portablerelease 2
# Portable suffix differs between RHEL and CentOS
%if 0%{?centos} == 0
%global portablerhel %{?pkgos:7_9}%{!?pkgos:8}
%else
%global portablerhel 9
%endif
%global portablebuilddir /builddir/build/BUILD
%global portablesuffix el%{portablerhel}
# Check if pandoc was available to generate docs (including man pages)
%if 0%{?portablerhel} == 8
%global pandoc_available 1
%else
%global pandoc_available 0
%endif
# Priority must be 8 digits in total; up to openjdk 1.8, we were using 18..... so when we moved to 11, we had to add another digit
%if %is_system_jdk
# Using 10 digits may overflow the int used for priority, so we combine the patch and build versions
@ -380,29 +447,6 @@
%global priority %( printf '%08d' 1 )
%endif
# Define milestone (EA for pre-releases, GA for releases)
# Release will be (where N is usually a number starting at 1):
# - 0.N%%{?extraver}%%{?dist} for EA releases,
# - N%%{?extraver}{?dist} for GA releases
%global is_ga 1
%if %{is_ga}
%global build_type GA
%global ea_designator ""
%global ea_designator_zip %{nil}
%global extraver %{nil}
%global eaprefix %{nil}
%else
%global build_type EA
%global ea_designator ea
%global ea_designator_zip -%{ea_designator}
%global extraver .%{ea_designator}
%global eaprefix 0.
%endif
# parametrized macros are order-sensitive
%global compatiblename java-%{featurever}-%{origin}
%global fullversion %{compatiblename}-%{version}-%{release}
# output dir stub
%define installoutputdir() %{expand:install/jdk%{featurever}.install%{?1}}
# we can copy the javadoc to not arched dir, or make it not noarch
%define uniquejavadocdir() %{expand:%{compatiblename}%{?1}}
@ -448,7 +492,7 @@
%global rpm_state_dir %{_localstatedir}/lib/rpm-state/
# For flatpack builds hard-code /usr/sbin/alternatives,
# otherwise use %%{_sbindir} relative path.
# otherwise use _sbindir relative path.
%if 0%{?flatpak}
%global alternatives_requires /usr/sbin/alternatives
%else
@ -1121,8 +1165,8 @@ Requires: ca-certificates
# Require javapackages-filesystem for ownership of /usr/lib/jvm/ and macros
Requires: javapackages-filesystem
# Require zone-info data provided by tzdata-java sub-package
# 2025a required as of JDK-8347965
Requires: tzdata-java >= 2025a
# 2026b required as of JDK-8383175
Requires: tzdata-java >= 2026b
# for support of kernel stream control
# libsctp.so.1 is being `dlopen`ed on demand
Requires: lksctp-tools%{?_isa}
@ -1243,51 +1287,10 @@ Provides: java-%{origin}-src%{?1} = %{epoch}:%{version}-%{release}
# Prevent brp-java-repack-jars from being run
%global __jar_repack 0
# Define the root name of the portable packages
%global pkgnameroot java-%{featurever}-%{origin}-portable%{?pkgos:-%{pkgos}}
# Define the architectures on which we build
ExclusiveArch: %{aarch64} %{ppc64le} s390x x86_64 riscv64
Name: java-%{javaver}-%{origin}
Version: %{newjavaver}.%{buildver}
Release: %{?eaprefix}%{rpmrelease}%{?extraver}%{?dist}
# Equivalent for the portable build
%global prelease %{?eaprefix}%{portablerelease}%{?extraver}
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
# also included the epoch in their virtual provides. This created a
# situation where in-the-wild java-1.5.0-ibm packages provided "java =
# 1:1.5.0". In RPM terms, "1.6.0 < 1:1.5.0" since 1.6.0 is
# interpreted as 0:1.6.0. So the "java >= 1.6.0" requirement would be
# satisfied by the 1:1.5.0 packages. Thus we need to set the epoch in
# JDK package >= 1.6.0 to 1, and packages referring to JDK virtual
# provides >= 1.6.0 must specify the epoch, "java >= 1:1.6.0".
Epoch: 1
Summary: %{origin_nice} %{featurever} Runtime Environment
# Groups are only used up to RHEL 8 and on Fedora versions prior to F30
%if (0%{?rhel} > 0 && 0%{?rhel} <= 8) || (0%{?fedora} >= 0 && 0%{?fedora} < 30)
Group: Development/Languages
%endif
# HotSpot code is licensed under GPLv2
# JDK library code is licensed under GPLv2 with the Classpath exception
# The Apache license is used in code taken from Apache projects (primarily xalan & xerces)
# DOM levels 2 & 3 and the XML digital signature schemas are licensed under the W3C Software License
# The JSR166 concurrency code is in the public domain
# The BSD and MIT licenses are used for a number of third-party libraries (see ADDITIONAL_LICENSE_INFO)
# The OpenJDK source tree includes:
# - JPEG library (IJG), zlib & libpng (zlib), giflib (MIT), harfbuzz (ISC),
# - freetype (FTL), jline (BSD) and LCMS (MIT)
# - jquery (MIT), jdk.crypto.cryptoki PKCS 11 wrapper (RSA)
# - public_suffix_list.dat from publicsuffix.org (MPLv2.0)
# The test code includes copies of NSS under the Mozilla Public License v2.0
# The PCSClite headers are under a BSD with advertising license
# The elliptic curve cryptography (ECC) source code is licensed under the LGPLv2.1 or any later version
License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib and ISC and FTL and RSA
URL: http://openjdk.java.net/
# The source tarball, generated using generate_source_tarball.sh
Source0: https://openjdk-sources.osci.io/openjdk%{featurever}/open%{vcstag}%{ea_designator_zip}.tar.xz
@ -1367,41 +1370,15 @@ Source32: create-redhat-properties-files.bash
############################################
# Crypto policy and FIPS support patches
# Patch is generated from the fips-25u tree at https://github.com/rh-openjdk/jdk/tree/fips-25u
# as follows: git diff %%{vcstag} src make test > fips-25u-$(git show -s --format=%h HEAD).patch
# as follows: git diff <vcstag> src make test > fips-25u-$(git show -s --format=%h HEAD).patch
# Diff is limited to src and make subdirectories to exclude .github changes
# Fixes currently included:
# PR3183, RH1340845: Follow system wide crypto policy
# PR3695: Allow use of system crypto policy to be disabled by the user
# RH1655466: Support RHEL FIPS mode using SunPKCS11 provider
# RH1818909: No ciphersuites availale for SSLSocket in FIPS mode
# RH1860986: Disable TLSv1.3 with the NSS-FIPS provider until PKCS#11 v3.0 support is available
# RH1915071: Always initialise JavaSecuritySystemConfiguratorAccess
# RH1929465: Improve system FIPS detection
# RH1995150: Disable non-FIPS crypto in SUN and SunEC security providers
# RH1996182: Login to the NSS software token in FIPS mode
# RH1991003: Allow plain key import unless com.redhat.fips.plainKeySupport is set to false
# RH2021263: Resolve outstanding FIPS issues
# RH2052819: Fix FIPS reliance on crypto policies
# RH2052829: Detect NSS at Runtime for FIPS detection
# RH2052070: Enable AlgorithmParameters and AlgorithmParameterGenerator services in FIPS mode
# RH2023467: Enable FIPS keys export
# RH2094027: SunEC runtime permission for FIPS
# RH2036462: sun.security.pkcs11.wrapper.PKCS11.getInstance breakage
# RH2090378: Revert to disabling system security properties and FIPS mode support together
# RH2104724: Avoid import/export of DH private keys
# RH2092507: P11Key.getEncoded does not work for DH keys in FIPS mode
# Build the systemconf library on all platforms
# RH2048582: Support PKCS#12 keystores [now part of JDK-8301553 upstream]
# RH2020290: Support TLS 1.3 in FIPS mode
# Add nss.fips.cfg support to OpenJDK tree
# RH2117972: Extend the support for NSS DBs (PKCS11) in FIPS mode
# Remove forgotten dead code from RH2020290 and RH2104724
# OJ1357: Fix issue on FIPS with a SecurityManager in place
# RH2134669: Add missing attributes when registering services in FIPS mode.
# test/jdk/sun/security/pkcs11/fips/VerifyMissingAttributes.java: fixed jtreg main class
# RH1940064: Enable XML Signature provider in FIPS mode
# RH2173781: Avoid calling C_GetInfo() too early, before cryptoki is initialized [now part of JDK-8301553 upstream]
# OPENJDK-2108: Internal __redhat_fips__ property
# OPENJDK-2123: Algorithms lockdown
# OPENJDK-4559: Red Hat Build of OpenJDK 25 should not restrict all the providers in FIPS
Patch1001: fips-%{featurever}u-%{fipsver}.patch
#############################################
@ -1418,7 +1395,10 @@ Patch1001: fips-%{featurever}u-%{fipsver}.patch
#
#############################################
# Currently empty
# JDK-8347901: C2 should remove unused leaf / pure runtime calls
Patch2002: jdk8347901-c2_unused_leaf_removal.patch
# JDK-83787313: C2: performance regression due to missing constant folding for Math.pow()
Patch2003: jdk8378713-c2_missing_pow_constant_folding.patch
#############################################
#
@ -1433,7 +1413,8 @@ Patch1001: fips-%{featurever}u-%{fipsver}.patch
# NSS adapter patches
#
#############################################
Patch2001: nssadapter-ldflags.patch
# Currently empty
BuildRequires: autoconf
BuildRequires: automake
@ -1482,8 +1463,8 @@ BuildRequires: %{pkgnameroot}-misc = %{epoch}:%{version}-%{prelease}.%{portables
%ifarch %{zero_arches}
BuildRequires: libffi-devel
%endif
# 2025a required as of JDK-8347965
BuildRequires: tzdata-java >= 2025a
# 2026b required as of JDK-8383175
BuildRequires: tzdata-java >= 2026b
# Earlier versions have a bug in tree vectorization on PPC
BuildRequires: gcc >= 4.8.3-8
@ -1506,19 +1487,19 @@ BuildRequires: libpng-devel
BuildRequires: zlib-devel
%else
# Version in src/java.desktop/share/legal/freetype.md
Provides: bundled(freetype) = 2.13.3
Provides: bundled(freetype) = 2.14.3
# Version in src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h
Provides: bundled(giflib) = 5.2.2
Provides: bundled(giflib) = 6.1.3
# Version in src/java.desktop/share/native/libharfbuzz/hb-version.h
Provides: bundled(harfbuzz) = 10.4.0
Provides: bundled(harfbuzz) = 14.2.0
# Version in src/java.desktop/share/native/liblcms/lcms2.h
Provides: bundled(lcms2) = 2.17.0
Provides: bundled(lcms2) = 2.19.1
# Version in src/java.desktop/share/native/libjavajpeg/jpeglib.h
Provides: bundled(libjpeg) = 6b
# Version in src/java.desktop/share/native/libsplashscreen/libpng/png.h
Provides: bundled(libpng) = 1.6.47
Provides: bundled(libpng) = 1.6.58
# Version in src/java.base/share/native/libzip/zlib/zlib.h
Provides: bundled(zlib) = 1.3.1
Provides: bundled(zlib) = 1.3.2
%endif
%ifarch %{sleef_arches}
# SLEEF is always bundled
@ -1886,6 +1867,7 @@ The %{origin_nice} %{featurever} cryptography adapter library.
echo "Preparing %{oj_vendor_version}"
echo "System is RHEL=%{?rhel}%{!?rhel:0}, CentOS=%{?centos}%{!?centos:0}, EPEL=%{?epel}%{!?epel:0}, Fedora=%{?fedora}%{!?fedora:0}"
echo "Portable suffix is %{?pkgos}%{!?pkgos:unset}"
# Using the echo macro breaks rpmdev-bumpspec, as it parses the first line of stdout :-(
%if 0%{?stapinstall:1}
@ -1936,27 +1918,18 @@ sh %{SOURCE12} %{top_level_dir_name}
%endif
# Patch the JDK
# This syntax is deprecated:
# %patchN [...]
# and should be replaced with:
# %patch -PN [...]
# For example:
# %patch1001 -p1
# becomes:
# %patch -P1001 -p1
# The replacement format suggested by recent (circa Fedora 38) RPM
# deprecation messages:
# %patch N [...]
# is not backward-compatible with prior (circa RHEL-8) versions of
# rpmbuild.
pushd %{top_level_dir_name}
# Add crypto policy and FIPS support
%patch -P1001 -p1
# Add C2 patches
%patch -P2002 -p1
%patch -P2003 -p1
popd # openjdk
# Patch NSS adapter
pushd %{nssadapter_name}
%patch -P2001 -p1
# Nothing to do
popd # nssadapter
# The OpenJDK version file includes the current
@ -2005,7 +1978,7 @@ function customisejdk() {
if [ -d ${imagepath} ] ; then
# Install crypto-policies FIPS configuration files and append
# include line to java.security
bash -x %{SOURCE32} ${imagepath}/conf/security %{_libdir}/%{sdkdir -- ${suffix}}/libnssadapter.so
bash -ex %{SOURCE32} ${imagepath}/conf/security %{_libdir}/%{sdkdir -- ${suffix}}/libnssadapter.so
# Use system-wide tzdata
rm ${imagepath}/lib/tzdb.dat
@ -2128,10 +2101,7 @@ $JAVA_HOME/bin/java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -versi
# Check translations are available for new timezones (during flatpak builds, the
# tzdb.dat used by this test is not where the test expects it, so this is
# disabled for flatpak builds)
# Disable test until we are on the latest JDK
$JAVA_HOME/bin/javac -d . %{SOURCE18}
$JAVA_HOME/bin/java $(echo $(basename %{SOURCE18})|sed "s|\.java||") JRE
$JAVA_HOME/bin/java -Djava.locale.providers=CLDR $(echo $(basename %{SOURCE18})|sed "s|\.java||") CLDR
$JAVA_HOME/bin/java %{SOURCE18}
%endif
# Check src.zip has all sources. See RHBZ#1130490
@ -2626,6 +2596,146 @@ exit 0
%endif
%changelog
* Sun Aug 23 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.4.1.1-2.1
- Sync the copy of the portable specfile with the latest update
- Related: RHEL-235627
* Fri Aug 07 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.4.1.1-1.1
- Update to jdk-25.0.4.1+1 (GA)
- Update release notes to 25.0.4.1+1
- Report pkgos value during build
- Sync the copy of the portable specfile with the latest update
- ** This tarball is embargoed until 2026-08-18 @ 1pm PT. **
- Resolves: RHEL-235627
* Thu Jul 23 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.4.0.7-2.1
- Add CVEs to NEWS file
- Update to tarball with final changeset ID
- Sync the copy of the portable specfile with the latest update
- Related: RHEL-188883
* Thu Jul 16 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.4.0.7-1.1
- Update to jdk-25.0.4+7 (GA)
- Update release notes to 25.0.4+7
- Bump freetype version to 2.14.3 following JDK-8385390
- Bump giflib version to 6.1.3 following JDK-8384902
- Bump HarfBuzz version to 14.2.0 following JDK-8385490
- Bump lcms2 version to 2.19.1 following JDK-8375065 & JDK-8383354
- Bump libpng version to 1.6.58 following JDK-8384495
- Require tzdata 2026b due to upstream inclusion of JDK-8383175
- Drop local copy of JDK-8375294 EOPNOTSUPP patch
- Obsolete old RHEL releases (9.7.0-z, 10.1-z)
- Revert fr_FR and de_DE changes made in d43f0e6186370fdeb0ca2f3594f39783e20eef1c now JDK-8382020 is fixed
- Simplify TestTranslations run now there is only the CLDR provider and one set of data (JDK-8174269)
- Make zone string debug output optional in TestTranslations
- Sync the copy of the portable specfile with the latest update
- ** This tarball is embargoed until 2026-07-21 @ 1pm PT. **
- Resolves: RHEL-188883
- Resolves: RHEL-212294
- Resolves: RHEL-212296
* Tue Jul 14 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.3.0.9-3.1
- Cleanup tagging and gating scripts to appease shellcheck:
- * scripts/builds/build_vanilla.sh: Use an array to handle the varying arguments to rhpkg.
- * scripts/builds/check_signatures.sh: Quote variable usage.
- * scripts/builds/waive_issue.sh: Remove redundant 'test "x"' usage.
- * scripts/builds/waive_leapp_issue.sh: Likewise.
- * scripts/builds/waive_rpminspect.sh: Likewise.
- * scripts/builds/waive_usual_rpminspect.sh: Likewise and add missing WORKING_DIR variable.
- * scripts/builds/waive_usual_tier0.sh: Remove redundant 'test "x"' usage.
- Remove macro references in comments where possible (%dnl not compatible enough yet)
- Move version information and core NVR definitions back towards the top of the file
- Specify portablerelease and rpmrelease (always 0 for portables) in the Release field
- Add 25u backports of JDK-8347901 & JDK-8378713 C2 performance fixes
- Sync the copy of the portable specfile with the latest update
- Related: RHEL-155327
- Related: RHEL-155339
- Resolves: RHEL-150977
- Resolves: RHEL-210972
- Resolves: RHEL-210993
* Sat Apr 18 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.3.0.9-1
- Update to jdk-25.0.3+9 (GA)
- Update release notes to 25.0.3+9
- Update FIPS patch to 57722aab802 version synced with 25.0.3+8
- Drop local libpng patches now JDK-8372534, JDK-8375063 & JDK-8377526 are included upstream
- Drop local HarfBuzz patch now JDK-8375057 is included upstream
- Bump freetype version to 2.14.2 following JDK-8373290 & JDK-8379158
- Bump giflib version to 6.1.2 following JDK-8379256 & JDK-8380078
- Bump libpng version to 1.6.57 following JDK-8380959 & JDK-8382047
- Bump zlib version to 1.3.2 following JDK-8378631
- Bump tzdata version to 2026a following JDK-8379035
- Add JDK-8375294 EOPNOTSUPP patch ahead of 25.0.4
- Sync the copy of the portable specfile with the latest update
- ** This tarball is embargoed until 2026-04-21 @ 1pm PT. **
- Resolves: RHEL-169620
- Resolves: RHEL-157091
- Resolves: RHEL-161217
- Resolves: RHEL-161333
- Resolves: RHEL-169613
* Thu Mar 12 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.2.0.10-4
- Add tagging scripts with signature checks and gating handling
- Update tagged versions to include 9.8.0-z, 9.9.0, 10.2-z & 10.3.
- Add gating scripts to simplify obtaining results and waiving issues
- Sync the copy of the portable specfile with the latest update
- Resolves: RHEL-155327
- Resolves: RHEL-155337
- Resolves: RHEL-155339
- Related: RHEL-155000
- Related: RHEL-146649
- Related: RHEL-148327
- Related: RHEL-148830
* Wed Mar 11 2026 Thomas Fitzsimmons <fitzsim@redhat.com> - 1:25.0.2.0.10-3
- Disable abidiff inspection in rpminspect.yaml to avoid an out-of-memory error on the CentOS test farm
- See: https://docs.testing-farm.io/Testing%20Farm/0.1/errors.html#TFE-1
- Resolves: RHEL-150976
* Tue Mar 03 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.2.0.10-3
- Update FIPS patch to e55ada9353e to include the fix for the too restrictive provider lockdown
- Fix FIPS issue list to represent the new 25u version
- Add JDK-8375063 libpng 1.6.54 ahead of 25.0.3
- Add JDK-8375057 harfbuzz 12.3.2 ahead of 25.0.3
- Add JDK-8377526 libpng 1.6.55 ahead of 25.0.3
- Bump libpng version to 1.6.55 following JDK-8375063 & JDK-8377526
- Bump harfbuzz version to 12.3.2 following JDK-8375057
- Bump nssadapter version to bring in shared PKCS11 session fix
- Drop LDFLAGS nssadapter patch which is now upstream in 0.1.1
- Resolves: RHEL-155000
- Resolves: RHEL-146649
- Resolves: RHEL-148327
- Resolves: RHEL-148830
- Resolves: RHEL-155044
* Wed Feb 18 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.2.0.10-2
- Bump rpmrelease for CentOS build
- Related: RHEL-139579
- Related: RHEL-131430
- Related: RHEL-131443
- Related: RHEL-142855
- Related: RHEL-142799
* Wed Jan 21 2026 Jiri Vanek <jvanek@redhat.com> - 1:25.0.2.0.10-1
- Execute create-redhat-properties-files.bash with '-e' to exit on failure
- Related: RHEL-142855
* Mon Jan 12 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.2.0.10-1
- Update to jdk-25.0.2+10 (GA)
- Update release notes to 25.0.2+10
- Add JDK-8372534 libpng 1.6.51 ahead of 25.0.3
- Bump libpng version to 1.6.51 following JDK-8372534
- Bump ID of NSS adapter patch so we can stay in sync with portable on the libpng patch
- Test for java.security's existence in create-redhat-properties-files.bash
- Handle 'upgrade' as an alternative to 'update' in openjdk_news.sh
- Sync the copy of the portable specfile with the latest update
- ** This tarball is embargoed until 2026-01-20 @ 1pm PT. **
- Resolves: RHEL-139579
- Resolves: RHEL-131430
- Resolves: RHEL-131443
- Resolves: RHEL-142855
- Resolves: RHEL-142799
* Sat Dec 06 2025 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.1.0.8-6
- Sync the copy of the portable specfile with the latest update
- Related: RHEL-133733

View File

@ -0,0 +1,772 @@
From 09853461a6896ab1f15469c753c21ca212e7e650 Mon Sep 17 00:00:00 2001
From: duke <duke@openjdk.org>
Date: Tue, 7 Apr 2026 15:14:53 +0000
Subject: [PATCH 1/2] Backport ed70910b0f3e1b19d915ec13ac3434407d01bc5d
---
src/hotspot/share/opto/callnode.cpp | 53 +++++++-
src/hotspot/share/opto/callnode.hpp | 29 ++++-
src/hotspot/share/opto/classes.hpp | 2 +
src/hotspot/share/opto/compile.cpp | 19 +++
src/hotspot/share/opto/divnode.cpp | 158 ++++++++++--------------
src/hotspot/share/opto/divnode.hpp | 35 +++---
src/hotspot/share/opto/graphKit.cpp | 29 +++--
src/hotspot/share/opto/graphKit.hpp | 1 +
src/hotspot/share/opto/library_call.cpp | 2 +-
src/hotspot/share/opto/macro.cpp | 15 +--
src/hotspot/share/opto/multnode.cpp | 13 ++
src/hotspot/share/opto/multnode.hpp | 46 +++++++
src/hotspot/share/opto/node.cpp | 12 +-
src/hotspot/share/opto/node.hpp | 5 +-
src/hotspot/share/opto/parse2.cpp | 8 +-
15 files changed, 282 insertions(+), 145 deletions(-)
diff --git a/src/hotspot/share/opto/callnode.cpp b/src/hotspot/share/opto/callnode.cpp
index 6f13ce0f809..fc4b0c35dff 100644
--- a/src/hotspot/share/opto/callnode.cpp
+++ b/src/hotspot/share/opto/callnode.cpp
@@ -935,7 +935,7 @@ Node *CallNode::result_cast() {
}
-void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts) {
+void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts) const {
projs->fallthrough_proj = nullptr;
projs->fallthrough_catchproj = nullptr;
projs->fallthrough_ioproj = nullptr;
@@ -1319,6 +1319,57 @@ void CallLeafVectorNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_
//=============================================================================
+bool CallLeafPureNode::is_unused() const {
+ return proj_out_or_null(TypeFunc::Parms) == nullptr;
+}
+
+bool CallLeafPureNode::is_dead() const {
+ return proj_out_or_null(TypeFunc::Control) == nullptr;
+}
+
+/* We make a tuple of the global input state + TOP for the output values.
+ * We use this to delete a pure function that is not used: by replacing the call with
+ * such a tuple, we let output Proj's idealization pick the corresponding input of the
+ * pure call, so jumping over it, and effectively, removing the call from the graph.
+ * This avoids doing the graph surgery manually, but leaves that to IGVN
+ * that is specialized for doing that right. We need also tuple components for output
+ * values of the function to respect the return arity, and in case there is a projection
+ * that would pick an output (which shouldn't happen at the moment).
+ */
+TupleNode* CallLeafPureNode::make_tuple_of_input_state_and_top_return_values(const Compile* C) const {
+ // Transparently propagate input state but parameters
+ TupleNode* tuple = TupleNode::make(
+ tf()->range(),
+ in(TypeFunc::Control),
+ in(TypeFunc::I_O),
+ in(TypeFunc::Memory),
+ in(TypeFunc::FramePtr),
+ in(TypeFunc::ReturnAdr));
+
+ // And add TOPs for the return values
+ for (uint i = TypeFunc::Parms; i < tf()->range()->cnt(); i++) {
+ tuple->set_req(i, C->top());
+ }
+
+ return tuple;
+}
+
+Node* CallLeafPureNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+ if (is_dead()) {
+ return nullptr;
+ }
+
+ // We need to wait until IGVN because during parsing, usages might still be missing
+ // and we would remove the call immediately.
+ if (can_reshape && is_unused()) {
+ // The result is not used. We remove the call by replacing it with a tuple, that
+ // is later disintegrated by the projections.
+ return make_tuple_of_input_state_and_top_return_values(phase->C);
+ }
+
+ return CallRuntimeNode::Ideal(phase, can_reshape);
+}
+
#ifndef PRODUCT
void CallLeafNode::dump_spec(outputStream *st) const {
st->print("# ");
diff --git a/src/hotspot/share/opto/callnode.hpp b/src/hotspot/share/opto/callnode.hpp
index 213fbda4e89..2462a88143f 100644
--- a/src/hotspot/share/opto/callnode.hpp
+++ b/src/hotspot/share/opto/callnode.hpp
@@ -752,7 +752,7 @@ class CallNode : public SafePointNode {
// Collect all the interesting edges from a call for use in
// replacing the call by something else. Used by macro expansion
// and the late inlining support.
- void extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts = true);
+ void extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts = true) const;
virtual uint match_edge(uint idx) const;
@@ -928,6 +928,33 @@ class CallLeafNode : public CallRuntimeNode {
#endif
};
+/* A pure function call, they are assumed not to be safepoints, not to read or write memory,
+ * have no exception... They just take parameters, return a value without side effect. It is
+ * always correct to create some, or remove them, if the result is not used.
+ *
+ * They still have control input to allow easy lowering into other kind of calls that require
+ * a control, but this is more a technical than a moral constraint.
+ *
+ * Pure calls must have only control and data input and output: I/O, Memory and so on must be top.
+ * Nevertheless, pure calls can typically be expensive math operations so care must be taken
+ * when letting the node float.
+ */
+class CallLeafPureNode : public CallLeafNode {
+protected:
+ bool is_unused() const;
+ bool is_dead() const;
+ TupleNode* make_tuple_of_input_state_and_top_return_values(const Compile* C) const;
+
+public:
+ CallLeafPureNode(const TypeFunc* tf, address addr, const char* name,
+ const TypePtr* adr_type)
+ : CallLeafNode(tf, addr, name, adr_type) {
+ init_class_id(Class_CallLeafPure);
+ }
+ int Opcode() const override;
+ Node* Ideal(PhaseGVN* phase, bool can_reshape) override;
+};
+
//------------------------------CallLeafNoFPNode-------------------------------
// CallLeafNode, not using floating point or using it in the same manner as
// the generated code
diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp
index bc259eed2d1..587d5fad8f2 100644
--- a/src/hotspot/share/opto/classes.hpp
+++ b/src/hotspot/share/opto/classes.hpp
@@ -61,6 +61,7 @@ macro(CallDynamicJava)
macro(CallJava)
macro(CallLeaf)
macro(CallLeafNoFP)
+macro(CallLeafPure)
macro(CallLeafVector)
macro(CallRuntime)
macro(CallStaticJava)
@@ -372,6 +373,7 @@ macro(SubI)
macro(SubL)
macro(TailCall)
macro(TailJump)
+macro(Tuple)
macro(MacroLogicV)
macro(ThreadLocal)
macro(Unlock)
diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
index 2b956dcb5d8..9f7f48b9a34 100644
--- a/src/hotspot/share/opto/compile.cpp
+++ b/src/hotspot/share/opto/compile.cpp
@@ -3298,6 +3298,25 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
case Op_Opaque1: // Remove Opaque Nodes before matching
n->subsume_by(n->in(1), this);
break;
+ case Op_CallLeafPure: {
+ // If the pure call is not supported, then lower to a CallLeaf.
+ if (!Matcher::match_rule_supported(Op_CallLeafPure)) {
+ CallNode* call = n->as_Call();
+ CallNode* new_call = new CallLeafNode(call->tf(), call->entry_point(),
+ call->_name, TypeRawPtr::BOTTOM);
+ new_call->init_req(TypeFunc::Control, call->in(TypeFunc::Control));
+ new_call->init_req(TypeFunc::I_O, C->top());
+ new_call->init_req(TypeFunc::Memory, C->top());
+ new_call->init_req(TypeFunc::ReturnAdr, C->top());
+ new_call->init_req(TypeFunc::FramePtr, C->top());
+ for (unsigned int i = TypeFunc::Parms; i < call->tf()->domain()->cnt(); i++) {
+ new_call->init_req(i, call->in(i));
+ }
+ n->subsume_by(new_call, this);
+ }
+ frc.inc_call_count();
+ break;
+ }
case Op_CallStaticJava:
case Op_CallJava:
case Op_CallDynamicJava:
diff --git a/src/hotspot/share/opto/divnode.cpp b/src/hotspot/share/opto/divnode.cpp
index a70194274a7..5dd8be877ff 100644
--- a/src/hotspot/share/opto/divnode.cpp
+++ b/src/hotspot/share/opto/divnode.cpp
@@ -42,19 +42,19 @@
#include <math.h>
-ModFloatingNode::ModFloatingNode(Compile* C, const TypeFunc* tf, const char* name) : CallLeafNode(tf, nullptr, name, TypeRawPtr::BOTTOM) {
+ModFloatingNode::ModFloatingNode(Compile* C, const TypeFunc* tf, address addr, const char* name) : CallLeafPureNode(tf, addr, name, TypeRawPtr::BOTTOM) {
add_flag(Flag_is_macro);
C->add_macro_node(this);
}
-ModDNode::ModDNode(Compile* C, Node* a, Node* b) : ModFloatingNode(C, OptoRuntime::Math_DD_D_Type(), "drem") {
+ModDNode::ModDNode(Compile* C, Node* a, Node* b) : ModFloatingNode(C, OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::drem), "drem") {
init_req(TypeFunc::Parms + 0, a);
init_req(TypeFunc::Parms + 1, C->top());
init_req(TypeFunc::Parms + 2, b);
init_req(TypeFunc::Parms + 3, C->top());
}
-ModFNode::ModFNode(Compile* C, Node* a, Node* b) : ModFloatingNode(C, OptoRuntime::modf_Type(), "frem") {
+ModFNode::ModFNode(Compile* C, Node* a, Node* b) : ModFloatingNode(C, OptoRuntime::modf_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::frem), "frem") {
init_req(TypeFunc::Parms + 0, a);
init_req(TypeFunc::Parms + 1, b);
}
@@ -1516,137 +1516,109 @@ const Type* UModLNode::Value(PhaseGVN* phase) const {
return unsigned_mod_value<TypeLong, julong, jlong>(phase, this);
}
-Node* ModFNode::Ideal(PhaseGVN* phase, bool can_reshape) {
- if (!can_reshape) {
- return nullptr;
- }
- PhaseIterGVN* igvn = phase->is_IterGVN();
-
- bool result_is_unused = proj_out_or_null(TypeFunc::Parms) == nullptr;
- bool not_dead = proj_out_or_null(TypeFunc::Control) != nullptr;
- if (result_is_unused && not_dead) {
- return replace_with_con(igvn, TypeF::make(0.));
- }
-
- // Either input is TOP ==> the result is TOP
- const Type* t1 = phase->type(dividend());
- const Type* t2 = phase->type(divisor());
- if (t1 == Type::TOP || t2 == Type::TOP) {
- return phase->C->top();
- }
-
+const Type* ModFNode::get_result_if_constant(const Type* dividend, const Type* divisor) const {
// If either number is not a constant, we know nothing.
- if ((t1->base() != Type::FloatCon) || (t2->base() != Type::FloatCon)) {
+ if ((dividend->base() != Type::FloatCon) || (divisor->base() != Type::FloatCon)) {
return nullptr; // note: x%x can be either NaN or 0
}
- float f1 = t1->getf();
- float f2 = t2->getf();
- jint x1 = jint_cast(f1); // note: *(int*)&f1, not just (int)f1
- jint x2 = jint_cast(f2);
+ float dividend_f = dividend->getf();
+ float divisor_f = divisor->getf();
+ jint dividend_i = jint_cast(dividend_f); // note: *(int*)&f1, not just (int)f1
+ jint divisor_i = jint_cast(divisor_f);
// If either is a NaN, return an input NaN
- if (g_isnan(f1)) {
- return replace_with_con(igvn, t1);
+ if (g_isnan(dividend_f)) {
+ return dividend;
}
- if (g_isnan(f2)) {
- return replace_with_con(igvn, t2);
+ if (g_isnan(divisor_f)) {
+ return divisor;
}
// If an operand is infinity or the divisor is +/- zero, punt.
- if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jint) {
+ if (!g_isfinite(dividend_f) || !g_isfinite(divisor_f) || divisor_i == 0 || divisor_i == min_jint) {
return nullptr;
}
// We must be modulo'ing 2 float constants.
// Make sure that the sign of the fmod is equal to the sign of the dividend
- jint xr = jint_cast(fmod(f1, f2));
- if ((x1 ^ xr) < 0) {
+ jint xr = jint_cast(fmod(dividend_f, divisor_f));
+ if ((dividend_i ^ xr) < 0) {
xr ^= min_jint;
}
- return replace_with_con(igvn, TypeF::make(jfloat_cast(xr)));
+ return TypeF::make(jfloat_cast(xr));
}
-Node* ModDNode::Ideal(PhaseGVN* phase, bool can_reshape) {
- if (!can_reshape) {
- return nullptr;
- }
- PhaseIterGVN* igvn = phase->is_IterGVN();
-
- bool result_is_unused = proj_out_or_null(TypeFunc::Parms) == nullptr;
- bool not_dead = proj_out_or_null(TypeFunc::Control) != nullptr;
- if (result_is_unused && not_dead) {
- return replace_with_con(igvn, TypeD::make(0.));
- }
-
- // Either input is TOP ==> the result is TOP
- const Type* t1 = phase->type(dividend());
- const Type* t2 = phase->type(divisor());
- if (t1 == Type::TOP || t2 == Type::TOP) {
- return nullptr;
- }
-
+const Type* ModDNode::get_result_if_constant(const Type* dividend, const Type* divisor) const {
// If either number is not a constant, we know nothing.
- if ((t1->base() != Type::DoubleCon) || (t2->base() != Type::DoubleCon)) {
+ if ((dividend->base() != Type::DoubleCon) || (divisor->base() != Type::DoubleCon)) {
return nullptr; // note: x%x can be either NaN or 0
}
- double f1 = t1->getd();
- double f2 = t2->getd();
- jlong x1 = jlong_cast(f1); // note: *(long*)&f1, not just (long)f1
- jlong x2 = jlong_cast(f2);
+ double dividend_d = dividend->getd();
+ double divisor_d = divisor->getd();
+ jlong dividend_l = jlong_cast(dividend_d); // note: *(long*)&f1, not just (long)f1
+ jlong divisor_l = jlong_cast(divisor_d);
// If either is a NaN, return an input NaN
- if (g_isnan(f1)) {
- return replace_with_con(igvn, t1);
+ if (g_isnan(dividend_d)) {
+ return dividend;
}
- if (g_isnan(f2)) {
- return replace_with_con(igvn, t2);
+ if (g_isnan(divisor_d)) {
+ return divisor;
}
// If an operand is infinity or the divisor is +/- zero, punt.
- if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jlong) {
+ if (!g_isfinite(dividend_d) || !g_isfinite(divisor_d) || divisor_l == 0 || divisor_l == min_jlong) {
return nullptr;
}
// We must be modulo'ing 2 double constants.
// Make sure that the sign of the fmod is equal to the sign of the dividend
- jlong xr = jlong_cast(fmod(f1, f2));
- if ((x1 ^ xr) < 0) {
+ jlong xr = jlong_cast(fmod(dividend_d, divisor_d));
+ if ((dividend_l ^ xr) < 0) {
xr ^= min_jlong;
}
- return replace_with_con(igvn, TypeD::make(jdouble_cast(xr)));
+ return TypeD::make(jdouble_cast(xr));
}
-Node* ModFloatingNode::replace_with_con(PhaseIterGVN* phase, const Type* con) {
- Compile* C = phase->C;
- Node* con_node = phase->makecon(con);
- CallProjections projs;
- extract_projections(&projs, false, false);
- phase->replace_node(projs.fallthrough_proj, in(TypeFunc::Control));
- if (projs.fallthrough_catchproj != nullptr) {
- phase->replace_node(projs.fallthrough_catchproj, in(TypeFunc::Control));
- }
- if (projs.fallthrough_memproj != nullptr) {
- phase->replace_node(projs.fallthrough_memproj, in(TypeFunc::Memory));
- }
- if (projs.catchall_memproj != nullptr) {
- phase->replace_node(projs.catchall_memproj, C->top());
- }
- if (projs.fallthrough_ioproj != nullptr) {
- phase->replace_node(projs.fallthrough_ioproj, in(TypeFunc::I_O));
- }
- assert(projs.catchall_ioproj == nullptr, "no exceptions from floating mod");
- assert(projs.catchall_catchproj == nullptr, "no exceptions from floating mod");
- if (projs.resproj != nullptr) {
- phase->replace_node(projs.resproj, con_node);
+Node* ModFloatingNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+ if (can_reshape) {
+ PhaseIterGVN* igvn = phase->is_IterGVN();
+
+ // Either input is TOP ==> the result is TOP
+ const Type* dividend_type = phase->type(dividend());
+ const Type* divisor_type = phase->type(divisor());
+ if (dividend_type == Type::TOP || divisor_type == Type::TOP) {
+ return phase->C->top();
+ }
+ const Type* constant_result = get_result_if_constant(dividend_type, divisor_type);
+ if (constant_result != nullptr) {
+ return make_tuple_of_input_state_and_constant_result(igvn, constant_result);
+ }
}
- phase->replace_node(this, C->top());
- C->remove_macro_node(this);
- disconnect_inputs(C);
- return nullptr;
+
+ return CallLeafPureNode::Ideal(phase, can_reshape);
+}
+
+/* Give a tuple node for ::Ideal to return, made of the input state (control to return addr)
+ * and the given constant result. Idealization of projections will make sure to transparently
+ * propagate the input state and replace the result by the said constant.
+ */
+TupleNode* ModFloatingNode::make_tuple_of_input_state_and_constant_result(PhaseIterGVN* phase, const Type* con) const {
+ Node* con_node = phase->makecon(con);
+ TupleNode* tuple = TupleNode::make(
+ tf()->range(),
+ in(TypeFunc::Control),
+ in(TypeFunc::I_O),
+ in(TypeFunc::Memory),
+ in(TypeFunc::FramePtr),
+ in(TypeFunc::ReturnAdr),
+ con_node);
+
+ return tuple;
}
//=============================================================================
diff --git a/src/hotspot/share/opto/divnode.hpp b/src/hotspot/share/opto/divnode.hpp
index 127e2431b0b..b13460c89f5 100644
--- a/src/hotspot/share/opto/divnode.hpp
+++ b/src/hotspot/share/opto/divnode.hpp
@@ -156,40 +156,45 @@ class ModLNode : public Node {
};
// Base class for float and double modulus
-class ModFloatingNode : public CallLeafNode {
+class ModFloatingNode : public CallLeafPureNode {
+ TupleNode* make_tuple_of_input_state_and_constant_result(PhaseIterGVN* phase, const Type* con) const;
+
protected:
- Node* replace_with_con(PhaseIterGVN* phase, const Type* con);
+ virtual Node* dividend() const = 0;
+ virtual Node* divisor() const = 0;
+ virtual const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const = 0;
public:
- ModFloatingNode(Compile* C, const TypeFunc* tf, const char *name);
+ ModFloatingNode(Compile* C, const TypeFunc* tf, address addr, const char* name);
+ Node* Ideal(PhaseGVN* phase, bool can_reshape) override;
};
// Float Modulus
class ModFNode : public ModFloatingNode {
private:
- Node* dividend() const { return in(TypeFunc::Parms + 0); }
- Node* divisor() const { return in(TypeFunc::Parms + 1); }
+ Node* dividend() const override { return in(TypeFunc::Parms + 0); }
+ Node* divisor() const override { return in(TypeFunc::Parms + 1); }
+ const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const override;
public:
ModFNode(Compile* C, Node* a, Node* b);
- virtual int Opcode() const;
- virtual uint ideal_reg() const { return Op_RegF; }
- virtual uint size_of() const { return sizeof(*this); }
- virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+ int Opcode() const override;
+ uint ideal_reg() const override { return Op_RegF; }
+ uint size_of() const override { return sizeof(*this); }
};
// Double Modulus
class ModDNode : public ModFloatingNode {
private:
- Node* dividend() const { return in(TypeFunc::Parms + 0); }
- Node* divisor() const { return in(TypeFunc::Parms + 2); }
+ Node* dividend() const override { return in(TypeFunc::Parms + 0); }
+ Node* divisor() const override { return in(TypeFunc::Parms + 2); }
+ const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const override;
public:
ModDNode(Compile* C, Node* a, Node* b);
- virtual int Opcode() const;
- virtual uint ideal_reg() const { return Op_RegD; }
- virtual uint size_of() const { return sizeof(*this); }
- virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+ int Opcode() const override;
+ uint ideal_reg() const override { return Op_RegD; }
+ uint size_of() const override { return sizeof(*this); }
};
//------------------------------UModINode---------------------------------------
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index 20feca26ede..1b8b7008578 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -1880,14 +1880,20 @@ Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_p
// after the call, if this call has restricted memory effects.
Node* GraphKit::set_predefined_input_for_runtime_call(SafePointNode* call, Node* narrow_mem) {
// Set fixed predefined input arguments
- Node* memory = reset_memory();
- Node* m = narrow_mem == nullptr ? memory : narrow_mem;
- call->init_req( TypeFunc::Control, control() );
- call->init_req( TypeFunc::I_O, top() ); // does no i/o
- call->init_req( TypeFunc::Memory, m ); // may gc ptrs
- call->init_req( TypeFunc::FramePtr, frameptr() );
- call->init_req( TypeFunc::ReturnAdr, top() );
- return memory;
+ call->init_req(TypeFunc::Control, control());
+ call->init_req(TypeFunc::I_O, top()); // does no i/o
+ call->init_req(TypeFunc::ReturnAdr, top());
+ if (call->is_CallLeafPure()) {
+ call->init_req(TypeFunc::Memory, top());
+ call->init_req(TypeFunc::FramePtr, top());
+ return nullptr;
+ } else {
+ Node* memory = reset_memory();
+ Node* m = narrow_mem == nullptr ? memory : narrow_mem;
+ call->init_req(TypeFunc::Memory, m); // may gc ptrs
+ call->init_req(TypeFunc::FramePtr, frameptr());
+ return memory;
+ }
}
//-------------------set_predefined_output_for_runtime_call--------------------
@@ -1905,6 +1911,11 @@ void GraphKit::set_predefined_output_for_runtime_call(Node* call,
const TypePtr* hook_mem) {
// no i/o
set_control(_gvn.transform( new ProjNode(call,TypeFunc::Control) ));
+ if (call->is_CallLeafPure()) {
+ // Pure function have only control (for now) and data output, in particular
+ // they don't touch the memory, so we don't want a memory proj that is set after.
+ return;
+ }
if (keep_mem) {
// First clone the existing memory state
set_all_memory(keep_mem);
@@ -2491,6 +2502,8 @@ Node* GraphKit::make_runtime_call(int flags,
} else if (flags & RC_VECTOR){
uint num_bits = call_type->range()->field_at(TypeFunc::Parms)->is_vect()->length_in_bytes() * BitsPerByte;
call = new CallLeafVectorNode(call_type, call_addr, call_name, adr_type, num_bits);
+ } else if (flags & RC_PURE) {
+ call = new CallLeafPureNode(call_type, call_addr, call_name, adr_type);
} else {
call = new CallLeafNode(call_type, call_addr, call_name, adr_type);
}
diff --git a/src/hotspot/share/opto/graphKit.hpp b/src/hotspot/share/opto/graphKit.hpp
index 28773d75333..806a211d7e2 100644
--- a/src/hotspot/share/opto/graphKit.hpp
+++ b/src/hotspot/share/opto/graphKit.hpp
@@ -784,6 +784,7 @@ class GraphKit : public Phase {
RC_NARROW_MEM = 16, // input memory is same as output
RC_UNCOMMON = 32, // freq. expected to be like uncommon trap
RC_VECTOR = 64, // CallLeafVectorNode
+ RC_PURE = 128, // CallLeaf is pure
RC_LEAF = 0 // null value: no flags set
};
diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp
index f74af38387c..12960d101a8 100644
--- a/src/hotspot/share/opto/library_call.cpp
+++ b/src/hotspot/share/opto/library_call.cpp
@@ -1802,7 +1802,7 @@ bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, c
Node* b = (call_type == OptoRuntime::Math_DD_D_Type()) ? argument(2) : nullptr;
const TypePtr* no_memory_effects = nullptr;
- Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
+ Node* trig = make_runtime_call(RC_LEAF | RC_PURE, call_type, funcAddr, funcName,
no_memory_effects,
a, top(), b, b ? top() : nullptr);
Node* value = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+0));
diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp
index acf1dbabf19..aafc5d3c170 100644
--- a/src/hotspot/share/opto/macro.cpp
+++ b/src/hotspot/share/opto/macro.cpp
@@ -2638,17 +2638,14 @@ bool PhaseMacroExpand::expand_macro_nodes() {
switch (n->Opcode()) {
case Op_ModD:
case Op_ModF: {
- bool is_drem = n->Opcode() == Op_ModD;
CallNode* mod_macro = n->as_Call();
- CallNode* call = new CallLeafNode(mod_macro->tf(),
- is_drem ? CAST_FROM_FN_PTR(address, SharedRuntime::drem)
- : CAST_FROM_FN_PTR(address, SharedRuntime::frem),
- is_drem ? "drem" : "frem", TypeRawPtr::BOTTOM);
+ CallNode* call = new CallLeafPureNode(mod_macro->tf(), mod_macro->entry_point(),
+ mod_macro->_name, TypeRawPtr::BOTTOM);
call->init_req(TypeFunc::Control, mod_macro->in(TypeFunc::Control));
- call->init_req(TypeFunc::I_O, mod_macro->in(TypeFunc::I_O));
- call->init_req(TypeFunc::Memory, mod_macro->in(TypeFunc::Memory));
- call->init_req(TypeFunc::ReturnAdr, mod_macro->in(TypeFunc::ReturnAdr));
- call->init_req(TypeFunc::FramePtr, mod_macro->in(TypeFunc::FramePtr));
+ call->init_req(TypeFunc::I_O, C->top());
+ call->init_req(TypeFunc::Memory, C->top());
+ call->init_req(TypeFunc::ReturnAdr, C->top());
+ call->init_req(TypeFunc::FramePtr, C->top());
for (unsigned int i = 0; i < mod_macro->tf()->domain()->cnt() - TypeFunc::Parms; i++) {
call->init_req(TypeFunc::Parms + i, mod_macro->in(TypeFunc::Parms + i));
}
diff --git a/src/hotspot/share/opto/multnode.cpp b/src/hotspot/share/opto/multnode.cpp
index 736e84315ee..f429d5daac0 100644
--- a/src/hotspot/share/opto/multnode.cpp
+++ b/src/hotspot/share/opto/multnode.cpp
@@ -120,6 +120,10 @@ const TypePtr *ProjNode::adr_type() const {
if (bottom_type() == Type::MEMORY) {
// in(0) might be a narrow MemBar; otherwise we will report TypePtr::BOTTOM
Node* ctrl = in(0);
+ if (ctrl->Opcode() == Op_Tuple) {
+ // Jumping over Tuples: the i-th projection of a Tuple is the i-th input of the Tuple.
+ ctrl = ctrl->in(_con);
+ }
if (ctrl == nullptr) return nullptr; // node is dead
const TypePtr* adr_type = ctrl->adr_type();
#ifdef ASSERT
@@ -163,6 +167,15 @@ void ProjNode::check_con() const {
assert(_con < t->is_tuple()->cnt(), "ProjNode::_con must be in range");
}
+//------------------------------Identity---------------------------------------
+Node* ProjNode::Identity(PhaseGVN* phase) {
+ if (in(0) != nullptr && in(0)->Opcode() == Op_Tuple) {
+ // Jumping over Tuples: the i-th projection of a Tuple is the i-th input of the Tuple.
+ return in(0)->in(_con);
+ }
+ return this;
+}
+
//------------------------------Value------------------------------------------
const Type* ProjNode::Value(PhaseGVN* phase) const {
if (in(0) == nullptr) return Type::TOP;
diff --git a/src/hotspot/share/opto/multnode.hpp b/src/hotspot/share/opto/multnode.hpp
index dff2caed38d..834dcfdca6d 100644
--- a/src/hotspot/share/opto/multnode.hpp
+++ b/src/hotspot/share/opto/multnode.hpp
@@ -82,6 +82,7 @@ class ProjNode : public Node {
virtual const Type *bottom_type() const;
virtual const TypePtr *adr_type() const;
virtual bool pinned() const;
+ virtual Node* Identity(PhaseGVN* phase);
virtual const Type* Value(PhaseGVN* phase) const;
virtual uint ideal_reg() const;
virtual const RegMask &out_RegMask() const;
@@ -105,4 +106,49 @@ class ProjNode : public Node {
ProjNode* other_if_proj() const;
};
+/* Tuples are used to avoid manual graph surgery. When a node with Proj outputs (such as a call)
+ * must be removed and its ouputs replaced by its input, or some other value, we can make its
+ * ::Ideal return a tuple of what we want for each output: the ::Identity of output Proj will
+ * take care to jump over the Tuple and directly pick up the right input of the Tuple.
+ *
+ * For instance, if a function call is proven to have no side effect and return the constant 0,
+ * we can replace it with the 6-tuple:
+ * (control input, IO input, memory input, frame ptr input, return addr input, Con:0)
+ * all the output projections will pick up the input of the now gone call, except for the result
+ * projection that is replaced by 0.
+ *
+ * Using TupleNode avoid manual graph surgery and leave that to our expert surgeon: IGVN.
+ * Since the user of a Tuple are expected to be Proj, when creating a tuple during idealization,
+ * the output Proj should be enqueued for IGVN immediately after, and the tuple should not survive
+ * after the current IGVN.
+ */
+class TupleNode : public MultiNode {
+ const TypeTuple* _tf;
+
+ template <typename... NN>
+ static void make_helper(TupleNode* tn, uint i, Node* node, NN... nn) {
+ tn->set_req(i, node);
+ make_helper(tn, i + 1, nn...);
+ }
+
+ static void make_helper(TupleNode*, uint) {}
+
+public:
+ TupleNode(const TypeTuple* tf) : MultiNode(tf->cnt()), _tf(tf) {}
+
+ int Opcode() const override;
+ const Type* bottom_type() const override { return _tf; }
+
+ /* Give as many `Node*` as you want in the `nn` pack:
+ * TupleNode::make(tf, input1)
+ * TupleNode::make(tf, input1, input2, input3, input4)
+ */
+ template <typename... NN>
+ static TupleNode* make(const TypeTuple* tf, NN... nn) {
+ TupleNode* tn = new TupleNode(tf);
+ make_helper(tn, 0, nn...);
+ return tn;
+ }
+};
+
#endif // SHARE_OPTO_MULTNODE_HPP
diff --git a/src/hotspot/share/opto/node.cpp b/src/hotspot/share/opto/node.cpp
index 8f6c67c16f5..5ecc038954d 100644
--- a/src/hotspot/share/opto/node.cpp
+++ b/src/hotspot/share/opto/node.cpp
@@ -2946,23 +2946,13 @@ bool Node::is_dead_loop_safe() const {
bool Node::is_div_or_mod(BasicType bt) const { return Opcode() == Op_Div(bt) || Opcode() == Op_Mod(bt) ||
Opcode() == Op_UDiv(bt) || Opcode() == Op_UMod(bt); }
-bool Node::is_pure_function() const {
- switch (Opcode()) {
- case Op_ModD:
- case Op_ModF:
- return true;
- default:
- return false;
- }
-}
-
// `maybe_pure_function` is assumed to be the input of `this`. This is a bit redundant,
// but we already have and need maybe_pure_function in all the call sites, so
// it makes it obvious that the `maybe_pure_function` is the same node as in the caller,
// while it takes more thinking to realize that a locally computed in(0) must be equal to
// the local in the caller.
bool Node::is_data_proj_of_pure_function(const Node* maybe_pure_function) const {
- return Opcode() == Op_Proj && as_Proj()->_con == TypeFunc::Parms && maybe_pure_function->is_pure_function();
+ return Opcode() == Op_Proj && as_Proj()->_con == TypeFunc::Parms && maybe_pure_function->is_CallLeafPure();
}
//=============================================================================
diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp
index 2bbb10879f5..dc0ac474c4b 100644
--- a/src/hotspot/share/opto/node.hpp
+++ b/src/hotspot/share/opto/node.hpp
@@ -54,6 +54,7 @@ class CallDynamicJavaNode;
class CallJavaNode;
class CallLeafNode;
class CallLeafNoFPNode;
+class CallLeafPureNode;
class CallNode;
class CallRuntimeNode;
class CallStaticJavaNode;
@@ -673,6 +674,7 @@ class Node {
DEFINE_CLASS_ID(CallRuntime, Call, 1)
DEFINE_CLASS_ID(CallLeaf, CallRuntime, 0)
DEFINE_CLASS_ID(CallLeafNoFP, CallLeaf, 0)
+ DEFINE_CLASS_ID(CallLeafPure, CallLeaf, 1)
DEFINE_CLASS_ID(Allocate, Call, 2)
DEFINE_CLASS_ID(AllocateArray, Allocate, 0)
DEFINE_CLASS_ID(AbstractLock, Call, 3)
@@ -907,6 +909,7 @@ class Node {
DEFINE_CLASS_QUERY(CallJava)
DEFINE_CLASS_QUERY(CallLeaf)
DEFINE_CLASS_QUERY(CallLeafNoFP)
+ DEFINE_CLASS_QUERY(CallLeafPure)
DEFINE_CLASS_QUERY(CallRuntime)
DEFINE_CLASS_QUERY(CallStaticJava)
DEFINE_CLASS_QUERY(Catch)
@@ -1289,8 +1292,6 @@ class Node {
bool is_div_or_mod(BasicType bt) const;
- bool is_pure_function() const;
-
bool is_data_proj_of_pure_function(const Node* maybe_pure_function) const;
//----------------- Printing, etc
diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp
index 1a4c3c91c4f..04b6e49b620 100644
--- a/src/hotspot/share/opto/parse2.cpp
+++ b/src/hotspot/share/opto/parse2.cpp
@@ -1097,11 +1097,11 @@ void Parse::jump_switch_ranges(Node* key_val, SwitchRange *lo, SwitchRange *hi,
Node* Parse::floating_point_mod(Node* a, Node* b, BasicType type) {
assert(type == BasicType::T_FLOAT || type == BasicType::T_DOUBLE, "only float and double are floating points");
- CallNode* mod = type == BasicType::T_DOUBLE ? static_cast<CallNode*>(new ModDNode(C, a, b)) : new ModFNode(C, a, b);
+ CallLeafPureNode* mod = type == BasicType::T_DOUBLE ? static_cast<CallLeafPureNode*>(new ModDNode(C, a, b)) : new ModFNode(C, a, b);
- Node* prev_mem = set_predefined_input_for_runtime_call(mod);
- mod = _gvn.transform(mod)->as_Call();
- set_predefined_output_for_runtime_call(mod, prev_mem, TypeRawPtr::BOTTOM);
+ set_predefined_input_for_runtime_call(mod);
+ mod = _gvn.transform(mod)->as_CallLeafPure();
+ set_predefined_output_for_runtime_call(mod);
Node* result = _gvn.transform(new ProjNode(mod, TypeFunc::Parms + 0));
record_for_igvn(mod);
return result;
--
2.53.0

View File

@ -0,0 +1,626 @@
From 1f61b6754b5abce07db45fd385a19c2cf9296a08 Mon Sep 17 00:00:00 2001
From: Kangcheng Xu <kxu@redhat.com>
Date: Mon, 27 Apr 2026 10:14:39 -0400
Subject: [PATCH 2/2] Backport 7f631ea958e30246b927f3524f0fbf37334422b9
---
src/hotspot/share/opto/callnode.cpp | 175 ++++++++++++++
src/hotspot/share/opto/callnode.hpp | 17 ++
src/hotspot/share/opto/classes.hpp | 1 +
src/hotspot/share/opto/library_call.cpp | 62 +----
src/hotspot/share/opto/macro.cpp | 19 +-
.../intrinsics/math/PowDNodeTests.java | 218 ++++++++++++++++++
.../compiler/lib/ir_framework/IRNode.java | 11 +
7 files changed, 437 insertions(+), 66 deletions(-)
create mode 100644 test/hotspot/jtreg/compiler/intrinsics/math/PowDNodeTests.java
diff --git a/src/hotspot/share/opto/callnode.cpp b/src/hotspot/share/opto/callnode.cpp
index fc4b0c35dff..cb6cc2082b3 100644
--- a/src/hotspot/share/opto/callnode.cpp
+++ b/src/hotspot/share/opto/callnode.cpp
@@ -42,6 +42,7 @@
#include "opto/rootnode.hpp"
#include "opto/runtime.hpp"
#include "runtime/sharedRuntime.hpp"
+#include "runtime/stubRoutines.hpp"
#include "utilities/powerOfTwo.hpp"
#include "code/vmreg.hpp"
@@ -1354,6 +1355,25 @@ TupleNode* CallLeafPureNode::make_tuple_of_input_state_and_top_return_values(con
return tuple;
}
+CallLeafPureNode* CallLeafPureNode::inline_call_leaf_pure_node(Node* control) const {
+ Node* top = Compile::current()->top();
+ if (control == nullptr) {
+ control = in(TypeFunc::Control);
+ }
+
+ CallLeafPureNode* call = new CallLeafPureNode(tf(), entry_point(), _name, nullptr);
+ call->init_req(TypeFunc::Control, control);
+ call->init_req(TypeFunc::I_O, top);
+ call->init_req(TypeFunc::Memory, top);
+ call->init_req(TypeFunc::ReturnAdr, top);
+ call->init_req(TypeFunc::FramePtr, top);
+ for (unsigned int i = 0; i < tf()->domain()->cnt() - TypeFunc::Parms; i++) {
+ call->init_req(TypeFunc::Parms + i, in(TypeFunc::Parms + i));
+ }
+
+ return call;
+}
+
Node* CallLeafPureNode::Ideal(PhaseGVN* phase, bool can_reshape) {
if (is_dead()) {
return nullptr;
@@ -2424,3 +2444,158 @@ bool CallNode::may_modify_arraycopy_helper(const TypeOopPtr* dest_t, const TypeO
return true;
}
+
+PowDNode::PowDNode(Compile* C, Node* base, Node* exp)
+ : CallLeafPureNode(
+ OptoRuntime::Math_DD_D_Type(),
+ StubRoutines::dpow() != nullptr ? StubRoutines::dpow() : CAST_FROM_FN_PTR(address, SharedRuntime::dpow),
+ "pow",
+ nullptr) {
+ add_flag(Flag_is_macro);
+ C->add_macro_node(this);
+
+ init_req(TypeFunc::Parms + 0, base);
+ init_req(TypeFunc::Parms + 1, C->top()); // double slot padding
+ init_req(TypeFunc::Parms + 2, exp);
+ init_req(TypeFunc::Parms + 3, C->top()); // double slot padding
+}
+
+const Type* PowDNode::Value(PhaseGVN* phase) const {
+ const Type* t_base = phase->type(base());
+ const Type* t_exp = phase->type(exp());
+
+ if (t_base == Type::TOP || t_exp == Type::TOP) {
+ return Type::TOP;
+ }
+
+ const TypeD* base_con = t_base->isa_double_constant();
+ const TypeD* exp_con = t_exp->isa_double_constant();
+ const TypeD* result_t = nullptr;
+
+ // constant folding: both inputs are constants
+ if (base_con != nullptr && exp_con != nullptr) {
+ result_t = TypeD::make(SharedRuntime::dpow(base_con->getd(), exp_con->getd()));
+ }
+
+ // Special cases when only the exponent is known:
+ if (exp_con != nullptr) {
+ double e = exp_con->getd();
+
+ // If the second argument is positive or negative zero, then the result is 1.0.
+ // i.e., pow(x, +/-0.0D) => 1.0
+ if (e == 0.0) { // true for both -0.0 and +0.0
+ result_t = TypeD::ONE;
+ }
+
+ // If the second argument is NaN, then the result is NaN.
+ // i.e., pow(x, NaN) => NaN
+ if (g_isnan(e)) {
+ result_t = TypeD::make(NAN);
+ }
+ }
+
+ if (result_t != nullptr) {
+ // We can't simply return a TypeD here, it must be a tuple type to be compatible with call nodes.
+ const Type** fields = TypeTuple::fields(2);
+ fields[TypeFunc::Parms + 0] = result_t;
+ fields[TypeFunc::Parms + 1] = Type::HALF;
+ return TypeTuple::make(TypeFunc::Parms + 2, fields);
+ }
+
+ return tf()->range();
+}
+
+Node* PowDNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+ if (!can_reshape) {
+ return nullptr; // wait for igvn
+ }
+
+ PhaseIterGVN* igvn = phase->is_IterGVN();
+ Node* base = this->base();
+ Node* exp = this->exp();
+
+ const Type* t_exp = phase->type(exp);
+ const TypeD* exp_con = t_exp->isa_double_constant();
+
+ // Special cases when only the exponent is known:
+ if (exp_con != nullptr) {
+ double e = exp_con->getd();
+
+ // If the second argument is 1.0, then the result is the same as the first argument.
+ // i.e., pow(x, 1.0) => x
+ if (e == 1.0) {
+ return make_tuple_of_input_state_and_result(igvn, base);
+ }
+
+ // If the second argument is 2.0, then strength reduce to multiplications.
+ // i.e., pow(x, 2.0) => x * x
+ if (e == 2.0) {
+ Node* mul = igvn->transform(new MulDNode(base, base));
+ return make_tuple_of_input_state_and_result(igvn, mul);
+ }
+
+ // If the second argument is 0.5, the strength reduce to square roots.
+ // i.e., pow(x, 0.5) => sqrt(x) iff x > 0
+ if (e == 0.5 && Matcher::match_rule_supported(Op_SqrtD)) {
+ Node* ctrl = in(TypeFunc::Control);
+ Node* zero = igvn->zerocon(T_DOUBLE);
+
+ // According to the API specs, pow(-0.0, 0.5) = 0.0 and sqrt(-0.0) = -0.0.
+ // So pow(-0.0, 0.5) shouldn't be replaced with sqrt(-0.0).
+ // -0.0/+0.0 are both excluded since floating-point comparison doesn't distinguish -0.0 from +0.0.
+ Node* cmp = igvn->register_new_node_with_optimizer(new CmpDNode(base, zero));
+ Node* test = igvn->register_new_node_with_optimizer(new BoolNode(cmp, BoolTest::le));
+
+ IfNode* iff = new IfNode(ctrl, test, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
+ igvn->register_new_node_with_optimizer(iff);
+ Node* if_slow = igvn->register_new_node_with_optimizer(new IfTrueNode(iff)); // x <= 0
+ Node* if_fast = igvn->register_new_node_with_optimizer(new IfFalseNode(iff)); // x > 0
+
+ // slow path: call pow(x, 0.5)
+ Node* call = igvn->register_new_node_with_optimizer(inline_call_leaf_pure_node(if_slow));
+ Node* call_ctrl = igvn->register_new_node_with_optimizer(new ProjNode(call, TypeFunc::Control));
+ Node* call_result = igvn->register_new_node_with_optimizer(new ProjNode(call, TypeFunc::Parms + 0));
+
+ // fast path: sqrt(x)
+ Node* sqrt = igvn->register_new_node_with_optimizer(new SqrtDNode(igvn->C, if_fast, base));
+
+ // merge paths
+ RegionNode* region = new RegionNode(3);
+ igvn->register_new_node_with_optimizer(region);
+ region->init_req(1, call_ctrl); // slow path
+ region->init_req(2, if_fast); // fast path
+
+ PhiNode* phi = new PhiNode(region, Type::DOUBLE);
+ igvn->register_new_node_with_optimizer(phi);
+ phi->init_req(1, call_result); // slow: pow() result
+ phi->init_req(2, sqrt); // fast: sqrt() result
+
+ igvn->C->set_has_split_ifs(true); // Has chance for split-if optimization
+
+ return make_tuple_of_input_state_and_result(igvn, phi, region);
+ }
+ }
+
+ return CallLeafPureNode::Ideal(phase, can_reshape);
+}
+
+// We can't simply have Ideal() returning a Con or MulNode since the users are still expecting a Call node, but we could
+// produce a tuple that follows the same pattern so users can still get control, io, memory, etc..
+TupleNode* PowDNode::make_tuple_of_input_state_and_result(PhaseIterGVN* phase, Node* result, Node* control) {
+ if (control == nullptr) {
+ control = in(TypeFunc::Control);
+ }
+
+ Compile* C = phase->C;
+ C->remove_macro_node(this);
+ TupleNode* tuple = TupleNode::make(
+ tf()->range(),
+ control,
+ in(TypeFunc::I_O),
+ in(TypeFunc::Memory),
+ in(TypeFunc::FramePtr),
+ in(TypeFunc::ReturnAdr),
+ result,
+ C->top());
+ return tuple;
+}
diff --git a/src/hotspot/share/opto/callnode.hpp b/src/hotspot/share/opto/callnode.hpp
index 2462a88143f..bb87746a3f6 100644
--- a/src/hotspot/share/opto/callnode.hpp
+++ b/src/hotspot/share/opto/callnode.hpp
@@ -953,6 +953,8 @@ class CallLeafPureNode : public CallLeafNode {
}
int Opcode() const override;
Node* Ideal(PhaseGVN* phase, bool can_reshape) override;
+
+ CallLeafPureNode* inline_call_leaf_pure_node(Node* control = nullptr) const;
};
//------------------------------CallLeafNoFPNode-------------------------------
@@ -1304,4 +1306,19 @@ class UnlockNode : public AbstractLockNode {
JVMState* dbg_jvms() const { return nullptr; }
#endif
};
+
+//------------------------------PowDNode--------------------------------------
+class PowDNode : public CallLeafPureNode {
+ TupleNode* make_tuple_of_input_state_and_result(PhaseIterGVN* phase, Node* result, Node* control = nullptr);
+
+public:
+ PowDNode(Compile* C, Node* base, Node* exp);
+ int Opcode() const override;
+ const Type* Value(PhaseGVN* phase) const override;
+ Node* Ideal(PhaseGVN* phase, bool can_reshape) override;
+
+ Node* base() const { return in(TypeFunc::Parms + 0); }
+ Node* exp() const { return in(TypeFunc::Parms + 2); }
+};
+
#endif // SHARE_OPTO_CALLNODE_HPP
diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp
index 587d5fad8f2..b7ba16e99a0 100644
--- a/src/hotspot/share/opto/classes.hpp
+++ b/src/hotspot/share/opto/classes.hpp
@@ -283,6 +283,7 @@ macro(OpaqueZeroTripGuard)
macro(OpaqueNotNull)
macro(OpaqueInitializedAssertionPredicate)
macro(OpaqueTemplateAssertionPredicate)
+macro(PowD)
macro(ProfileBoolean)
macro(OrI)
macro(OrL)
diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp
index 12960d101a8..6c71a61ba75 100644
--- a/src/hotspot/share/opto/library_call.cpp
+++ b/src/hotspot/share/opto/library_call.cpp
@@ -1817,61 +1817,17 @@ bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, c
//------------------------------inline_math_pow-----------------------------
bool LibraryCallKit::inline_math_pow() {
+ Node* base = argument(0);
Node* exp = argument(2);
- const TypeD* d = _gvn.type(exp)->isa_double_constant();
- if (d != nullptr) {
- if (d->getd() == 2.0) {
- // Special case: pow(x, 2.0) => x * x
- Node* base = argument(0);
- set_result(_gvn.transform(new MulDNode(base, base)));
- return true;
- } else if (d->getd() == 0.5 && Matcher::match_rule_supported(Op_SqrtD)) {
- // Special case: pow(x, 0.5) => sqrt(x)
- Node* base = argument(0);
- Node* zero = _gvn.zerocon(T_DOUBLE);
-
- RegionNode* region = new RegionNode(3);
- Node* phi = new PhiNode(region, Type::DOUBLE);
-
- Node* cmp = _gvn.transform(new CmpDNode(base, zero));
- // According to the API specs, pow(-0.0, 0.5) = 0.0 and sqrt(-0.0) = -0.0.
- // So pow(-0.0, 0.5) shouldn't be replaced with sqrt(-0.0).
- // -0.0/+0.0 are both excluded since floating-point comparison doesn't distinguish -0.0 from +0.0.
- Node* test = _gvn.transform(new BoolNode(cmp, BoolTest::le));
-
- Node* if_pow = generate_slow_guard(test, nullptr);
- Node* value_sqrt = _gvn.transform(new SqrtDNode(C, control(), base));
- phi->init_req(1, value_sqrt);
- region->init_req(1, control());
-
- if (if_pow != nullptr) {
- set_control(if_pow);
- address target = StubRoutines::dpow() != nullptr ? StubRoutines::dpow() :
- CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
- const TypePtr* no_memory_effects = nullptr;
- Node* trig = make_runtime_call(RC_LEAF, OptoRuntime::Math_DD_D_Type(), target, "POW",
- no_memory_effects, base, top(), exp, top());
- Node* value_pow = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+0));
-#ifdef ASSERT
- Node* value_top = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+1));
- assert(value_top == top(), "second value must be top");
-#endif
- phi->init_req(2, value_pow);
- region->init_req(2, _gvn.transform(new ProjNode(trig, TypeFunc::Control)));
- }
-
- C->set_has_split_ifs(true); // Has chance for split-if optimization
- set_control(_gvn.transform(region));
- record_for_igvn(region);
- set_result(_gvn.transform(phi));
- return true;
- }
- }
-
- return StubRoutines::dpow() != nullptr ?
- runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
- runtime_math(OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
+ CallNode* pow = new PowDNode(C, base, exp);
+ set_predefined_input_for_runtime_call(pow);
+ pow = _gvn.transform(pow)->as_CallLeafPure();
+ set_predefined_output_for_runtime_call(pow);
+ Node* result = _gvn.transform(new ProjNode(pow, TypeFunc::Parms + 0));
+ record_for_igvn(pow);
+ set_result(result);
+ return true;
}
//------------------------------inline_math_native-----------------------------
diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp
index aafc5d3c170..a28043c8d8f 100644
--- a/src/hotspot/share/opto/macro.cpp
+++ b/src/hotspot/share/opto/macro.cpp
@@ -2484,6 +2484,7 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
assert(n->Opcode() == Op_LoopLimit ||
n->Opcode() == Op_ModD ||
n->Opcode() == Op_ModF ||
+ n->Opcode() == Op_PowD ||
n->is_OpaqueNotNull() ||
n->is_OpaqueInitializedAssertionPredicate() ||
n->Opcode() == Op_MaxL ||
@@ -2637,19 +2638,11 @@ bool PhaseMacroExpand::expand_macro_nodes() {
default:
switch (n->Opcode()) {
case Op_ModD:
- case Op_ModF: {
- CallNode* mod_macro = n->as_Call();
- CallNode* call = new CallLeafPureNode(mod_macro->tf(), mod_macro->entry_point(),
- mod_macro->_name, TypeRawPtr::BOTTOM);
- call->init_req(TypeFunc::Control, mod_macro->in(TypeFunc::Control));
- call->init_req(TypeFunc::I_O, C->top());
- call->init_req(TypeFunc::Memory, C->top());
- call->init_req(TypeFunc::ReturnAdr, C->top());
- call->init_req(TypeFunc::FramePtr, C->top());
- for (unsigned int i = 0; i < mod_macro->tf()->domain()->cnt() - TypeFunc::Parms; i++) {
- call->init_req(TypeFunc::Parms + i, mod_macro->in(TypeFunc::Parms + i));
- }
- _igvn.replace_node(mod_macro, call);
+ case Op_ModF:
+ case Op_PowD: {
+ CallLeafPureNode* call_macro = n->as_CallLeafPure();
+ CallLeafPureNode* call = call_macro->inline_call_leaf_pure_node();
+ _igvn.replace_node(call_macro, call);
transform_later(call);
break;
}
diff --git a/test/hotspot/jtreg/compiler/intrinsics/math/PowDNodeTests.java b/test/hotspot/jtreg/compiler/intrinsics/math/PowDNodeTests.java
new file mode 100644
index 00000000000..e28cc5ab346
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/intrinsics/math/PowDNodeTests.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2026, IBM and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package compiler.intrinsics.math;
+
+import jdk.test.lib.Asserts;
+
+import compiler.lib.ir_framework.*;
+import compiler.lib.generators.*;
+import static compiler.lib.generators.Generators.*;
+
+import java.util.Random;
+
+/*
+ * @test
+ * @bug 8378713
+ * @key randomness
+ * @summary Math.pow(base, exp) should constant propagate
+ * @library /test/lib /
+ * @run driver ${test.main.class}
+ */
+public class PowDNodeTests {
+ public static final Generator<Double> UNIFORMS = G.uniformDoubles(); // [0, 1)
+
+ public static final double B = UNIFORMS.next() * 1000.0d;
+ public static final double E = UNIFORMS.next() * 1000.0d + 3.0d; // e >= 3 to avoid strength reduction code
+
+ public static void main(String[] args) {
+ TestFramework.run();
+
+ testCorrectness();
+ }
+
+ // Test 1: pow(2.0, 10.0) -> 1024.0
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ public static double constantLiteralFolding() {
+ return Math.pow(2.0, 10.0); // should fold to 1024.0
+ }
+
+ // Test 2: pow(final B, final E) -> B^E
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ public static double constantStaticFolding() {
+ return Math.pow(B, E); // should fold to B^E
+ }
+
+ // Test 3: pow(b, 0.0) -> 1.0
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ @Arguments(values = {Argument.RANDOM_EACH})
+ public static double expZero(double b) {
+ return Math.pow(b, 0.0);
+ }
+
+ // Test 4: pow(b, 1.0) -> b (identity)
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ @Arguments(values = {Argument.RANDOM_EACH})
+ public static double expOne(double b) {
+ return Math.pow(b, 1.0);
+ }
+
+ // Test 5: pow(b, NaN) -> NaN
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ @Arguments(values = {Argument.RANDOM_EACH})
+ public static double expNaN(double b) {
+ return Math.pow(b, Double.NaN);
+ }
+
+ // Test 6: pow(b, 2.0) -> b * b
+ // More tests in TestPow2Opt.java
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ @IR(counts = {IRNode.MUL_D, "1"})
+ @Arguments(values = {Argument.RANDOM_EACH})
+ public static double expTwo(double b) {
+ return Math.pow(b, 2.0);
+ }
+
+ // Test 7: pow(b, 0.5) -> b <= 0.0 ? pow(b, 0.5) : sqrt(b)
+ // More tests in TestPow0Dot5Opt.java
+ @Test
+ @IR(counts = {IRNode.IF, "1"})
+ @IR(counts = {IRNode.SQRT_D, "1"})
+ @IR(counts = {".*CallLeaf.*pow.*", "1"}, phase = CompilePhase.BEFORE_MATCHING)
+ @Arguments(values = {Argument.RANDOM_EACH})
+ public static double expDot5(double b) {
+ return Math.pow(b, 0.5); // expand to: if (b > 0) { sqrt(b) } else { call(b) }
+ }
+
+ // Test 8: non-constant exponent stays as call
+ @Test
+ @IR(counts = {IRNode.POW_D, "1"})
+ @Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
+ public static double nonConstant(double b, double e) {
+ return Math.pow(b, e);
+ }
+
+ // Test 9: late constant discovery on base (after loop opts)
+ @Test
+ @IR(counts = {IRNode.POW_D, "1"}, phase = CompilePhase.AFTER_PARSING)
+ @IR(failOn = {IRNode.POW_D})
+ public static double lateBaseConstant() {
+ double base = 0;
+ for (int i = 0; i < 4; i++) {
+ if ((i % 2) == 0) {
+ base = B;
+ }
+ }
+ // After loop opts, base == B (constant), so pow(B, E) folds
+ return Math.pow(base, E);
+ }
+
+ // Test 10: late constant discovery on exp (after loop opts)
+ @Test
+ @IR(counts = {IRNode.POW_D, "1"}, phase = CompilePhase.AFTER_PARSING)
+ @IR(failOn = {IRNode.POW_D})
+ public static double lateExpConstant() {
+ double exp = 0;
+ for (int i = 0; i < 4; i++) {
+ if ((i % 2) == 0) {
+ exp = E;
+ }
+ }
+ // After loop opts, exp == E (constant), so pow(B, E) folds
+ return Math.pow(B, exp);
+ }
+
+ // Test 11: late constant discoveries on both base and exp (after loop opts)
+ @Test
+ @IR(counts = {IRNode.POW_D, "1"}, phase = CompilePhase.AFTER_PARSING)
+ @IR(failOn = {IRNode.POW_D})
+ public static double lateBothConstant() {
+ double base = 0, exp = 0;
+ for (int i = 0; i < 4; i++) {
+ if ((i % 2) == 0) {
+ base = B;
+ exp = E;
+ }
+ }
+ // After loop opts, base = B, exp == E, so pow(B, E) folds
+ return Math.pow(base, exp);
+ }
+
+ private static void assertEQWithinOneUlp(double expected, double observed) {
+ if (Double.isNaN(expected) && Double.isNaN(observed)) return;
+
+ // Math.pow() requires result must be within 1 ulp of the respective magnitude
+ double ulp = Math.max(Math.ulp(expected), Math.ulp(observed));
+ if (Math.abs(expected - observed) > ulp) {
+ throw new AssertionError(String.format(
+ "expect = %x, observed = %x, ulp = %x",
+ Double.doubleToRawLongBits(expected), Double.doubleToRawLongBits(observed), Double.doubleToRawLongBits(ulp)
+ ));
+ }
+ }
+
+ private static void testCorrectness() {
+ // No need to warm up for intrinsics
+ Asserts.assertEQ(1024.0d, constantLiteralFolding());
+
+ double BE = StrictMath.pow(B, E);
+ assertEQWithinOneUlp(BE, constantStaticFolding());
+ assertEQWithinOneUlp(BE, lateBaseConstant());
+ assertEQWithinOneUlp(BE, lateExpConstant());
+ assertEQWithinOneUlp(BE, lateBothConstant());
+
+ Generator<Double> anyBits = G.anyBitsDouble();
+ Generator<Double> largeDoubles = G.uniformDoubles(Long.MAX_VALUE, Double.MAX_VALUE);
+ Generator<Double> doubles = G.doubles();
+ double[] values = {
+ Double.MIN_VALUE, Double.MIN_NORMAL, -42.0d, -1.0d, -0.0d, +0.0d, 0.5d, 1.0d, 2.0d, 123d, Double.MAX_VALUE,
+ Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN,
+ UNIFORMS.next(), UNIFORMS.next(),
+ largeDoubles.next(), -largeDoubles.next(), // some sufficiently large magnitudes
+ anyBits.next(), anyBits.next(), // any bits with potentially more NaN representation
+ doubles.next(), doubles.next() // a healthy sprinkle of whatever else is possible
+ };
+
+ for (double b : values) {
+ // Strength reduced, so we know the bits matches exactly
+ Asserts.assertEQ(1.0d, expZero(b));
+ Asserts.assertEQ(b, expOne(b));
+ Asserts.assertEQ(b * b, expTwo(b));
+
+ assertEQWithinOneUlp(Double.NaN, expNaN(b));
+
+ // Runtime calls, so make sure the result is within 1 ulp
+ assertEQWithinOneUlp(StrictMath.pow(b, 0.5d), expDot5(b));
+
+ for (double e : values) {
+ assertEQWithinOneUlp(StrictMath.pow(b, e), nonConstant(b, e));
+ }
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
index 7b751f1a72c..6a95a2b5da7 100644
--- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
@@ -1858,6 +1858,11 @@ public class IRNode {
beforeMatchingNameRegex(SQRT_HF, "SqrtHF");
}
+ public static final String SQRT_D = PREFIX + "SQRT_D" + POSTFIX;
+ static {
+ beforeMatchingNameRegex(SQRT_D, "SqrtD");
+ }
+
public static final String SQRT_F = PREFIX + "SQRT_F" + POSTFIX;
static {
beforeMatchingNameRegex(SQRT_F, "SqrtF");
@@ -2825,6 +2830,12 @@ public class IRNode {
macroNodes(MOD_D, regex);
}
+ public static final String POW_D = PREFIX + "POW_D" + POSTFIX;
+ static {
+ String regex = START + "PowD" + MID + END;
+ macroNodes(POW_D, regex);
+ }
+
public static final String BLACKHOLE = PREFIX + "BLACKHOLE" + POSTFIX;
static {
fromBeforeRemoveUselessToFinalCode(BLACKHOLE, "Blackhole");
--
2.53.0

View File

@ -1,41 +0,0 @@
diff --git a/Makefile b/Makefile
index 5175f21..571748a 100644
--- a/Makefile
+++ b/Makefile
@@ -13,12 +13,12 @@ DEVEL_PKGS = nss nss-softokn
LIB_DIR = $(shell pkg-config --variable=libdir nss-softokn)
SHARED_LIBS = pthread softokn3 nss3
STATIC_LIBS = freebl
-SHR_CFLAGS = -shared -fPIC -fvisibility=hidden -Wl,--exclude-libs,ALL \
- $(addprefix -l,$(SHARED_LIBS)) \
+SHR_CFLAGS = -shared -fPIC -fvisibility=hidden \
$(strip $(shell pkg-config --cflags $(DEVEL_PKGS))) \
-Wpedantic -Wall -Wextra -Wconversion -Werror
DBG_CFLAGS = -Wno-error=unused-variable -Wno-error=unused-parameter -DDEBUG \
-O0 -g
+SHR_LDFLAGS = -Wl,--exclude-libs,ALL $(addprefix -l,$(SHARED_LIBS))
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
CLANG_FORMAT_STYLE = { \
@@ -53,10 +53,12 @@ endif
.PHONY: release ## Build the library in RELEASE mode (default)
release: BLD_CFLAGS = $(SHR_CFLAGS) $(CFLAGS)
+release: BLD_LDFLAGS = $(SHR_LDFLAGS) $(LDFLAGS)
release: $(CLEAN_IF_PREVIOUS_BUILD_MODE_IS_DEBUG) $(OUTPUT)
.PHONY: debug ## Build the library in DEBUG mode
debug: BLD_CFLAGS = $(SHR_CFLAGS) $(DBG_CFLAGS) $(CFLAGS)
+debug: BLD_LDFLAGS = $(SHR_LDFLAGS) $(LDFLAGS)
debug: CREATE_DBG_SENTINEL_IF_NEEDED = touch $(DBG_SENTINEL)
debug: $(CLEAN_IF_PREVIOUS_BUILD_MODE_IS_RELEASE) $(OUTPUT)
@@ -73,7 +75,7 @@ $(BIN_DIR):
$(OUTPUT): $(BIN_DIR) $(SRC_FILES)
@$(CREATE_DBG_SENTINEL_IF_NEEDED)
- $(CC) $(BLD_CFLAGS) $(filter %.c, $+) \
+ $(CC) $(BLD_CFLAGS) $(filter %.c, $+) $(BLD_LDFLAGS) \
$(addprefix $(LIB_DIR)/lib,$(addsuffix .a,$(STATIC_LIBS))) -o $@

View File

@ -1,3 +1,4 @@
---
inspections:
javabytecode: off
abidiff: off

View File

@ -1,6 +1,6 @@
#!/bin/sh
#!/bin/bash
# Copyright (C) 2024 Red Hat, Inc.
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
@ -20,20 +20,24 @@
# Builds a scratch build of vanilla OpenJDK with no local patches
SEPARATE_ARCHES=${1}
CMD="--target java-openjdk-rhel-8-build --skip-nvr-check --nowait";
CMD=(rhpkg -v build --target java-openjdk-rhel-8-build --skip-nvr-check --nowait);
SUPPORTED_ARCHES="aarch64 ppc64le s390x x86_64";
if [ "x${SEPARATE_ARCHES}" = "x" ] ; then
if [ "${SEPARATE_ARCHES}" = "" ] ; then
SEPARATE_ARCHES=0;
fi
if [ ${SEPARATE_ARCHES} -eq 1 ] ; then
for arch in ${SUPPORTED_ARCHES}; do \
rhpkg -v build --arches ${arch} --scratch ${CMD} ; \
done && brew watch-task --mine
if [ "${SEPARATE_ARCHES}" -eq 1 ] ; then
for arch in ${SUPPORTED_ARCHES}; do \
ARCH_CMD=("${CMD[@]}" --arches "${arch}" --scratch) ;
echo "Executing ${ARCH_CMD[*]}";
command "${ARCH_CMD[@]}";
done
else
rhpkg -v build ${CMD} && brew watch-task --mine
echo "Executing ${CMD[*]}";
command "${CMD[@]}";
fi
brew watch-task --mine
# Local Variables:
# compile-command: "shellcheck build_vanilla.sh"

View File

@ -0,0 +1,77 @@
#!/bin/sh
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Check the signatures (if any) in RHEL RPM buildinfo
# This is intended to be run from the tagging scripts
# Return codes:
# - 1 - Buildinfo file not specified
# - 2 = Missing buildinfo file
# - 3 = No signatures
# - 4 = Multiple signature types found
# - 5 = PQC signature found
# - 6 = Old signature (fd431d51) found
# - 7 = Unknown signature found
BUILDINFO=${1}
NEW_SIGNATURE="release4";
OLD_SIGNATURE="fd431d51";
if test "${BUILDINFO}" = ""; then
echo "${0} <BUILDINFO>";
exit 1;
fi
if ! test -e "${BUILDINFO}" ; then
echo "${BUILDINFO} not found.";
exit 2;
fi
if grep -q "Signatures" < "${BUILDINFO}" ; then
signature=$(grep "Signatures" < "${BUILDINFO}" | cut -d ' ' -f 2- | uniq -c | sed 's#^\W*##');
uniq_count=$(echo "${signature}" | wc -l);
if test "${uniq_count}" -gt 1; then
echo "Multiple signature types found:";
echo "${signature}";
exit 4;
fi
sig_count=$(echo "${signature}" | cut -d ' ' -f 1);
sig_type=$(echo "${signature}" | cut -d ' ' -f 2);
echo "${sig_count} signatures of type ${sig_type} found";
if echo "${sig_type}" | grep -q "${NEW_SIGNATURE}" ; then
echo "PQC signature found.";
exit 5;
elif echo "${sig_type}" | grep -q "${OLD_SIGNATURE}"; then
echo "Old pre-PQC signature found.";
exit 6;
else
echo "Unknown signature found.";
exit 7;
fi
else
echo "Build has no signatures.";
exit 3;
fi
# Local Variables:
# compile-command: "shellcheck check_signatures.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -0,0 +1,63 @@
#!/bin/bash
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Retrieve the results of a gating test using the ID from the JSON
# retrieved by query_build_gating.sh
RESULT_ID=${1}
if test "${RESULT_ID}" = ""; then
echo "No ID specified.";
echo "${0} <RESULT_ID>";
exit 1;
fi
CURL=$(command -v curl)
JSON_TOOL=$(command -v jq)
if test "${CURL}" = ""; then
echo "curl not found";
exit 2;
fi
if test "${JSON_TOOL}" = ""; then
echo "jq not found";
exit 3;
fi
URL="https://resultsdb-api.engineering.redhat.com/api/v2.0/results/${RESULT_ID}"
JSON_OUT=$(mktemp --tmpdir out.XXXXXX.json)
CMD=("${CURL}" --silent --show-error "${URL}")
echo "${CMD[@]}"
if command "${CMD[@]}" > "${JSON_OUT}" ; then
"${JSON_TOOL}" < "${JSON_OUT}"
else
echo "Failed to obtain JSON";
exit 4;
fi
# Local Variables:
# compile-command: "shellcheck get_gating_results.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -0,0 +1,94 @@
#!/bin/bash
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Retrieve the status of a build's progress through gating
RHEL_VER=${1}
NVR=${2}
if test "${RHEL_VER}" = ""; then
echo "No RHEL version specified.";
echo "${0} <RHEL_VER> <NVR>";
exit 1;
fi
if test "${NVR}" = ""; then
echo "No NVR specified.";
echo "${0} <RHEL_VER> <NVR>";
exit 2;
fi
CURL=$(command -v curl)
JSON_TOOL=$(command -v jq)
JSON_FILE=$(mktemp --tmpdir query.XXXXXX.json)
JSON_OUT=$(mktemp --tmpdir out.XXXXXX.json)
URL="https://greenwave.engineering.redhat.com/api/v1.0/decision"
if test "${CURL}" = ""; then
echo "curl not found";
exit 3;
fi
if test "${JSON_TOOL}" = ""; then
echo "jq not found";
exit 4;
fi
{
echo "{";
printf "\t\"decision_context\":\"osci_compose_gate\",\n";
printf "\t\"product_version\":\"rhel-%d\",\n" "${RHEL_VER}";
printf "\t\"subject_type\":\"koji_build\",\n";
printf "\t\"subject_identifier\":\"%s\",\n" "${NVR}";
printf "\t\"verbose\":false\n";
echo "}";
} > "${JSON_FILE}"
echo "Sending the following JSON...";
cat "${JSON_FILE}"
CMD=("${CURL}" --silent --show-error -X POST)
JSON_COMMAND="--json";
# Check --json is available
${CURL} ${JSON_COMMAND} 2> /dev/null
if [ $? -eq 2 ] ; then
echo "--json unsupported; falling back on --data-ascii";
CMD=("${CMD[@]}" --header Content-Type:application/json --data-ascii);
else
CMD=("${CMD[@]}" "${JSON_COMMAND}");
fi
CMD=("${CMD[@]}" "@${JSON_FILE}" "${URL}")
echo "${CMD[@]}"
if command "${CMD[@]}" > "${JSON_OUT}" ; then
"${JSON_TOOL}" < "${JSON_OUT}"
else
echo "Failed to obtain JSON";
exit 5;
fi
# Local Variables:
# compile-command: "shellcheck query_build_gating.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

87
scripts/builds/tag_rhel.sh Executable file
View File

@ -0,0 +1,87 @@
#!/bin/sh
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Tag public RHEL RPMs into gating for all supported streams
# This is intended to be run from tag_rhel_<ver>_(public|embargoed).sh
BUILD="${1}"
BUILDLOG="${2}"
SUFFIX="${3}"
shift 3;
SUPPORTED_VERS="$*"
CMD_SYNTAX="${0} <BUILD> <BUILDLOG> <SUFFIX> <SUPPORTED_VERS>";
GATE_SUFFIX="gate"
if test "${BUILD}" = ""; then
echo "${CMD_SYNTAX}";
exit 1;
fi
if test "${BUILDLOG}" = ""; then
echo "${CMD_SYNTAX}";
exit 2;
fi
if test "${SUPPORTED_VERS}" = ""; then
echo "${CMD_SYNTAX}";
exit 3;
fi
buildtags=$(grep "^Tag" "${BUILDLOG}" | cut -d : -f 2-)
echo "Build has tags ${buildtags}";
if [ "${SUFFIX}" = "${GATE_SUFFIX}" ] ; then
echo "Gating system can only handle one tag at a time."
echo "Script will need to be re-run for subsequent tags once previous tag has moved to -candidate."
if echo "${buildtags}" | grep -q "${GATE_SUFFIX}"; then
echo "Tag with \"-${GATE_SUFFIX}\" found. Please complete gating before re-running.";
exit 1;
fi
fi
done=0;
for ver in ${SUPPORTED_VERS}; do
vertag="rhel-${ver}";
proposedtag="${vertag}-${SUFFIX}";
echo "Checking if ${BUILD} has been added to ${vertag}...";
if echo "${buildtags}" | grep -q "${vertag}" ; then
echo "${BUILD} has been tagged into ${proposedtag}";
else
if [ "${SUFFIX}" = "${GATE_SUFFIX}" ] && [ "${done}" -eq 1 ]; then
echo "Already added a tag. Need to tag ${proposedtag} in a future run.";
else
echo "Tagging ${BUILD} into ${proposedtag}";
brew tag-build --nowait "${proposedtag}" "${BUILD}";
done=1;
fi
fi
done
if [ "${done}" -eq 1 ]; then
brew watch-task --mine;
else
echo "Nothing to do.";
fi
# Local Variables:
# compile-command: "shellcheck tag_rhel.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -0,0 +1,67 @@
#!/bin/sh
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Tag newer PQC embargoed RHEL 10 RPMs into supported z-streams
BUILD=${1}
if test "${BUILD}" = ""; then
echo "${0} <BUILD>";
exit 1;
fi
BUILDLOG=$(mktemp --tmpdir "temp-${BUILD}-buildinfo-XXX")
SUPPORTED_VERS="10.2-z"
WORKING_DIR=$(dirname "${0}")
EMBARGOED_SUFFIX="nocompose-candidate"
echo "Obtaining buildinfo for ${BUILD}...";
brew buildinfo "${BUILD}" 2>&1 | tee "${BUILDLOG}" > /dev/null
echo "Checking signatures for ${BUILD}...";
"${WORKING_DIR}"/check_signatures.sh "${BUILDLOG}"
# Return codes:
# - 1 - Buildinfo file not specified
# - 2 = Missing buildinfo file
# - 3 = No signatures
# - 4 = Multiple signature types found
# - 5 = PQC signature found
# - 6 = Old signature (fd431d51) found
# - 7 = Unknown signature found
ret=$?;
if [ "${ret}" -eq 6 ] ; then
echo "Build has old signatures which should not be the case for OpenJDK 25";
exit 2;
elif ! { [ "${ret}" -eq 6 ] || [ "${ret}" -eq 3 ] ; } ; then
echo "Signature check failed.";
exit 3;
fi
echo "Tagging embargoed build for ${SUPPORTED_VERS}...";
"${WORKING_DIR}"/tag_rhel.sh "${BUILD}" "${BUILDLOG}" "${EMBARGOED_SUFFIX}" "${SUPPORTED_VERS}"
rm -f "${BUILDLOG}"
# Local Variables:
# compile-command: "shellcheck tag_rhel_10_embargoed_pqc.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -0,0 +1,67 @@
#!/bin/sh
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Tag newer PQC public RHEL 10 RPMs into gating for all supported streams
BUILD=${1}
if test "${BUILD}" = ""; then
echo "${0} <BUILD>";
exit 1;
fi
BUILDLOG=$(mktemp --tmpdir "temp-${BUILD}-buildinfo-XXX")
SUPPORTED_VERS="10.3 10.2-z"
WORKING_DIR=$(dirname "${0}")
GATE_SUFFIX="gate"
echo "Obtaining buildinfo for ${BUILD}...";
brew buildinfo "${BUILD}" 2>&1 | tee "${BUILDLOG}" > /dev/null
echo "Checking signatures for ${BUILD}...";
"${WORKING_DIR}"/check_signatures.sh "${BUILDLOG}"
# Return codes:
# - 1 - Buildinfo file not specified
# - 2 = Missing buildinfo file
# - 3 = No signatures
# - 4 = Multiple signature types found
# - 5 = PQC signature found
# - 6 = Old signature (fd431d51) found
# - 7 = Unknown signature found
ret=$?;
if [ "${ret}" -eq 6 ] ; then
echo "Build has old signatures which should not be the case for OpenJDK 25";
exit 2;
elif ! { [ "${ret}" -eq 5 ] || [ "${ret}" -eq 3 ] ; } ; then
echo "Signature check failed.";
exit 3;
fi
echo "Tagging build into gating for ${SUPPORTED_VERS}...";
"${WORKING_DIR}"/tag_rhel.sh "${BUILD}" "${BUILDLOG}" "${GATE_SUFFIX}" "${SUPPORTED_VERS}"
rm -f "${BUILDLOG}"
# Local Variables:
# compile-command: "shellcheck tag_rhel_10_public_pqc.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -0,0 +1,67 @@
#!/bin/sh
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Tag newer PQC embargoed RHEL 9 RPMs into supported z-streams
BUILD=${1}
if test "${BUILD}" = ""; then
echo "${0} <BUILD>";
exit 1;
fi
BUILDLOG=$(mktemp --tmpdir "temp-${BUILD}-buildinfo-XXX")
SUPPORTED_VERS="9.8.0-z"
WORKING_DIR=$(dirname "${0}")
EMBARGOED_SUFFIX="nocompose-candidate"
echo "Obtaining buildinfo for ${BUILD}...";
brew buildinfo "${BUILD}" 2>&1 | tee "${BUILDLOG}" > /dev/null
echo "Checking signatures for ${BUILD}...";
"${WORKING_DIR}"/check_signatures.sh "${BUILDLOG}"
# Return codes:
# - 1 - Buildinfo file not specified
# - 2 = Missing buildinfo file
# - 3 = No signatures
# - 4 = Multiple signature types found
# - 5 = PQC signature found
# - 6 = Old signature (fd431d51) found
# - 7 = Unknown signature found
ret=$?;
if [ "${ret}" -eq 6 ] ; then
echo "Build has old signatures which should not be the case for OpenJDK 25";
exit 2;
elif ! { [ "${ret}" -eq 6 ] || [ "${ret}" -eq 3 ] ; } ; then
echo "Signature check failed.";
exit 3;
fi
echo "Tagging embargoed build for ${SUPPORTED_VERS}...";
"${WORKING_DIR}"/tag_rhel.sh "${BUILD}" "${BUILDLOG}" "${EMBARGOED_SUFFIX}" "${SUPPORTED_VERS}"
rm -f "${BUILDLOG}"
# Local Variables:
# compile-command: "shellcheck tag_rhel_9_embargoed_pqc.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -0,0 +1,67 @@
#!/bin/sh
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Tag newer PQC public RHEL 9 RPMs into gating for all supported streams
BUILD=${1}
if test "${BUILD}" = ""; then
echo "${0} <BUILD>";
exit 1;
fi
BUILDLOG=$(mktemp --tmpdir "temp-${BUILD}-buildinfo-XXX")
SUPPORTED_VERS="9.9.0 9.8.0-z"
WORKING_DIR=$(dirname "${0}")
GATE_SUFFIX="gate"
echo "Obtaining buildinfo for ${BUILD}...";
brew buildinfo "${BUILD}" 2>&1 | tee "${BUILDLOG}" > /dev/null
echo "Checking signatures for ${BUILD}...";
"${WORKING_DIR}"/check_signatures.sh "${BUILDLOG}"
# Return codes:
# - 1 - Buildinfo file not specified
# - 2 = Missing buildinfo file
# - 3 = No signatures
# - 4 = Multiple signature types found
# - 5 = PQC signature found
# - 6 = Old signature (fd431d51) found
# - 7 = Unknown signature found
ret=$?;
if [ "${ret}" -eq 6 ] ; then
echo "Build has old signatures which should not be the case for OpenJDK 25";
exit 2;
elif ! { [ "${ret}" -eq 5 ] || [ "${ret}" -eq 3 ] ; } ; then
echo "Signature check failed.";
exit 3;
fi
echo "Tagging build into gating for ${SUPPORTED_VERS}...";
"${WORKING_DIR}"/tag_rhel.sh "${BUILD}" "${BUILDLOG}" "${GATE_SUFFIX}" "${SUPPORTED_VERS}"
rm -f "${BUILDLOG}"
# Local Variables:
# compile-command: "shellcheck tag_rhel_9_public_pqc.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

132
scripts/builds/waive_issue.sh Executable file
View File

@ -0,0 +1,132 @@
#!/bin/bash
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Waive a gating issue
RHEL_VER=${1}
NVR=${2}
TESTCASE=${3}
COMMENT=${4}
CURL=$(command -v curl)
JSON_TOOL=$(command -v json_verify)
JSON_FORMAT=$(command -v jq)
JSON_FILE=$(mktemp --tmpdir waive.XXXXXX.json)
HEADER_FILE=$(mktemp --tmpdir waive.XXXXXX.headers)
JSON_OUT=$(mktemp --tmpdir out.XXXXXX.json)
CACERT=/etc/ssl/certs/2022-IT-Root-CA.pem
CACERT_DIR=$(dirname ${CACERT})
URL="https://waiverdb.engineering.redhat.com/api/v1.0/waivers/"
if test -z "${JSON_TOOL}" -o ! -x "${JSON_TOOL}" ; then
echo "JSON verifier not found. Skipping verification.";
SKIP_JSON=1;
else
SKIP_JSON=0;
fi
if test "${RHEL_VER}" = ""; then
echo "No RHEL version specified.";
echo "${0} <RHEL_VER> <NVR> <TESTCASE> <COMMENT>";
exit 1;
fi
if test "${NVR}" = ""; then
echo "No NVR specified.";
echo "${0} <RHEL_VER> <NVR> <TESTCASE> <COMMENT>";
exit 2;
fi
if test "${TESTCASE}" = ""; then
echo "No testcase specified.";
echo "${0} <RHEL_VER> <NVR> <TESTCASE> <COMMENT>";
exit 3;
fi
if test "${COMMENT}" = ""; then
COMMENT="Gating broken";
echo "Setting COMMENT to default of '${COMMENT}'"
fi
if test "${CURL}" = ""; then
echo "curl not found";
exit 4;
fi
if test "${JSON_FORMAT}" = ""; then
echo "jq not found";
exit 5;
fi
{
echo "{";
printf "\t\"subject_type\":\"brew-build\",\n";
printf "\t\"subject_identifier\":\"%s\",\n" "${NVR}";
printf "\t\"testcase\":\"%s\",\n" "${TESTCASE}";
printf "\t\"waived\":true,\n";
printf "\t\"product_version\":\"rhel-%d\",\n" "${RHEL_VER}"
printf "\t\"comment\":\"%s\"\n" "${COMMENT}";
echo "}"
} > "${JSON_FILE}"
if [ "${SKIP_JSON}" -eq 0 ] ; then
"${JSON_TOOL}" < "${JSON_FILE}" || exit 6;
fi
CMD=("${CURL}" --silent --show-error --capath "${CACERT_DIR}" --negotiate -u :)
JSON_COMMAND="--json";
# Check --json is available
${CURL} ${JSON_COMMAND} 2> /dev/null
if [ $? -eq 2 ] ; then
echo "--json unsupported; falling back on --data-binary";
{
echo "Content-Type: application/json";
echo "Accept: application/json";
} > "${HEADER_FILE}"
echo "Header file:";
cat "${HEADER_FILE}"
CMD=("${CMD[@]}" --header "@${HEADER_FILE}" --data-binary);
else
CMD=("${CMD[@]}" "${JSON_COMMAND}");
fi
CMD=("${CMD[@]}" "@${JSON_FILE}" "${URL}")
echo "Sending the following JSON...";
cat "${JSON_FILE}"
echo "${CMD[@]}"
if command "${CMD[@]}" > "${JSON_OUT}" ; then
"${JSON_FORMAT}" < "${JSON_OUT}"
else
echo "Failed to file waiver";
exit 7;
fi
rm -v "${JSON_FILE}"
rm -v "${HEADER_FILE}"
# Local Variables:
# compile-command: "shellcheck waive_issue.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,6 +1,6 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
@ -17,26 +17,29 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Builds the RPM on RHEL 8
# Waive the leapp gating test which never seems to work
NVR=${1}
USER=${2}
RHEL_VER=${1}
NVR=${2}
if test "${NVR}" = ""; then
echo "${0} <NVR> <USER>";
WORKING_DIR=$(dirname "${0}")
if test "${RHEL_VER}" = ""; then
echo "No RHEL version specified.";
echo "${0} <RHEL_VER> <NVR>";
exit 1;
fi
if test "${USER}" = ""; then
echo "${0} <NVR> <USER>";
if test "${NVR}" = ""; then
echo "No NVR specified.";
echo "${0} <RHEL_VER> <NVR>";
exit 2;
fi
METADATA="{\"osci\": {\"upstream_nvr\": \"${NVR}\", \"upstream_owner_name\": \"${USER}\"}, \"rhel-target\": \"latest\"}"
rhpkg -v build --target=java-openjdk-rhel-8-build --custom-user-metadata "${METADATA}"
"${WORKING_DIR}"/waive_issue.sh "${RHEL_VER}" "${NVR}" leapp.brew-build.upgrade.distro "AWOL"
# Local Variables:
# compile-command: "shellcheck build_rhel_8.sh"
# compile-command: "shellcheck waive_leapp_issue.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4

View File

@ -0,0 +1,53 @@
#!/bin/sh
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Waive a rpminspect gating issue
RHEL_VER=${1}
NVR=${2}
COMMENT=${3}
WORKING_DIR=$(dirname "${0}")
if test "${RHEL_VER}" = ""; then
echo "No RHEL version specified.";
echo "${0} <RHEL_VER> <NVR> <COMMENT>";
exit 1;
fi
if test "${NVR}" = ""; then
echo "No NVR specified.";
echo "${0} <RHEL_VER> <NVR> <COMMENT>";
exit 2;
fi
if test "${COMMENT}" = ""; then
echo "No comment specified.";
echo "${0} <RHEL_VER> <NVR> <COMMENT>";
exit 3;
fi
"${WORKING_DIR}"/waive_issue.sh "${RHEL_VER}" "${NVR}" osci.brew-build.rpminspect.static-analysis "${COMMENT}"
# Local Variables:
# compile-command: "shellcheck waive_rpminspect.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -0,0 +1,48 @@
#!/bin/sh
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Waive the recurring rpminspect gating issues
# Should be resolved by RHELPLAN-102267
WORKING_DIR=$(dirname "${0}")
RHEL_VER=${1}
NVR=${2}
if test "${RHEL_VER}" = ""; then
echo "No RHEL version specified.";
echo "${0} <RHEL_VER> <NVR>";
exit 1;
fi
if test "${NVR}" = ""; then
echo "No NVR specified.";
echo "${0} <RHEL_VER> <NVR>";
exit 2;
fi
"${WORKING_DIR}"/waive_rpminspect.sh "${RHEL_VER}" "${NVR}" \
"Usual failures we waived through rpmdiff; slowdebug unoptimised, RPATH and IPv4 functions"
# Local Variables:
# compile-command: "shellcheck waive_usual_rpminspect.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,6 +1,6 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Copyright (C) 2026 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
@ -17,12 +17,30 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Builds the portable on RHEL 7
# Waive the usual tier0 gating issue
# Should be resolved by OPENJDK-4517
rhpkg -v build --target=java-openjdk-rhel-7-build --skip-nvr-check
RHEL_VER=${1}
NVR=${2}
WORKING_DIR=$(dirname "${0}")
if test "${RHEL_VER}" = ""; then
echo "No RHEL version specified.";
echo "${0} <RHEL_VER> <NVR>";
exit 1;
fi
if test "${NVR}" = ""; then
echo "No NVR specified.";
echo "${0} <RHEL_VER> <NVR>";
exit 2;
fi
"${WORKING_DIR}"/waive_issue.sh "${RHEL_VER}" "${NVR}" osci.brew-build.tier0.functional "Test unable to parse spec file"
# Local Variables:
# compile-command: "shellcheck build_rhel_7_portable_build.sh"
# compile-command: "shellcheck waive_usual_tier0.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4

View File

@ -98,7 +98,7 @@ else
echo "No apparent backouts.";
fi
printf "\nChecking for bundled library updates...";
if grep -iE ':( \(tz\))? update.*(freetype|gif|harfbuzz|lcms|jpeg|png|timezone|zlib)' "${TMPDIR}/fixes" > "${TMPDIR}/bundles"; then
if grep -iE ':( \(tz\))? (update|upgrade).*(freetype|gif|harfbuzz|lcms|jpeg|png|timezone|zlib)' "${TMPDIR}/fixes" > "${TMPDIR}/bundles"; then
printf "found.\nWARNING: Review the following with respect to bundled provides:\n";
cat "${TMPDIR}/bundles";
echo "Compare the output of $(dirname "${0}")/get_bundle_versions.sh with the RPM using the JDK source tree"

View File

@ -1,3 +1,3 @@
SHA512 (tapsets-icedtea-6.0.0pre00-c848b93a8598.tar.xz) = 97d026212363b3c83f6a04100ad7f6fdde833d16579717f8756e2b8c2eb70e144a41a330cb9ccde9c3badd37a2d54fdf4650a950ec21d8b686d545ecb2a64d30
SHA512 (openjdk-25.0.1+8.tar.xz) = eb84d876f81ca02803283e8294c89b6acbed3753426811c3bcc228615c9618deefc85da4aa702800cac2feb103e628ee8b92292b316e9d7e12a58b6de69c5085
SHA512 (nssadapter-0.1.0.tar.xz) = 581f49d1a27550e3a2fa0a9d407f43c507627a8439827904d14daaf24e071d9f73884a2abe4cb3d36d26f1af09ef7d20724b2d40c9bac202e0316fac6c1a636b
SHA512 (nssadapter-0.1.1.tar.xz) = 2b4675cfbfa2ccb6c9a4870a4b58ae555267f5b8c9bdb0cf37b075483e6e9ea929561c05070453cf0d67b0b029de5408274555bf2ff50e9533219e898b2717f9
SHA512 (openjdk-25.0.4.1+1.tar.xz) = e5f0aeec7d52671869ed46fda5c59f041d321c0ad989861a2eb2eb70b513bba9e297e09aa70256f26af6c3ac0269c8aaacc134fe49cbba99b9035e158b90fca0