Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/hotspot/share/include/jvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ JVM_InternString(JNIEnv *env, jstring str);
/*
* java.lang.System
*/
JNIEXPORT jboolean JNICALL
JVM_AOTEndRecording(JNIEnv *env);

JNIEXPORT jlong JNICALL
JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored);

Expand Down
13 changes: 13 additions & 0 deletions src/hotspot/share/prims/jvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,19 @@ extern void trace_class_resolution(Klass* to_class) {

// java.lang.System //////////////////////////////////////////////////////////////////////

JVM_ENTRY(jboolean, JVM_AOTEndRecording(JNIEnv *env))
#if INCLUDE_CDS
if (CDSConfig::is_dumping_preimage_static_archive()) {
if (AOTMetaspace::is_recording_preimage_static_archive()) {
AOTMetaspace::dump_static_archive(THREAD);
return JNI_TRUE;
}
}
return JNI_FALSE;
#else
return JNI_FALSE;
#endif // INCLUDE_CDS
JVM_END

JVM_LEAF(jlong, JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored))
return os::javaTimeMillis();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
Expand Down Expand Up @@ -48,6 +48,9 @@ public interface VMManagement {
public boolean isGcNotificationSupported();
public boolean isRemoteDiagnosticCommandsSupported();

// AOT Subsystem
public boolean endAOTRecording();

// Class Loading Subsystem
public long getTotalClassCount();
public int getLoadedClassCount();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
Expand Down Expand Up @@ -117,6 +117,9 @@ public boolean isRemoteDiagnosticCommandsSupported() {
public native boolean isThreadCpuTimeEnabled();
public native boolean isThreadAllocatedMemoryEnabled();

// AOT Subsystem
public native boolean endAOTRecording();

// Class Loading Subsystem
public int getLoadedClassCount() {
long count = getTotalClassCount() - getUnloadedClassCount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ Java_sun_management_VMManagementImpl_getVmArguments0
return JVM_GetVmArguments(env);
}

JNIEXPORT jboolean JNICALL
Java_sun_management_VMManagementImpl_endAOTRecording
(JNIEnv *env, jobject dummy)
{
return JVM_AOTEndRecording(env);
}

JNIEXPORT jlong JNICALL
Java_sun_management_VMManagementImpl_getTotalClassCount
(JNIEnv *env, jobject dummy)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.management.internal;

import javax.management.ObjectName;
import jdk.management.HotSpotAOTCacheMXBean;
import sun.management.Util;
import sun.management.VMManagement;

/**
* Implementation class for the AOT Cache subsystem.
*
* ManagementFactory.getRuntimeMXBean() returns an instance
* of this class.
*/
public class HotSpotAOTCacheImpl implements HotSpotAOTCacheMXBean {

private final VMManagement jvm;
/**
* Constructor of HotSpotAOTCacheImpl class.
*/
HotSpotAOTCacheImpl(VMManagement vm) {
this.jvm = vm;
}

public boolean endRecording(){
return jvm.endAOTRecording();
}

public ObjectName getObjectName() {
return Util.newObjectName("jdk.management:type=HotSpotAOTCache");
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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
Expand Down Expand Up @@ -39,6 +39,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.management.DynamicMBean;
import jdk.management.HotSpotAOTCacheMXBean;
import jdk.management.VirtualThreadSchedulerMXBean;
import sun.management.ManagementFactoryHelper;
import sun.management.spi.PlatformMBeanProvider;
Expand Down Expand Up @@ -159,6 +160,41 @@ public synchronized Map<String, java.lang.management.ThreadMXBean> nameToMBeanMa
}
});

/**
* HotSpotAOTCacheMXBean.
*/
initMBeanList.add(new PlatformComponent<HotSpotAOTCacheMXBean>() {
private final Set<Class<? extends HotSpotAOTCacheMXBean>> mbeanInterfaces =
Set.of(HotSpotAOTCacheMXBean.class);
private final Set<String> mbeanInterfaceNames =
Set.of(HotSpotAOTCacheMXBean.class.getName());
private HotSpotAOTCacheMXBean impl;

@Override
public Set<Class<? extends HotSpotAOTCacheMXBean>> mbeanInterfaces() {
return mbeanInterfaces;
}

@Override
public Set<String> mbeanInterfaceNames() {
return mbeanInterfaceNames;
}

@Override
public String getObjectNamePattern() {
return "jdk.management:type=HotSpotAOTCache";
}

@Override
public Map<String, HotSpotAOTCacheMXBean> nameToMBeanMap() {
HotSpotAOTCacheMXBean impl = this.impl;
if (impl == null) {
this.impl = impl = new HotSpotAOTCacheImpl(ManagementFactoryHelper.getVMManagement());
}
return Map.of("jdk.management:type=HotSpotAOTCache", impl);
}
});

/**
* VirtualThreadSchedulerMXBean.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.management;

import java.lang.management.ManagementFactory;
import java.lang.management.PlatformManagedObject;
import java.util.concurrent.ForkJoinPool;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume there is no need to import ForkJoinPool.

import javax.management.MBeanServer;
import javax.management.ObjectName;

/**
* Management interface for the JDK's Ahead of Time (AOT) optimizations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the word "optimizations" here but don't have a better one. Maybe "operation"? Still not great

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, one possible alternative is kind of implicit in the bean name:

"Management interface for the JDK's Ahead of Time (AOT) Cache"

*
* Currently, {@code HotSpotAOTCacheMXBean} defines one operation at this time to end the AOT recording.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you drop "Currently, ", it will be a bit clearer without it.

* More operations and/or properties may be added in a future release.
*
* <p> The management interface is registered with the platform {@link MBeanServer
* MBeanServer}. The {@link ObjectName ObjectName} that uniquely identifies the management
* interface within the {@code MBeanServer} is: "jdk.management:type=HotSpotAOTCache".
*
* <p> Direct access to the MXBean interface can be obtained with
* {@link ManagementFactory#getPlatformMXBean(Class)}.
*
* @since 26
*/
public interface HotSpotAOTCacheMXBean extends PlatformManagedObject {
/**
* If an AOT recording is in progress, ends the recording. This operation completes
* after the AOT artifacts have been completely written.
*
* <p>The JVM will start recording AOT artifacts upon start-up if certain JVM options are
* given in the command-line. The recording will stop when the JVM exits, or when
* the {@code endRecording} method is called. Examples:
*
* <p> java -XX:AOTCacheOutput=app.aot ....
*
* <blockquote>
* The JVM will record optimization information about the current application
* into the AOT cache file app.aot. In a future execution of this application,
* -XX:AOTCache=app.aot can be provided to improve the application's
* start-up and warm-up performance.
* </blockquote>
*
* <p> java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconfig ....
*
* <blockquote>
* The JVM will record optimization information about the current application
* into the AOT configuration file app.aotconfig. Subsequently, an AOT cache
* file can be created with the command:
*
* <p>java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconfig -XX:AOTCache=app.aot ...
* <blockquote>
*
* <p>For more information about creating and using the AOT artifacts, and detailed
* specification of the corresponding JVM command-line options, please refer
* to https://openjdk.org/jeps/483 and https://openjdk.org/jeps/514.
*
* <p>Note: Currently there are no APIs to start an AOT recording. AOT recordings must be
* started using JVM command-line options such as -XX:AOTCacheOutput.
*
* <p> There are also no APIs to querying whether the AOT recording is in progress, or what AOT
* artifacts are being recorded. If such information is required by the application, it should be passed
* to the application via system properties or command-line arguments. For example:
*
* <p> java -XX:AOTCacheOutput=app.aot -Dmyapp.cache.output=app.aot -jar myapp.jar MyApp
*
* <blockquote>
* The application can contain logic like the following. Note that it's possible
* to access the AOT cache file using regular file I/O APIs after the endRecording() function
* has returned {@code true}.
* <pre>
* {@code
* HotSpotAOTCacheMXBean bean = ....;
* String aotCache = System.getProperty("myapp.cache.output");
* if (aotCache != null) {
* System.out.println("JVM is recording into " + aotCache);
* performSomeActionsThatNeedsToBeRecorded();
* if (bean.endRecording()) {
* System.out.println("Recording is successfully finished: " + aotCache);
* }
* }</pre>
* </blockquote>
*
* @return {@code true} if a recording was in progress and has been ended successfully; {@code false} otherwise.
*/
Copy link
Contributor

@AlanBateman AlanBateman Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are issues in the javadoc that will cause the docs target to fail, e.g. mismatched blockquote. Can you fix these up so that we can generate the docs from the changes in the PR?

Copy link
Contributor Author

@macarte macarte Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an easy way to test the correctness of the javadoc parts (I couldn't find an option for javadoc). The </blockquote >above is matched to a <blockquote> on line 88, but there is a <pre></pre> pair in between, is that the issue you are referring to?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make docs. The second blockquote is matched with another blockquote, not </blockquote>. In the example, which can be converted to a snippet, then then braces not matched so the end brace for {@code ... } get mixed up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that now - fixing ....

Copy link
Contributor Author

@macarte macarte Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also removed the nested {@code ..} from within the <pre></pre> as that also caused an issue

public boolean endRecording();
}
Loading