-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8370203 - Add jcmd AOT.end_recording diagnostic command #27965
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ | |
| * | ||
| */ | ||
|
|
||
| #include "cds/aotMetaspace.hpp" | ||
| #include "cds/cds_globals.hpp" | ||
| #include "cds/cdsConfig.hpp" | ||
| #include "classfile/classLoaderDataGraph.hpp" | ||
|
|
@@ -165,6 +166,7 @@ void DCmd::register_dcmds(){ | |
|
|
||
| #if INCLUDE_CDS | ||
| DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<DumpSharedArchiveDCmd>(full_export, true, false)); | ||
| DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<AOTEndRecordingDCmd>(full_export, true, false)); | ||
| #endif // INCLUDE_CDS | ||
|
|
||
| DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<NMTDCmd>(full_export, true, false)); | ||
|
|
@@ -986,6 +988,28 @@ void ClassesDCmd::execute(DCmdSource source, TRAPS) { | |
| VMThread::execute(&vmop); | ||
| } | ||
|
|
||
| #if INCLUDE_CDS | ||
| void AOTEndRecordingDCmd::execute(DCmdSource source, TRAPS) { | ||
| if (!CDSConfig::is_dumping_preimage_static_archive()) { | ||
| output()->print_cr("Error! Not a recording run"); | ||
| return; | ||
| } | ||
|
|
||
| if (!AOTMetaspace::is_recording_preimage_static_archive()) { | ||
| output()->print_cr("Error! Not recording"); | ||
| return; | ||
| } | ||
|
|
||
| AOTMetaspace::dump_static_archive(THREAD); | ||
| if (!AOTMetaspace::is_recording_preimage_static_archive()) { | ||
| output()->print_cr("Recording ended successfully"); | ||
| return; | ||
| } | ||
|
|
||
| output()->print_cr("Error! Failed to end recording"); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there an error recorded or anything further that could be included for the error case? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is not, currently, the aotMetaspace method throws an exception if something goes wrong. I added this line in case the flow in aotMetaspace changes. The logic here is that if we asked the recording to stop, but it's still recording then we report to the user that 'we failed to stop the recording' |
||
| } | ||
| #endif // INCLUDE_CDS | ||
|
|
||
| #if INCLUDE_CDS | ||
| #define DEFAULT_CDS_ARCHIVE_FILENAME "java_pid%p_<subcmd>.jsa" | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| /* | ||
| * Copyright (c) 2025, Microsoft, Inc. 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 | ||
| * @requires vm.cds.supports.aot.class.linking | ||
| * @requires vm.cds.write.archived.java.heap | ||
| * @summary Sanity test for Jcmd AOT.end_recording command | ||
| * @library /test/lib | ||
| * @build JcmdAOTEndRecordingTest | ||
| * @run driver JcmdAOTEndRecordingTest | ||
| */ | ||
|
|
||
| import jdk.test.lib.JDKToolLauncher; | ||
| import jdk.test.lib.process.ProcessTools; | ||
| import jdk.test.lib.apps.LingeredApp; | ||
| import jdk.test.lib.dcmd.PidJcmdExecutor; | ||
| import jdk.test.lib.process.OutputAnalyzer; | ||
| import java.io.IOException; | ||
|
|
||
| public class JcmdAOTEndRecordingTest { | ||
| public static void main(String[] args) throws Exception { | ||
| LingeredApp theApp = null; | ||
| try { | ||
| theApp = new LingeredApp(); | ||
| theApp.setUseDefaultClasspath(false); | ||
| LingeredApp.startApp(theApp); | ||
| long pid = theApp.getPid(); | ||
|
|
||
| JDKToolLauncher jcmd = JDKToolLauncher.createUsingTestJDK("jcmd"); | ||
| jcmd.addToolArg(String.valueOf(pid)); | ||
| jcmd.addToolArg("AOT.end_recording"); | ||
|
|
||
| try { | ||
| OutputAnalyzer output = ProcessTools.executeProcess(jcmd.getCommand()); | ||
| output.shouldContain("Error! Not a recording run"); | ||
| } catch (Exception e) { | ||
| throw new RuntimeException("Test failed: " + e); | ||
| } | ||
| } | ||
| catch (IOException e) { | ||
| throw new RuntimeException("Test failed: " + e); | ||
| } | ||
| finally { | ||
| LingeredApp.stopApp(theApp); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to use an acquiring load here? i.e. can the read here and the cmpxchg below happen in different threads?
n.b. I'm not just thinking about the behaviour when this patch makes the DCmd available but also what happens when we supplement it with the MXBean interface to end recordings.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's okay, as ending the recording is controlled by the cmpxchg, even if two threads think the recording is still going on, only one call to end the recording will work, and if the threads both check whether the recording has completed they will both see that it has (regardless of which thread 'won')