Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions substratevm/mx.substratevm/mx_substratevm.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ def svm_gate_body(args, tasks):
javac_command = ['--javac-command', ' '.join(javac_image_command(svmbuild_dir()))]
helloworld(['--output-path', svmbuild_dir()] + javac_command)
helloworld(['--output-path', svmbuild_dir(), '--shared']) # Build and run helloworld as shared library
if not mx.is_windows():
helloworld(['--output-path', svmbuild_dir(), '-J-XX:StartFlightRecording=dumponexit=true']) # Build and run helloworld with FlightRecorder at image build time
cinterfacetutorial([])
clinittest([])

Expand Down
3 changes: 3 additions & 0 deletions substratevm/mx.substratevm/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,9 @@
"jdk.unsupported"
],
"requiresConcealed": {
"jdk.management": [
"com.sun.management.internal"
],
"jdk.jfr": [
"jdk.jfr.internal",
"jdk.jfr.internal.consumer",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,6 @@ public static void registerInvocationPlugins(AnnotationSubstitutionProcessor ann
registerArrayPlugins(plugins, snippetReflection, parsingReason);
registerClassPlugins(plugins, snippetReflection);
registerEdgesPlugins(metaAccess, plugins);
registerJFRThrowablePlugins(plugins, replacements);
registerJFREventTokenPlugins(plugins, replacements);
registerVMConfigurationPlugins(snippetReflection, plugins);
registerPlatformPlugins(snippetReflection, plugins);
registerAWTPlugins(plugins);
Expand Down Expand Up @@ -969,39 +967,6 @@ protected static long longValue(GraphBuilderContext b, ResolvedJavaMethod target
return node.asJavaConstant().asLong();
}

/*
* When Java Flight Recorder is enabled during image generation, the bytecodes of some methods
* get instrumented. Undo the instrumentation so that it does not end up in the generated image.
*/

private static void registerJFRThrowablePlugins(InvocationPlugins plugins, Replacements replacements) {
Registration r = new Registration(plugins, "oracle.jrockit.jfr.jdkevents.ThrowableTracer", replacements).setAllowOverwrite(true);
r.register2("traceError", Error.class, String.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode throwable, ValueNode message) {
return true;
}
});
r.register2("traceThrowable", Throwable.class, String.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode throwable, ValueNode message) {
return true;
}
});
}

private static void registerJFREventTokenPlugins(InvocationPlugins plugins, Replacements replacements) {
Registration r = new Registration(plugins, "com.oracle.jrockit.jfr.EventToken", replacements);
r.register1("isEnabled", Receiver.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
receiver.get();
b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
return true;
}
});
}

private static void registerVMConfigurationPlugins(SnippetReflectionProvider snippetReflection, InvocationPlugins plugins) {
Registration r = new Registration(plugins, ImageSingletons.class);
r.register1("contains", Class.class, new InvocationPlugin() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@

import java.util.function.BooleanSupplier;

import org.graalvm.compiler.serviceprovider.JavaVersionUtil;

import com.oracle.svm.core.OS;
import com.oracle.svm.core.VMInspectionOptions;
import org.graalvm.compiler.api.replacements.Fold;
import org.graalvm.nativeimage.ImageSingletons;

/**
* Used to include/exclude JFR feature and substitutions.
Expand All @@ -40,15 +38,8 @@ public boolean getAsBoolean() {
return get();
}

@Fold
public static boolean get() {
return VMInspectionOptions.AllowVMInspection.getValue() && jvmVersionSupported() && osSupported();
}

private static boolean jvmVersionSupported() {
return JavaVersionUtil.JAVA_SPEC >= 11;
}

private static boolean osSupported() {
return OS.getCurrent() == OS.LINUX || OS.getCurrent() == OS.DARWIN;
return ImageSingletons.contains(JfrFeature.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.BooleanSupplier;

import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.hosted.RuntimeClassInitialization;
import org.graalvm.nativeimage.hosted.RuntimeReflection;
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;

import com.oracle.svm.core.OS;
import com.oracle.svm.core.VMInspectionOptions;
import com.oracle.svm.core.annotate.AutomaticFeature;
import com.oracle.svm.core.annotate.Uninterruptible;
import com.oracle.svm.core.hub.DynamicHub;
Expand All @@ -47,12 +50,16 @@
import com.oracle.svm.core.meta.SharedType;
import com.oracle.svm.core.thread.ThreadListenerFeature;
import com.oracle.svm.core.thread.ThreadListenerSupport;
import com.oracle.svm.core.util.UserError;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.FeatureImpl;
import com.oracle.svm.jfr.traceid.JfrTraceId;
import com.oracle.svm.jfr.traceid.JfrTraceIdEpoch;
import com.oracle.svm.jfr.traceid.JfrTraceIdMap;
import com.oracle.svm.util.ModuleSupport;
import com.oracle.svm.util.ReflectionUtil;
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.internal.PlatformMBeanProviderImpl;

import jdk.jfr.Configuration;
import jdk.jfr.Event;
Expand Down Expand Up @@ -100,13 +107,59 @@
* consistent state).</li>
* </ul>
*/
@Platforms({Platform.LINUX.class, Platform.DARWIN.class})
@AutomaticFeature
public class JfrFeature implements Feature {

public static final class JfrHostedEnabled implements BooleanSupplier {
@Override
public boolean getAsBoolean() {
return ImageSingletons.contains(JfrFeature.class) && ImageSingletons.lookup(JfrFeature.class).hostedEnabled;
}
}

private final boolean hostedEnabled;

public JfrFeature() {
hostedEnabled = Boolean.valueOf(getDiagnosticBean().getVMOption("FlightRecorder").getValue());
}

@Override
public boolean isInConfiguration(IsInConfigurationAccess access) {
return JfrEnabled.get();
boolean systemSupported = jvmVersionSupported() && osSupported();
if (hostedEnabled && !systemSupported) {
throw UserError.abort("FlightRecorder cannot be used to profile the image generator on this platform. " +
"The image generator can only be profiled on platforms where FlightRecoder is also supported at run time.");
}
boolean runtimeEnabled = VMInspectionOptions.AllowVMInspection.getValue();
if (hostedEnabled && !runtimeEnabled) {
// Checkstyle: stop
System.err.println("Warning: When FlightRecoder is used to profile the image generator, it is also automatically enabled in the native image at run time. " +
"This can affect the measurements because it can can make the image larger and image build time longer.");
// Checkstyle: resume
runtimeEnabled = true;
}
return runtimeEnabled && systemSupported;
}

private static boolean jvmVersionSupported() {
return JavaVersionUtil.JAVA_SPEC >= 11;
}

private static boolean osSupported() {
return OS.getCurrent() == OS.LINUX || OS.getCurrent() == OS.DARWIN;
}

/**
* We cannot use the proper way of looking up the bean via
* {@link java.lang.management.ManagementFactory} because that initializes too many classes at
* image build time that we want to initialize only at run time.
*/
private static HotSpotDiagnosticMXBean getDiagnosticBean() {
try {
return (HotSpotDiagnosticMXBean) ReflectionUtil.lookupMethod(PlatformMBeanProviderImpl.class, "getDiagnosticMXBean").invoke(null);
} catch (ReflectiveOperationException ex) {
throw VMError.shouldNotReachHere(ex);
}
}

@Override
Expand Down Expand Up @@ -134,6 +187,14 @@ public void afterRegistration(AfterRegistrationAccess access) {
JfrSerializerSupport.get().register(new JfrFrameTypeSerializer());
JfrSerializerSupport.get().register(new JfrThreadStateSerializer());
ThreadListenerSupport.get().register(SubstrateJVM.getThreadLocal());

if (hostedEnabled) {
RuntimeClassInitializationSupport rci = ImageSingletons.lookup(RuntimeClassInitializationSupport.class);
rci.initializeAtBuildTime("jdk.management.jfr", "Allow FlightRecorder to be used at image build time");
rci.initializeAtBuildTime("com.sun.jmx.mbeanserver", "Allow FlightRecorder to be used at image build time");
rci.initializeAtBuildTime("com.sun.jmx.defaults", "Allow FlightRecorder to be used at image build time");
rci.initializeAtBuildTime("java.beans", "Allow FlightRecorder to be used at image build time");
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2021, 2021, 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. 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.oracle.svm.jfr;

import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.TargetClass;

@TargetClass(className = "com.sun.jmx.mbeanserver.MXBeanIntrospector", onlyWith = JfrFeature.JfrHostedEnabled.class)
final class Target_com_sun_jmx_mbeanserver_MXBeanIntrospector {

/* Reset caches that are used at image build time when FlightRecorder is enabled. */
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClassName = "com.sun.jmx.mbeanserver.MXBeanIntrospector") //
private static Target_com_sun_jmx_mbeanserver_MXBeanIntrospector instance;
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClassName = "com.sun.jmx.mbeanserver.MBeanIntrospector$MBeanInfoMap") //
private static Target_com_sun_jmx_mbeanserver_MBeanIntrospector_MBeanInfoMap mbeanInfoMap;
}

@TargetClass(className = "com.sun.jmx.mbeanserver.MBeanIntrospector", innerClass = "MBeanInfoMap")
final class Target_com_sun_jmx_mbeanserver_MBeanIntrospector_MBeanInfoMap {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021, 2021, 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. 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.oracle.svm.jfr;

import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.jfr.JfrFeature.JfrHostedEnabled;

@TargetClass(className = "com.sun.jmx.mbeanserver.MXBeanLookup", onlyWith = JfrHostedEnabled.class)
final class Target_com_sun_jmx_mbeanserver_MXBeanLookup {

/* Reset caches that are used at image build time when FlightRecorder is enabled. */
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClassName = "com.sun.jmx.mbeanserver.WeakIdentityHashMap") //
private static Target_com_sun_jmx_mbeanserver_WeakIdentityHashMap mbscToLookup;
}

@TargetClass(className = "com.sun.jmx.mbeanserver.WeakIdentityHashMap")
final class Target_com_sun_jmx_mbeanserver_WeakIdentityHashMap {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2021, 2021, 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. 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.oracle.svm.jfr;

import java.util.ArrayList;

import javax.management.MBeanServerBuilder;

import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.TargetClass;

@TargetClass(className = "javax.management.MBeanServerFactory", onlyWith = JfrFeature.JfrHostedEnabled.class)
final class Target_javax_management_MBeanServerFactory {

/* Reset caches that are used at image build time when FlightRecorder is enabled. */
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias) //
private static ArrayList<?> mBeanServerList = new ArrayList<>();
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias) //
private static MBeanServerBuilder builder = null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2021, 2021, 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. 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.oracle.svm.jfr;

import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.jfr.JfrFeature.JfrHostedEnabled;

import jdk.jfr.FlightRecorder;

@TargetClass(value = jdk.jfr.FlightRecorder.class, onlyWith = JfrHostedEnabled.class)
final class Target_jdk_jfr_FlightRecorder {
/*
* Ignore all state of the FlightRecorder maintained when profiling the image generator itself.
*/
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //
private static FlightRecorder platformRecorder;
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //
private static boolean initialized;
}