From 12a6d3e12dda9bba21dd8f2ec13c2361b235808f Mon Sep 17 00:00:00 2001 From: Tomas Zezula <tomas.zezula@oracle.com> Date: Tue, 23 Aug 2022 09:04:22 +0200 Subject: [PATCH 1/3] Removed deprecated libgraal management beans. --- compiler/CHANGELOG.md | 1 + compiler/mx.compiler/suite.py | 65 --- .../libgraal/annotation/JMXFromLibGraal.java | 100 ---- .../annotation/JMXFromLibGraalRepeated.java | 39 -- .../libgraal/annotation/JMXToLibGraal.java | 57 -- .../javax.annotation.processing.Processor | 1 - .../processor/JMXFromLibGraalProcessor.java | 63 -- .../management/AggregatedMemoryPoolBean.java | 198 ------- .../compiler/hotspot/management/Factory.java | 298 ---------- .../JMXFromLibGraalEntryPoints.java | 68 --- .../management/JMXToLibGraalCalls.java | 68 --- .../hotspot/management/LibGraalMBean.java | 541 ------------------ .../libgraal/JMXToLibGraalEntryPoints.java | 390 ------------- .../LibGraalHotSpotGraalManagement.java | 153 ----- .../libgraal/LibGraalMemoryPoolMBean.java | 235 -------- .../management/libgraal/MBeanProxy.java | 509 ---------------- .../compiler/hotspot/HotSpotGraalRuntime.java | 9 +- substratevm/mx.substratevm/mx_substratevm.py | 3 +- .../hotspot/libgraal/LibGraalEntryPoints.java | 14 - .../hotspot/libgraal/LibGraalFeature.java | 39 -- 20 files changed, 3 insertions(+), 2848 deletions(-) delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXFromLibGraal.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXFromLibGraalRepeated.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXToLibGraal.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal.processor/src/META-INF/services/javax.annotation.processing.Processor delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal.processor/src/org/graalvm/compiler/hotspot/management/libgraal/processor/JMXFromLibGraalProcessor.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/AggregatedMemoryPoolBean.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/Factory.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/JMXFromLibGraalEntryPoints.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/JMXToLibGraalCalls.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/LibGraalMBean.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/JMXToLibGraalEntryPoints.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/LibGraalHotSpotGraalManagement.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/LibGraalMemoryPoolMBean.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/MBeanProxy.java diff --git a/compiler/CHANGELOG.md b/compiler/CHANGELOG.md index 90d32ac16f84..62ff059dda8c 100644 --- a/compiler/CHANGELOG.md +++ b/compiler/CHANGELOG.md @@ -5,6 +5,7 @@ This changelog summarizes newly introduced optimizations that may be relevant to ## Version 22.3.0 * (GR-32382): Added a dedicated Native Image GC policy for libgraal that will adjust the eden space aggressively to minimize RSS memory usage. +* (GR-38950): Removed deprecated JMX `HotSpotGraalRuntime` management bean. ## Version 22.2.0 * (GR-23737): New global value numbering optimization for fixed nodes early in the compilation pipeline. diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index 6cc7021ea76c..e71058f5669c 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -640,54 +640,6 @@ "workingSets" : "Graal,HotSpot", }, - "org.graalvm.compiler.hotspot.management.libgraal.annotation" : { - "subDir" : "src", - "sourceDirs" : ["src"], - "dependencies" : [ - "org.graalvm.libgraal.jni.annotation", - ], - "checkstyle" : "org.graalvm.compiler.graph", - "javaCompliance" : "11+", - "workingSets" : "Graal", - }, - - "org.graalvm.compiler.hotspot.management.libgraal.processor" : { - "subDir" : "src", - "sourceDirs" : ["src"], - "dependencies" : [ - "org.graalvm.compiler.hotspot.management.libgraal.annotation", - "org.graalvm.libgraal.jni.processor", - ], - "requires" : [ - "java.compiler" # javax.annotation.processing.* - ], - "checkstyle" : "org.graalvm.compiler.graph", - "javaCompliance" : "11+", - "workingSets" : "Graal", - }, - - "org.graalvm.compiler.hotspot.management.libgraal" : { - "subDir" : "src", - "sourceDirs" : ["src"], - "dependencies" : [ - "org.graalvm.libgraal", - "org.graalvm.libgraal.jni", - "org.graalvm.compiler.hotspot.management", - "org.graalvm.compiler.hotspot.management.libgraal.annotation", - ], - "requires" : [ - "java.management", - ], - "checkstyle" : "org.graalvm.compiler.graph", - "checkPackagePrefix" : "false", - "annotationProcessors" : [ - "GRAAL_PROCESSOR", - "GRAAL_LIBGRAAL_PROCESSOR", - ], - "javaCompliance" : "11+", - "workingSets" : "Graal,HotSpot", - }, - "org.graalvm.compiler.hotspot.aarch64" : { "subDir" : "src", "sourceDirs" : ["src"], @@ -2028,7 +1980,6 @@ "dependencies" : [ "org.graalvm.libgraal.jni.processor", "org.graalvm.compiler.truffle.compiler.hotspot.libgraal.processor", - "org.graalvm.compiler.hotspot.management.libgraal.processor" ], "distDependencies" : ["GRAAL_PROCESSOR"], "maven": False, @@ -2157,22 +2108,6 @@ }, }, - "GRAAL_MANAGEMENT_LIBGRAAL": { - "subDir" : "src", - "dependencies" : [ - "org.graalvm.compiler.hotspot.management.libgraal", - ], - "overlaps" : [ - "GRAAL_LIBGRAAL_PROCESSOR" - ], - "distDependencies" : [ - "GRAAL_MANAGEMENT", - "GRAAL", - ], - "maven": False, - "javaCompliance" : "11+", - }, - "GRAAL_COMPILER_WHITEBOX_MICRO_BENCHMARKS" : { "subDir" : "src", "dependencies" : [ diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXFromLibGraal.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXFromLibGraal.java deleted file mode 100644 index dda233b50c8d..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXFromLibGraal.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2020, 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 org.graalvm.compiler.hotspot.management.libgraal.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import org.graalvm.libgraal.jni.annotation.FromLibGraalId; - -/** - * Annotates methods associated with both ends of a libgraal to HotSpot call. This annotation - * simplifies navigating between these methods in an IDE. The - * {@code org.graalvm.compiler.hotspot.management.libgraal.processor.JMXFromLibGraalProcessor} - * processor will produce a helper method for marshaling arguments and making the JNI call. - */ -@Repeatable(JMXFromLibGraalRepeated.class) -@Retention(RetentionPolicy.SOURCE) -@Target(ElementType.METHOD) -public @interface JMXFromLibGraal { - /** - * Gets the token identifying a call to HotSpot from libgraal. - */ - Id value(); - - /** - * Identifier for a call to HotSpot from libgraal. - */ - // Please keep sorted - enum Id implements FromLibGraalId { - GetFactory(Object.class), - SignalRegistrationRequest(void.class, Object.class, long.class), - Unregister(void.class, Object.class, long.class); - - private final String signature; - private final String methodName; - private final Class<?> returnType; - private final Class<?>[] parameterTypes; - - @Override - public String getName() { - return name(); - } - - @Override - public String getSignature() { - return signature; - } - - @Override - public String getMethodName() { - return methodName; - } - - @Override - public Class<?>[] getParameterTypes() { - return parameterTypes; - } - - @Override - public Class<?> getReturnType() { - return returnType; - } - - @Override - public String toString() { - return methodName + signature; - } - - Id(Class<?> returnType, Class<?>... parameterTypes) { - this.returnType = returnType; - this.parameterTypes = parameterTypes; - this.signature = FromLibGraalId.encodeMethodSignature(returnType, parameterTypes); - this.methodName = Character.toLowerCase(name().charAt(0)) + name().substring(1); - } - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXFromLibGraalRepeated.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXFromLibGraalRepeated.java deleted file mode 100644 index fcc07c0010c6..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXFromLibGraalRepeated.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2018, 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 org.graalvm.compiler.hotspot.management.libgraal.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Container for repeated {@link JMXFromLibGraal} annotations. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface JMXFromLibGraalRepeated { - JMXFromLibGraal[] value(); -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXToLibGraal.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXToLibGraal.java deleted file mode 100644 index 4d5b96a8228c..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.annotation/src/org/graalvm/compiler/hotspot/management/libgraal/annotation/JMXToLibGraal.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2020, 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 org.graalvm.compiler.hotspot.management.libgraal.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotates methods associated with both ends of a HotSpot to libgraal call. This annotation - * simplifies navigating between these methods in an IDE. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface JMXToLibGraal { - /** - * Gets the token identifying a call from HotSpot to libgraal. - */ - Id value(); - - /** - * Identifier for a call from HotSpot to libgraal. - */ - // Please keep sorted - enum Id { - FinishRegistration, - GetAttributes, - GetMBeanInfo, - GetObjectName, - Invoke, - PollRegistrations, - SetAttributes - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.processor/src/META-INF/services/javax.annotation.processing.Processor b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.processor/src/META-INF/services/javax.annotation.processing.Processor deleted file mode 100644 index ccf5ceb8c30b..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.processor/src/META-INF/services/javax.annotation.processing.Processor +++ /dev/null @@ -1 +0,0 @@ -org.graalvm.compiler.hotspot.management.libgraal.processor.JMXFromLibGraalProcessor diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.processor/src/org/graalvm/compiler/hotspot/management/libgraal/processor/JMXFromLibGraalProcessor.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.processor/src/org/graalvm/compiler/hotspot/management/libgraal/processor/JMXFromLibGraalProcessor.java deleted file mode 100644 index dcb8f81731d7..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal.processor/src/org/graalvm/compiler/hotspot/management/libgraal/processor/JMXFromLibGraalProcessor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2020, 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 org.graalvm.compiler.hotspot.management.libgraal.processor; - -import javax.annotation.processing.SupportedAnnotationTypes; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.PackageElement; -import org.graalvm.libgraal.jni.processor.AbstractFromLibGraalProcessor; -import org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal; -import org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal.Id; - -/** - * Processor for the {@link JMXFromLibGraal} annotation that generates code to push JNI arguments to - * the stack and make a JNI call corresponding to a {@link Id}. This helps mitigate bugs where - * incorrect arguments are pushed for a JNI call. Given the low level nature of - * {@code org.graalvm.nativeimage.StackValue}, it's very hard to use runtime assertion checking. - */ -@SupportedAnnotationTypes({"org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal", - "org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraalRepeated"}) -public class JMXFromLibGraalProcessor extends AbstractFromLibGraalProcessor<Id> { - - public JMXFromLibGraalProcessor() { - super(Id.class); - } - - @Override - protected boolean accept(ExecutableElement annotatedElement) { - PackageElement pkg = getPackage(annotatedElement); - return pkg != null && pkg.getQualifiedName().contentEquals("org.graalvm.compiler.hotspot.management.libgraal"); - } - - private static PackageElement getPackage(Element method) { - Element e = method.getEnclosingElement(); - while (e != null && e.getKind() != ElementKind.PACKAGE) { - e = e.getEnclosingElement(); - } - return (PackageElement) e; - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/AggregatedMemoryPoolBean.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/AggregatedMemoryPoolBean.java deleted file mode 100644 index e78a794a1f6e..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/AggregatedMemoryPoolBean.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2020, 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 org.graalvm.compiler.hotspot.management; - -import java.lang.management.MemoryPoolMXBean; -import java.lang.management.MemoryType; -import java.lang.management.MemoryUsage; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import javax.management.AttributeNotFoundException; -import javax.management.DynamicMBean; -import javax.management.MBeanException; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.management.ReflectionException; -import javax.management.openmbean.CompositeData; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; - -/** - * MemoryPoolBean providing aggregated memory usages for LibGraal isolates. - */ -@Platforms(Platform.HOSTED_ONLY.class) -public final class AggregatedMemoryPoolBean implements MemoryPoolMXBean { - - private static final String OBJECT_NAME = "java.lang:type=MemoryPool,name=Libgraal"; - - private final ObjectName objectName; - private final String[] memoryManagerNames; - private final String name; - private final MemoryType type; - private final Map<ObjectName, DynamicMBean> delegates; - - AggregatedMemoryPoolBean(DynamicMBean delegate, ObjectName delegateObjectName) throws MalformedObjectNameException { - this.delegates = Collections.synchronizedMap(new HashMap<>()); - this.objectName = new ObjectName(OBJECT_NAME); - String typeName = safeReadAttribute(delegate, "Type", String.class); - this.type = typeName != null ? MemoryType.valueOf(typeName) : MemoryType.NON_HEAP; - String[] names = safeReadAttribute(delegate, "MemoryManagerNames", String[].class); - this.memoryManagerNames = names != null ? names : new String[]{"unknown"}; - this.name = String.format("Aggregated %s", delegate.getMBeanInfo().getDescription()); - this.delegates.put(delegateObjectName, delegate); - } - - void addDelegate(DynamicMBean delegate, ObjectName delegateObjectName) { - delegates.put(delegateObjectName, delegate); - } - - void removeDelegate(ObjectName delegate) { - delegates.remove(delegate); - } - - @Override - public ObjectName getObjectName() { - return objectName; - } - - @Override - public String getName() { - return name; - } - - @Override - public MemoryType getType() { - return type; - } - - @Override - public boolean isValid() { - return true; - } - - @Override - public MemoryUsage getUsage() { - return collect("Usage"); - } - - @Override - public MemoryUsage getPeakUsage() { - return collect("PeakUsage"); - } - - private MemoryUsage collect(String attributeName) { - long init = 0L; - long used = 0L; - long committed = 0L; - long max = 0L; - synchronized (delegates) { - for (DynamicMBean delegate : delegates.values()) { - CompositeData compositeData = safeReadAttribute(delegate, attributeName, CompositeData.class); - if (compositeData != null) { - MemoryUsage isolateMemoryUsage = MemoryUsage.from(compositeData); - init += isolateMemoryUsage.getInit(); - used += isolateMemoryUsage.getUsed(); - committed += isolateMemoryUsage.getCommitted(); - max += isolateMemoryUsage.getMax(); - } - } - } - return new MemoryUsage(init, used, committed, max); - } - - static <T> T safeReadAttribute(DynamicMBean mbean, String name, Class<T> attrType) { - try { - return attrType.cast(mbean.getAttribute(name)); - } catch (AttributeNotFoundException | MBeanException | ReflectionException e) { - return null; - } - } - - @Override - public String[] getMemoryManagerNames() { - return Arrays.copyOf(memoryManagerNames, memoryManagerNames.length); - } - - @Override - public void resetPeakUsage() { - } - - @Override - public MemoryUsage getCollectionUsage() { - return null; - } - - @Override - public boolean isUsageThresholdSupported() { - return false; - } - - @Override - public boolean isUsageThresholdExceeded() { - throw new UnsupportedOperationException("UsageThreshold is not supported."); - } - - @Override - public long getUsageThresholdCount() { - throw new UnsupportedOperationException("UsageThreshold is not supported."); - } - - @Override - public long getUsageThreshold() { - throw new UnsupportedOperationException("UsageThreshold is not supported."); - } - - @Override - public void setUsageThreshold(long threshold) { - throw new UnsupportedOperationException("UsageThreshold is not supported."); - } - - @Override - public boolean isCollectionUsageThresholdSupported() { - return false; - } - - @Override - public boolean isCollectionUsageThresholdExceeded() { - throw new UnsupportedOperationException("CollectionUsageThreshold is not supported."); - } - - @Override - public long getCollectionUsageThresholdCount() { - throw new UnsupportedOperationException("CollectionUsageThreshold is not supported."); - } - - @Override - public long getCollectionUsageThreshold() { - throw new UnsupportedOperationException("CollectionUsageThreshold is not supported."); - } - - @Override - public void setCollectionUsageThreshold(long threshold) { - throw new UnsupportedOperationException("CollectionUsageThreshold is not supported."); - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/Factory.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/Factory.java deleted file mode 100644 index e9ccd1da0bb0..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/Factory.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2020, 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 org.graalvm.compiler.hotspot.management; - -import java.lang.management.ManagementFactory; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.management.DynamicMBean; -import javax.management.InstanceAlreadyExistsException; -import javax.management.InstanceNotFoundException; -import javax.management.MBeanRegistrationException; -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.MalformedObjectNameException; -import javax.management.NotCompliantMBeanException; -import javax.management.ObjectName; -import org.graalvm.compiler.debug.TTY; -import org.graalvm.libgraal.LibGraal; -import org.graalvm.libgraal.LibGraalScope; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; - -/** - * A factory thread creating the {@link LibGraalMBean} instances for {@link DynamicMBean}s in - * libgraal heap and registering them to {@link MBeanServer}. - */ -@Platforms(value = Platform.HOSTED_ONLY.class) -public final class Factory extends Thread { - - private static final String DOMAIN_GRAALVM_HOTSPOT = "org.graalvm.compiler.hotspot"; - private static final String TYPE_LIBGRAAL = "Libgraal"; - private static final String ATTR_TYPE = "type"; - private static final int POLL_INTERVAL_MS = 2000; - private static volatile Factory instance; - private MBeanServer platformMBeanServer; - private AggregatedMemoryPoolBean aggregatedMemoryPoolBean; - private Map<Long, ObjectName[]> mbeansForActiveIsolate; - - /** - * Set of isolates yet to be processed for MBean registrations. - */ - private final Set<Long> pendingIsolates; - - @SuppressWarnings("try") - private Factory() { - super("Libgraal MBean Registration"); - this.pendingIsolates = new LinkedHashSet<>(); - this.setPriority(Thread.MIN_PRIORITY); - this.setDaemon(true); - // The Factory class is a singleton, it's guaranteed that native method registration is - // performed at most once. The Factory instance is never created by the isolate shutdown - // hook as the unregister method is called by the isolate only if the Factory was already - // created by the registration thread. - try (LibGraalScope scope = new LibGraalScope(LibGraalScope.DetachAction.DETACH_RUNTIME_AND_RELEASE)) { - LibGraal.registerNativeMethods(JMXToLibGraalCalls.class); - } - } - - /** - * Main loop waiting for {@link DynamicMBean} creation in libgraal heap. When a new - * {@link DynamicMBean} is created in the libgraal heap this thread creates a new - * {@link LibGraalMBean} encapsulating the {@link DynamicMBean} and registers it to - * {@link MBeanServer}. - */ - @Override - public void run() { - while (true) { - try { - synchronized (this) { - // Wait until there are deferred registrations to process - while (pendingIsolates.isEmpty()) { - wait(); - } - try { - poll(); - } catch (SecurityException | UnsatisfiedLinkError | NoClassDefFoundError | UnsupportedOperationException e) { - // Without permission to find or create the MBeanServer, - // we cannot process any Graal mbeans. - // Various other errors can occur in the ManagementFactory (JDK-8076557) - break; - } - } - Thread.sleep(POLL_INTERVAL_MS); - } catch (InterruptedException e) { - // Be verbose about unexpected interruption and then continue - e.printStackTrace(TTY.out); - } - } - } - - /** - * Called by {@code MBeanProxy} in libgraal heap to notify this factory of an isolate with - * {@link DynamicMBean}s that needs registration. - */ - synchronized void signalRegistrationRequest(long isolate) { - pendingIsolates.add(isolate); - notify(); - } - - /** - * Called by {@code MBeanProxy} in libgraal heap when the isolate is closing to unregister its - * {@link DynamicMBean}s. - */ - synchronized void unregister(long isolate) { - // Remove pending registration requests - if (pendingIsolates.remove(isolate)) { - // The libgraal compiler notifies the Factory about a new runtime by calling the - // #signalRegistrationRequest(long) method. - // The #signalRegistrationRequest(long) method only puts the isolate into the - // #pendingIsolatesand set and notifies the working thread. - // The working thread processes the pending isolates asynchronously in the #run() and - // removes them from the #pendingIsolates set. - // When the #pendingIsolates contains the isolate the isolate was not yet processed and - // there are no registered MBeans to remove from MBeanServer. - return; - } - MBeanServer mBeanServer = findMBeanServer(); - if (mBeanServer == null) { - // Nothing registered yet. - return; - } - // The mbeansForActiveIsolate can be null when Factory#process() failed with an exception. - ObjectName[] objectNames = mbeansForActiveIsolate == null ? null : mbeansForActiveIsolate.remove(isolate); - if (objectNames != null) { - for (ObjectName objectName : objectNames) { - try { - if (aggregatedMemoryPoolBean != null && isLibGraalMBean(objectName)) { - aggregatedMemoryPoolBean.removeDelegate(objectName); - } - if (mBeanServer.isRegistered(objectName)) { - mBeanServer.unregisterMBean(objectName); - } - } catch (MBeanRegistrationException | InstanceNotFoundException e) { - e.printStackTrace(TTY.out); - } - } - } - } - - /** - * In case of successful {@link MBeanServer} initialization creates {@link LibGraalMBean}s for - * pending libgraal {@link DynamicMBean}s and registers them. - * - * @return {@code true} if {@link LibGraalMBean}s were successfuly registered, {@code false} - * when {@link MBeanServer} is not yet available and {@code poll} should be retried. - * @throws SecurityException can be thrown by {@link MBeanServer} - * @throws UnsatisfiedLinkError can be thrown by {@link MBeanServer} - * @throws NoClassDefFoundError can be thrown by {@link MBeanServer} - * @throws UnsupportedOperationException can be thrown by {@link MBeanServer} - */ - private boolean poll() { - MBeanServer mBeanServer = findMBeanServer(); - if (mBeanServer != null) { - return process(); - } else { - return false; - } - } - - /** - * Returns a {@link MBeanServer} if it already exists. - */ - private MBeanServer findMBeanServer() { - assert Thread.holdsLock(this); - if (platformMBeanServer == null) { - ArrayList<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null); - if (!servers.isEmpty()) { - platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); - } - } - return platformMBeanServer; - } - - /** - * Creates {@link LibGraalMBean}s for pending libgraal {@link DynamicMBean}s and registers them - * {@link MBeanServer}. - * - * @return {@code true} - * @throws SecurityException can be thrown by {@link MBeanServer} - * @throws UnsatisfiedLinkError can be thrown by {@link MBeanServer} - * @throws NoClassDefFoundError can be thrown by {@link MBeanServer} - * @throws UnsupportedOperationException can be thrown by {@link MBeanServer} - */ - private boolean process() { - for (Iterator<Long> iter = pendingIsolates.iterator(); iter.hasNext();) { - long isolate = iter.next(); - iter.remove(); - try (LibGraalScope scope = new LibGraalScope(isolate)) { - long isolateThread = scope.getIsolateThreadAddress(); - long[] handles = JMXToLibGraalCalls.pollRegistrations(isolateThread); - if (handles.length > 0) { - List<ObjectName> objectNames = new ArrayList<>(handles.length); - try { - for (long handle : handles) { - LibGraalMBean bean = new LibGraalMBean(isolate, handle); - String name = JMXToLibGraalCalls.getObjectName(isolateThread, handle); - try { - ObjectName objectName = new ObjectName(name); - objectNames.add(objectName); - if (isLibGraalMBean(objectName)) { - if (aggregatedMemoryPoolBean == null) { - aggregatedMemoryPoolBean = new AggregatedMemoryPoolBean(bean, objectName); - platformMBeanServer.registerMBean(aggregatedMemoryPoolBean, aggregatedMemoryPoolBean.getObjectName()); - } else { - aggregatedMemoryPoolBean.addDelegate(bean, objectName); - } - } - platformMBeanServer.registerMBean(bean, objectName); - } catch (MalformedObjectNameException | InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) { - e.printStackTrace(TTY.out); - } - } - } finally { - if (mbeansForActiveIsolate == null) { - mbeansForActiveIsolate = new HashMap<>(); - } - mbeansForActiveIsolate.put(isolate, objectNames.toArray(new ObjectName[objectNames.size()])); - } - } - } - } - return true; - } - - /** - * Tests if the given object name represents a libgraal MBean. - */ - private static boolean isLibGraalMBean(ObjectName objectName) { - Hashtable<String, String> props = objectName.getKeyPropertyList(); - return DOMAIN_GRAALVM_HOTSPOT.equals(objectName.getDomain()) && TYPE_LIBGRAAL.equals(props.get(ATTR_TYPE)); - } - - /** - * Returns a factory for registering the {@link LibGraalMBean} instances into - * {@link MBeanServer}. If the factory does not exist it is created and its registration thread - * is started. - */ - static Factory getInstance() { - Factory res = instance; - if (res == null) { - synchronized (LibGraalMBean.class) { - res = instance; - if (res == null) { - try { - res = new Factory(); - res.start(); - instance = res; - } catch (LinkageError e) { - Throwable cause = findCause(e); - throw throwUnchecked(RuntimeException.class, cause); - } - } - } - } - return res; - } - - private static Throwable findCause(Throwable e) { - Throwable current = e; - while (current.getCause() != null) { - current = current.getCause(); - } - return current; - } - - @SuppressWarnings({"unchecked", "unused"}) - private static <T extends Throwable> T throwUnchecked(Class<T> exceptionClass, Throwable exception) throws T { - throw (T) exception; - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/JMXFromLibGraalEntryPoints.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/JMXFromLibGraalEntryPoints.java deleted file mode 100644 index 3e58f956edc3..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/JMXFromLibGraalEntryPoints.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2019, 2020, 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 org.graalvm.compiler.hotspot.management; - -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal.Id.GetFactory; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal.Id.SignalRegistrationRequest; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal.Id.Unregister; - -import org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; - -/** - * Entry points in HotSpot for calls from libgraal. - */ -@Platforms(Platform.HOSTED_ONLY.class) -public final class JMXFromLibGraalEntryPoints { - - private JMXFromLibGraalEntryPoints() { - } - - /** - * @see Factory#getInstance() - */ - @JMXFromLibGraal(GetFactory) - static Object getFactory() { - Factory factory = Factory.getInstance(); - return factory; - } - - /** - * @see Factory#signalRegistrationRequest(long) - */ - @JMXFromLibGraal(SignalRegistrationRequest) - static void signalRegistrationRequest(Object factory, long isolate) { - ((Factory) factory).signalRegistrationRequest(isolate); - } - - /** - * @see Factory#unregister(long) - */ - @JMXFromLibGraal(Unregister) - static void unregister(Object factory, long isolate) { - ((Factory) factory).unregister(isolate); - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/JMXToLibGraalCalls.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/JMXToLibGraalCalls.java deleted file mode 100644 index 78a31ff89299..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/JMXToLibGraalCalls.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2019, 2020, 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 org.graalvm.compiler.hotspot.management; - -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.FinishRegistration; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.GetAttributes; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.GetMBeanInfo; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.GetObjectName; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.Invoke; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.PollRegistrations; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.SetAttributes; - -import org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; - -/** - * Native methods linked to libgraal entry points. - */ -@Platforms(Platform.HOSTED_ONLY.class) -public final class JMXToLibGraalCalls { - - private JMXToLibGraalCalls() { - } - - @JMXToLibGraal(PollRegistrations) - static native long[] pollRegistrations(long isolateThreadId); - - @JMXToLibGraal(FinishRegistration) - static native void finishRegistration(long isolateThreadId, long[] handles); - - @JMXToLibGraal(GetObjectName) - static native String getObjectName(long isolateThreadId, long handle); - - @JMXToLibGraal(GetMBeanInfo) - static native byte[] getMBeanInfo(long isolateThreadId, long handle); - - @JMXToLibGraal(GetAttributes) - static native byte[] getAttributes(long isolateThreadId, long handle, String[] attributes); - - @JMXToLibGraal(SetAttributes) - static native byte[] setAttributes(long isolateThreadId, long handle, byte[] rawData); - - @JMXToLibGraal(Invoke) - static native byte[] invoke(long isolateThreadId, long handle, String actionName, byte[] rawData, String[] signature); -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/LibGraalMBean.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/LibGraalMBean.java deleted file mode 100644 index bba81b7ee20e..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/LibGraalMBean.java +++ /dev/null @@ -1,541 +0,0 @@ -/* - * Copyright (c) 2019, 2020, 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 org.graalvm.compiler.hotspot.management; - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.AttributeNotFoundException; -import javax.management.DynamicMBean; -import javax.management.InvalidAttributeValueException; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanException; -import javax.management.MBeanInfo; -import javax.management.MBeanOperationInfo; -import javax.management.MBeanParameterInfo; -import javax.management.ReflectionException; -import javax.management.openmbean.ArrayType; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.CompositeType; -import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; - -import org.graalvm.compiler.debug.TTY; -import org.graalvm.libgraal.LibGraalScope; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; -import org.graalvm.util.OptionsEncoder; - -/** - * Encapsulates a handle to a {@link DynamicMBean} object in the libgraal heap. Implements the - * {@link DynamicMBean} by delegating all operations to an object in the libgraal heap. - */ -@Platforms(Platform.HOSTED_ONLY.class) -public class LibGraalMBean implements DynamicMBean { - - private static final String COMPOSITE_TAG = ".composite"; - private static final String ARRAY_TAG = ".array"; - private static final Map<Class<?>, OpenType<?>> PRIMITIVE_TO_OPENTYPE; - static { - PRIMITIVE_TO_OPENTYPE = new HashMap<>(); - PRIMITIVE_TO_OPENTYPE.put(Void.class, SimpleType.VOID); - PRIMITIVE_TO_OPENTYPE.put(Boolean.class, SimpleType.BOOLEAN); - PRIMITIVE_TO_OPENTYPE.put(Byte.class, SimpleType.BYTE); - PRIMITIVE_TO_OPENTYPE.put(Character.class, SimpleType.CHARACTER); - PRIMITIVE_TO_OPENTYPE.put(Short.class, SimpleType.SHORT); - PRIMITIVE_TO_OPENTYPE.put(Integer.class, SimpleType.INTEGER); - PRIMITIVE_TO_OPENTYPE.put(Float.class, SimpleType.FLOAT); - PRIMITIVE_TO_OPENTYPE.put(Long.class, SimpleType.LONG); - PRIMITIVE_TO_OPENTYPE.put(Double.class, SimpleType.DOUBLE); - PRIMITIVE_TO_OPENTYPE.put(String.class, SimpleType.STRING); - } - - private final long isolate; - private final long handle; - - LibGraalMBean(long isolate, long handle) { - this.isolate = isolate; - this.handle = handle; - } - - /** - * Obtain the value of a specific attribute of the Dynamic MBean by delegating to - * {@link DynamicMBean} instance in the libgraal heap. - * - * @param attribute the name of the attribute to be retrieved - */ - @Override - public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { - AttributeList attributes = getAttributes(new String[]{attribute}); - return attributes.isEmpty() ? null : ((Attribute) attributes.get(0)).getValue(); - } - - /** - * Set the value of a specific attribute of the Dynamic MBean by delegating to - * {@link DynamicMBean} instance in the libgraal heap. - * - * @param attribute the identification of the attribute to be set and the value it is to be set - * to - */ - @Override - public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { - AttributeList list = new AttributeList(); - list.add(attribute); - setAttributes(list); - } - - /** - * Get the values of several attributes of the Dynamic MBean by delegating to - * {@link DynamicMBean} instance in the libgraal heap. - * - * @param attributes a list of the attributes to be retrieved - */ - @Override - public AttributeList getAttributes(String[] attributes) { - try (LibGraalScope scope = new LibGraalScope(isolate)) { - byte[] rawData = JMXToLibGraalCalls.getAttributes(scope.getIsolateThreadAddress(), handle, attributes); - return rawToAttributeList(rawData); - } - } - - /** - * Sets the values of several attributes of the Dynamic MBean by delegating to - * {@link DynamicMBean} instance in the libgraal heap. - * - * @param attributes a list of attributes: The identification of the attributes to be set and - * the values they are to be set to. - */ - @Override - public AttributeList setAttributes(AttributeList attributes) { - try (LibGraalScope scope = new LibGraalScope(isolate)) { - Map<String, Object> map = new LinkedHashMap<>(); - for (Object item : attributes) { - Attribute attribute = (Attribute) item; - map.put(attribute.getName(), attribute.getValue()); - } - byte[] rawData = OptionsEncoder.encode(map); - rawData = JMXToLibGraalCalls.setAttributes(scope.getIsolateThreadAddress(), handle, rawData); - return rawToAttributeList(rawData); - } - } - - /** - * Decodes an {@link AttributeList} encoded to {@code byte} array using {@link OptionsEncoder}. - * - * @param rawData the encoded attribute list. - */ - private static AttributeList rawToAttributeList(byte[] rawData) { - AttributeList res = new AttributeList(); - Map<String, Object> map = OptionsEncoder.decode(rawData); - for (PushBackIterator<Map.Entry<String, Object>> it = new PushBackIterator<>(map.entrySet().iterator()); it.hasNext();) { - Map.Entry<String, Object> e = it.next(); - String attrName = e.getKey(); - Object attrValue = e.getValue(); - try { - if (isComposite(attrName)) { - attrValue = readComposite(attrName, (String) attrValue, it); - attrName = attrName(attrName, COMPOSITE_TAG); - } else if (isArray(attrName)) { - attrValue = readArray(attrName, (String) attrValue, it); - attrName = attrName(attrName, ARRAY_TAG); - } - } catch (OpenDataException ex) { - attrValue = null; - TTY.printf("WARNING: Cannot read attribute %s due to %s", attrName, ex.getMessage()); - } - res.add(new Attribute(attrName, attrValue)); - } - return res; - } - - /** - * Check if the serialized attribute is a {@link CompositeData}. - */ - private static boolean isComposite(String name) { - return name.endsWith(COMPOSITE_TAG); - } - - /** - * Removes the tag from attribute name. - */ - private static String attrName(String name, String tag) { - return name.substring(0, name.length() - tag.length()); - } - - /** - * Check if the serialized attribute is an array. - */ - private static boolean isArray(String name) { - return name.endsWith(ARRAY_TAG); - } - - /** - * Deserializes the {@link CompositeData}. - */ - private static CompositeData readComposite(String scope, String typeName, PushBackIterator<Map.Entry<String, Object>> it) throws OpenDataException { - String prefix = scope + '.'; - List<String> attrNames = new ArrayList<>(); - List<Object> attrValues = new ArrayList<>(); - List<OpenType<?>> attrTypes = new ArrayList<>(); - while (it.hasNext()) { - Map.Entry<String, Object> e = it.next(); - String attrName = e.getKey(); - if (!attrName.startsWith(prefix)) { - it.pushBack(e); - break; - } - Object attrValue = e.getValue(); - if (isComposite(attrName)) { - attrValue = readComposite(attrName, (String) attrValue, it); - attrName = attrName(attrName, COMPOSITE_TAG); - } else if (isArray(attrName)) { - attrValue = readArray(attrName, (String) attrValue, it); - attrName = attrName(attrName, ARRAY_TAG); - } - attrName = attrName.substring(prefix.length()); - attrNames.add(attrName); - attrValues.add(attrValue); - attrTypes.add(getOpenType(attrValue)); - } - String[] attrNamesArray = attrNames.toArray(new String[attrNames.size()]); - CompositeType type = new CompositeType(typeName, typeName, attrNamesArray, attrNamesArray, attrTypes.toArray(new OpenType<?>[attrTypes.size()])); - return new CompositeDataSupport(type, attrNamesArray, attrValues.toArray(new Object[attrValues.size()])); - } - - private static Object[] readArray(String scope, String typeName, PushBackIterator<Map.Entry<String, Object>> it) throws OpenDataException { - String prefix = scope + '.'; - List<Object> elements = new ArrayList<>(); - while (it.hasNext()) { - Map.Entry<String, Object> e = it.next(); - String attrName = e.getKey(); - if (!attrName.startsWith(prefix)) { - it.pushBack(e); - break; - } - Object attrValue = e.getValue(); - elements.add(attrValue); - } - Class<?> componentType = null; - for (Map.Entry<Class<?>, OpenType<?>> e : PRIMITIVE_TO_OPENTYPE.entrySet()) { - if (e.getValue().getTypeName().equals(typeName)) { - componentType = e.getKey(); - break; - } - } - if (componentType == null) { - throw new OpenDataException("Only arrays of simple open types are suppored."); - } - return elements.toArray((Object[]) Array.newInstance(componentType, elements.size())); - } - - /** - * Returns an {@link OpenType} representing given value. - */ - private static OpenType<?> getOpenType(Object value) throws OpenDataException { - if (value instanceof CompositeData) { - return ((CompositeData) value).getCompositeType(); - } - if (value != null && value.getClass().isArray()) { - return ArrayType.getArrayType(PRIMITIVE_TO_OPENTYPE.get(value.getClass().getComponentType())); - } - Class<?> clz = value == null ? String.class : value.getClass(); - OpenType<?> openType = PRIMITIVE_TO_OPENTYPE.get(clz); - if (openType == null) { - throw new IllegalArgumentException(clz.getName()); - } - return openType; - } - - /** - * Invokes an action on the Dynamic MBean by delegating to {@link DynamicMBean} instance in the - * libgraal heap. - * - * @param actionName the name of the action to be invoked - * @param params an array containing the parameters to be set when the action is invoked - * @param signature an array containing the signature of the action. The class objects will be - * loaded through the same class loader as the one used for loading the MBean on - * which the action is invoked - * - * @return The object returned by the action, which represents the result of invoking the action - * on the MBean specified. - * - */ - @Override - public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException { - try (LibGraalScope scope = new LibGraalScope(isolate)) { - Map<String, Object> paramsMap = new LinkedHashMap<>(); - if (params != null) { - for (int i = 0; i < params.length; i++) { - paramsMap.put(Integer.toString(i), params[i]); - } - } - byte[] rawData = OptionsEncoder.encode(paramsMap); - rawData = JMXToLibGraalCalls.invoke(scope.getIsolateThreadAddress(), handle, actionName, rawData, signature); - if (rawData == null) { - throw new MBeanException(null); - } - AttributeList attributesList = rawToAttributeList(rawData); - return attributesList.isEmpty() ? null : ((Attribute) attributesList.get(0)).getValue(); - } - } - - /** - * Provides the attributes and actions of the Dynamic MBean by delegating to - * {@link DynamicMBean} instance in the libgraal heap. - * - */ - @Override - public MBeanInfo getMBeanInfo() { - try (LibGraalScope scope = new LibGraalScope(isolate)) { - byte[] rawData = JMXToLibGraalCalls.getMBeanInfo(scope.getIsolateThreadAddress(), handle); - Map<String, Object> map = OptionsEncoder.decode(rawData); - String className = null; - String description = null; - List<MBeanAttributeInfo> attributes = new ArrayList<>(); - List<MBeanOperationInfo> operations = new ArrayList<>(); - for (PushBackIterator<Map.Entry<String, Object>> it = new PushBackIterator<>(map.entrySet().iterator()); it.hasNext();) { - Map.Entry<String, ?> entry = it.next(); - String key = entry.getKey(); - if (key.equals("bean.class")) { - className = (String) entry.getValue(); - } else if (key.equals("bean.description")) { - description = (String) entry.getValue(); - } else if (key.startsWith("attr.")) { - String attrName = (String) entry.getValue(); - if (!key.equals("attr." + attrName + ".name")) { - throw new IllegalStateException("Invalid order of attribute properties"); - } - MBeanAttributeInfo attr = createAttributeInfo(attrName, it); - attributes.add(attr); - } else if (key.startsWith("op.")) { - int opId = (Integer) entry.getValue(); - if (!key.equals("op." + opId + ".id")) { - throw new IllegalStateException("Invalid order of operation properties"); - } - MBeanOperationInfo op = createOperationInfo(opId, it); - operations.add(op); - } - } - Objects.requireNonNull(className, "ClassName must be non null."); - Objects.requireNonNull(description, "Description must be non null."); - return new MBeanInfo(className, description, - attributes.toArray(new MBeanAttributeInfo[attributes.size()]), null, - operations.toArray(new MBeanOperationInfo[operations.size()]), null); - } - } - - /** - * Parses {@link MBeanAttributeInfo} from iterator of MBean properties. - * - * @param attrName the current attribute name - * @param it the attribute properties {@link Iterator} - * @return the parsed {@link MBeanAttributeInfo} - */ - private static MBeanAttributeInfo createAttributeInfo(String attrName, PushBackIterator<Map.Entry<String, Object>> it) { - String attrType = null; - String attrDescription = null; - boolean isReadable = false; - boolean isWritable = false; - boolean isIs = false; - String prefix = "attr." + attrName + "."; - while (it.hasNext()) { - Map.Entry<String, Object> entry = it.next(); - String key = entry.getKey(); - if (!key.startsWith(prefix)) { - it.pushBack(entry); - break; - } - String propertyName = key.substring(key.lastIndexOf('.') + 1); - switch (propertyName) { - case "type": - attrType = (String) entry.getValue(); - break; - case "description": - attrDescription = (String) entry.getValue(); - break; - case "r": - isReadable = (Boolean) entry.getValue(); - break; - case "w": - isWritable = (Boolean) entry.getValue(); - break; - case "i": - isIs = (Boolean) entry.getValue(); - break; - default: - throw new IllegalStateException("Unkown attribute property: " + propertyName); - } - } - if (attrType == null) { - throw new IllegalStateException("Attribute type must be given."); - } - return new MBeanAttributeInfo(attrName, attrType, attrDescription, isReadable, isWritable, isIs); - } - - /** - * Parses {@link MBeanOperationInfo} from iterator of MBean properties. - * - * @param opId unique id of an operation. Each operation has an unique id as operation name is - * not an unique identifier due to overloads. - * @param it the attribute properties {@link Iterator} - * @return the parsed {@link MBeanOperationInfo} - */ - private static MBeanOperationInfo createOperationInfo(int opId, PushBackIterator<Map.Entry<String, Object>> it) { - String opName = null; - String opType = null; - String opDescription = null; - int opImpact = 0; - List<MBeanParameterInfo> params = new ArrayList<>(); - String prefix = "op." + opId + "."; - while (it.hasNext()) { - Map.Entry<String, Object> entry = it.next(); - String key = entry.getKey(); - if (!key.startsWith(prefix)) { - it.pushBack(entry); - break; - } - int nextDotIndex = key.indexOf('.', prefix.length()); - nextDotIndex = nextDotIndex < 0 ? key.length() : nextDotIndex; - String propertyName = key.substring(prefix.length(), nextDotIndex); - switch (propertyName) { - case "name": - opName = (String) entry.getValue(); - break; - case "type": - opType = (String) entry.getValue(); - break; - case "description": - opDescription = (String) entry.getValue(); - break; - case "i": - opImpact = (Integer) entry.getValue(); - break; - case "arg": - String paramName = (String) entry.getValue(); - if (!key.equals(prefix + "arg." + paramName + ".name")) { - throw new IllegalStateException("Invalid order of parameter properties"); - } - MBeanParameterInfo param = createParameterInfo(prefix, paramName, it); - params.add(param); - break; - default: - throw new IllegalStateException("Unkown attribute property: " + propertyName); - } - } - if (opName == null) { - throw new IllegalStateException("Operation name must be given."); - } - if (opType == null) { - throw new IllegalStateException("Operation return type must be given."); - } - return new MBeanOperationInfo(opName, opDescription, - params.toArray(new MBeanParameterInfo[params.size()]), - opType, opImpact); - } - - /** - * Parses {@link MBeanAttributeInfo} from iterator of MBean properties. - * - * @param owner the operation attribute scope - * @param paramName the name of the parameter - * @param it the attribute properties {@link Iterator} - * @return the parsed {@link MBeanParameterInfo} - */ - private static MBeanParameterInfo createParameterInfo(String owner, String paramName, PushBackIterator<Map.Entry<String, Object>> it) { - String paramType = null; - String paramDescription = null; - String prefix = owner + "arg." + paramName + "."; - while (it.hasNext()) { - Map.Entry<String, Object> entry = it.next(); - String key = entry.getKey(); - if (!key.startsWith(prefix)) { - it.pushBack(entry); - break; - } - String propertyName = key.substring(key.lastIndexOf('.') + 1); - switch (propertyName) { - case "type": - paramType = (String) entry.getValue(); - break; - case "description": - paramDescription = (String) entry.getValue(); - break; - default: - throw new IllegalStateException("Unkown parameter property: " + propertyName); - } - } - if (paramType == null) { - throw new IllegalStateException("Parameter type must be given."); - } - return new MBeanParameterInfo(paramName, paramType, paramDescription); - } - - /** - * An iterator allowing pushing back a single look ahead item. - */ - @Platforms(Platform.HOSTED_ONLY.class) - public static final class PushBackIterator<T> implements Iterator<T> { - - private final Iterator<T> delegate; - private T pushBack; - - PushBackIterator(Iterator<T> delegate) { - this.delegate = delegate; - } - - @Override - public boolean hasNext() { - return pushBack != null || delegate.hasNext(); - } - - @Override - public T next() { - if (pushBack != null) { - T res = pushBack; - pushBack = null; - return res; - } else { - return delegate.next(); - } - } - - void pushBack(T e) { - if (pushBack != null) { - throw new IllegalStateException("Push back element already exists."); - } - pushBack = e; - } - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/JMXToLibGraalEntryPoints.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/JMXToLibGraalEntryPoints.java deleted file mode 100644 index 4cd96afe4efb..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/JMXToLibGraalEntryPoints.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (c) 2019, 2022, 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 org.graalvm.compiler.hotspot.management.libgraal; - -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.FinishRegistration; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.GetAttributes; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.GetMBeanInfo; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.GetObjectName; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.Invoke; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.PollRegistrations; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal.Id.SetAttributes; - -import java.lang.reflect.Array; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.DynamicMBean; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanException; -import javax.management.MBeanInfo; -import javax.management.MBeanOperationInfo; -import javax.management.MBeanParameterInfo; -import javax.management.ReflectionException; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeType; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; -import org.graalvm.compiler.hotspot.management.JMXToLibGraalCalls; -import org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXToLibGraal; -import org.graalvm.jniutils.JNIMethodScope; -import org.graalvm.libgraal.jni.LibGraalUtil; -import org.graalvm.jniutils.JNI; -import org.graalvm.jniutils.JNIUtil; -import org.graalvm.nativeimage.ObjectHandles; -import org.graalvm.nativeimage.c.function.CEntryPoint; -import org.graalvm.nativeimage.c.type.CCharPointer; -import org.graalvm.nativeimage.c.type.CLongPointer; -import org.graalvm.nativeimage.c.type.CTypeConversion; -import org.graalvm.util.OptionsEncoder; -import org.graalvm.word.WordFactory; - -/** - * Entry points in libgraal for calls from HotSpot. - */ -final class JMXToLibGraalEntryPoints { - - private static final Map<Class<?>, OpenType<?>> PRIMITIVE_TO_OPENTYPE; - static { - PRIMITIVE_TO_OPENTYPE = new HashMap<>(); - PRIMITIVE_TO_OPENTYPE.put(Void.class, SimpleType.VOID); - PRIMITIVE_TO_OPENTYPE.put(Boolean.class, SimpleType.BOOLEAN); - PRIMITIVE_TO_OPENTYPE.put(Byte.class, SimpleType.BYTE); - PRIMITIVE_TO_OPENTYPE.put(Character.class, SimpleType.CHARACTER); - PRIMITIVE_TO_OPENTYPE.put(Short.class, SimpleType.SHORT); - PRIMITIVE_TO_OPENTYPE.put(Integer.class, SimpleType.INTEGER); - PRIMITIVE_TO_OPENTYPE.put(Float.class, SimpleType.FLOAT); - PRIMITIVE_TO_OPENTYPE.put(Long.class, SimpleType.LONG); - PRIMITIVE_TO_OPENTYPE.put(Double.class, SimpleType.DOUBLE); - PRIMITIVE_TO_OPENTYPE.put(String.class, SimpleType.STRING); - } - - private JMXToLibGraalEntryPoints() { - } - - /** - * Returns the pending {@link DynamicMBean} registrations. - */ - @JMXToLibGraal(PollRegistrations) - @CEntryPoint(name = "Java_org_graalvm_compiler_hotspot_management_JMXToLibGraalCalls_pollRegistrations") - @SuppressWarnings({"try", "unused"}) - static JNI.JLongArray pollRegistrations(JNI.JNIEnv env, JNI.JClass hsClazz, @CEntryPoint.IsolateThreadContext long isolateThreadId) { - JNIMethodScope scope = LibGraalUtil.openScope(JMXToLibGraalEntryPoints.class, PollRegistrations, env); - try (JNIMethodScope s = scope) { - List<MBeanProxy<?>> registrations = MBeanProxy.drainRegistrations(); - JNI.JLongArray res = JNIUtil.NewLongArray(env, registrations.size()); - CLongPointer elems = JNIUtil.GetLongArrayElements(env, res, WordFactory.nullPointer()); - try { - ObjectHandles globalHandles = ObjectHandles.getGlobal(); - for (int i = 0; i < registrations.size(); i++) { - long handle = globalHandles.create(registrations.get(i)).rawValue(); - elems.write(i, handle); - } - } finally { - JNIUtil.ReleaseLongArrayElements(env, res, elems, JNI.JArray.MODE_WRITE_RELEASE); - } - scope.setObjectResult(res); - } - return scope.getObjectResult(); - } - - /** - * Notifies the {@link MBeanProxy} about finished registration. - */ - @JMXToLibGraal(FinishRegistration) - @CEntryPoint(name = "Java_org_graalvm_compiler_hotspot_management_JMXToLibGraalCalls_finishRegistration") - @SuppressWarnings({"try", "unused"}) - static void finishRegistration(JNI.JNIEnv env, JNI.JClass hsClazz, @CEntryPoint.IsolateThreadContext long isolateThreadId, JNI.JLongArray handles) { - try (JNIMethodScope s = LibGraalUtil.openScope(JMXToLibGraalEntryPoints.class, FinishRegistration, env)) { - long len = JNIUtil.GetArrayLength(env, handles); - CLongPointer elems = JNIUtil.GetLongArrayElements(env, handles, WordFactory.nullPointer()); - try { - ObjectHandles globalHandles = ObjectHandles.getGlobal(); - for (int i = 0; i < len; i++) { - MBeanProxy<?> registration = globalHandles.get(WordFactory.pointer(elems.read(i))); - registration.finishRegistration(); - } - } finally { - JNIUtil.ReleaseLongArrayElements(env, handles, elems, JNI.JArray.MODE_RELEASE); - } - } - } - - /** - * Returns the name to use to register the MBean. - */ - @JMXToLibGraal(GetObjectName) - @CEntryPoint(name = "Java_org_graalvm_compiler_hotspot_management_JMXToLibGraalCalls_getObjectName") - @SuppressWarnings({"try", "unused"}) - static JNI.JString getObjectName(JNI.JNIEnv env, JNI.JClass hsClazz, @CEntryPoint.IsolateThreadContext long isolateThreadId, long handle) { - JNIMethodScope scope = LibGraalUtil.openScope(JMXToLibGraalEntryPoints.class, GetObjectName, env); - try (JNIMethodScope s = scope) { - ObjectHandles globalHandles = ObjectHandles.getGlobal(); - MBeanProxy<?> registration = globalHandles.get(WordFactory.pointer(handle)); - String name = registration.getName(); - scope.setObjectResult(JNIUtil.createHSString(env, name)); - } - return scope.getObjectResult(); - } - - /** - * Returns the {@link MBeanInfo} encoded as a byte array using {@link OptionsEncoder}. - */ - @JMXToLibGraal(GetMBeanInfo) - @CEntryPoint(name = "Java_org_graalvm_compiler_hotspot_management_JMXToLibGraalCalls_getMBeanInfo") - @SuppressWarnings({"try", "unused"}) - static JNI.JByteArray getMBeanInfo(JNI.JNIEnv env, JNI.JClass hsClazz, @CEntryPoint.IsolateThreadContext long isolateThreadId, long handle) { - JNIMethodScope scope = LibGraalUtil.openScope(JMXToLibGraalEntryPoints.class, GetMBeanInfo, env); - try (JNIMethodScope s = scope) { - ObjectHandles globalHandles = ObjectHandles.getGlobal(); - MBeanProxy<?> registration = globalHandles.get(WordFactory.pointer(handle)); - MBeanInfo info = registration.getBean().getMBeanInfo(); - Map<String, Object> map = new LinkedHashMap<>(); - map.put("bean.class", info.getClassName()); - map.put("bean.description", info.getDescription()); - for (MBeanAttributeInfo attr : info.getAttributes()) { - putAttributeInfo(map, attr); - } - int opCounter = 0; - for (MBeanOperationInfo op : info.getOperations()) { - putOperationInfo(map, op, ++opCounter); - } - scope.setObjectResult(mapToRaw(env, map)); - } - return scope.getObjectResult(); - } - - /** - * Serialization of a {@link MBeanAttributeInfo} into map. - */ - private static void putAttributeInfo(Map<String, Object> into, MBeanAttributeInfo attrInfo) { - String name = attrInfo.getName(); - into.put("attr." + name + ".name", name); - into.put("attr." + name + ".type", attrInfo.getType()); - into.put("attr." + name + ".description", attrInfo.getDescription()); - into.put("attr." + name + ".r", attrInfo.isReadable()); - into.put("attr." + name + ".w", attrInfo.isWritable()); - into.put("attr." + name + ".i", attrInfo.isIs()); - } - - /** - * Serialization of a {@link MBeanOperationInfo} into map. - */ - private static void putOperationInfo(Map<String, Object> into, MBeanOperationInfo opInfo, int opCounter) { - String name = opInfo.getName(); - into.put("op." + opCounter + ".id", opCounter); - into.put("op." + opCounter + ".name", name); - into.put("op." + opCounter + ".type", opInfo.getReturnType()); - into.put("op." + opCounter + ".description", opInfo.getDescription()); - into.put("op." + opCounter + ".i", opInfo.getImpact()); - for (MBeanParameterInfo param : opInfo.getSignature()) { - String paramName = param.getName(); - into.put("op." + opCounter + ".arg." + paramName + ".name", paramName); - into.put("op." + opCounter + ".arg." + paramName + ".description", param.getDescription()); - into.put("op." + opCounter + ".arg." + paramName + ".type", param.getType()); - } - } - - /** - * Returns the required {@link DynamicMBean}'s attribute values encoded as a byte array using - * {@link OptionsEncoder}. - */ - @JMXToLibGraal(GetAttributes) - @CEntryPoint(name = "Java_org_graalvm_compiler_hotspot_management_JMXToLibGraalCalls_getAttributes") - @SuppressWarnings({"try", "unused"}) - static JNI.JByteArray getAttributes(JNI.JNIEnv env, JNI.JClass hsClazz, @CEntryPoint.IsolateThreadContext long isolateThreadId, long handle, JNI.JObjectArray requiredAttributes) { - JNIMethodScope scope = LibGraalUtil.openScope(JMXToLibGraalEntryPoints.class, GetAttributes, env); - try (JNIMethodScope s = scope) { - int len = JNIUtil.GetArrayLength(env, requiredAttributes); - String[] attrNames = new String[len]; - for (int i = 0; i < len; i++) { - JNI.JString el = (JNI.JString) JNIUtil.GetObjectArrayElement(env, requiredAttributes, i); - attrNames[i] = JNIUtil.createString(env, el); - } - MBeanProxy<?> registration = ObjectHandles.getGlobal().get(WordFactory.pointer(handle)); - AttributeList attributesList = registration.getBean().getAttributes(attrNames); - scope.setObjectResult(attributeListToRaw(env, attributesList)); - } - return scope.getObjectResult(); - } - - /** - * Sets the given {@link DynamicMBean}'s attribute values. - */ - @JMXToLibGraal(SetAttributes) - @CEntryPoint(name = "Java_org_graalvm_compiler_hotspot_management_JMXToLibGraalCalls_setAttributes") - @SuppressWarnings({"try", "unused"}) - static JNI.JByteArray setAttributes(JNI.JNIEnv env, JNI.JClass hsClazz, @CEntryPoint.IsolateThreadContext long isolateThreadId, long handle, JNI.JByteArray attributes) { - JNIMethodScope scope = LibGraalUtil.openScope(JMXToLibGraalEntryPoints.class, SetAttributes, env); - try (JNIMethodScope s = scope) { - Map<String, Object> map = rawToMap(env, attributes); - AttributeList attributesList = new AttributeList(); - for (Map.Entry<String, Object> entry : map.entrySet()) { - attributesList.add(new Attribute(entry.getKey(), entry.getValue())); - } - MBeanProxy<?> registration = ObjectHandles.getGlobal().get(WordFactory.pointer(handle)); - attributesList = registration.getBean().setAttributes(attributesList); - scope.setObjectResult(attributeListToRaw(env, attributesList)); - } - return scope.getObjectResult(); - } - - /** - * Invokes an action on {@link DynamicMBean}. - */ - @JMXToLibGraal(Invoke) - @CEntryPoint(name = "Java_org_graalvm_compiler_hotspot_management_JMXToLibGraalCalls_invoke") - @SuppressWarnings({"try", "unused"}) - static JNI.JByteArray invoke(JNI.JNIEnv env, JNI.JClass hsClazz, @CEntryPoint.IsolateThreadContext long isolateThreadId, long handle, JNI.JString hsActionName, - JNI.JByteArray hsParams, JNI.JObjectArray hsSignature) { - JNIMethodScope scope = LibGraalUtil.openScope(JMXToLibGraalEntryPoints.class, Invoke, env); - try (JNIMethodScope s = scope) { - String actionName = JNIUtil.createString(env, hsActionName); - int len = hsSignature.isNull() ? 0 : JNIUtil.GetArrayLength(env, hsSignature); - String[] signature = new String[len]; - for (int i = 0; i < len; i++) { - signature[i] = JNIUtil.createString(env, (JNI.JString) JNIUtil.GetObjectArrayElement(env, hsSignature, i)); - } - Map<String, Object> map = rawToMap(env, hsParams); - Object[] params = map.values().toArray(new Object[map.size()]); - MBeanProxy<?> registration = ObjectHandles.getGlobal().get(WordFactory.pointer(handle)); - try { - Object result = registration.getBean().invoke(actionName, params, signature); - AttributeList attributesList = new AttributeList(); - if (result != null) { - attributesList.add(new Attribute("result", result)); - } - scope.setObjectResult(attributeListToRaw(env, attributesList)); - } catch (MBeanException | ReflectionException e) { - scope.setObjectResult(WordFactory.nullPointer()); - } - } - return scope.getObjectResult(); - } - - /** - * Converts properties encoded as JNI byte array into {@link Map} using {@link OptionsEncoder}. - */ - private static Map<String, Object> rawToMap(JNI.JNIEnv env, JNI.JByteArray raw) { - int len = JNIUtil.GetArrayLength(env, raw); - byte[] serialized = new byte[len]; - CCharPointer elems = JNIUtil.GetByteArrayElements(env, raw, WordFactory.nullPointer()); - try { - CTypeConversion.asByteBuffer(elems, len).get(serialized); - } finally { - JNIUtil.ReleaseByteArrayElements(env, raw, elems, JNI.JArray.MODE_WRITE_RELEASE); - } - return OptionsEncoder.decode(serialized); - } - - /** - * Encodes a {@link Map} of properties into JNI byte array using {@link OptionsEncoder}. - */ - private static JNI.JByteArray mapToRaw(JNI.JNIEnv env, Map<String, Object> map) { - byte[] serialized = OptionsEncoder.encode(map); - JNI.JByteArray res = JNIUtil.NewByteArray(env, serialized.length); - CCharPointer elems = JNIUtil.GetByteArrayElements(env, res, WordFactory.nullPointer()); - try { - CTypeConversion.asByteBuffer(elems, serialized.length).put(serialized); - } finally { - JNIUtil.ReleaseByteArrayElements(env, res, elems, JNI.JArray.MODE_WRITE_RELEASE); - } - return res; - } - - /** - * Encodes an {@link AttributeList} into JNI byte array using {@link OptionsEncoder}. - */ - private static JNI.JByteArray attributeListToRaw(JNI.JNIEnv env, AttributeList attributesList) { - Map<String, Object> values = new LinkedHashMap<>(); - for (Object item : attributesList) { - Attribute attr = (Attribute) item; - putAttribute(values, attr.getName(), attr.getValue()); - } - return mapToRaw(env, values); - } - - /** - * Serialization of a single attribute into a map. - */ - private static void putAttribute(Map<String, Object> into, String name, Object value) { - if (value == null) { - return; - } else if (value instanceof CompositeData) { - putCompositeData(into, name, (CompositeData) value); - } else if (value.getClass().isArray()) { - putArray(into, name, (Object[]) value); - } else { - into.put(name, value); - } - } - - /** - * Serialization of {@link CompositeData} into a map. - */ - private static void putCompositeData(Map<String, Object> into, String scope, CompositeData data) { - String prefix = scope + ".composite"; - CompositeType type = data.getCompositeType(); - into.put(prefix, type.getTypeName()); - for (String key : type.keySet()) { - Object value = data.get(key); - String name = prefix + '.' + key; - putAttribute(into, name, value); - } - } - - /** - * Serialization of an array into a map. - */ - private static void putArray(Map<String, Object> into, String scope, Object[] data) { - String prefix = scope + ".array"; - OpenType<?> type = findOpenType(data); - into.put(prefix, type.getTypeName()); - for (int i = 0; i < data.length; i++) { - Object value = Array.get(data, i); - String name = prefix + '.' + i; - putAttribute(into, name, value); - } - } - - private static OpenType<?> findOpenType(Object[] data) { - Class<?> componentType = data.getClass().getComponentType(); - OpenType<?> res = PRIMITIVE_TO_OPENTYPE.get(componentType); - // It's enough to support only arrays of simple open types. - // There is no use case for CompositeTypes yet. - if (res == null) { - throw new IllegalArgumentException("Unsupported type: " + componentType); - } - return res; - } - - static { - LibGraalUtil.checkToLibGraalCalls(JMXToLibGraalEntryPoints.class, JMXToLibGraalCalls.class, JMXToLibGraal.class); - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/LibGraalHotSpotGraalManagement.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/LibGraalHotSpotGraalManagement.java deleted file mode 100644 index 5f1fb8daffb3..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/LibGraalHotSpotGraalManagement.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2019, 2022, 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 org.graalvm.compiler.hotspot.management.libgraal; - -import java.util.function.Supplier; - -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; - -import org.graalvm.compiler.core.GraalServiceThread; -import org.graalvm.compiler.debug.TTY; -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration; -import org.graalvm.compiler.hotspot.HotSpotGraalRuntime; -import org.graalvm.compiler.hotspot.management.HotSpotGraalRuntimeMBean; -import org.graalvm.compiler.options.Option; -import org.graalvm.compiler.options.OptionKey; -import org.graalvm.compiler.options.OptionType; -import org.graalvm.word.LocationIdentity; -import org.graalvm.word.Pointer; - -/** - * Dynamically registers a {@link HotSpotGraalRuntimeMBean}s created in libgraal heap with an - * {@link MBeanServer} in the HotSpot heap. The instance is created by {@link HotSpotGraalRuntime} - * using a factory injected by {@code LibGraalFeature}. - */ -public final class LibGraalHotSpotGraalManagement extends MBeanProxy<HotSpotGraalRuntimeMBean> implements HotSpotGraalManagementRegistration { - - public LibGraalHotSpotGraalManagement() { - } - - static class Options { - /** - * The initialization of this management interface is delayed to avoid slowing down Graal - * initialization. The HotSpot side of this management interface requires initializing a - * complete JVMCI runtime which loads ~200 classes. - */ - @Option(help = "Milliseconds to delay initialization of the libgraal JMX interface. " + - "Specify a negative value to disable the interface altogether.", type = OptionType.Expert)// - static final OptionKey<Integer> LibGraalManagementDelay = new OptionKey<>(-1); - } - - /** - * Creates a {@link HotSpotGraalRuntimeMBean} for given {@code runtime}. It first defines the - * required classes in the HotSpot heap and starts the factory thread. Then it creates a - * {@link HotSpotGraalRuntimeMBean} for {@code runtime} and notifies the factory thread about a - * new pending registration. - * - * @param runtime the runtime to create {@link HotSpotGraalRuntimeMBean} for - * @param config the configuration used to obtain the {@code _jni_environment} offset - */ - @Override - public void initialize(HotSpotGraalRuntime runtime, GraalHotSpotVMConfig config) { - int delay = Options.LibGraalManagementDelay.getValue(runtime.getOptions()); - if (delay < 0) { - return; - } - Pointer warningShown = MBeanProxy.getOptionWarningStatePointer(); - if (warningShown.compareAndSwapInt(0, 0, 1, LocationIdentity.ANY_LOCATION) == 0) { - TTY.printf("The %s option is deprecated and will be removed in the next GraalVM version.%n", Options.LibGraalManagementDelay.getName()); - } - Pointer defineClassesStatePointer = getDefineClassesStatePointer(); - long defineClassesState = defineClassesStatePointer.readLong(0); - if (delay == 0 || defineClassesState == HS_CLASSES_DEFINED) { - // No delay or this is not the first Graal runtime to be initialized - // in the process. As such there's no need to use a separate thread - // to create the HotSpotGraalRuntimeMBean. - initialize0(runtime, config); - } else { - Thread t = new GraalServiceThread(LibGraalHotSpotGraalManagement.class.getSimpleName() + "-init", new Runnable() { - @Override - public void run() { - try { - Thread.sleep(delay); - initialize0(runtime, config); - } catch (Throwable error) { - runtime.handleManagementInitializationFailure(error); - } - } - }); - t.setDaemon(true); // don't delay VM shutdown - t.start(); - } - } - - private void initialize0(HotSpotGraalRuntime runtime, GraalHotSpotVMConfig config) { - if (!initializeJNI(config)) { - return; - } - HotSpotGraalRuntimeMBean mbean = getBean(); - if (mbean == null) { - if (runtime.getManagement() != this) { - throw new IllegalArgumentException("Cannot initialize a second management object for runtime " + runtime.getName()); - } - try { - String beanName = nameWithIsolateId("org.graalvm.compiler.hotspot:type=" + runtime.getName().replace(':', '_')); - ObjectName objectName = new ObjectName(beanName); - mbean = new HotSpotGraalRuntimeMBean(objectName, runtime); - initialize(mbean, beanName, objectName); - enqueueForRegistrationAndNotify(this, runtime); - } catch (MalformedObjectNameException err) { - err.printStackTrace(TTY.out); - } - } else if (mbean.getRuntime() != runtime) { - throw new IllegalArgumentException("Cannot change the runtime a management interface is associated with"); - } - } - - @Override - public ObjectName poll(boolean sync) { - return poll(); - } - - /** - * Factory for {@link LibGraalHotSpotGraalManagement}. - */ - static final class Factory implements Supplier<HotSpotGraalManagementRegistration> { - - Factory() { - } - - /** - * Creates a new {@link LibGraalHotSpotGraalManagement} instance. - */ - @Override - public HotSpotGraalManagementRegistration get() { - return new LibGraalHotSpotGraalManagement(); - } - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/LibGraalMemoryPoolMBean.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/LibGraalMemoryPoolMBean.java deleted file mode 100644 index 08a00a36a0c7..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/LibGraalMemoryPoolMBean.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2020, 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 org.graalvm.compiler.hotspot.management.libgraal; - -import static org.graalvm.compiler.hotspot.management.libgraal.MBeanProxy.nameWithIsolateId; - -import java.lang.management.MemoryUsage; -import java.util.ArrayList; -import java.util.List; -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.AttributeNotFoundException; -import javax.management.DynamicMBean; -import javax.management.InvalidAttributeValueException; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanConstructorInfo; -import javax.management.MBeanException; -import javax.management.MBeanInfo; -import javax.management.MBeanNotificationInfo; -import javax.management.MBeanOperationInfo; -import javax.management.ReflectionException; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.CompositeType; -import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; -import org.graalvm.compiler.serviceprovider.IsolateUtil; - -final class LibGraalMemoryPoolMBean implements DynamicMBean { - - private static final String BASE_OBJECT_NAME = "org.graalvm.compiler.hotspot:type=Libgraal"; - private static final String MEMORY_MANAGER = "Libgraal Memory Pool"; - - private static final String ATTR_NAME = "Name"; - private static final String ATTR_TYPE = "Type"; - private static final String ATTR_MEMORY_MANAGER_NAMES = "MemoryManagerNames"; - private static final String ATTR_VALID = "Valid"; - private static final String ATTR_USAGE = "Usage"; - private static final String ATTR_PEAK_USAGE = "PeakUsage"; - private static final String ATTR_COLLECTION_USAGE = "CollectionUsage"; - private static final String ATTR_COLLECTION_USAGE_THRESHOLD_SUPPORTED = "CollectionUsageThresholdSupported"; - private static final String ATTR_COLLECTION_USAGE_THRESHOLD = "CollectionUsageThreshold"; - private static final String ATTR_COLLECTION_USAGE_THRESHOLD_COUNT = "CollectionUsageThresholdCount"; - private static final String ATTR_COLLECTION_USAGE_THRESHOLD_EXCEEDED = "CollectionUsageThresholdExceeded"; - private static final String ATTR_USAGE_THRESHOLD_SUPPORTED = "UsageThresholdSupported"; - private static final String ATTR_USAGE_THRESHOLD = "UsageThreshold"; - private static final String ATTR_USAGE_THRESHOLD_COUNT = "UsageThresholdCount"; - private static final String ATTR_USAGE_THRESHOLD_EXCEEDED = "UsageThresholdExceeded"; - - private static final String ATTR_COMMITTED = "committed"; - private static final String ATTR_INIT = "init"; - private static final String ATTR_MAX = "max"; - private static final String ATTR_USED = "used"; - private static final String[] USAGE_TYPE_ATTRS = {ATTR_COMMITTED, ATTR_INIT, ATTR_MAX, ATTR_USED}; - private static final CompositeType USAGE_TYPE; - static { - try { - OpenType<?>[] types = {SimpleType.LONG, SimpleType.LONG, SimpleType.LONG, SimpleType.LONG}; - USAGE_TYPE = new CompositeType(MemoryUsage.class.getName(), "Memory Usage", USAGE_TYPE_ATTRS, USAGE_TYPE_ATTRS, types); - } catch (OpenDataException e) { - // Should never happen - throw new AssertionError("Cannot create memory usage type.", e); - } - } - - private final Runtime rt; - private final String objectId; - private final String name; - private volatile long peekTotalMemory; - private volatile long peekUsedMemory; - - LibGraalMemoryPoolMBean() { - rt = Runtime.getRuntime(); - objectId = nameWithIsolateId(BASE_OBJECT_NAME); - name = MEMORY_MANAGER + " " + IsolateUtil.getIsolateID(); - } - - String getObjectId() { - return objectId; - } - - @Override - public MBeanInfo getMBeanInfo() { - List<MBeanAttributeInfo> attrs = new ArrayList<>(); - attrs.add(createAttributeInfo(ATTR_NAME, String.class)); - attrs.add(createAttributeInfo(ATTR_TYPE, String.class)); - attrs.add(createAttributeInfo(ATTR_MEMORY_MANAGER_NAMES, String[].class)); - attrs.add(createAttributeInfo(ATTR_VALID, Boolean.class)); - attrs.add(createAttributeInfo(ATTR_USAGE, CompositeData.class)); - attrs.add(createAttributeInfo(ATTR_PEAK_USAGE, CompositeData.class)); - attrs.add(createAttributeInfo(ATTR_COLLECTION_USAGE, CompositeData.class)); - attrs.add(createAttributeInfo(ATTR_COLLECTION_USAGE_THRESHOLD_SUPPORTED, Boolean.class)); - attrs.add(createAttributeInfo(ATTR_COLLECTION_USAGE_THRESHOLD, Long.class)); - attrs.add(createAttributeInfo(ATTR_COLLECTION_USAGE_THRESHOLD_COUNT, Long.class)); - attrs.add(createAttributeInfo(ATTR_COLLECTION_USAGE_THRESHOLD_EXCEEDED, Boolean.class)); - attrs.add(createAttributeInfo(ATTR_USAGE_THRESHOLD_SUPPORTED, Boolean.class)); - attrs.add(createAttributeInfo(ATTR_USAGE_THRESHOLD, Long.class)); - attrs.add(createAttributeInfo(ATTR_USAGE_THRESHOLD_COUNT, Long.class)); - attrs.add(createAttributeInfo(ATTR_USAGE_THRESHOLD_EXCEEDED, Boolean.class)); - - return new MBeanInfo( - getClass().getName(), - MEMORY_MANAGER, - attrs.toArray(new MBeanAttributeInfo[attrs.size()]), - new MBeanConstructorInfo[0], - new MBeanOperationInfo[0], - new MBeanNotificationInfo[0]); - } - - private static MBeanAttributeInfo createAttributeInfo(String name, Class<?> type) { - return new MBeanAttributeInfo(name, type.getName(), name, true, false, false); - } - - @Override - public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { - switch (attribute) { - case ATTR_NAME: - return name; - case ATTR_TYPE: - return "NON_HEAP"; - case ATTR_MEMORY_MANAGER_NAMES: - return new String[]{MEMORY_MANAGER}; - case ATTR_VALID: - return true; - case ATTR_USAGE: - return getUsage(); - case ATTR_PEAK_USAGE: - return getPeekUsage(); - case ATTR_COLLECTION_USAGE_THRESHOLD_SUPPORTED: - return false; - case ATTR_COLLECTION_USAGE_THRESHOLD_EXCEEDED: - return false; - case ATTR_COLLECTION_USAGE_THRESHOLD_COUNT: - return 0L; - case ATTR_COLLECTION_USAGE_THRESHOLD: - return 0L; - case ATTR_COLLECTION_USAGE: - return null; - case ATTR_USAGE_THRESHOLD_SUPPORTED: - return false; - case ATTR_USAGE_THRESHOLD_EXCEEDED: - return false; - case ATTR_USAGE_THRESHOLD_COUNT: - return 0L; - case ATTR_USAGE_THRESHOLD: - return 0L; - default: - throw new AttributeNotFoundException(attribute); - } - } - - void update() { - updateMemStat(); - } - - private CompositeData getUsage() { - try { - return new CompositeDataSupport(USAGE_TYPE, USAGE_TYPE_ATTRS, updateMemStat()); - } catch (OpenDataException e) { - throw new RuntimeException(e); - } - } - - private CompositeData getPeekUsage() { - try { - Object[] data = updateMemStat(); - data[0] = peekTotalMemory; - data[3] = peekUsedMemory; - return new CompositeDataSupport(USAGE_TYPE, USAGE_TYPE_ATTRS, data); - } catch (OpenDataException e) { - throw new RuntimeException(e); - } - } - - private Object[] updateMemStat() { - long maxMemory = rt.maxMemory(); - long totalMemory = rt.totalMemory(); - long freeMemory = rt.freeMemory(); - long usedMemory = totalMemory - freeMemory; - peekTotalMemory = Math.max(peekTotalMemory, totalMemory); - peekUsedMemory = Math.max(peekUsedMemory, usedMemory); - return new Object[]{totalMemory, 0L, maxMemory, usedMemory}; - } - - @Override - public AttributeList getAttributes(String[] attributes) { - List<Attribute> result = new ArrayList<>(); - for (String attribute : attributes) { - try { - Object value = getAttribute(attribute); - result.add(new Attribute(attribute, value)); - } catch (AttributeNotFoundException | MBeanException | ReflectionException e) { - } - } - return new AttributeList(result); - } - - @Override - public void setAttribute(Attribute atrbt) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { - throw new UnsupportedOperationException("Set attribute is not supported."); - } - - @Override - public AttributeList setAttributes(AttributeList al) { - throw new UnsupportedOperationException("Set attribute is not supported."); - } - - @Override - public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException { - throw new UnsupportedOperationException("Operation invoke is not supported."); - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/MBeanProxy.java b/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/MBeanProxy.java deleted file mode 100644 index 0da03ade97e1..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management.libgraal/src/org/graalvm/compiler/hotspot/management/libgraal/MBeanProxy.java +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 2020, 2022, 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 org.graalvm.compiler.hotspot.management.libgraal; - -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal.Id.GetFactory; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal.Id.SignalRegistrationRequest; -import static org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal.Id.Unregister; -import static org.graalvm.compiler.hotspot.management.libgraal.MBeanProxyGen.callGetFactory; -import static org.graalvm.compiler.hotspot.management.libgraal.MBeanProxyGen.callSignalRegistrationRequest; -import static org.graalvm.compiler.hotspot.management.libgraal.MBeanProxyGen.callUnregister; -import static org.graalvm.jniutils.JNIUtil.getBinaryName; -import static org.graalvm.word.LocationIdentity.ANY_LOCATION; - -import java.io.DataInputStream; -import java.io.IOException; -import java.lang.reflect.Method; -import java.nio.ByteBuffer; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Queue; - -import javax.management.DynamicMBean; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; - -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.hotspot.HotSpotGraalRuntime; -import org.graalvm.compiler.hotspot.management.Factory; -import org.graalvm.compiler.hotspot.management.JMXToLibGraalCalls; -import org.graalvm.compiler.hotspot.management.LibGraalMBean; -import org.graalvm.compiler.hotspot.management.JMXFromLibGraalEntryPoints; -import org.graalvm.compiler.hotspot.management.libgraal.annotation.JMXFromLibGraal; -import org.graalvm.compiler.serviceprovider.IsolateUtil; -import org.graalvm.jniutils.JNI; -import org.graalvm.jniutils.JNIExceptionWrapper; -import org.graalvm.jniutils.JNIExceptionWrapper.ExceptionHandler; -import org.graalvm.jniutils.JNIUtil; -import org.graalvm.nativeimage.CurrentIsolate; -import org.graalvm.nativeimage.UnmanagedMemory; -import org.graalvm.nativeimage.c.type.CCharPointer; -import org.graalvm.nativeimage.c.type.CTypeConversion; -import org.graalvm.word.WordFactory; - -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import org.graalvm.compiler.hotspot.management.AggregatedMemoryPoolBean; -import org.graalvm.libgraal.jni.annotation.FromLibGraalEntryPointsResolver; -import org.graalvm.word.Pointer; - -class MBeanProxy<T extends DynamicMBean> { - - private static final Method getCurrentJavaThreadMethod; - static { - Method m; - try { - m = HotSpotJVMCIRuntime.class.getMethod("getCurrentJavaThread"); - } catch (NoSuchMethodException e) { - m = null; - } - getCurrentJavaThreadMethod = m; - } - - // Classes defined in HotSpot heap by JNI. - private static final ClassData HS_BEAN_CLASS = ClassData.create(LibGraalMBean.class); - private static final ClassData HS_BEAN_FACTORY_CLASS = ClassData.create(Factory.class); - private static final ClassData HS_CALLS_CLASS = ClassData.create(JMXToLibGraalCalls.class); - private static final ClassData HS_PUSHBACK_ITER_CLASS = ClassData.create(LibGraalMBean.PushBackIterator.class); - private static final ClassData HS_ENTRYPOINTS_CLASS = ClassData.create(JMXFromLibGraalEntryPoints.class); - private static final ClassData HS_AGGREGATED_MEMORY_POOL_BEAN_CLASS = ClassData.create(AggregatedMemoryPoolBean.class); - - // Values for the global word used to synchronize definition - // of the above classes in the HotSpot heap - static final long HS_CLASSES_UNDEFINED = 0L; - static final long HS_CLASSES_DEFINING = 1L; - static final long HS_CLASSES_DEFINED = 2L; - - /** - * Pending MBeans registrations on HotSpot side. - * - * Access is synchronized on {@code MBeanProxy.class}. - */ - private static Queue<MBeanProxy<?>> registrations = new ArrayDeque<>(); - - // JNI Globals - private static JNI.JClass fromLibGraalEntryPoints; - - /** - * Offset of the {@code _jni_environment} field in {@code JavaThread}. - */ - private static volatile long jniEnvOffset; - - private static LibGraalMemoryPoolMBean memPoolBean; - - /** - * Lifecycle state. - * - * Access is synchronized on {@code MBeanProxy.class}. - * - * @see State - */ - private static State state = State.INIT; - - /** - * The MBean instance. - */ - private T bean; - - /** - * The name of the MBean. - */ - private String name; - - /** - * JMX Object name. - */ - private ObjectName objName; - - /** - * Flag for pending registration. - */ - private volatile boolean needsRegistration = true; - - /** - * Creates a new uninitialized {@link MBeanProxy}. The - * {@link MBeanProxy#initialize(javax.management.DynamicMBean, java.lang.String, javax.management.ObjectName)} - * must be called before the instance is used. - */ - MBeanProxy() { - } - - /** - * Creates a new {@link MBeanProxy} initialized by given {@code mbean}. - */ - MBeanProxy(T mbean, String strName) throws MalformedObjectNameException { - initialize(mbean, strName, new ObjectName(strName)); - } - - void initialize(T mbean, String strName, ObjectName objectName) { - Objects.requireNonNull(mbean); - Objects.requireNonNull(strName); - Objects.requireNonNull(objectName); - if (this.bean != null) { - throw new IllegalStateException("Already initialized."); - } - assert this.name == null; - assert this.objName == null; - this.bean = mbean; - this.name = strName; - this.objName = objectName; - } - - /** - * Returns the MBean used for delegation from HotSpot heap. - */ - T getBean() { - return bean; - } - - /** - * Notification about finished registration in HotSpot heap. - */ - void finishRegistration() { - needsRegistration = false; - } - - /** - * Returns the name which should be used to register this MBean. - */ - String getName() { - return name; - } - - ObjectName poll() { - LibGraalMemoryPoolMBean memPool = memPoolBean; - if (memPool != null) { - memPool.update(); - } - if (bean == null || needsRegistration) { - return null; - } - return objName; - } - - static boolean initializeJNI(GraalHotSpotVMConfig config) { - if (getCurrentJavaThreadMethod == null) { - return false; - } - if (jniEnvOffset == 0) { - synchronized (MBeanProxy.class) { - if (jniEnvOffset == 0) { - if (config.jniEnvironmentOffset == Integer.MIN_VALUE) { - // Old unsupported JVMCI version. - return false; - } - memPoolBean = new LibGraalMemoryPoolMBean(); - jniEnvOffset = config.jniEnvironmentOffset; - defineClassesInHotSpot(getCurrentJNIEnv()); - try { - MBeanProxy<?> memPoolMBean = new MBeanProxy<>(memPoolBean, memPoolBean.getObjectId()); - enqueueForRegistration(memPoolMBean); - } catch (MalformedObjectNameException mon) { - throw new AssertionError("Invlid object name.", mon); - } - } - } - } - return true; - } - - @FromLibGraalEntryPointsResolver(JMXFromLibGraal.Id.class) - static JNI.JClass getHotSpotEntryPoints() { - return fromLibGraalEntryPoints; - } - - /** - * Computes {@code JNIEnv} for a current {@code JavaThread}. - */ - static JNI.JNIEnv getCurrentJNIEnv() { - if (jniEnvOffset == 0) { - throw new IllegalStateException("JniEnvOffset is not yet initialized."); - } - if (getCurrentJavaThreadMethod == null) { - throw new IllegalStateException("CurrentJavaThread not supported by JVMCI."); - } - try { - long currentJavaThreadAddr = (Long) getCurrentJavaThreadMethod.invoke(HotSpotJVMCIRuntime.runtime()); - return WordFactory.pointer(currentJavaThreadAddr + jniEnvOffset); - } catch (ReflectiveOperationException reflectiveException) { - throw new RuntimeException("Failed to invoke HotSpotJVMCIRuntime::getCurrentJavaThread", reflectiveException); - } - } - - /** - * Removes the pending registrations. - * - * @return the pending registrations - */ - static synchronized List<MBeanProxy<?>> drainRegistrations() { - if (state != State.ACTIVE || registrations.isEmpty()) { - return Collections.emptyList(); - } else { - List<MBeanProxy<?>> res = new ArrayList<>(registrations); - registrations.clear(); - return res; - } - } - - /** - * Registers a given {@link LibGraalHotSpotGraalManagement} instance into pending registrations - * and notifies the worker in HotSpot heap. - * - * @return the {@code instance} if successfully registered or {@code null} when the registration - * in not accepted because the isolate is closing - */ - static <T extends MBeanProxy<?>> T enqueueForRegistrationAndNotify(T instance, HotSpotGraalRuntime runtime) { - T res = enqueueForRegistration(instance); - if (res != null) { - signalRegistrationRequest(runtime); - } - return res; - } - - static String nameWithIsolateId(String name) { - long id = IsolateUtil.getIsolateID(); - return id == 0L ? name : name + ",isolate=" + id; - } - - /** - * Registers a given {@link LibGraalHotSpotGraalManagement} instance into pending registrations. - * - * @return the {@code instance} if successfully registered or {@code null} when the registration - * in not accepted because the isolate is closing - */ - private static synchronized <T extends MBeanProxy<?>> T enqueueForRegistration(T instance) { - if (state == State.CLOSED) { - return null; - } - registrations.add(instance); - return instance; - } - - /** - * Updates state to active. The state is set to active when the Factory was successfully created - * on the HotSpot side. If Factory creation failed the updateStateToActive is not called. This - * prevents the repetitive exception from the shutdown hook. - */ - private static synchronized void updateStateToActive(HotSpotGraalRuntime runtime) { - if (state == State.INIT) { - state = State.ACTIVE; - runtime.addShutdownHook(new OnShutDown()); - } - } - - /** - * Uses JNI to define the classes in HotSpot heap. - */ - private static void defineClassesInHotSpot(JNI.JNIEnv env) { - Pointer barrier = getDefineClassesStatePointer(); - JNI.JObject classLoader = JNIUtil.getJVMCIClassLoader(env); - Runnable defineAction = () -> { - defineClassInHotSpot(env, classLoader, HS_CALLS_CLASS); - long entryPoints = defineClassInHotSpot(env, classLoader, HS_ENTRYPOINTS_CLASS).rawValue(); - defineClassInHotSpot(env, classLoader, HS_BEAN_CLASS); - defineClassInHotSpot(env, classLoader, HS_BEAN_FACTORY_CLASS); - defineClassInHotSpot(env, classLoader, HS_PUSHBACK_ITER_CLASS); - defineClassInHotSpot(env, classLoader, HS_AGGREGATED_MEMORY_POOL_BEAN_CLASS); - fromLibGraalEntryPoints = JNIUtil.NewGlobalRef(env, WordFactory.pointer(entryPoints), "Class<" + HS_ENTRYPOINTS_CLASS.binaryName + ">"); - }; - Runnable loadAction = () -> { - long entryPoints = JNIUtil.findClass(env, classLoader, HS_ENTRYPOINTS_CLASS.binaryName, true).rawValue(); - fromLibGraalEntryPoints = JNIUtil.NewGlobalRef(env, WordFactory.pointer(entryPoints), "Class<" + HS_ENTRYPOINTS_CLASS.binaryName + ">"); - }; - runGuarded(barrier, defineAction, loadAction); - } - - /** - * Guards defining and loading classes. The {@code barrier} is used to ensure the {@code action} - * with {@code defineClass} parameter is executed exactly once in the process (i.e. synchronized - * across all threads and isolates). The other threads will block until the {@code defineClass} - * action finishes in order to run the {@code loadClass} action. - */ - private static void runGuarded(Pointer barrier, Runnable defineAction, Runnable loadAction) { - if (barrier.isNull()) { - throw new IllegalStateException("Missing substitution for MBeanProxy.defineClassesInHotSpot"); - } - long defineClassState = barrier.readLong(0); - if (defineClassState == HS_CLASSES_DEFINED) { - loadAction.run(); - } else { - while (true) { - defineClassState = barrier.readLong(0); - if (defineClassState == HS_CLASSES_UNDEFINED) { - if (barrier.compareAndSwapLong(0, HS_CLASSES_UNDEFINED, HS_CLASSES_DEFINING, ANY_LOCATION) == HS_CLASSES_UNDEFINED) { - defineAction.run(); - barrier.writeLong(0, HS_CLASSES_DEFINED); - break; - } - } else { - if (defineClassState == HS_CLASSES_DEFINED) { - loadAction.run(); - break; - } - try { - Thread.sleep(10); - } catch (InterruptedException e) { - } - } - } - } - } - - /** - * Defines a class in HotSpot heap using JNI. - * - * @param env the {@code JNIEnv} - * @param classLoader the class loader to define class in. - * @param classData the class to define in HotSpot - * @return the defined class - */ - private static JNI.JClass defineClassInHotSpot(JNI.JNIEnv env, JNI.JObject classLoader, ClassData classData) { - CCharPointer classDataPointer = UnmanagedMemory.malloc(classData.byteCode.length); - ByteBuffer buffer = CTypeConversion.asByteBuffer(classDataPointer, classData.byteCode.length); - buffer.put(classData.byteCode); - try (CTypeConversion.CCharPointerHolder className = CTypeConversion.toCString(classData.binaryName)) { - JNI.JClass definedClass = JNIUtil.DefineClass( - env, - className.get(), - classLoader, - classDataPointer, - classData.byteCode.length); - return definedClass; - } finally { - UnmanagedMemory.free(classDataPointer); - // LinkageError is allowed, the class may be already defined - JNIExceptionWrapper.wrapAndThrowPendingJNIException(env, ExceptionHandler.allowExceptions(LinkageError.class)); - } - } - - /** - * Gets a reference to factory thread running in HotSpot heap. - */ - @JMXFromLibGraal(GetFactory) - private static JNI.JObject getFactory(JNI.JNIEnv env) { - return callGetFactory(env); - } - - /** - * Notifies the factory thread in HotSpot heap of new management bean instances to register. - */ - @JMXFromLibGraal(SignalRegistrationRequest) - private static void signalRegistrationRequest(HotSpotGraalRuntime runtime) { - JNI.JNIEnv env = getCurrentJNIEnv(); - JNI.JObject factory = getFactory(env); - updateStateToActive(runtime); - callSignalRegistrationRequest(env, factory, CurrentIsolate.getIsolate().rawValue()); - } - - /** - * Performs MBeans unregistration in the HotSpot heap. - */ - @JMXFromLibGraal(Unregister) - private static void unregister() { - JNI.JNIEnv env = getCurrentJNIEnv(); - JNI.JObject factory = getFactory(env); - callUnregister(env, factory, CurrentIsolate.getIsolate().rawValue()); - } - - /** - * Gets a pointer to a global word used as spin lock for safely defining classes in HotSpot. - */ - static Pointer getDefineClassesStatePointer() { - // Substituted by Target_org_graalvm_compiler_hotspot_management_libgraal_MBeanProxy - return WordFactory.nullPointer(); - } - - /** - * Gets a pointer to a global word used as a flag to show a deprecated option warning only once - * even in case of multiple compiler isolates per process. - */ - static Pointer getOptionWarningStatePointer() { - // Substituted by Target_org_graalvm_compiler_hotspot_management_libgraal_MBeanProxy - return WordFactory.nullPointer(); - } - - /** - * Lifecycle state. - */ - private enum State { - /** - * Initial state when an isolate is created. - */ - INIT, - - /** - * Active state, the MBeans are registered. - */ - ACTIVE, - - /** - * Closed, new MBean registrations are no longer accepted. - */ - CLOSED - } - - private static final class OnShutDown implements Runnable { - - @Override - public void run() { - State prevState; - synchronized (MBeanProxy.class) { - prevState = state; - state = State.CLOSED; - } - if (prevState == State.ACTIVE) { - unregister(); - } - } - } - - /** - * Represents a class defined in the HotSpot heap. The {@code ClassData} objects are created - * when building libgraal. - * - */ - private static final class ClassData { - final String binaryName; - final byte[] byteCode; - - private ClassData(String binaryName, byte[] byteCode) { - this.binaryName = binaryName; - this.byteCode = byteCode; - } - - static ClassData create(Class<?> clz) { - String binaryName = getBinaryName(clz.getName()); - try (DataInputStream in = new DataInputStream(clz.getResourceAsStream('/' + binaryName + ".class"))) { - byte[] buffer = new byte[in.available()]; - in.readFully(buffer); - return new ClassData(binaryName, buffer); - } catch (IOException ioe) { - throw new InternalError("Error loading class file for %s: " + clz.getName(), ioe); - } - } - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java index 2710c9afda9d..4e2e34144d2c 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java @@ -35,7 +35,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Supplier; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.EconomicSet; @@ -104,12 +103,6 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider { private static final boolean IS_AOT = Boolean.parseBoolean(Services.getSavedProperties().get("com.oracle.graalvm.isaot")); - /** - * A factory for a {@link HotSpotGraalManagementRegistration} injected by - * {@code Target_org_graalvm_compiler_hotspot_HotSpotGraalRuntime}. - */ - private static final Supplier<HotSpotGraalManagementRegistration> AOT_INJECTED_MANAGEMENT = null; - private static boolean checkArrayIndexScaleInvariants(MetaAccessProvider metaAccess) { assert metaAccess.getArrayIndexScale(JavaKind.Byte) == 1; assert metaAccess.getArrayIndexScale(JavaKind.Boolean) == 1; @@ -183,7 +176,7 @@ public GlobalMetrics getMetricValues() { this.instrumentation = compilerConfigurationFactory.createInstrumentation(options); if (IS_AOT) { - management = AOT_INJECTED_MANAGEMENT == null ? null : AOT_INJECTED_MANAGEMENT.get(); + management = null; } else { management = GraalServices.loadSingle(HotSpotGraalManagementRegistration.class, false); } diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index cd1a158934c2..8a44106c2231 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -1136,8 +1136,7 @@ def _native_image_launcher_extra_jvm_args(): libgraal_jar_distributions = [ 'substratevm:GRAAL_HOTSPOT_LIBRARY', - 'compiler:GRAAL_TRUFFLE_COMPILER_LIBGRAAL', - 'compiler:GRAAL_MANAGEMENT_LIBGRAAL'] + 'compiler:GRAAL_TRUFFLE_COMPILER_LIBGRAAL'] libgraal_build_args = [ ## Pass via JVM args opening up of packages needed for image builder early on diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java index a524bf1bafe6..1555e4876789 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java @@ -81,20 +81,6 @@ public final class LibGraalEntryPoints { */ static final CGlobalData<Pointer> LOG_FILE_BARRIER = CGlobalDataFactory.createWord((Pointer) WordFactory.zero()); - /** - * The spin lock field for the - * {@code org.graalvm.compiler.hotspot.management.libgraal.MBeanProxy#defineClassesInHotSpot}. - */ - static final CGlobalData<Pointer> MANAGEMENT_BARRIER = CGlobalDataFactory.createWord((Pointer) WordFactory.zero()); - - /** - * A flag used by the - * {@code org.graalvm.compiler.hotspot.management.libgraal.LibGraalHotSpotGraalManagement#initialize} - * to show a deprecated option warning only once even in case of multiple compiler isolates per - * process. - */ - static final CGlobalData<Pointer> MANAGEMENT_OPTION_WARNING = CGlobalDataFactory.createWord((Pointer) WordFactory.zero()); - static final CGlobalData<Pointer> GLOBAL_TIMESTAMP = CGlobalDataFactory.createBytes(() -> 8); @CEntryPoint(builtin = Builtin.GET_CURRENT_THREAD, name = "Java_org_graalvm_libgraal_LibGraalScope_getIsolateThreadIn") diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index fbacf24404fd..e071dacdea3b 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -48,7 +48,6 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.function.BooleanSupplier; -import java.util.function.Supplier; import java.util.stream.Collectors; import org.graalvm.collections.EconomicMap; @@ -61,7 +60,6 @@ import org.graalvm.compiler.hotspot.EncodedSnippets; import org.graalvm.compiler.hotspot.HotSpotCodeCacheListener; import org.graalvm.compiler.hotspot.HotSpotGraalCompiler; -import org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration; import org.graalvm.compiler.hotspot.HotSpotGraalOptionValues; import org.graalvm.compiler.hotspot.HotSpotGraalRuntime; import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl; @@ -102,7 +100,6 @@ import org.graalvm.nativeimage.StackValue; import org.graalvm.nativeimage.VMRuntime; import org.graalvm.nativeimage.hosted.Feature; -import org.graalvm.nativeimage.hosted.FieldValueTransformer; import org.graalvm.nativeimage.hosted.RuntimeReflection; import org.graalvm.nativeimage.impl.ConfigurationCondition; import org.graalvm.word.LocationIdentity; @@ -678,33 +675,12 @@ private static CompilationRequestResult compileMethod(HotSpotGraalCompiler compi @TargetClass(className = "org.graalvm.compiler.hotspot.HotSpotGraalRuntime", onlyWith = LibGraalFeature.IsEnabled.class) final class Target_org_graalvm_compiler_hotspot_HotSpotGraalRuntime { - // Checkstyle: stop - @Alias @RecomputeFieldValue(kind = Kind.Custom, declClass = InjectedManagementComputer.class, isFinal = true)// - private static Supplier<HotSpotGraalManagementRegistration> AOT_INJECTED_MANAGEMENT; - // Checkstyle: resume - @SuppressWarnings("unused") @Substitute private static void startupLibGraal(HotSpotGraalRuntime runtime) { VMRuntime.initialize(); } - private static final class InjectedManagementComputer implements FieldValueTransformer { - @Override - public Object transform(Object receiver, Object originalValue) { - try { - Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass("org.graalvm.compiler.hotspot.management.libgraal.LibGraalHotSpotGraalManagement$Factory"); - Constructor<?> constructor = clazz.getDeclaredConstructor(); - constructor.setAccessible(true); - return constructor.newInstance(); - } catch (ClassNotFoundException cnf) { - return null; - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - } - @Substitute private static void shutdownLibGraal(HotSpotGraalRuntime runtime) { try { @@ -771,21 +747,6 @@ private static void notifyLowMemoryPoint(boolean fullGC) { } } -@TargetClass(className = "org.graalvm.compiler.hotspot.management.libgraal.MBeanProxy", onlyWith = LibGraalFeature.IsEnabled.class) -final class Target_org_graalvm_compiler_hotspot_management_libgraal_MBeanProxy { - - @Substitute - private static Pointer getDefineClassesStatePointer() { - return LibGraalEntryPoints.MANAGEMENT_BARRIER.get(); - } - - @Substitute - private static Pointer getOptionWarningStatePointer() { - return LibGraalEntryPoints.MANAGEMENT_OPTION_WARNING.get(); - } - -} - @TargetClass(className = "org.graalvm.compiler.hotspot.HotSpotGraalOptionValues", onlyWith = LibGraalFeature.IsEnabled.class) final class Target_org_graalvm_compiler_hotspot_HotSpotGraalOptionValues { @Substitute From 4c4b93d1db47c49de94f75617d727dfb7fd51931 Mon Sep 17 00:00:00 2001 From: Tomas Zezula <tomas.zezula@oracle.com> Date: Wed, 24 Aug 2022 18:49:26 +0200 Subject: [PATCH 2/3] Removed jargraal management beans. --- compiler/CHANGELOG.md | 2 +- compiler/mx.compiler/suite.py | 19 - .../management/HotSpotGraalManagement.java | 185 -------- .../management/HotSpotGraalRuntimeMBean.java | 253 ----------- .../test/HotSpotGraalManagementTest.java | 423 ------------------ .../HotSpotGraalManagementRegistration.java | 51 --- .../compiler/hotspot/HotSpotGraalRuntime.java | 254 ----------- 7 files changed, 1 insertion(+), 1186 deletions(-) delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalManagementTest.java delete mode 100644 compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalManagementRegistration.java diff --git a/compiler/CHANGELOG.md b/compiler/CHANGELOG.md index 62ff059dda8c..890243d74742 100644 --- a/compiler/CHANGELOG.md +++ b/compiler/CHANGELOG.md @@ -5,7 +5,7 @@ This changelog summarizes newly introduced optimizations that may be relevant to ## Version 22.3.0 * (GR-32382): Added a dedicated Native Image GC policy for libgraal that will adjust the eden space aggressively to minimize RSS memory usage. -* (GR-38950): Removed deprecated JMX `HotSpotGraalRuntime` management bean. +* (GR-38950): Removed deprecated JMX `HotSpotGraalRuntime` management bean in both `libgraal` and `jargraal` compiler. ## Version 22.2.0 * (GR-23737): New global value numbering optimization for fixed nodes early in the compilation pipeline. diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index e71058f5669c..0f98a51f416b 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -606,23 +606,6 @@ "workingSets" : "Graal,HotSpot", }, - "org.graalvm.compiler.hotspot.management" : { - "subDir" : "src", - "sourceDirs" : ["src"], - "dependencies" : [ - "org.graalvm.compiler.hotspot", - ], - "requires" : [ - "java.management", - ], - "checkstyle" : "org.graalvm.compiler.graph", - "annotationProcessors" : [ - "GRAAL_PROCESSOR", - ], - "javaCompliance" : "11+", - "workingSets" : "Graal,HotSpot", - }, - "org.graalvm.compiler.management" : { "subDir" : "src", "sourceDirs" : ["src"], @@ -2013,7 +1996,6 @@ "org.graalvm.compiler.debug.DebugHandlersFactory", "org.graalvm.compiler.debug.TTYStreamProvider", "org.graalvm.compiler.debug.PathUtilitiesProvider", - "org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration", "org.graalvm.compiler.hotspot.HotSpotCodeCacheListener", "org.graalvm.compiler.hotspot.HotSpotBackendFactory", "org.graalvm.compiler.hotspot.meta.HotSpotInvocationPluginProvider", @@ -2091,7 +2073,6 @@ "subDir" : "src", "dependencies" : [ "org.graalvm.compiler.management", - "org.graalvm.compiler.hotspot.management", ], "distDependencies" : [ "GRAAL", diff --git a/compiler/src/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java b/compiler/src/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java deleted file mode 100644 index 8be33e109f70..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 org.graalvm.compiler.hotspot.management; - -import java.lang.management.ManagementFactory; -import java.util.ArrayList; - -import javax.management.InstanceAlreadyExistsException; -import javax.management.MBeanRegistrationException; -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.MalformedObjectNameException; -import javax.management.NotCompliantMBeanException; -import javax.management.ObjectName; - -import org.graalvm.compiler.debug.TTY; -import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; -import org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration; -import org.graalvm.compiler.hotspot.HotSpotGraalRuntime; -import org.graalvm.compiler.serviceprovider.ServiceProvider; - -/** - * Dynamically registers an MBean with the {@link ManagementFactory#getPlatformMBeanServer()}. - * - * Polling for an active platform MBean server is done by calling - * {@link MBeanServerFactory#findMBeanServer(String)} with an argument value of {@code null}. Once - * this returns an non-empty list, {@link ManagementFactory#getPlatformMBeanServer()} can be called - * to obtain a reference to the platform MBean server instance. - */ -@ServiceProvider(HotSpotGraalManagementRegistration.class) -public final class HotSpotGraalManagement implements HotSpotGraalManagementRegistration { - - private HotSpotGraalRuntimeMBean bean; - private volatile boolean needsRegistration = true; - HotSpotGraalManagement nextDeferred; - - @Override - public void initialize(HotSpotGraalRuntime runtime, GraalHotSpotVMConfig config) { - if (bean == null) { - if (runtime.getManagement() != this) { - throw new IllegalArgumentException("Cannot initialize a second management object for runtime " + runtime.getName()); - } - try { - String name = runtime.getName().replace(':', '_'); - ObjectName objectName = new ObjectName("org.graalvm.compiler.hotspot:type=" + name); - bean = new HotSpotGraalRuntimeMBean(objectName, runtime); - registration.add(this); - } catch (MalformedObjectNameException err) { - err.printStackTrace(TTY.out); - } - } else if (bean.getRuntime() != runtime) { - throw new IllegalArgumentException("Cannot change the runtime a management interface is associated with"); - } - } - - static final class RegistrationThread extends Thread { - - private MBeanServer platformMBeanServer; - private HotSpotGraalManagement deferred; - - RegistrationThread() { - super("HotSpotGraalManagement Bean Registration"); - this.setPriority(Thread.MIN_PRIORITY); - this.setDaemon(true); - this.start(); - } - - /** - * Poll for active MBean server every 2 seconds. - */ - private static final int POLL_INTERVAL_MS = 2000; - - /** - * Adds a {@link HotSpotGraalManagement} to register with an active MBean server when one - * becomes available. - */ - synchronized void add(HotSpotGraalManagement e) { - if (deferred != null) { - e.nextDeferred = deferred; - } - deferred = e; - - // Notify the registration thread that there is now - // a deferred registration to process - notify(); - } - - /** - * Processes and clears any deferred registrations. - */ - private void process() { - for (HotSpotGraalManagement m = deferred; m != null; m = m.nextDeferred) { - HotSpotGraalRuntimeMBean bean = m.bean; - if (m.needsRegistration && bean != null) { - try { - platformMBeanServer.registerMBean(bean, bean.getObjectName()); - } catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) { - e.printStackTrace(TTY.out); - // Registration failed - don't try again - m.bean = null; - } - m.needsRegistration = false; - } - } - deferred = null; - } - - @Override - public void run() { - while (true) { - try { - synchronized (this) { - // Wait until there are deferred registrations to process - while (deferred == null) { - wait(); - } - } - poll(); - Thread.sleep(POLL_INTERVAL_MS); - } catch (InterruptedException e) { - // Be verbose about unexpected interruption and then continue - e.printStackTrace(TTY.out); - } - } - } - - /** - * Checks for active MBean server and if available, processes deferred registrations. - */ - synchronized void poll() { - if (platformMBeanServer == null) { - try { - ArrayList<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null); - if (!servers.isEmpty()) { - platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); - process(); - } - } catch (SecurityException | UnsatisfiedLinkError | NoClassDefFoundError | UnsupportedOperationException e) { - // Without permission to find or create the MBeanServer, - // we cannot process any Graal mbeans. - // Various other errors can occur in the ManagementFactory (JDK-8076557) - deferred = null; - } - } else { - process(); - } - } - } - - private static final RegistrationThread registration = new RegistrationThread(); - - @Override - public ObjectName poll(boolean sync) { - if (sync) { - registration.poll(); - } - if (bean == null || needsRegistration) { - // initialize() has not been called, it failed or registration failed - return null; - } - return bean.getObjectName(); - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java b/compiler/src/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java deleted file mode 100644 index eb15fd5ee6ca..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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 org.graalvm.compiler.hotspot.management; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.AttributeNotFoundException; -import javax.management.DynamicMBean; -import javax.management.InvalidAttributeValueException; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanException; -import javax.management.MBeanInfo; -import javax.management.MBeanOperationInfo; -import javax.management.MBeanParameterInfo; -import javax.management.ObjectName; -import javax.management.ReflectionException; - -import org.graalvm.collections.EconomicMap; -import org.graalvm.compiler.core.common.SuppressFBWarnings; -import org.graalvm.compiler.debug.TTY; -import org.graalvm.compiler.hotspot.HotSpotGraalRuntime; -import org.graalvm.compiler.options.OptionDescriptor; -import org.graalvm.compiler.options.OptionDescriptors; -import org.graalvm.compiler.options.OptionsParser; - -import jdk.vm.ci.services.Services; - -/** - * MBean used to access properties and operations of a {@link HotSpotGraalRuntime} instance. - */ -public final class HotSpotGraalRuntimeMBean implements DynamicMBean { - - /** - * The runtime instance to which this bean provides a management connection. - */ - private final HotSpotGraalRuntime runtime; - - /** - * The object name under which the bean is registered. - */ - private final ObjectName objectName; - - public HotSpotGraalRuntimeMBean(ObjectName objectName, HotSpotGraalRuntime runtime) { - this.objectName = objectName; - this.runtime = runtime; - } - - public ObjectName getObjectName() { - return objectName; - } - - public HotSpotGraalRuntime getRuntime() { - return runtime; - } - - private static final boolean DEBUG = initDebug(); - - private static boolean initDebug() { - try { - return Boolean.parseBoolean(Services.getSavedProperties().get(HotSpotGraalRuntimeMBean.class.getSimpleName() + ".debug")); - } catch (SecurityException e) { - // Swallow the exception - return false; - } - } - - @Override - public Object getAttribute(String name) throws AttributeNotFoundException { - String[] result = runtime.getOptionValues(name); - String value = result[0]; - if (value == null) { - throw new AttributeNotFoundException(name); - } - if (DEBUG) { - System.out.printf("getAttribute: %s = %s (type: %s)%n", name, value, value == null ? "null" : value.getClass().getName()); - } - return result[0]; - } - - @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality on the receiver is what we want") - @Override - public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException { - String name = attribute.getName(); - Object value = attribute.getValue(); - String svalue = String.valueOf(value); - if (DEBUG) { - System.out.printf("setAttribute: %s = %s (type: %s)%n", name, svalue, value == null ? "null" : value.getClass().getName()); - } - String[] result = runtime.setOptionValues(new String[]{name}, new String[]{svalue}); - if (result[0] != name) { - if (result[0] == null) { - throw new AttributeNotFoundException(name); - } - throw new InvalidAttributeValueException(result[0]); - } - } - - @Override - public AttributeList getAttributes(String[] names) { - String[] values = runtime.getOptionValues(names); - AttributeList list = new AttributeList(); - for (int i = 0; i < names.length; i++) { - String value = values[i]; - String name = names[i]; - if (value == null) { - TTY.printf("No such option named %s%n", name); - } else { - if (DEBUG) { - System.out.printf("getAttributes: %s = %s (type: %s)%n", name, value, value == null ? "null" : value.getClass().getName()); - } - list.add(new Attribute(name, value)); - } - } - return list; - } - - @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality on the receiver is what we want") - @Override - public AttributeList setAttributes(AttributeList attributes) { - String[] names = new String[attributes.size()]; - String[] values = new String[attributes.size()]; - - int i = 0; - for (Attribute attr : attributes.asList()) { - String name = attr.getName(); - names[i] = name; - Object value = attr.getValue(); - String svalue = String.valueOf(value); - values[i] = svalue; - if (DEBUG) { - System.out.printf("setAttributes: %s = %s (type: %s)%n", name, svalue, value == null ? "null" : value.getClass().getName()); - } - i++; - } - String[] result = runtime.setOptionValues(names, values); - AttributeList setOk = new AttributeList(); - i = 0; - for (Attribute attr : attributes.asList()) { - if (names[i] == result[i]) { - setOk.add(attr); - } else if (result[i] == null) { - TTY.printf("Error setting %s to %s: unknown option%n", attr.getName(), attr.getValue()); - } else { - TTY.printf("Error setting %s to %s: %s%n", attr.getName(), attr.getValue(), result[i]); - } - i++; - } - return setOk; - } - - @Override - public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException { - try { - if (DEBUG) { - System.out.printf("invoke: %s%s%n", actionName, Arrays.asList(params)); - } - Object retvalue = null; - if ("dumpMethod".equals(actionName)) { - retvalue = runtime.invokeManagementAction(actionName, params); - } - if (DEBUG) { - System.out.printf("invoke: %s%s = %s%n", actionName, Arrays.asList(params), retvalue); - } - return retvalue; - } catch (MBeanException ex) { - throw ex; - } catch (Exception ex) { - throw new ReflectionException(ex); - } - } - - @Override - public MBeanInfo getMBeanInfo() { - List<MBeanAttributeInfo> attrs = new ArrayList<>(); - for (OptionDescriptor option : getOptionDescriptors().getValues()) { - Class<?> optionValueType = option.getOptionValueType(); - if (Enum.class.isAssignableFrom(optionValueType)) { - // Enum values are passed through - // the management interface as Strings. - optionValueType = String.class; - } - attrs.add(new MBeanAttributeInfo(option.getName(), optionValueType.getName(), option.getHelp(), true, true, false)); - } - attrs.sort(new Comparator<MBeanAttributeInfo>() { - @Override - public int compare(MBeanAttributeInfo o1, MBeanAttributeInfo o2) { - return o1.getName().compareTo(o2.getName()); - } - }); - List<MBeanOperationInfo> opts = new ArrayList<>(); - opts.add(new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{ - new MBeanParameterInfo("className", "java.lang.String", "Class to observe"), - new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"), - }, "void", MBeanOperationInfo.ACTION)); - opts.add(new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{ - new MBeanParameterInfo("className", "java.lang.String", "Class to observe"), - new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"), - new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"), - }, "void", MBeanOperationInfo.ACTION)); - opts.add(new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{ - new MBeanParameterInfo("className", "java.lang.String", "Class to observe"), - new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"), - new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"), - new MBeanParameterInfo("host", "java.lang.String", "The host where the IGV tool is running at"), - new MBeanParameterInfo("port", "int", "The port where the IGV tool is listening at"), - }, "void", MBeanOperationInfo.ACTION)); - - return new MBeanInfo( - HotSpotGraalRuntimeMBean.class.getName(), - "Graal", - attrs.toArray(new MBeanAttributeInfo[attrs.size()]), - null, - opts.toArray(new MBeanOperationInfo[opts.size()]), - null); - } - - private static EconomicMap<String, OptionDescriptor> getOptionDescriptors() { - EconomicMap<String, OptionDescriptor> result = EconomicMap.create(); - for (OptionDescriptors set : OptionsParser.getOptionsLoader()) { - for (OptionDescriptor option : set) { - result.put(option.getName(), option); - } - } - return result; - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalManagementTest.java b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalManagementTest.java deleted file mode 100644 index fcf333397c2c..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalManagementTest.java +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Copyright (c) 2013, 2022, 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 org.graalvm.compiler.hotspot.test; - -import static org.graalvm.compiler.hotspot.test.HotSpotGraalCompilerTest.assumeGraalIsNotJIT; -import static org.graalvm.compiler.hotspot.test.HotSpotGraalManagementTest.JunitShield.findAttributeInfo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.AttributeNotFoundException; -import javax.management.InvalidAttributeValueException; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanInfo; -import javax.management.MBeanOperationInfo; -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.ObjectInstance; -import javax.management.ObjectName; - -import org.graalvm.compiler.api.test.Graal; -import org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration; -import org.graalvm.compiler.hotspot.HotSpotGraalRuntime; -import org.graalvm.compiler.options.EnumOptionKey; -import org.graalvm.compiler.options.NestedBooleanOptionKey; -import org.graalvm.compiler.options.OptionDescriptor; -import org.graalvm.compiler.options.OptionDescriptors; -import org.graalvm.compiler.options.OptionKey; -import org.graalvm.compiler.options.OptionsParser; -import org.junit.Assert; -import org.junit.AssumptionViolatedException; -import org.junit.Test; - -public class HotSpotGraalManagementTest { - - private static final boolean DEBUG = Boolean.getBoolean(HotSpotGraalManagementTest.class.getSimpleName() + ".debug"); - - public HotSpotGraalManagementTest() { - assumeGraalIsNotJIT("random flipping of Graal options can cause havoc if Graal is being used as a JIT"); - try { - /* Trigger loading of the management library using the bootstrap class loader. */ - ManagementFactory.getThreadMXBean(); - MBeanServerFactory.findMBeanServer(null); - } catch (UnsatisfiedLinkError | NoClassDefFoundError e) { - throw new AssumptionViolatedException("Management classes/module(s) not available: " + e); - } - } - - @Test - public void registration() throws Exception { - HotSpotGraalRuntime runtime = (HotSpotGraalRuntime) Graal.getRuntime(); - HotSpotGraalManagementRegistration management = runtime.getManagement(); - if (management == null) { - return; - } - - MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - - ObjectName name; - assertNotNull("Now the bean thinks it is registered", name = (ObjectName) management.poll(true)); - - assertNotNull("And the bean is found", server.getObjectInstance(name)); - } - - @Test - public void readBeanInfo() throws Exception { - - assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); - - HotSpotGraalRuntime runtime = (HotSpotGraalRuntime) Graal.getRuntime(); - HotSpotGraalManagementRegistration management = runtime.getManagement(); - if (management == null) { - return; - } - - ObjectName mbeanName; - assertNotNull("Bean is registered", mbeanName = (ObjectName) management.poll(true)); - final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - - ObjectInstance bean = server.getObjectInstance(mbeanName); - assertNotNull("Bean is registered", bean); - MBeanInfo info = server.getMBeanInfo(mbeanName); - assertNotNull("Info is found", info); - - AttributeList originalValues = new AttributeList(); - AttributeList newValues = new AttributeList(); - for (OptionDescriptors set : OptionsParser.getOptionsLoader()) { - for (OptionDescriptor option : set) { - JunitShield.testOption(info, mbeanName, server, runtime, option, newValues, originalValues); - } - } - - String[] attributeNames = new String[originalValues.size()]; - for (int i = 0; i < attributeNames.length; i++) { - attributeNames[i] = ((Attribute) originalValues.get(i)).getName(); - } - AttributeList actualValues = server.getAttributes(mbeanName, attributeNames); - assertEquals(originalValues.size(), actualValues.size()); - for (int i = 0; i < attributeNames.length; i++) { - Object expect = String.valueOf(((Attribute) originalValues.get(i)).getValue()); - Object actual = String.valueOf(((Attribute) actualValues.get(i)).getValue()); - assertEquals(attributeNames[i], expect, actual); - } - - try { - server.setAttributes(mbeanName, newValues); - } finally { - server.setAttributes(mbeanName, originalValues); - } - } - - /** - * Junit scans all methods of a test class and tries to resolve all method parameter and return - * types. We hide such methods in an inner class to prevent errors such as: - * - * <pre> - * java.lang.NoClassDefFoundError: javax/management/MBeanInfo - * at java.base/java.lang.Class.getDeclaredMethods0(Native Method) - * at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3119) - * at java.base/java.lang.Class.getDeclaredMethods(Class.java:2268) - * at org.junit.internal.MethodSorter.getDeclaredMethods(MethodSorter.java:54) - * at org.junit.runners.model.TestClass.scanAnnotatedMembers(TestClass.java:65) - * at org.junit.runners.model.TestClass.<init>(TestClass.java:57) - * - * </pre> - */ - static class JunitShield { - - /** - * Tests changing the value of {@code option} via the management interface to a) a new legal - * value and b) an illegal value. - */ - static void testOption(MBeanInfo mbeanInfo, - ObjectName mbeanName, - MBeanServer server, - HotSpotGraalRuntime runtime, - OptionDescriptor option, - AttributeList newValues, - AttributeList originalValues) throws Exception { - OptionKey<?> optionKey = option.getOptionKey(); - Object currentValue = optionKey.getValue(runtime.getOptions()); - Class<?> optionType = option.getOptionValueType(); - String name = option.getName(); - if (DEBUG) { - System.out.println("Testing option " + name); - } - MBeanAttributeInfo attrInfo = findAttributeInfo(name, mbeanInfo); - assertNotNull("Attribute not found for option " + name, attrInfo); - - String expectAttributeValue = stringValue(currentValue, option.getOptionValueType() == String.class); - Object actualAttributeValue = server.getAttribute(mbeanName, name); - assertEquals(expectAttributeValue, actualAttributeValue); - - Map<String, String> legalValues = new HashMap<>(); - List<String> illegalValues = new ArrayList<>(); - if (optionKey instanceof EnumOptionKey) { - EnumOptionKey<?> enumOptionKey = (EnumOptionKey<?>) optionKey; - for (Object obj : enumOptionKey.getAllValues()) { - if (obj != currentValue) { - legalValues.put(obj.toString(), obj.toString()); - } - } - illegalValues.add(String.valueOf(42)); - } else if (optionType == Boolean.class) { - Object defaultValue; - if (optionKey instanceof NestedBooleanOptionKey) { - NestedBooleanOptionKey nbok = (NestedBooleanOptionKey) optionKey; - defaultValue = nbok.getParentOption().getValue(runtime.getOptions()); - } else { - defaultValue = optionKey.getDefaultValue(); - } - legalValues.put("", unquotedStringValue(defaultValue)); - illegalValues.add(String.valueOf(42)); - illegalValues.add("true"); - illegalValues.add("false"); - } else if (optionType == String.class) { - legalValues.put("", quotedStringValue(optionKey.getDefaultValue())); - legalValues.put("\"" + currentValue + "Prime\"", "\"" + currentValue + "Prime\""); - legalValues.put("\"quoted string\"", "\"quoted string\""); - illegalValues.add("\"unbalanced quotes"); - illegalValues.add("\""); - illegalValues.add("non quoted string"); - } else if (optionType == Float.class) { - legalValues.put("", unquotedStringValue(optionKey.getDefaultValue())); - String value = unquotedStringValue(currentValue == null ? 33F : ((float) currentValue) + 11F); - legalValues.put(value, value); - illegalValues.add("string"); - } else if (optionType == Double.class) { - legalValues.put("", unquotedStringValue(optionKey.getDefaultValue())); - String value = unquotedStringValue(currentValue == null ? 33D : ((double) currentValue) + 11D); - legalValues.put(value, value); - illegalValues.add("string"); - } else if (optionType == Integer.class) { - legalValues.put("", unquotedStringValue(optionKey.getDefaultValue())); - String value = unquotedStringValue(currentValue == null ? 33 : ((int) currentValue) + 11); - legalValues.put(value, value); - illegalValues.add("42.42"); - illegalValues.add("string"); - } else if (optionType == Long.class) { - legalValues.put("", unquotedStringValue(optionKey.getDefaultValue())); - String value = unquotedStringValue(currentValue == null ? 33L : ((long) currentValue) + 11L); - legalValues.put(value, value); - illegalValues.add("42.42"); - illegalValues.add("string"); - } - - Attribute originalAttributeValue = new Attribute(name, expectAttributeValue); - try { - for (Map.Entry<String, String> e : legalValues.entrySet()) { - String legalValue = e.getKey(); - if (DEBUG) { - System.out.printf("Changing %s from %s to %s%n", name, currentValue, legalValue); - } - Attribute newAttributeValue = new Attribute(name, legalValue); - newValues.add(newAttributeValue); - server.setAttribute(mbeanName, newAttributeValue); - Object actual = optionKey.getValue(runtime.getOptions()); - actual = server.getAttribute(mbeanName, name); - String expectValue = e.getValue(); - if (option.getOptionValueType() == String.class && expectValue == null) { - expectValue = ""; - } else if (option.getOptionKey() instanceof NestedBooleanOptionKey && null == expectValue) { - NestedBooleanOptionKey nbok = (NestedBooleanOptionKey) option.getOptionKey(); - expectValue = String.valueOf(nbok.getValue(runtime.getOptions())); - actual = server.getAttribute(mbeanName, name); - } - assertEquals(expectValue, actual); - } - } finally { - if (DEBUG) { - System.out.printf("Resetting %s to %s%n", name, currentValue); - } - originalValues.add(originalAttributeValue); - server.setAttribute(mbeanName, originalAttributeValue); - } - - try { - for (Object illegalValue : illegalValues) { - if (DEBUG) { - System.out.printf("Changing %s from %s to illegal value %s%n", name, currentValue, illegalValue); - } - server.setAttribute(mbeanName, new Attribute(name, illegalValue)); - Assert.fail("Expected setting " + name + " to " + illegalValue + " to fail"); - } - } catch (InvalidAttributeValueException e) { - // Expected - } finally { - if (DEBUG) { - System.out.printf("Resetting %s to %s%n", name, currentValue); - } - server.setAttribute(mbeanName, originalAttributeValue); - } - - try { - - String unknownOptionName = "definitely not an option name"; - server.setAttribute(mbeanName, new Attribute(unknownOptionName, "")); - Assert.fail("Expected setting option with name \"" + unknownOptionName + "\" to fail"); - } catch (AttributeNotFoundException e) { - // Expected - } - } - - static MBeanAttributeInfo findAttributeInfo(String attrName, MBeanInfo info) { - for (MBeanAttributeInfo attr : info.getAttributes()) { - if (attr.getName().equals(attrName)) { - assertTrue("Readable", attr.isReadable()); - assertTrue("Writable", attr.isWritable()); - return attr; - } - } - return null; - } - } - - private static String quotedStringValue(Object optionValue) { - return stringValue(optionValue, true); - } - - private static String unquotedStringValue(Object optionValue) { - return stringValue(optionValue, false); - } - - private static String stringValue(Object optionValue, boolean withQuoting) { - if (optionValue == null) { - return ""; - } - if (withQuoting) { - return "\"" + optionValue + "\""; - } - return String.valueOf(optionValue); - } - - private static String quoted(Object s) { - return "\"" + s + "\""; - } - - /** - * Tests publicaly visible names and identifiers used by tools developed and distributed on an - * independent schedule (like VisualVM). Consider keeping the test passing without any semantic - * modifications. The cost of changes is higher than you estimate. Include all available - * stakeholders as reviewers to give them a chance to stop you before causing too much damage. - */ - @Test - public void publicJmxApiOfGraalDumpOperation() throws Exception { - assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); - - HotSpotGraalRuntime runtime = (HotSpotGraalRuntime) Graal.getRuntime(); - HotSpotGraalManagementRegistration management = runtime.getManagement(); - if (management == null) { - return; - } - - ObjectName mbeanName; - assertNotNull("Bean is registered", mbeanName = (ObjectName) management.poll(true)); - final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - - assertEquals("Domain name is used to lookup the beans by VisualVM", "org.graalvm.compiler.hotspot", mbeanName.getDomain()); - assertEquals("type can be used to identify the Graal bean", "HotSpotGraalRuntime_VM", mbeanName.getKeyProperty("type")); - - ObjectInstance bean = server.getObjectInstance(mbeanName); - assertNotNull("Bean is registered", bean); - - MBeanInfo info = server.getMBeanInfo(mbeanName); - assertNotNull("Info is found", info); - - final MBeanOperationInfo[] arr = info.getOperations(); - MBeanOperationInfo dumpOp = null; - int dumpMethodCount = 0; - for (int i = 0; i < arr.length; i++) { - if ("dumpMethod".equals(arr[i].getName())) { - if (arr[i].getSignature().length == 3) { - dumpOp = arr[i]; - } - dumpMethodCount++; - } - } - assertEquals("Currently three overloads", 3, dumpMethodCount); - assertNotNull("three args variant (as used by VisualVM) found", dumpOp); - - MBeanAttributeInfo dumpPath = findAttributeInfo("DumpPath", info); - MBeanAttributeInfo printGraphFile = findAttributeInfo("PrintGraphFile", info); - MBeanAttributeInfo showDumpFiles = findAttributeInfo("ShowDumpFiles", info); - MBeanAttributeInfo methodFilter = findAttributeInfo("MethodFilter", info); - Object originalDumpPath = server.getAttribute(mbeanName, dumpPath.getName()); - Object originalPrintGraphFile = server.getAttribute(mbeanName, printGraphFile.getName()); - Object originalShowDumpFiles = server.getAttribute(mbeanName, showDumpFiles.getName()); - Object originalMethodFilter = server.getAttribute(mbeanName, methodFilter.getName()); - final File tmpDir = new File(HotSpotGraalManagementTest.class.getSimpleName() + "_" + System.currentTimeMillis()).getAbsoluteFile(); - - server.setAttribute(mbeanName, new Attribute(dumpPath.getName(), quoted(tmpDir))); - server.setAttribute(mbeanName, new Attribute(methodFilter.getName(), "")); - // Force output to a file even if there's a running IGV instance available. - server.setAttribute(mbeanName, new Attribute(printGraphFile.getName(), true)); - server.setAttribute(mbeanName, new Attribute(showDumpFiles.getName(), false)); - Object[] params = {"java.util.Arrays", "asList", ":3"}; - try { - server.invoke(mbeanName, "dumpMethod", params, null); - boolean found = false; - String expectedIgvDumpSuffix = "[Arrays.asList(Object[])List].bgv"; - Assert.assertTrue(tmpDir.toString() + " was not created or is not a directory", tmpDir.isDirectory()); - List<String> dumpPathEntries = Arrays.asList(tmpDir.list()); - for (String entry : dumpPathEntries) { - if (entry.endsWith(expectedIgvDumpSuffix)) { - found = true; - } - } - if (!found) { - Assert.fail(String.format("Expected file ending with \"%s\" in %s but only found:%n%s", expectedIgvDumpSuffix, tmpDir, - dumpPathEntries.stream().collect(Collectors.joining(System.lineSeparator())))); - } - } finally { - if (tmpDir.isDirectory()) { - deleteDirectory(tmpDir.toPath()); - } - server.setAttribute(mbeanName, new Attribute(dumpPath.getName(), originalDumpPath)); - server.setAttribute(mbeanName, new Attribute(methodFilter.getName(), originalMethodFilter)); - server.setAttribute(mbeanName, new Attribute(printGraphFile.getName(), originalPrintGraphFile)); - server.setAttribute(mbeanName, new Attribute(showDumpFiles.getName(), originalShowDumpFiles)); - } - } - - static void deleteDirectory(Path toDelete) throws IOException { - Files.walk(toDelete).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalManagementRegistration.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalManagementRegistration.java deleted file mode 100644 index b02fbc9bb8b2..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalManagementRegistration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017, 2020, 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 org.graalvm.compiler.hotspot; - -/** - * Communicates with an MBean providing a JMX interface to a {@link HotSpotGraalRuntime} instance. - * The MBean will be dynamically created when a JMX client attaches or some other event causes the - * platform MBean server to be started. - */ -public interface HotSpotGraalManagementRegistration { - - /** - * Completes the initialization of this registration by recording the - * {@link HotSpotGraalRuntime} the MBean will provide an JMX interface to. - */ - void initialize(HotSpotGraalRuntime runtime, GraalHotSpotVMConfig config); - - /** - * Polls this registration to see if the MBean is registered in a MBean server. - * - * @param sync synchronize with other threads that may be processing this registration. This is - * useful when the caller knows the server is active (e.g., it has a reference to - * server) and expects this poll to therefore return a non-null value. - * @return an {@link javax.management.ObjectName} that can be used to access the MBean or - * {@code null} if the MBean has not been registered with an MBean server (e.g., no JMX - * client has attached to the VM) - */ - Object poll(boolean sync); -} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java index 4e2e34144d2c..c813b209979a 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java @@ -37,9 +37,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.graalvm.collections.EconomicMap; -import org.graalvm.collections.EconomicSet; import org.graalvm.collections.Equivalence; -import org.graalvm.collections.UnmodifiableMapCursor; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.api.runtime.GraalRuntime; import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction; @@ -55,7 +53,6 @@ import org.graalvm.compiler.debug.DebugContext.Builder; import org.graalvm.compiler.debug.DebugContext.Description; import org.graalvm.compiler.debug.DebugHandlersFactory; -import org.graalvm.compiler.debug.DebugOptions; import org.graalvm.compiler.debug.DiagnosticsOutputDirectory; import org.graalvm.compiler.debug.GlobalMetrics; import org.graalvm.compiler.debug.GraalError; @@ -65,12 +62,7 @@ import org.graalvm.compiler.hotspot.debug.BenchmarkCounters; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.nodes.spi.StampProvider; -import org.graalvm.compiler.options.EnumOptionKey; -import org.graalvm.compiler.options.OptionDescriptor; -import org.graalvm.compiler.options.OptionDescriptors; -import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionValues; -import org.graalvm.compiler.options.OptionsParser; import org.graalvm.compiler.phases.tiers.CompilerConfiguration; import org.graalvm.compiler.replacements.SnippetCounter; import org.graalvm.compiler.replacements.SnippetCounter.Group; @@ -80,19 +72,11 @@ import jdk.vm.ci.code.Architecture; import jdk.vm.ci.code.stack.StackIntrospection; import jdk.vm.ci.common.InitTimer; -import jdk.vm.ci.hotspot.HotSpotCompilationRequest; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; -import jdk.vm.ci.hotspot.HotSpotResolvedJavaType; -import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; import jdk.vm.ci.hotspot.HotSpotVMConfigStore; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.runtime.JVMCI; import jdk.vm.ci.runtime.JVMCIBackend; -import jdk.vm.ci.services.Services; //JaCoCo Exclude @@ -101,8 +85,6 @@ */ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider { - private static final boolean IS_AOT = Boolean.parseBoolean(Services.getSavedProperties().get("com.oracle.graalvm.isaot")); - private static boolean checkArrayIndexScaleInvariants(MetaAccessProvider metaAccess) { assert metaAccess.getArrayIndexScale(JavaKind.Byte) == 1; assert metaAccess.getArrayIndexScale(JavaKind.Boolean) == 1; @@ -133,12 +115,6 @@ public GlobalMetrics getMetricValues() { private final Instrumentation instrumentation; - /** - * The options can be {@linkplain #setOptionValues(String[], String[]) updated} by external - * interfaces such as JMX. This comes with the risk that inconsistencies can arise as an - * {@link OptionValues} object can be cached by various parts of Graal instead of always - * obtaining them from this object. However, concurrent updates are never lost. - */ private AtomicReference<OptionValues> optionsRef = new AtomicReference<>(); private final DiagnosticsOutputDirectory outputDirectory; @@ -175,19 +151,6 @@ public GlobalMetrics getMetricValues() { this.instrumentation = compilerConfigurationFactory.createInstrumentation(options); - if (IS_AOT) { - management = null; - } else { - management = GraalServices.loadSingle(HotSpotGraalManagementRegistration.class, false); - } - if (management != null) { - try { - management.initialize(this, config); - } catch (Throwable error) { - handleManagementInitializationFailure(error); - } - } - BackendMap backendMap = compilerConfigurationFactory.createBackendMap(); JVMCIBackend hostJvmciBackend = jvmciRuntime.getHostJVMCIBackend(); @@ -363,24 +326,6 @@ public GraalHotSpotVMConfig getVMConfig() { @Override public DebugContext openDebugContext(OptionValues compilationOptions, CompilationIdentifier compilationId, Object compilable, Iterable<DebugHandlersFactory> factories, PrintStream logStream) { - if (management != null && management.poll(false) != null) { - if (compilable instanceof HotSpotResolvedJavaMethod) { - HotSpotResolvedObjectType type = ((HotSpotResolvedJavaMethod) compilable).getDeclaringClass(); - if (type instanceof HotSpotResolvedJavaType) { - Class<?> clazz = runtime().getMirror(type); - if (clazz != null) { - try { - ClassLoader cl = clazz.getClassLoader(); - if (cl != null) { - loaders.add(cl); - } - } catch (SecurityException e) { - // This loader can obviously not be used for resolving class names - } - } - } - } - } Description description = new Description(compilable, compilationId.toString(CompilationIdentifier.Verbosity.ID)); Builder builder = new Builder(compilationOptions, factories).// @@ -574,203 +519,4 @@ public DiagnosticsOutputDirectory getOutputDirectory() { public Map<ExceptionAction, Integer> getCompilationProblemsPerAction() { return compilationProblemsPerAction; } - - // ------- Management interface --------- - - private HotSpotGraalManagementRegistration management; - - /** - * @returns the management object for this runtime or {@code null} - */ - public HotSpotGraalManagementRegistration getManagement() { - return management; - } - - public void handleManagementInitializationFailure(Throwable cause) { - if (cause instanceof ThreadDeath) { - throw (ThreadDeath) cause; - } - TTY.println("Cannot install GraalVM MBean due to " + cause.getMessage()); - management = null; - } - - /** - * Set of weak references to {@link ClassLoader}s available for resolving class names present in - * management {@linkplain #invokeManagementAction(String, Object[]) action} arguments. - */ - private final WeakClassLoaderSet loaders = new WeakClassLoaderSet(ClassLoader.getSystemClassLoader()); - - /** - * Sets or updates this object's {@linkplain #getOptions() options} from {@code names} and - * {@code values}. - * - * @param values the values to set. The empty string represents {@code null} which resets an - * option to its default value. For string type options, a non-empty value must be - * enclosed in double quotes. - * @return an array of Strings where the element at index i is {@code names[i]} if setting the - * denoted option succeeded, {@code null} if the option is unknown otherwise an error - * message describing the failure to set the option - */ - public String[] setOptionValues(String[] names, String[] values) { - EconomicMap<String, OptionDescriptor> optionDescriptors = getOptionDescriptors(); - EconomicMap<OptionKey<?>, Object> newValues = EconomicMap.create(names.length); - EconomicSet<OptionKey<?>> resetValues = EconomicSet.create(names.length); - String[] result = new String[names.length]; - for (int i = 0; i < names.length; i++) { - String name = names[i]; - OptionDescriptor option = optionDescriptors.get(name); - if (option != null) { - String svalue = values[i]; - Class<?> optionValueType = option.getOptionValueType(); - OptionKey<?> optionKey = option.getOptionKey(); - if (svalue == null || svalue.isEmpty() && !(optionKey instanceof EnumOptionKey)) { - resetValues.add(optionKey); - result[i] = name; - } else { - String valueToParse; - if (optionValueType == String.class) { - if (svalue.length() < 2 || svalue.charAt(0) != '"' || svalue.charAt(svalue.length() - 1) != '"') { - result[i] = "Invalid value for String option '" + name + "': must be the empty string or be enclosed in double quotes: " + svalue; - continue; - } else { - valueToParse = svalue.substring(1, svalue.length() - 1); - } - } else { - valueToParse = svalue; - } - try { - OptionsParser.parseOption(name, valueToParse, newValues, OptionsParser.getOptionsLoader()); - result[i] = name; - } catch (IllegalArgumentException e) { - result[i] = e.getMessage(); - continue; - } - } - } else { - result[i] = null; - } - } - - OptionValues currentOptions; - OptionValues newOptions; - do { - currentOptions = optionsRef.get(); - UnmodifiableMapCursor<OptionKey<?>, Object> cursor = currentOptions.getMap().getEntries(); - while (cursor.advance()) { - OptionKey<?> key = cursor.getKey(); - if (!resetValues.contains(key) && !newValues.containsKey(key)) { - newValues.put(key, OptionValues.decodeNull(cursor.getValue())); - } - } - newOptions = new OptionValues(newValues); - } while (!optionsRef.compareAndSet(currentOptions, newOptions)); - - return result; - } - - /** - * Gets the values for the options corresponding to {@code names} encoded as strings. The empty - * string represents {@code null}. For string type options, non-{@code null} values will be - * enclosed in double quotes. - * - * @param names a list of option names - * @return the values for each named option. If an element in {@code names} does not denote an - * existing option, the corresponding element in the returned array will be {@code null} - */ - public String[] getOptionValues(String... names) { - String[] values = new String[names.length]; - EconomicMap<String, OptionDescriptor> optionDescriptors = getOptionDescriptors(); - for (int i = 0; i < names.length; i++) { - OptionDescriptor option = optionDescriptors.get(names[i]); - if (option != null) { - OptionKey<?> optionKey = option.getOptionKey(); - Object value = optionKey.getValue(getOptions()); - String svalue; - if (option.getOptionValueType() == String.class && value != null) { - svalue = "\"" + value + "\""; - } else if (value == null) { - svalue = ""; - } else { - svalue = String.valueOf(value); - } - values[i] = svalue; - } else { - // null denotes the option does not exist - values[i] = null; - } - } - return values; - } - - private static EconomicMap<String, OptionDescriptor> getOptionDescriptors() { - EconomicMap<String, OptionDescriptor> result = EconomicMap.create(); - for (OptionDescriptors set : OptionsParser.getOptionsLoader()) { - for (OptionDescriptor option : set) { - result.put(option.getName(), option); - } - } - return result; - } - - private void dumpMethod(String className, String methodName, String filter, String host, int port) throws Exception { - EconomicSet<ClassNotFoundException> failures = EconomicSet.create(); - EconomicSet<Class<?>> found = loaders.resolve(className, failures); - if (found.isEmpty()) { - ClassNotFoundException cause = failures.isEmpty() ? new ClassNotFoundException(className) : failures.iterator().next(); - throw new Exception("Cannot find class " + className + " to schedule recompilation", cause); - } - for (Class<?> clazz : found) { - ResolvedJavaType type = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaType(clazz); - for (ResolvedJavaMethod method : type.getDeclaredMethods()) { - if (methodName.equals(method.getName()) && method instanceof HotSpotResolvedJavaMethod) { - HotSpotResolvedJavaMethod hotSpotMethod = (HotSpotResolvedJavaMethod) method; - dumpMethod(hotSpotMethod, filter, host, port); - } - } - } - } - - private void dumpMethod(HotSpotResolvedJavaMethod hotSpotMethod, String filter, String host, int port) throws Exception { - EconomicMap<OptionKey<?>, Object> extra = EconomicMap.create(); - extra.put(DebugOptions.Dump, filter); - extra.put(DebugOptions.PrintGraphHost, host); - extra.put(DebugOptions.PrintGraphPort, port); - OptionValues compileOptions = new OptionValues(getOptions(), extra); - HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime().getCompiler(); - compiler.compileMethod(new HotSpotCompilationRequest(hotSpotMethod, -1, 0L), false, compileOptions); - } - - public Object invokeManagementAction(String actionName, Object[] params) throws Exception { - if ("dumpMethod".equals(actionName)) { - if (params.length != 0 && params[0] instanceof HotSpotResolvedJavaMethod) { - HotSpotResolvedJavaMethod method = param(params, 0, "method", HotSpotResolvedJavaMethod.class, null); - String filter = param(params, 1, "filter", String.class, ":3"); - String host = param(params, 2, "host", String.class, "localhost"); - Number port = param(params, 3, "port", Number.class, 4445); - dumpMethod(method, filter, host, port.intValue()); - } else { - String className = param(params, 0, "className", String.class, null); - String methodName = param(params, 1, "methodName", String.class, null); - String filter = param(params, 2, "filter", String.class, ":3"); - String host = param(params, 3, "host", String.class, "localhost"); - Number port = param(params, 4, "port", Number.class, 4445); - dumpMethod(className, methodName, filter, host, port.intValue()); - } - } - return null; - } - - private static <T> T param(Object[] arr, int index, String name, Class<T> type, T defaultValue) { - Object value = arr.length > index ? arr[index] : null; - if (value == null || (value instanceof String && ((String) value).isEmpty())) { - if (defaultValue == null) { - throw new IllegalArgumentException(name + " must be specified"); - } - value = defaultValue; - } - if (type.isInstance(value)) { - return type.cast(value); - } - throw new IllegalArgumentException("Expecting " + type.getName() + " for " + name + " but was " + value); - } } From 79fe2ca78a532e1ed9696a14e172e710c59a4d30 Mon Sep 17 00:00:00 2001 From: Tomas Zezula <tomas.zezula@oracle.com> Date: Thu, 25 Aug 2022 11:23:56 +0200 Subject: [PATCH 3/3] Fixed review comments. --- compiler/CHANGELOG.md | 2 +- .../compiler/hotspot/HotSpotGraalRuntime.java | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/compiler/CHANGELOG.md b/compiler/CHANGELOG.md index 890243d74742..5503a8043c21 100644 --- a/compiler/CHANGELOG.md +++ b/compiler/CHANGELOG.md @@ -5,7 +5,7 @@ This changelog summarizes newly introduced optimizations that may be relevant to ## Version 22.3.0 * (GR-32382): Added a dedicated Native Image GC policy for libgraal that will adjust the eden space aggressively to minimize RSS memory usage. -* (GR-38950): Removed deprecated JMX `HotSpotGraalRuntime` management bean in both `libgraal` and `jargraal` compiler. +* (GR-38950): Removed deprecated JMX `HotSpotGraalRuntime` management bean from both `libgraal` and `jargraal`. ## Version 22.2.0 * (GR-23737): New global value numbering optimization for fixed nodes early in the compilation pipeline. diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java index c813b209979a..e5fa4958378e 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java @@ -34,7 +34,6 @@ import java.util.EnumMap; import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.Equivalence; @@ -115,7 +114,7 @@ public GlobalMetrics getMetricValues() { private final Instrumentation instrumentation; - private AtomicReference<OptionValues> optionsRef = new AtomicReference<>(); + private final OptionValues options; private final DiagnosticsOutputDirectory outputDirectory; private final Map<ExceptionAction, Integer> compilationProblemsPerAction; @@ -135,11 +134,10 @@ public GlobalMetrics getMetricValues() { // Only set HotSpotPrintInlining if it still has its default value (false). if (GraalOptions.HotSpotPrintInlining.getValue(initialOptions) == false && config.printInlining) { - optionsRef.set(new OptionValues(initialOptions, HotSpotPrintInlining, true)); + options = new OptionValues(initialOptions, HotSpotPrintInlining, true); } else { - optionsRef.set(initialOptions); + options = initialOptions; } - OptionValues options = optionsRef.get(); garbageCollector = getSelectedGC(); @@ -342,7 +340,7 @@ public DebugContext openDebugContext(OptionValues compilationOptions, Compilatio @Override public OptionValues getOptions() { - return optionsRef.get(); + return options; } @Override @@ -366,7 +364,7 @@ public <T> T getCapability(Class<T> clazz) { if (clazz == RuntimeProvider.class) { return (T) this; } else if (clazz == OptionValues.class) { - return (T) optionsRef.get(); + return (T) options; } else if (clazz == StackIntrospection.class) { return (T) this; } else if (clazz == SnippetReflectionProvider.class) { @@ -425,7 +423,7 @@ public Instrumentation getInstrumentation() { * @param phase the execution phase being entered */ void phaseTransition(String phase) { - if (Options.UseCompilationStatistics.getValue(optionsRef.get())) { + if (Options.UseCompilationStatistics.getValue(options)) { CompilationStatistics.clear(phase); } } @@ -453,7 +451,7 @@ synchronized void shutdown() { } } - metricValues.print(optionsRef.get()); + metricValues.print(options); phaseTransition("final"); @@ -462,7 +460,7 @@ synchronized void shutdown() { TTY.out().out().println(group); } } - BenchmarkCounters.shutdown(runtime(), optionsRef.get(), runtimeStartTime); + BenchmarkCounters.shutdown(runtime(), options, runtimeStartTime); outputDirectory.close();