diff --git a/Backport-JDK-7036144-GZIPInputStream-readTrailer-use.patch b/Backport-JDK-7036144-GZIPInputStream-readTrailer-use.patch deleted file mode 100644 index b9dad132eaf6cfdf048cfca7eda8279209e3636f..0000000000000000000000000000000000000000 --- a/Backport-JDK-7036144-GZIPInputStream-readTrailer-use.patch +++ /dev/null @@ -1,148 +0,0 @@ -Subject: [PATCH] Backport JDK-8337393: GZIPInputStream readTrailer uses faulty - available() test for end-of-stream - ---- - .../java/util/zip/GZIPInputStream.java | 24 ++--- - .../zip/GZIP/GZIPInputStreamAvailable.java | 93 +++++++++++++++++++ - 2 files changed, 102 insertions(+), 15 deletions(-) - create mode 100644 test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java - -diff --git a/src/java.base/share/classes/java/util/zip/GZIPInputStream.java b/src/java.base/share/classes/java/util/zip/GZIPInputStream.java -index 850691e02..ad819e271 100644 ---- a/src/java.base/share/classes/java/util/zip/GZIPInputStream.java -+++ b/src/java.base/share/classes/java/util/zip/GZIPInputStream.java -@@ -260,23 +260,17 @@ public class GZIPInputStream extends InflaterInputStream { - (readUInt(in) != (inf.getBytesWritten() & 0xffffffffL))) - throw new ZipException("Corrupt GZIP trailer"); - -- // If there are more bytes available in "in" or -- // the leftover in the "inf" is > 26 bytes: -- // this.trailer(8) + next.header.min(10) + next.trailer(8) - // try concatenated case -- if (this.in.available() > 0 || n > 26) { -- int m = 8; // this.trailer -- try { -- m += readHeader(in); // next.header -- } catch (IOException ze) { -- return true; // ignore any malformed, do nothing -- } -- inf.reset(); -- if (n > m) -- inf.setInput(buf, len - n + m, n - m); -- return false; -+ int m = 8; // this.trailer -+ try { -+ m += readHeader(in); // next.header -+ } catch (IOException ze) { -+ return true; // ignore any malformed, do nothing - } -- return true; -+ inf.reset(); -+ if (n > m) -+ inf.setInput(buf, len - n + m, n - m); -+ return false; - } - - /* -diff --git a/test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java b/test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java -new file mode 100644 -index 000000000..1468c104f ---- /dev/null -+++ b/test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java -@@ -0,0 +1,93 @@ -+/* -+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+/* @test -+ * @bug 7036144 -+ * @summary Test concatenated gz streams when available() returns zero -+ * @run junit GZIPInputStreamAvailable -+ */ -+ -+import org.junit.jupiter.api.Test; -+ -+import java.io.*; -+import java.util.*; -+import java.util.zip.*; -+ -+import static org.junit.jupiter.api.Assertions.assertArrayEquals; -+ -+public class GZIPInputStreamAvailable { -+ -+ public static final int NUM_COPIES = 100; -+ -+ @Test -+ public void testZeroAvailable() throws IOException { -+ -+ // Create some uncompressed data and then repeat it NUM_COPIES times -+ byte[] uncompressed1 = "this is a test".getBytes("ASCII"); -+ byte[] uncompressedN = repeat(uncompressed1, NUM_COPIES); -+ -+ // Compress the original data and then repeat that NUM_COPIES times -+ byte[] compressed1 = deflate(uncompressed1); -+ byte[] compressedN = repeat(compressed1, NUM_COPIES); -+ -+ // (a) Read back inflated data from a stream where available() is accurate and verify -+ byte[] readback1 = inflate(new ByteArrayInputStream(compressedN)); -+ assertArrayEquals(uncompressedN, readback1); -+ -+ // (b) Read back inflated data from a stream where available() always returns zero and verify -+ byte[] readback2 = inflate(new ZeroAvailableStream(new ByteArrayInputStream(compressedN))); -+ assertArrayEquals(uncompressedN, readback2); -+ } -+ -+ public static byte[] repeat(byte[] data, int count) { -+ byte[] repeat = new byte[data.length * count]; -+ int off = 0; -+ for (int i = 0; i < count; i++) { -+ System.arraycopy(data, 0, repeat, off, data.length); -+ off += data.length; -+ } -+ return repeat; -+ } -+ -+ public static byte[] deflate(byte[] data) throws IOException { -+ ByteArrayOutputStream buf = new ByteArrayOutputStream(); -+ try (GZIPOutputStream out = new GZIPOutputStream(buf)) { -+ out.write(data); -+ } -+ return buf.toByteArray(); -+ } -+ -+ public static byte[] inflate(InputStream in) throws IOException { -+ return new GZIPInputStream(in).readAllBytes(); -+ } -+ -+ public static class ZeroAvailableStream extends FilterInputStream { -+ public ZeroAvailableStream(InputStream in) { -+ super(in); -+ } -+ @Override -+ public int available() { -+ return 0; -+ } -+ } -+} --- -2.48.1 - diff --git a/Backport-JDK-8339460-CDS-error-when-module-is-locate.patch b/Backport-JDK-8339460-CDS-error-when-module-is-locate.patch deleted file mode 100644 index 66e3b4bcd82ce46059342d6ac2a35f7ab35518c4..0000000000000000000000000000000000000000 --- a/Backport-JDK-8339460-CDS-error-when-module-is-locate.patch +++ /dev/null @@ -1,486 +0,0 @@ -Subject: Backport JDK-8339460 CDS error when module is located in a directory with space in the name - ---- - src/hotspot/share/cds/classListParser.cpp | 6 +- - src/hotspot/share/cds/classListWriter.cpp | 4 +- - src/hotspot/share/cds/filemap.cpp | 4 +- - src/hotspot/share/classfile/classLoader.cpp | 50 +++++- - src/hotspot/share/classfile/classLoader.hpp | 4 +- - .../share/classfile/classLoaderExt.cpp | 12 +- - test/hotspot/jtreg/TEST.groups | 3 +- - .../cds/appcds/complexURI/ComplexURITest.java | 167 ++++++++++++++++++ - .../appcds/complexURI/mypackage/Another.java | 27 +++ - .../cds/appcds/complexURI/mypackage/Main.java | 37 ++++ - 10 files changed, 296 insertions(+), 18 deletions(-) - create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/complexURI/ComplexURITest.java - create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Another.java - create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Main.java - -diff --git a/src/hotspot/share/cds/classListParser.cpp b/src/hotspot/share/cds/classListParser.cpp -index a1e1a4131..0ba74ca4e 100644 ---- a/src/hotspot/share/cds/classListParser.cpp -+++ b/src/hotspot/share/cds/classListParser.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -472,7 +472,9 @@ InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS - THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); - } - -- InstanceKlass* k = UnregisteredClasses::load_class(class_name, _source, CHECK_NULL); -+ ResourceMark rm; -+ char * source_path = os::strdup_check_oom(ClassLoader::uri_to_path(_source)); -+ InstanceKlass* k = UnregisteredClasses::load_class(class_name, source_path, CHECK_NULL); - if (k->local_interfaces()->length() != _interfaces->length()) { - print_specified_interfaces(); - print_actual_interfaces(k); -diff --git a/src/hotspot/share/cds/classListWriter.cpp b/src/hotspot/share/cds/classListWriter.cpp -index 2a65ee51d..53637429a 100644 ---- a/src/hotspot/share/cds/classListWriter.cpp -+++ b/src/hotspot/share/cds/classListWriter.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -171,6 +171,8 @@ void ClassListWriter::write_to_stream(const InstanceKlass* k, outputStream* stre - } - } - -+ // NB: the string following "source: " is not really a proper file name, but rather -+ // a truncated URI referring to a file. It must be decoded after reading. - #ifdef _WINDOWS - // "file:/C:/dir/foo.jar" -> "C:/dir/foo.jar" - stream->print(" source: %s", cfs->source() + 6); -diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp -index 023c0762a..f56920c64 100644 ---- a/src/hotspot/share/cds/filemap.cpp -+++ b/src/hotspot/share/cds/filemap.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -583,7 +583,7 @@ int FileMapInfo::get_module_shared_path_index(Symbol* location) { - - // skip_uri_protocol was also called during dump time -- see ClassLoaderExt::process_module_table() - ResourceMark rm; -- const char* file = ClassLoader::skip_uri_protocol(location->as_C_string()); -+ const char* file = ClassLoader::uri_to_path(location->as_C_string()); - for (int i = ClassLoaderExt::app_module_paths_start_index(); i < get_number_of_shared_paths(); i++) { - SharedClassPathEntry* ent = shared_path(i); - assert(ent->in_named_module(), "must be"); -diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp -index 5e89673a5..74b9d9300 100644 ---- a/src/hotspot/share/classfile/classLoader.cpp -+++ b/src/hotspot/share/classfile/classLoader.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -78,6 +78,9 @@ - #include "utilities/macros.hpp" - #include "utilities/utf8.hpp" - -+#include -+#include -+ - // Entry point in java.dll for path canonicalization - - typedef int (*canonicalize_fn_t)(const char *orig, char *out, int len); -@@ -1223,7 +1226,7 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR - } - - #if INCLUDE_CDS --char* ClassLoader::skip_uri_protocol(char* source) { -+static const char* skip_uri_protocol(const char* source) { - if (strncmp(source, "file:", 5) == 0) { - // file: protocol path could start with file:/ or file:/// - // locate the char after all the forward slashes -@@ -1242,6 +1245,47 @@ char* ClassLoader::skip_uri_protocol(char* source) { - return source; - } - -+static char decode_percent_encoded(const char *str, size_t& index) { -+ if (str[index] == '%' -+ && isxdigit(str[index + 1]) -+ && isxdigit(str[index + 2])) { -+ char hex[3]; -+ hex[0] = str[index + 1]; -+ hex[1] = str[index + 2]; -+ hex[2] = '\0'; -+ index += 2; -+ return (char) strtol(hex, NULL, 16); -+ } -+ return str[index]; -+} -+ -+char* ClassLoader::uri_to_path(const char* uri) { -+ const size_t len = strlen(uri) + 1; -+ char* path = NEW_RESOURCE_ARRAY(char, len); -+ -+ uri = skip_uri_protocol(uri); -+ -+ if (strncmp(uri, "//", 2) == 0) { -+ // Skip the empty "authority" part -+ uri += 2; -+ } -+ -+#ifdef _WINDOWS -+ if (uri[0] == '/') { -+ // Absolute path name on Windows does not begin with a slash -+ uri += 1; -+ } -+#endif -+ -+ size_t path_index = 0; -+ for (size_t i = 0; i < strlen(uri); ++i) { -+ char decoded = decode_percent_encoded(uri, i); -+ path[path_index++] = decoded; -+ } -+ path[path_index] = '\0'; -+ return path; -+} -+ - // Record the shared classpath index and loader type for classes loaded - // by the builtin loaders at dump time. - void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik, -@@ -1275,7 +1319,7 @@ void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik, - // Save the path from the file: protocol or the module name from the jrt: protocol - // if no protocol prefix is found, path is the same as stream->source(). This path - // must be valid since the class has been successfully parsed. -- char* path = skip_uri_protocol(src); -+ const char* path = ClassLoader::uri_to_path(src); - assert(path != nullptr, "sanity"); - for (int i = 0; i < FileMapInfo::get_number_of_shared_paths(); i++) { - SharedClassPathEntry* ent = FileMapInfo::shared_path(i); -diff --git a/src/hotspot/share/classfile/classLoader.hpp b/src/hotspot/share/classfile/classLoader.hpp -index 4cb196719..2f464063e 100644 ---- a/src/hotspot/share/classfile/classLoader.hpp -+++ b/src/hotspot/share/classfile/classLoader.hpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -364,7 +364,7 @@ class ClassLoader: AllStatic { - // entries during shared classpath setup time. - static int num_module_path_entries(); - static void exit_with_path_failure(const char* error, const char* message); -- static char* skip_uri_protocol(char* source); -+ static char* uri_to_path(const char* uri); - static void record_result(JavaThread* current, InstanceKlass* ik, - const ClassFileStream* stream, bool redefined); - #endif -diff --git a/src/hotspot/share/classfile/classLoaderExt.cpp b/src/hotspot/share/classfile/classLoaderExt.cpp -index c9fd8173b..5334b118e 100644 ---- a/src/hotspot/share/classfile/classLoaderExt.cpp -+++ b/src/hotspot/share/classfile/classLoaderExt.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -98,12 +98,10 @@ void ClassLoaderExt::process_module_table(JavaThread* current, ModuleEntryTable* - ModulePathsGatherer(JavaThread* current, GrowableArray* module_paths) : - _current(current), _module_paths(module_paths) {} - void do_module(ModuleEntry* m) { -- char* path = m->location()->as_C_string(); -- if (strncmp(path, "file:", 5) == 0) { -- path = ClassLoader::skip_uri_protocol(path); -- char* path_copy = NEW_RESOURCE_ARRAY(char, strlen(path) + 1); -- strcpy(path_copy, path); -- _module_paths->append(path_copy); -+ char* uri = m->location()->as_C_string(); -+ if (strncmp(uri, "file:", 5) == 0) { -+ char* path = ClassLoader::uri_to_path(uri); -+ _module_paths->append(path); - } - } - }; -diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups -index 4923fbd5b..4c7352956 100644 ---- a/test/hotspot/jtreg/TEST.groups -+++ b/test/hotspot/jtreg/TEST.groups -@@ -1,5 +1,5 @@ - # --# Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. -+# Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. - # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - # - # This code is free software; you can redistribute it and/or modify it -@@ -430,6 +430,7 @@ hotspot_cds_only = \ - hotspot_appcds_dynamic = \ - runtime/cds/appcds/ \ - -runtime/cds/appcds/cacheObject \ -+ -runtime/cds/appcds/complexURI \ - -runtime/cds/appcds/customLoader \ - -runtime/cds/appcds/dynamicArchive \ - -runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java \ -diff --git a/test/hotspot/jtreg/runtime/cds/appcds/complexURI/ComplexURITest.java b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/ComplexURITest.java -new file mode 100644 -index 000000000..409e37e10 ---- /dev/null -+++ b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/ComplexURITest.java -@@ -0,0 +1,167 @@ -+/* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2024 JetBrains s.r.o. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+/* -+ * @test -+ * @summary Verifies that CDS works with jar located in directories -+ * with names that need escaping -+ * @bug 8339460 -+ * @requires vm.cds -+ * @requires vm.cds.custom.loaders -+ * @requires vm.flagless -+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds -+ * @compile mypackage/Main.java mypackage/Another.java -+ * @run main/othervm ComplexURITest -+ */ -+ -+import jdk.test.lib.process.OutputAnalyzer; -+import jdk.test.lib.process.ProcessTools; -+import jdk.test.lib.Platform; -+ -+import java.io.File; -+import java.nio.file.Files; -+import java.nio.file.Path; -+ -+public class ComplexURITest { -+ final static String moduleName = "mymodule"; -+ -+ public static void main(String[] args) throws Exception { -+ System.setProperty("test.noclasspath", "true"); -+ String jarFile = JarBuilder.build(moduleName, "mypackage/Main", "mypackage/Another"); -+ -+ Path subDir = Path.of(".", "dir with space"); -+ Files.createDirectory(subDir); -+ Path newJarFilePath = subDir.resolve(moduleName + ".jar"); -+ Files.move(Path.of(jarFile), newJarFilePath); -+ jarFile = newJarFilePath.toString(); -+ -+ final String listFileName = "test-classlist.txt"; -+ final String staticArchiveName = "test-static.jsa"; -+ final String dynamicArchiveName = "test-dynamic.jsa"; -+ -+ // Verify static archive creation and use -+ File fileList = new File(listFileName); -+ delete(fileList.toPath()); -+ File staticArchive = new File(staticArchiveName); -+ delete(staticArchive.toPath()); -+ -+ createClassList(jarFile, listFileName); -+ if (!fileList.exists()) { -+ throw new RuntimeException("No class list created at " + fileList); -+ } -+ -+ createArchive(jarFile, listFileName, staticArchiveName); -+ if (!staticArchive.exists()) { -+ throw new RuntimeException("No shared classes archive created at " + staticArchive); -+ } -+ -+ useArchive(jarFile, staticArchiveName); -+ -+ // Verify dynamic archive creation and use -+ File dynamicArchive = new File(dynamicArchiveName); -+ delete(dynamicArchive.toPath()); -+ -+ createDynamicArchive(jarFile, dynamicArchiveName); -+ if (!dynamicArchive.exists()) { -+ throw new RuntimeException("No dynamic archive created at " + dynamicArchive); -+ } -+ -+ testDynamicArchive(jarFile, dynamicArchiveName); -+ } -+ -+ private static void delete(Path path) throws Exception { -+ if (Files.exists(path)) { -+ if (Platform.isWindows()) { -+ Files.setAttribute(path, "dos:readonly", false); -+ } -+ Files.delete(path); -+ } -+ } -+ -+ private static void createClassList(String jarFile, String list) throws Exception { -+ String[] launchArgs = { -+ "-XX:DumpLoadedClassList=" + list, -+ "--module-path", -+ jarFile, -+ "--module", -+ moduleName + "/mypackage.Main"}; -+ ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(launchArgs); -+ OutputAnalyzer output = TestCommon.executeAndLog(pb, "create-list"); -+ output.shouldHaveExitValue(0); -+ } -+ -+ private static void createArchive(String jarFile, String list, String archive) throws Exception { -+ String[] launchArgs = { -+ "-Xshare:dump", -+ "-XX:SharedClassListFile=" + list, -+ "-XX:SharedArchiveFile=" + archive, -+ "--module-path", -+ jarFile, -+ "--module", -+ moduleName + "/mypackage.Main"}; -+ ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(launchArgs); -+ OutputAnalyzer output = TestCommon.executeAndLog(pb, "dump-archive"); -+ output.shouldHaveExitValue(0); -+ } -+ -+ private static void useArchive(String jarFile, String archive) throws Exception { -+ String[] launchArgs = { -+ "-Xshare:on", -+ "-XX:SharedArchiveFile=" + archive, -+ "--module-path", -+ jarFile, -+ "--module", -+ moduleName + "/mypackage.Main"}; -+ ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(launchArgs); -+ OutputAnalyzer output = TestCommon.executeAndLog(pb, "use-archive"); -+ output.shouldHaveExitValue(0); -+ } -+ -+ private static void createDynamicArchive(String jarFile, String archive) throws Exception { -+ String[] launchArgs = { -+ "-XX:ArchiveClassesAtExit=" + archive, -+ "--module-path", -+ jarFile, -+ "--module", -+ moduleName + "/mypackage.Main"}; -+ ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(launchArgs); -+ OutputAnalyzer output = TestCommon.executeAndLog(pb, "dynamic-archive"); -+ output.shouldHaveExitValue(0); -+ } -+ -+ private static void testDynamicArchive(String jarFile, String archive) throws Exception { -+ String[] launchArgs = { -+ "-XX:SharedArchiveFile=" + archive, -+ "-XX:+PrintSharedArchiveAndExit", -+ "--module-path", -+ jarFile, -+ "--module", -+ moduleName + "/mypackage.Main"}; -+ ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(launchArgs); -+ OutputAnalyzer output = TestCommon.executeAndLog(pb, "dynamic-archive"); -+ output.shouldHaveExitValue(0); -+ output.shouldContain("archive is valid"); -+ output.shouldContain(": mypackage.Main app_loader"); -+ output.shouldContain(": mypackage.Another unregistered_loader"); -+ } -+} -diff --git a/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Another.java b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Another.java -new file mode 100644 -index 000000000..106dfd490 ---- /dev/null -+++ b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Another.java -@@ -0,0 +1,27 @@ -+/* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2024 JetBrains s.r.o. -+ * 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 mypackage; -+ -+public class Another { -+} -diff --git a/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Main.java b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Main.java -new file mode 100644 -index 000000000..fdb79e895 ---- /dev/null -+++ b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Main.java -@@ -0,0 +1,37 @@ -+/* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2024 JetBrains s.r.o. -+ * 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 mypackage; -+ -+import java.net.URL; -+import java.net.URLClassLoader; -+ -+public class Main { -+ public static void main(String[] args) throws Exception { -+ URL url1 = Main.class.getProtectionDomain().getCodeSource().getLocation(); -+ System.out.println("Will load Another from " + url1); -+ ClassLoader cl = URLClassLoader.newInstance(new URL[] { url1 }, null); -+ var anotherClass = cl.loadClass("mypackage.Another"); -+ System.out.println("Class " + anotherClass + " loaded successfully"); -+ } -+} --- -2.33.0 - diff --git a/huawei-Add-KAE-zip-feature.patch b/huawei-Add-KAE-zip-feature.patch index 026e33f2750ab914a99fb770e16afa97b77edc6c..7b43e5b13b63eee6034ec037722c30f23ac2508c 100644 --- a/huawei-Add-KAE-zip-feature.patch +++ b/huawei-Add-KAE-zip-feature.patch @@ -242,7 +242,7 @@ index d704fd3c9..850691e02 100644 } @@ -254,6 +279,39 @@ public class GZIPInputStream extends InflaterInputStream { - return true; + return false; } + /* diff --git a/huawei-posix_spawn-clock_gettime-clock_getres-__cxa_thread_.patch b/huawei-posix_spawn-clock_gettime-clock_getres-__cxa_thread_.patch new file mode 100644 index 0000000000000000000000000000000000000000..8c0c7ec9e2510574744262ca1184f9f85dd19839 --- /dev/null +++ b/huawei-posix_spawn-clock_gettime-clock_getres-__cxa_thread_.patch @@ -0,0 +1,858 @@ +Date: Fri, 17 Oct 2025 12:19:34 +0800 +Subject: [PATCH] posix_spawn clock_gettime clock_getres + __cxa_thread_atexit_impl symbol downgrade + +--- + make/autoconf/flags-cflags.m4 | 19 +++ + make/autoconf/libraries.m4 | 9 -- + src/hotspot/os/aix/os_aix.cpp | 15 ++ + src/hotspot/os/aix/os_aix.inline.hpp | 5 + + src/hotspot/os/bsd/os_bsd.cpp | 71 +++++++++- + src/hotspot/os/bsd/os_bsd.hpp | 2 + + src/hotspot/os/bsd/os_bsd.inline.hpp | 8 ++ + src/hotspot/os/bsd/os_perf_bsd.cpp | 9 +- + src/hotspot/os/linux/os_linux.cpp | 84 +++++++++++- + src/hotspot/os/posix/os_posix.cpp | 167 +++++++++++++++-------- + src/hotspot/os/posix/os_posix.hpp | 17 +++ + src/hotspot/os/posix/os_posix.inline.hpp | 22 +++ + src/hotspot/share/prims/upcallLinker.cpp | 38 ++++++ + src/hotspot/share/prims/upcallLinker.hpp | 10 ++ + src/hotspot/share/runtime/javaThread.cpp | 2 +- + src/hotspot/share/runtime/os.hpp | 1 + + src/hotspot/share/runtime/threads.cpp | 4 + + 17 files changed, 400 insertions(+), 83 deletions(-) + +diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 +index b0b317db6..485988ec6 100644 +--- a/make/autoconf/flags-cflags.m4 ++++ b/make/autoconf/flags-cflags.m4 +@@ -727,6 +727,25 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER], + fi + fi + ++ # Optional POSIX functionality needed by the JVM ++ # ++ # Check if clock_gettime is available and in which library. This indicates ++ # availability of CLOCK_MONOTONIC for hotspot. But we don't need to link, so ++ # don't let it update LIBS. ++ save_LIBS="$LIBS" ++ AC_SEARCH_LIBS(clock_gettime, rt, [HAS_CLOCK_GETTIME=true], []) ++ if test "x$LIBS" = "x-lrt "; then ++ CLOCK_GETTIME_IN_LIBRT=true ++ fi ++ LIBS="$save_LIBS" ++ ++ if test "x$HAS_CLOCK_GETTIME" = "xtrue"; then ++ OS_CFLAGS_JVM="$OS_CFLAGS_JVM -DSUPPORTS_CLOCK_MONOTONIC" ++ if test "x$CLOCK_GETTIME_IN_LIBRT" = "xtrue"; then ++ OS_CFLAGS_JVM="$OS_CFLAGS_JVM -DNEEDS_LIBRT" ++ fi ++ fi ++ + # Extra flags needed when building optional static versions of certain + # JDK libraries. + STATIC_LIBS_CFLAGS="-DSTATIC_BUILD=1" +diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4 +index b4f62ca19..23df5f1b5 100644 +--- a/make/autoconf/libraries.m4 ++++ b/make/autoconf/libraries.m4 +@@ -148,15 +148,6 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES], + BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lpthread" + fi + +- # librt for legacy clock_gettime +- if test "x$OPENJDK_TARGET_OS" = xlinux; then +- # Hotspot needs to link librt to get the clock_* functions. +- # But once our supported minimum build and runtime platform +- # has glibc 2.17, this can be removed as the functions are +- # in libc. +- BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lrt" +- fi +- + # perfstat lib + if test "x$OPENJDK_TARGET_OS" = xaix; then + BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lperfstat" +diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp +index a914422e5..f1990407d 100644 +--- a/src/hotspot/os/aix/os_aix.cpp ++++ b/src/hotspot/os/aix/os_aix.cpp +@@ -948,6 +948,21 @@ double os::elapsedVTime() { + } + } + ++jlong os::javaTimeMillis() { ++ timeval time; ++ int status = gettimeofday(&time, NULL); ++ assert(status != -1, "aix error at gettimeofday()"); ++ return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); ++} ++ ++void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) { ++ timeval time; ++ int status = gettimeofday(&time, NULL); ++ assert(status != -1, "aix error at gettimeofday()"); ++ seconds = jlong(time.tv_sec); ++ nanos = jlong(time.tv_usec) * 1000; ++} ++ + // We use mread_real_time here. + // On AIX: If the CPU has a time register, the result will be RTC_POWER and + // it has to be converted to real time. AIX documentations suggests to do +diff --git a/src/hotspot/os/aix/os_aix.inline.hpp b/src/hotspot/os/aix/os_aix.inline.hpp +index f7e7ee8ab..4ded87316 100644 +--- a/src/hotspot/os/aix/os_aix.inline.hpp ++++ b/src/hotspot/os/aix/os_aix.inline.hpp +@@ -56,4 +56,9 @@ inline void os::map_stack_shadow_pages(address sp) { + inline bool os::can_trim_native_heap() { return false; } + inline bool os::trim_native_heap(os::size_change_t* rss_change) { return false; } + ++inline bool os::supports_monotonic_clock() { ++ // mread_real_time() is monotonic on AIX (see os::javaTimeNanos() comments) ++ return true; ++} ++ + #endif // OS_AIX_OS_AIX_INLINE_HPP +diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp +index eca9aa9c9..526cf82bc 100644 +--- a/src/hotspot/os/bsd/os_bsd.cpp ++++ b/src/hotspot/os/bsd/os_bsd.cpp +@@ -125,6 +125,8 @@ julong os::Bsd::_physical_memory = 0; + #ifdef __APPLE__ + mach_timebase_info_data_t os::Bsd::_timebase_info = {0, 0}; + volatile uint64_t os::Bsd::_max_abstime = 0; ++#else ++int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL; + #endif + pthread_t os::Bsd::_main_thread; + +@@ -745,13 +747,40 @@ double os::elapsedVTime() { + return elapsedTime(); + } + ++jlong os::javaTimeMillis() { ++ timeval time; ++ int status = gettimeofday(&time, NULL); ++ assert(status != -1, "bsd error"); ++ return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); ++} ++ ++void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) { ++ timeval time; ++ int status = gettimeofday(&time, NULL); ++ assert(status != -1, "bsd error"); ++ seconds = jlong(time.tv_sec); ++ nanos = jlong(time.tv_usec) * 1000; ++} ++ ++#ifndef __APPLE__ ++ #ifndef CLOCK_MONOTONIC ++ #define CLOCK_MONOTONIC (1) ++ #endif ++#endif ++ + #ifdef __APPLE__ + void os::Bsd::clock_init() { + mach_timebase_info(&_timebase_info); + } + #else + void os::Bsd::clock_init() { +- // Nothing to do ++ struct timespec res; ++ struct timespec tp; ++ if (::clock_getres(CLOCK_MONOTONIC, &res) == 0 && ++ ::clock_gettime(CLOCK_MONOTONIC, &tp) == 0) { ++ // yes, monotonic clock is supported ++ _clock_gettime = ::clock_gettime; ++ } + } + #endif + +@@ -783,14 +812,44 @@ jlong os::javaTimeNanos() { + return (prev == obsv) ? now : obsv; + } + +-void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { +- info_ptr->max_value = ALL_64_BITS; +- info_ptr->may_skip_backward = false; // not subject to resetting or drifting +- info_ptr->may_skip_forward = false; // not subject to resetting or drifting +- info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time ++#else // __APPLE__ ++ ++jlong os::javaTimeNanos() { ++ if (os::supports_monotonic_clock()) { ++ struct timespec tp; ++ int status = Bsd::_clock_gettime(CLOCK_MONOTONIC, &tp); ++ assert(status == 0, "gettime error"); ++ jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec); ++ return result; ++ } else { ++ timeval time; ++ int status = gettimeofday(&time, NULL); ++ assert(status != -1, "bsd error"); ++ jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec); ++ return 1000 * usecs; ++ } + } + #endif // __APPLE__ + ++void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { ++ if (os::supports_monotonic_clock()) { ++ info_ptr->max_value = ALL_64_BITS; ++ ++ // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past ++ info_ptr->may_skip_backward = false; // not subject to resetting or drifting ++ info_ptr->may_skip_forward = false; // not subject to resetting or drifting ++ } else { ++ // gettimeofday - based on time in seconds since the Epoch thus does not wrap ++ info_ptr->max_value = ALL_64_BITS; ++ ++ // gettimeofday is a real time clock so it skips ++ info_ptr->may_skip_backward = true; ++ info_ptr->may_skip_forward = true; ++ } ++ ++ info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time ++} ++ + // Information of current thread in variety of formats + pid_t os::Bsd::gettid() { + int retval = -1; +diff --git a/src/hotspot/os/bsd/os_bsd.hpp b/src/hotspot/os/bsd/os_bsd.hpp +index f79212bc4..7bf3ff83b 100644 +--- a/src/hotspot/os/bsd/os_bsd.hpp ++++ b/src/hotspot/os/bsd/os_bsd.hpp +@@ -36,6 +36,8 @@ class os::Bsd { + // mach_absolute_time + static mach_timebase_info_data_t _timebase_info; + static volatile uint64_t _max_abstime; ++#else ++ static int (*_clock_gettime)(clockid_t, struct timespec *); + #endif + + static GrowableArray* _cpu_to_node; +diff --git a/src/hotspot/os/bsd/os_bsd.inline.hpp b/src/hotspot/os/bsd/os_bsd.inline.hpp +index 2049b3371..706a8b861 100644 +--- a/src/hotspot/os/bsd/os_bsd.inline.hpp ++++ b/src/hotspot/os/bsd/os_bsd.inline.hpp +@@ -59,4 +59,12 @@ inline void os::map_stack_shadow_pages(address sp) { + inline bool os::can_trim_native_heap() { return false; } + inline bool os::trim_native_heap(os::size_change_t* rss_change) { return false; } + ++inline bool os::supports_monotonic_clock() { ++#ifdef __APPLE__ ++ return true; ++#else ++ return Bsd::_clock_gettime != NULL; ++#endif ++} ++ + #endif // OS_BSD_OS_BSD_INLINE_HPP +diff --git a/src/hotspot/os/bsd/os_perf_bsd.cpp b/src/hotspot/os/bsd/os_perf_bsd.cpp +index 631d2135b..8d5702378 100644 +--- a/src/hotspot/os/bsd/os_perf_bsd.cpp ++++ b/src/hotspot/os/bsd/os_perf_bsd.cpp +@@ -58,13 +58,12 @@ class CPUPerformanceInterface::CPUPerformance : public CHeapObj { + int _active_processor_count; + + bool now_in_nanos(uint64_t* resultp) { +- struct timespec tp; +- int status = clock_gettime(CLOCK_REALTIME, &tp); +- assert(status == 0, "clock_gettime error: %s", os::strerror(errno)); +- if (status != 0) { ++ timeval current_time; ++ if (gettimeofday(¤t_time, NULL) != 0) { ++ // Error getting current time + return false; + } +- *resultp = tp.tv_sec * NANOS_PER_SEC + tp.tv_nsec; ++ *resultp = current_time.tv_sec * NANOS_PER_SEC + 1000L * current_time.tv_usec; + return true; + } + #endif +diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp +index ddc9ac85c..f73459337 100644 +--- a/src/hotspot/os/linux/os_linux.cpp ++++ b/src/hotspot/os/linux/os_linux.cpp +@@ -1410,6 +1410,11 @@ void os::Linux::capture_initial_stack(size_t max_size) { + + //////////////////////////////////////////////////////////////////////////////// + // time support ++ ++#ifndef SUPPORTS_CLOCK_MONOTONIC ++#error "Build platform doesn't support clock_gettime and related functionality" ++#endif ++ + double os::elapsedVTime() { + struct rusage usage; + int retval = getrusage(RUSAGE_THREAD, &usage); +@@ -1421,6 +1426,38 @@ double os::elapsedVTime() { + } + } + ++jlong os::javaTimeMillis() { ++ if (os::Posix::supports_clock_gettime()) { ++ struct timespec ts; ++ int status = os::Posix::clock_gettime(CLOCK_REALTIME, &ts); ++ assert_status(status == 0, status, "gettime error"); ++ return jlong(ts.tv_sec) * MILLIUNITS + ++ jlong(ts.tv_nsec) / NANOUNITS_PER_MILLIUNIT; ++ } else { ++ timeval time; ++ int status = gettimeofday(&time, NULL); ++ assert(status != -1, "linux error"); ++ return jlong(time.tv_sec) * MILLIUNITS + ++ jlong(time.tv_usec) / (MICROUNITS / MILLIUNITS); ++ } ++} ++ ++void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) { ++ if (os::Posix::supports_clock_gettime()) { ++ struct timespec ts; ++ int status = os::Posix::clock_gettime(CLOCK_REALTIME, &ts); ++ assert_status(status == 0, status, "gettime error"); ++ seconds = jlong(ts.tv_sec); ++ nanos = jlong(ts.tv_nsec); ++ } else { ++ timeval time; ++ int status = gettimeofday(&time, NULL); ++ assert(status != -1, "linux error"); ++ seconds = jlong(time.tv_sec); ++ nanos = jlong(time.tv_usec) * (NANOUNITS / MICROUNITS); ++ } ++} ++ + void os::Linux::fast_thread_clock_init() { + if (!UseLinuxPosixThreadCPUClocks) { + return; +@@ -1441,12 +1478,47 @@ void os::Linux::fast_thread_clock_init() { + + if (pthread_getcpuclockid_func && + pthread_getcpuclockid_func(_main_thread, &clockid) == 0 && +- clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) { ++ os::Posix::clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) { + _supports_fast_thread_cpu_time = true; + _pthread_getcpuclockid = pthread_getcpuclockid_func; + } + } + ++jlong os::javaTimeNanos() { ++ if (os::supports_monotonic_clock()) { ++ struct timespec tp; ++ int status = os::Posix::clock_gettime(CLOCK_MONOTONIC, &tp); ++ assert(status == 0, "gettime error"); ++ jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec); ++ return result; ++ } else { ++ timeval time; ++ int status = gettimeofday(&time, NULL); ++ assert(status != -1, "linux error"); ++ jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec); ++ return 1000 * usecs; ++ } ++} ++ ++void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { ++ if (os::supports_monotonic_clock()) { ++ info_ptr->max_value = ALL_64_BITS; ++ ++ // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past ++ info_ptr->may_skip_backward = false; // not subject to resetting or drifting ++ info_ptr->may_skip_forward = false; // not subject to resetting or drifting ++ } else { ++ // gettimeofday - based on time in seconds since the Epoch thus does not wrap ++ info_ptr->max_value = ALL_64_BITS; ++ ++ // gettimeofday is a real time clock so it skips ++ info_ptr->may_skip_backward = true; ++ info_ptr->may_skip_forward = true; ++ } ++ ++ info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time ++} ++ + // thread_id is kernel thread id (similar to Solaris LWP id) + intx os::current_thread_id() { return os::Linux::gettid(); } + int os::current_process_id() { +@@ -4412,8 +4484,8 @@ OSReturn os::get_native_priority(const Thread* const thread, + + jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) { + struct timespec tp; +- int status = clock_gettime(clockid, &tp); +- assert(status == 0, "clock_gettime error: %s", os::strerror(errno)); ++ int rc = os::Posix::clock_gettime(clockid, &tp); ++ assert(rc == 0, "clock_gettime is expected to return 0 code"); + return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec; + } + +@@ -4533,6 +4605,12 @@ void os::init(void) { + FLAG_SET_DEFAULT(UseMadvPopulateWrite, (::madvise(0, 0, MADV_POPULATE_WRITE) == 0)); + + os::Posix::init(); ++ ++ // Always warn if no monotonic clock available ++ if (!os::Posix::supports_monotonic_clock()) { ++ warning("No monotonic clock was available - timed services may " \ ++ "be adversely affected if the time-of-day clock changes"); ++ } + } + + // To install functions for atexit system call +diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp +index 7f95560a1..cb4122ab8 100644 +--- a/src/hotspot/os/posix/os_posix.cpp ++++ b/src/hotspot/os/posix/os_posix.cpp +@@ -23,7 +23,6 @@ + */ + + #include "classfile/classLoader.hpp" +-#include "jvm.h" + #include "jvmtifiles/jvmti.h" + #include "logging/log.hpp" + #include "memory/allocation.inline.hpp" +@@ -97,6 +96,12 @@ + #define assert_with_errno(cond, msg) check_with_errno(assert, cond, msg) + #define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg) + ++#if defined(AMD64) ++ __asm__(".symver posix_spawn,posix_spawn@GLIBC_2.2.5"); ++#elif defined(AARCH64) ++ __asm__(".symver posix_spawn,posix_spawn@GLIBC_2.17"); ++#endif ++ + static jlong initial_time_count = 0; + + static int clock_tics_per_sec = 100; +@@ -832,6 +837,10 @@ int os::connect(int fd, struct sockaddr* him, socklen_t len) { + RESTARTABLE_RETURN_INT(::connect(fd, him, len)); + } + ++bool os::supports_monotonic_clock() { ++ return os::Posix::supports_monotonic_clock(); ++} ++ + void os::exit(int num) { + ALLOW_C_FUNCTION(::exit, ::exit(num);) + } +@@ -1223,6 +1232,23 @@ static void pthread_init_common(void) { + PlatformMutex::init(); + } + ++// Not all POSIX types and API's are available on all notionally "posix" ++// platforms. If we have build-time support then we will check for actual ++// runtime support via dlopen/dlsym lookup. This allows for running on an ++// older OS version compared to the build platform. But if there is no ++// build time support then there cannot be any runtime support as we do not ++// know what the runtime types would be (for example clockid_t might be an ++// int or int64_t). ++// ++#ifdef SUPPORTS_CLOCK_MONOTONIC ++ ++// This means we have clockid_t, clock_gettime et al and CLOCK_MONOTONIC ++ ++int (*os::Posix::_clock_gettime)(clockid_t, struct timespec *) = NULL; ++int (*os::Posix::_clock_getres)(clockid_t, struct timespec *) = NULL; ++ ++bool os::Posix::_supports_monotonic_clock = false; ++ + static int (*_pthread_condattr_setclock)(pthread_condattr_t *, clockid_t) = nullptr; + + static bool _use_clock_monotonic_condattr = false; +@@ -1238,7 +1264,44 @@ void os::Posix::init(void) { + // NOTE: no logging available when this is called. Put logging + // statements in init_2(). + +- // Check for pthread_condattr_setclock support. ++ // 1. Check for CLOCK_MONOTONIC support. ++ ++ void* handle = NULL; ++ ++ // For older linux we need librt, for other OS we can find ++ // this function in regular libc. ++#ifdef NEEDS_LIBRT ++ // We do dlopen's in this particular order due to bug in linux ++ // dynamic loader (see 6348968) leading to crash on exit. ++ handle = dlopen("librt.so.1", RTLD_LAZY); ++ if (handle == NULL) { ++ handle = dlopen("librt.so", RTLD_LAZY); ++ } ++#endif ++ ++ if (handle == NULL) { ++ handle = RTLD_DEFAULT; ++ } ++ ++ int (*clock_getres_func)(clockid_t, struct timespec*) = ++ (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres"); ++ int (*clock_gettime_func)(clockid_t, struct timespec*) = ++ (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_gettime"); ++ if (clock_getres_func != NULL && clock_gettime_func != NULL) { ++ _clock_gettime = clock_gettime_func; ++ _clock_getres = clock_getres_func; ++ // We assume that if both clock_gettime and clock_getres support ++ // CLOCK_MONOTONIC then the OS provides true high-res monotonic clock. ++ struct timespec res; ++ struct timespec tp; ++ if (clock_getres_func(CLOCK_MONOTONIC, &res) == 0 && ++ clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) { ++ // Yes, monotonic clock is supported. ++ _supports_monotonic_clock = true; ++ } ++ } ++ ++ // 2. Check for pthread_condattr_setclock support. + + // libpthread is already loaded. + int (*condattr_setclock_func)(pthread_condattr_t*, clockid_t) = +@@ -1253,7 +1316,7 @@ void os::Posix::init(void) { + pthread_init_common(); + + int status; +- if (_pthread_condattr_setclock != nullptr) { ++ if (_pthread_condattr_setclock != nullptr && _clock_gettime != nullptr) { + if ((status = _pthread_condattr_setclock(_condAttr, CLOCK_MONOTONIC)) != 0) { + if (status == EINVAL) { + _use_clock_monotonic_condattr = false; +@@ -1271,13 +1334,28 @@ void os::Posix::init(void) { + } + + void os::Posix::init_2(void) { +- log_info(os)("Use of CLOCK_MONOTONIC is supported"); ++ log_info(os)("Use of CLOCK_MONOTONIC is%s supported",(_clock_gettime != NULL ? "" : " not")); + log_info(os)("Use of pthread_condattr_setclock is%s supported", + (_pthread_condattr_setclock != nullptr ? "" : " not")); + log_info(os)("Relative timed-wait using pthread_cond_timedwait is associated with %s", + _use_clock_monotonic_condattr ? "CLOCK_MONOTONIC" : "the default clock"); + } + ++#else // !SUPPORTS_CLOCK_MONOTONIC ++ ++void os::Posix::init(void) { ++ pthread_init_common(); ++} ++ ++void os::Posix::init_2(void) { ++ log_info(os)("Use of CLOCK_MONOTONIC is not supported"); ++ log_info(os)("Use of pthread_condattr_setclock is not supported"); ++ log_info(os)("Relative timed-wait using pthread_cond_timedwait is associated with the default clock"); ++} ++ ++#endif // SUPPORTS_CLOCK_MONOTONIC ++ ++ + // Utility to convert the given timeout to an absolute timespec + // (based on the appropriate clock) to use with pthread_cond_timewait, + // and sem_timedwait(). +@@ -1329,6 +1406,7 @@ static void calc_rel_time(timespec* abstime, jlong timeout, jlong now_sec, + + // Unpack the given deadline in milliseconds since the epoch, into the given timespec. + // The current time in seconds is also passed in to enforce an upper bound as discussed above. ++// This is only used with gettimeofday, when clock_gettime is not available. + static void unpack_abs_time(timespec* abstime, jlong deadline, jlong now_sec) { + time_t max_secs = now_sec + MAX_SECS; + +@@ -1363,21 +1441,38 @@ static void to_abstime(timespec* abstime, jlong timeout, + timeout = 0; + } + +- clockid_t clock = CLOCK_MONOTONIC; +- if (isAbsolute || (!_use_clock_monotonic_condattr || isRealtime)) { +- clock = CLOCK_REALTIME; +- } +- +- struct timespec now; +- int status = clock_gettime(clock, &now); +- assert(status == 0, "clock_gettime error: %s", os::strerror(errno)); ++#ifdef SUPPORTS_CLOCK_MONOTONIC + +- if (!isAbsolute) { ++ clockid_t clock = CLOCK_MONOTONIC; ++ // need to ensure we have a runtime check for clock_gettime support ++ if (!isAbsolute && os::Posix::supports_monotonic_clock()) { ++ if (!_use_clock_monotonic_condattr || isRealtime) { ++ clock = CLOCK_REALTIME; ++ } ++ struct timespec now; ++ int status = os::Posix::clock_gettime(clock, &now); ++ assert_status(status == 0, status, "clock_gettime"); + calc_rel_time(abstime, timeout, now.tv_sec, now.tv_nsec, NANOUNITS); ++ DEBUG_ONLY(max_secs += now.tv_sec;) + } else { +- unpack_abs_time(abstime, timeout, now.tv_sec); ++ ++#else ++ ++ { // Match the block scope. ++ ++#endif // SUPPORTS_CLOCK_MONOTONIC ++ ++ // Time-of-day clock is all we can reliably use. ++ struct timeval now; ++ int status = gettimeofday(&now, NULL); ++ assert_status(status == 0, errno, "gettimeofday"); ++ if (isAbsolute) { ++ unpack_abs_time(abstime, timeout, now.tv_sec); ++ } else { ++ calc_rel_time(abstime, timeout, now.tv_sec, now.tv_usec, MICROUNITS); ++ } ++ DEBUG_ONLY(max_secs += now.tv_sec;) + } +- DEBUG_ONLY(max_secs += now.tv_sec;) + + assert(abstime->tv_sec >= 0, "tv_sec < 0"); + assert(abstime->tv_sec <= max_secs, "tv_sec > max_secs"); +@@ -1393,50 +1486,6 @@ void os::Posix::to_RTC_abstime(timespec* abstime, int64_t millis) { + true /* use real-time clock */); + } + +-// Common (partly) shared time functions +- +-jlong os::javaTimeMillis() { +- struct timespec ts; +- int status = clock_gettime(CLOCK_REALTIME, &ts); +- assert(status == 0, "clock_gettime error: %s", os::strerror(errno)); +- return jlong(ts.tv_sec) * MILLIUNITS + +- jlong(ts.tv_nsec) / NANOUNITS_PER_MILLIUNIT; +-} +- +-void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) { +- struct timespec ts; +- int status = clock_gettime(CLOCK_REALTIME, &ts); +- assert(status == 0, "clock_gettime error: %s", os::strerror(errno)); +- seconds = jlong(ts.tv_sec); +- nanos = jlong(ts.tv_nsec); +-} +- +-// macOS and AIX have platform specific implementations for javaTimeNanos() +-// using native clock/timer access APIs. These have historically worked well +-// for those platforms, but it may be possible for them to switch to the +-// generic clock_gettime mechanism in the future. +-#if !defined(__APPLE__) && !defined(AIX) +- +-jlong os::javaTimeNanos() { +- struct timespec tp; +- int status = clock_gettime(CLOCK_MONOTONIC, &tp); +- assert(status == 0, "clock_gettime error: %s", os::strerror(errno)); +- jlong result = jlong(tp.tv_sec) * NANOSECS_PER_SEC + jlong(tp.tv_nsec); +- return result; +-} +- +-// for timer info max values which include all bits +-#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) +- +-void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { +- // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past +- info_ptr->max_value = ALL_64_BITS; +- info_ptr->may_skip_backward = false; // not subject to resetting or drifting +- info_ptr->may_skip_forward = false; // not subject to resetting or drifting +- info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time +-} +-#endif // ! APPLE && !AIX +- + // Time since start-up in seconds to a fine granularity. + double os::elapsedTime() { + return ((double)os::elapsed_counter()) / os::elapsed_frequency(); // nanosecond resolution +diff --git a/src/hotspot/os/posix/os_posix.hpp b/src/hotspot/os/posix/os_posix.hpp +index 9e98f4316..0fb974634 100644 +--- a/src/hotspot/os/posix/os_posix.hpp ++++ b/src/hotspot/os/posix/os_posix.hpp +@@ -96,6 +96,23 @@ public: + static address ucontext_get_pc(const ucontext_t* ctx); + static void ucontext_set_pc(ucontext_t* ctx, address pc); + ++#ifdef SUPPORTS_CLOCK_MONOTONIC ++ ++private: ++ static bool _supports_monotonic_clock; ++ // These need to be members so we can access them from inline functions ++ static int (*_clock_gettime)(clockid_t, struct timespec *); ++ static int (*_clock_getres)(clockid_t, struct timespec *); ++public: ++ static bool supports_monotonic_clock(); ++ static bool supports_clock_gettime(); ++ static int clock_gettime(clockid_t clock_id, struct timespec *tp); ++ static int clock_getres(clockid_t clock_id, struct timespec *tp); ++#else ++ static bool supports_monotonic_clock() { return false; } ++ static bool supports_clock_gettime() { return false; } ++#endif ++ + static void to_RTC_abstime(timespec* abstime, int64_t millis); + + static bool handle_stack_overflow(JavaThread* thread, address addr, address pc, +diff --git a/src/hotspot/os/posix/os_posix.inline.hpp b/src/hotspot/os/posix/os_posix.inline.hpp +index cf81c5d62..52bdca757 100644 +--- a/src/hotspot/os/posix/os_posix.inline.hpp ++++ b/src/hotspot/os/posix/os_posix.inline.hpp +@@ -37,6 +37,28 @@ + // Aix does not have NUMA support but need these for compilation. + inline bool os::numa_has_group_homing() { AIX_ONLY(ShouldNotReachHere();) return false; } + ++#ifdef SUPPORTS_CLOCK_MONOTONIC ++ ++// Exported clock functionality ++ ++inline bool os::Posix::supports_monotonic_clock() { ++ return _supports_monotonic_clock; ++} ++ ++inline bool os::Posix::supports_clock_gettime() { ++ return _clock_gettime != NULL; ++} ++ ++inline int os::Posix::clock_gettime(clockid_t clock_id, struct timespec *tp) { ++ return _clock_gettime != NULL ? _clock_gettime(clock_id, tp) : -1; ++} ++ ++inline int os::Posix::clock_getres(clockid_t clock_id, struct timespec *tp) { ++ return _clock_getres != NULL ? _clock_getres(clock_id, tp) : -1; ++} ++ ++#endif // SUPPORTS_CLOCK_MONOTONIC ++ + // Platform Mutex/Monitor implementation + + inline void PlatformMutex::lock() { +diff --git a/src/hotspot/share/prims/upcallLinker.cpp b/src/hotspot/share/prims/upcallLinker.cpp +index d9692bd52..a1e39a4c1 100644 +--- a/src/hotspot/share/prims/upcallLinker.cpp ++++ b/src/hotspot/share/prims/upcallLinker.cpp +@@ -26,6 +26,9 @@ + #include "classfile/symbolTable.hpp" + #include "classfile/systemDictionary.hpp" + #include "compiler/compilationPolicy.hpp" ++#if defined(AARCH64) || defined(AMD64) ++#include "memory/allocation.hpp" ++#endif // AARCH64 || AMD64 + #include "memory/resourceArea.hpp" + #include "prims/upcallLinker.hpp" + #include "runtime/interfaceSupport.inline.hpp" +@@ -44,7 +47,11 @@ extern struct JavaVM_ main_vm; + // to keep track of the fact that we have attached a native thread to the VM. When the thread local + // storage is destroyed (which happens when the native threads is terminated), we check if the + // storage has an attached thread and, if so, we detach it from the VM. ++#if defined(AARCH64) || defined(AMD64) ++struct UpcallContext: public CHeapObj { ++#else + struct UpcallContext { ++#endif // AARCH64 || AMD64 + Thread* attachedThread; + + UpcallContext() {} // Explicit constructor to address XL C compiler bug. +@@ -56,9 +63,36 @@ struct UpcallContext { + } + }; + ++#if defined(AARCH64) || defined(AMD64) ++static unsigned int upcall_thread_key; ++ ++void ThreadLocalUpCall::upcall_destructor(void* threadContext) { ++ delete static_cast(threadContext); ++} ++ ++void ThreadLocalUpCall::init() { ++ int rslt = pthread_key_create(&upcall_thread_key, upcall_destructor); ++ assert_status(rslt == 0, rslt, "pthread_key_create"); ++} ++ ++void* ThreadLocalUpCall::get() { ++ return pthread_getspecific(upcall_thread_key); ++} ++ ++void ThreadLocalUpCall::set() { ++ if (!ThreadLocalUpCall::get()) { ++ UpcallContext* threadContext = new UpcallContext(); ++ pthread_setspecific(upcall_thread_key, threadContext); ++ } ++} ++#else + APPROVED_CPP_THREAD_LOCAL UpcallContext threadContext; ++#endif // AARCH64 || AMD64 + + JavaThread* UpcallLinker::maybe_attach_and_get_thread() { ++#if defined(AARCH64) || defined(AMD64) ++ ThreadLocalUpCall::set(); ++#endif // AARCH64 || AMD64 + JavaThread* thread = JavaThread::current_or_null(); + if (thread == nullptr) { + JavaVM_ *vm = (JavaVM *)(&main_vm); +@@ -66,7 +100,11 @@ JavaThread* UpcallLinker::maybe_attach_and_get_thread() { + jint result = vm->functions->AttachCurrentThreadAsDaemon(vm, (void**) &p_env, nullptr); + guarantee(result == JNI_OK, "Could not attach thread for upcall. JNI error code: %d", result); + thread = JavaThread::current(); ++#if defined(AARCH64) || defined(AMD64) ++ ((UpcallContext *)(ThreadLocalUpCall::get()))->attachedThread = thread; ++#else + threadContext.attachedThread = thread; ++#endif // AARCH64 || AMD64 + assert(!thread->has_last_Java_frame(), "newly-attached thread not expected to have last Java frame"); + } + return thread; +diff --git a/src/hotspot/share/prims/upcallLinker.hpp b/src/hotspot/share/prims/upcallLinker.hpp +index 3f8c717e5..417e16a48 100644 +--- a/src/hotspot/share/prims/upcallLinker.hpp ++++ b/src/hotspot/share/prims/upcallLinker.hpp +@@ -46,4 +46,14 @@ public: + bool needs_return_buffer, int ret_buf_size); + }; + ++#if defined(AARCH64) || defined(AMD64) ++class ThreadLocalUpCall { ++public: ++ static void upcall_destructor(void* threadContext); ++ static void init(); ++ static void set(); ++ static void* get(); ++}; ++#endif // AARCH64 || AMD64 ++ + #endif // SHARE_VM_PRIMS_UPCALLLINKER_HPP +diff --git a/src/hotspot/share/runtime/javaThread.cpp b/src/hotspot/share/runtime/javaThread.cpp +index 515a8d9d9..43da36495 100644 +--- a/src/hotspot/share/runtime/javaThread.cpp ++++ b/src/hotspot/share/runtime/javaThread.cpp +@@ -2026,7 +2026,7 @@ bool JavaThread::sleep_nanos(jlong nanos) { + if (newtime - prevtime < 0) { + // time moving backwards, should only happen if no monotonic clock + // not a guarantee() because JVM should not abort on kernel/glibc bugs +- assert(false, ++ assert(!os::supports_monotonic_clock(), + "unexpected time moving backwards detected in JavaThread::sleep()"); + } else { + nanos_remaining -= (newtime - prevtime); +diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp +index 1cc59d275..10b53c3de 100644 +--- a/src/hotspot/share/runtime/os.hpp ++++ b/src/hotspot/share/runtime/os.hpp +@@ -262,6 +262,7 @@ class os: AllStatic { + static void javaTimeNanos_info(jvmtiTimerInfo *info_ptr); + static void javaTimeSystemUTC(jlong &seconds, jlong &nanos); + static void run_periodic_checks(outputStream* st); ++ static bool supports_monotonic_clock(); + + // Returns the elapsed time in seconds since the vm started. + static double elapsedTime(); +diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp +index 8b7058405..0df523f76 100644 +--- a/src/hotspot/share/runtime/threads.cpp ++++ b/src/hotspot/share/runtime/threads.cpp +@@ -58,6 +58,7 @@ + #include "oops/symbol.hpp" + #include "prims/jvmtiAgentList.hpp" + #include "prims/jvm_misc.hpp" ++#include "prims/upcallLinker.hpp" + #include "runtime/arguments.hpp" + #include "runtime/fieldDescriptor.inline.hpp" + #include "runtime/flags/jvmFlagLimit.hpp" +@@ -424,6 +425,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { + // Initialize library-based TLS + ThreadLocalStorage::init(); + ++ // Initialize ThreadLocalUpCall ++ ThreadLocalUpCall::init(); ++ + // Initialize the output stream module + ostream_init(); + +-- +2.34.1 + diff --git a/jdk-updates-jdk21u-jdk-21.0.8+9.tar.gz b/jdk-updates-jdk21u-jdk-21.0.9+10.tar.gz similarity index 86% rename from jdk-updates-jdk21u-jdk-21.0.8+9.tar.gz rename to jdk-updates-jdk21u-jdk-21.0.9+10.tar.gz index 1ea9749566b155457ac32292521f7df3f57cae5e..a61d8843f260536bd53f3412a483d7095c5a313a 100644 Binary files a/jdk-updates-jdk21u-jdk-21.0.8+9.tar.gz and b/jdk-updates-jdk21u-jdk-21.0.9+10.tar.gz differ diff --git a/openjdk-21.spec b/openjdk-21.spec index 3f6d080fbd64d7fcbee1a9f4f49256d133f21b4a..5378f6732a1262c7b2b21583e8d65b9a8b202992 100644 --- a/openjdk-21.spec +++ b/openjdk-21.spec @@ -160,7 +160,7 @@ # Used via new version scheme. JDK 19 was # GA'ed in March 2022 => 22.3 %global vendor_version_string BiSheng -%global securityver 8 +%global securityver 9 # buildjdkver is usually same as %%{majorver}, # but in time of bootstrap of next jdk, it is majorver-1, # and this it is better to change it here, on single place @@ -180,7 +180,7 @@ %global origin_nice OpenJDK %global top_level_dir_name %{origin} %global minorver 0 -%global buildver 9 +%global buildver 10 %global rpmrelease 1 # 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 @@ -905,7 +905,7 @@ Name: java-21-%{origin} Version: %{newjavaver}.%{buildver} # This package needs `.rolling` as part of Release so as to not conflict on install with # java-X-openjdk. I.e. when latest rolling release is also an LTS release packaged as -Release: 7 +Release: 0 # 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 @@ -1012,7 +1012,6 @@ Patch64: Backport-JDK-8337334-Test-tools-javac-7142086-T71420.patch Patch65: Backport-JDK-8340623-Remove-outdated-PROCESSOR_ARCHI.patch Patch67: Backport-JDK-8340186-Shenandoah-Missing-load_referen.patch Patch68: Backport-JDK-8340273-Remove-CounterHalfLifeTime.patch -Patch69: Backport-JDK-8339460-CDS-error-when-module-is-locate.patch Patch70: Backport-JDK-8332297-annotation-processor-that-gener.patch Patch71: Backport-JDK-8329174-update-CodeBuffer-layout-in-com.patch Patch72: Backport-JDK-8325994-JFR-Examples-in-JFR.start-help-.patch @@ -1032,7 +1031,6 @@ Patch85: huawei-Adapt-to-clang-build-toolchain.patch #21.0.7 Patch87: huawei-fix-build-fail-realpath.patch Patch89: heapdump-bug-fix.patch -Patch90: Backport-JDK-7036144-GZIPInputStream-readTrailer-use.patch Patch92: Backport-JDK-8340532-C2-assert-is_OuterStripMinedLoo.patch Patch93: huawei-fix-arm32-build-fail-undefined-reference-_Copy_conjo.patch Patch94: huawei-AArch64-Incorrect-matching-rule.patch @@ -1040,6 +1038,9 @@ Patch94: huawei-AArch64-Incorrect-matching-rule.patch #21.0.8 Patch95: huawei-remove-provides-in-kaeprovider-module-info.patch +#21.0.9 +Patch96: huawei-posix_spawn-clock_gettime-clock_getres-__cxa_thread_.patch + ############################################ # # LoongArch64 specific patches @@ -1328,7 +1329,6 @@ pushd %{top_level_dir_name} %patch65 -p1 %patch67 -p1 %patch68 -p1 -%patch69 -p1 %patch70 -p1 %patch71 -p1 %patch72 -p1 @@ -1346,11 +1346,11 @@ pushd %{top_level_dir_name} %patch85 -p1 %patch87 -p1 %patch89 -p1 -%patch90 -p1 %patch92 -p1 %patch93 -p1 %patch94 -p1 %patch95 -p1 +%patch96 -p1 popd # openjdk %endif @@ -1934,6 +1934,13 @@ cjc.mainProgram(args) -- the returns from copy_jdk_configs.lua should not affect %changelog +* Fri Oct 17 2025 Benshuai5D - 1:21.0.9.10-0 +- update to jdk21.0.9-ga +- delete Backport-JDK-8339460-CDS-error-when-module-is-locate.patch +- delete Backport-JDK-7036144-GZIPInputStream-readTrailer-use.patch +- modify huawei-Add-KAE-zip-feature.patch +- add huawei-posix_spawn-clock_gettime-clock_getres-__cxa_thread_.patch + * Fri Oct 17 2025 zhangzejian - 1:21.0.8.9-7 - RISC-V Add Zfa zli imm loads