diff --git a/src/hotspot/share/cds/aotClassLinker.cpp b/src/hotspot/share/cds/aotClassLinker.cpp index dc539eb3d553f..28159e813049d 100644 --- a/src/hotspot/share/cds/aotClassLinker.cpp +++ b/src/hotspot/share/cds/aotClassLinker.cpp @@ -117,9 +117,9 @@ void AOTClassLinker::add_new_candidate(InstanceKlass* ik) { _candidates->put_when_absent(ik, true); _sorted_candidates->append(ik); - if (log_is_enabled(Info, cds, aot, link)) { + if (log_is_enabled(Info, aot, link)) { ResourceMark rm; - log_info(cds, aot, link)("%s %s %p", class_category_name(ik), ik->external_name(), ik); + log_info(aot, link)("%s %s %p", class_category_name(ik), ik->external_name(), ik); } } @@ -149,7 +149,7 @@ bool AOTClassLinker::try_add_candidate(InstanceKlass* ik) { InstanceKlass* nest_host = ik->nest_host_not_null(); if (!try_add_candidate(nest_host)) { ResourceMark rm; - log_warning(cds, aot, link)("%s cannot be aot-linked because it nest host is not aot-linked", ik->external_name()); + log_warning(aot, link)("%s cannot be aot-linked because it nest host is not aot-linked", ik->external_name()); return false; } } @@ -232,7 +232,7 @@ Array* AOTClassLinker::write_classes(oop class_loader, bool is_j return nullptr; } else { const char* category = class_category_name(list.at(0)); - log_info(cds, aot, link)("wrote %d class(es) for category %s", list.length(), category); + log_info(aot, link)("wrote %d class(es) for category %s", list.length(), category); return ArchiveUtils::archive_array(&list); } } diff --git a/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp b/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp index 31d95024e3bfd..0c4e07d332805 100644 --- a/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp +++ b/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp @@ -179,11 +179,11 @@ void AOTLinkedClassBulkLoader::load_classes_impl(AOTLinkedClassCategory class_ca for (int i = 0; i < classes->length(); i++) { InstanceKlass* ik = classes->at(i); - if (log_is_enabled(Info, cds, aot, load)) { + if (log_is_enabled(Info, aot, load)) { ResourceMark rm(THREAD); - log_info(cds, aot, load)("%-5s %s%s%s", category_name, ik->external_name(), - ik->is_loaded() ? " (already loaded)" : "", - ik->is_hidden() ? " (hidden)" : ""); + log_info(aot, load)("%-5s %s%s%s", category_name, ik->external_name(), + ik->is_loaded() ? " (already loaded)" : "", + ik->is_hidden() ? " (hidden)" : ""); } if (!ik->is_loaded()) { @@ -236,11 +236,11 @@ void AOTLinkedClassBulkLoader::initiate_loading(JavaThread* current, const char* assert(ik->class_loader() == nullptr || ik->class_loader() == SystemDictionary::java_platform_loader(), "must be"); if (ik->is_public() && !ik->is_hidden()) { - if (log_is_enabled(Info, cds, aot, load)) { + if (log_is_enabled(Info, aot, load)) { ResourceMark rm(current); const char* defining_loader = (ik->class_loader() == nullptr ? "boot" : "plat"); - log_info(cds, aot, load)("%s %s (initiated, defined by %s)", category_name, ik->external_name(), - defining_loader); + log_info(aot, load)("%s %s (initiated, defined by %s)", category_name, ik->external_name(), + defining_loader); } SystemDictionary::add_to_initiating_loader(current, ik, loader_data); } diff --git a/src/hotspot/share/cds/cdsConfig.cpp b/src/hotspot/share/cds/cdsConfig.cpp index 463bfe3a98df3..9224e877dce48 100644 --- a/src/hotspot/share/cds/cdsConfig.cpp +++ b/src/hotspot/share/cds/cdsConfig.cpp @@ -407,7 +407,12 @@ void CDSConfig::check_aot_flags() { } if (FLAG_IS_DEFAULT(AOTCache) && FLAG_IS_DEFAULT(AOTConfiguration) && FLAG_IS_DEFAULT(AOTMode)) { - // AOTCache/AOTConfiguration/AOTMode not used. + // AOTCache/AOTConfiguration/AOTMode not used -> using the "classic CDS" workflow. + + // The old "cds" log tags are deprecated, but we keep printing them for now as [cds] + // for the classic workflow to be backwards compatible with older script. This will be + // removed as part of JDK-8356317. + PrintCDSLogsAsAOTLogs = false; return; } else { _new_aot_flags_used = true; diff --git a/src/hotspot/share/cds/cds_globals.hpp b/src/hotspot/share/cds/cds_globals.hpp index b5657a73ef132..1d256b58f9fa7 100644 --- a/src/hotspot/share/cds/cds_globals.hpp +++ b/src/hotspot/share/cds/cds_globals.hpp @@ -99,6 +99,9 @@ "do not map the archive") \ range(0, 2) \ \ + product(bool, PrintCDSLogsAsAOTLogs, true, DIAGNOSTIC, \ + "Print [cds] logs as [aot] logs when AOT cache is used") \ + \ /*========== New "AOT" flags =========================================*/ \ /* The following 3 flags are aliases of -Xshare:dump, */ \ /* -XX:SharedArchiveFile=..., etc. See CDSConfig::check_flag_aliases()*/ \ diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index 654c2e7ecd780..9b5ba681926ed 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -1141,7 +1141,8 @@ void MetaspaceShared::report_loading_error(const char* format, ...) { static bool printed_error = false; if (!printed_error) { // No need for locks. Loading error checks happen only in main thread. - ls.print_cr("An error has occurred while processing the %s. Run with -Xlog:cds for details.", CDSConfig::type_of_archive_being_loaded()); + ls.print_cr("An error has occurred while processing the %s. Run with -Xlog:%s for details.", + CDSConfig::type_of_archive_being_loaded(), PrintCDSLogsAsAOTLogs ? "aot" : "cds"); printed_error = true; } diff --git a/src/hotspot/share/logging/logSelection.cpp b/src/hotspot/share/logging/logSelection.cpp index 476fdebc9c540..d93382c220927 100644 --- a/src/hotspot/share/logging/logSelection.cpp +++ b/src/hotspot/share/logging/logSelection.cpp @@ -21,6 +21,8 @@ * questions. * */ + +#include "cds/cds_globals.hpp" #include "jvm_io.h" #include "logging/log.hpp" #include "logging/logSelection.hpp" @@ -180,7 +182,16 @@ bool LogSelection::selects(const LogTagSet& ts) const { if (!_wildcard && _ntags != ts.ntags()) { return false; } - for (size_t i = 0; i < _ntags; i++) { + size_t i = 0; + +#if INCLUDE_CDS + if (PrintCDSLogsAsAOTLogs && _ntags > 0 && _tags[0] == LogTag::_aot && ts.tag(0) == LogTag::_cds) { + // Consider it a match + i++; + } +#endif + + for (; i < _ntags; i++) { if (!ts.contains(_tags[i])) { return false; } diff --git a/src/hotspot/share/logging/logTagSet.cpp b/src/hotspot/share/logging/logTagSet.cpp index 4719d0a926ee4..485a66999e87d 100644 --- a/src/hotspot/share/logging/logTagSet.cpp +++ b/src/hotspot/share/logging/logTagSet.cpp @@ -21,6 +21,8 @@ * questions. * */ + +#include "cds/cds_globals.hpp" #include "jvm.h" #include "logging/logAsyncWriter.hpp" #include "logging/logDecorations.hpp" @@ -32,6 +34,7 @@ #include "logging/logTagSet.hpp" #include "logging/logTagSetDescriptions.hpp" #include "memory/allocation.inline.hpp" +#include "memory/resourceArea.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/ostream.hpp" #include "utilities/permitForbiddenFunctions.hpp" @@ -95,7 +98,16 @@ void LogTagSet::log(const LogMessageBuffer& msg) { } void LogTagSet::label(outputStream* st, const char* separator) const { - for (size_t i = 0; i < _ntags; i++) { + size_t i = 0; + +#if INCLUDE_CDS + if (PrintCDSLogsAsAOTLogs && _ntags > 0 && _tag[0] == LogTag::_cds) { + st->print("%s", "aot"); + i++; + } +#endif + + for (; i < _ntags; i++) { st->print("%s%s", (i == 0 ? "" : separator), LogTag::name(_tag[i])); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/AOTFlags.java b/test/hotspot/jtreg/runtime/cds/appcds/AOTFlags.java index 53036071fe313..ad7e06ee0e98e 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/AOTFlags.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/AOTFlags.java @@ -74,7 +74,7 @@ static void positiveTests() throws Exception { "-cp", appJar); out = CDSTestUtils.executeAndLog(pb, "asm"); out.shouldContain("Dumping shared data to file:"); - out.shouldMatch("cds.*hello[.]aot"); + out.shouldMatch("hello[.]aot"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -142,7 +142,7 @@ static void positiveTests() throws Exception { "-cp", appJar); out = CDSTestUtils.executeAndLog(pb, "asm"); out.shouldContain("Dumping shared data to file:"); - out.shouldMatch("cds.*hello[.]aot"); + out.shouldMatch("hello[.]aot"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java index 5050550221785..77e7293d1c5ee 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java @@ -50,9 +50,9 @@ public static void main(String... args) throws Exception { .addVmArgs("-Xlog:cds+class=debug", "-Xlog:cds") .appCommandLine("AppWithCustomLoaders") .setAssemblyChecker((OutputAnalyzer out) -> { - out.shouldMatch("cds,class.*unreg AppWithCustomLoaders[$]MyLoadeeA") - .shouldMatch("cds,class.*array \\[LAppWithCustomLoaders[$]MyLoadeeA;") - .shouldNotMatch("cds,class.* ReturnIntegerAsString"); + out.shouldMatch(",class.*unreg AppWithCustomLoaders[$]MyLoadeeA") + .shouldMatch(",class.*array \\[LAppWithCustomLoaders[$]MyLoadeeA;") + .shouldNotMatch(",class.* ReturnIntegerAsString"); }) .setProductionChecker((OutputAnalyzer out) -> { out.shouldContain("Using AOT-linked classes: true"); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java new file mode 100644 index 0000000000000..413657f32b769 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2025, 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 + * @summary when AOT cache options are used, old "cds" logs should be aliased to "aot". + * @requires vm.cds + * @requires vm.flagless + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes + * @build Hello + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello + * @run driver AOTLoggingTag + */ + +import java.io.File; +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class AOTLoggingTag { + static String appJar = ClassFileInstaller.getJarPath("hello.jar"); + static String aotConfigFile = "hello.aotconfig"; + static String aotCacheFile = "hello.aot"; + static String helloClass = "Hello"; + + public static void main(String[] args) throws Exception { + ProcessBuilder pb; + OutputAnalyzer out; + + //---------------------------------------------------------------------- + printTestCase("Training Run"); + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTMode=record", + "-XX:AOTConfiguration=" + aotConfigFile, + "-Xlog:aot", + "-cp", appJar, helloClass); + + out = CDSTestUtils.executeAndLog(pb, "train"); + out.shouldContain("[info][aot] Writing binary AOTConfiguration file:"); + out.shouldHaveExitValue(0); + + //---------------------------------------------------------------------- + printTestCase("Assembly Phase"); + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTMode=create", + "-XX:AOTConfiguration=" + aotConfigFile, + "-XX:AOTCache=" + aotCacheFile, + "-Xlog:aot", + "-cp", appJar); + out = CDSTestUtils.executeAndLog(pb, "asm"); + out.shouldContain("[info][aot] Opened AOT configuration file hello.aotconfig"); + out.shouldHaveExitValue(0); + + //---------------------------------------------------------------------- + printTestCase("Production Run with AOTCache"); + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTCache=" + aotCacheFile, + "-Xlog:aot", + "-cp", appJar, helloClass); + out = CDSTestUtils.executeAndLog(pb, "prod"); + out.shouldContain("[info][aot] Opened AOT cache hello.aot"); + out.shouldHaveExitValue(0); + + //---------------------------------------------------------------------- + printTestCase("-Xlog:aot+heap should alias to -Xlog:cds+heap"); + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTCache=" + aotCacheFile, + "-Xlog:aot+heap", + "-cp", appJar, helloClass); + out = CDSTestUtils.executeAndLog(pb, "prod"); + out.shouldNotContain("No tag set matches selection: aot+heap"); + out.shouldContain("[info][aot,heap] resolve subgraph java.lang.Integer$IntegerCache"); + out.shouldHaveExitValue(0); + + //---------------------------------------------------------------------- + printTestCase("When running with AOT cache, -Xlog:cds should be printed using [aot] decoration"); + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTCache=" + aotCacheFile, + "-Xlog:cds", + "-cp", appJar, helloClass); + out = CDSTestUtils.executeAndLog(pb, "prod"); + out.shouldContain("[info][aot] Opened AOT cache hello.aot"); + out.shouldHaveExitValue(0); + + //---------------------------------------------------------------------- + printTestCase("Production Run: errors should be printed with [aot] decoration"); + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTCache=nosuchfile.aot", + "-XX:AOTMode=on", + "-cp", appJar, helloClass); + out = CDSTestUtils.executeAndLog(pb, "prod"); + out.shouldContain("[error][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details."); + out.shouldNotHaveExitValue(0); + } + + static int testNum = 0; + static void printTestCase(String s) { + System.out.println("vvvvvvv TEST CASE " + testNum + ": " + s + " starts here vvvvvvv"); + testNum++; + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java index aa34f4799366f..3b67c0792d380 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java @@ -137,7 +137,7 @@ public String classpath(RunMode runMode) { @Override public String[] vmArgs(RunMode runMode) { return new String[] { - "-Xlog:cds,cds+aot+load,cds+class=debug", + "-Xlog:cds,aot+load,cds+class=debug", "-XX:+AOTClassLinking", }; } @@ -158,7 +158,7 @@ public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception if (isDumping(runMode)) { // Check that we are archiving classes for custom class loaders. - out.shouldMatch("cds,class.* SimpleCusty"); + out.shouldMatch(",class.* SimpleCusty"); } } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java index 5bec6623a08d8..8c2539df6210d 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java @@ -94,9 +94,9 @@ public String[] appCommandLine(RunMode runMode) { @Override public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception { if (isDumping(runMode)) { - out.shouldMatch("cds,class.* FakeCodeLocationApp"); - out.shouldNotMatch("cds,class.* ClassNotInJar1"); - out.shouldNotMatch("cds,class.* ClassNotInJar2"); + out.shouldMatch(",class.* FakeCodeLocationApp"); + out.shouldNotMatch(",class.* ClassNotInJar1"); + out.shouldNotMatch(",class.* ClassNotInJar2"); } if (runMode.isProductionRun()) {